diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/acceptance/nodesets/default.yml | 19 | ||||
-rw-r--r-- | spec/acceptance/tests/create_spec.rb | 31 | ||||
-rw-r--r-- | spec/acceptance/tests/destroy_spec.rb | 41 | ||||
-rw-r--r-- | spec/acceptance/tests/modify_spec.rb | 42 | ||||
-rw-r--r-- | spec/acceptance/tests/query_spec.rb | 35 | ||||
-rw-r--r-- | spec/default_facts.yml | 8 | ||||
-rw-r--r-- | spec/fixtures/integration/provider/mailalias/aliases/test1 | 31 | ||||
-rw-r--r-- | spec/integration/provider/mailalias/aliases_spec.rb | 9 | ||||
-rw-r--r-- | spec/lib/puppet_spec/files.rb | 123 | ||||
-rw-r--r-- | spec/shared_behaviours/all_parsedfile_providers.rb | 21 | ||||
-rw-r--r-- | spec/spec_helper.rb | 44 | ||||
-rw-r--r-- | spec/spec_helper_acceptance.rb | 24 | ||||
-rw-r--r-- | spec/unit/type/mailalias_spec.rb | 54 |
13 files changed, 482 insertions, 0 deletions
diff --git a/spec/acceptance/nodesets/default.yml b/spec/acceptance/nodesets/default.yml new file mode 100644 index 0000000..b53e1a1 --- /dev/null +++ b/spec/acceptance/nodesets/default.yml @@ -0,0 +1,19 @@ +--- +HOSTS: + ubuntu1604-64-1: + pe_dir: + pe_ver: + pe_upgrade_dir: + pe_upgrade_ver: + hypervisor: vmpooler + platform: ubuntu-16.04-amd64 + packaging_platform: ubuntu-16.04-amd64 + template: ubuntu-1604-x86_64 + roles: + - agent + - default +CONFIG: + type: agent + nfs_server: none + consoleport: 443 + pooling_api: http://vmpooler.delivery.puppetlabs.net/ diff --git a/spec/acceptance/tests/create_spec.rb b/spec/acceptance/tests/create_spec.rb new file mode 100644 index 0000000..82adfec --- /dev/null +++ b/spec/acceptance/tests/create_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper_acceptance' + +RSpec.context 'Mailalias: should create an email alias' do + name = "pl#{rand(999_999).to_i}" + + before(:all) do + non_windows_agents.each do |agent| + on(agent, 'cp /etc/aliases /tmp/aliases', acceptable_exit_codes: [0, 1]) + end + end + + after(:all) do + non_windows_agents.each do |agent| + on(agent, 'mv /tmp/aliases /etc/aliases', acceptable_exit_codes: [0, 1]) + end + end + + non_windows_agents.each do |agent| + it 'creates a mailalias with puppet' do + args = ['ensure=present', + 'recipient="foo,bar,baz"'] + on(agent, puppet_resource('mailalias', name, args)) + end + + it 'verifies the alias exists' do + on(agent, 'cat /etc/aliases') do |res| + assert_match(%r{#{name}:.*foo,bar,baz}, res.stdout, 'mailalias not in aliases file') + end + end + end +end diff --git a/spec/acceptance/tests/destroy_spec.rb b/spec/acceptance/tests/destroy_spec.rb new file mode 100644 index 0000000..0f805a5 --- /dev/null +++ b/spec/acceptance/tests/destroy_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper_acceptance' + +RSpec.context 'should delete an email alias' do + name = "pl#{rand(999_999).to_i}" + + before(:all) do + non_windows_agents.each do |agent| + # (setup) backup alias file + on(agent, 'cp /etc/aliases /tmp/aliases', acceptable_exit_codes: [0, 1]) + + # (setup) create a mailalias + on(agent, "echo '#{name}: foo,bar,baz' >> /etc/aliases") + + # (setup) verify the alias exists + on(agent, 'cat /etc/aliases') do |res| + assert_match(%r{#{name}:.*foo,bar,baz}, res.stdout, 'mailalias not in aliases file') + end + end + end + + after(:all) do + non_windows_agents.each do |agent| + # (teardown) restore the alias file + on(agent, 'mv /tmp/aliases /etc/aliases', acceptable_exit_codes: [0, 1]) + end + end + + non_windows_agents.each do |agent| + it 'deletes the aliases database with puppet' do + args = ['ensure=absent', + 'recipient="foo,bar,baz"'] + on(agent, puppet_resource('mailalias', name, args)) + end + + it 'verifies the alias is absent' do + on(agent, 'cat /etc/aliases') do |res| + assert_no_match(%r{#{name}:.*foo,bar,baz}, res.stdout, 'mailalias was not removed from aliases file') + end + end + end +end diff --git a/spec/acceptance/tests/modify_spec.rb b/spec/acceptance/tests/modify_spec.rb new file mode 100644 index 0000000..f4ea7bf --- /dev/null +++ b/spec/acceptance/tests/modify_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper_acceptance' + +RSpec.context 'should modify an email alias' do + name = "pl#{rand(999_999).to_i}" + + before(:all) do + non_windows_agents.each do |agent| + #------- SETUP -------# + # (setup) backup alias file + on(agent, 'cp /etc/aliases /tmp/aliases', acceptable_exit_codes: [0, 1]) + + # (setup) create a mailalias + on(agent, "echo '#{name}: foo,bar,baz' >> /etc/aliases") + + # (setup) verify the alias exists + on(agent, 'cat /etc/aliases') do |res| + assert_match(%r{#{name}:.*foo,bar,baz}, res.stdout, 'mailalias not in aliases file') + end + end + end + + after(:all) do + non_windows_agents.each do |agent| + # (teardown) restore the alias file + on(agent, 'mv /tmp/aliases /etc/aliases', acceptable_exit_codes: [0, 1]) + end + end + + non_windows_agents.each do |agent| + it 'modifies the aliases database with puppet' do + args = ['ensure=present', + 'recipient="foo,bar,baz,blarvitz"'] + on(agent, puppet_resource('mailalias', name, args)) + end + + it 'verifies the updated alias is present' do + on(agent, 'cat /etc/aliases') do |res| + assert_match(%r{#{name}:.*foo,bar,baz,blarvitz}, res.stdout, 'updated mailalias not in aliases file') + end + end + end +end diff --git a/spec/acceptance/tests/query_spec.rb b/spec/acceptance/tests/query_spec.rb new file mode 100644 index 0000000..17e0bbf --- /dev/null +++ b/spec/acceptance/tests/query_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper_acceptance' + +RSpec.context 'should be able to find an exisitng email alias' do + name = "pl#{rand(999_999).to_i}" + + before(:all) do + non_windows_agents.each do |agent| + # (setup) backup alias file + on(agent, 'cp /etc/aliases /tmp/aliases', acceptable_exit_codes: [0, 1]) + + # (setup) create a mailalias + on(agent, "echo '#{name}: foo,bar,baz' >> /etc/aliases") + + # (setup) verify the alias exists + on(agent, 'cat /etc/aliases') do |res| + assert_match(%r{#{name}:.*foo,bar,baz}, res.stdout, 'mailalias not in aliases file') + end + end + end + + after(:all) do + non_windows_agents.each do |agent| + # (teardown) restore the alias file + on(agent, 'mv /tmp/aliases /etc/aliases', acceptable_exit_codes: [0, 1]) + end + end + + non_windows_agents.each do |agent| + it 'queries for the mail alias with puppet' do + on(agent, puppet_resource('mailalias', name)) do + fail_test "didn't find the scheduled_task #{name}" unless stdout.include? 'present' + end + end + end +end diff --git a/spec/default_facts.yml b/spec/default_facts.yml new file mode 100644 index 0000000..3248be5 --- /dev/null +++ b/spec/default_facts.yml @@ -0,0 +1,8 @@ +# Use default_module_facts.yml for module specific facts. +# +# Facts specified here will override the values provided by rspec-puppet-facts. +--- +concat_basedir: "/tmp" +ipaddress: "172.16.254.254" +is_pe: false +macaddress: "AA:AA:AA:AA:AA:AA" diff --git a/spec/fixtures/integration/provider/mailalias/aliases/test1 b/spec/fixtures/integration/provider/mailalias/aliases/test1 new file mode 100644 index 0000000..a69be8a --- /dev/null +++ b/spec/fixtures/integration/provider/mailalias/aliases/test1 @@ -0,0 +1,31 @@ +# Basic system aliases -- these MUST be present +MAILER-DAEMON: postmaster +postmaster: root + +# General redirections for pseudo accounts +bin: root +daemon: root +named: root +nobody: root +uucp: root +www: root +ftp-bugs: root +postfix: root + +# Put your local aliases here. + +# Well-known aliases +manager: root +dumper: root +operator: root +abuse: postmaster + +# trap decode to catch security attacks +decode: root + +# Other tests +anothertest: "|/path/to/rt-mailgate --queue 'another test' --action correspond --url http://my.com/" +test: "|/path/to/rt-mailgate --queue 'test' --action correspond --url http://my.com/" + +# Included file +incfile: :include: /tmp/somefile diff --git a/spec/integration/provider/mailalias/aliases_spec.rb b/spec/integration/provider/mailalias/aliases_spec.rb new file mode 100644 index 0000000..ae9dc10 --- /dev/null +++ b/spec/integration/provider/mailalias/aliases_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' +require 'shared_behaviours/all_parsedfile_providers' + +provider_class = Puppet::Type.type(:mailalias).provider(:aliases) + +describe provider_class do + # #1560, in which we corrupt the format of complex mail aliases. + it_behaves_like 'all parsedfile providers', provider_class +end diff --git a/spec/lib/puppet_spec/files.rb b/spec/lib/puppet_spec/files.rb new file mode 100644 index 0000000..5fef530 --- /dev/null +++ b/spec/lib/puppet_spec/files.rb @@ -0,0 +1,123 @@ +require 'fileutils' +require 'tempfile' +require 'tmpdir' +require 'pathname' + +# A support module for testing files. +module PuppetSpec::Files + @global_tempfiles = [] + + def self.cleanup + until @global_tempfiles.empty? + path = @global_tempfiles.pop + begin + Dir.unstub(:entries) + FileUtils.rm_rf path, secure: true + end + end + end + + def make_absolute(path) + PuppetSpec::Files.make_absolute(path) + end + + def self.make_absolute(path) + path = File.expand_path(path) + path[0] = 'c' if Puppet.features.microsoft_windows? + path + end + + def tmpfile(name, dir = nil) + PuppetSpec::Files.tmpfile(name, dir) + end + + def self.tmpfile(name, dir = nil) + # Generate a temporary file, just for the name... + source = dir ? Tempfile.new(name, dir) : Tempfile.new(name) + path = Puppet::FileSystem.expand_path(source.path.encode(Encoding::UTF_8)) + source.close! + + record_tmp(File.expand_path(path)) + + path + end + + def file_containing(name, contents) + PuppetSpec::Files.file_containing(name, contents) + end + + def self.file_containing(name, contents) + file = tmpfile(name) + File.open(file, 'wb') { |f| f.write(contents) } + file + end + + def script_containing(name, contents) + PuppetSpec::Files.script_containing(name, contents) + end + + def self.script_containing(name, contents) + file = tmpfile(name) + if Puppet.features.microsoft_windows? + file += '.bat' + text = contents[:windows] + else + text = contents[:posix] + end + File.open(file, 'wb') { |f| f.write(text) } + Puppet::FileSystem.chmod(0o755, file) + file + end + + def tmpdir(name) + PuppetSpec::Files.tmpdir(name) + end + + def self.tmpdir(name) + dir = Puppet::FileSystem.expand_path(Dir.mktmpdir(name).encode!(Encoding::UTF_8)) + + record_tmp(dir) + + dir + end + + def dir_containing(name, contents_hash) + PuppetSpec::Files.dir_containing(name, contents_hash) + end + + def self.dir_containing(name, contents_hash) + dir_contained_in(tmpdir(name), contents_hash) + end + + def dir_contained_in(dir, contents_hash) + PuppetSpec::Files.dir_contained_in(dir, contents_hash) + end + + def self.dir_contained_in(dir, contents_hash) + contents_hash.each do |k, v| + if v.is_a?(Hash) + Dir.mkdir(tmp = File.join(dir, k)) + dir_contained_in(tmp, v) + else + file = File.join(dir, k) + File.open(file, 'wb') { |f| f.write(v) } + end + end + dir + end + + def self.record_tmp(tmp) + # ...record it for cleanup, + @global_tempfiles << tmp + end + + def expect_file_mode(file, mode) + actual_mode = '%o' % Puppet::FileSystem.stat(file).mode + target_mode = if Puppet.features.microsoft_windows? + mode + else + '10' + '%04i' % mode.to_i + end + expect(actual_mode).to eq(target_mode) + end +end diff --git a/spec/shared_behaviours/all_parsedfile_providers.rb b/spec/shared_behaviours/all_parsedfile_providers.rb new file mode 100644 index 0000000..d697a14 --- /dev/null +++ b/spec/shared_behaviours/all_parsedfile_providers.rb @@ -0,0 +1,21 @@ +shared_examples_for 'all parsedfile providers' do |provider, *files| + if files.empty? + files = my_fixtures + end + + files.flatten.each do |file| + it "should rewrite #{file} reasonably unchanged" do + provider.stubs(:default_target).returns(file) + provider.prefetch + + text = provider.to_file(provider.target_records(file)) + text.gsub!(%r{^# HEADER.+\n}, '') + + oldlines = File.readlines(file) + newlines = text.chomp.split "\n" + oldlines.zip(newlines).each do |old, new| + expect(new.gsub(%r{\s+}, '')).to eq(old.chomp.gsub(%r{\s+}, '')) + end + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..9885e2d --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,44 @@ +require 'puppetlabs_spec_helper/module_spec_helper' +require 'rspec-puppet-facts' + +begin + require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb')) +rescue LoadError => loaderror + warn "Could not require spec_helper_local: #{loaderror.message}" +end + +include RspecPuppetFacts + +default_facts = { + puppetversion: Puppet.version, + facterversion: Facter.version, +} + +default_facts_path = File.expand_path(File.join(File.dirname(__FILE__), 'default_facts.yml')) +default_module_facts_path = File.expand_path(File.join(File.dirname(__FILE__), 'default_module_facts.yml')) + +if File.exist?(default_facts_path) && File.readable?(default_facts_path) + default_facts.merge!(YAML.safe_load(File.read(default_facts_path))) +end + +if File.exist?(default_module_facts_path) && File.readable?(default_module_facts_path) + default_facts.merge!(YAML.safe_load(File.read(default_module_facts_path))) +end + +RSpec.configure do |c| + c.default_facts = default_facts +end + +dir = File.expand_path(File.dirname(__FILE__)) +$LOAD_PATH.unshift File.join(dir, 'lib') + +# So everyone else doesn't have to include this base constant. +module PuppetSpec + FIXTURE_DIR = File.join(File.expand_path(File.dirname(__FILE__)), 'fixtures') unless defined?(FIXTURE_DIR) +end + +require 'puppet_spec/files' + +Pathname.glob("#{dir}/shared_behaviours/**/*.rb") do |behaviour| + require behaviour.relative_path_from(Pathname.new(dir)) +end diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb new file mode 100644 index 0000000..0adde24 --- /dev/null +++ b/spec/spec_helper_acceptance.rb @@ -0,0 +1,24 @@ +require 'puppet' +require 'beaker-rspec' +require 'beaker/module_install_helper' +require 'beaker/puppet_install_helper' + +$LOAD_PATH << File.join(__dir__, 'acceptance/lib') + +def beaker_opts + { debug: true, trace: true, expect_failures: true, acceptable_exit_codes: (0...256) } +end + +def non_windows_agents + agents.reject { |agent| agent['platform'].include?('windows') } +end + +RSpec.configure do |c| + c.before :suite do + unless ENV['BEAKER_provision'] == 'no' + run_puppet_install_helper + install_module_on(hosts_as(hosts)) + install_module_dependencies_on(hosts) + end + end +end diff --git a/spec/unit/type/mailalias_spec.rb b/spec/unit/type/mailalias_spec.rb new file mode 100644 index 0000000..1fb195e --- /dev/null +++ b/spec/unit/type/mailalias_spec.rb @@ -0,0 +1,54 @@ +require 'spec_helper' + +describe Puppet::Type.type(:mailalias) do + include PuppetSpec::Files + + let :tmpfile_path do + tmpfile('afile') + end + + let :target do + tmpfile('mailalias') + end + + let :recipient_resource do + described_class.new(name: 'luke', recipient: 'yay', target: target) + end + + let :file_resource do + described_class.new(name: 'lukefile', file: tmpfile_path, target: target) + end + + it 'is initially absent as a recipient' do + expect(recipient_resource.retrieve_resource[:recipient]).to eq(:absent) + end + + it 'is initially absent as an included file' do + expect(file_resource.retrieve_resource[:file]).to eq(:absent) + end + + it 'tries and set the recipient when it does the sync' do + expect(recipient_resource.retrieve_resource[:recipient]).to eq(:absent) + recipient_resource.property(:recipient).expects(:set).with(['yay']) + recipient_resource.property(:recipient).sync + end + + it 'tries and set the included file when it does the sync' do + expect(file_resource.retrieve_resource[:file]).to eq(:absent) + file_resource.property(:file).expects(:set).with(tmpfile_path) + file_resource.property(:file).sync + end + + it 'fails when file is not an absolute path' do + expect { + Puppet::Type.type(:mailalias).new(name: 'x', file: 'afile') + }.to raise_error Puppet::Error, %r{File paths must be fully qualified} + end + + it 'fails when both file and recipient are specified' do + expect { + Puppet::Type.type(:mailalias).new(name: 'x', file: tmpfile_path, + recipient: 'foo@example.com') + }.to raise_error Puppet::Error, %r{cannot specify both a recipient and a file} + end +end |