From c9efdd46406e8c05880d74bea35e7bd4ac4257a8 Mon Sep 17 00:00:00 2001 From: Bill Hurt Date: Tue, 27 Feb 2018 12:49:18 -0800 Subject: [PATCH] (MODULES-6746) Convert Tests to RSpec This change converts the module tests to the more standardized RSpec tests. Add back utf-8 test file. --- Rakefile | 7 + spec/acceptance/config_values_spec.rb | 169 +++++ spec/acceptance/features_spec.rb | 219 +++++++ spec/acceptance/package_spec.rb | 118 ++++ spec/acceptance/sources_spec.rb | 595 ++++++++++++++++++ spec/spec_helper.rb | 30 +- spec/spec_helper_acceptance.rb | 23 + spec/support/examples/failing_manifest.rb | 12 + .../examples/manifest_removes_value.rb | 15 + .../examples/password_value_should_be.rb | 26 + .../examples/successful_config_change.rb | 16 + spec/support/utilities/helpers.rb | 83 +++ 12 files changed, 1286 insertions(+), 27 deletions(-) create mode 100644 spec/acceptance/config_values_spec.rb create mode 100644 spec/acceptance/features_spec.rb create mode 100644 spec/acceptance/package_spec.rb create mode 100644 spec/acceptance/sources_spec.rb create mode 100644 spec/spec_helper_acceptance.rb create mode 100644 spec/support/examples/failing_manifest.rb create mode 100644 spec/support/examples/manifest_removes_value.rb create mode 100644 spec/support/examples/password_value_should_be.rb create mode 100644 spec/support/examples/successful_config_change.rb create mode 100644 spec/support/utilities/helpers.rb diff --git a/Rakefile b/Rakefile index 6ebf524f..5a17515b 100644 --- a/Rakefile +++ b/Rakefile @@ -3,6 +3,13 @@ require 'rspec/core/rake_task' require 'puppetlabs_spec_helper/rake_tasks' require 'puppet_blacksmith/rake_tasks' if Bundler.rubygems.find_name('puppet-blacksmith').any? require 'puppet' +require 'bundler' + +require 'pry' if Bundler.rubygems.find_name('pry').any? +Bundler.require(:rake) + +Dir.glob('build/*.rb').each { |r| import r } +Dir.glob('build/*.rake').each { |r| import r } begin require 'beaker/tasks/test' unless RUBY_PLATFORM =~ /win32/ diff --git a/spec/acceptance/config_values_spec.rb b/spec/acceptance/config_values_spec.rb new file mode 100644 index 00000000..cf209b61 --- /dev/null +++ b/spec/acceptance/config_values_spec.rb @@ -0,0 +1,169 @@ +require 'spec_helper_acceptance' + +describe 'Chocolatey Config' do + + context 'MODULES-3035 - Add New Config Item' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + chocolatey_src = <<-PP + chocolateyconfig {'hello123': + ensure => present, + value => 'this guy', + } + PP + + it_behaves_like 'a successful config change', chocolatey_src, 'hello123', /this guy/ + end + + context 'MODULES-3035 - Add a Value to an Existing Config Setting' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + chocolatey_src = <<-PP + chocolateyconfig {'proxy': + ensure => present, + value => 'https://somewhere', + } + PP + + it_behaves_like 'a successful config change', chocolatey_src, 'proxy', /https\:\/\/somewhere/ + end + + context 'MODULES-3035 - Config Settings Change Config Value' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + chocolatey_src = <<-PP + chocolateyconfig {'proxyUser': + value => 'bob', + } + PP + + chocolatey_src_change = <<-PP + chocolateyconfig {'proxyuser': + value => 'tim', + } + PP + + # Add the config item + it_behaves_like 'a successful config change', chocolatey_src, 'proxyUser', /bob/ + + # Now that it exists, change its value + it_behaves_like 'a successful config change', chocolatey_src_change, 'proxyUser', /tim/ + end + + context 'MODULES-3035 Ensure Config Value with Password In Name' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + chocolatey_src = <<-PP + chocolateyconfig {'proxyPassword': + value => 'secrect', + } + PP + + chocolatey_src_change = <<-PP + chocolateyconfig {'proxyPassword': + value => 'secrect2', + } + PP + + # The password should set one time and then not change. + it_behaves_like 'a password that doesn\'t change', chocolatey_src, chocolatey_src_change, 'proxyPassword' + end + + context 'MODULES-3035 - Fail to Set Present With No Value' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + chocolatey_src = <<-PP + chocolateyconfig {'bob': + ensure => present, + } + PP + + expected_error = /Unless ensure => absent, value is required./ + + # A manifest with present set, but no values to enforce should not run. + it_behaves_like 'a failing manifest', chocolatey_src, expected_error + end + + context 'MODULES-3035 - Config Settings Remove Value with Password in the Name' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + chocolatey_src = <<-PP + chocolateyconfig {'proxyPassword': + value => 'secret', + } + PP + + chocolatey_src_change = <<-PP + chocolateyconfig {'proxyPassword': + ensure => absent, + } + PP + + # The password will end up a hash, so we specify a regex that just verifies a hash exists. + it_behaves_like 'a successful config change', chocolatey_src, 'proxyPassword', /(.+)/ + + it_behaves_like 'a manifest that removes a config value', chocolatey_src_change, 'proxyPassword' + end + + context 'MODULES-3035 - Remove Value from Config Setting' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + chocolatey_src = <<-PP + chocolateyconfig {'commandExecutionTimeoutSeconds': + ensure => absent, + } + PP + + it_behaves_like 'a manifest that removes a config value', chocolatey_src, 'commandExecutionTimeoutSeconds' + end +end + diff --git a/spec/acceptance/features_spec.rb b/spec/acceptance/features_spec.rb new file mode 100644 index 00000000..b41319c1 --- /dev/null +++ b/spec/acceptance/features_spec.rb @@ -0,0 +1,219 @@ +require 'spec_helper_acceptance' + +describe 'Chocolatey features' do + context 'MODULES-3034 Disable an Already Disabled Feature' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + chocolatey_src = <<-PP + chocolateyfeature {'failOnAutoUninstaller': + ensure => disabled, + } + PP + + windows_agents.each do | agent | + it 'should verify the features is disabled' do + on(agent, config_content_command) do | result | + assert_match(/false/, get_xml_value("//features/feature[@name='failOnAutoUninstaller']/@enabled", result.output).to_s, 'Was not disabled by default, please adjust test to find another value.') + end + end + + it 'Should apply the manifest to disable the feature' do + apply_manifest_on(agent, chocolatey_src, :catch_failures => true) + end + + it 'should verify the feature is still disabled' do + on(agent, config_content_command) do | result | + assert_match(/false/, get_xml_value("//features/feature[@name='failOnAutoUninstaller']/@enabled", result.output).to_s, 'Was not found disabled') + end + end + end + end + + context 'MODULES-3034 Disable an Enabled Feature' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + chocolatey_src = <<-PP + chocolateyfeature {'checksumFiles': + ensure => disabled, + } + PP + + windows_agents.each do | agent | + it 'should validate the feature is enabled' do + on(agent, config_content_command) do | result | + assert_match(/true/, get_xml_value("//features/feature[@name='checksumFiles']/@enabled", result.output).to_s, 'Was not enabled by default, please adjust test to find another value.') + end + end + + it 'should apply the manifest to disable the feature' do + apply_manifest_on(agent, chocolatey_src) + end + + it 'should validate the feature is now disabled' do + on(agent, config_content_command) do | result | + assert_match(/false/, get_xml_value("//features/feature[@name='checksumFiles']/@enabled", result.output).to_s, 'Was not found disabled') + end + end + end + end + + context 'MODULES-3034 Enable a Disabled Feature' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + chocolatey_src = <<-PP + chocolateyfeature {'failOnAutoUninstaller': + ensure => enabled, + } + PP + + windows_agents.each do | agent | + it 'Should verify the feature is disabled' do + on(agent, config_content_command) do | result | + assert_match(/false/, get_xml_value("//features/feature[@name='failOnAutoUninstaller']/@enabled", result.output).to_s, 'Was not disabled by default, please adjust test to find another value.') + end + end + + it 'should apply the manifest to enable the feature' do + apply_manifest_on(agent, chocolatey_src, :catch_failures => true) + end + + it 'Should verify the feature is now enabled' do + on(agent, config_content_command) do | result | + assert_match(/true/, get_xml_value("//features/feature[@name='failOnAutoUninstaller']/@enabled", result.output).to_s, 'Was not found enabled') + end + end + end + end + + context 'MODULES-3034 - Enable Already Enabled Feature' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + chocolatey_src = <<-PP + chocolateyfeature {'usePackageExitCodes': + ensure => enabled, + } + PP + + windows_agents.each do | agent | + it 'Should verify the feature is already enabled' do + on(agent, config_content_command) do | result | + assert_match(/true/, get_xml_value("//features/feature[@name='usePackageExitCodes']/@enabled", result.output).to_s, 'Was not enabled by default, please adjust test to find another value.') + end + end + + it 'should apply the manifest to enable the feature' do + apply_manifest_on(agent, chocolatey_src, :catch_failures => true) + end + + it 'Should verify the feature is still enabled' do + on(agent, config_content_command) do | result | + assert_match(/true/, get_xml_value("//features/feature[@name='usePackageExitCodes']/@enabled", result.output).to_s, 'Was not found enabled') + end + end + end + end + + context 'MODULES-3034 - Enable a non-existent feature' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + chocolatey_src = <<-PP + chocolateyfeature {'idontexistfeature123123': + ensure => enabled, + } + PP + + windows_agents.each do | agent | + it 'Should fail to apply the manifest' do + apply_manifest_on(agent, chocolatey_src, :expect_failures => true) do | result | + assert_match(/returned 1: Feature 'idontexistfeature123123' not found/, result.stderr, "stderr did not match expected") + end + end + end + end + + context 'MODULES-3034 - Enable non-existent feature' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + chocolatey_src = <<-PP + chocolateyfeature {'idontexistfeature123123': + ensure => enabled, + } + PP + + windows_agents.each do | agent | + it 'Should fail to apply the manifest' do + apply_manifest_on(agent, chocolatey_src, :expect_failures => true) do | result | + assert_match(/returned 1: Feature 'idontexistfeature123123' not found/, result.stderr, "stderr did not match expected") + end + end + end + end + + context 'MODULES-3034 - Attempt to remove feature' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + chocolatey_src = <<-PP + chocolateyfeature {'checksumFiles': + ensure => absent, + } + PP + + windows_agents.each do | agent | + it 'Should fail to apply the manifest' do + apply_manifest_on(agent, chocolatey_src, :expect_failures => true) do | result | + assert_match(/Error: Parameter ensure failed on Chocolateyfeature\[checksumFiles\]: Invalid value \"absent\"/, result.stderr, "stderr did not match expected") + end + end + end + end +end + diff --git a/spec/acceptance/package_spec.rb b/spec/acceptance/package_spec.rb new file mode 100644 index 00000000..ce7ba26a --- /dev/null +++ b/spec/acceptance/package_spec.rb @@ -0,0 +1,118 @@ +require 'spec_helper_acceptance' + +describe 'Chocolatey Package' do + + context 'MODULES-3037 Install a known good package via manifest and remove via manifest' do + package_name = 'vlc' + package_exe_path = %{C:\\'Program Files\\VideoLAN\\VLC\\vlc.exe'} + software_uninstall_command = %{cmd.exe /C C:\\'Program Files\\VideoLAN\\VLC\\uninstall.exe' /S} + + chocolatey_package_manifest = <<-PP + package { "#{package_name}": + ensure => present, + provider => chocolatey, + source => 'http://nexus.delivery.puppetlabs.net/service/local/nuget/choco-pipeline-tests/' + } + PP + + chocolatey_package_manifest_chng = <<-PP + package { "#{package_name}": + ensure => absent, + provider => chocolatey, + } + PP + + after(:all) do + windows_agents.each do | agent | + on(agent, powershell("test-path #{package_exe_path}", {'EncodedCommand' => true}), :catch_errors => true) do | result | + on(agent, powershell(software_uninstall_command, {'EncodedCommand' => true}), :catch_errors => true) if result.stdout =~ /True/ + end + end + end + + windows_agents.each do | agent | + + it 'Should verify the package is not installed.' do + on(agent, powershell("test-path #{package_exe_path}", {'EncodedCommand' => true}), :catch_errors => true) do | result | + assert_match(/False/i, result.output, "#{package_name} was present before application of manifest.") + end + end + + it 'Should apply the manifest to install the package' do + + apply_manifest_on(agent, chocolatey_package_manifest, :catch_failures => true) do | result | + assert_match(/Notice\: \/Stage\[main\]\/Main\/Package\[#{package_name}\]\/ensure\: created/, result.stdout, "stdout did not report package creation of #{package_name}") + end + end + + it "should have a valid version of #{package_name}" do + on(agent, powershell("test-path #{package_exe_path}", {'EncodedCommand' => true}), :catch_errors => true) do |result| + assert_match(/True/i, result.output, "#{package_name} was not present after application of manifest.") + end + end + + it 'Should uninstall the package' do + apply_manifest_on(agent, chocolatey_package_manifest_chng, :catch_failures => true) do | result | + assert_match(/Stage\[main\]\/Main\/Package\[#{package_name}\]\/ensure\: removed/, result.stdout, "stdout did not report package removal of #{package_name}") + end + end + end + end + + skip 'UTF-8 Not Suported At This Time - MODULES-3037 Install a known good package with utf-8 via manifest and remove via manifest' do + package_name = '竹ChocolateyGUIÖ' + package_exe_path = %{C:\\'Program Files (x86)\\ChocolateyGUI\\ChocolateyGUI.exe'} + software_uninstall_command = %{msiexec /x C:\\ProgramData\\chocolatey\\lib\\竹ChocolateyGUIÖ\\tools\\竹ChocolateyGUIÖ.msi /q}.force_encoding("ASCII-8BIT") + + chocolatey_package_manifest = <<-PP + package { "#{package_name}": + ensure => present, + provider => chocolatey, + source => 'http://nexus.delivery.puppetlabs.net/service/local/nuget/choco-pipeline-tests/' + } + PP + + chocolatey_package_manifest_chng = <<-PP + package { "#{package_name}": + ensure => absent, + provider => chocolatey, + } + PP + + after(:all) do + windows_agents.each do | agent | + on(agent, powershell("test-path #{package_exe_path}", {'EncodedCommand' => true}), :catch_errors => true) do | result | + on(agent, powershell(software_uninstall_command, {'EncodedCommand' => true}), :catch_errors => true) if result.stdout =~ /True/ + end + end + end + + windows_agents.each do | agent | + + it 'Should verify the package is not installed.' do + on(agent, powershell("test-path #{package_exe_path}", {'EncodedCommand' => true}), :catch_errors => true) do | result | + assert_match(/False/i, result.output, "#{package_name} was present before application of manifest.") + end + end + + it 'Should apply the manifest to install the package' do + apply_manifest_on(agent, chocolatey_package_manifest, :catch_failures => true) do | result | + assert_match(/Notice\: \/Stage\[main\]\/Main\/Package\[#{package_name}\]\/ensure\: created/, result.stdout, "stdout did not report package creation of #{package_name}") + end + end + + it "should have a valid version of #{package_name}" do + on(agent, powershell("test-path #{package_exe_path}", {'EncodedCommand' => true}), :catch_errors => true) do |result| + assert_match(/True/i, result.output, "#{package_name} was not present after application of manifest.") + end + end + + it 'Should uninstall the package' do + apply_manifest_on(agent, chocolatey_package_manifest_chng, :catch_failures => true) do | result | + assert_match(/Stage\[main\]\/Main\/Package\[#{package_name}\]\/ensure\: removed/, result.stdout, "stdout did not report package removal of #{package_name}") + end + end + end + end +end + diff --git a/spec/acceptance/sources_spec.rb b/spec/acceptance/sources_spec.rb new file mode 100644 index 00000000..801ac131 --- /dev/null +++ b/spec/acceptance/sources_spec.rb @@ -0,0 +1,595 @@ +require 'spec_helper_acceptance' + +describe 'Chocolatey Source' do + context 'MODULES-3037 - Add Priority to an Existing Source' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + windows_agents.each do | agent | + + it 'Should Apply the Manifest' do + chocolatey_src = <<-PP + chocolateysource {'chocolatey': + ensure => present, + location => 'https://chocolatey.org/api/v2', + priority => 1, + } + PP + + apply_manifest_on(agent, chocolatey_src, :catch_failures => true) + end + + it 'Should now have proper priority' do + on(agent, config_content_command) do |result| + assert_match(/1/, get_xml_value("//sources/source[@id='chocolatey']/@priority", result.output).to_s, 'Priority did not match') + end + end + end + end + + context 'MODULES-3037 - Add Source With All Options' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + windows_agents.each do | agent | + + it 'Should Apply the Manifest' do + chocolatey_src = <<-PP + chocolateysource {'test': + ensure => present, + location => 'c:\\packages', + priority => 2, + user => 'bob', + password => 'yes', + } + PP + + apply_manifest_on(agent, chocolatey_src, :catch_failures => true) + end + + it 'Should have the correct properties' do + on(agent, config_content_command) do | result | + assert_match(/c:\\packages/, get_xml_value("//sources/source[@id='test']/@value", result.output).to_s, 'Location did not match') + assert_match(/2/, get_xml_value("//sources/source[@id='test']/@priority", result.output).to_s, 'Priority did not match') + assert_match(/bob/, get_xml_value("//sources/source[@id='test']/@user", result.output).to_s, 'User did not match') + assert_match(/.+/, get_xml_value("//sources/source[@id='test']/@password", result.output).to_s, 'Password was not saved') + assert_match(/false/, get_xml_value("//sources/source[@id='test']/@disabled", result.output).to_s, 'Disabled did not match') + end + end + end + end + + context 'MODULES-3037 - Add Source Minimal' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + windows_agents.each do | agent | + it 'Should Apply the Manifest' do + chocolatey_src = <<-PP + chocolateysource {'test': + location => 'c:\\packages', + } + PP + + apply_manifest_on(agent, chocolatey_src, :catch_failures => true) + end + + it 'Should verify the results' do + on(agent, config_content_command) do |result| + assert_match(/c:\\packages/, get_xml_value("//sources/source[@id='test']/@value", result.output).to_s, 'Location did not match') + assert_match(/false/, get_xml_value("//sources/source[@id='test']/@disabled", result.output).to_s, 'Disabled did not match') + end + end + end + end + + context 'MODULES-3037 - Add Source Happy Path' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + windows_agents.each do | agent | + it 'Should Apply the manifest' do + chocolatey_src = <<-PP + chocolateysource {'test': + ensure => present, + location => 'c:\\packages', + } + PP + + apply_manifest_on(agent, chocolatey_src, :catch_failures => true) + end + + it 'Should verify results' do + on(agent, config_content_command) do | result | + assert_match(/c:\\packages/, get_xml_value("//sources/source[@id='test']/@value", result.output).to_s, 'Location did not match') + assert_match(/false/, get_xml_value("//sources/source[@id='test']/@disabled", result.output).to_s, 'Disabled did not match') + end + end + end + end + + context 'MODULES-3037 - Add User/Password to an Existing Source' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + windows_agents.each do | agent | + it 'Should apply the manifest' do + chocolatey_src = <<-PP + chocolateysource {'chocolatey': + ensure => present, + location => 'https://chocolatey.org/api/v2', + user => 'tim', + password => 'test', + } + PP + + apply_manifest_on(agent, chocolatey_src, :catch_failures => true) + end + + it 'Should verify the results' do + on(agent, config_content_command) do |result| + assert_match(/tim/, get_xml_value("//sources/source[@id='chocolatey']/@user", result.output).to_s, 'User did not match') + # we are not able to verify password other than if it has a value - it will be encrypted in a non-verifyable way + assert_match(/.+/, get_xml_value("//sources/source[@id='chocolatey']/@password", result.output).to_s, 'Password was not saved') + end + end + end + end + + context 'MODULES-3037 - Change Existing Priority' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + windows_agents.each do | agent | + it 'Should apply a manifest to set priority' do + chocolatey_src = <<-PP + chocolateysource {'chocolatey': + ensure => present, + location => 'https://chocolatey.org/api/v2', + priority => 1, + } + PP + + apply_manifest_on(agent, chocolatey_src, :catch_failures => true) + end + + it 'Should verify the setup was added' do + on(agent, config_content_command) do | result | + assert_match(/1/, get_xml_value("//sources/source[@id='chocolatey']/@priority", result.output).to_s, 'Priority setup did not match') + end + end + + it 'Should apply a manifest to change the priority' do + chocolatey_src_change = <<-PP + chocolateysource {'chocolatey': + ensure => present, + location => 'https://chocolatey.org/api/v2', + priority => 5, + } + PP + + apply_manifest_on(agent, chocolatey_src_change, :catch_failures => true) + end + + it 'Should verify results' do + on(agent, config_content_command) do | result | + assert_match(/5/, get_xml_value("//sources/source[@id='chocolatey']/@priority", result.output).to_s, 'Priority change did not match') + end + end + end + end + + context 'MODULES-3037 - Change Source Location for an Existing Source' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + windows_agents.each do | agent | + it 'Should Apply a manifest' do + chocolatey_src = <<-PP + chocolateysource {'chocolatey': + ensure => present, + location => 'c:\\packages', + } + PP + + apply_manifest_on(agent, chocolatey_src, :catch_failures => true) + end + + it 'Should verify the results' do + on(agent, config_content_command) do | result | + assert_match(/c:\\packages/, get_xml_value("//sources/source[@id='chocolatey']/@value", result.output).to_s, 'Location did not match') + end + end + end + end + + context 'MODULES-3037 - Change User/Password in an existing source.' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + windows_agents.each do | agent | + it 'Should apply a manifest to create a username/pass' do + chocolatey_src = <<-PP + chocolateysource {'chocolatey': + ensure => present, + location => 'https://chocolatey.org/api/v2', + user => 'tim', + password => 'test', + } + PP + + apply_manifest_on(agent, chocolatey_src, :catch_failures => true) + end + + it 'Should verify the results' do + on(agent, config_content_command) do | result | + assert_match(/tim/, get_xml_value("//sources/source[@id='chocolatey']/@user", result.output).to_s, 'User setup did not match') + # we are not able to verify password other than if it has a value - it will be encrypted in a non-verifyable way + assert_match(/.+/, get_xml_value("//sources/source[@id='chocolatey']/@password", result.output).to_s, 'Password was not saved') + end + end + + it 'Should apply a manifest to change the values' do + chocolatey_src_change = <<-PP + chocolateysource {'chocolatey': + ensure => present, + location => 'https://chocolatey.org/api/v2', + user => 'bob', + password => 'newpass', + } + PP + + apply_manifest_on(agent, chocolatey_src_change, :catch_failures => true) + end + + it 'Should validate the results' do + on(agent, config_content_command) do | result | + assert_match(/bob/, get_xml_value("//sources/source[@id='chocolatey']/@user", result.output).to_s, 'User change did not match') + assert_match(/.+/, get_xml_value("//sources/source[@id='chocolatey']/@password", result.output).to_s, 'Password no longer exists') + end + end + end + end + + context 'MODULES-3037 - Disable an Existing resource' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + windows_agents.each do | agent | + it 'Should apply a manifest to disable the resource' do + chocolatey_src = <<-PP + chocolateysource {'chocolatey': + ensure => disabled, + } + PP + + apply_manifest_on(agent, chocolatey_src, :catch_failures => true) + apply_manifest_on(agent, chocolatey_src, :catch_changes => true) + end + + it 'Should verify the results' do + on(agent, config_content_command) do | result | + assert_match(/true/, get_xml_value("//sources/source[@id='chocolatey']/@disabled", result.output).to_s, 'Disabled did not match') + end + end + end + end + + context 'MODULES-3037 Disable an Existing Source' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + windows_agents.each do | agent | + it 'Should Apply a manifest' do + chocolatey_src = <<-PP + chocolateysource {'chocolatey': + ensure => disabled, + } + PP + + apply_manifest_on(agent, chocolatey_src, :catch_failures => true) + end + + it 'Should verify the results' do + on(agent, config_content_command) do | result | + assert_match(/true/, get_xml_value("//sources/source[@id='chocolatey']/@disabled", result.output).to_s, 'Disabled did not match') + end + end + end + end + + context 'MODULES-3037 Add Source Sad Path: Fail to apply manifest without location' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + windows_agents.each do | agent | + it 'Should fail to apply a bad manifest with the correct error' do + chocolatey_src = <<-PP + chocolateysource {'chocolatey': + ensure => present, + } + PP + + apply_manifest_on(agent, chocolatey_src, :expect_failures => true) do | result | + assert_match(/Error: Validation of Chocolateysource\[chocolatey\] failed: A non-empty location/, result.stderr, "stderr did not match expected") + end + end + end + end + + context 'MODULES-3037 - Add Source Sad Path: Fail to apply bad manifest' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + windows_agents.each do | agent | + it 'Should fail to apply a manifest' do + chocolatey_src = <<-PP + chocolateysource {'test': + ensure => sad, + location => 'c:\\packages', + } + PP + + apply_manifest_on(agent, chocolatey_src, :expect_failures => true) do | result | + assert_match(/Error: Parameter ensure failed on Chocolateysource\[test\]: Invalid value "sad"/, result.stderr, "stderr did not match expected") + end + end + end + end + + context 'MODULES-3037 - Add Source Sad Path: Set password with no user' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + windows_agents.each do | agent | + it 'Should fail to apply a manifest' do + chocolatey_src = <<-PP + chocolateysource {'chocolatey': + ensure => present, + location => 'https://chocolatey.org/api/v2', + password => 'test', + } + PP + + apply_manifest_on(agent, chocolatey_src, :expect_failures => true) do | result | + assert_match(/Error: Validation of Chocolateysource\[chocolatey\] failed: If specifying user\/password, you must specify both values/, result.stderr, "stderr did not match expected") + end + end + end + end + + context 'MODULES-3037 - Add Source Sad Path: Set user with no password' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + windows_agents.each do | agent | + it 'Should fail to apply a manifest' do + chocolatey_src = <<-PP + chocolateysource {'chocolatey': + ensure => present, + location => 'https://chocolatey.org/api/v2', + user => 'tim', + } + PP + + apply_manifest_on(agent, chocolatey_src, :expect_failures => true) do | result | + assert_match(/Error: Validation of Chocolateysource\[chocolatey\] failed: If specifying user\/password, you must specify both values/, result.stderr, "stderr did not match expected") + end + end + end + end + + context 'MODULES-3037 - Remove an Existing Source' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + windows_agents.each do | agent | + it 'Should apply a manifest' do + chocolatey_src = <<-PP + chocolateysource {'chocolatey': + ensure => absent, + } + PP + + apply_manifest_on(agent, chocolatey_src, :catch_failures => true) + end + + it 'Should verify the result' do + on(agent, config_content_command) do | result | + assert_not_match(/chocolatey/, get_xml_value("//sources/source[@id='chocolatey']/@id", result.output).to_s, 'Source was not removed') + end + end + end + end + + context 'MODULES-3037 Remove Priority from an Existing Source' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + windows_agents.each do | agent | + chocolatey_src = <<-PP + chocolateysource {'chocolatey': + ensure => present, + location => 'https://chocolatey.org/api/v2', + priority => 1, + } + PP + + chocolatey_src_remove = <<-PP + chocolateysource {'chocolatey': + ensure => present, + location => 'https://chocolatey.org/api/v2', + } + PP + + it 'Should apply a manifest' do + apply_manifest_on(agent, chocolatey_src, :catch_failures => true) + end + + it 'Should verify setup' do + on(agent, config_content_command) do | result | + assert_match(/1/, get_xml_value("//sources/source[@id='chocolatey']/@priority", result.output).to_s, 'Priority did not match') + end + end + + it 'Should apply remove manifest' do + apply_manifest_on(agent, chocolatey_src_remove, :catch_failures => true) + end + + it 'Should verify results' do + on(agent, config_content_command) do | result | + assert_match(/0/, get_xml_value("//sources/source[@id='chocolatey']/@priority", result.output).to_s, 'Priority change did not match') + end + end + end + end + + context 'MODULES-3037 - Remove User/Password From an Existing Source' do + + before(:all) do + backup_config + end + + after(:all) do + reset_config + end + + windows_agents.each do | agent | + chocolatey_src = <<-PP + chocolateysource {'chocolatey': + ensure => present, + location => 'https://chocolatey.org/api/v2', + user => 'tim', + password => 'test', + } + PP + + chocolatey_src_remove = <<-PP + chocolateysource {'chocolatey': + ensure => present, + location => 'https://chocolatey.org/api/v2', + } + PP + + it 'Should apply a manifest' do + apply_manifest_on(agent, chocolatey_src, :catch_failures => true) + end + + it 'Should verify setup' do + on(agent, config_content_command) do | result | + assert_match(/tim/, get_xml_value("//sources/source[@id='chocolatey']/@user", result.output).to_s, 'User setup did not match') + # we are not able to verify password other than if it has a value - it will be encrypted in a non-verifyable way + assert_match(/.+/, get_xml_value("//sources/source[@id='chocolatey']/@password", result.output).to_s, 'Password was not saved') + end + end + + it 'Should apply remove manifest' do + apply_manifest_on(agent, chocolatey_src_remove, :catch_failures => true) + end + + it 'Should verify results' do + on(agent, config_content_command) do | result | + assert_not_match(/.+/, get_xml_value("//sources/source[@id='chocolatey']/@user", result.output).to_s, 'User was not removed') + assert_not_match(/.+/, get_xml_value("//sources/source[@id='chocolatey']/@password", result.output).to_s, 'Password was not removed') + end + end + end + end +end + diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 72c40769..7f646a09 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,31 +1,7 @@ -#require 'ruby-prof' -#RubyProf.start - -IDEAL_CONSOLE_WIDTH = 72 -def horizontal_rule(width = 5) - '=' * [width, IDEAL_CONSOLE_WIDTH].min -end - +require 'pry' if Bundler.rubygems.find_name('pry').any? require 'puppetlabs_spec_helper/module_spec_helper' - -# require dependencies -gems = [ - #'minitest/autorun', # http://docs.seattlerb.org/minitest/ - #'minitest/unit', # https://github.com/freerange/mocha#bundler - 'mocha', # http://gofreerange.com/mocha/docs/Mocha/Configuration.html - 'puppet', -] -begin - gems.each {|gem| require gem} -rescue => e - # http://goo.gl/r3nFG - # emphasize dependency failures in case a task spews lots of output - warn horizontal_rule(e.message.length) - warn e.class - warn e.message - warn horizontal_rule(e.message.length) - exit(1) -end +require 'rake' +require 'fileutils' RSpec.configure do |c| # set the environment variable before files are loaded, otherwise it is too late diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb new file mode 100644 index 00000000..8633e5b0 --- /dev/null +++ b/spec/spec_helper_acceptance.rb @@ -0,0 +1,23 @@ +# Not sure if these are still neeed. +# require 'net/http' +# require 'uri' +require 'nokogiri' + +require 'beaker-rspec' +require 'beaker/puppet_install_helper' +require 'beaker/module_install_helper' +require 'beaker/ca_cert_helper' +#require 'beaker/testmode_switcher' +#require 'beaker/testmode_switcher/dsl' +#require 'beaker-puppet' +Dir["./spec/support/**/*.rb"].sort.each { |f| require f } + +run_puppet_install_helper +install_ca_certs + +windows_agents.each do |agent| + install_module_dependencies_on(agent) + install_module_on(agent) + install_chocolatey +end + diff --git a/spec/support/examples/failing_manifest.rb b/spec/support/examples/failing_manifest.rb new file mode 100644 index 00000000..c06c8682 --- /dev/null +++ b/spec/support/examples/failing_manifest.rb @@ -0,0 +1,12 @@ +shared_examples 'a failing manifest' do |manifest, expected_error| + + windows_agents.each do |agent| + + it 'Should fail to apply a bad manifest' do + apply_manifest_on(agent, manifest, :expect_failures => true) do + assert_match(expected_error, stderr, "stderr did not match expected error") + end + end + end +end + diff --git a/spec/support/examples/manifest_removes_value.rb b/spec/support/examples/manifest_removes_value.rb new file mode 100644 index 00000000..ca575864 --- /dev/null +++ b/spec/support/examples/manifest_removes_value.rb @@ -0,0 +1,15 @@ +shared_examples 'a manifest that removes a config value' do |manifest, key| + + windows_agents.each do |agent| + it 'should apply the manifest that removes the value' do + apply_manifest_on(agent, manifest, :catch_failures => true) + end + + it 'should validate the key has been removed' do + on(agent, config_content_command) do |result| + assert_not_match(/.+/, get_xml_value("//config/add[@key='#{key}']/@value", result.output).to_s, 'Value should have been removed') + end + end + end +end + diff --git a/spec/support/examples/password_value_should_be.rb b/spec/support/examples/password_value_should_be.rb new file mode 100644 index 00000000..8995f541 --- /dev/null +++ b/spec/support/examples/password_value_should_be.rb @@ -0,0 +1,26 @@ +shared_examples 'a password that doesn\'t change' do |manifest, modify_manfiest, key| + + password = '' + + windows_agents.each do |agent| + # Should apply the password here. + # 'password' variable is set to the password hash value. + it 'Should apply the manifest to set the password' do + apply_manifest_on(agent, manifest, :catch_failures => true) + on(agent, config_content_command) do |result| + password = get_xml_value("//config/add[@key='#{key}']/@value", result.output).to_s + assert_match(/.+/, password, 'Value did not match') + end + end + + it 'should validate the value' do + # Apply a manifest with a modified password value + apply_manifest(modify_manfiest, :catch_failures => true) + on(agent, config_content_command) do |result| + # Verify here that the hash value in the config did not change. + assert_match(password, get_xml_value("//config/add[@key='#{key}']/@value", result.output).to_s, 'Value should not have changed') + end + end + end +end + diff --git a/spec/support/examples/successful_config_change.rb b/spec/support/examples/successful_config_change.rb new file mode 100644 index 00000000..99ba8475 --- /dev/null +++ b/spec/support/examples/successful_config_change.rb @@ -0,0 +1,16 @@ +shared_examples 'a successful config change' do |manifest, key, expected_value| + + windows_agents.each do |agent| + + it 'Should apply the config manifest' do + apply_manifest_on(agent, manifest, :catch_failures => true) + end + + it 'should validate the value' do + on(agent, config_content_command) do |result| + assert_match(expected_value, get_xml_value("//config/add[@key='#{key}']/@value", result.output).to_s, 'Value did not match') + end + end + end +end + diff --git a/spec/support/utilities/helpers.rb b/spec/support/utilities/helpers.rb new file mode 100644 index 00000000..319ef35a --- /dev/null +++ b/spec/support/utilities/helpers.rb @@ -0,0 +1,83 @@ +CHOCOLATEY_LATEST_INFO_URL = "http://nexus.delivery.puppetlabs.net/service/local/nuget/choco-pipeline-tests/Packages()?$filter=((Id%20eq%20%27chocolatey%27)%20and%20(not%20IsPrerelease))%20and%20IsLatestVersion" + +def get_latest_chocholatey_download_url + uri = URI.parse(CHOCOLATEY_LATEST_INFO_URL) + + response = Net::HTTP.get_response(uri) + xml_str = Nokogiri::XML(response.body) + + src_url = xml_str.css('//feed//content').attr('src') + + return src_url +end + +def install_chocolatey + chocolatey_pp = <<-MANIFEST + class {'chocolatey': + chocolatey_download_url => 'file:///C:/chocolatey.nupkg', + use_7zip => false, + } + MANIFEST + + chocoVersion = /[0-9]+[\d'.']*/ + + windows_agents.each do |agent| + opts = { + :acceptable_exit_codes => [0, 2] + } + + curl_on(agent, "#{get_latest_chocholatey_download_url} > C:/chocolatey.nupkg") + + apply_manifest_on(agent, chocolatey_pp, opts) do |result| + assert_no_match(/Error:/, result.stderr, 'Unexpected error was detected!') + end + + on(agent, 'C:/ProgramData/chocolatey/bin/choco.exe -v', :acceptable_exit_codes => 0) do |result| + assert_match(chocoVersion, result.stdout, 'Expected: ' + chocoVersion.to_s + ' but got ' + result.stdout) + end + end +end + + +def windows_agents + agents.select { |agent| agent['platform'].include?('windows') } +end + +def config_file_location + 'c:\\ProgramData\\chocolatey\\config\\chocolatey.config' +end + +def backup_config + windows_agents.each do |agent| + backup_command = <<-COMMAND + if (Test-Path #{config_file_location}) { + Copy-Item -Path #{config_file_location} -Destination #{config_file_location}.bkp + } + COMMAND + + execute_powershell_script_on(agent, backup_command, :catch_failures => true) + end +end + +def reset_config + windows_agents.each do |agent| + backup_command = <<-COMMAND + if (Test-Path #{config_file_location}.bkp) { + Move-Item -Path #{config_file_location}.bkp -Destination #{config_file_location} -force + } + COMMAND + + execute_powershell_script_on(agent, backup_command, :catch_failures => true) + end +end + +def get_xml_value(xpath, file_text) + doc = Nokogiri::XML(file_text) + + doc.xpath(xpath) +end + +def config_content_command + "cmd.exe /c \"type #{config_file_location}\"" +end +