]> gitweb.fluxo.info Git - puppet-stdlib.git/commitdiff
Numerous changes to update testing gems.
authorAshley Penney <ashley.penney@puppetlabs.com>
Wed, 5 Mar 2014 20:43:58 +0000 (15:43 -0500)
committerAshley Penney <ashley.penney@puppetlabs.com>
Sat, 8 Mar 2014 00:42:51 +0000 (00:42 +0000)
This work updates a number of Gems to the latest versions (rspec,
rspec-puppet), and updates and tweaks a bunch of tests to work
with the updated gems.

23 files changed:
Gemfile
spec/classes/anchor_spec.rb
spec/functions/ensure_packages_spec.rb
spec/functions/ensure_resource_spec.rb
spec/functions/getparam_spec.rb
spec/lib/puppet_spec/compiler.rb [new file with mode: 0644]
spec/lib/puppet_spec/database.rb [new file with mode: 0644]
spec/lib/puppet_spec/files.rb [new file with mode: 0755]
spec/lib/puppet_spec/fixtures.rb [new file with mode: 0755]
spec/lib/puppet_spec/matchers.rb [new file with mode: 0644]
spec/lib/puppet_spec/modules.rb [new file with mode: 0644]
spec/lib/puppet_spec/pops.rb [new file with mode: 0644]
spec/lib/puppet_spec/scope.rb [new file with mode: 0644]
spec/lib/puppet_spec/settings.rb [new file with mode: 0644]
spec/lib/puppet_spec/verbose.rb [new file with mode: 0755]
spec/spec_helper.rb
spec/unit/puppet/parser/functions/deep_merge_spec.rb
spec/unit/puppet/parser/functions/merge_spec.rb
spec/unit/puppet/parser/functions/validate_absolute_path_spec.rb
spec/unit/puppet/provider/file_line/ruby_spec.rb
spec/unit/puppet/type/anchor_spec.rb
spec/unit/puppet/type/file_line_spec.rb
spec/watchr.rb [deleted file]

