diff options
| author | Max Martin <max@puppetlabs.com> | 2011-03-30 13:02:19 -0700 |
|---|---|---|
| committer | Max Martin <max@puppetlabs.com> | 2011-03-30 13:02:19 -0700 |
| commit | 9c06fbd762cddcc41a7185a36f2a8e72879125eb (patch) | |
| tree | bfd37ac5887307857d0b0d79a1db034010eed424 /spec/unit/parser | |
| parent | 4196699f5fbb90ceecbb709c8502622eaad39062 (diff) | |
| parent | 11309a214148abb2167c1bd0adba0e035b2d8384 (diff) | |
| download | puppet-9c06fbd762cddcc41a7185a36f2a8e72879125eb.tar.gz puppet-9c06fbd762cddcc41a7185a36f2a8e72879125eb.tar.xz puppet-9c06fbd762cddcc41a7185a36f2a8e72879125eb.zip | |
Merge branch 'next'
* next: (39 commits)
(#5908) Add support for new update-rc.d disable API
(#6830) Fix tests that depended on special inherited behavior
(#6830) Fix overly stubbed tests
(#6830) Fix instance_variables now comes back as symbols
(#6830) Fix badly stubbed Time object in test
(#6830) Fix MD5 handling to work with Ruby 1.9
(#6830) Fix File class scoping
(#6830) Handle case where array is actually a string
(#6830) Fix case where instance_variables returns symbols in Ruby 1.9
(#6862) Add a default subject for the mail_patches rake task
Fixed #6256 - Creation of rrd directory.
(#6855) ResourceType#search now accepts a regex
(#5477) Allow watch_file to watch non-existent files, especially site.pp
(#5477) Allow watch_file to watch non-existent files, especially site.pp
Fixing #6851 - ResourceType#find/search loads types
Fixing Module#path detection
Fixed #6850 - Clean up ResourceType#to_pson
(#6830) Fix stat method calls to not use an unneeded argument
(#4576) Raise an error when a node is classified into a non-existent class
Update CHANGELOG for 2.6.7
...
Diffstat (limited to 'spec/unit/parser')
| -rwxr-xr-x | spec/unit/parser/ast/casestatement_spec.rb | 26 | ||||
| -rwxr-xr-x | spec/unit/parser/compiler_spec.rb | 24 | ||||
| -rwxr-xr-x | spec/unit/parser/functions/create_resources_spec.rb | 135 | ||||
| -rwxr-xr-x | spec/unit/parser/lexer_spec.rb | 12 | ||||
| -rw-r--r-- | spec/unit/parser/type_loader_spec.rb | 97 |
5 files changed, 264 insertions, 30 deletions
diff --git a/spec/unit/parser/ast/casestatement_spec.rb b/spec/unit/parser/ast/casestatement_spec.rb index a77c04c43..bce3ad801 100755 --- a/spec/unit/parser/ast/casestatement_spec.rb +++ b/spec/unit/parser/ast/casestatement_spec.rb @@ -13,11 +13,14 @@ describe Puppet::Parser::AST::CaseStatement do @test = stub 'test' @test.stubs(:safeevaluate).with(@scope).returns("value") - @option1 = stub 'option1', :eachopt => nil, :default? => false - @option2 = stub 'option2', :eachopt => nil, :default? => false + @option1 = Puppet::Parser::AST::CaseOpt.new({}) + @option1.stubs(:eachopt) + @option1.stubs(:default?).returns false + @option2 = Puppet::Parser::AST::CaseOpt.new({}) + @option2.stubs(:eachopt) + @option2.stubs(:default?).returns false - @options = stub 'options' - @options.stubs(:each).multiple_yields(@option1, @option2) + @options = Puppet::Parser::AST::ASTArray.new(:children => [@option1, @option2]) @casestmt = Puppet::Parser::AST::CaseStatement.new :test => @test, :options => @options end @@ -29,8 +32,6 @@ describe Puppet::Parser::AST::CaseStatement do end it "should scan each option" do - @options.expects(:each).multiple_yields(@option1, @option2) - @casestmt.evaluate(@scope) end @@ -137,12 +138,15 @@ describe Puppet::Parser::AST::CaseStatement do options = tests.collect do |result, values| values = values.collect { |v| AST::Leaf.new :value => v } - AST::CaseOpt.new( - :value => AST::ASTArray.new(:children => values), - - :statements => AST::Leaf.new(:value => result)) + AST::CaseOpt.new( + :value => AST::ASTArray.new(:children => values), + :statements => AST::Leaf.new(:value => result) + ) end - options << AST::CaseOpt.new(:value => AST::Default.new(:value => "default"), :statements => AST::Leaf.new(:value => "default")) + options << AST::CaseOpt.new( + :value => AST::Default.new(:value => "default"), + :statements => AST::Leaf.new(:value => "default") + ) ast = nil param = AST::Variable.new(:value => "testparam") diff --git a/spec/unit/parser/compiler_spec.rb b/spec/unit/parser/compiler_spec.rb index 18f9a93b6..e4b18e14b 100755 --- a/spec/unit/parser/compiler_spec.rb +++ b/spec/unit/parser/compiler_spec.rb @@ -576,18 +576,16 @@ describe Puppet::Parser::Compiler do proc { @compiler.evaluate_classes(%w{one two}, scope) }.should raise_error(Puppet::DevError) end - it "should tag the catalog with the name of each not-found class" do - @compiler.catalog.expects(:tag).with("notfound") + it "should raise an error if a class is not found" do @scope.expects(:find_hostclass).with("notfound").returns(nil) - @compiler.evaluate_classes(%w{notfound}, @scope) + lambda{ @compiler.evaluate_classes(%w{notfound}, @scope) }.should raise_error(Puppet::Error, /Could not find class/) end - # I wish it would fail - it "should log when it can't find class" do + + it "should raise an error when it can't find class" do klasses = {'foo'=>nil} @node.classes = klasses @compiler.topscope.stubs(:find_hostclass).with('foo').returns(nil) - Puppet.expects(:info).with('Could not find class foo for testnode') - @compiler.compile + lambda{ @compiler.compile }.should raise_error(Puppet::Error, /Could not find class foo for testnode/) end end @@ -714,18 +712,6 @@ describe Puppet::Parser::Compiler do Puppet::Parser::Resource.expects(:new).never @compiler.evaluate_classes(%w{MyClass}, @scope, false) end - - it "should return the list of found classes" do - @compiler.catalog.stubs(:tag) - - @compiler.stubs(:add_resource) - @scope.stubs(:find_hostclass).with("notfound").returns(nil) - @scope.stubs(:class_scope).with(@class) - - Puppet::Parser::Resource.stubs(:new).returns(@resource) - @class.stubs :ensure_in_catalog - @compiler.evaluate_classes(%w{myclass notfound}, @scope).should == %w{myclass} - end end describe "when evaluating AST nodes with no AST nodes present" do diff --git a/spec/unit/parser/functions/create_resources_spec.rb b/spec/unit/parser/functions/create_resources_spec.rb new file mode 100755 index 000000000..d4095b777 --- /dev/null +++ b/spec/unit/parser/functions/create_resources_spec.rb @@ -0,0 +1,135 @@ +require 'puppet' +require File.dirname(__FILE__) + '/../../../spec_helper' + +describe 'function for dynamically creating resources' do + + def get_scope + @topscope = Puppet::Parser::Scope.new + # This is necessary so we don't try to use the compiler to discover our parent. + @topscope.parent = nil + @scope = Puppet::Parser::Scope.new + @scope.compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("floppy", :environment => 'production')) + @scope.parent = @topscope + @compiler = @scope.compiler + end + before :each do + get_scope + Puppet::Parser::Functions.function(:create_resources) + end + + it "should exist" do + Puppet::Parser::Functions.function(:create_resources).should == "function_create_resources" + end + it 'should require two arguments' do + lambda { @scope.function_create_resources(['foo']) }.should raise_error(ArgumentError, 'create_resources(): wrong number of arguments (1; must be 2)') + end + describe 'when creating native types' do + before :each do + Puppet[:code]='notify{test:}' + get_scope + @scope.resource=Puppet::Parser::Resource.new('class', 't', :scope => @scope) + end + it 'empty hash should not cause resources to be added' do + @scope.function_create_resources(['file', {}]) + @compiler.catalog.resources.size == 1 + end + it 'should be able to add' do + @scope.function_create_resources(['file', {'/etc/foo'=>{'ensure'=>'present'}}]) + @compiler.catalog.resource(:file, "/etc/foo")['ensure'].should == 'present' + end + it 'should accept multiple types' do + type_hash = {} + type_hash['foo'] = {'message' => 'one'} + type_hash['bar'] = {'message' => 'two'} + @scope.function_create_resources(['notify', type_hash]) + @compiler.catalog.resource(:notify, "foo")['message'].should == 'one' + @compiler.catalog.resource(:notify, "bar")['message'].should == 'two' + end + it 'should fail to add non-existing type' do + lambda { @scope.function_create_resources(['foo', {}]) }.should raise_error(ArgumentError, 'could not create resource of unknown type foo') + end + it 'should be able to add edges' do + @scope.function_create_resources(['notify', {'foo'=>{'require' => 'Notify[test]'}}]) + @scope.compiler.compile + edge = @scope.compiler.catalog.to_ral.relationship_graph.edges.detect do |edge| + edge.source.title == 'test' + end + edge.source.title.should == 'test' + edge.target.title.should == 'foo' + end + end + describe 'when dynamically creating resource types' do + before :each do + Puppet[:code]= +'define foo($one){notify{$name: message => $one}} +notify{test:} +' + get_scope + @scope.resource=Puppet::Parser::Resource.new('class', 't', :scope => @scope) + Puppet::Parser::Functions.function(:create_resources) + end + it 'should be able to create defined resoure types' do + @scope.function_create_resources(['foo', {'blah'=>{'one'=>'two'}}]) + # still have to compile for this to work... + # I am not sure if this constraint ruins the tests + @scope.compiler.compile + @compiler.catalog.resource(:notify, "blah")['message'].should == 'two' + end + it 'should fail if defines are missing params' do + @scope.function_create_resources(['foo', {'blah'=>{}}]) + lambda { @scope.compiler.compile }.should raise_error(Puppet::ParseError, 'Must pass one to Foo[blah] at line 1') + end + it 'should be able to add multiple defines' do + hash = {} + hash['blah'] = {'one' => 'two'} + hash['blaz'] = {'one' => 'three'} + @scope.function_create_resources(['foo', hash]) + # still have to compile for this to work... + # I am not sure if this constraint ruins the tests + @scope.compiler.compile + @compiler.catalog.resource(:notify, "blah")['message'].should == 'two' + @compiler.catalog.resource(:notify, "blaz")['message'].should == 'three' + end + it 'should be able to add edges' do + @scope.function_create_resources(['foo', {'blah'=>{'one'=>'two', 'require' => 'Notify[test]'}}]) + @scope.compiler.compile + edge = @scope.compiler.catalog.to_ral.relationship_graph.edges.detect do |edge| + edge.source.title == 'test' + end + edge.source.title.should == 'test' + edge.target.title.should == 'blah' + @compiler.catalog.resource(:notify, "blah")['message'].should == 'two' + end + end + describe 'when creating classes' do + before :each do + Puppet[:code]= +'class bar($one){notify{test: message => $one}} +notify{tester:} +' + get_scope + @scope.resource=Puppet::Parser::Resource.new('class', 't', :scope => @scope) + Puppet::Parser::Functions.function(:create_resources) + end + it 'should be able to create classes' do + @scope.function_create_resources(['class', {'bar'=>{'one'=>'two'}}]) + @scope.compiler.compile + @compiler.catalog.resource(:notify, "test")['message'].should == 'two' + @compiler.catalog.resource(:class, "bar").should_not be_nil#['message'].should == 'two' + end + it 'should fail to create non-existing classes' do + lambda { @scope.function_create_resources(['class', {'blah'=>{'one'=>'two'}}]) }.should raise_error(ArgumentError ,'could not find hostclass blah') + end + it 'should be able to add edges' do + @scope.function_create_resources(['class', {'bar'=>{'one'=>'two', 'require' => 'Notify[tester]'}}]) + @scope.compiler.compile + edge = @scope.compiler.catalog.to_ral.relationship_graph.edges.detect do |e| + e.source.title == 'tester' + end + edge.source.title.should == 'tester' + edge.target.title.should == 'test' + #@compiler.catalog.resource(:notify, "blah")['message'].should == 'two' + end + + end +end diff --git a/spec/unit/parser/lexer_spec.rb b/spec/unit/parser/lexer_spec.rb index 96df61348..bc9e22e48 100755 --- a/spec/unit/parser/lexer_spec.rb +++ b/spec/unit/parser/lexer_spec.rb @@ -676,3 +676,15 @@ describe "Puppet::Parser::Lexer in the old tests when lexing example files" do end end end + +describe "when trying to lex an non-existent file" do + include PuppetSpec::Files + + it "should return an empty list of tokens" do + lexer = Puppet::Parser::Lexer.new + lexer.file = nofile = tmpfile('lexer') + File.exists?(nofile).should == false + + lexer.fullscan.should == [[false,false]] + end +end diff --git a/spec/unit/parser/type_loader_spec.rb b/spec/unit/parser/type_loader_spec.rb index bd41adfb6..12bc1ccd6 100644 --- a/spec/unit/parser/type_loader_spec.rb +++ b/spec/unit/parser/type_loader_spec.rb @@ -93,6 +93,103 @@ describe Puppet::Parser::TypeLoader do end end + describe "when importing all" do + before do + @base = tmpdir("base") + + # Create two module path directories + @modulebase1 = File.join(@base, "first") + FileUtils.mkdir_p(@modulebase1) + @modulebase2 = File.join(@base, "second") + FileUtils.mkdir_p(@modulebase2) + + Puppet[:modulepath] = "#{@modulebase1}:#{@modulebase2}" + end + + def mk_module(basedir, name) + module_dir = File.join(basedir, name) + + # Go ahead and make our manifest directory + FileUtils.mkdir_p(File.join(module_dir, "manifests")) + + return Puppet::Module.new(name) + end + + # We have to pass the base path so that we can + # write to modules that are in the second search path + def mk_manifests(base, mod, type, files) + exts = {"ruby" => ".rb", "puppet" => ".pp"} + files.collect do |file| + name = mod.name + "::" + file.gsub("/", "::") + path = File.join(base, mod.name, "manifests", file + exts[type]) + FileUtils.mkdir_p(File.split(path)[0]) + + # write out the class + if type == "ruby" + File.open(path, "w") { |f| f.print "hostclass '#{name}' do\nend" } + else + File.open(path, "w") { |f| f.print "class #{name} {}" } + end + name + end + end + + it "should load all puppet manifests from all modules in the specified environment" do + @module1 = mk_module(@modulebase1, "one") + @module2 = mk_module(@modulebase2, "two") + + mk_manifests(@modulebase1, @module1, "puppet", %w{a b}) + mk_manifests(@modulebase2, @module2, "puppet", %w{c d}) + + @loader.import_all + + @loader.environment.known_resource_types.hostclass("one::a").should be_instance_of(Puppet::Resource::Type) + @loader.environment.known_resource_types.hostclass("one::b").should be_instance_of(Puppet::Resource::Type) + @loader.environment.known_resource_types.hostclass("two::c").should be_instance_of(Puppet::Resource::Type) + @loader.environment.known_resource_types.hostclass("two::d").should be_instance_of(Puppet::Resource::Type) + end + + it "should load all ruby manifests from all modules in the specified environment" do + @module1 = mk_module(@modulebase1, "one") + @module2 = mk_module(@modulebase2, "two") + + mk_manifests(@modulebase1, @module1, "ruby", %w{a b}) + mk_manifests(@modulebase2, @module2, "ruby", %w{c d}) + + @loader.import_all + + @loader.environment.known_resource_types.hostclass("one::a").should be_instance_of(Puppet::Resource::Type) + @loader.environment.known_resource_types.hostclass("one::b").should be_instance_of(Puppet::Resource::Type) + @loader.environment.known_resource_types.hostclass("two::c").should be_instance_of(Puppet::Resource::Type) + @loader.environment.known_resource_types.hostclass("two::d").should be_instance_of(Puppet::Resource::Type) + end + + it "should not load manifests from duplicate modules later in the module path" do + @module1 = mk_module(@modulebase1, "one") + + # duplicate + @module2 = mk_module(@modulebase2, "one") + + mk_manifests(@modulebase1, @module1, "puppet", %w{a}) + mk_manifests(@modulebase2, @module2, "puppet", %w{c}) + + @loader.import_all + + @loader.environment.known_resource_types.hostclass("one::c").should be_nil + end + + it "should load manifests from subdirectories" do + @module1 = mk_module(@modulebase1, "one") + + mk_manifests(@modulebase1, @module1, "puppet", %w{a a/b a/b/c}) + + @loader.import_all + + @loader.environment.known_resource_types.hostclass("one::a::b").should be_instance_of(Puppet::Resource::Type) + @loader.environment.known_resource_types.hostclass("one::a::b::c").should be_instance_of(Puppet::Resource::Type) + end + end + describe "when parsing a file" do before do @parser = Puppet::Parser::Parser.new(@loader.environment) |
