diff options
| author | Luke Kanies <luke@reductivelabs.com> | 2009-12-21 16:23:44 -0800 |
|---|---|---|
| committer | Luke Kanies <luke@reductivelabs.com> | 2009-12-21 16:23:44 -0800 |
| commit | 740fd6b301af89ab3aad89bca183ad1fcdc24ac4 (patch) | |
| tree | f34617a229509c373d28d67abb453e7ae2136c39 /spec | |
| parent | 8971d8beae2c409f9052f27c3f80ad3bdfff4de2 (diff) | |
| parent | 4a06379f8770c164e42bcc410d874076c6e95f24 (diff) | |
| download | puppet-740fd6b301af89ab3aad89bca183ad1fcdc24ac4.tar.gz puppet-740fd6b301af89ab3aad89bca183ad1fcdc24ac4.tar.xz puppet-740fd6b301af89ab3aad89bca183ad1fcdc24ac4.zip | |
Merge branch '0.25.x'
Conflicts:
lib/puppet/agent.rb
lib/puppet/application/puppetd.rb
lib/puppet/parser/ast/leaf.rb
lib/puppet/util/rdoc/parser.rb
Diffstat (limited to 'spec')
37 files changed, 854 insertions, 80 deletions
diff --git a/spec/integration/defaults.rb b/spec/integration/defaults.rb index 0e9a03fcb..590be1310 100755 --- a/spec/integration/defaults.rb +++ b/spec/integration/defaults.rb @@ -29,6 +29,17 @@ describe "Puppet defaults" do end end + describe "when setting the :catalog_format" do + it "should log a deprecation notice" do + Puppet.expects(:warning) + Puppet.settings[:catalog_format] = 'marshal' + end + it "should copy the value to :preferred_serialization_format" do + Puppet.settings[:catalog_format] = 'marshal' + Puppet.settings[:preferred_serialization_format].should == 'marshal' + end + end + it "should have a clientyamldir setting" do Puppet.settings[:clientyamldir].should_not be_nil end diff --git a/spec/integration/type/file.rb b/spec/integration/type/file.rb index 40f9244f1..fe6e2ddc6 100755 --- a/spec/integration/type/file.rb +++ b/spec/integration/type/file.rb @@ -223,7 +223,7 @@ describe Puppet::Type.type(:file) do end it "should not recursively manage files managed by a more specific explicit file" do - dir = tmpfile("file_source_integration_source") + dir = tmpfile("recursion_vs_explicit_1") subdir = File.join(dir, "subdir") file = File.join(subdir, "file") @@ -242,6 +242,25 @@ describe Puppet::Type.type(:file) do (File.stat(file).mode & 007777).should == 0644 end + + it "should recursively manage files even if there is an explicit file whose name is a prefix of the managed file" do + dir = tmpfile("recursion_vs_explicit_2") + + managed = File.join(dir, "file") + generated = File.join(dir, "file_with_a_name_starting_with_the_word_file") + + FileUtils.mkdir_p(dir) + File.open(managed, "w") { |f| f.puts "" } + File.open(generated, "w") { |f| f.puts "" } + + @catalog = Puppet::Resource::Catalog.new + @catalog.add_resource Puppet::Type::File.new(:name => dir, :recurse => true, :backup => false, :mode => "755") + @catalog.add_resource Puppet::Type::File.new(:name => managed, :recurse => true, :backup => false, :mode => "644") + + @catalog.apply + + (File.stat(generated).mode & 007777).should == 0755 + end end describe "when generating resources" do diff --git a/spec/unit/application/puppetd.rb b/spec/unit/application/puppetd.rb index 380608506..04c6daf32 100755 --- a/spec/unit/application/puppetd.rb +++ b/spec/unit/application/puppetd.rb @@ -40,7 +40,7 @@ describe "puppetd" do describe "in preinit" do before :each do - @pupetd.stubs(:trap) + @puppetd.stubs(:trap) end it "should catch INT" do diff --git a/spec/unit/application/puppetdoc.rb b/spec/unit/application/puppetdoc.rb index b9173752f..cb60581a4 100755 --- a/spec/unit/application/puppetdoc.rb +++ b/spec/unit/application/puppetdoc.rb @@ -290,16 +290,16 @@ describe "puppetdoc" do @puppetdoc.manifest = false Puppet.stubs(:info) Puppet.stubs(:[]).with(:trace).returns(false) - Puppet.stubs(:[]).with(:modulepath).returns('modules') - Puppet.stubs(:[]).with(:manifestdir).returns('manifests') + @env = stub 'env' + Puppet::Node::Environment.stubs(:new).returns(@env) + @env.stubs(:modulepath).returns(['modules']) + @env.stubs(:manifestdir).returns(['manifests']) @puppetdoc.options.stubs(:[]).with(:all).returns(false) @puppetdoc.options.stubs(:[]).with(:outputdir).returns('doc') Puppet.settings.stubs(:[]=).with(:document_all, false) Puppet.settings.stubs(:setdefaults) Puppet::Util::RDoc.stubs(:rdoc) @puppetdoc.stubs(:exit) - File.stubs(:expand_path).with('modules').returns('modules') - File.stubs(:expand_path).with('manifests').returns('manifests') @old = ARGV.dup ARGV.clear end @@ -331,6 +331,15 @@ describe "puppetdoc" do Puppet::Util::RDoc.expects(:manifestdoc) @puppetdoc.rdoc end + + it "should get modulepath and manifestdir values from the environment" do + @env.expects(:modulepath).returns(['envmodules1','envmodules2']) + @env.expects(:manifestdir).returns(['envmanifests1','envmanifests2']) + + Puppet::Util::RDoc.expects(:rdoc).with('doc', ['envmodules1','envmodules2','envmanifests1','envmanifests2']) + + @puppetdoc.rdoc + end end describe "in the other modes" do diff --git a/spec/unit/configurer.rb b/spec/unit/configurer.rb index 0490967ba..cd5102546 100755 --- a/spec/unit/configurer.rb +++ b/spec/unit/configurer.rb @@ -183,6 +183,12 @@ describe Puppet::Configurer, "when converting the catalog" do @agent.convert_catalog(@oldcatalog, 10).should equal(@catalog) end + it "should finalize the catalog" do + @catalog.expects(:finalize) + + @agent.convert_catalog(@oldcatalog, 10) + end + it "should record the passed retrieval time with the RAL catalog" do @catalog.expects(:retrieval_duration=).with 10 diff --git a/spec/unit/configurer/fact_handler.rb b/spec/unit/configurer/fact_handler.rb index 0c4af9554..ec60c6dcd 100755 --- a/spec/unit/configurer/fact_handler.rb +++ b/spec/unit/configurer/fact_handler.rb @@ -102,7 +102,7 @@ describe Puppet::Configurer::FactHandler do @facthandler.expects(:find_facts).returns facts - @facthandler.facts_for_uploading.should == {:facts_format => :yaml, :facts => text} + @facthandler.facts_for_uploading.should == {:facts_format => :b64_zlib_yaml, :facts => text} end it "should properly accept facts containing a '+'" do @@ -112,12 +112,12 @@ describe Puppet::Configurer::FactHandler do @facthandler.expects(:find_facts).returns facts - @facthandler.facts_for_uploading.should == {:facts_format => :yaml, :facts => text} + @facthandler.facts_for_uploading.should == {:facts_format => :b64_zlib_yaml, :facts => text} end it "should hard-code yaml as the serialization" do facts = stub 'facts' - facts.expects(:render).with(:yaml).returns "my text" + facts.expects(:render).with(:b64_zlib_yaml).returns "my text" text = CGI.escape("my text") @facthandler.expects(:find_facts).returns facts diff --git a/spec/unit/file_serving/configuration.rb b/spec/unit/file_serving/configuration.rb index f6acfad39..4621a0c82 100755 --- a/spec/unit/file_serving/configuration.rb +++ b/spec/unit/file_serving/configuration.rb @@ -104,17 +104,31 @@ describe Puppet::FileServing::Configuration do it "should allow all access to modules and plugins if no fileserver.conf exists" do FileTest.expects(:exists?).returns false # the file doesn't exist - modules = stub 'modules' + modules = stub 'modules', :empty? => true Puppet::FileServing::Mount::Modules.stubs(:new).returns(modules) modules.expects(:allow).with('*') - plugins = stub 'plugins' + plugins = stub 'plugins', :empty? => true Puppet::FileServing::Mount::Plugins.stubs(:new).returns(plugins) plugins.expects(:allow).with('*') Puppet::FileServing::Configuration.create end + it "should not allow access from all to modules and plugins if the fileserver.conf provided some rules" do + FileTest.expects(:exists?).returns false # the file doesn't exist + + modules = stub 'modules', :empty? => false + Puppet::FileServing::Mount::Modules.stubs(:new).returns(modules) + modules.expects(:allow).with('*').never + + plugins = stub 'plugins', :empty? => false + Puppet::FileServing::Mount::Plugins.stubs(:new).returns(plugins) + plugins.expects(:allow).with('*').never + + Puppet::FileServing::Configuration.create + end + it "should add modules and plugins mounts even if they are not returned by the parser" do @parser.expects(:parse).returns("one" => mock("mount")) FileTest.expects(:exists?).returns true # the file doesn't exist diff --git a/spec/unit/file_serving/metadata.rb b/spec/unit/file_serving/metadata.rb index de0c4570c..c27efd6bb 100755 --- a/spec/unit/file_serving/metadata.rb +++ b/spec/unit/file_serving/metadata.rb @@ -20,6 +20,84 @@ describe Puppet::FileServing::Metadata do it "should have a method that triggers attribute collection" do Puppet::FileServing::Metadata.new("/foo/bar").should respond_to(:collect) end + + it "should support pson serialization" do + Puppet::FileServing::Metadata.new("/foo/bar").should respond_to(:to_pson) + end + + it "should support to_pson_data_hash" do + Puppet::FileServing::Metadata.new("/foo/bar").should respond_to(:to_pson_data_hash) + end + + it "should support pson deserialization" do + Puppet::FileServing::Metadata.should respond_to(:from_pson) + end + + describe "when serializing" do + before do + @metadata = Puppet::FileServing::Metadata.new("/foo/bar") + end + it "should perform pson serialization by calling to_pson on it's pson_data_hash" do + pdh = mock "data hash" + pdh_as_pson = mock "data as pson" + @metadata.expects(:to_pson_data_hash).returns pdh + pdh.expects(:to_pson).returns pdh_as_pson + @metadata.to_pson.should == pdh_as_pson + end + + it "should serialize as FileMetadata" do + @metadata.to_pson_data_hash['document_type'].should == "FileMetadata" + end + + it "the data should include the path, relative_path, links, owner, group, mode, checksum, type, and destination" do + @metadata.to_pson_data_hash['data'].keys.sort.should == %w{ path relative_path links owner group mode checksum type destination }.sort + end + + it "should pass the path in the hash verbatum" do + @metadata.to_pson_data_hash['data']['path'] == @metadata.path + end + + it "should pass the relative_path in the hash verbatum" do + @metadata.to_pson_data_hash['data']['relative_path'] == @metadata.relative_path + end + + it "should pass the links in the hash verbatum" do + @metadata.to_pson_data_hash['data']['links'] == @metadata.links + end + + it "should pass the path owner in the hash verbatum" do + @metadata.to_pson_data_hash['data']['owner'] == @metadata.owner + end + + it "should pass the group in the hash verbatum" do + @metadata.to_pson_data_hash['data']['group'] == @metadata.group + end + + it "should pass the mode in the hash verbatum" do + @metadata.to_pson_data_hash['data']['mode'] == @metadata.mode + end + + it "should pass the ftype in the hash verbatum as the 'type'" do + @metadata.to_pson_data_hash['data']['type'] == @metadata.ftype + end + + it "should pass the destination verbatum" do + @metadata.to_pson_data_hash['data']['destination'] == @metadata.destination + end + + it "should pass the checksum in the hash as a nested hash" do + @metadata.to_pson_data_hash['data']['checksum'].should be_is_a Hash + end + + it "should pass the checksum_type in the hash verbatum as the checksum's type" do + @metadata.to_pson_data_hash['data']['checksum']['type'] == @metadata.checksum_type + end + + it "should pass the checksum in the hash verbatum as the checksum's value" do + @metadata.to_pson_data_hash['data']['checksum']['value'] == @metadata.checksum + end + + end end describe Puppet::FileServing::Metadata, " when finding the file to use for setting attributes" do diff --git a/spec/unit/indirector/catalog/active_record.rb b/spec/unit/indirector/catalog/active_record.rb index 463552f55..8678dd6b3 100755 --- a/spec/unit/indirector/catalog/active_record.rb +++ b/spec/unit/indirector/catalog/active_record.rb @@ -76,9 +76,12 @@ describe "Puppet::Resource::Catalog::ActiveRecord" do describe "when saving an instance" do before do - @host = stub 'host', :name => "foo", :save => nil, :merge_resources => nil, :last_compile= => nil + @host = stub 'host', :name => "foo", :save => nil, :merge_resources => nil, :last_compile= => nil, :ip= => nil, :environment= => nil @host.stubs(:railsmark).yields + @node = stub_everything 'node', :parameters => {} + Puppet::Node.stubs(:find).returns(@node) + Puppet::Rails::Host.stubs(:find_by_name).returns @host @catalog = Puppet::Resource::Catalog.new("foo") @request = stub 'request', :key => "foo", :instance => @catalog @@ -105,6 +108,22 @@ describe "Puppet::Resource::Catalog::ActiveRecord" do @terminus.save(@request) end + it "should set host ip if we could find a matching node" do + @node.stubs(:parameters).returns({"ipaddress" => "192.168.0.1"}) + + @host.expects(:ip=).with '192.168.0.1' + + @terminus.save(@request) + end + + it "should set host environment if we could find a matching node" do + @node.stubs(:environment).returns("myenv") + + @host.expects(:environment=).with 'myenv' + + @terminus.save(@request) + end + it "should set the last compile time on the host" do now = Time.now Time.expects(:now).returns now diff --git a/spec/unit/network/authstore.rb b/spec/unit/network/authstore.rb index 55b2c7bbc..4087b28ed 100644 --- a/spec/unit/network/authstore.rb +++ b/spec/unit/network/authstore.rb @@ -4,6 +4,36 @@ require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/network/authconfig' +describe Puppet::Network::AuthStore do + describe "when checking if the acl has some entries" do + before :each do + @authstore = Puppet::Network::AuthStore.new + end + + it "should be empty if no ACE have been entered" do + @authstore.should be_empty + end + + it "should not be empty if it is a global allow" do + @authstore.allow('*') + + @authstore.should_not be_empty + end + + it "should not be empty if at least one allow has been entered" do + @authstore.allow('1.1.1.*') + + @authstore.should_not be_empty + end + + it "should not be empty if at least one deny has been entered" do + @authstore.deny('1.1.1.*') + + @authstore.should_not be_empty + end + end +end + describe Puppet::Network::AuthStore::Declaration do ['100.101.99.98','100.100.100.100','1.2.3.4','11.22.33.44'].each { |ip| diff --git a/spec/unit/network/format_handler.rb b/spec/unit/network/format_handler.rb index 8a79a58b3..110effe09 100755 --- a/spec/unit/network/format_handler.rb +++ b/spec/unit/network/format_handler.rb @@ -49,15 +49,35 @@ describe Puppet::Network::FormatHandler do FormatTester.supported_formats.should == [:four, :two, :three, :one] end - it "should always put the preferred serialization format first if it is supported" do - one = stub 'supported', :supported? => true, :name => :one, :weight => 1 - two = stub 'supported', :supported? => true, :name => :two, :weight => 6 - Puppet.settings.expects(:value).with(:preferred_serialization_format).returns :one - Puppet::Network::FormatHandler.stubs(:formats).returns [:one, :two] - Puppet::Network::FormatHandler.stubs(:format).with(:one).returns one - Puppet::Network::FormatHandler.stubs(:format).with(:two).returns two - FormatTester.supported_formats.should == [:one, :two] + describe "with a preferred serialization format setting" do + before do + one = stub 'supported', :supported? => true, :name => :one, :weight => 1 + two = stub 'supported', :supported? => true, :name => :two, :weight => 6 + Puppet::Network::FormatHandler.stubs(:formats).returns [:one, :two] + Puppet::Network::FormatHandler.stubs(:format).with(:one).returns one + Puppet::Network::FormatHandler.stubs(:format).with(:two).returns two + end + describe "that is supported" do + before do + Puppet.settings.expects(:value).with(:preferred_serialization_format).returns :one + end + it "should return the preferred serialization format first" do + FormatTester.supported_formats.should == [:one, :two] + end + end + describe "that is not supported" do + before do + Puppet.settings.expects(:value).with(:preferred_serialization_format).returns :unsupported + end + it "should still return the default format first" do + FormatTester.supported_formats.should == [:two, :one] + end + it "should log a warning" do + Puppet.expects(:warning) + FormatTester.supported_formats + end + end end it "should return the first format as the default format" do diff --git a/spec/unit/network/formats.rb b/spec/unit/network/formats.rb index de2e0afe3..b1ef9ec53 100755 --- a/spec/unit/network/formats.rb +++ b/spec/unit/network/formats.rb @@ -90,6 +90,91 @@ describe "Puppet Network Format" do end end + describe "base64 compressed yaml" do + before do + @yaml = Puppet::Network::FormatHandler.format(:b64_zlib_yaml) + end + + it "should have its mime type set to text/b64_zlib_yaml" do + @yaml.mime.should == "text/b64_zlib_yaml" + end + + it "should render by calling 'to_yaml' on the instance" do + instance = mock 'instance' + instance.expects(:to_yaml).returns "foo" + @yaml.render(instance) + end + + it "should fixup generated yaml on render" do + instance = mock 'instance', :to_yaml => "foo" + + @yaml.expects(:fixup).with("foo").returns "bar" + + @yaml.render(instance) + end + + it "should encode generated yaml on render" do + instance = mock 'instance', :to_yaml => "foo" + + @yaml.expects(:encode).with("foo").returns "bar" + + @yaml.render(instance).should == "bar" + end + + it "should render multiple instances by calling 'to_yaml' on the array" do + instances = [mock('instance')] + instances.expects(:to_yaml).returns "foo" + @yaml.render_multiple(instances) + end + + it "should fixup generated yaml on render" do + instances = [mock('instance')] + instances.stubs(:to_yaml).returns "foo" + + @yaml.expects(:fixup).with("foo").returns "bar" + + @yaml.render(instances) + end + + it "should encode generated yaml on render" do + instances = [mock('instance')] + instances.stubs(:to_yaml).returns "foo" + + @yaml.expects(:encode).with("foo").returns "bar" + + @yaml.render(instances).should == "bar" + end + + it "should intern by calling decode" do + text = "foo" + @yaml.expects(:decode).with("foo").returns "bar" + @yaml.intern(String, text).should == "bar" + end + + it "should intern multiples by calling 'decode'" do + text = "foo" + @yaml.expects(:decode).with("foo").returns "bar" + @yaml.intern_multiple(String, text).should == "bar" + end + + it "should decode by base64 decoding, uncompressing and Yaml loading" do + Base64.expects(:decode64).with("zorg").returns "foo" + Zlib::Inflate.expects(:inflate).with("foo").returns "baz" + YAML.expects(:load).with("baz").returns "bar" + @yaml.decode("zorg").should == "bar" + end + + it "should encode by compressing and base64 encoding" do + Zlib::Deflate.expects(:deflate).with("foo", Zlib::BEST_COMPRESSION).returns "bar" + Base64.expects(:encode64).with("bar").returns "baz" + @yaml.encode("foo").should == "baz" + end + + it "should fixup incorrect yaml to correct" do + @yaml.fixup("&id004 !ruby/object:Puppet::Relationship ?").should == "? &id004 !ruby/object:Puppet::Relationship" + end + end + it "should include a marshal format" do Puppet::Network::FormatHandler.format(:marshal).should_not be_nil end diff --git a/spec/unit/network/http/webrick.rb b/spec/unit/network/http/webrick.rb index 1b76341ba..fca2e075e 100755 --- a/spec/unit/network/http/webrick.rb +++ b/spec/unit/network/http/webrick.rb @@ -15,7 +15,7 @@ end describe Puppet::Network::HTTP::WEBrick, "when turning on listening" do before do - @mock_webrick = stub('webrick', :[] => {}) + @mock_webrick = stub('webrick', :[] => {}, :listeners => []) [:mount, :start, :shutdown].each {|meth| @mock_webrick.stubs(meth)} WEBrick::HTTPServer.stubs(:new).returns(@mock_webrick) @server = Puppet::Network::HTTP::WEBrick.new @@ -162,7 +162,7 @@ end describe Puppet::Network::HTTP::WEBrick, "when turning off listening" do before do - @mock_webrick = stub('webrick', :[] => {}) + @mock_webrick = stub('webrick', :[] => {}, :listeners => []) [:mount, :start, :shutdown].each {|meth| @mock_webrick.stubs(meth)} WEBrick::HTTPServer.stubs(:new).returns(@mock_webrick) @server = Puppet::Network::HTTP::WEBrick.new diff --git a/spec/unit/network/rights.rb b/spec/unit/network/rights.rb index 244fa18c8..7f00891ac 100755 --- a/spec/unit/network/rights.rb +++ b/spec/unit/network/rights.rb @@ -391,7 +391,7 @@ describe Puppet::Network::Rights do end it "should match as a regex" do - @acl.match?("this shoud work.rb").should_not be_nil + @acl.match?("this should work.rb").should_not be_nil end it "should return nil if no match" do diff --git a/spec/unit/node/environment.rb b/spec/unit/node/environment.rb index a16b3d6e1..9b0d5eefa 100755 --- a/spec/unit/node/environment.rb +++ b/spec/unit/node/environment.rb @@ -22,6 +22,10 @@ describe Puppet::Node::Environment do Puppet::Node::Environment.attr_ttl(:modules).should == Integer(Puppet[:filetimeout]) end + it "should use the filetimeout for the ttl for the manifestdir" do + Puppet::Node::Environment.attr_ttl(:manifestdir).should == Integer(Puppet[:filetimeout]) + end + it "should use the default environment if no name is provided while initializing an environment" do Puppet.settings.expects(:value).with(:environment).returns("one") Puppet::Node::Environment.new().name.should == :one @@ -39,45 +43,57 @@ describe Puppet::Node::Environment do Puppet::Node::Environment.new(:one).to_s.should == "one" end - it "should consider its module path to be the environment-specific modulepath setting" do - FileTest.stubs(:directory?).returns true - env = Puppet::Node::Environment.new("testing") - module_path = %w{/one /two}.join(File::PATH_SEPARATOR) - env.expects(:[]).with(:modulepath).returns module_path + [:modulepath, :manifestdir].each do |setting| + it "should validate the #{setting} directories" do + path = %w{/one /two}.join(File::PATH_SEPARATOR) + + env = Puppet::Node::Environment.new("testing") + env.stubs(:[]).with(setting).returns path + + env.expects(:validate_dirs).with(%w{/one /two}) + + env.send(setting) + end + + it "should return the validated dirs for #{setting}" do + path = %w{/one /two}.join(File::PATH_SEPARATOR) - env.modulepath.should == %w{/one /two} + env = Puppet::Node::Environment.new("testing") + env.stubs(:[]).with(setting).returns path + env.stubs(:validate_dirs).returns %w{/one /two} + + env.send(setting).should == %w{/one /two} + end end it "should prefix the value of the 'PUPPETLIB' environment variable to the module path if present" do - FileTest.stubs(:directory?).returns true Puppet::Util::Execution.withenv("PUPPETLIB" => %w{/l1 /l2}.join(File::PATH_SEPARATOR)) do env = Puppet::Node::Environment.new("testing") module_path = %w{/one /two}.join(File::PATH_SEPARATOR) + env.expects(:validate_dirs).with(%w{/l1 /l2 /one /two}).returns %w{/l1 /l2 /one /two} env.expects(:[]).with(:modulepath).returns module_path env.modulepath.should == %w{/l1 /l2 /one /two} end end - it "should not return non-directories in the module path" do - env = Puppet::Node::Environment.new("testing") - module_path = %w{/one /two}.join(File::PATH_SEPARATOR) - env.expects(:[]).with(:modulepath).returns module_path + describe "when validating modulepath or manifestdir directories" do + it "should not return non-directories" do + env = Puppet::Node::Environment.new("testing") - FileTest.expects(:directory?).with("/one").returns true - FileTest.expects(:directory?).with("/two").returns false + FileTest.expects(:directory?).with("/one").returns true + FileTest.expects(:directory?).with("/two").returns false - env.modulepath.should == %w{/one} - end + env.validate_dirs(%w{/one /two}).should == %w{/one} + end - it "should use the current working directory to fully-qualify unqualified paths" do - FileTest.stubs(:directory?).returns true - env = Puppet::Node::Environment.new("testing") - module_path = %w{/one two}.join(File::PATH_SEPARATOR) - env.expects(:[]).with(:modulepath).returns module_path + it "should use the current working directory to fully-qualify unqualified paths" do + FileTest.stubs(:directory?).returns true + env = Puppet::Node::Environment.new("testing") - two = File.join(Dir.getwd, "two") - env.modulepath.should == ["/one", two] + two = File.join(Dir.getwd, "two") + env.validate_dirs(%w{/one two}).should == ["/one", two] + end end describe "when modeling a specific environment" do diff --git a/spec/unit/parser/collector.rb b/spec/unit/parser/collector.rb index 926033c68..7f88bf754 100755 --- a/spec/unit/parser/collector.rb +++ b/spec/unit/parser/collector.rb @@ -498,35 +498,46 @@ describe Puppet::Parser::Collector, "when building its ActiveRecord query for co Puppet::Rails::Host.expects(:find_by_name).with(@scope.host).returns(@host) Puppet::Rails::Resource.stubs(:find).with { |*arguments| - options = arguments[3] + options = arguments[1] options[:conditions][0] =~ /^host_id != \?/ and options[:conditions][1] == 5 }.returns([@resource]) @collector.evaluate.should == [@resource] end - it "should return parameter names, parameter values when querying ActiveRecord" do + it "should join with parameter names, parameter values when querying ActiveRecord" do + @collector.equery = "param_names.name = title" Puppet::Rails::Resource.stubs(:find).with { |*arguments| - options = arguments[3] - options[:include] == {:param_values => :param_name} + options = arguments[1] + options[:joins] == {:param_values => :param_name} }.returns([@resource]) @collector.evaluate.should == [@resource] end - it "should return tags when querying ActiveRecord with a tag exported query" do + it "should join with tag tables when querying ActiveRecord with a tag exported query" do @collector.equery = "puppet_tags.name = test" Puppet::Rails::Resource.stubs(:find).with { |*arguments| - options = arguments[3] - options[:include] == {:param_values => :param_name, :puppet_tags => :resource_tags} + options = arguments[1] + options[:joins] == {:resource_tags => :puppet_tag} }.returns([@resource]) @collector.evaluate.should == [@resource] end + it "should not join parameters when querying ActiveRecord with a tag exported query" do + @collector.equery = "puppet_tags.name = test" + Puppet::Rails::Resource.stubs(:find).with { |*arguments| + options = arguments[1] + options[:joins] == {:param_values => :param_name} + }.returns([@resource]) + + @collector.evaluate.should be_false + end + it "should only search for exported resources with the matching type" do Puppet::Rails::Resource.stubs(:find).with { |*arguments| - options = arguments[3] + options = arguments[1] options[:conditions][0].include?("(exported=? AND restype=?)") and options[:conditions][1] == true and options[:conditions][2] == "Mytype" }.returns([@resource]) @@ -536,7 +547,7 @@ describe Puppet::Parser::Collector, "when building its ActiveRecord query for co it "should include the export query if one is provided" do @collector.equery = "test = true" Puppet::Rails::Resource.stubs(:find).with { |*arguments| - options = arguments[3] + options = arguments[1] options[:conditions][0].include?("test = true") }.returns([@resource]) diff --git a/spec/unit/parser/functions/require.rb b/spec/unit/parser/functions/require.rb index 24c9ecc64..577a52a42 100755 --- a/spec/unit/parser/functions/require.rb +++ b/spec/unit/parser/functions/require.rb @@ -31,6 +31,12 @@ describe "the require function" do @scope.function_require("myclass") end + it "should verify the 'include' function is loaded" do + Puppet::Parser::Functions.expects(:function).with(:include).returns(:function_include) + @scope.stubs(:function_include) + @scope.function_require("myclass") + end + it "should include the class but not add a dependency if used on a client not at least version 0.25" do @resource.expects(:metaparam_compatibility_mode?).returns true @scope.expects(:warning) diff --git a/spec/unit/parser/resource.rb b/spec/unit/parser/resource.rb index 0a67c4b54..3f08de958 100755 --- a/spec/unit/parser/resource.rb +++ b/spec/unit/parser/resource.rb @@ -25,7 +25,7 @@ describe Puppet::Parser::Resource do params = args[:params] || {:one => "yay", :three => "rah"} if args[:params] == :none args.delete(:params) - else + elsif not args[:params].is_a? Array args[:params] = paramify(args[:source], params) end @@ -483,5 +483,18 @@ describe Puppet::Parser::Resource do result = @parser_resource.to_resource result[:fee].should == ["a", Puppet::Resource::Reference.new(:file, "/my/file1"), Puppet::Resource::Reference.new(:file, "/my/file2")] end + + it "should fail if the same param is declared twice" do + lambda do + @parser_resource = mkresource :source => @source, :params => [ + Puppet::Parser::Resource::Param.new( + :name => :foo, :value => "bar", :source => @source + ), + Puppet::Parser::Resource::Param.new( + :name => :foo, :value => "baz", :source => @source + ) + ] + end.should raise_error(Puppet::ParseError) + end end end diff --git a/spec/unit/parser/resource/reference.rb b/spec/unit/parser/resource/reference.rb index e082136c5..064c51b20 100755 --- a/spec/unit/parser/resource/reference.rb +++ b/spec/unit/parser/resource/reference.rb @@ -40,10 +40,15 @@ describe Puppet::Parser::Resource::Reference do ref.to_s.should == "File[/tmp/yay]" end - it "should canonize resource references" do + it "should canonize resource reference types" do ref = @type.new(:type => "foo::bar", :title => "/tmp/yay") ref.to_s.should == "Foo::Bar[/tmp/yay]" end + + it "should canonize resource reference values" do + ref = @type.new(:type => "file", :title => "/tmp/yay/") + ref.to_s.should == "File[/tmp/yay]" + end end describe Puppet::Parser::Resource::Reference, " when modeling defined types" do diff --git a/spec/unit/parser/scope.rb b/spec/unit/parser/scope.rb index 0859eadb4..d7800e4b3 100755 --- a/spec/unit/parser/scope.rb +++ b/spec/unit/parser/scope.rb @@ -43,7 +43,7 @@ describe Puppet::Parser::Scope do describe "and the variable is qualified" do before do @parser = Puppet::Parser::Parser.new() - @compiler = Puppet::Parser::Compiler.new(stub("node", :name => "foonode"), @parser) + @compiler = Puppet::Parser::Compiler.new(stub("node", :name => "foonode", :classes => []), @parser) @scope.compiler = @compiler @scope.parser = @parser end diff --git a/spec/unit/property.rb b/spec/unit/property.rb index 26a5765a2..03b848b15 100755 --- a/spec/unit/property.rb +++ b/spec/unit/property.rb @@ -101,6 +101,12 @@ describe Puppet::Property do @property.should.must == [:one, :two] end + it "should munge the canonicalization of the value" do + @property.class.to_canonicalize { |x| x.reverse } + @property.value = 'data' + @property.should.must == 'atad' + end + it "should return any set value" do (@property.value = :one).should == :one end diff --git a/spec/unit/provider/package/dpkg.rb b/spec/unit/provider/package/dpkg.rb index 08aaca875..0c5c9b527 100755 --- a/spec/unit/provider/package/dpkg.rb +++ b/spec/unit/provider/package/dpkg.rb @@ -149,6 +149,13 @@ describe provider do @provider.expects(:warning) @provider.latest end + + it "should cope with names containing ++" do + @resource = stub 'resource', :[] => "asdf++" + @provider = provider.new(@resource) + @provider.expects(:dpkg_deb).returns "asdf++\t1.0" + @provider.latest.should == "1.0" + end end it "should use 'dpkg -r' to uninstall" do diff --git a/spec/unit/provider/service/debian.rb b/spec/unit/provider/service/debian.rb index 87d627452..ea87c375d 100755 --- a/spec/unit/provider/service/debian.rb +++ b/spec/unit/provider/service/debian.rb @@ -60,7 +60,7 @@ describe provider_class do describe "when checking whether it is enabled" do it "should call Kernel.system() with the appropriate parameters" do - @provider.expects(:system).with("/usr/sbin/invoke-rc.d", "--query", @resource[:name], "start").once + @provider.expects(:system).with("/usr/sbin/invoke-rc.d", "--quiet", "--query", @resource[:name], "start").once @provider.enabled? end diff --git a/spec/unit/provider/ssh_authorized_key/parsed.rb b/spec/unit/provider/ssh_authorized_key/parsed.rb index 13bd08bd8..49abc13ec 100755 --- a/spec/unit/provider/ssh_authorized_key/parsed.rb +++ b/spec/unit/provider/ssh_authorized_key/parsed.rb @@ -78,6 +78,12 @@ describe provider_class do @provider.parse_options(optionstr).should == options end + + it "should use '' as name for entries that lack a comment" do + line = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAut8aOSxenjOqF527dlsdHWV4MNoAsX14l9M297+SQXaQ5Z3BedIxZaoQthkDALlV/25A1COELrg9J2MqJNQc8Xe9XQOIkBQWWinUlD/BXwoOTWEy8C8zSZPHZ3getMMNhGTBO+q/O+qiJx3y5cA4MTbw2zSxukfWC87qWwcZ64UUlegIM056vPsdZWFclS9hsROVEa57YUMrehQ1EGxT4Z5j6zIopufGFiAPjZigq/vqgcAqhAKP6yu4/gwO6S9tatBeEjZ8fafvj1pmvvIplZeMr96gHE7xS3pEEQqnB3nd4RY7AF6j9kFixnsytAUO7STPh/M3pLiVQBN89TvWPQ==" + + @provider.parse(line)[0][:name].should == "" + end end describe provider_class do diff --git a/spec/unit/rails.rb b/spec/unit/rails.rb index 8ecd77a49..da6db1548 100755 --- a/spec/unit/rails.rb +++ b/spec/unit/rails.rb @@ -39,6 +39,7 @@ describe Puppet::Rails, "when initializing any connection" do ActiveRecord::Base.stubs(:logger).returns(logger) logger.expects(:level=).with(Logger::DEBUG) + ActiveRecord::Base.stubs(:allow_concurrency=) ActiveRecord::Base.stubs(:verify_active_connections!) ActiveRecord::Base.stubs(:establish_connection) Puppet::Rails.stubs(:database_arguments) @@ -46,6 +47,16 @@ describe Puppet::Rails, "when initializing any connection" do Puppet::Rails.connect end + describe "on ActiveRecord 2.1.x" do + confine "ActiveRecord 2.1.x" => (::ActiveRecord::VERSION::MAJOR == 2 and ::ActiveRecord::VERSION::MINOR <= 1) + + it "should set ActiveRecord::Base.allow_concurrency" do + ActiveRecord::Base.expects(:allow_concurrency=).with(true) + + Puppet::Rails.connect + end + end + it "should call ActiveRecord::Base.verify_active_connections!" do ActiveRecord::Base.expects(:verify_active_connections!) diff --git a/spec/unit/ssl/certificate_revocation_list.rb b/spec/unit/ssl/certificate_revocation_list.rb index eb25268e6..3d15db78b 100755 --- a/spec/unit/ssl/certificate_revocation_list.rb +++ b/spec/unit/ssl/certificate_revocation_list.rb @@ -46,18 +46,6 @@ describe Puppet::SSL::CertificateRevocationList do end end - describe "when initializing" do - it "should fail if :cacrl is set to false" do - Puppet.settings.expects(:value).with(:cacrl).returns false - lambda { @class.new("crl") }.should raise_error(Puppet::Error) - end - - it "should fail if :cacrl is set to the string 'false'" do - Puppet.settings.expects(:value).with(:cacrl).returns "false" - lambda { @class.new("crl") }.should raise_error(Puppet::Error) - end - end - describe "when generating the crl" do before do @real_crl = mock 'crl' diff --git a/spec/unit/transaction.rb b/spec/unit/transaction.rb index 7966c7a65..1b3562153 100755 --- a/spec/unit/transaction.rb +++ b/spec/unit/transaction.rb @@ -20,8 +20,8 @@ describe Puppet::Transaction do describe "when generating resources" do it "should finish all resources" do - generator = stub 'generator', :depthfirst? => true - resource = stub 'resource' + generator = stub 'generator', :depthfirst? => true, :tags => [] + resource = stub 'resource', :tag => nil @catalog = Puppet::Resource::Catalog.new @transaction = Puppet::Transaction.new(@catalog) @@ -36,8 +36,8 @@ describe Puppet::Transaction do end it "should skip generated resources that conflict with existing resources" do - generator = mock 'generator' - resource = stub 'resource' + generator = mock 'generator', :tags => [] + resource = stub 'resource', :tag => nil @catalog = Puppet::Resource::Catalog.new @transaction = Puppet::Transaction.new(@catalog) @@ -51,6 +51,21 @@ describe Puppet::Transaction do @transaction.generate_additional_resources(generator, :generate).should be_empty end + + it "should copy all tags to the newly generated resources" do + child = stub 'child' + generator = stub 'resource', :tags => ["one", "two"] + + @catalog = Puppet::Resource::Catalog.new + @transaction = Puppet::Transaction.new(@catalog) + + generator.stubs(:generate).returns [child] + @catalog.stubs(:add_resource) + + child.expects(:tag).with("one", "two") + + @transaction.generate_additional_resources(generator, :generate) + end end describe "when skipping a resource" do @@ -65,6 +80,16 @@ describe Puppet::Transaction do @transaction.skip?(@resource).should be_true end + it "should ask the resource if it's tagged with any of the tags" do + tags = ['one', 'two'] + @transaction.stubs(:ignore_tags?).returns(false) + @transaction.stubs(:tags).returns(tags) + + @resource.expects(:tagged?).with(*tags).returns(true) + + @transaction.missing_tags?(@resource).should be_false + end + it "should skip not scheduled resources" do @transaction.stubs(:scheduled?).returns(false) @transaction.skip?(@resource).should be_true @@ -108,4 +133,14 @@ describe Puppet::Transaction, " when determining tags" do @transaction.tags = "one::two" @transaction.tags.should == %w{one::two} end + + it "should accept a comma-delimited string" do + @transaction.tags = "one, two" + @transaction.tags.should == %w{one two} + end + + it "should accept an empty string" do + @transaction.tags = "" + @transaction.tags.should == [] + end end diff --git a/spec/unit/type/cron.rb b/spec/unit/type/cron.rb new file mode 100755 index 000000000..6951077e0 --- /dev/null +++ b/spec/unit/type/cron.rb @@ -0,0 +1,33 @@ +#!/usr/bin/env ruby + +Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } + +describe Puppet::Type.type(:cron) do + before do + @cron = Puppet::Type.type(:cron).new( :name => "foo" ) + end + + it "it should accept an :environment that looks like a path" do + lambda do + @cron[:environment] = 'PATH=/bin:/usr/bin:/usr/sbin' + end.should_not raise_error + end + + it "should not accept environment variables that do not contain '='" do + lambda do + @cron[:environment] = "INVALID" + end.should raise_error(Puppet::Error) + end + + it "should accept empty environment variables that do not contain '='" do + lambda do + @cron[:environment] = "MAILTO=" + end.should_not raise_error(Puppet::Error) + end + + it "should accept 'absent'" do + lambda do + @cron[:environment] = 'absent' + end.should_not raise_error(Puppet::Error) + end +end diff --git a/spec/unit/type/file/content.rb b/spec/unit/type/file/content.rb index 8bdb1f226..442de1309 100755 --- a/spec/unit/type/file/content.rb +++ b/spec/unit/type/file/content.rb @@ -119,6 +119,15 @@ describe content do @content.retrieve.should be_nil end + it "should not manage content on links" do + @content = content.new(:resource => @resource) + + stat = mock 'stat', :ftype => "link" + @resource.expects(:stat).returns stat + + @content.retrieve.should be_nil + end + it "should always return the checksum as a string" do @content = content.new(:resource => @resource) @content.stubs(:checksum_type).returns "mtime" @@ -188,6 +197,26 @@ describe content do @content.must be_insync("{md5}" + Digest::MD5.hexdigest("some content")) end + describe "and Puppet[:show_diff] is set" do + before do + Puppet[:show_diff] = true + end + + it "should display a diff if the current contents are different from the desired content" do + @content.should = "some content" + @content.expects(:string_file_diff).once + + @content.insync?("other content") + end + + it "should not display a diff if the sum for the current contents is the same as the sum for the desired content" do + @content.should = "some content" + @content.expects(:string_file_diff).never + + @content.insync?("{md5}" + Digest::MD5.hexdigest("some content")) + end + end + describe "and the content is specified via a remote source" do before do @metadata = stub 'metadata' diff --git a/spec/unit/type/file/owner.rb b/spec/unit/type/file/owner.rb index 1ea01cbc7..62f7b0ae5 100755 --- a/spec/unit/type/file/owner.rb +++ b/spec/unit/type/file/owner.rb @@ -55,11 +55,13 @@ describe property do describe "when determining if the file is in sync" do describe "and not running as root" do - it "should warn and return true" do - @owner.should = 10 + it "should warn once and return true" do Puppet::Util::SUIDManager.expects(:uid).returns 1 - @owner.expects(:warning) - @owner.must be_insync("whatever") + + @owner.expects(:warnonce) + + @owner.should = [10] + @owner.must be_insync(20) end end @@ -67,6 +69,10 @@ describe property do Puppet::Util::SUIDManager.stubs(:uid).returns 0 end + it "should be in sync if 'should' is not provided" do + @owner.must be_insync(10) + end + it "should directly compare the owner values if the desired owner is an integer" do @owner.should = [10] @owner.must be_insync(10) diff --git a/spec/unit/type/maillist.rb b/spec/unit/type/maillist.rb new file mode 100755 index 000000000..585336665 --- /dev/null +++ b/spec/unit/type/maillist.rb @@ -0,0 +1,42 @@ +#!/usr/bin/env ruby + +Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } + +maillist = Puppet::Type.type(:maillist) + +describe maillist do + before do + @provider_class = Puppet::Type.type(:maillist).provider(:mailman) + + @provider = stub 'provider', :class => @provider_class, :clear => nil + @provider.stubs(:respond_to).with(:aliases).returns(true) + + @provider_class.stubs(:new).returns(@provider) + + Puppet::Type.type(:maillist).stubs(:defaultprovider).returns(@provider_class) + + @maillist = Puppet::Type.type(:maillist).new( :name => 'test' ) + + @catalog = Puppet::Resource::Catalog.new + @maillist.catalog = @catalog + end + + it "should generate aliases unless they already exist" do + # Mail List aliases are careful not to stomp on managed Mail Alias aliases + + # test1 is an unmanaged alias from /etc/aliases + Puppet::Type.type(:mailalias).provider(:aliases).stubs(:target_object).returns( StringIO.new("test1: root\n") ) + + # test2 is a managed alias from the manifest + dupe = Puppet::Type.type(:mailalias).new( :name => 'test2' ) + @catalog.add_resource dupe + + @provider.stubs(:aliases).returns({"test1" => 'this will get included', "test2" => 'this will dropped', "test3" => 'this will get included'}) + + generated = @maillist.generate + generated.map{ |x| x.name }.sort.should == ['test1', 'test3'] + generated.map{ |x| x.class }.should == [Puppet::Type::Mailalias, Puppet::Type::Mailalias] + + end + +end diff --git a/spec/unit/type/resources.rb b/spec/unit/type/resources.rb index 147f21db4..480b6c00d 100644 --- a/spec/unit/type/resources.rb +++ b/spec/unit/type/resources.rb @@ -8,7 +8,7 @@ resources = Puppet::Type.type(:resources) describe resources do describe "when initializing" do it "should fail if the specified resource type does not exist" do - Puppet::Type.stubs(:type).with("Resources").returns resources + Puppet::Type.stubs(:type).with { |x| x.to_s.downcase == "resources"}.returns resources Puppet::Type.expects(:type).with("nosuchtype").returns nil lambda { resources.new :name => "nosuchtype" }.should raise_error(Puppet::Error) end @@ -21,4 +21,69 @@ describe resources do resources.new(:name => "file").resource_type.should == Puppet::Type.type(:file) end end + + describe "#generate" do + before do + @host1 = Puppet::Type.type(:host).new(:name => 'localhost', :ip => '127.0.0.1') + @catalog = Puppet::Resource::Catalog.new + @context = Puppet::Transaction.new(@catalog) + end + + describe "when dealing with non-purging resources" do + before do + @resources = Puppet::Type.type(:resources).new(:name => 'host') + end + + it "should not generate any resource" do + @resources.generate.should be_empty + end + end + + describe "when the catalog contains a purging resource" do + before do + @resources = Puppet::Type.type(:resources).new(:name => 'host', :purge => true) + @purgeable_resource = Puppet::Type.type(:host).new(:name => 'localhost', :ip => '127.0.0.1') + @catalog.add_resource @resources + end + + it "should not generate a duplicate of that resource" do + Puppet::Type.type(:host).stubs(:instances).returns [@host1] + @catalog.add_resource @host1 + @resources.generate.collect { |r| r.ref }.should_not include(@host1.ref) + end + + + describe "when generating a purgeable resource" do + it "should be included in the generated resources" do + Puppet::Type.type(:host).stubs(:instances).returns [@purgeable_resource] + @resources.generate.collect { |r| r.ref }.should include(@purgeable_resource.ref) + end + end + + describe "when the instance's do not have an ensure property" do + it "should not be included in the generated resources" do + @no_ensure_resource = Puppet::Type.type(:exec).new(:name => '/usr/bin/env echo') + Puppet::Type.type(:host).stubs(:instances).returns [@no_ensure_resource] + @resources.generate.collect { |r| r.ref }.should_not include(@no_ensure_resource.ref) + end + end + + describe "when the instance's ensure property does not accept absent" do + it "should not be included in the generated resources" do + @no_absent_resource = Puppet::Type.type(:service).new(:name => 'foobar') + Puppet::Type.type(:host).stubs(:instances).returns [@no_absent_resource] + @resources.generate.collect { |r| r.ref }.should_not include(@no_absent_resource.ref) + end + end + + describe "when checking the instance fails" do + it "should not be included in the generated resources" do + @purgeable_resource = Puppet::Type.type(:host).new(:name => 'foobar') + Puppet::Type.type(:host).stubs(:instances).returns [@purgeable_resource] + @resources.expects(:check).with(@purgeable_resource).returns(false) + @resources.generate.collect { |r| r.ref }.should_not include(@purgeable_resource.ref) + end + end + end + end end diff --git a/spec/unit/type/tidy.rb b/spec/unit/type/tidy.rb index caf5b22b7..88e2e280a 100755 --- a/spec/unit/type/tidy.rb +++ b/spec/unit/type/tidy.rb @@ -7,6 +7,10 @@ tidy = Puppet::Type.type(:tidy) describe tidy do before do Puppet.settings.stubs(:use) + + # for an unknown reason some of these specs fails when run individually + # with a failed expectation on File.lstat in the autoloader. + File.stubs(:lstat) end it "should use :lstat when stating a file" do @@ -161,7 +165,7 @@ describe tidy do Puppet::FileServing::Fileset.stubs(:new).returns @fileset end - it "should use a Fileset for recursion" do + it "should use a Fileset for infinite recursion" do Puppet::FileServing::Fileset.expects(:new).with("/what/ever", :recurse => true).returns @fileset @fileset.expects(:files).returns %w{. one two} @tidy.stubs(:tidy?).returns false @@ -169,6 +173,15 @@ describe tidy do @tidy.generate end + it "should use a Fileset for limited recursion" do + @tidy[:recurse] = 42 + Puppet::FileServing::Fileset.expects(:new).with("/what/ever", :recurse => true, :recurselimit => 42).returns @fileset + @fileset.expects(:files).returns %w{. one two} + @tidy.stubs(:tidy?).returns false + + @tidy.generate + end + it "should generate a file resource for every file that should be tidied but not for files that should not be tidied" do @fileset.expects(:files).returns %w{. one two} diff --git a/spec/unit/util/log.rb b/spec/unit/util/log.rb index 4e2c8dcc5..35e6a71e8 100755 --- a/spec/unit/util/log.rb +++ b/spec/unit/util/log.rb @@ -13,6 +13,42 @@ describe Puppet::Util::Log do Puppet::Util::Log.close_all end + describe Puppet::Util::Log::DestConsole do + before do + @console = Puppet::Util::Log::DestConsole.new + end + + it "should colorize if Puppet[:color] is :ansi" do + Puppet[:color] = :ansi + + @console.colorize(:alert, "abc").should == "\e[0;31mabc\e[0m" + end + + it "should colorize if Puppet[:color] is 'yes'" do + Puppet[:color] = "yes" + + @console.colorize(:alert, "abc").should == "\e[0;31mabc\e[0m" + end + + it "should htmlize if Puppet[:color] is :html" do + Puppet[:color] = :html + + @console.colorize(:alert, "abc").should == "<span style=\"color: FFA0A0\">abc</span>" + end + + it "should do nothing if Puppet[:color] is false" do + Puppet[:color] = false + + @console.colorize(:alert, "abc").should == "abc" + end + + it "should do nothing if Puppet[:color] is invalid" do + Puppet[:color] = "invalid option" + + @console.colorize(:alert, "abc").should == "abc" + end + end + describe "instances" do before do Puppet::Util::Log.stubs(:newmessage) diff --git a/spec/unit/util/monkey_patches.rb b/spec/unit/util/monkey_patches.rb new file mode 100644 index 000000000..335f90b86 --- /dev/null +++ b/spec/unit/util/monkey_patches.rb @@ -0,0 +1,103 @@ +#!/usr/bin/env ruby + +Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } + +require 'puppet/util/monkey_patches' + +describe RDoc do + it "should return the call stack if a script is called directly" do + stack = [ + "/usr/lib/ruby/1.8/rdoc/usage.rb:99:in `usage_no_exit'", + "/usr/lib/ruby/1.8/rdoc/usage.rb:93:in `usage'", + "./puppet/application.rb:295:in `help'", + "./puppet/application.rb:207:in `handle_help'", + "./puppet/application.rb:141:in `send'", + "./puppet/application.rb:141:in `option'", + "/usr/lib/ruby/1.8/optparse.rb:1267:in `call'", + "/usr/lib/ruby/1.8/optparse.rb:1267:in `parse_in_order'", + "/usr/lib/ruby/1.8/optparse.rb:1254:in `catch'", + "/usr/lib/ruby/1.8/optparse.rb:1254:in `parse_in_order'", + "/usr/lib/ruby/1.8/optparse.rb:1248:in `order!'", + "/usr/lib/ruby/1.8/optparse.rb:1339:in `permute!'", + "/usr/lib/ruby/1.8/optparse.rb:1360:in `parse!'", + "./puppet/application.rb:262:in `parse_options'", + "./puppet/application.rb:214:in `run'", + "./puppet/application.rb:306:in `exit_on_fail'", + "./puppet/application.rb:214:in `run'", + "../bin/puppet:71" + ] + + old_dollar_zero = $0 + $0 = "../bin/puppet" + + # Mocha explodes if you try to mock :caller directly + Kernel.expects( :mock_caller ).returns( stack ) + Kernel.instance_eval { alias orig_caller caller } + Kernel.instance_eval { alias caller mock_caller } + + RDoc.caller.must == stack + + $0 = old_dollar_zero + Kernel.instance_eval { alias caller orig_caller } + end + + it "should return a truncated call stack if a script is called from a rubygems stub" do + gem_stack = [ + "/usr/lib/ruby/1.8/rdoc/usage.rb:99:in `usage_no_exit'", + "/usr/lib/ruby/1.8/rdoc/usage.rb:93:in `usage'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/lib/puppet/application.rb:295:in `help'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/lib/puppet/application.rb:207:in `handle_help'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/lib/puppet/application.rb:141:in `send'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/lib/puppet/application.rb:141:in `option'", + "/usr/lib/ruby/1.8/optparse.rb:1267:in `call'", + "/usr/lib/ruby/1.8/optparse.rb:1267:in `parse_in_order'", + "/usr/lib/ruby/1.8/optparse.rb:1254:in `catch'", + "/usr/lib/ruby/1.8/optparse.rb:1254:in `parse_in_order'", + "/usr/lib/ruby/1.8/optparse.rb:1248:in `order!'", + "/usr/lib/ruby/1.8/optparse.rb:1339:in `permute!'", + "/usr/lib/ruby/1.8/optparse.rb:1360:in `parse!'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/lib/puppet/application.rb:262:in `parse_options'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/lib/puppet/application.rb:214:in `run'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/lib/puppet/application.rb:306:in `exit_on_fail'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/lib/puppet/application.rb:214:in `run'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/bin/puppet:71", + "/usr/bin/puppet:19:in `load'", + "/usr/bin/puppet:19" + ] + + real_stack = [ + "/usr/lib/ruby/1.8/rdoc/usage.rb:99:in `usage_no_exit'", + "/usr/lib/ruby/1.8/rdoc/usage.rb:93:in `usage'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/lib/puppet/application.rb:295:in `help'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/lib/puppet/application.rb:207:in `handle_help'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/lib/puppet/application.rb:141:in `send'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/lib/puppet/application.rb:141:in `option'", + "/usr/lib/ruby/1.8/optparse.rb:1267:in `call'", + "/usr/lib/ruby/1.8/optparse.rb:1267:in `parse_in_order'", + "/usr/lib/ruby/1.8/optparse.rb:1254:in `catch'", + "/usr/lib/ruby/1.8/optparse.rb:1254:in `parse_in_order'", + "/usr/lib/ruby/1.8/optparse.rb:1248:in `order!'", + "/usr/lib/ruby/1.8/optparse.rb:1339:in `permute!'", + "/usr/lib/ruby/1.8/optparse.rb:1360:in `parse!'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/lib/puppet/application.rb:262:in `parse_options'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/lib/puppet/application.rb:214:in `run'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/lib/puppet/application.rb:306:in `exit_on_fail'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/lib/puppet/application.rb:214:in `run'", + "/usr/lib/ruby/gems/1.8/gems/puppet-0.25.1/bin/puppet:71", + ] + + old_dollar_zero = $0 + $0 = '/usr/bin/puppet' + + # Mocha explodes if you try to mock :caller directly + Kernel.expects( :mock_caller ).returns( gem_stack ) + Kernel.instance_eval { alias orig_caller caller } + Kernel.instance_eval { alias caller mock_caller } + + RDoc.caller.must == real_stack + + $0 = old_dollar_zero + Kernel.instance_eval { alias caller orig_caller } + end +end + diff --git a/spec/unit/util/selinux.rb b/spec/unit/util/selinux.rb index da4686ec4..7e6cdaf30 100755 --- a/spec/unit/util/selinux.rb +++ b/spec/unit/util/selinux.rb @@ -61,6 +61,42 @@ describe Puppet::Util::SELinux do selinux_label_support?('/mnt/nfs/testfile').should be_false end + it "should follow symlinks when determining file systems" do + self.stubs(:realpath).with('/mnt/symlink/testfile').returns('/mnt/nfs/dest/testfile') + + selinux_label_support?('/mnt/symlink/testfile').should be_false + end + + end + + describe "realpath" do + it "should handle files that don't exist" do + + # Since I'm stubbing Pathname.new for this test, + # I need to also stub the internal calls to Pathname.new, + # which happen in Pathname.dirname and Parthname.basename + # I want those to return real Pathname objects, + # so I'm creating them before the stub is in place. + realpaths = Hash.new {|hash, path| hash[path] = Pathname.new(path) } + paths = ['symlink', '/mnt'] + paths.each { |path| realpaths[path] } + + realpaths['/mnt/symlink'] = stubs "Pathname" + realpaths['/mnt/symlink'].stubs(:realpath).returns(realpaths['/mnt/nfs/dest']) + realpaths['/mnt/symlink'].stubs(:exist?).returns(true) + + realpaths['/mnt/symlink/nonexistant'] = stubs "Pathname" + realpaths['/mnt/symlink/nonexistant'].stubs(:realpath).raises(Errno::ENOENT) + realpaths['/mnt/symlink/nonexistant'].stubs(:exist?).returns(false) + realpaths['/mnt/symlink/nonexistant'].stubs(:dirname).returns(realpaths['/mnt/symlink']) + realpaths['/mnt/symlink/nonexistant'].stubs(:basename).returns(realpaths['nonexistant']) + + realpaths.each do |path, value| + Pathname.stubs(:new).with(path).returns(value) + end + + realpath('/mnt/symlink/nonexistant').should == '/mnt/nfs/dest/nonexistant' + end end describe "get_selinux_current_context" do @@ -158,6 +194,12 @@ describe Puppet::Util::SELinux do set_selinux_context("/foo", "user_u:role_r:type_t:s0").should be_nil end + it "should return nil if selinux_label_support returns false" do + self.expects(:selinux_support?).returns true + self.expects(:selinux_label_support?).with("/foo").returns false + set_selinux_context("/foo", "user_u:role_r:type_t:s0").should be_nil + end + it "should use lsetfilecon to set a context" do self.expects(:selinux_support?).returns true Selinux.expects(:lsetfilecon).with("/foo", "user_u:role_r:type_t:s0").returns 0 diff --git a/spec/unit/util/tagging.rb b/spec/unit/util/tagging.rb index d61ee8ccb..3486f46f2 100755 --- a/spec/unit/util/tagging.rb +++ b/spec/unit/util/tagging.rb @@ -89,4 +89,14 @@ describe Puppet::Util::Tagging, "when adding tags" do it "should indicate when the object is not tagged with a provided tag" do @tagger.should_not be_tagged("one") end + + it "should indicate when the object is tagged with any tag in an array" do + @tagger.tag("one") + @tagger.should be_tagged("one","two","three") + end + + it "should indicate when the object is not tagged with any tag in an array" do + @tagger.tag("one") + @tagger.should_not be_tagged("two","three") + end end |
