summaryrefslogtreecommitdiffstats
path: root/spec/unit/parser
diff options
context:
space:
mode:
authorMax Martin <max@puppetlabs.com>2011-03-30 13:02:19 -0700
committerMax Martin <max@puppetlabs.com>2011-03-30 13:02:19 -0700
commit9c06fbd762cddcc41a7185a36f2a8e72879125eb (patch)
treebfd37ac5887307857d0b0d79a1db034010eed424 /spec/unit/parser
parent4196699f5fbb90ceecbb709c8502622eaad39062 (diff)
parent11309a214148abb2167c1bd0adba0e035b2d8384 (diff)
downloadpuppet-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-xspec/unit/parser/ast/casestatement_spec.rb26
-rwxr-xr-xspec/unit/parser/compiler_spec.rb24
-rwxr-xr-xspec/unit/parser/functions/create_resources_spec.rb135
-rwxr-xr-xspec/unit/parser/lexer_spec.rb12
-rw-r--r--spec/unit/parser/type_loader_spec.rb97
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)