summaryrefslogtreecommitdiffstats
path: root/spec
diff options
context:
space:
mode:
authorJames Turnbull <james@lovedthanlost.net>2008-05-20 19:06:45 +1000
committerJames Turnbull <james@lovedthanlost.net>2008-05-20 19:06:45 +1000
commit84a787a2a764a5035f7cbb8d30f94fc601bed154 (patch)
treeec46287a86ce738fec5774347ea4f9afcf804953 /spec
parent390db8061ae81174ee9d42e26a6ebfe7182ea529 (diff)
parentee4be4f78f7c904dbe5873ff7b44993d1440da41 (diff)
downloadpuppet-84a787a2a764a5035f7cbb8d30f94fc601bed154.tar.gz
puppet-84a787a2a764a5035f7cbb8d30f94fc601bed154.tar.xz
puppet-84a787a2a764a5035f7cbb8d30f94fc601bed154.zip
Merge branch '0.24.x' of git://github.com/lak/puppet into 0.24.x
Conflicts: CHANGELOG
Diffstat (limited to 'spec')
-rwxr-xr-xspec/integration/defaults.rb17
-rwxr-xr-xspec/integration/node/catalog.rb6
-rwxr-xr-xspec/unit/provider/confine.rb200
-rwxr-xr-xspec/unit/provider/confine/exists.rb80
-rwxr-xr-xspec/unit/provider/confine/facter.rb86
-rwxr-xr-xspec/unit/provider/confine/false.rb52
-rwxr-xr-xspec/unit/provider/confine/feature.rb59
-rwxr-xr-xspec/unit/provider/confine/true.rb50
-rwxr-xr-xspec/unit/provider/confine_collection.rb121
-rwxr-xr-xspec/unit/provider/confiner.rb4
-rwxr-xr-xspec/unit/provider/interface/redhat.rb4
-rwxr-xr-xspec/unit/util/storage.rb237
12 files changed, 677 insertions, 239 deletions
diff --git a/spec/integration/defaults.rb b/spec/integration/defaults.rb
new file mode 100755
index 000000000..b14a141fb
--- /dev/null
+++ b/spec/integration/defaults.rb
@@ -0,0 +1,17 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../spec_helper'
+
+require 'puppet/defaults'
+
+describe "Puppet defaults" do
+ describe "when setting the :factpath" do
+ after { Puppet.settings.clear }
+
+ it "should add the :factpath to Facter's search paths" do
+ Facter.expects(:search).with("/my/fact/path")
+
+ Puppet.settings[:factpath] = "/my/fact/path"
+ end
+ end
+end
diff --git a/spec/integration/node/catalog.rb b/spec/integration/node/catalog.rb
index ca14c2ea8..941d2cc6c 100755
--- a/spec/integration/node/catalog.rb
+++ b/spec/integration/node/catalog.rb
@@ -7,6 +7,12 @@ require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Node::Catalog do
describe "when using the indirector" do
+ before do
+ # This is so the tests work w/out networking.
+ Facter.stubs(:to_hash).returns({"hostname" => "foo.domain.com"})
+ Facter.stubs(:value).returns("eh")
+ end
+
after { Puppet::Node::Catalog.indirection.clear_cache }
it "should be able to delegate to the :yaml terminus" do
diff --git a/spec/unit/provider/confine.rb b/spec/unit/provider/confine.rb
index bb2e751d6..6a9214e26 100755
--- a/spec/unit/provider/confine.rb
+++ b/spec/unit/provider/confine.rb
@@ -5,219 +5,61 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/provider/confine'
describe Puppet::Provider::Confine do
- it "should require a test" do
- lambda { Puppet::Provider::Confine.new }.should raise_error(ArgumentError)
- end
-
it "should require a value" do
- lambda { Puppet::Provider::Confine.new(:exists) }.should raise_error(ArgumentError)
- end
-
- it "should have a test" do
- Puppet::Provider::Confine.new(:exists, "/some/file").test.should == :exists
+ lambda { Puppet::Provider::Confine.new() }.should raise_error(ArgumentError)
end
it "should always convert values to an array" do
- Puppet::Provider::Confine.new(:exists, "/some/file").values.should be_instance_of(Array)
+ Puppet::Provider::Confine.new("/some/file").values.should be_instance_of(Array)
end
- it "should have an accessor for its fact" do
- Puppet::Provider::Confine.new(:foo, :bar).should respond_to(:fact)
+ it "should have a 'true' test" do
+ Puppet::Provider::Confine.test(:true).should be_instance_of(Class)
end
- it "should be possible to mark the confine as a binary test" do
- Puppet::Provider::Confine.new(:foo, :bar).should respond_to(:for_binary=)
+ it "should have a 'false' test" do
+ Puppet::Provider::Confine.test(:false).should be_instance_of(Class)
end
- it "should have a boolean method to indicate it's a binary confine" do
- Puppet::Provider::Confine.new(:foo, :bar).should respond_to(:for_binary?)
+ it "should have a 'feature' test" do
+ Puppet::Provider::Confine.test(:feature).should be_instance_of(Class)
end
- it "should indicate it's a boolean confine if it has been marked that way" do
- confine = Puppet::Provider::Confine.new(:foo, :bar)
- confine.for_binary = true
- confine.should be_for_binary
+ it "should have an 'exists' test" do
+ Puppet::Provider::Confine.test(:exists).should be_instance_of(Class)
end
- it "should have a method for returning a binary's path" do
- Puppet::Provider::Confine.new(:foo, :bar).private_methods.should be_include("binary")
- end
-
- describe "when testing values" do
- before { @confine = Puppet::Provider::Confine.new("eh", "foo") }
-
- describe "and the test is 'false'" do
- it "should use the 'false?' method to test validity" do
- @confine = Puppet::Provider::Confine.new(:false, "foo")
- @confine.expects(:false?).with("foo")
- @confine.valid?
- end
-
- it "should return true if the value is false" do
- @confine.false?(false).should be_true
- end
-
- it "should return false if the value is not false" do
- @confine.false?("else").should be_false
- end
-
- it "should log that a value is false" do
- @confine = Puppet::Provider::Confine.new(:false, "foo")
- Puppet.expects(:debug).with { |l| l.include?("false") }
- @confine.valid?
- end
- end
-
- describe "and the test is 'true'" do
- it "should use the 'true?' method to test validity" do
- @confine = Puppet::Provider::Confine.new(:true, "foo")
- @confine.expects(:true?).with("foo")
- @confine.valid?
- end
-
- it "should return true if the value is not false" do
- @confine.true?("else").should be_true
- end
-
- it "should return false if the value is false" do
- @confine.true?(nil).should be_false
- end
- end
-
- describe "and the test is 'exists'" do
- it "should use the 'exists?' method to test validity" do
- @confine = Puppet::Provider::Confine.new(:exists, "foo")
- @confine.expects(:exists?).with("foo")
- @confine.valid?
- end
-
- it "should return false if the value is false" do
- @confine.exists?(false).should be_false
- end
-
- it "should return false if the value does not point to a file" do
- FileTest.expects(:exist?).with("/my/file").returns false
- @confine.exists?("/my/file").should be_false
- end
-
- it "should return true if the value points to a file" do
- FileTest.expects(:exist?).with("/my/file").returns true
- @confine.exists?("/my/file").should be_true
- end
-
- it "should log that a value is true" do
- @confine = Puppet::Provider::Confine.new(:true, nil)
- Puppet.expects(:debug).with { |l| l.include?("true") }
- @confine.valid?
- end
-
- describe "and the confine is for binaries" do
- before { @confine.stubs(:for_binary).returns true }
- it "should use its 'binary' method to look up the full path of the file" do
- @confine.expects(:binary).returns nil
- @confine.exists?("/my/file")
- end
-
- it "should return false if no binary can be found" do
- @confine.expects(:binary).with("/my/file").returns nil
- @confine.exists?("/my/file").should be_false
- end
-
- it "should return true if the binary can be found and the file exists" do
- @confine.expects(:binary).with("/my/file").returns "/my/file"
- FileTest.expects(:exist?).with("/my/file").returns true
- @confine.exists?("/my/file").should be_true
- end
-
- it "should return false if the binary can be found but the file does not exist" do
- @confine.expects(:binary).with("/my/file").returns "/my/file"
- FileTest.expects(:exist?).with("/my/file").returns true
- @confine.exists?("/my/file").should be_true
- end
- end
- end
-
- describe "and the test is not 'true', 'false', or 'exists'" do
- it "should use the 'match?' method to test validity" do
- @confine = Puppet::Provider::Confine.new("yay", "foo")
- @confine.expects(:match?).with("foo")
- @confine.valid?
- end
-
- it "should return true if the value matches the facter value" do
- Facter.expects(:value).returns("foo")
-
- @confine.match?("foo").should be_true
- end
-
- it "should return false if the value does not match the facter value" do
- Facter.expects(:value).returns("boo")
-
- @confine.match?("foo").should be_false
- end
-
- it "should be case insensitive" do
- Facter.expects(:value).returns("FOO")
-
- @confine.match?("foo").should be_true
- end
-
- it "should not care whether the value is a string or symbol" do
- Facter.expects(:value).returns("FOO")
-
- @confine.match?(:foo).should be_true
- end
-
- it "should cache the fact during testing" do
- Facter.expects(:value).once.returns("FOO")
-
- @confine.match?(:foo)
- @confine.match?(:foo)
- end
-
- it "should log that the fact value is not correct" do
- @confine = Puppet::Provider::Confine.new("foo", ["bar", "bee"])
- Facter.expects(:value).with("foo").returns "yayness"
- Puppet.expects(:debug).with { |l| l.include?("facter") and l.include?("bar,bee") }
- @confine.valid?
- end
- end
+ it "should have a 'facter' test" do
+ Puppet::Provider::Confine.test(:facter).should be_instance_of(Class)
end
describe "when testing all values" do
- before { @confine = Puppet::Provider::Confine.new(:true, %w{a b c}) }
+ before { @confine = Puppet::Provider::Confine.new(%w{a b c}) }
it "should be invalid if any values fail" do
- @confine.stubs(:true?).returns true
- @confine.expects(:true?).with("b").returns false
+ @confine.stubs(:pass?).returns true
+ @confine.expects(:pass?).with("b").returns false
@confine.should_not be_valid
end
it "should be valid if all values pass" do
- @confine.stubs(:true?).returns true
+ @confine.stubs(:pass?).returns true
@confine.should be_valid
end
it "should short-cut at the first failing value" do
- @confine.expects(:true?).once.returns false
- @confine.valid?
- end
-
- it "should remove the cached facter value" do
- @confine = Puppet::Provider::Confine.new(:foo, :bar)
- Facter.expects(:value).with(:foo).times(2).returns "eh"
- @confine.valid?
+ @confine.expects(:pass?).once.returns false
@confine.valid?
end
end
describe "when testing the result of the values" do
- before { @confine = Puppet::Provider::Confine.new(:true, %w{a b c d}) }
+ before { @confine = Puppet::Provider::Confine.new(%w{a b c d}) }
it "should return an array with the result of the test for each value" do
- @confine.stubs(:true?).returns true
- @confine.expects(:true?).with("b").returns false
- @confine.expects(:true?).with("d").returns false
+ @confine.stubs(:pass?).returns true
+ @confine.expects(:pass?).with("b").returns false
+ @confine.expects(:pass?).with("d").returns false
@confine.result.should == [true, false, true, false]
end
diff --git a/spec/unit/provider/confine/exists.rb b/spec/unit/provider/confine/exists.rb
new file mode 100755
index 000000000..1ab1d39f7
--- /dev/null
+++ b/spec/unit/provider/confine/exists.rb
@@ -0,0 +1,80 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/provider/confine/exists'
+
+describe Puppet::Provider::Confine::Exists do
+ before do
+ @confine = Puppet::Provider::Confine::Exists.new("/my/file")
+ end
+
+ it "should be named :exists" do
+ Puppet::Provider::Confine::Exists.name.should == :exists
+ end
+
+ it "should use the 'pass?' method to test validity" do
+ @confine.expects(:pass?).with("/my/file")
+ @confine.valid?
+ end
+
+ it "should return false if the value is false" do
+ @confine.pass?(false).should be_false
+ end
+
+ it "should return false if the value does not point to a file" do
+ FileTest.expects(:exist?).with("/my/file").returns false
+ @confine.pass?("/my/file").should be_false
+ end
+
+ it "should return true if the value points to a file" do
+ FileTest.expects(:exist?).with("/my/file").returns true
+ @confine.pass?("/my/file").should be_true
+ end
+
+ it "should produce a message saying that a file is missing" do
+ @confine.message("/my/file").should be_include("does not exist")
+ end
+
+ describe "and the confine is for binaries" do
+ before { @confine.stubs(:for_binary).returns true }
+ it "should use its 'binary' method to look up the full path of the file" do
+ @confine.expects(:binary).returns nil
+ @confine.pass?("/my/file")
+ end
+
+ it "should return false if no binary can be found" do
+ @confine.expects(:binary).with("/my/file").returns nil
+ @confine.pass?("/my/file").should be_false
+ end
+
+ it "should return true if the binary can be found and the file exists" do
+ @confine.expects(:binary).with("/my/file").returns "/my/file"
+ FileTest.expects(:exist?).with("/my/file").returns true
+ @confine.pass?("/my/file").should be_true
+ end
+
+ it "should return false if the binary can be found but the file does not exist" do
+ @confine.expects(:binary).with("/my/file").returns "/my/file"
+ FileTest.expects(:exist?).with("/my/file").returns true
+ @confine.pass?("/my/file").should be_true
+ end
+ end
+
+ it "should produce a summary containing all missing files" do
+ FileTest.stubs(:exist?).returns true
+ FileTest.expects(:exist?).with("/two").returns false
+ FileTest.expects(:exist?).with("/four").returns false
+
+ confine = Puppet::Provider::Confine::Exists.new %w{/one /two /three /four}
+ confine.summary.should == %w{/two /four}
+ end
+
+ it "should summarize multiple instances by returning a flattened array of their summaries" do
+ c1 = mock '1', :summary => %w{one}
+ c2 = mock '2', :summary => %w{two}
+ c3 = mock '3', :summary => %w{three}
+
+ Puppet::Provider::Confine::Exists.summarize([c1, c2, c3]).should == %w{one two three}
+ end
+end
diff --git a/spec/unit/provider/confine/facter.rb b/spec/unit/provider/confine/facter.rb
new file mode 100755
index 000000000..560263257
--- /dev/null
+++ b/spec/unit/provider/confine/facter.rb
@@ -0,0 +1,86 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/provider/confine/facter'
+
+describe Puppet::Provider::Confine::Facter::Facter do
+ it "should be named :facter" do
+ Puppet::Provider::Confine::Facter.name.should == :facter
+ end
+
+ it "should require a value" do
+ lambda { Puppet::Provider::Confine::Facter.new() }.should raise_error(ArgumentError)
+ end
+
+ it "should always convert values to an array" do
+ Puppet::Provider::Confine::Facter.new("/some/file").values.should be_instance_of(Array)
+ end
+
+ it "should have an accessor for its fact" do
+ Puppet::Provider::Confine::Facter.new(:bar).should respond_to(:fact)
+ end
+
+ describe "when testing values" do
+ before { @confine = Puppet::Provider::Confine::Facter.new("foo") }
+ it "should use the 'pass?' method to test validity" do
+ @confine.expects(:pass?).with("foo")
+ @confine.valid?
+ end
+
+ it "should return true if the value matches the facter value" do
+ Facter.expects(:value).returns("foo")
+
+ @confine.pass?("foo").should be_true
+ end
+
+ it "should return false if the value does not match the facter value" do
+ Facter.expects(:value).returns("boo")
+
+ @confine.pass?("foo").should be_false
+ end
+
+ it "should be case insensitive" do
+ Facter.expects(:value).returns("FOO")
+
+ @confine.pass?("foo").should be_true
+ end
+
+ it "should not care whether the value is a string or symbol" do
+ Facter.expects(:value).returns("FOO")
+
+ @confine.pass?(:foo).should be_true
+ end
+
+ it "should cache the fact during testing" do
+ Facter.expects(:value).once.returns("FOO")
+
+ @confine.pass?(:foo)
+ @confine.pass?(:foo)
+ end
+
+ it "should produce a message that the fact value is not correct" do
+ @confine = Puppet::Provider::Confine::Facter.new(%w{bar bee})
+ message = @confine.message("value")
+ message.should be_include("facter")
+ message.should be_include("bar,bee")
+ end
+ end
+
+ describe "when summarizing multiple instances" do
+ it "should return a hash of failing variables and their values" do
+ c1 = stub '1', :valid? => false, :values => %w{one}, :fact => "uno"
+ c2 = stub '2', :valid? => true, :values => %w{two}, :fact => "dos"
+ c3 = stub '3', :valid? => false, :values => %w{three}, :fact => "tres"
+
+ Puppet::Provider::Confine::Facter.summarize([c1, c2, c3]).should == {"uno" => %w{one}, "tres" => %w{three}}
+ end
+
+ it "should combine the values of multiple confines with the same fact" do
+ c1 = stub '1', :valid? => false, :values => %w{one}, :fact => "uno"
+ c2 = stub '2', :valid? => false, :values => %w{two}, :fact => "uno"
+
+ Puppet::Provider::Confine::Facter.summarize([c1, c2]).should == {"uno" => %w{one two}}
+ end
+ end
+end
diff --git a/spec/unit/provider/confine/false.rb b/spec/unit/provider/confine/false.rb
new file mode 100755
index 000000000..c6c43e391
--- /dev/null
+++ b/spec/unit/provider/confine/false.rb
@@ -0,0 +1,52 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/provider/confine/false'
+
+describe Puppet::Provider::Confine::False do
+ it "should be named :false" do
+ Puppet::Provider::Confine::False.name.should == :false
+ end
+
+ it "should require a value" do
+ lambda { Puppet::Provider::Confine.new() }.should raise_error(ArgumentError)
+ end
+
+ describe "when testing values" do
+ before { @confine = Puppet::Provider::Confine::False.new("foo") }
+
+ it "should use the 'pass?' method to test validity" do
+ @confine = Puppet::Provider::Confine::False.new("foo")
+ @confine.expects(:pass?).with("foo")
+ @confine.valid?
+ end
+
+ it "should return true if the value is false" do
+ @confine.pass?(false).should be_true
+ end
+
+ it "should return false if the value is not false" do
+ @confine.pass?("else").should be_false
+ end
+
+ it "should produce a message that a value is true" do
+ @confine = Puppet::Provider::Confine::False.new("foo")
+ @confine.message("eh").should be_include("true")
+ end
+ end
+
+ it "should be able to produce a summary with the number of incorrectly true values" do
+ confine = Puppet::Provider::Confine::False.new %w{one two three four}
+ confine.expects(:pass?).times(4).returns(true).returns(false).returns(true).returns(false)
+ confine.summary.should == 2
+ end
+
+ it "should summarize multiple instances by summing their summaries" do
+ c1 = mock '1', :summary => 1
+ c2 = mock '2', :summary => 2
+ c3 = mock '3', :summary => 3
+
+ Puppet::Provider::Confine::False.summarize([c1, c2, c3]).should == 6
+ end
+end
diff --git a/spec/unit/provider/confine/feature.rb b/spec/unit/provider/confine/feature.rb
new file mode 100755
index 000000000..1845c9a47
--- /dev/null
+++ b/spec/unit/provider/confine/feature.rb
@@ -0,0 +1,59 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/provider/confine/feature'
+
+describe Puppet::Provider::Confine::Feature do
+ it "should be named :feature" do
+ Puppet::Provider::Confine::Feature.name.should == :feature
+ end
+
+ it "should require a value" do
+ lambda { Puppet::Provider::Confine::Feature.new() }.should raise_error(ArgumentError)
+ end
+
+ it "should always convert values to an array" do
+ Puppet::Provider::Confine::Feature.new("/some/file").values.should be_instance_of(Array)
+ end
+
+ describe "when testing values" do
+ before do
+ @features = mock 'features'
+ Puppet.stubs(:features).returns @features
+ @confine = Puppet::Provider::Confine::Feature.new("myfeature")
+ end
+
+ it "should use the Puppet features instance to test validity" do
+ @features.expects(:myfeature?)
+ @confine.valid?
+ end
+
+ it "should return true if the feature is present" do
+ @features.expects(:myfeature?).returns true
+ @confine.pass?("myfeature").should be_true
+ end
+
+ it "should return false if the value is false" do
+ @features.expects(:myfeature?).returns false
+ @confine.pass?("myfeature").should be_false
+ end
+
+ it "should log that a feature is missing" do
+ @confine.message("myfeat").should be_include("missing")
+ end
+ end
+
+ it "should summarize multiple instances by returning a flattened array of all missing features" do
+ confines = []
+ confines << Puppet::Provider::Confine::Feature.new(%w{one two})
+ confines << Puppet::Provider::Confine::Feature.new(%w{two})
+ confines << Puppet::Provider::Confine::Feature.new(%w{three four})
+
+ features = mock 'feature'
+ features.stub_everything
+ Puppet.stubs(:features).returns features
+
+ Puppet::Provider::Confine::Feature.summarize(confines).sort.should == %w{one two three four}.sort
+ end
+end
diff --git a/spec/unit/provider/confine/true.rb b/spec/unit/provider/confine/true.rb
new file mode 100755
index 000000000..c9cc83c9e
--- /dev/null
+++ b/spec/unit/provider/confine/true.rb
@@ -0,0 +1,50 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/provider/confine/true'
+
+describe Puppet::Provider::Confine::True do
+ it "should be named :true" do
+ Puppet::Provider::Confine::True.name.should == :true
+ end
+
+ it "should require a value" do
+ lambda { Puppet::Provider::Confine::True.new() }.should raise_error(ArgumentError)
+ end
+
+ describe "when testing values" do
+ before { @confine = Puppet::Provider::Confine::True.new("foo") }
+
+ it "should use the 'pass?' method to test validity" do
+ @confine.expects(:pass?).with("foo")
+ @confine.valid?
+ end
+
+ it "should return true if the value is not false" do
+ @confine.pass?("else").should be_true
+ end
+
+ it "should return false if the value is false" do
+ @confine.pass?(nil).should be_false
+ end
+
+ it "should produce the message that a value is false" do
+ @confine.message("eh").should be_include("false")
+ end
+ end
+
+ it "should produce the number of false values when asked for a summary" do
+ @confine = Puppet::Provider::Confine::True.new %w{one two three four}
+ @confine.expects(:pass?).times(4).returns(true).returns(false).returns(true).returns(false)
+ @confine.summary.should == 2
+ end
+
+ it "should summarize multiple instances by summing their summaries" do
+ c1 = mock '1', :summary => 1
+ c2 = mock '2', :summary => 2
+ c3 = mock '3', :summary => 3
+
+ Puppet::Provider::Confine::True.summarize([c1, c2, c3]).should == 6
+ end
+end
diff --git a/spec/unit/provider/confine_collection.rb b/spec/unit/provider/confine_collection.rb
index 3430d604f..da4b3fe72 100755
--- a/spec/unit/provider/confine_collection.rb
+++ b/spec/unit/provider/confine_collection.rb
@@ -9,105 +9,114 @@ describe Puppet::Provider::ConfineCollection do
Puppet::Provider::ConfineCollection.new.should respond_to(:confine)
end
- it "should create a Confine instance for every confine call" do
- Puppet::Provider::Confine.expects(:new).with(:foo, :bar).returns "eh"
- Puppet::Provider::Confine.expects(:new).with(:baz, :bee).returns "eh"
- Puppet::Provider::ConfineCollection.new.confine :foo => :bar, :baz => :bee
- end
+ describe "when creating confine instances" do
+ it "should create an instance of the named test with the provided values" do
+ test_class = mock 'test_class'
+ test_class.expects(:new).with(%w{my values})
+ Puppet::Provider::Confine.expects(:test).with(:foo).returns test_class
+
+ Puppet::Provider::ConfineCollection.new.confine :foo => %w{my values}
+ end
+
+ describe "and the test cannot be found" do
+ before do
+ @facter = mock 'facter_test'
+
+ Puppet::Provider::Confine.expects(:test).with(:foo).returns nil
+ Puppet::Provider::Confine.expects(:test).with(:facter).returns @facter
+ end
+
+ it "should create a Facter test with the provided values and set the fact to the test name" do
+ confine = mock 'confine'
+ confine.expects(:fact=).with(:foo)
+ @facter.expects(:new).with(%w{my values}).returns confine
+ Puppet::Provider::ConfineCollection.new.confine :foo => %w{my values}
+ end
+ end
- it "should mark each confine as a binary confine if :for_binary => true is included" do
- confine = mock 'confine'
- confine.expects(:for_binary=).with true
- Puppet::Provider::Confine.expects(:new).with(:foo, :bar).returns confine
- Puppet::Provider::ConfineCollection.new.confine :foo => :bar, :for_binary => true
+ describe "and the 'for_binary' option was provided" do
+ it "should mark the test as a binary confine" do
+ confine = mock 'confine'
+ confine.expects(:for_binary=).with true
+ Puppet::Provider::Confine.test(:exists).expects(:new).with(:bar).returns confine
+ Puppet::Provider::ConfineCollection.new.confine :exists => :bar, :for_binary => true
+ end
+ end
end
it "should be valid if no confines are present" do
Puppet::Provider::ConfineCollection.new.should be_valid
end
- it "should be valid if all confines are valid" do
+ it "should be valid if all confines pass" do
c1 = mock 'c1', :valid? => true
c2 = mock 'c2', :valid? => true
- Puppet::Provider::Confine.expects(:new).times(2).returns(c1).then.returns(c2)
+ Puppet::Provider::Confine.test(:true).expects(:new).returns(c1)
+ Puppet::Provider::Confine.test(:false).expects(:new).returns(c2)
confiner = Puppet::Provider::ConfineCollection.new
- confiner.confine :foo => :bar, :baz => :bee
+ confiner.confine :true => :bar, :false => :bee
confiner.should be_valid
end
- it "should not be valid if any confines are valid" do
- c1 = mock 'c1', :valid? => true
- c2 = mock 'c2', :valid? => false
+ it "should not be valid if any confines fail" do
+ c1 = stub 'c1', :valid? => true
+ c2 = stub 'c2', :valid? => false
- Puppet::Provider::Confine.expects(:new).times(2).returns(c1).then.returns(c2)
+ Puppet::Provider::Confine.test(:true).expects(:new).returns(c1)
+ Puppet::Provider::Confine.test(:false).expects(:new).returns(c2)
confiner = Puppet::Provider::ConfineCollection.new
- confiner.confine :foo => :bar, :baz => :bee
+ confiner.confine :true => :bar, :false => :bee
confiner.should_not be_valid
end
- describe "when providing a complete result" do
+ describe "when providing a summary" do
before do
@confiner = Puppet::Provider::ConfineCollection.new
end
it "should return a hash" do
- @confiner.result.should be_instance_of(Hash)
+ @confiner.summary.should be_instance_of(Hash)
end
it "should return an empty hash if the confiner is valid" do
- @confiner.result.should == {}
+ @confiner.summary.should == {}
end
- it "should contain the number of incorrectly false values" do
- c1 = stub 'c1', :result => [true, false, true], :test => :true
- c2 = stub 'c2', :result => [false, true, false], :test => :true
-
- Puppet::Provider::Confine.expects(:new).times(2).returns(c1).then.returns(c2)
-
- confiner = Puppet::Provider::ConfineCollection.new
- confiner.confine :foo => :bar, :baz => :bee
+ it "should add each test type's summary to the hash" do
+ @confiner.confine :true => :bar, :false => :bee
+ Puppet::Provider::Confine.test(:true).expects(:summarize).returns :tsumm
+ Puppet::Provider::Confine.test(:false).expects(:summarize).returns :fsumm
- confiner.result[:true].should == 3
+ @confiner.summary.should == {:true => :tsumm, :false => :fsumm}
end
- it "should contain the number of incorrectly true values" do
- c1 = stub 'c1', :result => [true, false, true], :test => :false
- c2 = stub 'c2', :result => [false, true, false], :test => :false
+ it "should not include tests that return 0" do
+ @confiner.confine :true => :bar, :false => :bee
+ Puppet::Provider::Confine.test(:true).expects(:summarize).returns 0
+ Puppet::Provider::Confine.test(:false).expects(:summarize).returns :fsumm
- Puppet::Provider::Confine.expects(:new).times(2).returns(c1).then.returns(c2)
-
- confiner = Puppet::Provider::ConfineCollection.new
- confiner.confine :foo => :bar, :baz => :bee
-
- confiner.result[:false].should == 3
+ @confiner.summary.should == {:false => :fsumm}
end
- it "should contain the missing files" do
- FileTest.stubs(:exist?).returns true
- FileTest.expects(:exist?).with("/two").returns false
- FileTest.expects(:exist?).with("/four").returns false
-
- confiner = Puppet::Provider::ConfineCollection.new
- confiner.confine :exists => %w{/one /two}
- confiner.confine :exists => %w{/three /four}
+ it "should not include tests that return empty arrays" do
+ @confiner.confine :true => :bar, :false => :bee
+ Puppet::Provider::Confine.test(:true).expects(:summarize).returns []
+ Puppet::Provider::Confine.test(:false).expects(:summarize).returns :fsumm
- confiner.result[:exists].should == %w{/two /four}
+ @confiner.summary.should == {:false => :fsumm}
end
- it "should contain a hash of facts and the allowed values" do
- Facter.expects(:value).with(:foo).returns "yay"
- Facter.expects(:value).with(:bar).returns "boo"
- confiner = Puppet::Provider::ConfineCollection.new
- confiner.confine :foo => "yes", :bar => "boo"
+ it "should not include tests that return empty hashes" do
+ @confiner.confine :true => :bar, :false => :bee
+ Puppet::Provider::Confine.test(:true).expects(:summarize).returns({})
+ Puppet::Provider::Confine.test(:false).expects(:summarize).returns :fsumm
- result = confiner.result
- result[:facter][:foo].should == %w{yes}
- result[:facter][:bar].should be_nil
+ @confiner.summary.should == {:false => :fsumm}
end
end
end
diff --git a/spec/unit/provider/confiner.rb b/spec/unit/provider/confiner.rb
index 38fffc102..078fc4420 100755
--- a/spec/unit/provider/confiner.rb
+++ b/spec/unit/provider/confiner.rb
@@ -54,8 +54,8 @@ describe Puppet::Provider::Confiner do
@object.should_not be_suitable
end
- it "should return the result of the confine collection if a long result is asked for" do
- @coll.expects(:result).returns "myresult"
+ it "should return the summary of the confine collection if a long result is asked for" do
+ @coll.expects(:summary).returns "myresult"
@object.suitable?(false).should == "myresult"
end
end
diff --git a/spec/unit/provider/interface/redhat.rb b/spec/unit/provider/interface/redhat.rb
index 5a7a8dfcd..99ac50f01 100755
--- a/spec/unit/provider/interface/redhat.rb
+++ b/spec/unit/provider/interface/redhat.rb
@@ -9,12 +9,12 @@ provider_class = Puppet::Type.type(:interface).provider(:redhat)
describe provider_class do
it "should not be functional on systems without a network-scripts directory" do
- FileTest.expects(:exists?).with("/etc/sysconfig/network-scripts").returns(false)
+ FileTest.expects(:exist?).with("/etc/sysconfig/network-scripts").returns(false)
provider_class.should_not be_suitable
end
it "should be functional on systems with a network-scripts directory" do
- FileTest.expects(:exists?).with("/etc/sysconfig/network-scripts").returns(true)
+ FileTest.expects(:exist?).with("/etc/sysconfig/network-scripts").returns(true)
provider_class.should be_suitable
end
end
diff --git a/spec/unit/util/storage.rb b/spec/unit/util/storage.rb
new file mode 100755
index 000000000..55d1d1f61
--- /dev/null
+++ b/spec/unit/util/storage.rb
@@ -0,0 +1,237 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'yaml'
+require 'tempfile'
+
+require 'puppet/util/storage'
+
+describe Puppet::Util::Storage do
+ before(:all) do
+ Puppet[:statedir] = Dir.tmpdir()
+ end
+
+ before(:each) do
+ Puppet::Util::Storage.clear()
+ end
+
+ describe "when caching a symbol" do
+ it "should return an empty hash" do
+ Puppet::Util::Storage.cache(:yayness).should == {}
+ Puppet::Util::Storage.cache(:more_yayness).should == {}
+ end
+
+ it "should add the symbol to its internal state" do
+ Puppet::Util::Storage.cache(:yayness)
+ Puppet::Util::Storage.state().should == {:yayness=>{}}
+ end
+
+ it "should not clobber existing state when caching additional objects" do
+ Puppet::Util::Storage.cache(:yayness)
+ Puppet::Util::Storage.state().should == {:yayness=>{}}
+ Puppet::Util::Storage.cache(:bubblyness)
+ Puppet::Util::Storage.state().should == {:yayness=>{},:bubblyness=>{}}
+ end
+ end
+
+ describe "when caching a Puppet::Type" do
+ before(:all) do
+ @file_test = Puppet.type(:file).create(:name => "/yayness", :check => %w{checksum type})
+ @exec_test = Puppet.type(:exec).create(:name => "/bin/ls /yayness")
+ end
+
+ it "should return an empty hash" do
+ Puppet::Util::Storage.cache(@file_test).should == {}
+ Puppet::Util::Storage.cache(@exec_test).should == {}
+ end
+
+ it "should add the resource ref to its internal state" do
+ Puppet::Util::Storage.state().should == {}
+ Puppet::Util::Storage.cache(@file_test)
+ Puppet::Util::Storage.state().should == {"File[/yayness]"=>{}}
+ Puppet::Util::Storage.cache(@exec_test)
+ Puppet::Util::Storage.state().should == {"File[/yayness]"=>{}, "Exec[/bin/ls /yayness]"=>{}}
+ end
+ end
+
+ describe "when caching invalid objects" do
+ before(:all) do
+ @bogus_objects = [ {}, [], "foo", 42, nil, Tempfile.new('storage_test') ]
+ end
+
+ it "should raise an ArgumentError" do
+ @bogus_objects.each do |object|
+ proc { Puppet::Util::Storage.cache(object) }.should raise_error()
+ end
+ end
+
+ it "should not add anything to its internal state" do
+ @bogus_objects.each do |object|
+ begin
+ Puppet::Util::Storage.cache(object)
+ rescue
+ Puppet::Util::Storage.state().should == {}
+ end
+ end
+ end
+ end
+
+ it "should clear its internal state when clear() is called" do
+ Puppet::Util::Storage.cache(:yayness)
+ Puppet::Util::Storage.state().should == {:yayness=>{}}
+ Puppet::Util::Storage.clear()
+ Puppet::Util::Storage.state().should == {}
+ end
+
+ describe "when loading from the state file" do
+ describe "when the state file/directory does not exist" do
+ before(:each) do
+ transient = Tempfile.new('storage_test')
+ @path = transient.path()
+ transient.close!()
+ end
+
+ it "should not fail to load()" do
+ FileTest.exists?(@path).should be_false()
+ Puppet[:statedir] = @path
+ proc { Puppet::Util::Storage.load() }.should_not raise_error()
+ Puppet[:statefile] = @path
+ proc { Puppet::Util::Storage.load() }.should_not raise_error()
+ end
+
+ it "should not lose its internal state when load() is called" do
+ FileTest.exists?(@path).should be_false()
+
+ Puppet::Util::Storage.cache(:yayness)
+ Puppet::Util::Storage.state().should == {:yayness=>{}}
+
+ Puppet[:statefile] = @path
+ proc { Puppet::Util::Storage.load() }.should_not raise_error()
+
+ Puppet::Util::Storage.state().should == {:yayness=>{}}
+ end
+ end
+
+ describe "when the state file/directory exists" do
+ before(:each) do
+ @state_file = Tempfile.new('storage_test')
+ @saved_statefile = Puppet[:statefile]
+ Puppet[:statefile] = @state_file.path()
+ end
+
+ it "should overwrite its internal state if load() is called" do
+ # Should the state be overwritten even if Puppet[:statefile] is not valid YAML?
+ Puppet::Util::Storage.cache(:yayness)
+ Puppet::Util::Storage.state().should == {:yayness=>{}}
+
+ proc { Puppet::Util::Storage.load() }.should_not raise_error()
+ Puppet::Util::Storage.state().should == {}
+ end
+
+ it "should restore its internal state if the state file contains valid YAML" do
+ test_yaml = {'File["/yayness"]'=>{"name"=>{:a=>:b,:c=>:d}}}
+ YAML.expects(:load).returns(test_yaml)
+
+ proc { Puppet::Util::Storage.load() }.should_not raise_error()
+ Puppet::Util::Storage.state().should == test_yaml
+ end
+
+ it "should initialize with a clear internal state if the state file does not contain valid YAML" do
+ @state_file.write(:booness)
+
+ proc { Puppet::Util::Storage.load() }.should_not raise_error()
+ Puppet::Util::Storage.state().should == {}
+ end
+
+ it "should raise an error if the state file does not contain valid YAML and cannot be renamed" do
+ @state_file.write(:booness)
+ File.chmod(0000, @state_file.path())
+
+ proc { Puppet::Util::Storage.load() }.should raise_error()
+ end
+
+ it "should attempt to rename the state file if the file is corrupted" do
+ # We fake corruption by causing YAML.load to raise an exception
+ YAML.expects(:load).raises(Puppet::Error)
+ File.expects(:rename).at_least_once
+
+ proc { Puppet::Util::Storage.load() }.should_not raise_error()
+ end
+
+ it "should fail gracefully on load() if the state file is not a regular file" do
+ @state_file.close!()
+ Dir.mkdir(Puppet[:statefile])
+ File.expects(:rename).returns(0)
+
+ proc { Puppet::Util::Storage.load() }.should_not raise_error()
+
+ Dir.rmdir(Puppet[:statefile])
+ end
+
+ it "should fail gracefully on load() if it cannot get a read lock on the state file" do
+ Puppet::Util.expects(:readlock).yields(false)
+ test_yaml = {'File["/yayness"]'=>{"name"=>{:a=>:b,:c=>:d}}}
+ YAML.expects(:load).returns(test_yaml)
+
+ proc { Puppet::Util::Storage.load() }.should_not raise_error()
+ Puppet::Util::Storage.state().should == test_yaml
+ end
+
+ after(:each) do
+ @state_file.close!()
+ Puppet[:statefile] = @saved_statefile
+ end
+ end
+ end
+
+ describe "when storing to the state file" do
+ before(:each) do
+ @state_file = Tempfile.new('storage_test')
+ @saved_statefile = Puppet[:statefile]
+ Puppet[:statefile] = @state_file.path()
+ end
+
+ it "should create the state file if it does not exist" do
+ @state_file.close!()
+ FileTest.exists?(Puppet[:statefile]).should be_false()
+ Puppet::Util::Storage.cache(:yayness)
+
+ proc { Puppet::Util::Storage.store() }.should_not raise_error()
+ FileTest.exists?(Puppet[:statefile]).should be_true()
+ end
+
+ it "should raise an exception if the state file is not a regular file" do
+ @state_file.close!()
+ Dir.mkdir(Puppet[:statefile])
+ Puppet::Util::Storage.cache(:yayness)
+
+ proc { Puppet::Util::Storage.store() }.should raise_error()
+
+ Dir.rmdir(Puppet[:statefile])
+ end
+
+ it "should raise an exception if it cannot get a write lock on the state file" do
+ Puppet::Util.expects(:writelock).yields(false)
+ Puppet::Util::Storage.cache(:yayness)
+
+ proc { Puppet::Util::Storage.store() }.should raise_error()
+ end
+
+ it "should load() the same information that it store()s" do
+ Puppet::Util::Storage.cache(:yayness)
+
+ Puppet::Util::Storage.state().should == {:yayness=>{}}
+ proc { Puppet::Util::Storage.store() }.should_not raise_error()
+ Puppet::Util::Storage.clear()
+ Puppet::Util::Storage.state().should == {}
+ proc { Puppet::Util::Storage.load() }.should_not raise_error()
+ Puppet::Util::Storage.state().should == {:yayness=>{}}
+ end
+
+ after(:each) do
+ @state_file.close!()
+ Puppet[:statefile] = @saved_statefile
+ end
+ end
+end