diff options
author | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2018-09-20 14:50:39 +0200 |
---|---|---|
committer | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2018-09-20 14:50:39 +0200 |
commit | 6162b571d3dea04957ba6712a4191b83c8fb2c89 (patch) | |
tree | b77e271107d885984ba2ec394c908ca5519f7558 /code/environments/production/modules/stdlib/spec/unit | |
parent | 3f1bbf87bbcc3daa15cd7391b2949b5bf742781b (diff) | |
download | puppet.FWSECK-6162b571d3dea04957ba6712a4191b83c8fb2c89.tar.gz puppet.FWSECK-6162b571d3dea04957ba6712a4191b83c8fb2c89.tar.bz2 puppet.FWSECK-6162b571d3dea04957ba6712a4191b83c8fb2c89.zip |
Bundles puppetlabs-stdlib 4.25.1.
Diffstat (limited to 'code/environments/production/modules/stdlib/spec/unit')
13 files changed, 1340 insertions, 0 deletions
diff --git a/code/environments/production/modules/stdlib/spec/unit/facter/facter_dot_d_spec.rb b/code/environments/production/modules/stdlib/spec/unit/facter/facter_dot_d_spec.rb new file mode 100644 index 0000000..49707ab --- /dev/null +++ b/code/environments/production/modules/stdlib/spec/unit/facter/facter_dot_d_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' +require 'facter/facter_dot_d' + +describe Facter::Util::DotD do # rubocop:disable RSpec/FilePath : Spec path is as it should be + context 'with a simple fact' do + before :each do + Facter.stubs(:version).returns('1.6.1') + subject.stubs(:entries).returns(['/etc/facter/facts.d/fake_fact.txt']) + File.stubs(:readlines).with('/etc/facter/facts.d/fake_fact.txt').returns(['fake_fact=fake fact']) + subject.create + end + + it 'returns successfully' do + expect(Facter.fact(:fake_fact).value).to eq('fake fact') + end + end + + context 'with a fact with equals signs' do + before :each do + Facter.stubs(:version).returns('1.6.1') + subject.stubs(:entries).returns(['/etc/facter/facts.d/foo.txt']) + File.stubs(:readlines).with('/etc/facter/facts.d/foo.txt').returns(['foo=1+1=2']) + subject.create + end + + it 'returns successfully' do + expect(Facter.fact(:foo).value).to eq('1+1=2') + end + end +end diff --git a/code/environments/production/modules/stdlib/spec/unit/facter/package_provider_spec.rb b/code/environments/production/modules/stdlib/spec/unit/facter/package_provider_spec.rb new file mode 100644 index 0000000..2ebfe2d --- /dev/null +++ b/code/environments/production/modules/stdlib/spec/unit/facter/package_provider_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper' +require 'puppet/type' +require 'puppet/type/package' + +describe 'package_provider', :type => :fact do + before(:each) { Facter.clear } + after(:each) { Facter.clear } + + ['4.2.2', '3.7.1 (Puppet Enterprise 3.2.1)'].each do |puppetversion| + describe "on puppet ''#{puppetversion}''" do + before :each do + Facter.stubs(:value).returns puppetversion + end + + context 'when darwin' do + it 'returns pkgdmg' do + provider = Puppet::Type.type(:package).provider(:pkgdmg) + Puppet::Type.type(:package).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:package_provider).value).to eq('pkgdmg') + end + end + + context 'when centos 7' do + it 'returns yum' do + provider = Puppet::Type.type(:package).provider(:yum) + Puppet::Type.type(:package).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:package_provider).value).to eq('yum') + end + end + + context 'when ubuntu' do + it 'returns apt' do + provider = Puppet::Type.type(:package).provider(:apt) + Puppet::Type.type(:package).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:package_provider).value).to eq('apt') + end + end + end + end +end diff --git a/code/environments/production/modules/stdlib/spec/unit/facter/pe_version_spec.rb b/code/environments/production/modules/stdlib/spec/unit/facter/pe_version_spec.rb new file mode 100644 index 0000000..73c4bfd --- /dev/null +++ b/code/environments/production/modules/stdlib/spec/unit/facter/pe_version_spec.rb @@ -0,0 +1,88 @@ +require 'spec_helper' + +describe 'PE Version specs' do + before :each do + # Explicitly load the pe_version.rb file which contains generated facts + # that cannot be automatically loaded. Puppet 2.x implements + # Facter.collection.load while Facter 1.x markes Facter.collection.load as + # a private method. + if Facter.collection.respond_to? :load + Facter.collection.load(:pe_version) + else + Facter.collection.loader.load(:pe_version) + end + end + + context 'when puppetversion is nil' do + before :each do + Facter.fact(:puppetversion).stubs(:value).returns(nil) + end + + it 'puppetversion is nil' do + expect(Facter.fact(:puppetversion).value).to be_nil + end + + it 'pe_version is nil' do + expect(Facter.fact(:pe_version).value).to be_nil + end + end + + context 'when PE is installed' do + %w[2.6.1 2.10.300].each do |version| + puppetversion = "2.7.19 (Puppet Enterprise #{version})" + context "puppetversion => #{puppetversion}" do + before :each do + Facter.fact(:puppetversion).stubs(:value).returns(puppetversion) + end + + (major, minor, patch) = version.split('.') + + it 'returns true' do + expect(Facter.fact(:is_pe).value).to eq(true) + end + + it "Should have a version of #{version}" do + expect(Facter.fact(:pe_version).value).to eq(version) + end + + it "Should have a major version of #{major}" do + expect(Facter.fact(:pe_major_version).value).to eq(major) + end + + it "Should have a minor version of #{minor}" do + expect(Facter.fact(:pe_minor_version).value).to eq(minor) + end + + it "Should have a patch version of #{patch}" do + expect(Facter.fact(:pe_patch_version).value).to eq(patch) + end + end + end + end + + context 'when PE is not installed' do + before :each do + Facter.fact(:puppetversion).stubs(:value).returns('2.7.19') + end + + it 'is_pe is false' do + expect(Facter.fact(:is_pe).value).to eq(false) + end + + it 'pe_version is nil' do + expect(Facter.fact(:pe_version).value).to be_nil + end + + it 'pe_major_version is nil' do + expect(Facter.fact(:pe_major_version).value).to be_nil + end + + it 'pe_minor_version is nil' do + expect(Facter.fact(:pe_minor_version).value).to be_nil + end + + it 'has a patch version' do + expect(Facter.fact(:pe_patch_version).value).to be_nil + end + end +end diff --git a/code/environments/production/modules/stdlib/spec/unit/facter/root_home_spec.rb b/code/environments/production/modules/stdlib/spec/unit/facter/root_home_spec.rb new file mode 100644 index 0000000..656f65d --- /dev/null +++ b/code/environments/production/modules/stdlib/spec/unit/facter/root_home_spec.rb @@ -0,0 +1,67 @@ +require 'spec_helper' +require 'facter/root_home' +describe 'Root Home Specs' do + describe Facter::Util::RootHome do + context 'when solaris' do + let(:root_ent) { 'root:x:0:0:Super-User:/:/sbin/sh' } + let(:expected_root_home) { '/' } + + it 'returns /' do + Facter::Util::Resolution.expects(:exec).with('getent passwd root').returns(root_ent) + expect(described_class.returnt_root_home).to eq(expected_root_home) + end + end + context 'when linux' do + let(:root_ent) { 'root:x:0:0:root:/root:/bin/bash' } + let(:expected_root_home) { '/root' } + + it 'returns /root' do + Facter::Util::Resolution.expects(:exec).with('getent passwd root').returns(root_ent) + expect(described_class.returnt_root_home).to eq(expected_root_home) + end + end + context 'when windows' do + before :each do + Facter::Util::Resolution.expects(:exec).with('getent passwd root').returns(nil) + end + it 'is nil on windows' do + expect(described_class.returnt_root_home).to be_nil + end + end + end + + describe 'root_home', :type => :fact do + before(:each) { Facter.clear } + after(:each) { Facter.clear } + + context 'when macosx' do + before(:each) do + Facter.fact(:kernel).stubs(:value).returns('Darwin') + Facter.fact(:osfamily).stubs(:value).returns('Darwin') + end + let(:expected_root_home) { '/var/root' } + + sample_dscacheutil = File.read(fixtures('dscacheutil', 'root')) + + it 'returns /var/root' do + Facter::Util::Resolution.stubs(:exec).with('dscacheutil -q user -a name root').returns(sample_dscacheutil) + expect(Facter.fact(:root_home).value).to eq(expected_root_home) + end + end + + context 'when aix' do + before(:each) do + Facter.fact(:kernel).stubs(:value).returns('AIX') + Facter.fact(:osfamily).stubs(:value).returns('AIX') + end + let(:expected_root_home) { '/root' } + + sample_lsuser = File.read(fixtures('lsuser', 'root')) + + it 'returns /root' do + Facter::Util::Resolution.stubs(:exec).with('lsuser -c -a home root').returns(sample_lsuser) + expect(Facter.fact(:root_home).value).to eq(expected_root_home) + end + end + end +end diff --git a/code/environments/production/modules/stdlib/spec/unit/facter/service_provider_spec.rb b/code/environments/production/modules/stdlib/spec/unit/facter/service_provider_spec.rb new file mode 100644 index 0000000..202f7c0 --- /dev/null +++ b/code/environments/production/modules/stdlib/spec/unit/facter/service_provider_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' +require 'puppet/type' +require 'puppet/type/service' + +describe 'service_provider', :type => :fact do + before(:each) { Facter.clear } + after(:each) { Facter.clear } + + context 'when macosx' do + it 'returns launchd' do + provider = Puppet::Type.type(:service).provider(:launchd) + Puppet::Type.type(:service).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:service_provider).value).to eq('launchd') + end + end + + context 'when systemd' do + it 'returns systemd' do + provider = Puppet::Type.type(:service).provider(:systemd) + Puppet::Type.type(:service).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:service_provider).value).to eq('systemd') + end + end + + context 'when redhat' do + it 'returns redhat' do + provider = Puppet::Type.type(:service).provider(:redhat) + Puppet::Type.type(:service).stubs(:defaultprovider).returns provider + + expect(Facter.fact(:service_provider).value).to eq('redhat') + end + end +end diff --git a/code/environments/production/modules/stdlib/spec/unit/facter/util/puppet_settings_spec.rb b/code/environments/production/modules/stdlib/spec/unit/facter/util/puppet_settings_spec.rb new file mode 100644 index 0000000..dd870bb --- /dev/null +++ b/code/environments/production/modules/stdlib/spec/unit/facter/util/puppet_settings_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' +require 'facter/util/puppet_settings' + +describe Facter::Util::PuppetSettings do + describe '#with_puppet' do + context 'without Puppet loaded' do + before(:each) do + Module.expects(:const_get).with('Puppet').raises(NameError) + end + + it 'is nil' do + expect(subject.with_puppet { Puppet[:vardir] }).to be_nil + end + it 'does not yield to the block' do + Puppet.expects(:[]).never + expect(subject.with_puppet { Puppet[:vardir] }).to be_nil + end + end + context 'with Puppet loaded' do + module Puppet; end + let(:vardir) { '/var/lib/puppet' } + + before :each do + Puppet.expects(:[]).with(:vardir).returns vardir + end + + it 'yields to the block' do + subject.with_puppet { Puppet[:vardir] } + end + it 'returns the nodes vardir' do + expect(subject.with_puppet { Puppet[:vardir] }).to eq vardir + end + end + end +end diff --git a/code/environments/production/modules/stdlib/spec/unit/puppet/parser/functions/enclose_ipv6_spec.rb b/code/environments/production/modules/stdlib/spec/unit/puppet/parser/functions/enclose_ipv6_spec.rb new file mode 100644 index 0000000..c2a237e --- /dev/null +++ b/code/environments/production/modules/stdlib/spec/unit/puppet/parser/functions/enclose_ipv6_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper' + +describe 'the enclose_ipv6 function' do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + it 'exists' do + expect(Puppet::Parser::Functions.function('enclose_ipv6')).to eq('function_enclose_ipv6') + end + + it 'raises a ParseError if there is less than 1 arguments' do + expect { scope.function_enclose_ipv6([]) }.to(raise_error(Puppet::ParseError)) + end + + it 'raises a ParseError if there is more than 1 arguments' do + expect { scope.function_enclose_ipv6(%w[argument1 argument2]) }.to(raise_error(Puppet::ParseError)) + end + + it 'raises a ParseError when given garbage' do + expect { scope.function_enclose_ipv6(['garbage']) }.to(raise_error(Puppet::ParseError)) + end + + it 'raises a ParseError when given something else than a string or an array' do + expect { scope.function_enclose_ipv6([['1' => '127.0.0.1']]) }.to(raise_error(Puppet::ParseError)) + end + + it 'does not raise a ParseError when given a single ip string' do + expect { scope.function_enclose_ipv6(['127.0.0.1']) }.not_to raise_error + end + + it 'does not raise a ParseError when given * as ip string' do + expect { scope.function_enclose_ipv6(['*']) }.not_to raise_error + end + + it 'does not raise a ParseError when given an array of ip strings' do + expect { scope.function_enclose_ipv6([['127.0.0.1', 'fe80::1']]) }.not_to raise_error + end + + it 'does not raise a ParseError when given differently notations of ip addresses' do + expect { scope.function_enclose_ipv6([['127.0.0.1', 'fe80::1', '[fe80::1]']]) }.not_to raise_error + end + + it 'raises a ParseError when given a wrong ipv4 address' do + expect { scope.function_enclose_ipv6(['127..0.0.1']) }.to(raise_error(Puppet::ParseError)) + end + + it 'raises a ParseError when given a ipv4 address with square brackets' do + expect { scope.function_enclose_ipv6(['[127.0.0.1]']) }.to(raise_error(Puppet::ParseError)) + end + + it 'raises a ParseError when given a wrong ipv6 address' do + expect { scope.function_enclose_ipv6(['fe80:::1']) }.to(raise_error(Puppet::ParseError)) + end + + it 'embraces ipv6 adresses within an array of ip addresses' do + result = scope.function_enclose_ipv6([['127.0.0.1', 'fe80::1', '[fe80::2]']]) + expect(result).to(eq(['127.0.0.1', '[fe80::1]', '[fe80::2]'])) + end + + it 'embraces a single ipv6 adresse' do + result = scope.function_enclose_ipv6(['fe80::1']) + expect(result).to(eq(['[fe80::1]'])) + end + + it 'does not embrace a single ipv4 adresse' do + result = scope.function_enclose_ipv6(['127.0.0.1']) + expect(result).to(eq(['127.0.0.1'])) + end +end diff --git a/code/environments/production/modules/stdlib/spec/unit/puppet/parser/functions/is_absolute_path_spec.rb b/code/environments/production/modules/stdlib/spec/unit/puppet/parser/functions/is_absolute_path_spec.rb new file mode 100644 index 0000000..589ad82 --- /dev/null +++ b/code/environments/production/modules/stdlib/spec/unit/puppet/parser/functions/is_absolute_path_spec.rb @@ -0,0 +1,87 @@ +require 'spec_helper' + +describe 'is_absolute_path' do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + let(:function_args) do + [] + end + + let(:function) do + scope.function_is_absolute_path(function_args) + end + + describe 'validate arity' do + let(:function_args) do + [1, 2] + end + + it 'raises a ParseError if there is more than 1 arguments' do + -> { function }.should(raise_error(ArgumentError)) + end + end + + it 'exists' do + Puppet::Parser::Functions.function(subject).should == "function_#{subject}" + end + + # help enforce good function defination + it 'contains arity' do + end + + it 'raises a ParseError if there is less than 1 arguments' do + -> { function }.should(raise_error(ArgumentError)) + end + + describe 'should retrun true' do + let(:return_value) do + true + end + + describe 'windows' do + let(:function_args) do + ['c:\temp\test.txt'] + end + + it 'returns data' do + function.should eq(return_value) + end + end + + describe 'non-windows' do + let(:function_args) do + ['/temp/test.txt'] + end + + it 'returns data' do + function.should eq(return_value) + end + end + end + + describe 'should return false' do + let(:return_value) do + false + end + + describe 'windows' do + let(:function_args) do + ['..\temp\test.txt'] + end + + it 'returns data' do + function.should eq(return_value) + end + end + + describe 'non-windows' do + let(:function_args) do + ['../var/lib/puppet'] + end + + it 'returns data' do + function.should eq(return_value) + end + end + end +end diff --git a/code/environments/production/modules/stdlib/spec/unit/puppet/provider/file_line/ruby_spec.rb b/code/environments/production/modules/stdlib/spec/unit/puppet/provider/file_line/ruby_spec.rb new file mode 100644 index 0000000..d0f653a --- /dev/null +++ b/code/environments/production/modules/stdlib/spec/unit/puppet/provider/file_line/ruby_spec.rb @@ -0,0 +1,258 @@ +require 'spec_helper' + +provider_class = Puppet::Type.type(:file_line).provider(:ruby) +# These tests fail on windows when run as part of the rake task. Individually they pass +describe provider_class, :unless => Puppet::Util::Platform.windows? do + include PuppetlabsSpec::Files + + let :tmpfile do + tmpfilename('file_line_test') + end + let :content do + '' + end + let :params do + {} + end + let :resource do + Puppet::Type::File_line.new({ + :name => 'foo', + :path => tmpfile, + :line => 'foo', + }.merge(params)) + end + let :provider do + provider_class.new(resource) + end + + before :each do + File.open(tmpfile, 'w') do |fh| + fh.write(content) + end + end + + describe 'line parameter' do + context 'when line exists' do + let(:content) { 'foo' } + + it 'detects the line' do + expect(provider).to be_exists + end + end + context 'when line does not exist' do + let(:content) { 'foo bar' } + + it 'requests changes' do + expect(provider).not_to be_exists + end + it 'appends the line' do + provider.create + expect(File.read(tmpfile).chomp).to eq("foo bar\nfoo") + end + end + end + + describe 'match parameter' do + let(:params) { { :match => '^bar' } } + + describe 'does not match line - line does not exist - replacing' do + let(:content) { "foo bar\nbar" } + + it 'requests changes' do + expect(provider).not_to be_exists + end + it 'replaces the match' do + provider.create + expect(File.read(tmpfile).chomp).to eq("foo bar\nfoo") + end + end + + describe 'does not match line - line does not exist - appending' do + let(:params) { super().merge(:replace => false) } + let(:content) { "foo bar\nbar" } + + it 'does not request changes' do + expect(provider).to be_exists + end + end + + context 'when does not match line - line exists' do + let(:content) { "foo\nbar" } + + it 'detects the line' do + expect(provider).to be_exists + end + end + + context 'when matches line - line exists' do + let(:params) { { :match => '^foo' } } + let(:content) { "foo\nbar" } + + it 'detects the line' do + expect(provider).to be_exists + end + end + + context 'when matches line - line does not exist' do + let(:params) { { :match => '^foo' } } + let(:content) { "foo bar\nbar" } + + it 'requests changes' do + expect(provider).not_to be_exists + end + it 'replaces the match' do + provider.create + expect(File.read(tmpfile).chomp).to eq("foo\nbar") + end + end + end + + describe 'append_on_no_match' do + let(:params) do + { + :append_on_no_match => false, + :match => '^foo1$', + } + end + + context 'when matching' do + let(:content) { "foo1\nbar" } + + it 'requests changes' do + expect(provider).not_to be_exists + end + it 'replaces the match' do + provider.create + expect(File.read(tmpfile).chomp).to eql("foo\nbar") + end + end + context 'when not matching' do + let(:content) { "foo3\nbar" } + + it 'does not affect the file' do + expect(provider).to be_exists + end + end + end + + describe 'replace_all_matches_not_matching_line' do + context 'when replace is false' do + let(:params) do + { + :replace_all_matches_not_matching_line => true, + :replace => false, + } + end + + it 'raises an error' do + expect { provider.exists? }.to raise_error(Puppet::Error, %r{replace must be true}) + end + end + + context 'when match matches line - when there are more matches than lines' do + let(:params) do + { + :replace_all_matches_not_matching_line => true, + :match => '^foo', + :multiple => true, + } + end + let(:content) { "foo\nfoo bar\nbar\nfoo baz" } + + it 'requests changes' do + expect(provider).not_to be_exists + end + it 'replaces the matches' do + provider.create + expect(File.read(tmpfile).chomp).to eql("foo\nfoo\nbar\nfoo") + end + end + + context 'when match matches line - when there are the same matches and lines' do + let(:params) do + { + :replace_all_matches_not_matching_line => true, + :match => '^foo', + :multiple => true, + } + end + let(:content) { "foo\nfoo\nbar" } + + it 'does not request changes' do + expect(provider).to be_exists + end + end + + context 'when match does not match line - when there are more matches than lines' do + let(:params) do + { + :replace_all_matches_not_matching_line => true, + :match => '^bar', + :multiple => true, + } + end + let(:content) { "foo\nfoo bar\nbar\nbar baz" } + + it 'requests changes' do + expect(provider).not_to be_exists + end + it 'replaces the matches' do + provider.create + expect(File.read(tmpfile).chomp).to eql("foo\nfoo bar\nfoo\nfoo") + end + end + + context 'when match does not match line - when there are the same matches and lines' do + let(:params) do + { + :replace_all_matches_not_matching_line => true, + :match => '^bar', + :multiple => true, + } + end + let(:content) { "foo\nfoo\nbar\nbar baz" } + + it 'requests changes' do + expect(provider).not_to be_exists + end + it 'replaces the matches' do + provider.create + expect(File.read(tmpfile).chomp).to eql("foo\nfoo\nfoo\nfoo") + end + end + end + + context 'when match does not match line - when there are no matches' do + let(:params) do + { + :replace_all_matches_not_matching_line => true, + :match => '^bar', + :multiple => true, + } + end + let(:content) { "foo\nfoo bar" } + + it 'does not request changes' do + expect(provider).to be_exists + end + end + + context 'when match does not match line - when there are no matches or lines' do + let(:params) do + { + :replace_all_matches_not_matching_line => true, + :match => '^bar', + :multiple => true, + } + end + let(:content) { 'foo bar' } + + it 'requests changes' do + expect(provider).not_to be_exists + end + it 'appends the line' do + provider.create + expect(File.read(tmpfile).chomp).to eql("foo bar\nfoo") + end + end +end diff --git a/code/environments/production/modules/stdlib/spec/unit/puppet/provider/file_line/ruby_spec_alter.rb b/code/environments/production/modules/stdlib/spec/unit/puppet/provider/file_line/ruby_spec_alter.rb new file mode 100644 index 0000000..c2b30ff --- /dev/null +++ b/code/environments/production/modules/stdlib/spec/unit/puppet/provider/file_line/ruby_spec_alter.rb @@ -0,0 +1,374 @@ +require 'spec_helper' + +provider_class = Puppet::Type.type(:file_line).provider(:ruby) +# These tests fail on windows when run as part of the rake task. Individually they pass +describe provider_class, :unless => Puppet::Util::Platform.windows? do + include PuppetlabsSpec::Files + + let :tmpfile do + tmpfilename('file_line_test') + end + let :content do + '' + end + let :params do + {} + end + let :resource do + Puppet::Type::File_line.new({ + :name => 'foo', + :path => tmpfile, + :line => 'foo', + }.merge(params)) + end + let :provider do + provider_class.new(resource) + end + + before :each do + File.open(tmpfile, 'w') do |fh| + fh.write(content) + end + end + + describe '#create' do + context 'when adding' do + pending('To be added.') + end + context 'when replacing' do + let :params do + { + :line => 'foo = bar', + :match => '^foo\s*=.*$', + :replace => false, + } + end + let(:content) { "foo1\nfoo=blah\nfoo2\nfoo3" } + + it "providor 'be_exists'" do + expect(provider).to be_exists + end + it 'does not replace the matching line' do + provider.create + expect(File.read(tmpfile).chomp).to eql("foo1\nfoo=blah\nfoo2\nfoo3") + end + it 'appends the line if no matches are found' do + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo2") } + expect(provider.exists?).to be false + provider.create + expect(File.read(tmpfile).chomp).to eql("foo1\nfoo2\nfoo = bar") + end + it 'raises an error with invalid values' do + expect { + @resource = Puppet::Type::File_line.new( + :name => 'foo', :path => tmpfile, :line => 'foo = bar', :match => '^foo\s*=.*$', :replace => 'asgadga', + ) + }.to raise_error(Puppet::Error, %r{Invalid value "asgadga"\. Valid values are true, false\.}) + end + end + end + describe '#destroy' do + pending('To be added?') + end + context 'when matching' do + # rubocop:disable RSpec/InstanceVariable : replacing before with let breaks the tests, variables need to be altered within it block : multi + before :each do + @resource = Puppet::Type::File_line.new( + :name => 'foo', + :path => tmpfile, + :line => 'foo = bar', + :match => '^foo\s*=.*$', + ) + @provider = provider_class.new(@resource) + end + describe 'using match' do + it 'raises an error if more than one line matches, and should not have modified the file' do + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo=blah\nfoo2\nfoo=baz") } + expect { @provider.create }.to raise_error(Puppet::Error, %r{More than one line.*matches}) + expect(File.read(tmpfile)).to eql("foo1\nfoo=blah\nfoo2\nfoo=baz") + end + + it 'replaces all lines that matches' do + @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :line => 'foo = bar', :match => '^foo\s*=.*$', :multiple => true) + @provider = provider_class.new(@resource) + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo=blah\nfoo2\nfoo=baz") } + @provider.create + expect(File.read(tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2\nfoo = bar") + end + + it 'replaces all lines that match, even when some lines are correct' do + @resource = Puppet::Type::File_line.new(:name => 'neil', :path => tmpfile, :line => "\thard\tcore\t0\n", :match => '^[ \t]hard[ \t]+core[ \t]+.*', :multiple => true) + @provider = provider_class.new(@resource) + File.open(tmpfile, 'w') { |fh| fh.write("\thard\tcore\t90\n\thard\tcore\t0\n") } + @provider.create + expect(File.read(tmpfile).chomp).to eql("\thard\tcore\t0\n\thard\tcore\t0") + end + + it 'raises an error with invalid values' do + expect { + @resource = Puppet::Type::File_line.new( + :name => 'foo', :path => tmpfile, :line => 'foo = bar', :match => '^foo\s*=.*$', :multiple => 'asgadga', + ) + }.to raise_error(Puppet::Error, %r{Invalid value "asgadga"\. Valid values are true, false\.}) + end + + it 'replaces a line that matches' do + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo=blah\nfoo2") } + @provider.create + expect(File.read(tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2") + end + it 'adds a new line if no lines match' do + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo2") } + @provider.create + expect(File.read(tmpfile)).to eql("foo1\nfoo2\nfoo = bar\n") + end + it 'does nothing if the exact line already exists' do + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo = bar\nfoo2") } + @provider.create + expect(File.read(tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2") + end + end + describe 'using match+append_on_no_match - when there is a match' do + it 'replaces line' do + @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :line => 'inserted = line', :match => '^foo3$', :append_on_no_match => false) + @provider = provider_class.new(@resource) + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo = blah\nfoo2\nfoo = baz") } + expect(File.read(tmpfile).chomp).to eql("foo1\nfoo = blah\nfoo2\nfoo = baz") + end + end + describe 'using match+append_on_no_match - when there is no match' do + it 'does not add line after no matches found' do + @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :line => 'inserted = line', :match => '^foo3$', :append_on_no_match => false) + @provider = provider_class.new(@resource) + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo = blah\nfoo2\nfoo = baz") } + expect(File.read(tmpfile).chomp).to eql("foo1\nfoo = blah\nfoo2\nfoo = baz") + end + end + end + context 'when match+replace+append_on_no_match' do + pending('to do') + end + context 'when after' do + let :resource do + Puppet::Type::File_line.new( + :name => 'foo', + :path => tmpfile, + :line => 'inserted = line', + :after => '^foo1', + ) + end + + let :provider do + provider_class.new(resource) + end + + context 'when match and after set' do + shared_context 'when resource_create' do + let(:match) { '^foo2$' } + let(:after) { '^foo1$' } + let(:resource) do + Puppet::Type::File_line.new( + :name => 'foo', + :path => tmpfile, + :line => 'inserted = line', + :after => after, + :match => match, + ) + end + end + before :each do + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo2\nfoo = baz") } + end + describe 'inserts at match' do + include_context 'resource_create' + it { + provider.create + expect(File.read(tmpfile).chomp).to eq("foo1\ninserted = line\nfoo = baz") + } + end + describe 'inserts a new line after when no match' do + include_context 'resource_create' do + let(:match) { '^nevergoingtomatch$' } + end + it { + provider.create + expect(File.read(tmpfile).chomp).to eq("foo1\ninserted = line\nfoo2\nfoo = baz") + } + end + describe 'append to end of file if no match for both after and match' do + include_context 'resource_create' do + let(:match) { '^nevergoingtomatch$' } + let(:after) { '^stillneverafter' } + end + it { + provider.create + expect(File.read(tmpfile).chomp).to eq("foo1\nfoo2\nfoo = baz\ninserted = line") + } + end + end + context 'with one line matching the after expression' do + before :each do + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo = blah\nfoo2\nfoo = baz") } + end + + it 'inserts the specified line after the line matching the "after" expression' do + provider.create + expect(File.read(tmpfile).chomp).to eql("foo1\ninserted = line\nfoo = blah\nfoo2\nfoo = baz") + end + end + context 'with multiple lines matching the after expression' do + before :each do + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo = blah\nfoo2\nfoo1\nfoo = baz") } + end + + it 'errors out stating "One or no line must match the pattern"' do + expect { provider.create }.to raise_error(Puppet::Error, %r{One or no line must match the pattern}) + end + + it 'adds the line after all lines matching the after expression' do + @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :line => 'inserted = line', :after => '^foo1$', :multiple => true) + @provider = provider_class.new(@resource) + @provider.create + expect(File.read(tmpfile).chomp).to eql("foo1\ninserted = line\nfoo = blah\nfoo2\nfoo1\ninserted = line\nfoo = baz") + end + end + context 'with no lines matching the after expression' do + let :content do + "foo3\nfoo = blah\nfoo2\nfoo = baz\n" + end + + before :each do + File.open(tmpfile, 'w') { |fh| fh.write(content) } + end + + it 'appends the specified line to the file' do + provider.create + expect(File.read(tmpfile)).to eq(content << resource[:line] << "\n") + end + end + end + context 'when removing with a line' do + before :each do + # TODO: these should be ported over to use the PuppetLabs spec_helper + # file fixtures once the following pull request has been merged: + # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files + @resource = Puppet::Type::File_line.new( + :name => 'foo', + :path => tmpfile, + :line => 'foo', + :ensure => 'absent', + ) + @provider = provider_class.new(@resource) + end + it 'removes the line if it exists' do + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2") } + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2") + end + it 'removes the line without touching the last new line' do + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2\n") } + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2\n") + end + it 'removes any occurence of the line' do + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2\nfoo\nfoo") } + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2\n") + end + it 'example in the docs' do + @resource = Puppet::Type::File_line.new(:name => 'bashrc_proxy', :ensure => 'absent', :path => tmpfile, :line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128') + @provider = provider_class.new(@resource) + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo2\nexport HTTP_PROXY=http://squid.puppetlabs.vm:3128\nfoo4\n") } + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2\nfoo4\n") + end + end + context 'when removing with a match' do + before :each do + @resource = Puppet::Type::File_line.new( + :name => 'foo', + :path => tmpfile, + :line => 'foo2', + :ensure => 'absent', + :match => 'o$', + :match_for_absence => true, + ) + @provider = provider_class.new(@resource) + end + + it 'finds a line to match' do + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2") } + expect(@provider.exists?).to be true + end + + it 'removes one line if it matches' do + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2") } + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2") + end + + it 'the line parameter is actually not used at all but is silently ignored if here' do + @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :line => 'supercalifragilisticexpialidocious', :ensure => 'absent', :match => 'o$', :match_for_absence => true) + @provider = provider_class.new(@resource) + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2") } + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2") + end + + it 'and may not be here and does not need to be here' do + @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :ensure => 'absent', :match => 'o$', :match_for_absence => true) + @provider = provider_class.new(@resource) + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2") } + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2") + end + + it 'raises an error if more than one line matches' do + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2\nfoo\nfoo") } + expect { @provider.destroy }.to raise_error(Puppet::Error, %r{More than one line}) + end + + it 'removes multiple lines if :multiple is true' do + @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :line => 'foo2', :ensure => 'absent', :match => 'o$', :multiple => true, :match_for_absence => true) + @provider = provider_class.new(@resource) + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2\nfoo\nfoo") } + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2\n") + end + + it 'ignores the match if match_for_absence is not specified' do + @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :line => 'foo2', :ensure => 'absent', :match => 'o$') + @provider = provider_class.new(@resource) + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2") } + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo\n") + end + + it 'ignores the match if match_for_absence is false' do + @resource = Puppet::Type::File_line.new(:name => 'foo', :path => tmpfile, :line => 'foo2', :ensure => 'absent', :match => 'o$', :match_for_absence => false) + @provider = provider_class.new(@resource) + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo\nfoo2") } + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo\n") + end + + it 'example in the docs' do + @resource = Puppet::Type::File_line.new( + :name => 'bashrc_proxy', :ensure => 'absent', :path => tmpfile, :line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', + :match => '^export\ HTTP_PROXY\=', :match_for_absence => true + ) + @provider = provider_class.new(@resource) + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo2\nexport HTTP_PROXY=foo\nfoo4\n") } + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2\nfoo4\n") + end + + it 'example in the docs showing line is redundant' do + @resource = Puppet::Type::File_line.new(:name => 'bashrc_proxy', :ensure => 'absent', :path => tmpfile, :match => '^export\ HTTP_PROXY\=', :match_for_absence => true) + @provider = provider_class.new(@resource) + File.open(tmpfile, 'w') { |fh| fh.write("foo1\nfoo2\nexport HTTP_PROXY=foo\nfoo4\n") } + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2\nfoo4\n") + end + end +end diff --git a/code/environments/production/modules/stdlib/spec/unit/puppet/provider/file_line/ruby_spec_use_cases.rb b/code/environments/production/modules/stdlib/spec/unit/puppet/provider/file_line/ruby_spec_use_cases.rb new file mode 100644 index 0000000..5114dec --- /dev/null +++ b/code/environments/production/modules/stdlib/spec/unit/puppet/provider/file_line/ruby_spec_use_cases.rb @@ -0,0 +1,135 @@ +require 'spec_helper' + +provider_class = Puppet::Type.type(:file_line).provider(:ruby) +# These tests fail on windows when run as part of the rake task. Individually they pass +describe provider_class, :unless => Puppet::Util::Platform.windows? do + include PuppetlabsSpec::Files + + let :tmpfile do + tmpfilename('file_line_test') + end + let :content do + '' + end + let :params do + {} + end + let :resource do + Puppet::Type::File_line.new({ + :name => 'foo', + :path => tmpfile, + :line => 'foo', + }.merge(params)) + end + let :provider do + provider_class.new(resource) + end + + before :each do + File.open(tmpfile, 'w') do |fh| + fh.write(content) + end + end + + describe 'customer use cases - no lines' do + describe 'MODULES-5003' do + let(:params) do + { + :line => "*\thard\tcore\t0", + :match => "^[ \t]*\\*[ \t]+hard[ \t]+core[ \t]+.*", + :multiple => true, + } + end + let(:content) { "* hard core 90\n* hard core 10\n" } + + it 'requests changes' do + expect(provider).not_to be_exists + end + it 'replaces the matches' do + provider.create + expect(File.read(tmpfile).chomp).to eq("* hard core 0\n* hard core 0") + end + end + + describe 'MODULES-5003 - one match, one line - just ensure the line exists' do + let(:params) do + { + :line => "*\thard\tcore\t0", + :match => "^[ \t]*\\*[ \t]+hard[ \t]+core[ \t]+.*", + :multiple => true, + } + end + let(:content) { "* hard core 90\n* hard core 0\n" } + + it 'does not request changes' do + expect(provider).to be_exists + end + end + + describe 'MODULES-5003 - one match, one line - replace all matches, even when line exists' do + let(:params) do + { + :line => "*\thard\tcore\t0", + :match => "^[ \t]*\\*[ \t]+hard[ \t]+core[ \t]+.*", + :multiple => true, + + }.merge(:replace_all_matches_not_matching_line => true) + end + let(:content) { "* hard core 90\n* hard core 0\n" } + + it 'requests changes' do + expect(provider).not_to be_exists + end + it 'replaces the matches' do + provider.create + expect(File.read(tmpfile).chomp).to eq("* hard core 0\n* hard core 0") + end + end + + describe 'MODULES-5651 - match, no line' do + let(:params) do + { + :line => 'LogLevel=notice', + :match => '^#LogLevel$', + } + end + let(:content) { "#LogLevel\nstuff" } + + it 'requests changes' do + expect(provider).not_to be_exists + end + it 'replaces the match' do + provider.create + expect(File.read(tmpfile).chomp).to eq("LogLevel=notice\nstuff") + end + end + + describe 'MODULES-5651 - match, line' do + let(:params) do + { + :line => 'LogLevel=notice', + :match => '^#LogLevel$', + } + end + let(:content) { "#Loglevel\nLogLevel=notice\nstuff" } + + it 'does not request changes' do + expect(provider).to be_exists + end + end + + describe 'MODULES-5651 - no match, line' do + let(:params) do + { + :line => 'LogLevel=notice', + :match => '^#LogLevel$', + } + end + let(:content) { "LogLevel=notice\nstuff" } + + it 'does not request changes' do + expect(provider).to be_exists + end + end + end +end diff --git a/code/environments/production/modules/stdlib/spec/unit/puppet/type/anchor_spec.rb b/code/environments/production/modules/stdlib/spec/unit/puppet/type/anchor_spec.rb new file mode 100644 index 0000000..c2d9779 --- /dev/null +++ b/code/environments/production/modules/stdlib/spec/unit/puppet/type/anchor_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +anchor = Puppet::Type.type(:anchor).new(:name => 'ntp::begin') + +describe anchor do + it 'stringifies normally' do + expect(anchor.to_s).to eq('Anchor[ntp::begin]') + end +end diff --git a/code/environments/production/modules/stdlib/spec/unit/puppet/type/file_line_spec.rb b/code/environments/production/modules/stdlib/spec/unit/puppet/type/file_line_spec.rb new file mode 100644 index 0000000..627bdf0 --- /dev/null +++ b/code/environments/production/modules/stdlib/spec/unit/puppet/type/file_line_spec.rb @@ -0,0 +1,111 @@ +require 'spec_helper' +require 'tempfile' +describe Puppet::Type.type(:file_line) do + let :tmp_path do + if Puppet::Util::Platform.windows? + 'C:\tmp\path' + else + '/tmp/path' + end + end + let :my_path do + if Puppet::Util::Platform.windows? + 'C:\my\path' + else + '/my/path' + end + end + let :file_line do + Puppet::Type.type(:file_line).new(:name => 'foo', :line => 'line', :path => tmp_path) + end + + it 'accepts a line' do + file_line[:line] = 'my_line' + expect(file_line[:line]).to eq('my_line') + end + it 'accepts a path' do + file_line[:path] = my_path + expect(file_line[:path]).to eq(my_path) + end + it 'accepts a match regex' do + file_line[:match] = '^foo.*$' + expect(file_line[:match]).to eq('^foo.*$') + end + + it 'accepts a match regex that does not match the specified line' do + expect { + Puppet::Type.type(:file_line).new( + :name => 'foo', :path => my_path, :line => 'foo=bar', :match => '^bar=blah$', + ) + }.not_to raise_error + end + it 'accepts a match regex that does match the specified line' do + expect { + Puppet::Type.type(:file_line).new( + :name => 'foo', :path => my_path, :line => 'foo=bar', :match => '^\s*foo=.*$', + ) + }.not_to raise_error + end + it 'accepts utf8 characters' do + expect { + Puppet::Type.type(:file_line).new( + :name => 'ƒồỗ', :path => my_path, :line => 'ƒồỗ=ьåя', :match => '^ьåя=βļάħ$', + ) + }.not_to raise_error + end + it 'accepts double byte characters' do + expect { + Puppet::Type.type(:file_line).new( + :name => 'フーバー', :path => my_path, :line => 'この=それ', :match => '^この=ああ$', + ) + }.not_to raise_error + end + it 'accepts posix filenames' do + file_line[:path] = tmp_path + expect(file_line[:path]).to eq(tmp_path) + end + it 'does not accept unqualified path' do + expect { file_line[:path] = 'file' }.to raise_error(Puppet::Error, %r{File paths must be fully qualified}) + end + it 'requires that a line is specified' do + expect { Puppet::Type.type(:file_line).new(:name => 'foo', :path => tmp_path) }.to raise_error(Puppet::Error, %r{line is a required attribute}) + end + it 'does not require that a line is specified when matching for absence' do + expect { Puppet::Type.type(:file_line).new(:name => 'foo', :path => tmp_path, :ensure => :absent, :match_for_absence => :true, :match => 'match') }.not_to raise_error # rubocop:disable Metrics/LineLength + end + it 'although if a line is specified anyway when matching for absence it still works and the line is silently ignored' do + expect { Puppet::Type.type(:file_line).new(:name => 'foo', :path => tmp_path, :line => 'i_am_irrelevant', :ensure => :absent, :match_for_absence => :true, :match => 'match') }.not_to raise_error # rubocop:disable Metrics/LineLength + end + it 'requires that a file is specified' do + expect { Puppet::Type.type(:file_line).new(:name => 'foo', :line => 'path') }.to raise_error(Puppet::Error, %r{path is a required attribute}) + end + it 'defaults to ensure => present' do + expect(file_line[:ensure]).to eq :present + end + it 'defaults to replace => true' do + expect(file_line[:replace]).to eq :true + end + it 'defaults to encoding => UTF-8' do + expect(file_line[:encoding]).to eq 'UTF-8' + end + it 'accepts encoding => iso-8859-1' do + expect { Puppet::Type.type(:file_line).new(:name => 'foo', :path => tmp_path, :ensure => :present, :encoding => 'iso-8859-1', :line => 'bar') }.not_to raise_error + end + + it 'autorequires the file it manages' do + catalog = Puppet::Resource::Catalog.new + file = Puppet::Type.type(:file).new(:name => tmp_path) + catalog.add_resource file + catalog.add_resource file_line + relationship = file_line.autorequire.find do |rel| + (rel.source.to_s == "File[#{tmp_path}]") && (rel.target.to_s == file_line.to_s) + end + expect(relationship).to be_a Puppet::Relationship + end + + it 'does not autorequire the file it manages if it is not managed' do + catalog = Puppet::Resource::Catalog.new + catalog.add_resource file_line + expect(file_line.autorequire).to be_empty + end +end |