From 71b91f55531225a5302eb970f2b85b747b22b9de Mon Sep 17 00:00:00 2001 From: Lance Albertson Date: Mon, 6 Jan 2020 14:57:32 -0800 Subject: [PATCH] Improve ChefSpec test speed by enabling caching This updates all references of let(:chef_run) to cached(:chef_run) to speed up tests. By doing this, we have to create a new cached(:chef_run) block whenever we need to adjust node attributes for testing. Speed was improved from 56 minutes 34 seconds to 8 minutes 43 seconds Change-Id: Ic7cf02200cf9d09beb66f6aa0d27cadffa65f7c9 --- spec/apache2-server-redhat_spec.rb | 15 +- spec/apache2-server_spec.rb | 462 +++++++++++++++----------- spec/horizon-redhat_spec.rb | 2 +- spec/horizon_spec.rb | 471 +++++++++++++++------------ spec/neutron-fwaas-dashboard_spec.rb | 6 +- spec/neutron-lbaas-dashboard_spec.rb | 6 +- spec/spec_helper.rb | 8 +- 7 files changed, 555 insertions(+), 415 deletions(-) diff --git a/spec/apache2-server-redhat_spec.rb b/spec/apache2-server-redhat_spec.rb index 34c9f47..5c11ee5 100644 --- a/spec/apache2-server-redhat_spec.rb +++ b/spec/apache2-server-redhat_spec.rb @@ -5,7 +5,7 @@ describe 'openstack-dashboard::apache2-server' do describe 'redhat' do let(:runner) { ChefSpec::SoloRunner.new(REDHAT_OPTS) } let(:node) { runner.node } - let(:chef_run) do + cached(:chef_run) do runner.converge(described_recipe) end include_context 'dashboard_stubs' @@ -37,10 +37,15 @@ describe 'openstack-dashboard::apache2-server' do expect(key).to notify('execute[restore-selinux-context]').to(:run) end - it 'does not mess with certs if ssl not enabled' do - node.override['openstack']['dashboard']['use_ssl'] = false - expect(chef_run).not_to create_file('/etc/ssl/certs/horizon.pem') - expect(chef_run).not_to create_file('/etc/pki/tls/private/horizon.key') + context 'does not mess with certs if ssl not enabled' do + cached(:chef_run) do + node.override['openstack']['dashboard']['use_ssl'] = false + runner.converge(described_recipe) + end + it do + expect(chef_run).not_to create_file('/etc/ssl/certs/horizon.pem') + expect(chef_run).not_to create_file('/etc/pki/tls/private/horizon.key') + end end end end diff --git a/spec/apache2-server_spec.rb b/spec/apache2-server_spec.rb index a405bca..ac4b23d 100644 --- a/spec/apache2-server_spec.rb +++ b/spec/apache2-server_spec.rb @@ -3,8 +3,11 @@ require_relative 'spec_helper' shared_examples 'virtualhost port configurator' do |port_attribute_name, port_attribute_value| let(:virtualhost_directive) { "" } - before do + cached(:chef_run) do node.override['openstack']['endpoints'][port_attribute_name]['port'] = port_attribute_value + node.override['openstack']['dashboard']['server_aliases'] = %w(server_aliases_value) + node.override['openstack']['dashboard']['server_hostname'] = 'server_hostname_value' + runner.converge(described_recipe) end it 'does not set NameVirtualHost directives when apache 2.4' do @@ -15,28 +18,32 @@ shared_examples 'virtualhost port configurator' do |port_attribute_name, port_at expect(chef_run).to render_file(file.name).with_content(/^#{virtualhost_directive}$/) end - context 'server_hostname' do + describe 'server_hostname' do it 'sets the value if the server_hostname is present' do - node.override['openstack']['dashboard']['server_hostname'] = 'server_hostname_value' - expect(chef_run).to render_file(file.name).with_content(/^#{virtualhost_directive}\s*ServerName server_hostname_value$/) + expect(chef_run).to render_file(file.name) + .with_content(/^#{virtualhost_directive}\s*ServerName server_hostname_value$/) end it 'does not set the value if the server_hostname is not present' do - node.override['openstack']['dashboard']['server_hostname'] = nil expect(chef_run).not_to render_file(file.name).with_content(/^#{virtualhost_directive}\s*ServerName$/) end end - context 'server_aliases' do + describe 'server_aliases' do it 'sets the value if the server_aliases is present' do - node.override['openstack']['dashboard']['server_aliases'] = %w(server_aliases_value) - expect(chef_run).to render_file(file.name).with_content(/^#{virtualhost_directive}\s*ServerAlias server_aliases_value$/) + expect(chef_run).to render_file(file.name) + .with_content(/^#{virtualhost_directive}\s*ServerName.*\s*ServerAlias server_aliases_value$/) end - it 'sets the value if multiple server_aliases is present' do - node.override['openstack']['dashboard']['server_aliases'] = %w(server_aliases_value1 server_aliases_value2) - expect(chef_run).to render_file(file.name).with_content(/^#{virtualhost_directive}\s*ServerAlias server_aliases_value1 server_aliases_value2$/) + context 'sets the value if multiple server_aliases is present' do + cached(:chef_run) do + node.override['openstack']['dashboard']['server_aliases'] = %w(server_aliases_value1 server_aliases_value2) + runner.converge(described_recipe) + end + it do + expect(chef_run).to render_file(file.name) + .with_content(/^#{virtualhost_directive}\s*ServerAlias server_aliases_value1 server_aliases_value2$/) + end end it 'does not set the value if the server_aliases is not present' do - node.override['openstack']['dashboard']['server_hostname'] = [] expect(chef_run).not_to render_file(file.name).with_content(/^#{virtualhost_directive}\s*ServerAlias$/) end end @@ -46,14 +53,27 @@ describe 'openstack-dashboard::apache2-server' do describe 'ubuntu' do let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) } let(:node) { runner.node } - let(:chef_run) do + cached(:chef_run) do + node.override['openstack']['dashboard']['custom_template_banner'] = 'custom_template_banner_value' + node.override['openstack']['dashboard']['traceenable'] = 'value' + node.override['apache']['log_dir'] = 'log_dir_value' + node.override['apache']['contact'] = 'apache_contact_value' + node.override['openstack']['dashboard']['error_log'] = 'error_log_value' + node.override['openstack']['dashboard']['access_log'] = 'access_log_value' runner.converge(described_recipe) end - let(:chef_run_session_sql) do - node.override['openstack']['dashboard']['session_backend'] = 'sql' + cached(:chef_run_no_ssl) do + node.override['openstack']['dashboard']['use_ssl'] = false + node.override['openstack']['dashboard']['ssl']['chain'] = 'horizon-chain.pem' runner.converge(described_recipe) end + + cached(:chef_run_chain) do + node.override['openstack']['dashboard']['ssl']['chain'] = 'horizon-chain.pem' + runner.converge(described_recipe) + end + include_context 'non_redhat_stubs' include_context 'dashboard_stubs' @@ -67,17 +87,18 @@ describe 'openstack-dashboard::apache2-server' do end it 'includes apache packages' do - %w(apache2 - apache2::mod_headers - apache2::mod_rewrite - apache2::mod_ssl).each do |recipe| + %w( + apache2 + apache2::mod_headers + apache2::mod_rewrite + apache2::mod_ssl + ).each do |recipe| expect(chef_run).to include_recipe(recipe) end end it 'does not include the apache mod_ssl package when ssl disabled' do - node.override['openstack']['dashboard']['use_ssl'] = false - expect(chef_run).not_to include_recipe('apache2::mod_ssl') + expect(chef_run_no_ssl).not_to include_recipe('apache2::mod_ssl') end it 'does not execute set-selinux-enforcing' do @@ -107,14 +128,11 @@ describe 'openstack-dashboard::apache2-server' do expect(key).to notify('execute[restore-selinux-context]').to(:run) end end - context 'set ssl chain' do - before do - node.override['openstack']['dashboard']['ssl']['chain'] = 'horizon-chain.pem' - end - let(:chain) { chef_run.file('/etc/ssl/certs/horizon-chain.pem') } + describe 'set ssl chain' do + let(:chain) { chef_run_chain.file('/etc/ssl/certs/horizon-chain.pem') } it 'create files and restarts apache' do - expect(chef_run).to create_file('/etc/ssl/certs/horizon-chain.pem').with( + expect(chef_run_chain).to create_file('/etc/ssl/certs/horizon-chain.pem').with( content: 'horizon_chain_pem_value', user: 'root', group: 'root', @@ -126,11 +144,12 @@ describe 'openstack-dashboard::apache2-server' do describe 'get secret with only one pem' do let(:key) { chef_run.file('/etc/ssl/private/horizon.pem') } - before do + cached(:chef_run) do node.override['openstack']['dashboard']['ssl'].tap do |ssl| ssl['cert_dir'] = ssl['key_dir'] = '/etc/ssl/private' ssl['cert'] = ssl['key'] = 'horizon.pem' end + runner.converge(described_recipe) end it do @@ -154,29 +173,35 @@ describe 'openstack-dashboard::apache2-server' do end it 'does not mess with certs if ssl not enabled' do - node.override['openstack']['dashboard']['use_ssl'] = false - node.override['openstack']['dashboard']['ssl']['chain'] = 'horizon-chain.pem' - expect(chef_run).not_to create_file('/etc/ssl/certs/horizon.pem') - expect(chef_run).not_to create_file('/etc/ssl/certs/horizon.key') - expect(chef_run).not_to create_file('/etc/ssl/certs/horizon-chain.pem') + expect(chef_run_no_ssl).not_to create_file('/etc/ssl/certs/horizon.pem') + expect(chef_run_no_ssl).not_to create_file('/etc/ssl/certs/horizon.key') + expect(chef_run_no_ssl).not_to create_file('/etc/ssl/certs/horizon-chain.pem') end end - describe 'get different secret' do + context 'get different secret' do let(:pem) { chef_run.file('/etc/anypath/any.pem') } let(:key) { chef_run.file('/etc/anypath/any.key') } - before do + cached(:chef_run) do node.override['openstack']['dashboard']['ssl']['cert_dir'] = '/etc/anypath' node.override['openstack']['dashboard']['ssl']['key_dir'] = '/etc/anypath' node.override['openstack']['dashboard']['ssl']['cert'] = 'any.pem' node.override['openstack']['dashboard']['ssl']['key'] = 'any.key' + node.override['openstack']['dashboard']['ssl']['chain'] = 'any-chain.pem' + runner.converge(described_recipe) + end + + before do allow_any_instance_of(Chef::Recipe).to receive(:secret) .with('certs', 'any.pem') .and_return('any_pem_value') allow_any_instance_of(Chef::Recipe).to receive(:secret) .with('certs', 'any.key') .and_return('any_key_value') + allow_any_instance_of(Chef::Recipe).to receive(:secret) + .with('certs', 'any-chain.pem') + .and_return('any_chain_pem_value') node.override['openstack']['dashboard'] end it 'create files and restarts apache' do @@ -195,14 +220,8 @@ describe 'openstack-dashboard::apache2-server' do expect(key).to notify('execute[restore-selinux-context]').to(:run) expect(pem).to notify('execute[restore-selinux-context]').to(:run) end - context 'set ssl chain' do + describe 'set ssl chain' do let(:chain) { chef_run.file('/etc/anypath/any-chain.pem') } - before do - node.override['openstack']['dashboard']['ssl']['chain'] = 'any-chain.pem' - allow_any_instance_of(Chef::Recipe).to receive(:secret) - .with('certs', 'any-chain.pem') - .and_return('any_chain_pem_value') - end it 'create files and restarts apache' do expect(chef_run).to create_file('/etc/anypath/any-chain.pem').with( content: 'any_chain_pem_value', @@ -214,17 +233,21 @@ describe 'openstack-dashboard::apache2-server' do end end it 'does not mess with certs if ssl not enabled' do - node.override['openstack']['dashboard']['use_ssl'] = false - expect(chef_run).not_to create_file('/etc/anypath/any.key') - expect(chef_run).not_to create_file('/etc/anypath/any.pem') - expect(chef_run).not_to create_file('/etc/anypath/any-chain.pem') + expect(chef_run_no_ssl).not_to create_file('/etc/anypath/any.key') + expect(chef_run_no_ssl).not_to create_file('/etc/anypath/any.pem') + expect(chef_run_no_ssl).not_to create_file('/etc/anypath/any-chain.pem') end - it 'does not create certs if certs data bag is disabled' do - node.override['openstack']['dashboard']['ssl']['use_data_bag'] = false - node.override['openstack']['dashboard']['ssl']['chain'] = 'horizon-chain.pem' - expect(chef_run).not_to create_file('/etc/ssl/certs/horizon.pem') - expect(chef_run).not_to create_file('/etc/ssl/certs/horizon.key') - expect(chef_run).not_to create_file('/etc/ssl/certs/horizon-chain.pem') + context 'does not create certs if certs data bag is disabled' do + cached(:chef_run) do + node.override['openstack']['dashboard']['ssl']['use_data_bag'] = false + node.override['openstack']['dashboard']['ssl']['chain'] = 'horizon-chain.pem' + runner.converge(described_recipe) + end + it do + expect(chef_run).not_to create_file('/etc/ssl/certs/horizon.pem') + expect(chef_run).not_to create_file('/etc/ssl/certs/horizon.key') + expect(chef_run).not_to create_file('/etc/ssl/certs/horizon-chain.pem') + end end end end @@ -246,100 +269,123 @@ describe 'openstack-dashboard::apache2-server' do ) end - context 'template content' do + describe 'template content' do let(:rewrite_ssl_directive) { /^\s*RewriteEngine On\s*RewriteCond \%\{HTTPS\} off$/ } let(:default_rewrite_rule) { %r(^\s*RewriteRule \^\(\.\*\)\$ https\://%\{HTTP_HOST\}%\{REQUEST_URI\} \[L,R\]$) } it 'has the default banner' do - node.override['openstack']['dashboard']['custom_template_banner'] = 'custom_template_banner_value' expect(chef_run).to render_file(file.name).with_content(/^custom_template_banner_value$/) end - context 'cache_html' do + describe 'cache_html' do it 'prevents html page caching' do - expect(chef_run).to render_file(file.name).with_content(%r{^\s*SetEnvIfExpr "req\('accept'\) =~/html/" NO_CACHE$}) - expect(chef_run).to render_file(file.name).with_content(/^\s*Header merge Cache-Control no-cache env=NO_CACHE$/) - expect(chef_run).to render_file(file.name).with_content(/^\s*Header merge Cache-Control no-store env=NO_CACHE$/) + expect(chef_run).to render_file(file.name) + .with_content(%r{^\s*SetEnvIfExpr "req\('accept'\) =~/html/" NO_CACHE$}) + expect(chef_run).to render_file(file.name) + .with_content(/^\s*Header merge Cache-Control no-cache env=NO_CACHE$/) + expect(chef_run).to render_file(file.name) + .with_content(/^\s*Header merge Cache-Control no-store env=NO_CACHE$/) end - it 'allows html page caching' do - node.override['openstack']['dashboard']['cache_html'] = true - expect(chef_run).not_to render_file(file.name).with_content(%r{^\s*SetEnvIfExpr "req\('accept'\) =~/html/" NO_CACHE$}) - expect(chef_run).not_to render_file(file.name).with_content(/^\s*Header merge Cache-Control no-cache env=NO_CACHE$/) - expect(chef_run).not_to render_file(file.name).with_content(/^\s*Header merge Cache-Control no-store env=NO_CACHE$/) + context 'allows html page caching' do + cached(:chef_run) do + node.override['openstack']['dashboard']['cache_html'] = true + runner.converge(described_recipe) + end + it do + expect(chef_run).not_to render_file(file.name) + .with_content(%r{^\s*SetEnvIfExpr "req\('accept'\) =~/html/" NO_CACHE$}) + expect(chef_run).not_to render_file(file.name) + .with_content(/^\s*Header merge Cache-Control no-cache env=NO_CACHE$/) + expect(chef_run).not_to render_file(file.name) + .with_content(/^\s*Header merge Cache-Control no-store env=NO_CACHE$/) + end end end it_should_behave_like 'virtualhost port configurator', 'dashboard-http-bind', 80 - context 'with use_ssl enabled' do - before do - node.override['openstack']['dashboard']['use_ssl'] = true - end - + describe 'with use_ssl enabled' do it_should_behave_like 'virtualhost port configurator', 'dashboard-https-bind', 443 it 'shows rewrite ssl directive' do expect(chef_run).to render_file(file.name).with_content(rewrite_ssl_directive) end - context 'rewrite rule' do + describe 'rewrite rule' do it 'shows the default SSL rewrite rule when http_port is 80 and https_port is 443' do - node.override['openstack']['bind_service']['dashboard_http']['port'] = 80 - node.override['openstack']['bind_service']['dashboard_https']['port'] = 443 expect(chef_run).to render_file(file.name).with_content(default_rewrite_rule) end - it 'shows the parameterized SSL rewrite rule when http_port is different from 80' do + context 'shows the parameterized SSL rewrite rule when http_port is different from 80' do https_port_value = 443 - node.override['openstack']['bind_service']['dashboard_http']['port'] = 81 - node.override['openstack']['bind_service']['dashboard_https']['port'] = https_port_value - expect(chef_run).to render_file(file.name) - .with_content(%r{^\s*RewriteRule \^\(\.\*\)\$ https://%\{SERVER_NAME\}:#{https_port_value}%\{REQUEST_URI\} \[L,R\]$}) + cached(:chef_run) do + node.override['openstack']['dashboard']['use_ssl'] = true + node.override['openstack']['bind_service']['dashboard_http']['port'] = 81 + node.override['openstack']['bind_service']['dashboard_https']['port'] = https_port_value + runner.converge(described_recipe) + end + it do + expect(chef_run).to render_file(file.name) + .with_content(%r{^\s*RewriteRule \^\(\.\*\)\$ https://%\{SERVER_NAME\}:#{https_port_value}%\{REQUEST_URI\} \[L,R\]$}) + end end - it 'shows the parameterized SSL rewrite rule when https_port is different from 443' do + context 'shows the parameterized SSL rewrite rule when https_port is different from 443' do https_port_value = 444 - node.override['openstack']['bind_service']['dashboard_http']['port'] = 80 - node.override['openstack']['bind_service']['dashboard_https']['port'] = https_port_value - expect(chef_run).to render_file(file.name) - .with_content(%r{^\s*RewriteRule \^\(\.\*\)\$ https://%\{SERVER_NAME\}:#{https_port_value}%\{REQUEST_URI\} \[L,R\]$}) + cached(:chef_run) do + node.override['openstack']['dashboard']['use_ssl'] = true + node.override['openstack']['bind_service']['dashboard_http']['port'] = 80 + node.override['openstack']['bind_service']['dashboard_https']['port'] = https_port_value + runner.converge(described_recipe) + end + it do + expect(chef_run).to render_file(file.name) + .with_content(%r{^\s*RewriteRule \^\(\.\*\)\$ https://%\{SERVER_NAME\}:#{https_port_value}%\{REQUEST_URI\} \[L,R\]$}) + end end end it 'shows ssl certificate related directives defaults' do - [/^\s*SSLEngine on$/, - %r{^\s*SSLCertificateFile /etc/ssl/certs/horizon.pem$}, - %r{^\s*SSLCertificateKeyFile /etc/ssl/private/horizon.key$}, - /^\s*SSLProtocol All -SSLv2 -SSLv3$/].each do |ssl_certificate_directive| + [ + /^\s*SSLEngine on$/, + %r{^\s*SSLCertificateFile /etc/ssl/certs/horizon.pem$}, + %r{^\s*SSLCertificateKeyFile /etc/ssl/private/horizon.key$}, + /^\s*SSLProtocol All -SSLv2 -SSLv3$/, + ].each do |ssl_certificate_directive| expect(chef_run).to render_file(file.name).with_content(ssl_certificate_directive) end - expect(chef_run).to_not render_file(file.name) - .with_content(/SSLCertificateChainFile/) + expect(chef_run).to_not render_file(file.name).with_content(/SSLCertificateChainFile/) end - context 'set ssl chain' do + describe 'set ssl chain' do it 'shows chain directive' do - node.override['openstack']['dashboard']['ssl']['chain'] = 'horizon-chain.pem' - expect(chef_run).to render_file(file.name) + expect(chef_run_chain).to render_file(file.name) .with_content(%r{^\s*SSLCertificateChainFile /etc/ssl/certs/horizon-chain.pem$}) end end context 'set use_data_bag to false' do - it 'shows ssl certificate related directives defaults' do + cached(:chef_run) do node.override['openstack']['dashboard']['ssl']['use_data_bag'] = false - [/^\s*SSLEngine on$/, - %r{^\s*SSLCertificateFile /etc/ssl/certs/horizon.pem$}, - %r{^\s*SSLCertificateKeyFile /etc/ssl/private/horizon.key$}, - /^\s*SSLProtocol All -SSLv2 -SSLv3$/].each do |ssl_certificate_directive| + runner.converge(described_recipe) + end + it 'shows ssl certificate related directives defaults' do + [ + /^\s*SSLEngine on$/, + %r{^\s*SSLCertificateFile /etc/ssl/certs/horizon.pem$}, + %r{^\s*SSLCertificateKeyFile /etc/ssl/private/horizon.key$}, + /^\s*SSLProtocol All -SSLv2 -SSLv3$/, + ].each do |ssl_certificate_directive| expect(chef_run).to render_file(file.name).with_content(ssl_certificate_directive) end - expect(chef_run).to_not render_file(file.name) - .with_content(/SSLCertificateChainFile/) + expect(chef_run).to_not render_file(file.name).with_content(/SSLCertificateChainFile/) end context 'set ssl chain' do - it 'shows chain directive' do + cached(:chef_run) do node.override['openstack']['dashboard']['ssl']['use_data_bag'] = false node.override['openstack']['dashboard']['ssl']['chain'] = 'horizon-chain.pem' + runner.converge(described_recipe) + end + it 'shows chain directive' do expect(chef_run).to render_file(file.name) .with_content(%r{^\s*SSLCertificateChainFile /etc/ssl/certs/horizon-chain.pem$}) end @@ -350,6 +396,15 @@ describe 'openstack-dashboard::apache2-server' do end # noinspection CookbookSourceRoot context 'override attributes' do + cached(:chef_run) do + node.override['openstack']['dashboard']['ssl']['cert'] = 'ssl.cert' + node.override['openstack']['dashboard']['ssl']['key'] = 'ssl.key' + node.override['openstack']['dashboard']['ssl']['cert_dir'] = 'ssl_dir_value/certs' + node.override['openstack']['dashboard']['ssl']['key_dir'] = 'ssl_dir_value/private' + node.override['openstack']['dashboard']['ssl']['protocol'] = 'ssl_protocol_value' + node.override['openstack']['dashboard']['ssl']['ciphers'] = 'ssl_ciphers_value' + runner.converge(described_recipe) + end before do allow_any_instance_of(Chef::Recipe).to receive(:secret) .with('certs', 'ssl.cert') @@ -357,129 +412,155 @@ describe 'openstack-dashboard::apache2-server' do allow_any_instance_of(Chef::Recipe).to receive(:secret) .with('certs', 'ssl.key') .and_return('ssl_key_value') - node.override['openstack']['dashboard']['ssl']['cert'] = 'ssl.cert' - node.override['openstack']['dashboard']['ssl']['key'] = 'ssl.key' - node.override['openstack']['dashboard']['ssl']['cert_dir'] = 'ssl_dir_value/certs' - node.override['openstack']['dashboard']['ssl']['key_dir'] = 'ssl_dir_value/private' - node.override['openstack']['dashboard']['ssl']['protocol'] = 'ssl_protocol_value' - node.override['openstack']['dashboard']['ssl']['ciphers'] = 'ssl_ciphers_value' end it 'shows ssl related directives overrides' do - [/^\s*SSLEngine on$/, - %r{^\s*SSLCertificateFile ssl_dir_value/certs/ssl.cert$}, - %r{^\s*SSLCertificateKeyFile ssl_dir_value/private/ssl.key$}, - /^\s*SSLProtocol ssl_protocol_value$/, - /^\s*SSLCipherSuite ssl_ciphers_value$/].each do |ssl_directive| + [ + /^\s*SSLEngine on$/, + %r{^\s*SSLCertificateFile ssl_dir_value/certs/ssl.cert$}, + %r{^\s*SSLCertificateKeyFile ssl_dir_value/private/ssl.key$}, + /^\s*SSLProtocol ssl_protocol_value$/, + /^\s*SSLCipherSuite ssl_ciphers_value$/, + ].each do |ssl_directive| expect(chef_run).to render_file(file.name).with_content(ssl_directive) end - expect(chef_run).to_not render_file(file.name) - .with_content(/SSLCertificateChainFile/) + expect(chef_run).to_not render_file(file.name).with_content(/SSLCertificateChainFile/) end end end context 'with use_ssl disabled' do - before do + cached(:chef_run) do node.override['openstack']['dashboard']['use_ssl'] = false + runner.converge(described_recipe) end it 'does not show rewrite ssl directive' do expect(chef_run).not_to render_file(file.name).with_content(rewrite_ssl_directive) end - it 'does not show the default rewrite rule' do - node.override['openstack']['endpoints']['dashboard-http-bind']['port'] = 80 - node.override['openstack']['endpoints']['dashboard-https-bind']['port'] = 443 - expect(chef_run).not_to render_file(file.name).with_content(default_rewrite_rule) + context 'does not show the default rewrite rule' do + cached(:chef_run) do + node.override['openstack']['dashboard']['use_ssl'] = false + node.override['openstack']['endpoints']['dashboard-http-bind']['port'] = 80 + node.override['openstack']['endpoints']['dashboard-https-bind']['port'] = 443 + runner.converge(described_recipe) + end + it do + expect(chef_run).not_to render_file(file.name).with_content(default_rewrite_rule) + end end it 'does not show ssl certificate related directives' do - [/^\s*SSLEngine on$/, - /^\s*SSLCertificateFile/, - /^\s*SSLCertificateKeyFile/].each do |ssl_certificate_directive| + [ + /^\s*SSLEngine on$/, + /^\s*SSLCertificateFile/, + /^\s*SSLCertificateKeyFile/, + ].each do |ssl_certificate_directive| expect(chef_run).not_to render_file(file.name).with_content(ssl_certificate_directive) end - expect(chef_run).to_not render_file(file.name) - .with_content(/SSLCertificateChainFile/) + expect(chef_run).to_not render_file(file.name).with_content(/SSLCertificateChainFile/) end end it 'shows the ServerAdmin' do - node.override['apache']['contact'] = 'apache_contact_value' expect(chef_run).to render_file(file.name).with_content(/\s*ServerAdmin apache_contact_value$/) end it 'sets the WSGI script alias defaults' do - expect(chef_run).to render_file(file.name).with_content(%r{^\s*WSGIScriptAlias / /usr/share/openstack-dashboard/openstack_dashboard/wsgi.py$}) - end - - it 'sets the WSGI script alias' do - node.override['openstack']['dashboard']['wsgi_path'] = 'wsgi_path_value' - node.override['openstack']['dashboard']['webroot'] = 'root' - expect(chef_run).to render_file(file.name).with_content(/^\s*WSGIScriptAlias root wsgi_path_value$/) - end - - it 'sets the WSGI daemon process' do - node.override['openstack']['dashboard']['horizon_user'] = 'horizon_user_value' - node.override['openstack']['dashboard']['horizon_group'] = 'horizon_group_value' - node.override['openstack']['dashboard']['dash_path'] = 'dash_path_value' - expect(chef_run).to render_file(file.name).with_content( - /^\s*WSGIDaemonProcess dashboard user=horizon_user_value group=horizon_group_value processes=3 threads=10 python-path=dash_path_value$/ - ) - end - - it 'has the default DocRoot' do - node.override['openstack']['dashboard']['dash_path'] = 'dash_path_value' expect(chef_run).to render_file(file.name) - .with_content(%r{\s*DocumentRoot dash_path_value/.blackhole/$}) + .with_content(%r{^\s*WSGIScriptAlias / /usr/share/openstack-dashboard/openstack_dashboard/wsgi.py$}) end - it 'has TraceEnable set' do - node.override['openstack']['dashboard']['traceenable'] = 'value' - expect(chef_run).to render_file(file.name) - .with_content(/^ TraceEnable value$/) - end - - it 'sets the right Alias path for /static' do - node.override['openstack']['dashboard']['static_path'] = 'static_path_value' - expect(chef_run).to render_file(file.name).with_content(%r{^\s+Alias /static static_path_value$}) - end - - %w(dash_path static_path).each do |dir_attribute| - it "sets the #{dir_attribute} directory directive" do - node.override['openstack']['dashboard'][dir_attribute] = "#{dir_attribute}_value" - expect(chef_run).to render_file(file.name).with_content(/^\s*$/) + context 'sets the WSGI script alias' do + cached(:chef_run) do + node.override['openstack']['dashboard']['wsgi_path'] = 'wsgi_path_value' + node.override['openstack']['dashboard']['webroot'] = 'root' + runner.converge(described_recipe) + end + it do + expect(chef_run).to render_file(file.name).with_content(/^\s*WSGIScriptAlias root wsgi_path_value$/) end end - context 'directory options' do + context 'sets the WSGI daemon process' do + cached(:chef_run) do + node.override['openstack']['dashboard']['horizon_user'] = 'horizon_user_value' + node.override['openstack']['dashboard']['horizon_group'] = 'horizon_group_value' + node.override['openstack']['dashboard']['dash_path'] = 'dash_path_value' + runner.converge(described_recipe) + end + it do + expect(chef_run).to render_file(file.name).with_content( + /^\s*WSGIDaemonProcess dashboard user=horizon_user_value group=horizon_group_value processes=3 threads=10 python-path=dash_path_value$/ + ) + end + end + + context 'has the default DocRoot' do + cached(:chef_run) do + node.override['openstack']['dashboard']['dash_path'] = 'dash_path_value' + runner.converge(described_recipe) + end + it do + expect(chef_run).to render_file(file.name).with_content(%r{\s*DocumentRoot dash_path_value/.blackhole/$}) + end + end + + it 'has TraceEnable set' do + expect(chef_run).to render_file(file.name).with_content(/^ TraceEnable value$/) + end + + context 'sets the right Alias path for /static' do + cached(:chef_run) do + node.override['openstack']['dashboard']['static_path'] = 'static_path_value' + runner.converge(described_recipe) + end + it do + expect(chef_run).to render_file(file.name).with_content(%r{^\s+Alias /static static_path_value$}) + end + end + + context 'sets the directory directive' do + cached(:chef_run) do + %w(dash_path static_path).each do |dir_attribute| + node.override['openstack']['dashboard'][dir_attribute] = "#{dir_attribute}_value" + end + runner.converge(described_recipe) + end + %w(dash_path static_path).each do |dir_attribute| + it do + expect(chef_run).to render_file(file.name).with_content(/^\s*$/) + end + end + end + + describe 'directory options' do it 'sets default options for apache 2.4' do expect(chef_run).to render_file(file.name).with_content(/^\s*Require all granted$/) end end - context 'log directives' do - before do - node.override['apache']['log_dir'] = 'log_dir_value' - end - - it 'sets de ErrorLog directive' do - node.override['openstack']['dashboard']['error_log'] = 'error_log_value' + describe 'log directives' do + it 'sets the ErrorLog directive' do expect(chef_run).to render_file(file.name).with_content(%r{^\s*ErrorLog log_dir_value/error_log_value$}) end - it 'sets de CustomLog directive' do - node.override['openstack']['dashboard']['access_log'] = 'access_log_value' - expect(chef_run).to render_file(file.name).with_content(%r{^\s*CustomLog log_dir_value/access_log_value combined$}) + it 'sets the CustomLog directive' do + expect(chef_run).to render_file(file.name) + .with_content(%r{^\s*CustomLog log_dir_value/access_log_value combined$}) end end - it 'sets wsgi socket prefix if wsgi_socket_prefix attribute is preset' do - node.override['openstack']['dashboard']['wsgi_socket_prefix'] = '/var/run/wsgi' - expect(chef_run).to render_file(file.name).with_content(%r{^WSGISocketPrefix /var/run/wsgi$}) + context 'sets wsgi socket prefix if wsgi_socket_prefix attribute is preset' do + cached(:chef_run) do + node.override['openstack']['dashboard']['wsgi_socket_prefix'] = '/var/run/wsgi' + runner.converge(described_recipe) + end + it do + expect(chef_run).to render_file(file.name).with_content(%r{^WSGISocketPrefix /var/run/wsgi$}) + end end it 'omits wsgi socket prefix if wsgi_socket_prefix attribute is not preset' do - node.override['openstack']['dashboard']['wsgi_socket_prefix'] = nil expect(chef_run).not_to render_file(file.name).with_content(/^WSGISocketPrefix $/) end end @@ -506,26 +587,28 @@ describe 'openstack-dashboard::apache2-server' do expect(file).not_to notify('service[apache2]').to(:restart) end - it 'has configurable path and ownership settings' do - node.override['openstack']['dashboard']['secret_key_path'] = 'somerandompath' - node.override['openstack']['dashboard']['horizon_user'] = 'somerandomuser' - node.override['openstack']['dashboard']['horizon_group'] = 'somerandomgroup' - file = chef_run.file('somerandompath') - expect(file.owner).to eq('somerandomuser') - expect(file.group).to eq('somerandomgroup') - end - - describe 'secret_key_content set' do - before do + context 'has configurable path and ownership settings' do + cached(:chef_run) do + node.override['openstack']['dashboard']['secret_key_path'] = 'somerandompath' + node.override['openstack']['dashboard']['horizon_user'] = 'somerandomuser' + node.override['openstack']['dashboard']['horizon_group'] = 'somerandomgroup' node.override['openstack']['dashboard']['secret_key_content'] = 'somerandomcontent' + runner.converge(described_recipe) + end + it do + file = chef_run.file('somerandompath') + expect(file.owner).to eq('somerandomuser') + expect(file.group).to eq('somerandomgroup') end - it 'has configurable secret_key_content setting' do - expect(chef_run).to render_file(file.name).with_content('somerandomcontent') - end + describe 'secret_key_content set' do + it 'has configurable secret_key_content setting' do + expect(chef_run).to render_file('somerandompath').with_content('somerandomcontent') + end - it 'notifies apache2 restart when secret_key_content set' do - expect(file).to notify('service[apache2]').to(:restart) + it 'notifies apache2 restart when secret_key_content set' do + expect(chef_run.file('somerandompath')).to notify('service[apache2]').to(:restart) + end end end end @@ -567,7 +650,6 @@ describe 'openstack-dashboard::apache2-server' do it 'does not execute restore-selinux-context' do cmd = 'restorecon -Rv /etc/httpd /etc/pki; chcon -R -t httpd_sys_content_t /usr/share/openstack-dashboard || :' - expect(chef_run).not_to run_execute(cmd) end end diff --git a/spec/horizon-redhat_spec.rb b/spec/horizon-redhat_spec.rb index 5fee291..1142ab5 100644 --- a/spec/horizon-redhat_spec.rb +++ b/spec/horizon-redhat_spec.rb @@ -5,7 +5,7 @@ describe 'openstack-dashboard::horizon' do describe 'redhat' do let(:runner) { ChefSpec::SoloRunner.new(REDHAT_OPTS) } let(:node) { runner.node } - let(:chef_run) do + cached(:chef_run) do runner.converge(described_recipe) end diff --git a/spec/horizon_spec.rb b/spec/horizon_spec.rb index 788d9a8..7180e57 100644 --- a/spec/horizon_spec.rb +++ b/spec/horizon_spec.rb @@ -5,11 +5,51 @@ describe 'openstack-dashboard::horizon' do describe 'ubuntu' do let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) } let(:node) { runner.node } - let(:chef_run) do + cached(:chef_run) do + node.override['openstack']['dashboard']['custom_template_banner'] = 'custom_template_banner_value' + node.override['openstack']['dashboard']['allowed_hosts'] = ['dashboard.example.net'] + node.override['openstack']['dashboard']['ssl_cacert'] = '/path_to_cacert.pem' + node.override['openstack']['dashboard']['identity_api_version'] = 'identity_api_version_value' + node.override['openstack']['dashboard']['volume_api_version'] = 'volume_api_version_value' + node.override['openstack']['dashboard']['keystone_default_domain'] = 'keystone_default_domain_value' + node.override['openstack']['dashboard']['console_type'] = 'console_type_value' + node.override['openstack']['dashboard']['help_url'] = 'help_url_value' + node.override['openstack']['dashboard']['password_autocomplete'] = 'password_autocomplete_value' + node.override['openstack']['dashboard']['secret_key_path'] = 'secret_key_path_value' + node.override['openstack']['dashboard']['use_ssl'] = true + node.override['openstack']['dashboard']['keystone_backend']['name'] = 'native' + node.override['openstack']['dashboard']['misc_local_settings'] = { + 'CUSTOM_CONFIG_A' => { + 'variable1' => 'value1', + 'variable2' => 'value2', + }, + 'CUSTOM_CONFIG_B' => { + 'variable1' => 'value1', + 'variable2' => 'value2', + }, + } runner.converge(described_recipe) end - let(:chef_run_session_sql) do + cached(:chef_run2) do + node.override['openstack']['dashboard']['debug'] = true + node.override['openstack']['dashboard']['ssl_no_verify'] = 'False' + node.override['openstack']['dashboard']['use_ssl'] = false + node.override['openstack']['dashboard']['ssl_offload'] = false + node.override['openstack']['dashboard']['file_upload_temp_dir'] = '/foobar' + node.override['openstack']['dashboard']['keystone_multidomain_support'] = true + node.override['openstack']['dashboard']['simple_ip_management'] = true + node.override['openstack']['dashboard']['session_backend'] = 'file' + node.override['openstack']['dashboard']['keystone_default_role'] = 'keystone_default_role_value' + node.override['openstack']['dashboard']['keystone_backend']['name'] = 'ldap' + node.override['openstack']['dashboard']['neutron']['enable_quotas'] = false + node.override['openstack']['dashboard']['neutron']['enable_lb'] = true + node.override['openstack']['dashboard']['plugins'] = %w(testPlugin1 testPlugin2) + node.override['openstack']['db']['dashboard']['migrate'] = false + runner.converge(described_recipe) + end + + cached(:chef_run_sql) do node.override['openstack']['dashboard']['session_backend'] = 'sql' runner.converge(described_recipe) end @@ -41,62 +81,40 @@ describe 'openstack-dashboard::horizon' do expect(file).to notify('service[apache2]').to(:restart).delayed end - context 'template contents' do + describe 'template contents' do it 'has the customer banner' do - node.override['openstack']['dashboard']['custom_template_banner'] = 'custom_template_banner_value' expect(chef_run).to render_file(file.name).with_content(/^custom_template_banner_value$/) end - context 'misc settings' do - before do - node.override['openstack']['dashboard']['misc_local_settings'] = { - 'CUSTOM_CONFIG_A' => { - 'variable1' => 'value1', - 'variable2' => 'value2', - }, - 'CUSTOM_CONFIG_B' => { - 'variable1' => 'value1', - 'variable2' => 'value2', - }, - } - end - - it 'sets misc settings properly' do - [ - ['CUSTOM_CONFIG_A = {', - ' \'variable1\': \'value1\',', - ' \'variable2\': \'value2\',', - '}'], - ['CUSTOM_CONFIG_B = {', - ' \'variable1\': \'value1\',', - ' \'variable2\': \'value2\',', - '}'], - ].each do |content| - expect(chef_run).to render_file(file.name).with_content(build_section(content)) - end + it 'sets misc settings properly' do + [ + ['CUSTOM_CONFIG_A = {', + ' \'variable1\': \'value1\',', + ' \'variable2\': \'value2\',', + '}', + ], + ['CUSTOM_CONFIG_B = {', + ' \'variable1\': \'value1\',', + ' \'variable2\': \'value2\',', + '}', + ], + ].each do |content| + expect(chef_run).to render_file(file.name).with_content(build_section(content)) end end - context 'debug setting' do - context 'set to true' do - before do - node.override['openstack']['dashboard']['debug'] = true - end - + describe 'debug setting' do + describe 'set to true' do it 'has a true value for the DEBUG attribute' do - expect(chef_run).to render_file(file.name).with_content(/^DEBUG = True$/) + expect(chef_run2).to render_file(file.name).with_content(/^DEBUG = True$/) end it 'sets the console logging level to DEBUG' do - expect(chef_run).to render_file(file.name).with_content(/^\s*'level': 'DEBUG',$/) + expect(chef_run2).to render_file(file.name).with_content(/^\s*'level': 'DEBUG',$/) end end - context 'set to false' do - before do - node.override['openstack']['dashboard']['debug'] = false - end - + describe 'set to false' do it 'has a false value for the DEBUG attribute' do expect(chef_run).to render_file(file.name).with_content(/^DEBUG = False$/) end @@ -107,108 +125,98 @@ describe 'openstack-dashboard::horizon' do end end - context 'config ssl_no_verify' do - context 'set to the default value' do + describe 'config ssl_no_verify' do + describe 'set to the default value' do it 'has a True value for the OPENSTACK_SSL_NO_VERIFY attribute' do expect(chef_run).to render_file(file.name).with_content(/^OPENSTACK_SSL_NO_VERIFY = True$/) end end context 'set to False' do - before do + cached(:chef_run) do + node.override['openstack']['dashboard']['use_ssl'] = true node.override['openstack']['dashboard']['ssl_no_verify'] = 'False' + runner.converge(described_recipe) end - it 'has a False value for the OPENSTACK_SSL_NO_VERIFY attribute' do expect(chef_run).to render_file(file.name).with_content(/^OPENSTACK_SSL_NO_VERIFY = False$/) end end - context 'not set when ssl disabled' do + describe 'not set when ssl disabled' do it 'has a True value for the OPENSTACK_SSL_NO_VERIFY attribute' do - node.override['openstack']['dashboard']['use_ssl'] = false - expect(chef_run).not_to render_file(file.name).with_content(/^OPENSTACK_SSL_NO_VERIFY = True$/) + expect(chef_run2).not_to render_file(file.name).with_content(/^OPENSTACK_SSL_NO_VERIFY = True$/) end end end it 'config ssl_cacert' do - node.override['openstack']['dashboard']['ssl_cacert'] = '/path_to_cacert.pem' expect(chef_run).to render_file(file.name).with_content(%r{^OPENSTACK_SSL_CACERT = '/path_to_cacert.pem'$}) end it 'does not config ssl_cacert when ssl disabled' do - node.override['openstack']['dashboard']['use_ssl'] = false - node.override['openstack']['dashboard']['ssl_cacert'] = '/path_to_cacert.pem' - expect(chef_run).not_to render_file(file.name).with_content(%r{^OPENSTACK_SSL_CACERT = '/path_to_cacert.pem'$}) + expect(chef_run2).not_to render_file(file.name) + .with_content(%r{^OPENSTACK_SSL_CACERT = '/path_to_cacert.pem'$}) end it 'has some allowed hosts set' do - node.override['openstack']['dashboard']['allowed_hosts'] = ['dashboard.example.net'] expect(chef_run).to render_file(file.name).with_content(/^ALLOWED_HOSTS = \["dashboard.example.net"\]$/) end - context 'ssl offload' do + describe 'ssl offload' do let(:secure_proxy_string) { 'SECURE_PROXY_SSL_HEADER = \(\'HTTP_X_FORWARDED_PROTOCOL\', \'https\'\)' } - it 'does not configure ssl proxy when ssl_offload is false' do - node.override['openstack']['dashboard']['ssl_offload'] = false - expect(chef_run).not_to render_file(file.name).with_content(/^#{secure_proxy_string}$/) - end it 'configures ssl proxy when ssl_offload is set to true' do - node.override['openstack']['dashboard']['ssl_offload'] = true expect(chef_run).to render_file(file.name).with_content(/^#{secure_proxy_string}$/) end + + it 'does not configure ssl proxy when ssl_offload is false' do + expect(chef_run2).not_to render_file(file.name).with_content(/^#{secure_proxy_string}$/) + end end - context 'temp dir override' do - context 'temp dir is nil' do + describe 'temp dir override' do + describe 'temp dir is nil' do it 'does not override temp dir when it is nil' do - node.override['openstack']['dashboard']['file_upload_temp_dir'] = nil expect(chef_run).not_to render_file(file.name).with_content(/^FILE_UPLOAD_TEMP_DIR =/) end it 'does override temp dir when it is not nil' do - node.override['openstack']['dashboard']['file_upload_temp_dir'] = '/foobar' - expect(chef_run).to render_file(file.name).with_content(%r{^FILE_UPLOAD_TEMP_DIR = "/foobar"$}) + expect(chef_run2).to render_file(file.name).with_content(%r{^FILE_UPLOAD_TEMP_DIR = "/foobar"$}) end end end - context 'ssl settings' do - context 'use_ssl enabled' do - before do - node.override['openstack']['dashboard']['use_ssl'] = true + describe 'ssl settings' do + describe 'use_ssl enabled' do + it 'sets secure csrf cookie to true when the attribute is enabled' do + expect(chef_run).to render_file(file.name).with_content(/^CSRF_COOKIE_SECURE = True$/) end - context 'csrf_cookie_secure setting' do - it 'sets secure csrf cookie to true when the attribute is enabled' do - node.override['openstack']['dashboard']['csrf_cookie_secure'] = true - expect(chef_run).to render_file(file.name).with_content(/^CSRF_COOKIE_SECURE = True$/) - end + it 'set secure csrf cookie to true when the attribute is enabled' do + expect(chef_run).to render_file(file.name).with_content(/^SESSION_COOKIE_SECURE = True$/) + end - it 'sets secure csrf cookie to false when the attribute is disabled' do + context 'sets secure csrf & session cookie to false when the attribute is disabled' do + cached(:chef_run) do node.override['openstack']['dashboard']['csrf_cookie_secure'] = false + node.override['openstack']['dashboard']['session_cookie_secure'] = false + runner.converge(described_recipe) + end + it do expect(chef_run).to render_file(file.name).with_content(/^CSRF_COOKIE_SECURE = False$/) end - end - - context 'session_cookie_secure setting' do - it 'set secure csrf cookie to true when the sttribute is enabled' do - node.override['openstack']['dashboard']['session_cookie_secure'] = true - expect(chef_run).to render_file(file.name).with_content(/^SESSION_COOKIE_SECURE = True$/) - end - - it 'set secure csrf cookie to false when the sttribute is disabled' do - node.override['openstack']['dashboard']['session_cookie_secure'] = false + it do expect(chef_run).to render_file(file.name).with_content(/^SESSION_COOKIE_SECURE = False$/) end end end it 'does not set secure csrf nor secure session cookie settings when use_ssl is disabled' do - node.override['openstack']['dashboard']['use_ssl'] = false - [/^CSRF_COOKIE_SECURE$/, /^SESSION_COOKIE_SECURE$/].each do |setting| - expect(chef_run).not_to render_file(file.name).with_content(setting) + [ + /^CSRF_COOKIE_SECURE$/, + /^SESSION_COOKIE_SECURE$/, + ].each do |setting| + expect(chef_run2).not_to render_file(file.name).with_content(setting) end end end @@ -232,10 +240,8 @@ describe 'openstack-dashboard::horizon' do .with_content(%r{^POLICY_FILES_PATH = '/usr/share/openstack-dashboard/openstack_dashboard/conf'$}) end - context 'identity and volume api version setting' do + describe 'identity and volume api version setting' do it 'is configurable directly' do - node.override['openstack']['dashboard']['identity_api_version'] = 'identity_api_version_value' - node.override['openstack']['dashboard']['volume_api_version'] = 'volume_api_version_value' [ /^\s*"identity": identity_api_version_value,$/, /^\s*"volume": volume_api_version_value$/, @@ -245,30 +251,26 @@ describe 'openstack-dashboard::horizon' do end end - context 'keystone multidomain support' do + describe 'keystone multidomain support' do it 'sets to true when the attribute is enabled' do - node.override['openstack']['dashboard']['keystone_multidomain_support'] = true - expect(chef_run).to render_file(file.name).with_content(/^OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True$/) + expect(chef_run2).to render_file(file.name).with_content(/^OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True$/) end - it 'sets to false when the attribute is disabled' do - node.override['openstack']['dashboard']['keystone_multidomain_support'] = false - expect(chef_run).to render_file(file.name).with_content(/^OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = False$/) + expect(chef_run).to render_file(file.name) + .with_content(/^OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = False$/) end end it 'has a keystone default domain setting' do - node.override['openstack']['dashboard']['keystone_default_domain'] = 'keystone_default_domain_value' - expect(chef_run).to render_file(file.name).with_content(/^OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = "keystone_default_domain_value"$/) + expect(chef_run).to render_file(file.name) + .with_content(/^OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = "keystone_default_domain_value"$/) end it 'has a console_type setting' do - node.override['openstack']['dashboard']['console_type'] = 'console_type_value' expect(chef_run).to render_file(file.name).with_content(/^CONSOLE_TYPE = "console_type_value"$/) end it 'has a help_url setting' do - node.override['openstack']['dashboard']['help_url'] = 'help_url_value' expect(chef_run).to render_file(file.name).with_content(/\s*'help_url': "help_url_value",$/) end @@ -277,153 +279,202 @@ describe 'openstack-dashboard::horizon' do expect(chef_run).not_to render_file(file.name).with_content(/\s*'default_dashboard':/) end - context 'simple ip management' do - it 'enables the setting when the attribute is set' do - node.override['openstack']['dashboard']['simple_ip_management'] = true - expect(chef_run).to render_file(file.name).with_content('HORIZON_CONFIG["simple_ip_management"] = True') - end - + describe 'simple ip management' do it 'disables the setting when the attribute is not set' do - node.override['openstack']['dashboard']['simple_ip_management'] = false expect(chef_run).to render_file(file.name).with_content('HORIZON_CONFIG["simple_ip_management"] = False') end + it 'enables the setting when the attribute is set' do + expect(chef_run2).to render_file(file.name).with_content('HORIZON_CONFIG["simple_ip_management"] = True') + end end it 'has default password_autocomplete setting' do - node.override['openstack']['dashboard']['password_autocomplete'] = 'password_autocomplete_value' - expect(chef_run).to render_file(file.name).with_content(/^HORIZON_CONFIG\["password_autocomplete"\] = "password_autocomplete_value"$/) + expect(chef_run).to render_file(file.name) + .with_content(/^HORIZON_CONFIG\["password_autocomplete"\] = "password_autocomplete_value"$/) end it 'has configurable secret_key_path setting' do - node.override['openstack']['dashboard']['secret_key_path'] = 'secret_key_path_value' - expect(chef_run).to render_file(file.name).with_content(/^SECRET_KEY = secret_key.generate_or_read_from_file\(os.path.realpath\('secret_key_path_value'\)\)$/) + expect(chef_run).to render_file(file.name) + .with_content( + /^SECRET_KEY = secret_key.generate_or_read_from_file\(os.path.realpath\('secret_key_path_value'\)\)$/ + ) end - context 'session backend' do - it 'sets the session engine to file when it is the session backend' do - node.override['openstack']['dashboard']['session_backend'] = 'file' - expect(chef_run).to render_file(file.name).with_content(/^SESSION_ENGINE = 'django.contrib.sessions.backends.file'$/) + describe 'session backend' do + describe 'file as session backend' do + it 'sets the session engine to file when it is the session backend' do + expect(chef_run2).to render_file(file.name) + .with_content(/^SESSION_ENGINE = 'django.contrib.sessions.backends.file'$/) + end end - context 'memcached as session backend' do + describe 'memcached as session backend' do let(:memcached_session_engine_setting) { /^SESSION_ENGINE = 'django.contrib.sessions.backends.cache'$/ } - context 'with memcache servers' do + describe 'with memcache servers' do it 'sets the session engine attribute' do expect(chef_run).to render_file(file.name).with_content(memcached_session_engine_setting) end it 'sets the location of the caches to the memcached servers addresses' do - expect(chef_run).to render_file(file.name).with_content(/^\s*'LOCATION': \[\s*'hostA:port',\s*'hostB:port',\s*\]$/) + expect(chef_run).to render_file(file.name) + .with_content(/^\s*'LOCATION': \[\s*'hostA:port',\s*'hostB:port',\s*\]$/) end end - context 'without memcache servers' do - [nil, []].each do |empty_value| + [nil, []].each do |empty_value| + context 'without memcache servers' do + cached(:chef_run) do + allow_any_instance_of(Chef::Recipe).to receive(:memcached_servers).and_return(empty_value) + runner.converge(described_recipe) + end it "does not configure caching when backend == memcache and #{empty_value} provided as memcache servers" do - allow_any_instance_of(Chef::Recipe).to receive(:memcached_servers) - .and_return(empty_value) - - expect(chef_run).not_to render_file(file.name) - .with_content(memcached_session_engine_setting) + expect(chef_run).to_not render_file(file.name) + .with_content(/^\s*'LOCATION': \[\s*'hostA:port',\s*'hostB:port',\s*\]$/) end end end end it 'sets the session engine to db when sql is the session backend' do - node.override['openstack']['dashboard']['session_backend'] = 'sql' - expect(chef_run).to render_file(file.name).with_content(/^SESSION_ENGINE = 'django.contrib.sessions.backends.db'$/) + expect(chef_run_sql).to render_file(file.name) + .with_content(/^SESSION_ENGINE = 'django.contrib.sessions.backends.db'$/) end end it 'has a keystone url' do - expect(chef_run).to render_file(file.name).with_content(%r{OPENSTACK_KEYSTONE_URL = "http://127.0.0.1:5000/v3"}) + expect(chef_run).to render_file(file.name) + .with_content(%r{OPENSTACK_KEYSTONE_URL = "http://127.0.0.1:5000/v3"}) end it 'has a keystone default role' do - node.override['openstack']['dashboard']['keystone_default_role'] = 'keystone_default_role_value' - expect(chef_run).to render_file(file.name).with_content(/^OPENSTACK_KEYSTONE_DEFAULT_ROLE = "keystone_default_role_value"$/) + expect(chef_run2).to render_file(file.name) + .with_content(/^OPENSTACK_KEYSTONE_DEFAULT_ROLE = "keystone_default_role_value"$/) end - context 'keystone_backend settings' do - %w(native ldap).each do |keystone_backend_name| - it "sets the backend name to #{keystone_backend_name}" do - node.override['openstack']['dashboard']['keystone_backend']['name'] = keystone_backend_name - expect(chef_run).to render_file(file.name).with_content(/^\s*'name': '#{keystone_backend_name}',$/) - end - end + it 'sets the backend name to native' do + expect(chef_run).to render_file(file.name).with_content(/^\s*'name': 'native',$/) + end - %w(can_edit_user can_edit_group can_edit_project can_edit_domain can_edit_role).each do |keystone_setting| - it "enables the #{keystone_setting} keystone backend setting when the attribute is True" do + it 'sets the backend name to ldap' do + expect(chef_run2).to render_file(file.name).with_content(/^\s*'name': 'ldap',$/) + end + + keystone_settings = %w(can_edit_user can_edit_group can_edit_project can_edit_domain can_edit_role) + context 'enables the keystone backend settings when the attribute is True' do + cached(:chef_run) do + keystone_settings.each do |keystone_setting| node.override['openstack']['dashboard']['keystone_backend'][keystone_setting] = true + end + runner.converge(described_recipe) + end + keystone_settings.each do |keystone_setting| + it do expect(chef_run).to render_file(file.name).with_content(/^\s*\'#{keystone_setting}\': True,$/) end + end + end - it "disables the #{keystone_setting} keystone backend setting when the attribute is False" do + context 'disables the keystone backend settings when the attribute is False' do + cached(:chef_run) do + keystone_settings.each do |keystone_setting| node.override['openstack']['dashboard']['keystone_backend'][keystone_setting] = false + end + runner.converge(described_recipe) + end + keystone_settings.each do |keystone_setting| + it do expect(chef_run).to render_file(file.name).with_content(/^\s*\'#{keystone_setting}\': False,$/) end end end - context 'neutron settings' do + describe 'neutron settings' do it 'enables the enable_quotas setting when the attributes is True' do - node.override['openstack']['dashboard']['neutron']['enable_quotas'] = true expect(chef_run).to render_file(file.name).with_content(/^\s*'enable_quotas': True,$/) end it 'disables the enable_quotas setting when the attributes is False' do - node.override['openstack']['dashboard']['neutron']['enable_quotas'] = false - expect(chef_run).to render_file(file.name).with_content(/^\s*'enable_quotas': False,$/) + expect(chef_run2).to render_file(file.name).with_content(/^\s*'enable_quotas': False,$/) end - context 'lbaas setting' do + + describe 'lbaas setting' do it 'enables the enable_lb setting when the attribute is true' do - node.override['openstack']['dashboard']['neutron']['enable_lb'] = true - expect(chef_run).to render_file(file.name).with_content(/^\s*'enable_lb': True,$/) + expect(chef_run2).to render_file(file.name).with_content(/^\s*'enable_lb': True,$/) end - it 'disables the enable_lb setting when the attribute is falase' do - node.override['openstack']['dashboard']['neutron']['enable_lb'] = false + it 'disables the enable_lb setting when the attribute is false' do expect(chef_run).to render_file(file.name).with_content(/^\s*'enable_lb': False,$/) end end end - %w(horizon openstack_dashboard novaclient cinderclient keystoneclient - glanceclient neutronclient heatclient ceilometerclient troveclient - swiftclient openstack_auth nose.plugins.manager django).each do |component| - it "sets the logger level for #{component}" do - node.override['openstack']['dashboard']['log_level'][component] = "#{component}_log_level_value" - expect(chef_run).to render_file(file.name).with_content( - /^\s*'#{component}': {\s*'handlers': \['console'\],\s*'level': '#{component}_log_level_value',$/ - ) + context 'sets the logger level for components' do + components = %w( + ceilometerclient + cinderclient + django + glanceclient + heatclient + horizon + keystoneclient + neutronclient + nose.plugins.manager + novaclient + openstack_auth + openstack_dashboard + swiftclient + troveclient + ) + cached(:chef_run) do + components.each do |component| + node.override['openstack']['dashboard']['log_level'][component] = "#{component}_log_level_value" + end + runner.converge(described_recipe) + end + components.each do |component| + it do + expect(chef_run).to render_file(file.name).with_content( + /^\s*'#{component}': {\s*'handlers': \['console'\],\s*'level': '#{component}_log_level_value',$/ + ) + end end end - { 'mysql' => 'django.db.backends.mysql', - 'sqlite' => 'django.db.backends.sqlite3' }.each do |service_type, backend| + { + 'mysql' => 'django.db.backends.mysql', + 'sqlite' => 'django.db.backends.sqlite3', + }.each do |service_type, backend| context "#{service_type} database settings" do + cached(:chef_run) do + node.override['openstack']['db']['dashboard']['username'] = "#{service_type}_user" + node.override['openstack']['db']['python_packages'][service_type] = ['pkg1', 'pkg2'] + runner.converge(described_recipe) + end before do allow_any_instance_of(Chef::Recipe).to receive(:db) .with('dashboard') - .and_return('service_type' => service_type, - 'db_name' => "#{service_type}_db", - 'host' => "#{service_type}_host", - 'port' => "#{service_type}_port") - node.override['openstack']['db']['dashboard']['username'] = "#{service_type}_user" - node.override['openstack']['db']['python_packages'][service_type] = ['pkg1', 'pkg2'] + .and_return( + 'service_type' => service_type, + 'db_name' => "#{service_type}_db", + 'host' => "#{service_type}_host", + 'port' => "#{service_type}_port" + ) end - [/^\s*'ENGINE': '#{backend}',$/, - /^\s*'NAME': '#{service_type}_db',$/].each do |cfg| + [ + /^\s*'ENGINE': '#{backend}',$/, + /^\s*'NAME': '#{service_type}_db',$/, + ].each do |cfg| it "configures the #{service_type} backend with #{cfg}" do expect(chef_run).to render_file(file.name).with_content(cfg) end end - [/^\s*'USER': '#{service_type}_user',$/, - /^\s*'PASSWORD': 'test-passes',$/, - /^\s*'HOST': '#{service_type}_host',$/, - /^\s*'PORT': '#{service_type}_port',$/].each do |cfg| + [ + /^\s*'USER': '#{service_type}_user',$/, + /^\s*'PASSWORD': 'test-passes',$/, + /^\s*'HOST': '#{service_type}_host',$/, + /^\s*'PORT': '#{service_type}_port',$/, + ].each do |cfg| next if service_type == 'sqlite' it "configures the #{service_type} backend with #{cfg}" do expect(chef_run).to render_file(file.name).with_content(cfg) @@ -432,27 +483,22 @@ describe 'openstack-dashboard::horizon' do end end - context 'plugins' do + describe 'plugins' do let(:mod_regex) { /^mod = sys.modules\['openstack_dashboard.settings'\]$/ } - context 'plugins enabled' do - let(:plugins) { %w(testPlugin1 testPlugin2) } - before do - node.override['openstack']['dashboard']['plugins'] = plugins - end - + describe 'plugins enabled' do it 'shows the mod setting' do - expect(chef_run).to render_file(file.name).with_content(mod_regex) + expect(chef_run2).to render_file(file.name).with_content(mod_regex) end it 'shows enabled plugins as installed apps' do - plugins.each do |plugin| - expect(chef_run).to render_file(file.name).with_content(/^mod\.INSTALLED_APPS \+= \('#{plugin}', \)$/) + %w(testPlugin1 testPlugin2).each do |plugin| + expect(chef_run2).to render_file(file.name) + .with_content(/^mod\.INSTALLED_APPS \+= \('#{plugin}', \)$/) end end end it 'does not show the mod setting if there are no plugins' do - node.override['openstack']['dashboard']['plugins'] = nil expect(chef_run).not_to render_file(file.name).with_content(mod_regex) end end @@ -469,39 +515,48 @@ describe 'openstack-dashboard::horizon' do it 'does not execute when session_backend is not sql' do expect(chef_run).not_to run_execute(sync_db_cmd).with( - cwd: node['openstack']['dashboard']['django_path'], + cwd: '/usr/share/openstack-dashboard', environment: sync_db_environment ) end - it 'executes when session_backend is sql' do - expect(chef_run_session_sql).to run_execute(sync_db_cmd).with( - cwd: node['openstack']['dashboard']['django_path'], - environment: sync_db_environment - ) + describe 'with sql session' do + it 'executes when session_backend is sql' do + expect(chef_run_sql).to run_execute(sync_db_cmd).with( + cwd: '/usr/share/openstack-dashboard', + environment: sync_db_environment + ) + end + + it 'does not execute when the migrate attribute is set to false' do + expect(chef_run2).not_to run_execute(sync_db_cmd).with( + cwd: '/usr/share/openstack-dashboard', + environment: sync_db_environment + ) + end end - it 'does not execute when the migrate attribute is set to false' do - node.override['openstack']['db']['dashboard']['migrate'] = false - expect(chef_run_session_sql).not_to run_execute(sync_db_cmd).with( - cwd: node['openstack']['dashboard']['django_path'], - environment: sync_db_environment - ) - end - - it 'executes when database backend is sqlite' do - node.override['openstack']['db']['dashboard']['service_type'] = 'sqlite' - expect(chef_run_session_sql).to run_execute(sync_db_cmd).with( - cwd: node['openstack']['dashboard']['django_path'], - environment: sync_db_environment - ) + context 'executes when database backend is sqlite' do + cached(:chef_run) do + node.override['openstack']['db']['dashboard']['service_type'] = 'sqlite' + runner.converge(described_recipe) + end + it do + expect(chef_run).to run_execute(sync_db_cmd).with( + cwd: '/usr/share/openstack-dashboard', + environment: sync_db_environment + ) + end end end it 'has group write mode on path' do - path = chef_run.directory("#{chef_run.node['openstack']['dashboard']['dash_path']}/local") - expect(path.mode).to eq(0o2770) - expect(path.group).to eq(chef_run.node['openstack']['dashboard']['horizon_group']) + expect(chef_run).to create_directory('/usr/share/openstack-dashboard/openstack_dashboard/local') + .with( + owner: 'root', + group: 'horizon', + mode: 0o2770 + ) end end end diff --git a/spec/neutron-fwaas-dashboard_spec.rb b/spec/neutron-fwaas-dashboard_spec.rb index 098c1c5..bed4e9d 100644 --- a/spec/neutron-fwaas-dashboard_spec.rb +++ b/spec/neutron-fwaas-dashboard_spec.rb @@ -3,9 +3,9 @@ require_relative 'spec_helper' describe 'openstack-dashboard::neutron-fwaas-dashboard' do describe 'ubuntu' do - let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) } - let(:node) { runner.node } - let(:chef_run) do + cached(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) } + cached(:node) { runner.node } + cached(:chef_run) do runner.converge(described_recipe) end diff --git a/spec/neutron-lbaas-dashboard_spec.rb b/spec/neutron-lbaas-dashboard_spec.rb index 61cf143..834c183 100644 --- a/spec/neutron-lbaas-dashboard_spec.rb +++ b/spec/neutron-lbaas-dashboard_spec.rb @@ -3,9 +3,9 @@ require_relative 'spec_helper' describe 'openstack-dashboard::neutron-lbaas-dashboard' do describe 'ubuntu' do - let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) } - let(:node) { runner.node } - let(:chef_run) do + cached(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) } + cached(:node) { runner.node } + cached(:chef_run) do runner.converge(described_recipe) end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a92773c..b71dba1 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,21 +2,19 @@ require 'chefspec' require 'chefspec/berkshelf' -ChefSpec::Coverage.start! { add_filter 'openstack-dashboard' } - RSpec.configure do |config| config.color = true config.formatter = :documentation - config.log_level = :fatal + config.log_level = :warn end REDHAT_OPTS = { platform: 'redhat', - version: '7.4', + version: '7', }.freeze UBUNTU_OPTS = { platform: 'ubuntu', - version: '16.04', + version: '18.04', }.freeze # Build a regex for a section of lines