summaryrefslogtreecommitdiffstats
path: root/spec/unit
diff options
context:
space:
mode:
Diffstat (limited to 'spec/unit')
-rwxr-xr-xspec/unit/module.rb6
-rwxr-xr-xspec/unit/network/client/master.rb18
-rwxr-xr-x[-rw-r--r--]spec/unit/network/xmlrpc/client.rb0
-rwxr-xr-xspec/unit/node/catalog.rb18
-rwxr-xr-xspec/unit/other/transobject.rb8
-rw-r--r--spec/unit/parser/ast.rb37
-rwxr-xr-xspec/unit/parser/ast/arithmetic_operator.rb20
-rwxr-xr-xspec/unit/parser/ast/boolean_operator.rb18
-rwxr-xr-xspec/unit/parser/ast/collexpr.rb22
-rwxr-xr-xspec/unit/parser/ast/comparison_operator.rb60
-rw-r--r--spec/unit/parser/ast/function.rb77
-rwxr-xr-xspec/unit/parser/ast/resource_override.rb14
-rwxr-xr-xspec/unit/parser/ast/resource_reference.rb10
-rwxr-xr-xspec/unit/parser/compiler.rb41
-rw-r--r--spec/unit/parser/functions.rb83
-rw-r--r--spec/unit/parser/functions/inline_template.rb59
-rw-r--r--spec/unit/parser/functions/template.rb62
-rwxr-xr-xspec/unit/parser/lexer.rb94
-rwxr-xr-xspec/unit/parser/parser.rb87
-rwxr-xr-xspec/unit/parser/resource/reference.rb20
-rwxr-xr-xspec/unit/parser/templatewrapper.rb57
-rw-r--r--spec/unit/property/list.rb9
-rw-r--r--spec/unit/property/ordered_list.rb64
-rwxr-xr-xspec/unit/provider/confine.rb13
-rwxr-xr-xspec/unit/provider/confine/exists.rb1
-rwxr-xr-xspec/unit/provider/confine/false.rb1
-rwxr-xr-xspec/unit/provider/confine/feature.rb1
-rwxr-xr-xspec/unit/provider/confine/true.rb5
-rwxr-xr-xspec/unit/provider/confine/variable.rb33
-rwxr-xr-xspec/unit/provider/confine_collection.rb56
-rwxr-xr-xspec/unit/provider/confiner.rb3
-rwxr-xr-xspec/unit/provider/mcx/mcxcontent.rb175
-rwxr-xr-xspec/unit/provider/mount/parsed.rb6
-rwxr-xr-xspec/unit/provider/service/launchd.rb134
-rwxr-xr-xspec/unit/provider/ssh_authorized_key/parsed.rb7
-rw-r--r--spec/unit/provider/user/user_role_add.rb58
-rwxr-xr-xspec/unit/provider/zfs/solaris.rb87
-rwxr-xr-xspec/unit/provider/zone/solaris.rb42
-rwxr-xr-xspec/unit/provider/zpool/solaris.rb158
-rwxr-xr-xspec/unit/ssl/certificate_request.rb3
-rwxr-xr-xspec/unit/transaction/change.rb13
-rwxr-xr-xspec/unit/type/computer.rb78
-rwxr-xr-xspec/unit/type/file/owner.rb132
-rw-r--r--spec/unit/type/file/selinux.rb3
-rwxr-xr-xspec/unit/type/mcx.rb100
-rwxr-xr-xspec/unit/type/package.rb1
-rw-r--r--spec/unit/type/resources.rb23
-rwxr-xr-xspec/unit/type/ssh_authorized_key.rb12
-rwxr-xr-xspec/unit/type/user.rb47
-rwxr-xr-xspec/unit/type/zfs.rb28
-rwxr-xr-xspec/unit/type/zone.rb20
-rwxr-xr-xspec/unit/type/zpool.rb28
-rw-r--r--spec/unit/util/selinux.rb109
53 files changed, 2046 insertions, 215 deletions
diff --git a/spec/unit/module.rb b/spec/unit/module.rb
index a6608fc1b..1deaec232 100755
--- a/spec/unit/module.rb
+++ b/spec/unit/module.rb
@@ -114,6 +114,12 @@ describe Puppet::Module, " when searching for templates" do
Puppet::Module.find_template("mytemplate").should == "/my/templates/mytemplate"
end
+ it "should accept relative templatedirs" do
+ Puppet[:templatedir] = "my/templates"
+ File.expects(:directory?).with(File.join(Dir.getwd,"my/templates")).returns(true)
+ Puppet::Module.find_template("mytemplate").should == File.join(Dir.getwd,"my/templates/mytemplate")
+ end
+
it "should use the environment templatedir if no module is found and an environment is specified" do
Puppet::Module.stubs(:templatepath).with("myenv").returns(["/myenv/templates"])
Puppet::Module.expects(:find).with("mymod", "myenv").returns(nil)
diff --git a/spec/unit/network/client/master.rb b/spec/unit/network/client/master.rb
index f55ba316c..050088707 100755
--- a/spec/unit/network/client/master.rb
+++ b/spec/unit/network/client/master.rb
@@ -411,29 +411,29 @@ describe Puppet::Network::Client::Master, " when using the cached catalog" do
Puppet.stubs(:[]).with(:splaylimit).returns(42)
end
- it "should sleep for a random time" do
- @client.expects(:rand).with(42).returns(42)
- @client.expects(:sleep).with(42)
+ it "should sleep for a random time plus 1" do
+ @client.expects(:rand).with(43).returns(43)
+ @client.expects(:sleep).with(43)
@client.send(:splay)
end
it "should inform that it is splayed" do
- @client.stubs(:rand).with(42).returns(42)
- @client.stubs(:sleep).with(42)
+ @client.stubs(:rand).with(43).returns(43)
+ @client.stubs(:sleep).with(43)
Puppet.expects(:info)
@client.send(:splay)
end
it "should set splay = true" do
- @client.stubs(:rand).with(42).returns(42)
- @client.stubs(:sleep).with(42)
+ @client.stubs(:rand).returns(43)
+ @client.stubs(:sleep)
@client.send(:splay)
@client.send(:splayed?).should == true
end
it "should do nothing if already splayed" do
- @client.stubs(:rand).with(42).returns(42).at_most_once
- @client.stubs(:sleep).with(42).at_most_once
+ @client.stubs(:rand).returns(43).at_most_once
+ @client.stubs(:sleep).at_most_once
@client.send(:splay)
@client.send(:splay)
end
diff --git a/spec/unit/network/xmlrpc/client.rb b/spec/unit/network/xmlrpc/client.rb
index a0a2e77fb..a0a2e77fb 100644..100755
--- a/spec/unit/network/xmlrpc/client.rb
+++ b/spec/unit/network/xmlrpc/client.rb
diff --git a/spec/unit/node/catalog.rb b/spec/unit/node/catalog.rb
index e3661d995..97674dfc2 100755
--- a/spec/unit/node/catalog.rb
+++ b/spec/unit/node/catalog.rb
@@ -152,7 +152,7 @@ describe Puppet::Node::Catalog, " when extracting transobjects" do
end
describe Puppet::Node::Catalog, " when converting to a transobject catalog" do
- class TestResource
+ class CatalogTestResource
attr_accessor :name, :virtual, :builtin
def initialize(name, options = {})
@name = name
@@ -185,14 +185,14 @@ describe Puppet::Node::Catalog, " when converting to a transobject catalog" do
@original.tag(*%w{one two three})
@original.add_class *%w{four five six}
- @top = TestResource.new 'top'
- @topobject = TestResource.new 'topobject', :builtin => true
- @virtual = TestResource.new 'virtual', :virtual => true
- @virtualobject = TestResource.new 'virtualobject', :builtin => true, :virtual => true
- @middle = TestResource.new 'middle'
- @middleobject = TestResource.new 'middleobject', :builtin => true
- @bottom = TestResource.new 'bottom'
- @bottomobject = TestResource.new 'bottomobject', :builtin => true
+ @top = CatalogTestResource.new 'top'
+ @topobject = CatalogTestResource.new 'topobject', :builtin => true
+ @virtual = CatalogTestResource.new 'virtual', :virtual => true
+ @virtualobject = CatalogTestResource.new 'virtualobject', :builtin => true, :virtual => true
+ @middle = CatalogTestResource.new 'middle'
+ @middleobject = CatalogTestResource.new 'middleobject', :builtin => true
+ @bottom = CatalogTestResource.new 'bottom'
+ @bottomobject = CatalogTestResource.new 'bottomobject', :builtin => true
@resources = [@top, @topobject, @middle, @middleobject, @bottom, @bottomobject]
diff --git a/spec/unit/other/transobject.rb b/spec/unit/other/transobject.rb
index 07ffdf8bd..33de72c74 100755
--- a/spec/unit/other/transobject.rb
+++ b/spec/unit/other/transobject.rb
@@ -77,9 +77,15 @@ describe Puppet::TransObject, " when converting to a RAL component instance" do
@resource.to_component.should == :yay
end
+ it "should copy over the catalog" do
+ @resource.catalog = "mycat"
+ Puppet::Type::Component.expects(:create).with { |resource| resource.catalog == "mycat" }.returns(:yay)
+ @resource.to_component
+ end
+
# LAK:FIXME This really isn't the design we want going forward, but it's
# good enough for now.
- it "should not pass resource paramaters that are not metaparams" do
+ it "should not pass resource parameters that are not metaparams" do
Puppet::Type::Component.expects(:create).with { |resource| resource["one"].nil? }.returns(:yay)
@resource.to_component.should == :yay
end
diff --git a/spec/unit/parser/ast.rb b/spec/unit/parser/ast.rb
new file mode 100644
index 000000000..513943725
--- /dev/null
+++ b/spec/unit/parser/ast.rb
@@ -0,0 +1,37 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/parser/ast'
+
+describe Puppet::Parser::AST do
+
+ it "should have a doc accessor" do
+ ast = Puppet::Parser::AST.new({})
+ ast.should respond_to(:doc)
+ end
+
+ it "should have a use_docs accessor to indicate it wants documentation" do
+ ast = Puppet::Parser::AST.new({})
+ ast.should respond_to(:use_docs)
+ end
+
+ [ Puppet::Parser::AST::Collection, Puppet::Parser::AST::Definition, Puppet::Parser::AST::Else,
+ Puppet::Parser::AST::Function, Puppet::Parser::AST::HostClass, Puppet::Parser::AST::IfStatement,
+ Puppet::Parser::AST::Node, Puppet::Parser::AST::Resource, Puppet::Parser::AST::ResourceDefaults,
+ Puppet::Parser::AST::ResourceOverride, Puppet::Parser::AST::VarDef
+ ].each do |k|
+ it "#{k}.use_docs should return true" do
+ ast = k.new({})
+ ast.use_docs.should be_true
+ end
+ end
+
+ describe "when initializing" do
+ it "should store the doc argument if passed" do
+ ast = Puppet::Parser::AST.new(:doc => "documentation")
+ ast.doc.should == "documentation"
+ end
+ end
+
+end \ No newline at end of file
diff --git a/spec/unit/parser/ast/arithmetic_operator.rb b/spec/unit/parser/ast/arithmetic_operator.rb
index 24d6ad47d..ce6d42faf 100755
--- a/spec/unit/parser/ast/arithmetic_operator.rb
+++ b/spec/unit/parser/ast/arithmetic_operator.rb
@@ -4,7 +4,7 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::ArithmeticOperator do
- AST = Puppet::Parser::AST
+ ast = Puppet::Parser::AST
before :each do
@scope = Puppet::Parser::Scope.new()
@@ -18,19 +18,19 @@ describe Puppet::Parser::AST::ArithmeticOperator do
rval = stub "rval"
rval.expects(:safeevaluate).with(@scope).returns(2)
- operator = AST::ArithmeticOperator.new :rval => rval, :operator => "+", :lval => lval
+ operator = ast::ArithmeticOperator.new :rval => rval, :operator => "+", :lval => lval
operator.evaluate(@scope)
end
it "should fail for an unknown operator" do
- lambda { operator = AST::ArithmeticOperator.new :lval => @one, :operator => "%", :rval => @two }.should raise_error
+ lambda { operator = ast::ArithmeticOperator.new :lval => @one, :operator => "%", :rval => @two }.should raise_error
end
it "should call Puppet::Parser::Scope.number?" do
Puppet::Parser::Scope.expects(:number?).with(1).returns(1)
Puppet::Parser::Scope.expects(:number?).with(2).returns(2)
- AST::ArithmeticOperator.new(:lval => @one, :operator => "+", :rval => @two).evaluate(@scope)
+ ast::ArithmeticOperator.new(:lval => @one, :operator => "+", :rval => @two).evaluate(@scope)
end
@@ -38,7 +38,7 @@ describe Puppet::Parser::AST::ArithmeticOperator do
it "should call ruby Numeric '#{op}'" do
one = stub 'one'
two = stub 'two'
- operator = AST::ArithmeticOperator.new :lval => @one, :operator => op, :rval => @two
+ operator = ast::ArithmeticOperator.new :lval => @one, :operator => op, :rval => @two
Puppet::Parser::Scope.stubs(:number?).with(1).returns(one)
Puppet::Parser::Scope.stubs(:number?).with(2).returns(two)
one.expects(:send).with(op,two)
@@ -49,24 +49,24 @@ describe Puppet::Parser::AST::ArithmeticOperator do
it "should work even with numbers embedded in strings" do
two = stub 'two', :safeevaluate => "2"
one = stub 'one', :safeevaluate => "1"
- operator = AST::ArithmeticOperator.new :lval => two, :operator => "+", :rval => one
+ operator = ast::ArithmeticOperator.new :lval => two, :operator => "+", :rval => one
operator.evaluate(@scope).should == 3
end
it "should work even with floats" do
two = stub 'two', :safeevaluate => 2.53
one = stub 'one', :safeevaluate => 1.80
- operator = AST::ArithmeticOperator.new :lval => two, :operator => "+", :rval => one
+ operator = ast::ArithmeticOperator.new :lval => two, :operator => "+", :rval => one
operator.evaluate(@scope).should == 4.33
end
it "should work for variables too" do
@scope.expects(:lookupvar).with("one").returns(1)
@scope.expects(:lookupvar).with("two").returns(2)
- one = AST::Variable.new( :value => "one" )
- two = AST::Variable.new( :value => "two" )
+ one = ast::Variable.new( :value => "one" )
+ two = ast::Variable.new( :value => "two" )
- operator = AST::ArithmeticOperator.new :lval => one, :operator => "+", :rval => two
+ operator = ast::ArithmeticOperator.new :lval => one, :operator => "+", :rval => two
operator.evaluate(@scope).should == 3
end
diff --git a/spec/unit/parser/ast/boolean_operator.rb b/spec/unit/parser/ast/boolean_operator.rb
index 7304e2a10..98e173bf0 100755
--- a/spec/unit/parser/ast/boolean_operator.rb
+++ b/spec/unit/parser/ast/boolean_operator.rb
@@ -4,12 +4,12 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::BooleanOperator do
- AST = Puppet::Parser::AST
+ ast = Puppet::Parser::AST
before :each do
@scope = Puppet::Parser::Scope.new()
- @true_ast = AST::Boolean.new( :value => true)
- @false_ast = AST::Boolean.new( :value => false)
+ @true_ast = ast::Boolean.new( :value => true)
+ @false_ast = ast::Boolean.new( :value => false)
end
it "should evaluate left operand inconditionally" do
@@ -18,7 +18,7 @@ describe Puppet::Parser::AST::BooleanOperator do
rval = stub "rval", :safeevaluate => false
rval.expects(:safeevaluate).never
- operator = AST::BooleanOperator.new :rval => rval, :operator => "or", :lval => lval
+ operator = ast::BooleanOperator.new :rval => rval, :operator => "or", :lval => lval
operator.evaluate(@scope)
end
@@ -26,7 +26,7 @@ describe Puppet::Parser::AST::BooleanOperator do
lval = stub "lval", :safeevaluate => true
rval = stub "rval", :safeevaluate => false
rval.expects(:safeevaluate).with(@scope).returns(false)
- operator = AST::BooleanOperator.new :rval => rval, :operator => "and", :lval => lval
+ operator = ast::BooleanOperator.new :rval => rval, :operator => "and", :lval => lval
operator.evaluate(@scope)
end
@@ -34,20 +34,20 @@ describe Puppet::Parser::AST::BooleanOperator do
lval = stub "lval", :safeevaluate => false
rval = stub "rval", :safeevaluate => false
rval.expects(:safeevaluate).with(@scope).returns(false)
- operator = AST::BooleanOperator.new :rval => rval, :operator => "or", :lval => lval
+ operator = ast::BooleanOperator.new :rval => rval, :operator => "or", :lval => lval
operator.evaluate(@scope)
end
it "should return true for false OR true" do
- AST::BooleanOperator.new(:rval => @true_ast, :operator => "or", :lval => @false_ast).evaluate(@scope).should be_true
+ ast::BooleanOperator.new(:rval => @true_ast, :operator => "or", :lval => @false_ast).evaluate(@scope).should be_true
end
it "should return false for true AND false" do
- AST::BooleanOperator.new(:rval => @true_ast, :operator => "and", :lval => @false_ast ).evaluate(@scope).should be_false
+ ast::BooleanOperator.new(:rval => @true_ast, :operator => "and", :lval => @false_ast ).evaluate(@scope).should be_false
end
it "should return true for true AND true" do
- AST::BooleanOperator.new(:rval => @true_ast, :operator => "and", :lval => @true_ast ).evaluate(@scope).should be_true
+ ast::BooleanOperator.new(:rval => @true_ast, :operator => "and", :lval => @true_ast ).evaluate(@scope).should be_true
end
end
diff --git a/spec/unit/parser/ast/collexpr.rb b/spec/unit/parser/ast/collexpr.rb
index e5e6e0d7a..5f0ca941e 100755
--- a/spec/unit/parser/ast/collexpr.rb
+++ b/spec/unit/parser/ast/collexpr.rb
@@ -4,7 +4,7 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::CollExpr do
- AST = Puppet::Parser::AST
+ ast = Puppet::Parser::AST
before :each do
@scope = Puppet::Parser::Scope.new()
@@ -19,12 +19,12 @@ describe Puppet::Parser::AST::CollExpr do
end
it "should evaluate both" do
- collexpr = AST::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==")
+ collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==")
collexpr.evaluate(@scope)
end
it "should produce a textual representation and code of the expression" do
- collexpr = AST::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==")
+ collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==")
result = collexpr.evaluate(@scope)
result[0].should == "param_values.value = 'test2' and param_names.name = 'test1'"
result[1].should be_an_instance_of(Proc)
@@ -39,7 +39,7 @@ describe Puppet::Parser::AST::CollExpr do
t.expects(:form=)
end
- collexpr = AST::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==", :form => true, :type => true)
+ collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==", :form => true, :type => true)
result = collexpr.evaluate(@scope)
end
@@ -50,25 +50,25 @@ describe Puppet::Parser::AST::CollExpr do
end
it "should evaluate like the original expression for ==" do
- collexpr = AST::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper => "==")
+ collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper => "==")
collexpr.evaluate(@scope)[1].call(@resource).should === (@resource["test1"] == "test2")
end
it "should evaluate like the original expression for !=" do
- collexpr = AST::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper => "!=")
+ collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper => "!=")
collexpr.evaluate(@scope)[1].call(@resource).should === (@resource["test1"] != "test2")
end
end
it "should warn if this is an exported collection containing parenthesis (unsupported)" do
- collexpr = AST::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==", :parens => true, :form => :exported)
+ collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=>"==", :parens => true, :form => :exported)
Puppet.expects(:warning)
collexpr.evaluate(@scope)
end
%w{and or}.each do |op|
it "should raise an error if this is an exported collection with #{op} operator (unsupported)" do
- collexpr = AST::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=> op, :form => :exported)
+ collexpr = ast::CollExpr.new(:test1 => @test1, :test2 => @test2, :oper=> op, :form => :exported)
lambda { collexpr.evaluate(@scope) }.should raise_error(Puppet::ParseError)
end
end
@@ -81,12 +81,12 @@ describe Puppet::Parser::AST::CollExpr do
resource = mock 'resource'
resource.expects(:[]).with("array").at_least(1).returns(["test1","test2","test3"])
- collexpr = AST::CollExpr.new(:test1 => array, :test2 => test1, :oper => "==")
+ collexpr = ast::CollExpr.new(:test1 => array, :test2 => test1, :oper => "==")
collexpr.evaluate(@scope)[1].call(resource).should be_true
end
it "should raise an error for invalid operator" do
- lambda { collexpr = AST::CollExpr.new(:oper=>">") }.should raise_error
+ lambda { collexpr = ast::CollExpr.new(:oper=>">") }.should raise_error
end
-end \ No newline at end of file
+end
diff --git a/spec/unit/parser/ast/comparison_operator.rb b/spec/unit/parser/ast/comparison_operator.rb
index dbea349f2..80e8307fa 100755
--- a/spec/unit/parser/ast/comparison_operator.rb
+++ b/spec/unit/parser/ast/comparison_operator.rb
@@ -5,8 +5,8 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::ComparisonOperator do
before :each do
@scope = Puppet::Parser::Scope.new()
- @one = Puppet::Parser::AST::FlatString.new( :value => 1 )
- @two = Puppet::Parser::AST::FlatString.new( :value => 2 )
+ @one = stub 'one', :safeevaluate => "1"
+ @two = stub 'two', :safeevaluate => "2"
end
it "should evaluate both branches" do
@@ -19,34 +19,74 @@ describe Puppet::Parser::AST::ComparisonOperator do
operator.evaluate(@scope)
end
+ it "should convert arguments strings to numbers if they are" do
+ Puppet::Parser::Scope.expects(:number?).with("1").returns(1)
+ Puppet::Parser::Scope.expects(:number?).with("2").returns(2)
+
+ operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => "==", :rval => @two
+ operator.evaluate(@scope)
+ end
+
+ %w{< > <= >= ==}.each do |oper|
+ it "should use string comparison #{oper} if operands are strings" do
+ lval = stub 'one', :safeevaluate => "one"
+ rval = stub 'two', :safeevaluate => "two"
+ Puppet::Parser::Scope.stubs(:number?).with("one").returns(nil)
+ Puppet::Parser::Scope.stubs(:number?).with("two").returns(nil)
+
+ operator = Puppet::Parser::AST::ComparisonOperator.new :lval => lval, :operator => oper, :rval => rval
+ operator.evaluate(@scope).should == "one".send(oper,"two")
+ end
+ end
+
+ it "should fail with arguments of different types" do
+ lval = stub 'one', :safeevaluate => "one"
+ rval = stub 'two', :safeevaluate => "2"
+ Puppet::Parser::Scope.stubs(:number?).with("one").returns(nil)
+ Puppet::Parser::Scope.stubs(:number?).with("2").returns(2)
+
+ operator = Puppet::Parser::AST::ComparisonOperator.new :lval => lval, :operator => ">", :rval => rval
+ lambda { operator.evaluate(@scope) }.should raise_error(ArgumentError)
+ end
+
it "should fail for an unknown operator" do
lambda { operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => "or", :rval => @two }.should raise_error
end
%w{< > <= >= ==}.each do |oper|
it "should return the result of using '#{oper}' to compare the left and right sides" do
- one = stub 'one', :safeevaluate => "1"
- two = stub 'two', :safeevaluate => "2"
- operator = Puppet::Parser::AST::ComparisonOperator.new :lval => one, :operator => oper, :rval => two
+ operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => oper, :rval => @two
+
operator.evaluate(@scope).should == 1.send(oper,2)
end
end
it "should return the result of using '!=' to compare the left and right sides" do
- one = stub 'one', :safeevaluate => "1"
- two = stub 'two', :safeevaluate => "2"
- operator = Puppet::Parser::AST::ComparisonOperator.new :lval => one, :operator => '!=', :rval => two
+ operator = Puppet::Parser::AST::ComparisonOperator.new :lval => @one, :operator => '!=', :rval => @two
+
operator.evaluate(@scope).should == true
end
it "should work for variables too" do
- @scope.expects(:lookupvar).with("one").returns(1)
- @scope.expects(:lookupvar).with("two").returns(2)
one = Puppet::Parser::AST::Variable.new( :value => "one" )
two = Puppet::Parser::AST::Variable.new( :value => "two" )
+
+ @scope.expects(:lookupvar).with("one").returns(1)
+ @scope.expects(:lookupvar).with("two").returns(2)
operator = Puppet::Parser::AST::ComparisonOperator.new :lval => one, :operator => "<", :rval => two
operator.evaluate(@scope).should == true
end
+ # see ticket #1759
+ %w{< > <= >=}.each do |oper|
+ it "should return the correct result of using '#{oper}' to compare 10 and 9" do
+ ten = stub 'one', :safeevaluate => "10"
+ nine = stub 'two', :safeevaluate => "9"
+ operator = Puppet::Parser::AST::ComparisonOperator.new :lval => ten, :operator => oper, :rval => nine
+
+ operator.evaluate(@scope).should == 10.send(oper,9)
+ end
+ end
+
end
diff --git a/spec/unit/parser/ast/function.rb b/spec/unit/parser/ast/function.rb
new file mode 100644
index 000000000..15420132f
--- /dev/null
+++ b/spec/unit/parser/ast/function.rb
@@ -0,0 +1,77 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe Puppet::Parser::AST::Function do
+ before :each do
+ @scope = mock 'scope'
+ end
+
+ describe "when initializing" do
+ it "should not fail if the function doesn't exist" do
+ Puppet::Parser::Functions.stubs(:function).returns(false)
+
+ lambda{ Puppet::Parser::AST::Function.new :name => "dontexist" }.should_not raise_error(Puppet::ParseError)
+
+ end
+ end
+
+ describe "when evaluating" do
+
+ it "should fail if the function doesn't exist" do
+ Puppet::Parser::Functions.stubs(:function).returns(false)
+ func = Puppet::Parser::AST::Function.new :name => "dontexist"
+
+ lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should fail if the function is a statement used as rvalue" do
+ Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
+ Puppet::Parser::Functions.stubs(:rvalue?).with("exist").returns(false)
+
+ func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :rvalue
+
+ lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError, "Function 'exist' does not return a value")
+ end
+
+ it "should fail if the function is an rvalue used as statement" do
+ Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
+ Puppet::Parser::Functions.stubs(:rvalue?).with("exist").returns(true)
+
+ func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement
+
+ lambda{ func.evaluate(@scope) }.should raise_error(Puppet::ParseError,"Function 'exist' must be the value of a statement")
+ end
+
+ it "should evaluate its arguments" do
+ argument = stub 'arg'
+ Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
+ func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument
+ @scope.stubs(:function_exist)
+
+ argument.expects(:safeevaluate).with(@scope).returns("argument")
+
+ func.evaluate(@scope)
+ end
+
+ it "should call the underlying ruby function" do
+ argument = stub 'arg', :safeevaluate => "nothing"
+ Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
+ func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument
+
+ @scope.expects(:function_exist).with("nothing")
+
+ func.evaluate(@scope)
+ end
+
+ it "should return the ruby function return for rvalue functions" do
+ argument = stub 'arg', :safeevaluate => "nothing"
+ Puppet::Parser::Functions.stubs(:function).with("exist").returns(true)
+ func = Puppet::Parser::AST::Function.new :name => "exist", :ftype => :statement, :arguments => argument
+ @scope.stubs(:function_exist).with("nothing").returns("returning")
+
+ func.evaluate(@scope).should == "returning"
+ end
+
+ end
+end
diff --git a/spec/unit/parser/ast/resource_override.rb b/spec/unit/parser/ast/resource_override.rb
index 3fbeb323c..c1520bf78 100755
--- a/spec/unit/parser/ast/resource_override.rb
+++ b/spec/unit/parser/ast/resource_override.rb
@@ -4,12 +4,12 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::ResourceOverride do
- AST = Puppet::Parser::AST
+ ast = Puppet::Parser::AST
before :each do
@compiler = stub 'compiler'
@scope = Puppet::Parser::Scope.new(:compiler => @compiler)
- @params = AST::ASTArray.new({})
+ @params = ast::ASTArray.new({})
@compiler.stubs(:add_override)
end
@@ -17,7 +17,7 @@ describe Puppet::Parser::AST::ResourceOverride do
klass = stub 'klass', :title => "title", :type => "type"
object = mock 'object'
object.expects(:safeevaluate).with(@scope).returns(klass)
- AST::ResourceOverride.new(:object => object, :params => @params ).evaluate(@scope)
+ ast::ResourceOverride.new(:object => object, :params => @params ).evaluate(@scope)
end
it "should tell the compiler to override the resource with our own" do
@@ -25,13 +25,13 @@ describe Puppet::Parser::AST::ResourceOverride do
klass = stub 'klass', :title => "title", :type => "one"
object = mock 'object', :safeevaluate => klass
- AST::ResourceOverride.new(:object => object , :params => @params).evaluate(@scope)
+ ast::ResourceOverride.new(:object => object , :params => @params).evaluate(@scope)
end
it "should return the overriden resource directly when called with one item" do
klass = stub 'klass', :title => "title", :type => "one"
object = mock 'object', :safeevaluate => klass
- override = AST::ResourceOverride.new(:object => object , :params => @params).evaluate(@scope)
+ override = ast::ResourceOverride.new(:object => object , :params => @params).evaluate(@scope)
override.should be_an_instance_of(Puppet::Parser::Resource)
override.title.should == "title"
override.type.should == "One"
@@ -43,9 +43,9 @@ describe Puppet::Parser::AST::ResourceOverride do
object = mock 'object', :safeevaluate => [klass1,klass2]
- override = AST::ResourceOverride.new(:object => object , :params => @params).evaluate(@scope)
+ override = ast::ResourceOverride.new(:object => object , :params => @params).evaluate(@scope)
override.should have(2).elements
override.each {|o| o.should be_an_instance_of(Puppet::Parser::Resource) }
end
-end \ No newline at end of file
+end
diff --git a/spec/unit/parser/ast/resource_reference.rb b/spec/unit/parser/ast/resource_reference.rb
index e4b7c763b..ce2915a97 100755
--- a/spec/unit/parser/ast/resource_reference.rb
+++ b/spec/unit/parser/ast/resource_reference.rb
@@ -4,7 +4,7 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::ResourceReference do
- AST = Puppet::Parser::AST
+ ast = Puppet::Parser::AST
before :each do
@scope = Puppet::Parser::Scope.new()
@@ -12,7 +12,7 @@ describe Puppet::Parser::AST::ResourceReference do
def newref(title, type)
title = stub 'title', :safeevaluate => title
- ref = AST::ResourceReference.new(:type => type, :title => title)
+ ref = Puppet::Parser::AST::ResourceReference.new(:type => type, :title => title)
end
it "should evaluate correctly reference to builtin types" do
@@ -45,7 +45,7 @@ describe Puppet::Parser::AST::ResourceReference do
it "should return an array of reference if given an array of titles" do
titles = mock 'titles', :safeevaluate => ["title1","title2"]
- ref = AST::ResourceReference.new( :title => titles, :type => "Resource" )
+ ref = ast::ResourceReference.new( :title => titles, :type => "Resource" )
ref.stubs(:qualified_type).with(@scope).returns("Resource")
ref.evaluate(@scope).should have(2).elements
@@ -53,11 +53,11 @@ describe Puppet::Parser::AST::ResourceReference do
it "should qualify class of all titles for Class resource references" do
titles = mock 'titles', :safeevaluate => ["title1","title2"]
- ref = AST::ResourceReference.new( :title => titles, :type => "Class" )
+ ref = ast::ResourceReference.new( :title => titles, :type => "Class" )
ref.expects(:qualified_class).with(@scope,"title1").returns("class")
ref.expects(:qualified_class).with(@scope,"title2").returns("class")
ref.evaluate(@scope)
end
-end \ No newline at end of file
+end
diff --git a/spec/unit/parser/compiler.rb b/spec/unit/parser/compiler.rb
index c70fe8e13..bf50d8790 100755
--- a/spec/unit/parser/compiler.rb
+++ b/spec/unit/parser/compiler.rb
@@ -2,6 +2,34 @@
require File.dirname(__FILE__) + '/../../spec_helper'
+class CompilerTestResource
+ attr_accessor :builtin, :virtual, :evaluated, :type, :title
+
+ def initialize(type, title)
+ @type = type
+ @title = title
+ end
+
+ def ref
+ "%s[%s]" % [type.to_s.capitalize, title]
+ end
+
+ def evaluated?
+ @evaluated
+ end
+
+ def builtin?
+ @builtin
+ end
+
+ def virtual?
+ @virtual
+ end
+
+ def evaluate
+ end
+end
+
describe Puppet::Parser::Compiler do
before :each do
@node = Puppet::Node.new "testnode"
@@ -164,11 +192,12 @@ describe Puppet::Parser::Compiler do
end
it "should evaluate unevaluated resources" do
- resource = stub 'notevaluated', :ref => "File[testing]", :builtin? => false, :evaluated? => false, :virtual? => false
+ resource = CompilerTestResource.new(:file, "testing")
+
@compiler.add_resource(@scope, resource)
# We have to now mark the resource as evaluated
- resource.expects(:evaluate).with { |*whatever| resource.stubs(:evaluated?).returns true }
+ resource.expects(:evaluate).with { |*whatever| resource.evaluated = true }
@compiler.compile
end
@@ -182,14 +211,14 @@ describe Puppet::Parser::Compiler do
end
it "should evaluate unevaluated resources created by evaluating other resources" do
- resource = stub 'notevaluated', :ref => "File[testing]", :builtin? => false, :evaluated? => false, :virtual? => false
+ resource = CompilerTestResource.new(:file, "testing")
@compiler.add_resource(@scope, resource)
- resource2 = stub 'created', :ref => "File[other]", :builtin? => false, :evaluated? => false, :virtual? => false
+ resource2 = CompilerTestResource.new(:file, "other")
# We have to now mark the resource as evaluated
- resource.expects(:evaluate).with { |*whatever| resource.stubs(:evaluated?).returns(true); @compiler.add_resource(@scope, resource2) }
- resource2.expects(:evaluate).with { |*whatever| resource2.stubs(:evaluated?).returns(true) }
+ resource.expects(:evaluate).with { |*whatever| resource.evaluated = true; @compiler.add_resource(@scope, resource2) }
+ resource2.expects(:evaluate).with { |*whatever| resource2.evaluated = true }
@compiler.compile
diff --git a/spec/unit/parser/functions.rb b/spec/unit/parser/functions.rb
new file mode 100644
index 000000000..fe449139d
--- /dev/null
+++ b/spec/unit/parser/functions.rb
@@ -0,0 +1,83 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe Puppet::Parser::Functions do
+
+ before(:each) do
+ end
+
+ after(:each) do
+ # Rationale:
+ # our various tests will almost all register to Pupet::Parser::Functions
+ # a new function called "name". All tests are required to stub Puppet::Parser::Scope
+ # so that +no+ new real ruby method are defined.
+ # After each test, we want to leave the whole Puppet::Parser::Functions environment
+ # as it was before we were called, hence we call rmfunction (which might not succeed
+ # if the function hasn't been registered in the test). It is also important in this
+ # section to stub +remove_method+ here so that we don't pollute the scope.
+ Puppet::Parser::Scope.stubs(:remove_method)
+ begin
+ Puppet::Parser::Functions.rmfunction("name")
+ rescue
+ end
+ end
+
+ describe "when calling newfunction" do
+ it "should create the function in the scope class" do
+ Puppet::Parser::Scope.expects(:define_method).with { |name,block| name == "function_name" }
+
+ Puppet::Parser::Functions.newfunction("name", :type => :rvalue)
+ end
+
+ it "should raise an error if the function already exists" do
+ Puppet::Parser::Scope.expects(:define_method).with { |name,block| name == "function_name" }.once
+ Puppet::Parser::Functions.newfunction("name", :type => :rvalue)
+
+ lambda { Puppet::Parser::Functions.newfunction("name", :type => :rvalue) }.should raise_error
+ end
+
+ it "should raise an error if the function type is not correct" do
+ Puppet::Parser::Scope.expects(:define_method).with { |name,block| name == "function_name" }.never
+
+ lambda { Puppet::Parser::Functions.newfunction("name", :type => :unknown) }.should raise_error
+ end
+ end
+
+ describe "when calling rmfunction" do
+ it "should remove the function in the scope class" do
+ Puppet::Parser::Scope.expects(:define_method).with { |name,block| name == "function_name" }
+ Puppet::Parser::Functions.newfunction("name", :type => :rvalue)
+
+ Puppet::Parser::Scope.expects(:remove_method).with("function_name").once
+
+ Puppet::Parser::Functions.rmfunction("name")
+ end
+
+ it "should raise an error if the function doesn't exists" do
+ lambda { Puppet::Parser::Functions.rmfunction("name") }.should raise_error
+ end
+ end
+
+ describe "when calling function to test function existance" do
+
+ it "should return false if the function doesn't exist" do
+ Puppet::Parser::Functions.autoloader.stubs(:load)
+
+ Puppet::Parser::Functions.function("name").should be_false
+ end
+
+ it "should return it's name if the function exists" do
+ Puppet::Parser::Scope.expects(:define_method).with { |name,block| name == "function_name" }
+ Puppet::Parser::Functions.newfunction("name", :type => :rvalue)
+
+ Puppet::Parser::Functions.function("name").should == "function_name"
+ end
+
+ it "should try to autoload the function if it doesn't exist yet" do
+ Puppet::Parser::Functions.autoloader.expects(:load)
+
+ Puppet::Parser::Functions.function("name")
+ end
+ end
+end
diff --git a/spec/unit/parser/functions/inline_template.rb b/spec/unit/parser/functions/inline_template.rb
new file mode 100644
index 000000000..19e1a3b2a
--- /dev/null
+++ b/spec/unit/parser/functions/inline_template.rb
@@ -0,0 +1,59 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe "the inline_template function" do
+
+ before :each do
+ @scope = Puppet::Parser::Scope.new()
+ end
+
+ it "should exist" do
+ Puppet::Parser::Functions.function("inline_template").should == "function_inline_template"
+ end
+
+ it "should create a TemplateWrapper when called" do
+ tw = stub_everything 'template_wrapper'
+
+ Puppet::Parser::TemplateWrapper.expects(:new).returns(tw)
+
+ @scope.function_inline_template("test")
+ end
+
+ it "should pass the template string to TemplateWrapper.result" do
+ tw = stub_everything 'template_wrapper'
+ Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
+
+ tw.expects(:result).with("test")
+
+ @scope.function_inline_template("test")
+ end
+
+ it "should return what TemplateWrapper.result returns" do
+ tw = stub_everything 'template_wrapper'
+ Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
+
+ tw.expects(:result).returns("template contents evaluated")
+
+ @scope.function_inline_template("test").should == "template contents evaluated"
+ end
+
+ it "should concatenate template wrapper outputs for multiple templates" do
+ tw1 = stub_everything "template_wrapper1"
+ tw2 = stub_everything "template_wrapper2"
+ Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw1,tw2)
+ tw1.stubs(:result).returns("result1")
+ tw2.stubs(:result).returns("result2")
+
+ @scope.function_inline_template(["1","2"]).should == "result1result2"
+ end
+
+ it "should raise an error if the template raises an error" do
+ tw = stub_everything 'template_wrapper'
+ Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
+ tw.stubs(:result).raises
+
+ lambda { @scope.function_inline_template("1") }.should raise_error(Puppet::ParseError)
+ end
+
+end \ No newline at end of file
diff --git a/spec/unit/parser/functions/template.rb b/spec/unit/parser/functions/template.rb
new file mode 100644
index 000000000..8fc64d0c3
--- /dev/null
+++ b/spec/unit/parser/functions/template.rb
@@ -0,0 +1,62 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe "the template function" do
+
+ before :each do
+ @scope = Puppet::Parser::Scope.new()
+ end
+
+ it "should exist" do
+ Puppet::Parser::Functions.function("template").should == "function_template"
+ end
+
+ it "should create a TemplateWrapper when called" do
+ tw = stub_everything 'template_wrapper'
+
+ Puppet::Parser::TemplateWrapper.expects(:new).returns(tw)
+
+ @scope.function_template("test")
+ end
+
+ it "should give the template filename to the TemplateWrapper" do
+ tw = stub_everything 'template_wrapper'
+ Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
+
+ tw.expects(:file=).with("test")
+
+ @scope.function_template("test")
+ end
+
+ it "should return what TemplateWrapper.result returns" do
+ tw = stub_everything 'template_wrapper'
+ Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
+ tw.stubs(:file=).with("test")
+
+ tw.expects(:result).returns("template contents evaluated")
+
+ @scope.function_template("test").should == "template contents evaluated"
+ end
+
+ it "should concatenate template wrapper outputs for multiple templates" do
+ tw1 = stub_everything "template_wrapper1"
+ tw2 = stub_everything "template_wrapper2"
+ Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw1,tw2)
+ tw1.stubs(:file=).with("1")
+ tw2.stubs(:file=).with("2")
+ tw1.stubs(:result).returns("result1")
+ tw2.stubs(:result).returns("result2")
+
+ @scope.function_template(["1","2"]).should == "result1result2"
+ end
+
+ it "should raise an error if the template raises an error" do
+ tw = stub_everything 'template_wrapper'
+ Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
+ tw.stubs(:result).raises
+
+ lambda { @scope.function_template("1") }.should raise_error(Puppet::ParseError)
+ end
+
+end \ No newline at end of file
diff --git a/spec/unit/parser/lexer.rb b/spec/unit/parser/lexer.rb
index d62d99258..24c34632f 100755
--- a/spec/unit/parser/lexer.rb
+++ b/spec/unit/parser/lexer.rb
@@ -30,7 +30,7 @@ describe Puppet::Parser::Lexer::Token do
@token = Puppet::Parser::Lexer::Token.new(%r{something}, :NAME)
end
- [:regex, :name, :string, :skip, :incr_line, :skip_text].each do |param|
+ [:regex, :name, :string, :skip, :incr_line, :skip_text, :accumulate].each do |param|
it "should have a #{param.to_s} reader" do
@token.should be_respond_to(param)
end
@@ -208,6 +208,42 @@ describe Puppet::Parser::Lexer::TOKENS do
end
end
+describe Puppet::Parser::Lexer::TOKENS[:CLASSNAME] do
+ before { @token = Puppet::Parser::Lexer::TOKENS[:CLASSNAME] }
+
+ it "should match against lower-case alpha-numeric terms separated by double colons" do
+ @token.regex.should =~ "one::two"
+ end
+
+ it "should match against many lower-case alpha-numeric terms separated by double colons" do
+ @token.regex.should =~ "one::two::three::four::five"
+ end
+
+ it "should match against lower-case alpha-numeric terms prefixed by double colons" do
+ @token.regex.should =~ "::one"
+ end
+end
+
+describe Puppet::Parser::Lexer::TOKENS[:CLASSREF] do
+ before { @token = Puppet::Parser::Lexer::TOKENS[:CLASSREF] }
+
+ it "should match against single upper-case alpha-numeric terms" do
+ @token.regex.should =~ "One"
+ end
+
+ it "should match against upper-case alpha-numeric terms separated by double colons" do
+ @token.regex.should =~ "One::Two"
+ end
+
+ it "should match against many upper-case alpha-numeric terms separated by double colons" do
+ @token.regex.should =~ "One::Two::Three::Four::Five"
+ end
+
+ it "should match against upper-case alpha-numeric terms prefixed by double colons" do
+ @token.regex.should =~ "::One"
+ end
+end
+
describe Puppet::Parser::Lexer::TOKENS[:NAME] do
before { @token = Puppet::Parser::Lexer::TOKENS[:NAME] }
@@ -285,6 +321,14 @@ describe Puppet::Parser::Lexer::TOKENS[:COMMENT] do
it "should be marked to get skipped" do
@token.skip?.should be_true
end
+
+ it "should be marked to accumulate" do
+ @token.accumulate?.should be_true
+ end
+
+ it "'s block should return the comment without the #" do
+ @token.convert(@lexer,"# this is a comment")[1].should == "this is a comment"
+ end
end
describe Puppet::Parser::Lexer::TOKENS[:MLCOMMENT] do
@@ -313,6 +357,16 @@ describe Puppet::Parser::Lexer::TOKENS[:MLCOMMENT] do
match[1].should == " first "
end
+ it "should be marked to accumulate" do
+ @token.accumulate?.should be_true
+ end
+
+ it "'s block should return the comment without the comment marks" do
+ @lexer.stubs(:line=).with(0)
+
+ @token.convert(@lexer,"/* this is a comment */")[1].should == "this is a comment"
+ end
+
end
describe Puppet::Parser::Lexer::TOKENS[:RETURN] do
@@ -383,6 +437,43 @@ describe Puppet::Parser::Lexer::TOKENS[:VARIABLE] do
end
end
+describe Puppet::Parser::Lexer, "when lexing comments" do
+ before { @lexer = Puppet::Parser::Lexer.new }
+
+ it "should accumulate token in munge_token" do
+ token = stub 'token', :skip => true, :accumulate? => true, :incr_line => nil, :skip_text => false
+
+ token.stubs(:convert).with(@lexer, "# this is a comment").returns([token, " this is a comment"])
+ @lexer.munge_token(token, "# this is a comment")
+ @lexer.munge_token(token, "# this is a comment")
+
+ @lexer.getcomment.should == " this is a comment\n this is a comment\n"
+ end
+
+ it "should add a new comment stack level on LBRACE" do
+ @lexer.string = "{"
+
+ @lexer.expects(:commentpush)
+
+ @lexer.fullscan
+ end
+
+ it "should return the current comments on getcomment" do
+ @lexer.string = "# comment"
+ @lexer.fullscan
+
+ @lexer.getcomment.should == "comment\n"
+ end
+
+ it "should discard the previous comments on blank line" do
+ @lexer.string = "# 1\n\n# 2"
+ @lexer.fullscan
+
+ @lexer.getcomment.should == "2\n"
+ end
+
+end
+
# FIXME: We need to rewrite all of these tests, but I just don't want to take the time right now.
describe "Puppet::Parser::Lexer in the old tests" do
before { @lexer = Puppet::Parser::Lexer.new }
@@ -538,6 +629,7 @@ describe "Puppet::Parser::Lexer in the old tests" do
@lexer.fullscan[0].should == [:CLASSREF, foo]
end
end
+
end
require 'puppettest/support/utils'
diff --git a/spec/unit/parser/parser.rb b/spec/unit/parser/parser.rb
index 077f93d98..b764dee97 100755
--- a/spec/unit/parser/parser.rb
+++ b/spec/unit/parser/parser.rb
@@ -4,11 +4,11 @@ require File.dirname(__FILE__) + '/../../spec_helper'
describe Puppet::Parser do
- AST = Puppet::Parser::AST
+ ast = Puppet::Parser::AST
before :each do
@parser = Puppet::Parser::Parser.new :environment => "development"
- @true_ast = AST::Boolean.new :value => true
+ @true_ast = Puppet::Parser::AST::Boolean.new :value => true
end
describe "when parsing append operator" do
@@ -21,13 +21,13 @@ describe Puppet::Parser do
lambda { @parser.parse("$var += ") }.should raise_error
end
- it "should call AST::VarDef with append=true" do
- AST::VarDef.expects(:new).with { |h| h[:append] == true }
+ it "should call ast::VarDef with append=true" do
+ ast::VarDef.expects(:new).with { |h| h[:append] == true }
@parser.parse("$var += 2")
end
it "should work with arrays too" do
- AST::VarDef.expects(:new).with { |h| h[:append] == true }
+ ast::VarDef.expects(:new).with { |h| h[:append] == true }
@parser.parse("$var += ['test']")
end
@@ -35,22 +35,21 @@ describe Puppet::Parser do
describe Puppet::Parser, "when parsing 'if'" do
it "not, it should create the correct ast objects" do
- AST::Not.expects(:new).with { |h| h[:value].is_a?(AST::Boolean) }
+ ast::Not.expects(:new).with { |h| h[:value].is_a?(ast::Boolean) }
@parser.parse("if ! true { $var = 1 }")
-
end
it "boolean operation, it should create the correct ast objects" do
- AST::BooleanOperator.expects(:new).with {
- |h| h[:rval].is_a?(AST::Boolean) and h[:lval].is_a?(AST::Boolean) and h[:operator]=="or"
+ ast::BooleanOperator.expects(:new).with {
+ |h| h[:rval].is_a?(ast::Boolean) and h[:lval].is_a?(ast::Boolean) and h[:operator]=="or"
}
@parser.parse("if true or true { $var = 1 }")
end
it "comparison operation, it should create the correct ast objects" do
- AST::ComparisonOperator.expects(:new).with {
- |h| h[:lval].is_a?(AST::Name) and h[:rval].is_a?(AST::Name) and h[:operator]=="<"
+ ast::ComparisonOperator.expects(:new).with {
+ |h| h[:lval].is_a?(ast::Name) and h[:rval].is_a?(ast::Name) and h[:operator]=="<"
}
@parser.parse("if 1 < 2 { $var = 1 }")
@@ -60,14 +59,15 @@ describe Puppet::Parser do
describe Puppet::Parser, "when parsing if complex expressions" do
it "should create a correct ast tree" do
- AST::ComparisonOperator.expects(:new).with {
- |h| h[:rval].is_a?(AST::Name) and h[:lval].is_a?(AST::Name) and h[:operator]==">"
- }.returns("whatever")
- AST::ComparisonOperator.expects(:new).with {
- |h| h[:rval].is_a?(AST::Name) and h[:lval].is_a?(AST::Name) and h[:operator]=="=="
- }.returns("whatever")
- AST::BooleanOperator.expects(:new).with {
- |h| h[:rval]=="whatever" and h[:lval]=="whatever" and h[:operator]=="and"
+ aststub = stub_everything 'ast'
+ ast::ComparisonOperator.expects(:new).with {
+ |h| h[:rval].is_a?(ast::Name) and h[:lval].is_a?(ast::Name) and h[:operator]==">"
+ }.returns(aststub)
+ ast::ComparisonOperator.expects(:new).with {
+ |h| h[:rval].is_a?(ast::Name) and h[:lval].is_a?(ast::Name) and h[:operator]=="=="
+ }.returns(aststub)
+ ast::BooleanOperator.expects(:new).with {
+ |h| h[:rval]==aststub and h[:lval]==aststub and h[:operator]=="and"
}
@parser.parse("if (1 > 2) and (1 == 2) { $var = 1 }")
end
@@ -88,10 +88,10 @@ describe Puppet::Parser do
lambda { @parser.parse('exec { test: param => File["a","b"] }') }.should_not raise_error
end
- it "should create an AST::ResourceReference" do
- AST::Resource.stubs(:new)
- AST::ResourceReference.expects(:new).with { |arg|
- arg[:line]==1 and arg[:type]=="File" and arg[:title].is_a?(AST::ASTArray)
+ it "should create an ast::ResourceReference" do
+ ast::Resource.stubs(:new)
+ ast::ResourceReference.expects(:new).with { |arg|
+ arg[:line]==1 and arg[:type]=="File" and arg[:title].is_a?(ast::ASTArray)
}
@parser.parse('exec { test: command => File["a","b"] }')
end
@@ -107,9 +107,9 @@ describe Puppet::Parser do
lambda { @parser.parse('Resource["title1","title2"] { param => value }') }.should_not raise_error
end
- it "should create an AST::ResourceOverride" do
- AST::ResourceOverride.expects(:new).with { |arg|
- arg[:line]==1 and arg[:object].is_a?(AST::ResourceReference) and arg[:params].is_a?(AST::ResourceParam)
+ it "should create an ast::ResourceOverride" do
+ ast::ResourceOverride.expects(:new).with { |arg|
+ arg[:line]==1 and arg[:object].is_a?(ast::ResourceReference) and arg[:params].is_a?(ast::ResourceParam)
}
@parser.parse('Resource["title1","title2"] { param => value }')
end
@@ -131,12 +131,12 @@ describe Puppet::Parser do
end
it "should create a nop node for empty branch" do
- AST::Nop.expects(:new)
+ ast::Nop.expects(:new)
@parser.parse("if true { }")
end
it "should create a nop node for empty else branch" do
- AST::Nop.expects(:new)
+ ast::Nop.expects(:new)
@parser.parse("if true { notice('test') } else { }")
end
@@ -177,12 +177,12 @@ describe Puppet::Parser do
before :each do
@one = stub 'one', :is_a? => true
- @one.stubs(:is_a?).with(AST::ASTArray).returns(false)
- @one.stubs(:is_a?).with(AST).returns(true)
+ @one.stubs(:is_a?).with(ast::ASTArray).returns(false)
+ @one.stubs(:is_a?).with(ast).returns(true)
@two = stub 'two'
- @two.stubs(:is_a?).with(AST::ASTArray).returns(false)
- @two.stubs(:is_a?).with(AST).returns(true)
+ @two.stubs(:is_a?).with(ast::ASTArray).returns(false)
+ @two.stubs(:is_a?).with(ast).returns(true)
end
it "should return the first class" do
@@ -199,7 +199,30 @@ describe Puppet::Parser do
klass1.code.children.should == [@one,@two]
end
+ end
+ describe Puppet::Parser, "when parsing comments before statement" do
+ it "should associate the documentation to the statement AST node" do
+ ast = @parser.parse("""
+ # comment
+ class test {}
+ """)
+
+ ast[:classes]["test"].doc.should == "comment\n"
+ end
end
+ describe Puppet::Parser, "when building ast nodes" do
+ it "should get lexer comments if ast node declares use_docs" do
+ lexer = stub 'lexer'
+ ast = mock 'ast', :nil? => false, :use_docs => true, :doc => ""
+ @parser.stubs(:lexer).returns(lexer)
+
+ Puppet::Parser::AST::Definition.expects(:new).returns(ast)
+ lexer.expects(:getcomment).returns("comment")
+ ast.expects(:doc=).with("comment")
+
+ @parser.ast(Puppet::Parser::AST::Definition)
+ end
+ end
end
diff --git a/spec/unit/parser/resource/reference.rb b/spec/unit/parser/resource/reference.rb
index 147f772d1..bb1452692 100755
--- a/spec/unit/parser/resource/reference.rb
+++ b/spec/unit/parser/resource/reference.rb
@@ -72,4 +72,24 @@ describe Puppet::Parser::Resource::Reference, " when modeling defined types" do
ref.builtin?.should be_false
ref.definedtype.object_id.should == @nodedef.object_id
end
+
+ it "should only look for fully qualified classes" do
+ top = @parser.newclass "top"
+ sub = @parser.newclass "other::top"
+
+ scope = @compiler.topscope.class.new(:parent => @compiler.topscope, :namespace => "other", :parser => @parser)
+
+ ref = @type.new(:type => "class", :title => "top", :scope => scope)
+ ref.definedtype.classname.should equal(top.classname)
+ end
+
+ it "should only look for fully qualified definitions" do
+ top = @parser.newdefine "top"
+ sub = @parser.newdefine "other::top"
+
+ scope = @compiler.topscope.class.new(:parent => @compiler.topscope, :namespace => "other", :parser => @parser)
+
+ ref = @type.new(:type => "top", :title => "foo", :scope => scope)
+ ref.definedtype.classname.should equal(top.classname)
+ end
end
diff --git a/spec/unit/parser/templatewrapper.rb b/spec/unit/parser/templatewrapper.rb
index 532776223..fd9efa8af 100755
--- a/spec/unit/parser/templatewrapper.rb
+++ b/spec/unit/parser/templatewrapper.rb
@@ -10,99 +10,118 @@ describe Puppet::Parser::TemplateWrapper do
@file = "fake_template"
Puppet::Module.stubs(:find_template).returns("/tmp/fake_template")
FileTest.stubs(:exists?).returns("true")
- @tw = Puppet::Parser::TemplateWrapper.new(@scope, @file)
+ File.stubs(:read).with("/tmp/fake_template").returns("template content")
+ @tw = Puppet::Parser::TemplateWrapper.new(@scope)
end
- it "should create a new object TemplateWrapper from a scope and a file" do
+ it "should create a new object TemplateWrapper from a scope" do
+ tw = Puppet::Parser::TemplateWrapper.new(@scope)
+
+ tw.should be_a_kind_of(Puppet::Parser::TemplateWrapper)
+ end
+
+ it "should check template file existance and read its content" do
Puppet::Module.expects(:find_template).with("fake_template", "foo").returns("/tmp/fake_template")
FileTest.expects(:exists?).with("/tmp/fake_template").returns(true)
- tw = Puppet::Parser::TemplateWrapper.new(@scope, @file)
- tw.should be_a_kind_of(Puppet::Parser::TemplateWrapper)
+ File.expects(:read).with("/tmp/fake_template").returns("template content")
+
+ @tw.file = @file
end
- it "should turn into a string like template[name]" do
+ it "should turn into a string like template[name] for file based template" do
+ @tw.file = @file
@tw.to_s.should eql("template[/tmp/fake_template]")
end
+ it "should turn into a string like template[inline] for string-based template" do
+ @tw.to_s.should eql("template[inline]")
+ end
+
it "should return the processed template contents with a call to result" do
template_mock = mock("template", :result => "woot!")
File.expects(:read).with("/tmp/fake_template").returns("template contents")
ERB.expects(:new).with("template contents", 0, "-").returns(template_mock)
+
+ @tw.file = @file
@tw.result.should eql("woot!")
end
+ it "should return the processed template contents with a call to result and a string" do
+ template_mock = mock("template", :result => "woot!")
+ ERB.expects(:new).with("template contents", 0, "-").returns(template_mock)
+
+ @tw.result("template contents").should eql("woot!")
+ end
+
it "should return the contents of a variable if called via method_missing" do
@scope.expects(:lookupvar).with("chicken", false).returns("is good")
- tw = Puppet::Parser::TemplateWrapper.new(@scope, @file)
+ tw = Puppet::Parser::TemplateWrapper.new(@scope)
tw.chicken.should eql("is good")
end
it "should throw an exception if a variable is called via method_missing and it does not exist" do
@scope.expects(:lookupvar).with("chicken", false).returns(:undefined)
- tw = Puppet::Parser::TemplateWrapper.new(@scope, @file)
- lambda { tw.chicken }.should raise_error(Puppet::ParseError)
+ tw = Puppet::Parser::TemplateWrapper.new(@scope)
+ lambda { tw.chicken }.should raise_error(Puppet::ParseError)
end
it "should allow you to check whether a variable is defined with has_variable?" do
@scope.expects(:lookupvar).with("chicken", false).returns("is good")
- tw = Puppet::Parser::TemplateWrapper.new(@scope, @file)
+ tw = Puppet::Parser::TemplateWrapper.new(@scope)
tw.has_variable?("chicken").should eql(true)
end
it "should allow you to check whether a variable is not defined with has_variable?" do
@scope.expects(:lookupvar).with("chicken", false).returns(:undefined)
- tw = Puppet::Parser::TemplateWrapper.new(@scope, @file)
+ tw = Puppet::Parser::TemplateWrapper.new(@scope)
tw.has_variable?("chicken").should eql(false)
end
it "should allow you to retrieve the defined classes with classes" do
catalog = mock 'catalog', :classes => ["class1", "class2"]
@scope.expects(:catalog).returns( catalog )
- tw = Puppet::Parser::TemplateWrapper.new(@scope, @file)
+ tw = Puppet::Parser::TemplateWrapper.new(@scope)
tw.classes().should == ["class1", "class2"]
end
it "should allow you to retrieve all the tags with all_tags" do
catalog = mock 'catalog', :tags => ["tag1", "tag2"]
@scope.expects(:catalog).returns( catalog )
- tw = Puppet::Parser::TemplateWrapper.new(@scope, @file)
+ tw = Puppet::Parser::TemplateWrapper.new(@scope)
tw.all_tags().should == ["tag1","tag2"]
end
it "should allow you to retrieve the tags defined in the current scope" do
@scope.expects(:tags).returns( ["tag1", "tag2"] )
- tw = Puppet::Parser::TemplateWrapper.new(@scope, @file)
+ tw = Puppet::Parser::TemplateWrapper.new(@scope)
tw.tags().should == ["tag1","tag2"]
end
it "should set all of the scope's variables as instance variables" do
template_mock = mock("template", :result => "woot!")
- File.expects(:read).with("/tmp/fake_template").returns("template contents")
ERB.expects(:new).with("template contents", 0, "-").returns(template_mock)
@scope.expects(:to_hash).returns("one" => "foo")
- @tw.result
+ @tw.result("template contents")
@tw.instance_variable_get("@one").should == "foo"
end
it "should not error out if one of the variables is a symbol" do
template_mock = mock("template", :result => "woot!")
- File.expects(:read).with("/tmp/fake_template").returns("template contents")
ERB.expects(:new).with("template contents", 0, "-").returns(template_mock)
@scope.expects(:to_hash).returns(:_timestamp => "1234")
- @tw.result
+ @tw.result("template contents")
end
%w{! . ; :}.each do |badchar|
it "should translate #{badchar} to _ when setting the instance variables" do
template_mock = mock("template", :result => "woot!")
- File.expects(:read).with("/tmp/fake_template").returns("template contents")
ERB.expects(:new).with("template contents", 0, "-").returns(template_mock)
@scope.expects(:to_hash).returns("one#{badchar}" => "foo")
- @tw.result
+ @tw.result("template contents")
@tw.instance_variable_get("@one_").should == "foo"
end
diff --git a/spec/unit/property/list.rb b/spec/unit/property/list.rb
index 9c832c0cd..2fab868db 100644
--- a/spec/unit/property/list.rb
+++ b/spec/unit/property/list.rb
@@ -143,5 +143,14 @@ describe list_class do
@property.insync?(["bar","foo"]).must == false
end
end
+
+ describe "when calling dearrayify" do
+ it "should sort and join the array with 'delimiter'" do
+ array = mock "array"
+ array.expects(:sort).returns(array)
+ array.expects(:join).with(@property.delimiter)
+ @property.dearrayify(array)
+ end
+ end
end
end
diff --git a/spec/unit/property/ordered_list.rb b/spec/unit/property/ordered_list.rb
new file mode 100644
index 000000000..51c59a7dd
--- /dev/null
+++ b/spec/unit/property/ordered_list.rb
@@ -0,0 +1,64 @@
+#!/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/property/ordered_list'
+
+ordered_list_class = Puppet::Property::OrderedList
+
+describe ordered_list_class do
+
+ it "should be a subclass of List" do
+ ordered_list_class.superclass.must == Puppet::Property::List
+ end
+
+ describe "as an instance" do
+ before do
+ # Wow that's a messy interface to the resource.
+ ordered_list_class.initvars
+ @resource = stub 'resource', :[]= => nil, :property => nil
+ @property = ordered_list_class.new(:resource => @resource)
+ end
+
+ describe "when adding should to current" do
+ it "should add the arrays when current is an array" do
+ @property.add_should_with_current(["should"], ["current"]).should == ["should", "current"]
+ end
+
+ it "should return 'should' if current is not a array" do
+ @property.add_should_with_current(["should"], :absent).should == ["should"]
+ end
+
+ it "should return only the uniq elements leading with the order of 'should'" do
+ @property.add_should_with_current(["this", "is", "should"], ["is", "this", "current"]).should == ["this", "is", "should", "current"]
+ end
+ end
+
+ describe "when calling should" do
+ it "should return nil if @should is nil" do
+ @property.should.must == nil
+ end
+
+ it "should return the values of @should (without sorting) as a string if inclusive" do
+ @property.should = ["foo", "bar"]
+ @property.expects(:inclusive?).returns(true)
+ @property.should.must == "foo,bar"
+ end
+
+ it "should return the uniq values of @should + retrieve as a string if !inclusive with the @ values leading" do
+ @property.should = ["foo", "bar"]
+ @property.expects(:inclusive?).returns(false)
+ @property.expects(:retrieve).returns(["foo","baz"])
+ @property.should.must == "foo,bar,baz"
+ end
+ end
+
+ describe "when calling dearrayify" do
+ it "should join the array with the delimiter" do
+ array = mock "array"
+ array.expects(:join).with(@property.delimiter)
+ @property.dearrayify(array)
+ end
+ end
+ end
+end
diff --git a/spec/unit/provider/confine.rb b/spec/unit/provider/confine.rb
index 867b6e6be..626f79b27 100755
--- a/spec/unit/provider/confine.rb
+++ b/spec/unit/provider/confine.rb
@@ -34,7 +34,10 @@ describe Puppet::Provider::Confine do
end
describe "when testing all values" do
- before { @confine = Puppet::Provider::Confine.new(%w{a b c}) }
+ before do
+ @confine = Puppet::Provider::Confine.new(%w{a b c})
+ @confine.label = "foo"
+ end
it "should be invalid if any values fail" do
@confine.stubs(:pass?).returns true
@@ -51,6 +54,14 @@ describe Puppet::Provider::Confine do
@confine.expects(:pass?).once.returns false
@confine.valid?
end
+
+ it "should log failing confines with the label and message" do
+ @confine.stubs(:pass?).returns false
+ @confine.expects(:message).returns "My message"
+ @confine.expects(:label).returns "Mylabel"
+ Puppet.expects(:debug).with("Mylabel: My message")
+ @confine.valid?
+ end
end
describe "when testing the result of the values" do
diff --git a/spec/unit/provider/confine/exists.rb b/spec/unit/provider/confine/exists.rb
index 1ab1d39f7..a3539c4f5 100755
--- a/spec/unit/provider/confine/exists.rb
+++ b/spec/unit/provider/confine/exists.rb
@@ -7,6 +7,7 @@ require 'puppet/provider/confine/exists'
describe Puppet::Provider::Confine::Exists do
before do
@confine = Puppet::Provider::Confine::Exists.new("/my/file")
+ @confine.label = "eh"
end
it "should be named :exists" do
diff --git a/spec/unit/provider/confine/false.rb b/spec/unit/provider/confine/false.rb
index c6c43e391..6ff5cc133 100755
--- a/spec/unit/provider/confine/false.rb
+++ b/spec/unit/provider/confine/false.rb
@@ -18,6 +18,7 @@ describe Puppet::Provider::Confine::False do
it "should use the 'pass?' method to test validity" do
@confine = Puppet::Provider::Confine::False.new("foo")
+ @confine.label = "eh"
@confine.expects(:pass?).with("foo")
@confine.valid?
end
diff --git a/spec/unit/provider/confine/feature.rb b/spec/unit/provider/confine/feature.rb
index 1845c9a47..67e59363e 100755
--- a/spec/unit/provider/confine/feature.rb
+++ b/spec/unit/provider/confine/feature.rb
@@ -22,6 +22,7 @@ describe Puppet::Provider::Confine::Feature do
@features = mock 'features'
Puppet.stubs(:features).returns @features
@confine = Puppet::Provider::Confine::Feature.new("myfeature")
+ @confine.label = "eh"
end
it "should use the Puppet features instance to test validity" do
diff --git a/spec/unit/provider/confine/true.rb b/spec/unit/provider/confine/true.rb
index c9cc83c9e..75b36cea5 100755
--- a/spec/unit/provider/confine/true.rb
+++ b/spec/unit/provider/confine/true.rb
@@ -14,7 +14,10 @@ describe Puppet::Provider::Confine::True do
end
describe "when testing values" do
- before { @confine = Puppet::Provider::Confine::True.new("foo") }
+ before do
+ @confine = Puppet::Provider::Confine::True.new("foo")
+ @confine.label = "eh"
+ end
it "should use the 'pass?' method to test validity" do
@confine.expects(:pass?).with("foo")
diff --git a/spec/unit/provider/confine/variable.rb b/spec/unit/provider/confine/variable.rb
index 38b3dad1c..7a71fc1ae 100755
--- a/spec/unit/provider/confine/variable.rb
+++ b/spec/unit/provider/confine/variable.rb
@@ -27,60 +27,55 @@ describe Puppet::Provider::Confine::Variable do
@confine.name = :myvar
end
- it "should use the 'pass?' method to test validity" do
- @confine.expects(:pass?).with("foo")
- @confine.valid?
- end
-
it "should use settings if the variable name is a valid setting" do
Puppet.settings.expects(:valid?).with(:myvar).returns true
Puppet.settings.expects(:value).with(:myvar).returns "foo"
- @confine.pass?("foo")
+ @confine.valid?
end
it "should use Facter if the variable name is not a valid setting" do
Puppet.settings.expects(:valid?).with(:myvar).returns false
Facter.expects(:value).with(:myvar).returns "foo"
- @confine.pass?("foo")
+ @confine.valid?
end
- it "should return true if the value matches the facter value" do
+ it "should be valid if the value matches the facter value" do
@confine.expects(:test_value).returns "foo"
- @confine.pass?("foo").should be_true
+ @confine.should be_valid
end
it "should return false if the value does not match the facter value" do
@confine.expects(:test_value).returns "fee"
- @confine.pass?("foo").should be_false
+ @confine.should_not be_valid
end
it "should be case insensitive" do
@confine.expects(:test_value).returns "FOO"
- @confine.pass?("foo").should be_true
+ @confine.should be_valid
end
it "should not care whether the value is a string or symbol" do
@confine.expects(:test_value).returns "FOO"
- @confine.pass?(:foo).should be_true
- end
-
- it "should cache the facter value during testing" do
- Facter.expects(:value).once.returns("FOO")
-
- @confine.pass?(:foo)
- @confine.pass?(:foo)
+ @confine.should be_valid
end
it "should produce a message that the fact value is not correct" do
@confine = Puppet::Provider::Confine::Variable.new(%w{bar bee})
+ @confine.name = "eh"
message = @confine.message("value")
message.should be_include("facter")
message.should be_include("bar,bee")
end
+
+ it "should be valid if the test value matches any of the provided values" do
+ @confine = Puppet::Provider::Confine::Variable.new(%w{bar bee})
+ @confine.expects(:test_value).returns "bee"
+ @confine.should be_valid
+ end
end
describe "when summarizing multiple instances" do
diff --git a/spec/unit/provider/confine_collection.rb b/spec/unit/provider/confine_collection.rb
index 1598b5f99..444281c77 100755
--- a/spec/unit/provider/confine_collection.rb
+++ b/spec/unit/provider/confine_collection.rb
@@ -6,69 +6,81 @@ require 'puppet/provider/confine_collection'
describe Puppet::Provider::ConfineCollection do
it "should be able to add confines" do
- Puppet::Provider::ConfineCollection.new.should respond_to(:confine)
+ Puppet::Provider::ConfineCollection.new("label").should respond_to(:confine)
+ end
+
+ it "should require a label at initialization" do
+ lambda { Puppet::Provider::ConfineCollection.new }.should raise_error(ArgumentError)
+ end
+
+ it "should make its label available" do
+ Puppet::Provider::ConfineCollection.new("mylabel").label.should == "mylabel"
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})
+ test_class.expects(:new).with(%w{my values}).returns(stub('confine', :label= => nil))
Puppet::Provider::Confine.expects(:test).with(:foo).returns test_class
- Puppet::Provider::ConfineCollection.new.confine :foo => %w{my values}
+ Puppet::Provider::ConfineCollection.new("label").confine :foo => %w{my values}
end
- describe "and the test cannot be found" do
- before do
- @variable = mock 'variable_test'
+ it "should copy its label to the confine instance" do
+ confine = mock 'confine'
+ test_class = mock 'test_class'
+ test_class.expects(:new).returns confine
+ Puppet::Provider::Confine.expects(:test).returns test_class
- Puppet::Provider::Confine.expects(:test).with(:foo).returns nil
- Puppet::Provider::Confine.expects(:test).with(:variable).returns @variable
- end
+ confine.expects(:label=).with("label")
+ Puppet::Provider::ConfineCollection.new("label").confine :foo => %w{my values}
+ end
+
+ describe "and the test cannot be found" do
it "should create a Facter test with the provided values and set the name to the test name" do
- confine = mock 'confine'
+ confine = Puppet::Provider::Confine.test(:variable).new(%w{my values})
confine.expects(:name=).with(:foo)
- @variable.expects(:new).with(%w{my values}).returns confine
- Puppet::Provider::ConfineCollection.new.confine :foo => %w{my values}
+ confine.class.expects(:new).with(%w{my values}).returns confine
+ Puppet::Provider::ConfineCollection.new("label").confine(:foo => %w{my values})
end
end
describe "and the 'for_binary' option was provided" do
it "should mark the test as a binary confine" do
- confine = mock 'confine'
+ confine = Puppet::Provider::Confine.test(:exists).new(:bar)
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
+ Puppet::Provider::ConfineCollection.new("label").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
+ Puppet::Provider::ConfineCollection.new("label").should be_valid
end
it "should be valid if all confines pass" do
- c1 = mock 'c1', :valid? => true
- c2 = mock 'c2', :valid? => true
+ c1 = stub 'c1', :valid? => true, :label= => nil
+ c2 = stub 'c2', :valid? => true, :label= => nil
Puppet::Provider::Confine.test(:true).expects(:new).returns(c1)
Puppet::Provider::Confine.test(:false).expects(:new).returns(c2)
- confiner = Puppet::Provider::ConfineCollection.new
+ confiner = Puppet::Provider::ConfineCollection.new("label")
confiner.confine :true => :bar, :false => :bee
confiner.should be_valid
end
it "should not be valid if any confines fail" do
- c1 = stub 'c1', :valid? => true
- c2 = stub 'c2', :valid? => false
+ c1 = stub 'c1', :valid? => true, :label= => nil
+ c2 = stub 'c2', :valid? => false, :label= => nil
Puppet::Provider::Confine.test(:true).expects(:new).returns(c1)
Puppet::Provider::Confine.test(:false).expects(:new).returns(c2)
- confiner = Puppet::Provider::ConfineCollection.new
+ confiner = Puppet::Provider::ConfineCollection.new("label")
confiner.confine :true => :bar, :false => :bee
confiner.should_not be_valid
@@ -76,7 +88,7 @@ describe Puppet::Provider::ConfineCollection do
describe "when providing a summary" do
before do
- @confiner = Puppet::Provider::ConfineCollection.new
+ @confiner = Puppet::Provider::ConfineCollection.new("label")
end
it "should return a hash" do
diff --git a/spec/unit/provider/confiner.rb b/spec/unit/provider/confiner.rb
index 078fc4420..0a0d67fb5 100755
--- a/spec/unit/provider/confiner.rb
+++ b/spec/unit/provider/confiner.rb
@@ -30,7 +30,8 @@ describe Puppet::Provider::Confiner do
end
it "should create a new confine collection if one does not exist" do
- Puppet::Provider::ConfineCollection.expects(:new).returns "mycoll"
+ Puppet::Provider::ConfineCollection.expects(:new).with("mylabel").returns "mycoll"
+ @object.expects(:to_s).returns "mylabel"
@object.confine_collection.should == "mycoll"
end
diff --git a/spec/unit/provider/mcx/mcxcontent.rb b/spec/unit/provider/mcx/mcxcontent.rb
new file mode 100755
index 000000000..eedff7dad
--- /dev/null
+++ b/spec/unit/provider/mcx/mcxcontent.rb
@@ -0,0 +1,175 @@
+#! /usr/bin/env ruby
+#--
+# Copyright (C) 2008 Jeffrey J McCune.
+
+# This program and entire repository is free software; you can
+# redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Author: Jeff McCune <mccune.jeff@gmail.com>
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+provider_class = Puppet::Type.type(:mcx).provider(:mcxcontent)
+
+# describe creates a new ExampleGroup object.
+describe provider_class do
+
+ # :each executes before each test.
+ # :all executes once for the test group and before :each.
+ before :each do
+ # Create a mock resource
+ @resource = stub 'resource'
+
+ @provider = provider_class.new
+ @attached_to = "/Users/foobar"
+ @ds_path = "/Local/Default/Users/foobar"
+
+ # A catch all; no parameters set
+ @resource.stubs(:[]).returns(nil)
+
+ # But set name, ensure and enable
+ @resource.stubs(:[]).with(:name).returns @attached_to
+ @resource.stubs(:[]).with(:ensure).returns :present
+ @resource.stubs(:ref).returns "Mcx[#{@attached_to}]"
+
+ # stub out the provider methods that actually touch the filesystem
+ # or execute commands
+ @provider.class.stubs(:execute).returns('')
+ @provider.stubs(:execute).returns('')
+ @provider.stubs(:resource).returns @resource
+ end
+
+ it "should have a create method." do
+ @provider.should respond_to(:create)
+ end
+
+ it "should have a destroy method." do
+ @provider.should respond_to(:destroy)
+ end
+
+ it "should have an exists? method." do
+ @provider.should respond_to(:exists?)
+ end
+
+ it "should have an content method." do
+ @provider.should respond_to(:content)
+ end
+
+ it "should have an content= method." do
+ @provider.should respond_to(:content=)
+ end
+
+ describe "when managing the resource" do
+ it "should execute external command dscl from :create" do
+ @provider.class.expects(:dscl).returns('').once
+ @provider.create
+ end
+ it "should execute external command dscl from :destroy" do
+ @provider.class.expects(:dscl).with('localhost', '-mcxdelete', @ds_path).returns('').once
+ @provider.destroy
+ end
+ it "should execute external command dscl from :exists?" do
+ @provider.class.expects(:dscl).with('localhost', '-mcxexport', @ds_path).returns('').once
+ @provider.exists?
+ end
+ it "should execute external command dscl from :content" do
+ @provider.class.expects(:dscl).with('localhost', '-mcxexport', @ds_path).returns('')
+ @provider.content
+ end
+ it "should execute external command dscl from :content=" do
+ @provider.class.expects(:dscl).returns('')
+ @provider.content=''
+ end
+ end
+
+ describe "when creating and parsing the name for ds_type" do
+ before :each do
+ @resource.stubs(:[]).with(:name).returns "/Foo/bar"
+ end
+ it "should not accept /Foo/bar" do
+ lambda { @provider.create }.should raise_error(MCXContentProviderException)
+ end
+ it "should accept /Foo/bar with ds_type => user" do
+ @resource.stubs(:[]).with(:ds_type).returns "user"
+ lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
+ end
+ it "should accept /Foo/bar with ds_type => group" do
+ @resource.stubs(:[]).with(:ds_type).returns "group"
+ lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
+ end
+ it "should accept /Foo/bar with ds_type => computer" do
+ @resource.stubs(:[]).with(:ds_type).returns "computer"
+ lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
+ end
+ it "should accept :name => /Foo/bar with ds_type => computerlist" do
+ @resource.stubs(:[]).with(:ds_type).returns "computerlist"
+ lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
+ end
+ end
+
+ describe "when creating and :name => foobar" do
+ before :each do
+ @resource.stubs(:[]).with(:name).returns "foobar"
+ end
+ it "should not accept unspecified :ds_type and :ds_name" do
+ lambda { @provider.create }.should raise_error(MCXContentProviderException)
+ end
+ it "should not accept unspecified :ds_type" do
+ @resource.stubs(:[]).with(:ds_type).returns "user"
+ lambda { @provider.create }.should raise_error(MCXContentProviderException)
+ end
+ it "should not accept unspecified :ds_name" do
+ @resource.stubs(:[]).with(:ds_name).returns "foo"
+ lambda { @provider.create }.should raise_error(MCXContentProviderException)
+ end
+ it "should accept :ds_type => user, ds_name => foo" do
+ @resource.stubs(:[]).with(:ds_type).returns "user"
+ @resource.stubs(:[]).with(:ds_name).returns "foo"
+ lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
+ end
+ it "should accept :ds_type => group, ds_name => foo" do
+ @resource.stubs(:[]).with(:ds_type).returns "group"
+ @resource.stubs(:[]).with(:ds_name).returns "foo"
+ lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
+ end
+ it "should accept :ds_type => computer, ds_name => foo" do
+ @resource.stubs(:[]).with(:ds_type).returns "computer"
+ @resource.stubs(:[]).with(:ds_name).returns "foo"
+ lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
+ end
+ it "should accept :ds_type => computerlist, ds_name => foo" do
+ @resource.stubs(:[]).with(:ds_type).returns "computerlist"
+ @resource.stubs(:[]).with(:ds_name).returns "foo"
+ lambda { @provider.create }.should_not raise_error(MCXContentProviderException)
+ end
+ it "should not accept :ds_type => bogustype, ds_name => foo" do
+ @resource.stubs(:[]).with(:ds_type).returns "bogustype"
+ @resource.stubs(:[]).with(:ds_name).returns "foo"
+ lambda { @provider.create }.should raise_error(MCXContentProviderException)
+ end
+ end
+
+ describe "when gathering existing instances" do
+ it "should define an instances class method." do
+ @provider.class.should respond_to(:instances)
+ end
+ it "should call external command dscl -list /Local/Default/<ds_type> on each known ds_type" do
+ @provider.class.expects(:dscl).with('localhost', '-list', "/Local/Default/Users").returns('')
+ @provider.class.expects(:dscl).with('localhost', '-list', "/Local/Default/Groups").returns('')
+ @provider.class.expects(:dscl).with('localhost', '-list', "/Local/Default/Computers").returns('')
+ @provider.class.expects(:dscl).with('localhost', '-list', "/Local/Default/ComputerLists").returns('')
+ @provider.class.instances
+ end
+ end
+end
diff --git a/spec/unit/provider/mount/parsed.rb b/spec/unit/provider/mount/parsed.rb
index 8d043f97f..9585afa62 100755
--- a/spec/unit/provider/mount/parsed.rb
+++ b/spec/unit/provider/mount/parsed.rb
@@ -130,11 +130,11 @@ describe provider_class do
describe provider_class, " when modifying the filesystem tab" do
include ParsedMountTesting
before do
- @mount = mkmount
- @target = @provider_class.default_target
-
# Never write to disk, only to RAM.
@provider_class.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
+
+ @mount = mkmount
+ @target = @provider_class.default_target
end
it "should write the mount to disk when :flush is called" do
diff --git a/spec/unit/provider/service/launchd.rb b/spec/unit/provider/service/launchd.rb
new file mode 100755
index 000000000..9650ea423
--- /dev/null
+++ b/spec/unit/provider/service/launchd.rb
@@ -0,0 +1,134 @@
+#!/usr/bin/env ruby
+#
+# Unit testing for the launchd service provider
+#
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet'
+
+provider_class = Puppet::Type.type(:service).provider(:launchd)
+
+describe provider_class do
+
+ before :each do
+ # Create a mock resource
+ @resource = stub 'resource'
+
+ @provider = provider_class.new
+ @joblabel = "com.foo.food"
+ @jobplist = {}
+
+ # A catch all; no parameters set
+ @resource.stubs(:[]).returns(nil)
+
+ # But set name, ensure and enable
+ @resource.stubs(:[]).with(:name).returns @joblabel
+ @resource.stubs(:[]).with(:ensure).returns :enabled
+ @resource.stubs(:[]).with(:enable).returns :true
+ @resource.stubs(:ref).returns "Service[#{@joblabel}]"
+
+ # stub out the provider methods that actually touch the filesystem
+ # or execute commands
+ @provider.stubs(:plist_from_label).returns([@joblabel, @jobplist])
+ @provider.stubs(:execute).returns("")
+ @provider.stubs(:resource).returns @resource
+ end
+
+ it "should have a start method for #{@provider.object_id}" do
+ @provider.should respond_to(:start)
+ end
+
+ it "should have a stop method" do
+ @provider.should respond_to(:stop)
+ end
+
+ it "should have an enabled? method" do
+ @provider.should respond_to(:enabled?)
+ end
+
+ it "should have an enable method" do
+ @provider.should respond_to(:enable)
+ end
+
+ it "should have a disable method" do
+ @provider.should respond_to(:disable)
+ end
+
+ it "should have a status method" do
+ @provider.should respond_to(:status)
+ end
+
+
+ describe "when checking status" do
+ it "should call the external command 'launchctl list' once" do
+ @provider.expects("launchctl").with(:list, @resource[:name]).returns(:running).once
+ @provider.status
+ end
+ end
+
+ describe "when starting the service" do
+ it "should look for the relevant plist once" do
+ @provider.expects(:plist_from_label).once
+ @provider.start
+ end
+ it "should execute 'launchctl load' once without writing to the plist if the job is enabled" do
+ @provider.stubs(:enabled?).returns :true
+ @provider.expects(:execute).with([:launchctl, :load, @resource[:name]]).once
+ @provider.start
+ end
+ it "should execute 'launchctl load' with writing to the plist once if the job is disabled" do
+ @provider.stubs(:enabled?).returns :false
+ @provider.expects(:execute).with([:launchctl, :load, "-w", @resource[:name]]).once
+ @provider.start
+ end
+ it "should disable the job once if the job is disabled and should be disabled at boot" do
+ @provider.stubs(:enabled?).returns :false
+ @resource.stubs(:[]).with(:enable).returns :false
+ @provider.expects(:disable).once
+ @provider.start
+ end
+ end
+
+ describe "when stopping the service" do
+ it "should look for the relevant plist once" do
+ @provider.expects(:plist_from_label).once
+ @provider.stop
+ end
+ it "should execute 'launchctl unload' once without writing to the plist if the job is disabled" do
+ @provider.stubs(:enabled?).returns :false
+ @provider.expects(:execute).with([:launchctl, :unload, @resource[:name]]).once
+ @provider.stop
+ end
+ it "should execute 'launchctl unload' with writing to the plist once if the job is enabled" do
+ @provider.stubs(:enabled?).returns :true
+ @provider.expects(:execute).with([:launchctl, :unload, "-w", @resource[:name]]).once
+ @provider.stop
+ end
+ it "should enable the job once if the job is enabled and should be enabled at boot" do
+ @provider.stubs(:enabled?).returns :true
+ @resource.stubs(:[]).with(:enable).returns :true
+ @provider.expects(:enable).once
+ @provider.stop
+ end
+ end
+
+ describe "when enabling the service" do
+ it "should look for the relevant plist once" do
+ @provider.expects(:plist_from_label).once
+ @provider.stop
+ end
+ it "should check if the job is enabled once" do
+ @provider.expects(:enabled?).once
+ @provider.stop
+ end
+ end
+
+ describe "when disabling the service" do
+ it "should look for the relevant plist once" do
+ @provider.expects(:plist_from_label).once
+ @provider.stop
+ end
+ end
+
+ end
diff --git a/spec/unit/provider/ssh_authorized_key/parsed.rb b/spec/unit/provider/ssh_authorized_key/parsed.rb
index 16efc5b58..21f30f97e 100755
--- a/spec/unit/provider/ssh_authorized_key/parsed.rb
+++ b/spec/unit/provider/ssh_authorized_key/parsed.rb
@@ -92,4 +92,11 @@ describe provider_class do
it "should set correct default permissions" do
# No idea how to test the flush method
end
+
+ it "'s parse_options method should be able to parse options containing commas" do
+ options = %w{from="host1.reductlivelabs.com,host.reductivelabs.com" command="/usr/local/bin/run" ssh-pty}
+ optionstr = options.join(", ")
+
+ @provider.parse_options(optionstr).should == options
+ end
end
diff --git a/spec/unit/provider/user/user_role_add.rb b/spec/unit/provider/user/user_role_add.rb
index fc2074d44..49359eb10 100644
--- a/spec/unit/provider/user/user_role_add.rb
+++ b/spec/unit/provider/user/user_role_add.rb
@@ -49,6 +49,10 @@ describe provider_class do
end
describe "when calling create" do
+ before do
+ @provider.stubs(:password=)
+ end
+
it "should use the add command when the user is not a role" do
@provider.stubs(:is_role?).returns(false)
@provider.expects(:addcmd).returns("useradd")
@@ -107,6 +111,7 @@ describe provider_class do
end
it "should add -o when the user is being created" do
+ @provider.stubs(:password=)
@provider.create
end
@@ -188,4 +193,57 @@ describe provider_class do
@provider.keys=({})
end
end
+
+ describe "when getting the hashed password" do
+ before do
+ @array = mock "array"
+ end
+
+ it "should readlines of /etc/shadow" do
+ File.expects(:readlines).with("/etc/shadow").returns([])
+ @provider.password
+ end
+
+ it "should reject anything that doesn't start with alpha numerics" do
+ @array.expects(:reject).returns([])
+ File.stubs(:readlines).with("/etc/shadow").returns(@array)
+ @provider.password
+ end
+
+ it "should collect splitting on ':'" do
+ @array.stubs(:reject).returns(@array)
+ @array.expects(:collect).returns([])
+ File.stubs(:readlines).with("/etc/shadow").returns(@array)
+ @provider.password
+ end
+
+ it "should find the matching user" do
+ @resource.stubs(:[]).with(:name).returns("username")
+ @array.stubs(:reject).returns(@array)
+ @array.stubs(:collect).returns([["username", "hashedpassword"], ["someoneelse", "theirpassword"]])
+ File.stubs(:readlines).with("/etc/shadow").returns(@array)
+ @provider.password.must == "hashedpassword"
+ end
+
+ it "should get the right password" do
+ @resource.stubs(:[]).with(:name).returns("username")
+ File.stubs(:readlines).with("/etc/shadow").returns(["#comment", " nonsense", " ", "username:hashedpassword:stuff:foo:bar:::", "other:pword:yay:::"])
+ @provider.password.must == "hashedpassword"
+ end
+ end
+
+ describe "when setting the password" do
+ #how can you mock these blocks up?
+ it "should open /etc/shadow for reading and /etc/shadow_tmp for writing" do
+ File.expects(:open).with("/etc/shadow", "r")
+ File.stubs(:rename)
+ @provider.password=("hashedpassword")
+ end
+
+ it "should rename the /etc/shadow_tmp to /etc/shadow" do
+ File.stubs(:open).with("/etc/shadow", "r")
+ File.expects(:rename).with("/etc/shadow_tmp", "/etc/shadow")
+ @provider.password=("hashedpassword")
+ end
+ end
end
diff --git a/spec/unit/provider/zfs/solaris.rb b/spec/unit/provider/zfs/solaris.rb
new file mode 100755
index 000000000..63aefcdc4
--- /dev/null
+++ b/spec/unit/provider/zfs/solaris.rb
@@ -0,0 +1,87 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+provider_class = Puppet::Type.type(:zfs).provider(:solaris)
+
+describe provider_class do
+ before do
+ @resource = stub("resource", :name => "myzfs")
+ @resource.stubs(:[]).with(:name).returns "myzfs"
+ @resource.stubs(:[]).returns "shouldvalue"
+ @provider = provider_class.new(@resource)
+ end
+
+ describe "when calling add_properties" do
+ it "should add -o and the key=value for each properties with a value" do
+ @resource.stubs(:[]).with(:quota).returns ""
+ @resource.stubs(:[]).with(:mountpoint).returns "/foo"
+ properties = @provider.add_properties
+ properties.include?("-o").should == true
+ properties.include?("mountpoint=/foo").should == true
+ properties.detect { |a| a.include?("quota") }.should == nil
+ end
+ end
+
+ describe "when calling create" do
+ it "should call add_properties" do
+ @provider.stubs(:zfs)
+ @provider.expects(:add_properties).returns([])
+ @provider.create
+ end
+
+ it "should call zfs with create, properties and this zfs" do
+ @provider.stubs(:add_properties).returns(%w{a b})
+ @provider.expects(:zfs).with(:create, "a", "b", @resource[:name])
+ @provider.create
+ end
+ end
+
+ describe "when calling delete" do
+ it "should call zfs with :destroy and this zfs" do
+ @provider.expects(:zfs).with(:destroy, @resource[:name])
+ @provider.delete
+ end
+ end
+
+ describe "when calling exist?" do
+ it "should call zfs with :list" do
+ #return stuff because we have to slice and dice it
+ @provider.expects(:zfs).with(:list).returns("NAME USED AVAIL REFER MOUNTPOINT\nmyzfs 100K 27.4M /myzfs")
+ @provider.exists?
+ end
+
+ it "should return true if returned values match the name" do
+ @provider.stubs(:zfs).with(:list).returns("NAME USED AVAIL REFER MOUNTPOINT\n#{@resource[:name]} 100K 27.4M /myzfs")
+ @provider.exists?.should == true
+ end
+
+ it "should return false if returned values don't match the name" do
+ @provider.stubs(:zfs).with(:list).returns("no soup for you")
+ @provider.exists?.should == false
+ end
+
+ end
+
+ [:mountpoint, :compression, :copies, :quota, :reservation, :sharenfs, :snapdir].each do |prop|
+ describe "when getting the #{prop} value" do
+ it "should call zfs with :get, #{prop} and this zfs" do
+ @provider.expects(:zfs).with(:get, prop, @resource[:name]).returns("NAME PROPERTY VALUE SOURCE\nmyzfs name value blah")
+ @provider.send(prop)
+ end
+
+ it "should get the third value of the second line from the output" do
+ @provider.stubs(:zfs).with(:get, prop, @resource[:name]).returns("NAME PROPERTY VALUE SOURCE\nmyzfs name value blah")
+ @provider.send(prop).should == "value"
+ end
+ end
+
+ describe "when setting the #{prop} value" do
+ it "should call zfs with :set, #{prop}=value and this zfs" do
+ @provider.expects(:zfs).with(:set, "#{prop}=value", @resource[:name])
+ @provider.send("#{prop}=".intern, "value")
+ end
+ end
+ end
+
+end
diff --git a/spec/unit/provider/zone/solaris.rb b/spec/unit/provider/zone/solaris.rb
new file mode 100755
index 000000000..b7dd74705
--- /dev/null
+++ b/spec/unit/provider/zone/solaris.rb
@@ -0,0 +1,42 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+provider_class = Puppet::Type.type(:zone).provider(:solaris)
+
+describe provider_class do
+ before do
+ @resource = stub("resource", :name => "mypool")
+ @resource.stubs(:[]).returns "shouldvalue"
+ @provider = provider_class.new(@resource)
+ end
+
+ describe "when calling configure" do
+ it "should add the create args to the create str" do
+ @resource.stubs(:properties).returns([])
+ @resource.stubs(:[]).with(:create_args).returns("create_args")
+ @provider.expects(:setconfig).with("create -b create_args\nset zonepath=shouldvalue\ncommit\n")
+ @provider.configure
+ end
+ end
+
+ describe "when installing" do
+ it "should call zoneadm" do
+ @provider.expects(:zoneadm)
+ @provider.install
+ end
+
+ it "should just install if there are no install args" do
+ @resource.stubs(:[]).with(:install_args).returns(nil)
+ @provider.expects(:zoneadm).with(:install)
+ @provider.install
+ end
+
+ it "should add the install args to the command if they exist" do
+ @resource.stubs(:[]).with(:install_args).returns("install args")
+ @provider.expects(:zoneadm).with(:install, ["install", "args"])
+ @provider.install
+ end
+ end
+
+end
diff --git a/spec/unit/provider/zpool/solaris.rb b/spec/unit/provider/zpool/solaris.rb
new file mode 100755
index 000000000..af4db88c1
--- /dev/null
+++ b/spec/unit/provider/zpool/solaris.rb
@@ -0,0 +1,158 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+provider_class = Puppet::Type.type(:zpool).provider(:solaris)
+
+describe provider_class do
+ before do
+ @resource = stub("resource", :name => "mypool")
+ @resource.stubs(:[]).returns "shouldvalue"
+ @provider = provider_class.new(@resource)
+ end
+
+ describe "when getting the instance" do
+ it "should call process_zpool_data with the result of get_pool_data only once" do
+ @provider.stubs(:get_pool_data).returns(["foo", "disk"])
+ @provider.expects(:process_zpool_data).with(["foo", "disk"]).returns("stuff").once
+ @provider.current_pool
+ @provider.current_pool
+ end
+ end
+
+ describe "when calling flush" do
+ it "should need to reload the pool" do
+ @provider.stubs(:get_pool_data)
+ @provider.expects(:process_zpool_data).returns("stuff").times(2)
+ @provider.current_pool
+ @provider.flush
+ @provider.current_pool
+ end
+ end
+
+ describe "when procesing zpool data" do
+ before do
+ @zpool_data = ["foo", "disk"]
+ end
+
+ describe "when there is no data" do
+ it "should return a hash with ensure=>:absent" do
+ @provider.process_zpool_data([])[:ensure].should == :absent
+ end
+ end
+
+ describe "when there is a spare" do
+ it "should add the spare disk to the hash and strip the array" do
+ @zpool_data += ["spares", "spare_disk"]
+ @provider.process_zpool_data(@zpool_data)[:spare].should == ["spare_disk"]
+ end
+ end
+
+ describe "when there is a log" do
+ it "should add the log disk to the hash and strip the array" do
+ @zpool_data += ["logs", "log_disk"]
+ @provider.process_zpool_data(@zpool_data)[:log].should == ["log_disk"]
+ end
+ end
+
+ describe "when the vdev is a mirror" do
+ it "should call create_multi_array with mirror" do
+ @zpool_data = ["mirrorpool", "mirror", "disk1", "disk2", "mirror", "disk3", "disk4"]
+ @provider.process_zpool_data(@zpool_data)[:mirror].should == ["disk1 disk2", "disk3 disk4"]
+ end
+ end
+
+ describe "when the vdev is a raidz1" do
+ it "should call create_multi_array with raidz1" do
+ @zpool_data = ["mirrorpool", "raidz1", "disk1", "disk2"]
+ @provider.process_zpool_data(@zpool_data)[:raidz].should == ["disk1 disk2"]
+ end
+ end
+
+ describe "when the vdev is a raidz2" do
+ it "should call create_multi_array with raidz2 and set the raid_parity" do
+ @zpool_data = ["mirrorpool", "raidz2", "disk1", "disk2"]
+ pool = @provider.process_zpool_data(@zpool_data)
+ pool[:raidz].should == ["disk1 disk2"]
+ pool[:raid_parity].should == "raidz2"
+ end
+ end
+ end
+
+ describe "when calling the getters and setters" do
+ [:disk, :mirror, :raidz, :log, :spare].each do |field|
+ describe "when calling %s" % field do
+ it "should get the %s value from the current_pool hash" % field do
+ pool_hash = mock "pool hash"
+ pool_hash.expects(:[]).with(field)
+ @provider.stubs(:current_pool).returns(pool_hash)
+ @provider.send(field)
+ end
+ end
+
+ describe "when setting the %s" % field do
+ it "should warn the %s values were not in sync" % field do
+ Puppet.expects(:warning).with("NO CHANGES BEING MADE: zpool %s does not match, should be 'shouldvalue' currently is 'currentvalue'" % field)
+ @provider.stubs(:current_pool).returns(Hash.new("currentvalue"))
+ @provider.send((field.to_s + "=").intern, "shouldvalue")
+ end
+ end
+ end
+ end
+
+ describe "when calling create" do
+ before do
+ @resource.stubs(:[]).with(:pool).returns("mypool")
+ @provider.stubs(:zpool)
+ end
+
+
+ it "should call build_vdevs" do
+ @provider.expects(:build_vdevs).returns([])
+ @provider.create
+ end
+
+ it "should call build_named with 'spares' and 'log" do
+ @provider.expects(:build_named).with("spare").returns([])
+ @provider.expects(:build_named).with("log").returns([])
+ @provider.create
+ end
+
+ it "should call zpool with arguments from build_vdevs and build_named" do
+ @provider.expects(:zpool).with(:create, 'mypool', 'shouldvalue', 'spare', 'shouldvalue', 'log', 'shouldvalue')
+ @provider.create
+ end
+ end
+
+ describe "when calling delete" do
+ it "should call zpool with destroy and the pool name" do
+ @resource.stubs(:[]).with(:pool).returns("poolname")
+ @provider.expects(:zpool).with(:destroy, "poolname")
+ @provider.delete
+ end
+ end
+
+ describe "when calling exists?" do
+ before do
+ @current_pool = Hash.new(:absent)
+ @provider.stubs(:get_pool_data).returns([])
+ @provider.stubs(:process_zpool_data).returns(@current_pool)
+ end
+
+ it "should get the current pool" do
+ @provider.expects(:process_zpool_data).returns(@current_pool)
+ @provider.exists?
+ end
+
+ it "should return false if the current_pool is absent" do
+ #the before sets it up
+ @provider.exists?.should == false
+ end
+
+ it "should return true if the current_pool has values" do
+ @current_pool[:pool] = "mypool"
+ @provider.exists?.should == true
+ end
+ end
+
+end
diff --git a/spec/unit/ssl/certificate_request.rb b/spec/unit/ssl/certificate_request.rb
index 3f25500c0..5d0de0814 100755
--- a/spec/unit/ssl/certificate_request.rb
+++ b/spec/unit/ssl/certificate_request.rb
@@ -142,7 +142,8 @@ describe Puppet::SSL::CertificateRequest do
end
it "should verify the generated request using the public key" do
- @request.expects(:verify).with(@key.public_key)
+ # Stupid keys don't have a competent == method.
+ @request.expects(:verify).with { |public_key| public_key.to_s == @key.public_key.to_s }.returns true
@instance.generate(@key)
end
diff --git a/spec/unit/transaction/change.rb b/spec/unit/transaction/change.rb
index eaa6fb4ab..1f69311cd 100755
--- a/spec/unit/transaction/change.rb
+++ b/spec/unit/transaction/change.rb
@@ -108,6 +108,7 @@ describe Puppet::Transaction::Change do
@change.stubs(:noop?).returns false
@property.stub_everything
@property.stubs(:resource).returns "myresource"
+ @property.stubs(:name).returns :myprop
end
it "should sync the property" do
@@ -116,16 +117,20 @@ describe Puppet::Transaction::Change do
@change.forward
end
- it "should return nil if syncing the property returns nil" do
+ it "should return the default event if syncing the property returns nil" do
@property.stubs(:sync).returns nil
- @change.forward.should be_nil
+ @change.expects(:event).with(:myprop_changed).returns :myevent
+
+ @change.forward.should == [:myevent]
end
- it "should return nil if syncing the property returns an empty array" do
+ it "should return the default event if syncing the property returns an empty array" do
@property.stubs(:sync).returns []
- @change.forward.should be_nil
+ @change.expects(:event).with(:myprop_changed).returns :myevent
+
+ @change.forward.should == [:myevent]
end
it "should log the change" do
diff --git a/spec/unit/type/computer.rb b/spec/unit/type/computer.rb
new file mode 100755
index 000000000..43a313c5b
--- /dev/null
+++ b/spec/unit/type/computer.rb
@@ -0,0 +1,78 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+computer = Puppet::Type.type(:computer)
+
+describe Puppet.type(:computer), " when checking computer objects" do
+ before do
+ provider_class = Puppet::Type::Computer.provider(Puppet::Type::Computer.providers[0])
+ Puppet::Type::Computer.expects(:defaultprovider).returns provider_class
+ @resource = Puppet::Type::Computer.create(
+ :name => "puppetcomputertest",
+ :en_address => "aa:bb:cc:dd:ee:ff",
+ :ip_address => "1.2.3.4")
+ @properties = {}
+ @ensure = Puppet::Type::Computer.attrclass(:ensure).new(:resource => @resource)
+ end
+
+ it "should be able to create a instance" do
+ provider_class = Puppet::Type::Computer.provider(Puppet::Type::Computer.providers[0])
+ Puppet::Type::Computer.expects(:defaultprovider).returns provider_class
+ computer.create(:name => "bar").should_not be_nil
+ end
+
+ properties = [:en_address, :ip_address]
+ params = [:name]
+
+ properties.each do |property|
+ it "should have a %s property" % property do
+ computer.attrclass(property).ancestors.should be_include(Puppet::Property)
+ end
+
+ it "should have documentation for its %s property" % property do
+ computer.attrclass(property).doc.should be_instance_of(String)
+ end
+
+ it "should accept :absent as a value" do
+ prop = computer.attrclass(property).new(:resource => @resource)
+ prop.should = :absent
+ prop.should.must == :absent
+ end
+ end
+
+ params.each do |param|
+ it "should have a %s parameter" % param do
+ computer.attrclass(param).ancestors.should be_include(Puppet::Parameter)
+ end
+
+ it "should have documentation for its %s parameter" % param do
+ computer.attrclass(param).doc.should be_instance_of(String)
+ end
+ end
+
+ describe "default values" do
+ before do
+ provider_class = computer.provider(computer.providers[0])
+ computer.expects(:defaultprovider).returns provider_class
+ end
+
+ it "should be nil for en_address" do
+ computer.create(:name => :en_address)[:en_address].should == nil
+ end
+
+ it "should be nil for ip_address" do
+ computer.create(:name => :ip_address)[:ip_address].should == nil
+ end
+ end
+
+ describe "when managing the ensure property" do
+ it "should support a :present value" do
+ lambda { @ensure.should = :present }.should_not raise_error
+ end
+
+ it "should support an :absent value" do
+ lambda { @ensure.should = :absent }.should_not raise_error
+ end
+ end
+end
diff --git a/spec/unit/type/file/owner.rb b/spec/unit/type/file/owner.rb
new file mode 100755
index 000000000..743e64054
--- /dev/null
+++ b/spec/unit/type/file/owner.rb
@@ -0,0 +1,132 @@
+#!/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") }
+
+property = Puppet::Type.type(:file).attrclass(:owner)
+
+describe property do
+ before do
+ @resource = stub 'resource', :line => "foo", :file => "bar"
+ @resource.stubs(:[]).returns "foo"
+ @resource.stubs(:[]).with(:path).returns "/my/file"
+ @owner = property.new :resource => @resource
+ end
+
+ it "should have a method for testing whether an owner is valid" do
+ @owner.must respond_to(:validuser?)
+ end
+
+ it "should return the found uid if an owner is valid" do
+ @owner.expects(:uid).with("foo").returns 500
+ @owner.validuser?("foo").should == 500
+ end
+
+ it "should return false if an owner is not valid" do
+ @owner.expects(:uid).with("foo").returns nil
+ @owner.validuser?("foo").should be_false
+ end
+
+ describe "when retrieving the current value" do
+ it "should return :absent if the file cannot stat" do
+ @resource.expects(:stat).returns nil
+
+ @owner.retrieve.should == :absent
+ end
+
+ it "should get the uid from the stat instance from the file" do
+ stat = stub 'stat', :ftype => "foo"
+ @resource.expects(:stat).returns stat
+ stat.expects(:uid).returns 500
+
+ @owner.retrieve.should == 500
+ end
+
+ it "should warn and return :silly if the found value is higher than the maximum uid value" do
+ Puppet.settings.expects(:value).with(:maximum_uid).returns 500
+
+ stat = stub 'stat', :ftype => "foo"
+ @resource.expects(:stat).returns stat
+ stat.expects(:uid).returns 1000
+
+ @owner.expects(:warning)
+ @owner.retrieve.should == :silly
+ end
+ end
+
+ 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
+ Puppet::Util::SUIDManager.expects(:uid).returns 1
+ @owner.expects(:warning)
+ @owner.must be_insync("whatever")
+ end
+ end
+
+ before do
+ Puppet::Util::SUIDManager.stubs(:uid).returns 0
+ end
+
+ it "should directly compare the owner values if the desired owner is an integer" do
+ @owner.should = [10]
+ @owner.must be_insync(10)
+ end
+
+ it "should treat numeric strings as integers" do
+ @owner.should = ["10"]
+ @owner.must be_insync(10)
+ end
+
+ it "should convert the owner name to an integer if the desired owner is a string" do
+ @owner.expects(:uid).with("foo").returns 10
+ @owner.should = %w{foo}
+
+ @owner.must be_insync(10)
+ end
+
+ it "should fail if it cannot convert an owner name to an integer" do
+ @owner.expects(:uid).with("foo").returns nil
+ @owner.should = %w{foo}
+
+ lambda { @owner.insync?(10) }.should raise_error(Puppet::Error)
+ end
+
+ it "should return false if the owners are not equal" do
+ @owner.should = [10]
+ @owner.should_not be_insync(20)
+ end
+ end
+
+ describe "when changing the owner" do
+ before do
+ @owner.should = %w{one}
+ @owner.stubs(:path).returns "path"
+ @owner.stubs(:uid).returns 500
+ end
+
+ it "should chown the file if :links is set to :follow" do
+ @resource.expects(:[]).with(:links).returns :follow
+ File.expects(:chown)
+
+ @owner.sync
+ end
+
+ it "should lchown the file if :links is set to :manage" do
+ @resource.expects(:[]).with(:links).returns :manage
+ File.expects(:lchown)
+
+ @owner.sync
+ end
+
+ it "should use the first valid owner in its 'should' list" do
+ @owner.should = %w{one two three}
+ @owner.expects(:validuser?).with("one").returns nil
+ @owner.expects(:validuser?).with("two").returns 500
+ @owner.expects(:validuser?).with("three").never
+
+ File.expects(:chown).with(500, nil, "/my/file")
+
+ @owner.sync
+ end
+ end
+end
diff --git a/spec/unit/type/file/selinux.rb b/spec/unit/type/file/selinux.rb
index d346be362..c81270ab0 100644
--- a/spec/unit/type/file/selinux.rb
+++ b/spec/unit/type/file/selinux.rb
@@ -4,7 +4,7 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f
[:seluser, :selrole, :seltype, :selrange].each do |param|
-property = Puppet::Type.type(:file).attrclass(param)
+ property = Puppet::Type.type(:file).attrclass(param)
describe property do
before do
@resource = mock 'resource'
@@ -69,7 +69,6 @@ property = Puppet::Type.type(:file).attrclass(param)
it "should be able to set a new context" do
stat = stub 'stat', :ftype => "foo"
- @resource.expects(:stat).returns stat
@sel.should = %w{newone}
@sel.expects(:set_selinux_context).with("/my/file", ["newone"], param)
@sel.sync
diff --git a/spec/unit/type/mcx.rb b/spec/unit/type/mcx.rb
new file mode 100755
index 000000000..de7908e0f
--- /dev/null
+++ b/spec/unit/type/mcx.rb
@@ -0,0 +1,100 @@
+#!/usr/bin/env ruby
+#--
+# Copyright (C) 2008 Jeffrey J McCune.
+
+# This program and entire repository is free software; you can
+# redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Author: Jeff McCune <mccune.jeff@gmail.com>
+
+# Most of this code copied from /spec/type/service.rb
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/type/mcx'
+
+mcx_type = Puppet::Type.type(:mcx)
+
+describe mcx_type, "when validating attributes" do
+
+ properties = [:ensure, :content]
+ parameters = [:name, :ds_type, :ds_name]
+
+ parameters.each do |p|
+ it "should have a #{p} parameter" do
+ mcx_type.attrclass(p).ancestors.should be_include(Puppet::Parameter)
+ end
+ it "should have documentation for its #{p} parameter" do
+ mcx_type.attrclass(p).doc.should be_instance_of(String)
+ end
+ end
+
+ properties.each do |p|
+ it "should have a #{p} property" do
+ mcx_type.attrclass(p).ancestors.should be_include(Puppet::Property)
+ end
+ it "should have documentation for its #{p} property" do
+ mcx_type.attrclass(p).doc.should be_instance_of(String)
+ end
+ end
+
+end
+
+describe mcx_type, "default values" do
+
+ before :each do
+ provider_class = mcx_type.provider(mcx_type.providers[0])
+ mcx_type.stubs(:defaultprovider).returns provider_class
+ end
+
+ it "should be nil for :ds_type" do
+ mcx_type.create(:name => '/Foo/bar')[:ds_type].should be_nil
+ end
+
+ it "should be nil for :ds_name" do
+ mcx_type.create(:name => '/Foo/bar')[:ds_name].should be_nil
+ end
+
+ it "should be nil for :content" do
+ mcx_type.create(:name => '/Foo/bar')[:content].should be_nil
+ end
+
+end
+
+describe mcx_type, "when validating properties" do
+
+ before :each do
+ provider_class = mcx_type.provider(mcx_type.providers[0])
+ mcx_type.stubs(:defaultprovider).returns provider_class
+ end
+
+ it "should be able to create an instance" do
+ lambda {
+ mcx_type.create(:name => '/Foo/bar')
+ }.should_not raise_error
+ end
+
+ it "should support :present as a value to :ensure" do
+ lambda {
+ mcx_type.create(:name => "/Foo/bar", :ensure => :present)
+ }.should_not raise_error
+ end
+
+ it "should support :absent as a value to :ensure" do
+ lambda {
+ mcx_type.create(:name => "/Foo/bar", :ensure => :absent)
+ }.should_not raise_error
+ end
+
+end
diff --git a/spec/unit/type/package.rb b/spec/unit/type/package.rb
index 103fd6037..13bf4d3d3 100755
--- a/spec/unit/type/package.rb
+++ b/spec/unit/type/package.rb
@@ -105,6 +105,7 @@ describe Puppet::Type.type(:package) do
before :each do
@provider = stub 'provider', :class => Puppet::Type.type(:package).defaultprovider, :clear => nil, :satisfies? => true, :name => :mock
Puppet::Type.type(:package).defaultprovider.stubs(:new).returns(@provider)
+ Puppet::Type.type(:package).defaultprovider.stubs(:instances).returns([])
@package = Puppet::Type.type(:package).create(:name => "yay")
@catalog = Puppet::Node::Catalog.new
diff --git a/spec/unit/type/resources.rb b/spec/unit/type/resources.rb
new file mode 100644
index 000000000..70bc21b5d
--- /dev/null
+++ b/spec/unit/type/resources.rb
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+resources = Puppet::Type.type(:resources)
+
+# There are still plenty of tests to port over from test/.
+describe resources do
+ describe "when initializing" do
+ it "should fail if the specified resource type does not exist" do
+ Puppet::Type.expects(:type).with("nosuchtype").returns nil
+ lambda { resources.create :name => "nosuchtype" }.should raise_error(Puppet::Error)
+ end
+
+ it "should not fail when the specified resource type exists" do
+ lambda { resources.create :name => "file" }.should_not raise_error
+ end
+
+ it "should set its :resource_type attribute" do
+ resources.create(:name => "file").resource_type.should == Puppet::Type.type(:file)
+ end
+ end
+end
diff --git a/spec/unit/type/ssh_authorized_key.rb b/spec/unit/type/ssh_authorized_key.rb
index 1860f2714..3240b7a94 100755
--- a/spec/unit/type/ssh_authorized_key.rb
+++ b/spec/unit/type/ssh_authorized_key.rb
@@ -73,6 +73,18 @@ describe ssh_authorized_key do
@class.attrtype(:options).should == :property
end
+ it "'s options property should return well formed string of arrays from is_to_s" do
+ resource = @class.create(:name => "whev", :type => :rsa, :user => "nobody", :options => ["a","b","c"])
+
+ resource.property(:options).is_to_s(["a","b","c"]).should == "a,b,c"
+ end
+
+ it "'s options property should return well formed string of arrays from is_to_s" do
+ resource = @class.create(:name => "whev", :type => :rsa, :user => "nobody", :options => ["a","b","c"])
+
+ resource.property(:options).should_to_s(["a","b","c"]).should == "a,b,c"
+ end
+
it "should have a target property" do
@class.attrtype(:target).should == :property
end
diff --git a/spec/unit/type/user.rb b/spec/unit/type/user.rb
index 227a500f1..17524c5e5 100755
--- a/spec/unit/type/user.rb
+++ b/spec/unit/type/user.rb
@@ -52,6 +52,22 @@ describe user do
end
end
+ list_properties = [:groups, :roles, :auths]
+
+ list_properties.each do |property|
+ it "should have a list '%s'" % property do
+ user.attrclass(property).ancestors.should be_include(Puppet::Property::List)
+ end
+ end
+
+ it "should have an ordered list 'profiles'" do
+ user.attrclass(:profiles).ancestors.should be_include(Puppet::Property::OrderedList)
+ end
+
+ it "should have key values 'keys'" do
+ user.attrclass(:keys).ancestors.should be_include(Puppet::Property::KeyValue)
+ end
+
describe "when retrieving all current values" do
before do
@user = user.create(:name => "foo", :uid => 10, :gid => 10)
@@ -159,6 +175,26 @@ describe user do
gid.should.must == "foo"
end
+ describe "when testing whether in sync" do
+ before do
+ @gid = user.attrclass(:gid).new(:resource => @resource, :should => %w{foo bar})
+ end
+
+ it "should return true if any of the specified groups are equal to the current integer" do
+ Puppet::Util.expects(:gid).with("foo").returns 300
+ Puppet::Util.expects(:gid).with("bar").returns 500
+
+ @gid.must be_insync(500)
+ end
+
+ it "should return false if none of the specified groups are equal to the current integer" do
+ Puppet::Util.expects(:gid).with("foo").returns 300
+ Puppet::Util.expects(:gid).with("bar").returns 500
+
+ @gid.should_not be_insync(700)
+ end
+ end
+
describe "when syncing" do
before do
@gid = user.attrclass(:gid).new(:resource => @resource, :should => %w{foo bar})
@@ -200,4 +236,15 @@ describe user do
lambda { @ensure.should = :role }.should_not raise_error
end
end
+
+ describe "when user has roles" do
+ it "should autorequire roles" do
+ testuser = Puppet.type(:user).create(:name => "testuser", :roles => "testrole")
+ testrole = Puppet.type(:user).create(:name => "testrole")
+ config = Puppet::Node::Catalog.new :testing do |conf|
+ [testuser, testrole].each { |resource| conf.add_resource resource }
+ end
+ testuser.autorequire
+ end
+ end
end
diff --git a/spec/unit/type/zfs.rb b/spec/unit/type/zfs.rb
new file mode 100755
index 000000000..434415e24
--- /dev/null
+++ b/spec/unit/type/zfs.rb
@@ -0,0 +1,28 @@
+#!/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") }
+
+zpool = Puppet::Type.type(:zfs)
+
+describe zpool do
+ before do
+ @provider = stub 'provider'
+ @resource = stub 'resource', :resource => nil, :provider => @provider, :line => nil, :file => nil
+ end
+
+ properties = [:ensure, :mountpoint, :compression, :copies, :quota, :reservation, :sharenfs, :snapdir]
+
+ properties.each do |property|
+ it "should have a %s property" % property do
+ zpool.attrclass(property).ancestors.should be_include(Puppet::Property)
+ end
+ end
+
+ parameters = [:name]
+
+ parameters.each do |parameter|
+ it "should have a %s parameter" % parameter do
+ zpool.attrclass(parameter).ancestors.should be_include(Puppet::Parameter)
+ end
+ end
+end
diff --git a/spec/unit/type/zone.rb b/spec/unit/type/zone.rb
new file mode 100755
index 000000000..c99302644
--- /dev/null
+++ b/spec/unit/type/zone.rb
@@ -0,0 +1,20 @@
+#!/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") }
+
+zone = Puppet::Type.type(:zone)
+
+describe zone do
+ before do
+ @provider = stub 'provider'
+ @resource = stub 'resource', :resource => nil, :provider => @provider, :line => nil, :file => nil
+ end
+
+ parameters = [:create_args, :install_args]
+
+ parameters.each do |parameter|
+ it "should have a %s parameter" % parameter do
+ zone.attrclass(parameter).ancestors.should be_include(Puppet::Parameter)
+ end
+ end
+end
diff --git a/spec/unit/type/zpool.rb b/spec/unit/type/zpool.rb
new file mode 100755
index 000000000..6477d061d
--- /dev/null
+++ b/spec/unit/type/zpool.rb
@@ -0,0 +1,28 @@
+#!/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") }
+
+zpool = Puppet::Type.type(:zpool)
+
+describe zpool do
+ before do
+ @provider = stub 'provider'
+ @resource = stub 'resource', :resource => nil, :provider => @provider, :line => nil, :file => nil
+ end
+
+ properties = [:ensure, :disk, :mirror, :raidz, :spare, :log]
+
+ properties.each do |property|
+ it "should have a %s property" % property do
+ zpool.attrclass(property).ancestors.should be_include(Puppet::Property)
+ end
+ end
+
+ parameters = [:pool, :raid_parity]
+
+ parameters.each do |parameter|
+ it "should have a %s parameter" % parameter do
+ zpool.attrclass(parameter).ancestors.should be_include(Puppet::Parameter)
+ end
+ end
+end
diff --git a/spec/unit/util/selinux.rb b/spec/unit/util/selinux.rb
index 7a56f914a..dacf9f503 100644
--- a/spec/unit/util/selinux.rb
+++ b/spec/unit/util/selinux.rb
@@ -1,24 +1,66 @@
#!/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 File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/util/selinux'
include Puppet::Util::SELinux
+unless defined?(Selinux)
+ module Selinux
+ def self.is_selinux_enabled
+ false
+ end
+ end
+end
+
describe Puppet::Util::SELinux do
describe "selinux_support?" do
+ before do
+ end
it "should return :true if this system has SELinux enabled" do
- FileTest.expects(:exists?).with("/selinux/enforce").returns true
+ Selinux.expects(:is_selinux_enabled).returns 1
selinux_support?.should be_true
end
it "should return :false if this system lacks SELinux" do
- FileTest.expects(:exists?).with("/selinux/enforce").returns false
+ Selinux.expects(:is_selinux_enabled).returns 0
selinux_support?.should be_false
end
end
+ describe "filesystem detection" do
+ before :each do
+ File.expects(:read).with("/proc/mounts").returns "rootfs / rootfs rw 0 0\n/dev/root / ext3 rw,relatime,errors=continue,user_xattr,acl,data=ordered 0 0\n/dev /dev tmpfs rw,relatime,mode=755 0 0\n/proc /proc proc rw,relatime 0 0\n/sys /sys sysfs rw,relatime 0 0\n192.168.1.1:/var/export /mnt/nfs nfs rw,relatime,vers=3,rsize=32768,wsize=32768,namlen=255,hard,nointr,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.1.1,mountvers=3,mountproto=udp,addr=192.168.1.1 0 0\n"
+ end
+
+ it "should parse the contents of /proc/mounts" do
+ read_mounts().should == {
+ '/' => 'ext3',
+ '/sys' => 'sysfs',
+ '/mnt/nfs' => 'nfs',
+ '/proc' => 'proc',
+ '/dev' => 'tmpfs' }
+ end
+
+ it "should match a path on / to ext3" do
+ find_fs('/etc/puppet/testfile').should == "ext3"
+ end
+
+ it "should match a path on /mnt/nfs to nfs" do
+ find_fs('/mnt/nfs/testfile/foobar').should == "nfs"
+ end
+
+ it "should reture true for a capable filesystem" do
+ selinux_label_support?('/etc/puppet/testfile').should be_true
+ end
+
+ it "should return false for a noncapable filesystem" do
+ selinux_label_support?('/mnt/nfs/testfile').should be_false
+ end
+
+ end
+
describe "get_selinux_current_context" do
it "should return nil if no SELinux support" do
self.expects(:selinux_support?).returns false
@@ -27,19 +69,13 @@ describe Puppet::Util::SELinux do
it "should return a context" do
self.expects(:selinux_support?).returns true
- self.expects(:execpipe).with("/usr/bin/stat -c %C /foo").yields ["user_u:role_r:type_t:s0\n"]
+ Selinux.expects(:lgetfilecon).with("/foo").returns [0, "user_u:role_r:type_t:s0"]
get_selinux_current_context("/foo").should == "user_u:role_r:type_t:s0"
end
- it "should return nil if an exception is raised calling stat" do
- self.expects(:selinux_support?).returns true
- self.expects(:execpipe).with("/usr/bin/stat -c %C /foo").raises(Puppet::ExecutionFailure, 'error')
- get_selinux_current_context("/foo").should be_nil
- end
-
- it "should return nil if stat finds an unlabeled file" do
+ it "should return nil if lgetfilecon fails" do
self.expects(:selinux_support?).returns true
- self.expects(:execpipe).with("/usr/bin/stat -c %C /foo").yields ["(null)\n"]
+ Selinux.expects(:lgetfilecon).with("/foo").returns -1
get_selinux_current_context("/foo").should be_nil
end
end
@@ -50,25 +86,30 @@ describe Puppet::Util::SELinux do
get_selinux_default_context("/foo").should be_nil
end
- it "should return nil if matchpathcon is not executable" do
+ it "should return a context if a default context exists" do
self.expects(:selinux_support?).returns true
- FileTest.expects(:executable?).with("/usr/sbin/matchpathcon").returns false
- get_selinux_default_context("/foo").should be_nil
+ fstat = stub 'File::Stat', :mode => 0
+ File.expects(:lstat).with("/foo").returns fstat
+ self.expects(:find_fs).with("/foo").returns "ext3"
+ Selinux.expects(:matchpathcon).with("/foo", 0).returns [0, "user_u:role_r:type_t:s0"]
+ get_selinux_default_context("/foo").should == "user_u:role_r:type_t:s0"
end
- it "should return a context if a default context exists" do
+ it "should return nil if matchpathcon returns failure" do
self.expects(:selinux_support?).returns true
- FileTest.expects(:executable?).with("/usr/sbin/matchpathcon").returns true
- self.expects(:execpipe).with("/usr/sbin/matchpathcon /foo").yields ["/foo\tuser_u:role_r:type_t:s0\n"]
- get_selinux_default_context("/foo").should == "user_u:role_r:type_t:s0"
+ fstat = stub 'File::Stat', :mode => 0
+ File.expects(:lstat).with("/foo").returns fstat
+ self.expects(:find_fs).with("/foo").returns "ext3"
+ Selinux.expects(:matchpathcon).with("/foo", 0).returns -1
+ get_selinux_default_context("/foo").should be_nil
end
- it "should return nil if an exception is raised calling matchpathcon" do
+ it "should return nil if selinux_label_support returns false" do
self.expects(:selinux_support?).returns true
- FileTest.expects(:executable?).with("/usr/sbin/matchpathcon").returns true
- self.expects(:execpipe).with("/usr/sbin/matchpathcon /foo").raises(Puppet::ExecutionFailure, 'error')
+ self.expects(:find_fs).with("/foo").returns "nfs"
get_selinux_default_context("/foo").should be_nil
end
+
end
describe "parse_selinux_context" do
@@ -115,33 +156,37 @@ describe Puppet::Util::SELinux do
set_selinux_context("/foo", "user_u:role_r:type_t:s0").should be_nil
end
- it "should use chcon to set a context" do
+ it "should use lsetfilecon to set a context" do
self.expects(:selinux_support?).returns true
- self.expects(:execute).with(["/usr/bin/chcon","-h","user_u:role_r:type_t:s0","/foo"]).returns 0
+ Selinux.expects(:lsetfilecon).with("/foo", "user_u:role_r:type_t:s0").returns 0
set_selinux_context("/foo", "user_u:role_r:type_t:s0").should be_true
end
- it "should use chcon to set user_u user context" do
+ it "should use lsetfilecon to set user_u user context" do
self.expects(:selinux_support?).returns true
- self.expects(:execute).with(["/usr/bin/chcon","-h","-u","user_u","/foo"]).returns 0
+ Selinux.expects(:lgetfilecon).with("/foo").returns [0, "foo:role_r:type_t:s0"]
+ Selinux.expects(:lsetfilecon).with("/foo", "user_u:role_r:type_t:s0").returns 0
set_selinux_context("/foo", "user_u", :seluser).should be_true
end
- it "should use chcon to set role_r role context" do
+ it "should use lsetfilecon to set role_r role context" do
self.expects(:selinux_support?).returns true
- self.expects(:execute).with(["/usr/bin/chcon","-h","-r","role_r","/foo"]).returns 0
+ Selinux.expects(:lgetfilecon).with("/foo").returns [0, "user_u:foo:type_t:s0"]
+ Selinux.expects(:lsetfilecon).with("/foo", "user_u:role_r:type_t:s0").returns 0
set_selinux_context("/foo", "role_r", :selrole).should be_true
end
- it "should use chcon to set type_t type context" do
+ it "should use lsetfilecon to set type_t type context" do
self.expects(:selinux_support?).returns true
- self.expects(:execute).with(["/usr/bin/chcon","-h","-t","type_t","/foo"]).returns 0
+ Selinux.expects(:lgetfilecon).with("/foo").returns [0, "user_u:role_r:foo:s0"]
+ Selinux.expects(:lsetfilecon).with("/foo", "user_u:role_r:type_t:s0").returns 0
set_selinux_context("/foo", "type_t", :seltype).should be_true
end
- it "should use chcon to set s0:c3,c5 range context" do
+ it "should use lsetfilecon to set s0:c3,c5 range context" do
self.expects(:selinux_support?).returns true
- self.expects(:execute).with(["/usr/bin/chcon","-h","-l","s0:c3,c5","/foo"]).returns 0
+ Selinux.expects(:lgetfilecon).with("/foo").returns [0, "user_u:role_r:type_t:s0"]
+ Selinux.expects(:lsetfilecon).with("/foo", "user_u:role_r:type_t:s0:c3,c5").returns 0
set_selinux_context("/foo", "s0:c3,c5", :selrange).should be_true
end
end