diff options
Diffstat (limited to 'spec/lib')
-rw-r--r-- | spec/lib/matchers/resource.rb | 1 | ||||
-rw-r--r-- | spec/lib/puppet_spec/compiler.rb | 17 | ||||
-rwxr-xr-x | spec/lib/puppet_spec/files.rb | 10 | ||||
-rw-r--r-- | spec/lib/puppet_spec/language.rb | 74 | ||||
-rw-r--r-- | spec/lib/puppet_spec/matchers.rb | 91 | ||||
-rw-r--r-- | spec/lib/puppet_spec/module_tool/stub_source.rb | 3 |
6 files changed, 162 insertions, 34 deletions
diff --git a/spec/lib/matchers/resource.rb b/spec/lib/matchers/resource.rb index 4498f959e..fc305d0d2 100644 --- a/spec/lib/matchers/resource.rb +++ b/spec/lib/matchers/resource.rb @@ -64,4 +64,5 @@ module Matchers; module Resource @mismatch.empty? ? @matcher.failure_message_for_should : @mismatch end end + module_function :have_resource end; end diff --git a/spec/lib/puppet_spec/compiler.rb b/spec/lib/puppet_spec/compiler.rb index cf4851807..4757705aa 100644 --- a/spec/lib/puppet_spec/compiler.rb +++ b/spec/lib/puppet_spec/compiler.rb @@ -1,7 +1,10 @@ module PuppetSpec::Compiler + module_function + def compile_to_catalog(string, node = Puppet::Node.new('foonode')) Puppet[:code] = string - Puppet::Parser::Compiler.compile(node) + # see lib/puppet/indirector/catalog/compiler.rb#filter + Puppet::Parser::Compiler.compile(node).filter { |r| r.virtual? } end def compile_to_ral(manifest) @@ -19,7 +22,11 @@ module PuppetSpec::Compiler end def apply_compiled_manifest(manifest, prioritizer = Puppet::Graph::SequentialPrioritizer.new) - transaction = Puppet::Transaction.new(compile_to_ral(manifest), + catalog = compile_to_ral(manifest) + if block_given? + catalog.resources.each { |res| yield res } + end + transaction = Puppet::Transaction.new(catalog, Puppet::Transaction::Report.new("apply"), prioritizer) transaction.evaluate @@ -28,6 +35,12 @@ module PuppetSpec::Compiler transaction end + def apply_with_error_check(manifest) + apply_compiled_manifest(manifest) do |res| + res.expects(:err).never + end + end + def order_resources_traversed_in(relationships) order_seen = [] relationships.traverse { |resource| order_seen << resource.ref } diff --git a/spec/lib/puppet_spec/files.rb b/spec/lib/puppet_spec/files.rb index 1e1076b91..312c4fc95 100755 --- a/spec/lib/puppet_spec/files.rb +++ b/spec/lib/puppet_spec/files.rb @@ -75,4 +75,14 @@ module PuppetSpec::Files $global_tempfiles ||= [] $global_tempfiles << tmp end + + def expect_file_mode(file, mode) + actual_mode = "%o" % Puppet::FileSystem.stat(file).mode + target_mode = if Puppet.features.microsoft_windows? + mode + else + "10" + "%04i" % mode.to_i + end + actual_mode.should == target_mode + end end diff --git a/spec/lib/puppet_spec/language.rb b/spec/lib/puppet_spec/language.rb new file mode 100644 index 000000000..197c4b827 --- /dev/null +++ b/spec/lib/puppet_spec/language.rb @@ -0,0 +1,74 @@ +require 'puppet_spec/compiler' +require 'matchers/resource' + +module PuppetSpec::Language + extend RSpec::Matchers::DSL + + def produces(expectations) + calledFrom = caller + expectations.each do |manifest, resources| + it "evaluates #{manifest} to produce #{resources}" do + begin + case resources + when String + node = Puppet::Node.new('specification') + Puppet[:code] = manifest + compiler = Puppet::Parser::Compiler.new(node) + evaluator = Puppet::Pops::Parser::EvaluatingParser.new() + + # see lib/puppet/indirector/catalog/compiler.rb#filter + catalog = compiler.compile.filter { |r| r.virtual? } + + compiler.send(:instance_variable_set, :@catalog, catalog) + + expect(evaluator.evaluate_string(compiler.topscope, resources)).to eq(true) + when Array + catalog = PuppetSpec::Compiler.compile_to_catalog(manifest) + + if resources.empty? + base_resources = ["Class[Settings]", "Class[main]", "Stage[main]"] + expect(catalog.resources.collect(&:ref) - base_resources).to eq([]) + else + resources.each do |reference| + if reference.is_a?(Array) + matcher = Matchers::Resource.have_resource(reference[0]) + reference[1].each do |name, value| + matcher = matcher.with_parameter(name, value) + end + else + matcher = Matchers::Resource.have_resource(reference) + end + + expect(catalog).to matcher + end + end + else + raise "Unsupported creates specification: #{resources.inspect}" + end + rescue Puppet::Error, RSpec::Expectations::ExpectationNotMetError => e + # provide the backtrace from the caller, or it is close to impossible to find some originators + e.set_backtrace(calledFrom) + raise + end + + end + end + end + + def fails(expectations) + calledFrom = caller + expectations.each do |manifest, pattern| + it "fails to evaluate #{manifest} with message #{pattern}" do + begin + expect do + PuppetSpec::Compiler.compile_to_catalog(manifest) + end.to raise_error(Puppet::Error, pattern) + rescue RSpec::Expectations::ExpectationNotMetError => e + # provide the backgrace from the caller, or it is close to impossible to find some originators + e.set_backtrace(calledFrom) + raise + end + end + end + end +end diff --git a/spec/lib/puppet_spec/matchers.rb b/spec/lib/puppet_spec/matchers.rb index 448bd1811..c01d8e89d 100644 --- a/spec/lib/puppet_spec/matchers.rb +++ b/spec/lib/puppet_spec/matchers.rb @@ -44,63 +44,82 @@ RSpec::Matchers.define :exit_with do |expected| end end -class HavePrintedMatcher - attr_accessor :expected, :actual - def initialize(expected) - case expected +RSpec::Matchers.define :have_printed do |expected| + + case expected when String, Regexp - @expected = expected + expected = expected else - @expected = expected.to_s + expected = expected.to_s + end + + chain :and_exit_with do |code| + @expected_exit_code = code + end + + define_method :matches_exit_code? do |actual| + @expected_exit_code.nil? || @expected_exit_code == actual + end + + define_method :matches_output? do |actual| + return false unless actual + case expected + when String + actual.include?(expected) + when Regexp + expected.match(actual) + else + raise ArgumentError, "No idea how to match a #{actual.class.name}" end end - def matches?(block) + match do |block| + $stderr = $stdout = StringIO.new + $stdout.set_encoding('UTF-8') if $stdout.respond_to?(:set_encoding) + begin - $stderr = $stdout = StringIO.new - $stdout.set_encoding('UTF-8') if $stdout.respond_to?(:set_encoding) block.call + rescue SystemExit => e + raise unless @expected_exit_code + @actual_exit_code = e.status + ensure $stdout.rewind @actual = $stdout.read - ensure + $stdout = STDOUT $stderr = STDERR end - if @actual then - case @expected - when String - @actual.include? @expected - when Regexp - @expected.match @actual - end - else - false - end + matches_output?(@actual) && matches_exit_code?(@actual_exit_code) end - def failure_message_for_should - if @actual.nil? then - "expected #{@expected.inspect}, but nothing was printed" + failure_message_for_should do |actual| + if actual.nil? then + "expected #{expected.inspect}, but nothing was printed" else - "expected #{@expected.inspect} to be printed; got:\n#{@actual}" + if !@expected_exit_code.nil? && matches_output?(actual) + "expected exit with code #{@expected_exit_code} but " + + (@actual_exit_code.nil? ? " exit was not called" : "exited with #{@actual_exit_code} instead") + else + "expected #{expected.inspect} to be printed; got:\n#{actual}" + end end end - def failure_message_for_should_not - "expected #{@expected.inspect} to not be printed; got:\n#{@actual}" + failure_message_for_should_not do |actual| + if @expected_exit_code && matches_exit_code?(@actual_exit_code) + "expected exit code to not be #{@actual_exit_code}" + else + "expected #{expected.inspect} to not be printed; got:\n#{actual}" + end end - def description - "expect #{@expected.inspect} to be printed" + description do + "expect #{expected.inspect} to be printed" + (@expected_exit_code.nil ? '' : " with exit code #{@expected_exit_code}") end end -def have_printed(what) - HavePrintedMatcher.new(what) -end - RSpec::Matchers.define :equal_attributes_of do |expected| match do |actual| actual.instance_variables.all? do |attr| @@ -109,6 +128,14 @@ RSpec::Matchers.define :equal_attributes_of do |expected| end end +RSpec::Matchers.define :equal_resource_attributes_of do |expected| + match do |actual| + actual.keys do |attr| + actual[attr] == expected[attr] + end + end +end + RSpec::Matchers.define :be_one_of do |*expected| match do |actual| expected.include? actual diff --git a/spec/lib/puppet_spec/module_tool/stub_source.rb b/spec/lib/puppet_spec/module_tool/stub_source.rb index 5cee57c10..8b5f8bbe1 100644 --- a/spec/lib/puppet_spec/module_tool/stub_source.rb +++ b/spec/lib/puppet_spec/module_tool/stub_source.rb @@ -100,6 +100,9 @@ module PuppetSpec "0.0.2" => { "pmtacceptance/stdlib" => ">= 2.2.0", "pmtacceptance/mysql" => ">= 0.0.1" }, "0.0.1" => { "pmtacceptance/stdlib" => ">= 2.2.0" }, }, + 'puppetlabs-oneversion' => { + "0.0.1" => {} + } } @available_releases.each do |name, versions| |