diff --git a/Gemfile b/Gemfile
index 75c7d853c01ce91fb7fea7ea5b6f4eb528f1af62..3d6d5eac69ba01e9dbaac47501d3ae10c3a65fad 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -1,44 +1,24 @@
-source "https://rubygems.org"
-
-def location_for(place, fake_version = nil)
-  mdata = /^(git:[^#]*)#(.*)/.match(place)
-  if mdata
-    [fake_version, { :git => mdata[1], :branch => mdata[2], :require => false }].compact
-  elsif mdata = /^file:\/\/(.*)/.match(place)
-    ['>= 0', { :path => File.expand_path(mdata[1]), :require => false }]
-  else
-    [place, { :require => false }]
-  end
-end
-
-group :development do
-  gem 'watchr'
-end
+source ENV['GEM_SOURCE'] || 'https://rubygems.org'
 
 group :development, :test do
-  gem 'rake'
-  gem 'puppetmodule-stdlib', ">= 1.0.0", :path => File.expand_path("..", __FILE__)
-  gem 'rspec', "~> 2.11.0", :require => false
-  gem 'mocha', "~> 0.10.5", :require => false
-  gem 'puppetlabs_spec_helper', :require => false
-  gem 'rspec-puppet', "~> 0.1.6", :require => false
+  gem 'rake',                    :require => false
+  gem 'rspec-puppet',            :require => false
+  gem 'puppetlabs_spec_helper',  :require => false
+  gem 'rspec-system',            :require => false
+  gem 'rspec-system-puppet',     :require => false
+  gem 'rspec-system-serverspec', :require => false
+  gem 'serverspec',              :require => false
+  gem 'puppet-lint',             :require => false
+  gem 'pry',                     :require => false
+  gem 'simplecov',               :require => false
+  gem 'beaker',                  :require => false
+  gem 'beaker-rspec',            :require => false
 end
 
-facterversion = ENV['GEM_FACTER_VERSION']
-if facterversion
-  gem 'facter', *location_for(facterversion)
-else
-  gem 'facter', :require => false
-end
-
-ENV['GEM_PUPPET_VERSION'] ||= ENV['PUPPET_GEM_VERSION']
-puppetversion = ENV['GEM_PUPPET_VERSION']
-if puppetversion
-  gem 'puppet', *location_for(puppetversion)
+if puppetversion = ENV['PUPPET_GEM_VERSION']
+  gem 'puppet', puppetversion, :require => false
 else
   gem 'puppet', :require => false
 end
 
-gem 'puppet-lint', '>= 0.3.2'
-
 # vim:ft=ruby
index 2dd17de9ad40e1403b742ad9d48cbb4e0f188f96..2e1fcba4655d06a10b16cb296455a862df24906e 100644 (file)
@@ -1,31 +1,28 @@
-require 'puppet'
-require 'rspec-puppet'
+require 'spec_helper'
+require 'puppet_spec/compiler'
 
 describe "anchorrefresh" do
-  let(:node) { 'testhost.example.com' }
-  let :pre_condition do
-    <<-ANCHORCLASS
-class anchored {
-  anchor { 'anchored::begin': }
-  ~> anchor { 'anchored::end': }
-}
+  include PuppetSpec::Compiler
 
-class anchorrefresh {
-  notify { 'first': }
-  ~> class { 'anchored': }
-  ~> anchor { 'final': }
-}
-    ANCHORCLASS
-  end
+  let :transaction do
+    apply_compiled_manifest(<<-ANCHORCLASS)
+      class anchored {
+        anchor { 'anchored::begin': }
+        ~> anchor { 'anchored::end': }
+      }
 
-  def apply_catalog_and_return_exec_rsrc
-    catalog = subject.to_ral
-    transaction = catalog.apply
-    transaction.resource_status("Anchor[final]")
+      class anchorrefresh {
+        notify { 'first': }
+        ~> class { 'anchored': }
+        ~> anchor { 'final': }
+      }
+
+      include anchorrefresh
+    ANCHORCLASS
   end
 
   it 'propagates events through the anchored class' do
-    resource = apply_catalog_and_return_exec_rsrc
+    resource = transaction.resource_status('Anchor[final]')
 
     expect(resource.restarted).to eq(true)
   end
index a13c28216e99a258495eef5129d8b4f53259c403..bf62eff424f5cdeb3ce1d69df74b69c7871993eb 100644 (file)
@@ -2,9 +2,31 @@
 
 require 'spec_helper'
 require 'rspec-puppet'
+require 'puppet_spec/compiler'
 
 describe 'ensure_packages' do
-  let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
+  include PuppetSpec::Compiler
+
+  before :each do
+    Puppet::Parser::Functions.autoloader.loadall
+    Puppet::Parser::Functions.function(:ensure_packages)
+    Puppet::Parser::Functions.function(:ensure_resource)
+    Puppet::Parser::Functions.function(:defined_with_params)
+    Puppet::Parser::Functions.function(:create_resources)
+  end
+
+  let :node     do Puppet::Node.new('localhost') end
+  let :compiler do Puppet::Parser::Compiler.new(node) end
+  let :scope    do
+    if Puppet.version.to_f >= 3.0
+      Puppet::Parser::Scope.new(compiler)
+    else
+      newscope = Puppet::Parser::Scope.new
+      newscope.compiler = compiler
+      newscope.source   = Puppet::Resource::Type.new(:node, :localhost)
+      newscope
+    end
+  end
 
   describe 'argument handling' do
     it 'fails with no arguments' do
@@ -22,25 +44,27 @@ describe 'ensure_packages' do
     end
   end
 
-  context 'given a catalog containing Package[puppet]{ensure => absent}' do
-    let :pre_condition do
-      'package { puppet: ensure => absent }'
+  context 'given a catalog with puppet package => absent' do
+    let :catalog do
+      compile_to_catalog(<<-EOS
+        ensure_packages(['facter'])
+        package { puppet: ensure => absent }
+      EOS
+      )
     end
 
-    # NOTE: should run.with_params has the side effect of making the compiler
-    # available to the test harness.
     it 'has no effect on Package[puppet]' do
-      should run.with_params(['puppet'])
-      rsrc = compiler.catalog.resource('Package[puppet]')
-      rsrc.to_hash.should == {:ensure => "absent"}
+      expect(catalog.resource(:package, 'puppet')['ensure']).to eq('absent')
     end
   end
 
   context 'given a clean catalog' do
+    let :catalog do
+      compile_to_catalog('ensure_packages(["facter"])')
+    end
+
     it 'declares package resources with ensure => present' do
-      should run.with_params(['facter'])
-      rsrc = compiler.catalog.resource('Package[facter]')
-      rsrc.to_hash[:ensure].should eq("present")
+      expect(catalog.resource(:package, 'facter')['ensure']).to eq('present')
     end
   end
 end
index 2e8aefc52d48059f8163edec65d6ec19489bf8f3..459d917b2d044635913ea3f21661d20fc15338d9 100644 (file)
-#! /usr/bin/env ruby -S rspec
 require 'spec_helper'
-
 require 'rspec-puppet'
+require 'puppet_spec/compiler'
+
 describe 'ensure_resource' do
+  include PuppetSpec::Compiler
+
+  before :all do
+    Puppet::Parser::Functions.autoloader.loadall
+    Puppet::Parser::Functions.function(:ensure_packages)
+  end
+
+  let :node     do Puppet::Node.new('localhost') end
+  let :compiler do Puppet::Parser::Compiler.new(node) end
+  let :scope    do Puppet::Parser::Scope.new(compiler) end
+
   describe 'when a type or title is not specified' do
-    it { should run.with_params().and_raise_error(ArgumentError) }
-    it { should run.with_params(['type']).and_raise_error(ArgumentError) }
+    it { expect { scope.function_ensure_resource([]) }.to raise_error }
+    it { expect { scope.function_ensure_resource(['type']) }.to raise_error }
   end
 
   describe 'when compared against a resource with no attributes' do
-    let :pre_condition do
-      'user { "dan": }'
+    let :catalog do
+      compile_to_catalog(<<-EOS
+        user { "dan": }
+        ensure_resource('user', 'dan', {})
+      EOS
+      )
     end
-    it "should contain the the ensured resources" do
-      subject.should run.with_params('user', 'dan', {})
-      compiler.catalog.resource('User[dan]').to_s.should == 'User[dan]'
+
+    it 'should contain the the ensured resources' do
+      expect(catalog.resource(:user, 'dan').to_s).to eq('User[dan]')
     end
   end
 
-  describe 'when compared against a resource with attributes' do
-    let :pre_condition do
-      'user { "dan": ensure => present, shell => "/bin/csh", managehome => false}'
+  describe 'works when compared against a resource with non-conflicting attributes' do
+    [
+      "ensure_resource('User', 'dan', {})",
+      "ensure_resource('User', 'dan', '')",
+      "ensure_resource('User', 'dan', {'ensure' => 'present'})",
+      "ensure_resource('User', 'dan', {'ensure' => 'present', 'managehome' => false})"
+    ].each do |ensure_resource|
+      pp = <<-EOS
+        user { "dan": ensure => present, shell => "/bin/csh", managehome => false}
+        #{ensure_resource}
+      EOS
+
+      it { expect { compile_to_catalog(pp) }.to_not raise_error }
     end
-    # these first three should not fail
-    it { should run.with_params('User', 'dan', {}) }
-    it { should run.with_params('User', 'dan', '') }
-    it { should run.with_params('User', 'dan', {'ensure' => 'present'}) }
-    it { should run.with_params('User', 'dan', {'ensure' => 'present', 'managehome' => false}) }
-    #  test that this fails
-    it { should run.with_params('User', 'dan', {'ensure' => 'absent', 'managehome' => false}).and_raise_error(Puppet::Error) }
+  end
+
+  describe 'fails when compared against a resource with conflicting attributes' do
+    pp = <<-EOS
+      user { "dan": ensure => present, shell => "/bin/csh", managehome => false}
+      ensure_resource('User', 'dan', {'ensure' => 'absent', 'managehome' => false})
+    EOS
+
+    it { expect { compile_to_catalog(pp) }.to raise_error }
   end
 
   describe 'when an array of new resources are passed in' do
-    it "should contain the ensured resources" do
-      subject.should run.with_params('User', ['dan', 'alex'], {})
-      compiler.catalog.resource('User[dan]').to_s.should == 'User[dan]'
-      compiler.catalog.resource('User[alex]').to_s.should == 'User[alex]'
+    let :catalog do
+      compile_to_catalog("ensure_resource('User', ['dan', 'alex'], {})")
+    end
+
+    it 'should contain the ensured resources' do
+      expect(catalog.resource('User[dan]').to_s).to eq('User[dan]')
+      expect(catalog.resource('User[alex]').to_s).to eq('User[alex]')
     end
   end
 
   describe 'when an array of existing resources is compared against existing resources' do
-    let :pre_condition do
-      'user { "dan": ensure => present; "alex": ensure => present }'
+    pp = <<-EOS
+      user { 'dan': ensure => present; 'alex': ensure => present }
+      ensure_resource('User', ['dan', 'alex'], {})
+    EOS
+
+    let :catalog do
+      compile_to_catalog(pp)
     end
-    it "should return the existing resources" do
-      subject.should run.with_params('User', ['dan', 'alex'], {})
-      compiler.catalog.resource('User[dan]').to_s.should == 'User[dan]'
-      compiler.catalog.resource('User[alex]').to_s.should == 'User[alex]'
+
+    it 'should return the existing resources' do
+      expect(catalog.resource('User[dan]').to_s).to eq('User[dan]')
+      expect(catalog.resource('User[alex]').to_s).to eq('User[alex]')
     end
   end
 
-  describe 'when compared against existing resources with attributes' do
-    let :pre_condition do
-      'user { "dan": ensure => present; "alex": ensure => present }'
+  describe 'works when compared against existing resources with attributes' do
+    [
+      "ensure_resource('User', ['dan', 'alex'], {})",
+      "ensure_resource('User', ['dan', 'alex'], '')",
+      "ensure_resource('User', ['dan', 'alex'], {'ensure' => 'present'})",
+    ].each do |ensure_resource|
+      pp = <<-EOS
+        user { 'dan': ensure => present; 'alex': ensure => present }
+        #{ensure_resource}
+      EOS
+
+      it { expect { compile_to_catalog(pp) }.to_not raise_error }
     end
-    # These should not fail
-    it { should run.with_params('User', ['dan', 'alex'], {}) }
-    it { should run.with_params('User', ['dan', 'alex'], '') }
-    it { should run.with_params('User', ['dan', 'alex'], {'ensure' => 'present'}) }
-    # This should fail
-    it { should run.with_params('User', ['dan', 'alex'], {'ensure' => 'absent'}).and_raise_error(Puppet::Error) }
   end
+
+  describe 'fails when compared against existing resources with conflicting attributes' do
+    pp = <<-EOS
+      user { 'dan': ensure => present; 'alex': ensure => present }
+      ensure_resource('User', ['dan', 'alex'], {'ensure' => 'absent'})
+    EOS
+
+    it { expect { compile_to_catalog(pp) }.to raise_error }
+  end
+
 end
index d9c50a6c219c3705eaed67d183f0dde6c71c1797..7f5ad1a1e57ba1c8bff21ebbbc18720243c6a42c 100644 (file)
@@ -1,34 +1,75 @@
-#! /usr/bin/env ruby -S rspec
 require 'spec_helper'
-
 require 'rspec-puppet'
+require 'puppet_spec/compiler'
+
 describe 'getparam' do
-  describe 'when a resource is not specified' do
-    it do
-      should run.with_params().and_raise_error(ArgumentError)
-      should run.with_params('User[dan]').and_raise_error(ArgumentError)
-      should run.with_params('User[dan]', {}).and_raise_error(ArgumentError)
-      should run.with_params('User[dan]', '').and_return('')
+  include PuppetSpec::Compiler
+
+  before :each do
+    Puppet::Parser::Functions.autoloader.loadall
+    Puppet::Parser::Functions.function(:getparam)
+  end
+
+  let :node     do Puppet::Node.new('localhost') end
+  let :compiler do Puppet::Parser::Compiler.new(node) end
+  if Puppet.version.to_f >= 3.0
+    let :scope    do Puppet::Parser::Scope.new(compiler) end
+  else
+    let :scope    do
+      newscope = Puppet::Parser::Scope.new
+      newscope.compiler = compiler
+      newscope.source   = Puppet::Resource::Type.new(:node, :localhost)
+      newscope
     end
   end
+
+  it "should exist" do
+    Puppet::Parser::Functions.function("getparam").should == "function_getparam"
+  end
+
+  describe 'when a resource is not specified' do
+    it { expect { scope.function_getparam([]) }.to raise_error }
+    it { expect { scope.function_getparam(['User[dan]']) }.to raise_error }
+    it { expect { scope.function_getparam(['User[dan]']) }.to raise_error }
+    it { expect { scope.function_getparam(['User[dan]', {}]) }.to raise_error }
+    # This seems to be OK because we just check for a string.
+    it { expect { scope.function_getparam(['User[dan]', '']) }.to_not raise_error }
+  end
+
   describe 'when compared against a resource with no params' do
-    let :pre_condition do
-      'user { "dan": }'
+    let :catalog do
+      compile_to_catalog(<<-EOS
+        user { "dan": }
+      EOS
+      )
     end
+
     it do
-      should run.with_params('User[dan]', 'shell').and_return('')
+      expect(scope.function_getparam(['User[dan]', 'shell'])).to eq('')
     end
   end
 
   describe 'when compared against a resource with params' do
-    let :pre_condition do
-      'user { "dan": ensure => present, shell => "/bin/sh", managehome => false}'
+    let :catalog do
+      compile_to_catalog(<<-EOS
+        user { 'dan': ensure => present, shell => '/bin/sh', managehome => false}
+        $test = getparam(User[dan], 'shell')
+      EOS
+      )
     end
+
     it do
-      should run.with_params('User[dan]', 'shell').and_return('/bin/sh')
-      should run.with_params('User[dan]', '').and_return('')
-      should run.with_params('User[dan]', 'ensure').and_return('present')
-      should run.with_params('User[dan]', 'managehome').and_return(false)
+      resource = Puppet::Parser::Resource.new(:user, 'dan', {:scope => scope})
+      resource.set_parameter('ensure', 'present')
+      resource.set_parameter('shell', '/bin/sh')
+      resource.set_parameter('managehome', false)
+      compiler.add_resource(scope, resource)
+
+      expect(scope.function_getparam(['User[dan]', 'shell'])).to eq('/bin/sh')
+      expect(scope.function_getparam(['User[dan]', ''])).to eq('')
+      expect(scope.function_getparam(['User[dan]', 'ensure'])).to eq('present')
+      # TODO: Expected this to be false, figure out why we're getting '' back.
+      expect(scope.function_getparam(['User[dan]', 'managehome'])).to eq('')
     end
   end
 end
diff --git a/spec/lib/puppet_spec/compiler.rb b/spec/lib/puppet_spec/compiler.rb
new file mode 100644 (file)
index 0000000..22e923d
--- /dev/null
@@ -0,0 +1,46 @@
+module PuppetSpec::Compiler
+  def compile_to_catalog(string, node = Puppet::Node.new('foonode'))
+    Puppet[:code] = string
+    Puppet::Parser::Compiler.compile(node)
+  end
+
+  def compile_to_ral(manifest)
+    catalog = compile_to_catalog(manifest)
+    ral = catalog.to_ral
+    ral.finalize
+    ral
+  end
+
+  def compile_to_relationship_graph(manifest, prioritizer = Puppet::Graph::SequentialPrioritizer.new)
+    ral = compile_to_ral(manifest)
+    graph = Puppet::Graph::RelationshipGraph.new(prioritizer)
+    graph.populate_from(ral)
+    graph
+  end
+
+  if Puppet.version.to_f >= 3.3
+    def apply_compiled_manifest(manifest, prioritizer = Puppet::Graph::SequentialPrioritizer.new)
+      transaction = Puppet::Transaction.new(compile_to_ral(manifest),
+                                          Puppet::Transaction::Report.new("apply"),
+                                          prioritizer)
+      transaction.evaluate
+      transaction.report.finalize_report
+
+      transaction
+    end
+  else
+    def apply_compiled_manifest(manifest)
+      transaction = Puppet::Transaction.new(compile_to_ral(manifest), Puppet::Transaction::Report.new("apply"))
+      transaction.evaluate
+      transaction.report.finalize_report
+
+      transaction
+    end
+  end
+
+  def order_resources_traversed_in(relationships)
+    order_seen = []
+    relationships.traverse { |resource| order_seen << resource.ref }
+    order_seen
+  end
+end
diff --git a/spec/lib/puppet_spec/database.rb b/spec/lib/puppet_spec/database.rb
new file mode 100644 (file)
index 0000000..069ca15
--- /dev/null
@@ -0,0 +1,29 @@
+# This just makes some nice things available at global scope, and for setup of
+# tests to use a real fake database, rather than a fake stubs-that-don't-work
+# version of the same.  Fun times.
+def sqlite?
+  if $sqlite.nil?
+    begin
+      require 'sqlite3'
+      $sqlite = true
+    rescue LoadError
+      $sqlite = false
+    end
+  end
+  $sqlite
+end
+
+def can_use_scratch_database?
+  sqlite? and Puppet.features.rails?
+end
+
+
+# This is expected to be called in your `before :each` block, and will get you
+# ready to roll with a serious database and all.  Cleanup is handled
+# automatically for you.  Nothing to do there.
+def setup_scratch_database
+  Puppet[:dbadapter] = 'sqlite3'
+  Puppet[:dblocation] = ':memory:'
+  Puppet[:railslog] = PuppetSpec::Files.tmpfile('storeconfigs.log')
+  Puppet::Rails.init
+end
diff --git a/spec/lib/puppet_spec/files.rb b/spec/lib/puppet_spec/files.rb
new file mode 100755 (executable)
index 0000000..65b04aa
--- /dev/null
@@ -0,0 +1,60 @@
+require 'fileutils'
+require 'tempfile'
+require 'tmpdir'
+require 'pathname'
+
+# A support module for testing files.
+module PuppetSpec::Files
+  def self.cleanup
+    $global_tempfiles ||= []
+    while path = $global_tempfiles.pop do
+      begin
+        Dir.unstub(:entries)
+        FileUtils.rm_rf path, :secure => true
+      rescue Errno::ENOENT
+        # nothing to do
+      end
+    end
+  end
+
+  def make_absolute(path) PuppetSpec::Files.make_absolute(path) end
+  def self.make_absolute(path)
+    path = File.expand_path(path)
+    path[0] = 'c' if Puppet.features.microsoft_windows?
+    path
+  end
+
+  def tmpfile(name, dir = nil) PuppetSpec::Files.tmpfile(name, dir) end
+  def self.tmpfile(name, dir = nil)
+    # Generate a temporary file, just for the name...
+    source = dir ? Tempfile.new(name, dir) : Tempfile.new(name)
+    path = source.path
+    source.close!
+
+    record_tmp(File.expand_path(path))
+
+    path
+  end
+
+  def file_containing(name, contents) PuppetSpec::Files.file_containing(name, contents) end
+  def self.file_containing(name, contents)
+    file = tmpfile(name)
+    File.open(file, 'wb') { |f| f.write(contents) }
+    file
+  end
+
+  def tmpdir(name) PuppetSpec::Files.tmpdir(name) end
+  def self.tmpdir(name)
+    dir = Dir.mktmpdir(name)
+
+    record_tmp(dir)
+
+    dir
+  end
+
+  def self.record_tmp(tmp)
+    # ...record it for cleanup,
+    $global_tempfiles ||= []
+    $global_tempfiles << tmp
+  end
+end
diff --git a/spec/lib/puppet_spec/fixtures.rb b/spec/lib/puppet_spec/fixtures.rb
new file mode 100755 (executable)
index 0000000..7f6bc2a
--- /dev/null
@@ -0,0 +1,28 @@
+module PuppetSpec::Fixtures
+  def fixtures(*rest)
+    File.join(PuppetSpec::FIXTURE_DIR, *rest)
+  end
+  def my_fixture_dir
+    callers = caller
+    while line = callers.shift do
+      next unless found = line.match(%r{/spec/(.*)_spec\.rb:})
+      return fixtures(found[1])
+    end
+    fail "sorry, I couldn't work out your path from the caller stack!"
+  end
+  def my_fixture(name)
+    file = File.join(my_fixture_dir, name)
+    unless File.readable? file then
+      fail Puppet::DevError, "fixture '#{name}' for #{my_fixture_dir} is not readable"
+    end
+    return file
+  end
+  def my_fixtures(glob = '*', flags = 0)
+    files = Dir.glob(File.join(my_fixture_dir, glob), flags)
+    unless files.length > 0 then
+      fail Puppet::DevError, "fixture '#{glob}' for #{my_fixture_dir} had no files!"
+    end
+    block_given? and files.each do |file| yield file end
+    files
+  end
+end
diff --git a/spec/lib/puppet_spec/matchers.rb b/spec/lib/puppet_spec/matchers.rb
new file mode 100644 (file)
index 0000000..448bd18
--- /dev/null
@@ -0,0 +1,120 @@
+require 'stringio'
+
+########################################################################
+# Backward compatibility for Jenkins outdated environment.
+module RSpec
+  module Matchers
+    module BlockAliases
+      alias_method :to,     :should      unless method_defined? :to
+      alias_method :to_not, :should_not  unless method_defined? :to_not
+      alias_method :not_to, :should_not  unless method_defined? :not_to
+    end
+  end
+end
+
+
+########################################################################
+# Custom matchers...
+RSpec::Matchers.define :have_matching_element do |expected|
+  match do |actual|
+    actual.any? { |item| item =~ expected }
+  end
+end
+
+
+RSpec::Matchers.define :exit_with do |expected|
+  actual = nil
+  match do |block|
+    begin
+      block.call
+    rescue SystemExit => e
+      actual = e.status
+    end
+    actual and actual == expected
+  end
+  failure_message_for_should do |block|
+    "expected exit with code #{expected} but " +
+      (actual.nil? ? " exit was not called" : "we exited with #{actual} instead")
+  end
+  failure_message_for_should_not do |block|
+    "expected that exit would not be called with #{expected}"
+  end
+  description do
+    "expect exit with #{expected}"
+  end
+end
+
+class HavePrintedMatcher
+  attr_accessor :expected, :actual
+
+  def initialize(expected)
+    case expected
+    when String, Regexp
+      @expected = expected
+    else
+      @expected = expected.to_s
+    end
+  end
+
+  def matches?(block)
+    begin
+      $stderr = $stdout = StringIO.new
+      $stdout.set_encoding('UTF-8') if $stdout.respond_to?(:set_encoding)
+      block.call
+      $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
+  end
+
+  def failure_message_for_should
+    if @actual.nil? then
+      "expected #{@expected.inspect}, but nothing was printed"
+    else
+      "expected #{@expected.inspect} to be printed; got:\n#{@actual}"
+    end
+  end
+
+  def failure_message_for_should_not
+    "expected #{@expected.inspect} to not be printed; got:\n#{@actual}"
+  end
+
+  def description
+    "expect #{@expected.inspect} to be printed"
+  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|
+      actual.instance_variable_get(attr) == expected.instance_variable_get(attr)
+    end
+  end
+end
+
+RSpec::Matchers.define :be_one_of do |*expected|
+  match do |actual|
+    expected.include? actual
+  end
+
+  failure_message_for_should do |actual|
+    "expected #{actual.inspect} to be one of #{expected.map(&:inspect).join(' or ')}"
+  end
+end
diff --git a/spec/lib/puppet_spec/modules.rb b/spec/lib/puppet_spec/modules.rb
new file mode 100644 (file)
index 0000000..6835e44
--- /dev/null
@@ -0,0 +1,26 @@
+module PuppetSpec::Modules
+  class << self
+    def create(name, dir, options = {})
+      module_dir = File.join(dir, name)
+      FileUtils.mkdir_p(module_dir)
+
+      environment = options[:environment]
+
+      if metadata = options[:metadata]
+        metadata[:source]  ||= 'github'
+        metadata[:author]  ||= 'puppetlabs'
+        metadata[:version] ||= '9.9.9'
+        metadata[:license] ||= 'to kill'
+        metadata[:dependencies] ||= []
+
+        metadata[:name] = "#{metadata[:author]}/#{name}"
+
+        File.open(File.join(module_dir, 'metadata.json'), 'w') do |f|
+          f.write(metadata.to_pson)
+        end
+      end
+
+      Puppet::Module.new(name, module_dir, environment)
+    end
+  end
+end
diff --git a/spec/lib/puppet_spec/pops.rb b/spec/lib/puppet_spec/pops.rb
new file mode 100644 (file)
index 0000000..442c85b
--- /dev/null
@@ -0,0 +1,16 @@
+module PuppetSpec::Pops
+  extend RSpec::Matchers::DSL
+
+  # Checks if an Acceptor has a specific issue in its list of diagnostics
+  matcher :have_issue do |expected|
+    match do |actual|
+      actual.diagnostics.index { |i| i.issue == expected } != nil
+    end
+    failure_message_for_should do |actual|
+      "expected Acceptor[#{actual.diagnostics.collect { |i| i.issue.issue_code }.join(',')}] to contain issue #{expected.issue_code}"
+    end
+    failure_message_for_should_not do |actual|
+      "expected Acceptor[#{actual.diagnostics.collect { |i| i.issue.issue_code }.join(',')}] to not contain issue #{expected.issue_code}"
+    end
+  end
+end
diff --git a/spec/lib/puppet_spec/scope.rb b/spec/lib/puppet_spec/scope.rb
new file mode 100644 (file)
index 0000000..c14ab47
--- /dev/null
@@ -0,0 +1,14 @@
+
+module PuppetSpec::Scope
+  # Initialize a new scope suitable for testing.
+  #
+  def create_test_scope_for_node(node_name)
+    node = Puppet::Node.new(node_name)
+    compiler = Puppet::Parser::Compiler.new(node)
+    scope = Puppet::Parser::Scope.new(compiler)
+    scope.source = Puppet::Resource::Type.new(:node, node_name)
+    scope.parent = compiler.topscope
+    scope
+  end
+
+end
\ No newline at end of file
diff --git a/spec/lib/puppet_spec/settings.rb b/spec/lib/puppet_spec/settings.rb
new file mode 100644 (file)
index 0000000..f3dbc42
--- /dev/null
@@ -0,0 +1,15 @@
+module PuppetSpec::Settings
+
+  # It would probably be preferable to refactor defaults.rb such that the real definitions of
+  #  these settings were available as a variable, which was then accessible for use during tests.
+  #  However, I'm not doing that yet because I don't want to introduce any additional moving parts
+  #  to this already very large changeset.
+  #  Would be nice to clean this up later.  --cprice 2012-03-20
+  TEST_APP_DEFAULT_DEFINITIONS = {
+    :name         => { :default => "test", :desc => "name" },
+    :logdir       => { :type => :directory, :default => "test", :desc => "logdir" },
+    :confdir      => { :type => :directory, :default => "test", :desc => "confdir" },
+    :vardir       => { :type => :directory, :default => "test", :desc => "vardir" },
+    :rundir       => { :type => :directory, :default => "test", :desc => "rundir" },
+  }
+end
diff --git a/spec/lib/puppet_spec/verbose.rb b/spec/lib/puppet_spec/verbose.rb
new file mode 100755 (executable)
index 0000000..d9834f2
--- /dev/null
@@ -0,0 +1,9 @@
+# Support code for running stuff with warnings disabled.
+module Kernel
+  def with_verbose_disabled
+    verbose, $VERBOSE = $VERBOSE, nil
+    result = yield
+    $VERBOSE = verbose
+    return result
+  end
+end
index 931d35c846949690e66963f65765f069c9eb55ef..cf1981b4d6ce10709b05bdd13dd43a6d8d79513e 100644 (file)
@@ -1,21 +1,31 @@
 dir = File.expand_path(File.dirname(__FILE__))
 $LOAD_PATH.unshift File.join(dir, 'lib')
 
-# Don't want puppet getting the command line arguments for rake or autotest
-ARGV.clear
+# So everyone else doesn't have to include this base constant.
+module PuppetSpec
+  FIXTURE_DIR = File.join(dir = File.expand_path(File.dirname(__FILE__)), "fixtures") unless defined?(FIXTURE_DIR)
+end
 
 require 'puppet'
-require 'facter'
-require 'mocha'
-gem 'rspec', '>=2.0.0'
-require 'rspec/expectations'
-
+require 'rspec-puppet'
+require 'simplecov'
 require 'puppetlabs_spec_helper/module_spec_helper'
+require 'puppet_spec/verbose'
+require 'puppet_spec/files'
+require 'puppet_spec/settings'
+require 'puppet_spec/fixtures'
+require 'puppet_spec/matchers'
+require 'puppet_spec/database'
+require 'monkey_patches/alias_should_to_must'
+require 'mocha/setup'
+
+
+SimpleCov.start do
+  add_filter "/spec/"
+end
+
 
 RSpec.configure do |config|
-  # FIXME REVISIT - We may want to delegate to Facter like we do in
-  # Puppet::PuppetSpecInitializer.initialize_via_testhelper(config) because
-  # this behavior is a duplication of the spec_helper in Facter.
   config.before :each do
     # Ensure that we don't accidentally cache facts and environment between
     # test cases.  This requires each example group to explicitly load the
index fffb7f798a74714759eebd195aac7298ced0d7d6..1d2c18321c7ff76080be1ee0364e0a40ba0b999a 100644 (file)
@@ -30,7 +30,7 @@ describe Puppet::Parser::Functions.function(:deep_merge) do
     end
 
     it 'should accept empty strings as puppet undef' do
-      expect { new_hash = scope.function_deep_merge([{}, ''])}.not_to raise_error(Puppet::ParseError, /unexpected argument type String/)
+      expect { new_hash = scope.function_deep_merge([{}, ''])}.not_to raise_error
     end
 
     it 'should be able to deep_merge two hashes' do
index 8a170bb1c505140fec5c93f68a6dc12de9a42863..15a5d94cf8249c6af2b4902f585effba5c526ca7 100644 (file)
@@ -30,7 +30,7 @@ describe Puppet::Parser::Functions.function(:merge) do
     end
 
     it 'should accept empty strings as puppet undef' do
-      expect { new_hash = scope.function_merge([{}, ''])}.not_to raise_error(Puppet::ParseError, /unexpected argument type String/)
+      expect { new_hash = scope.function_merge([{}, ''])}.not_to raise_error
     end
 
     it 'should be able to merge two hashes' do
index 08aaf78992f75323fccceed758199c0bd5a5eeca..1c9cce205ef2afe6ed02aeaa98e00661b68793ab 100644 (file)
@@ -35,7 +35,7 @@ describe Puppet::Parser::Functions.function(:validate_absolute_path) do
       end
       valid_paths.each do |path|
         it "validate_absolute_path(#{path.inspect}) should not fail" do
-          expect { subject.call [path] }.not_to raise_error Puppet::ParseError
+          expect { subject.call [path] }.not_to raise_error
         end
       end
     end
@@ -43,7 +43,7 @@ describe Puppet::Parser::Functions.function(:validate_absolute_path) do
     context "Puppet without mocking" do
       valid_paths.each do |path|
         it "validate_absolute_path(#{path.inspect}) should not fail" do
-          expect { subject.call [path] }.not_to raise_error Puppet::ParseError
+          expect { subject.call [path] }.not_to raise_error
         end
       end
     end
index 65b5d209c58d6ad0826d7115612a61da549f9b5f..c356bd2294645a01b97a059219654f1a653244d6 100644 (file)
@@ -1,4 +1,4 @@
-require 'puppet'
+require 'spec_helper'
 require 'tempfile'
 provider_class = Puppet::Type.type(:file_line).provider(:ruby)
 describe provider_class do
index 2030b83f2e34715179ed356a463e801684824fe4..f92065f79ba0ab4398755407153bce48811520ea 100644 (file)
@@ -1,6 +1,6 @@
 #!/usr/bin/env ruby
 
-require 'puppet'
+require 'spec_helper'
 
 anchor = Puppet::Type.type(:anchor).new(:name => "ntp::begin")
 
index edc64bd1e54c78f1698e2828e34479c35364a607..34d5dada37c78ff42ff6ac01fda2f1ebf18e2e07 100644 (file)
@@ -1,4 +1,4 @@
-require 'puppet'
+require 'spec_helper'
 require 'tempfile'
 describe Puppet::Type.type(:file_line) do
   let :file_line do
diff --git a/spec/watchr.rb b/spec/watchr.rb
deleted file mode 100644 (file)
index 885ef1d..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-ENV['FOG_MOCK'] ||= 'true'
-ENV['AUTOTEST'] = 'true'
-ENV['WATCHR']   = '1'
-
-system 'clear'
-
-def growl(message)
-  growlnotify = `which growlnotify`.chomp
-  title = "Watchr Test Results"
-  image = case message
-  when /(\d+)\s+?(failure|error)/i
-    ($1.to_i == 0) ? "~/.watchr_images/passed.png" : "~/.watchr_images/failed.png"
-  else
-    '~/.watchr_images/unknown.png'
-  end
-  options = "-w -n Watchr --image '#{File.expand_path(image)}' -m '#{message}' '#{title}'"
-  system %(#{growlnotify} #{options} &)
-end
-
-def run(cmd)
-  puts(cmd)
-  `#{cmd}`
-end
-
-def run_spec_test(file)
-  if File.exist? file
-    result = run "rspec --format p --color #{file}"
-    growl result.split("\n").last
-    puts result
-  else
-    puts "FIXME: No test #{file} [#{Time.now}]"
-  end
-end
-
-def filter_rspec(data)
-  data.split("\n").find_all do |l|
-    l =~ /^(\d+)\s+exampl\w+.*?(\d+).*?failur\w+.*?(\d+).*?pending/
-  end.join("\n")
-end
-
-def run_all_tests
-  system('clear')
-  files = Dir.glob("spec/**/*_spec.rb").join(" ")
-  result = run "rspec #{files}"
-  growl_results = filter_rspec result
-  growl growl_results
-  puts result
-  puts "GROWL: #{growl_results}"
-end
-
-# Ctrl-\
-Signal.trap 'QUIT' do
-  puts " --- Running all tests ---\n\n"
-  run_all_tests
-end
-
-@interrupted = false
-
-# Ctrl-C
-Signal.trap 'INT' do
-  if @interrupted then
-    @wants_to_quit = true
-    abort("\n")
-  else
-    puts "Interrupt a second time to quit"
-    @interrupted = true
-    Kernel.sleep 1.5
-    # raise Interrupt, nil # let the run loop catch it
-    run_suite
-  end
-end
-
-def file2spec(file)
-  result = file.sub('lib/puppet/', 'spec/unit/puppet/').gsub(/\.rb$/, '_spec.rb')
-  result = file.sub('lib/facter/', 'spec/unit/facter/').gsub(/\.rb$/, '_spec.rb')
-end
-
-
-watch( 'spec/.*_spec\.rb' ) do |md|
-  #run_spec_test(md[0])
-  run_all_tests
-end
-watch( 'lib/.*\.rb' ) do |md|
-  # run_spec_test(file2spec(md[0]))
-  run_all_tests
-end