Please review pull request #653: (FOR REVIEW ONLY) Refactor/master/13691 spec helper compatibility opened by (cprice-puppet)

Description:

  • Opened: Wed Apr 11 02:29:47 UTC 2012
  • Based on: puppetlabs:master (42c8526aca72a4205358f8e8fdab20f48417106b)
  • Requested merge: cprice-puppet:refactor/master/13691-spec_helper_compatibility (5681b37ac679f7a009cd701ccd46a700037618a7)

Diff follows:

diff --git a/lib/puppet/application/kick.rb b/lib/puppet/application/kick.rb
index 72c9bf9..b9fc107 100644
--- a/lib/puppet/application/kick.rb
+++ b/lib/puppet/application/kick.rb
@@ -199,7 +199,7 @@ def main
       # do, then do the next host.
       if @children.length < options[:parallel] and ! todo.empty?
         host = todo.shift
-        pid = fork do
+        pid = safe_posix_fork do
           run_for_host(host)
         end
         @children[pid] = host
diff --git a/lib/puppet/face/module/build.rb b/lib/puppet/face/module/build.rb
index f1a0ef4..eec482e 100644
--- a/lib/puppet/face/module/build.rb
+++ b/lib/puppet/face/module/build.rb
@@ -3,9 +3,7 @@
     summary "Build a module release package."
     description <<-EOT
       Prepares a local module for release on the Puppet Forge by building a
-      ready-to-upload archive file. Before using this action, make sure that
-      the module directory's name is in the standard <username>-<module>
-      format.
+      ready-to-upload archive file.
 
       This action uses the Modulefile in the module directory to set metadata
       used by the Forge. See <http://links.puppetlabs.com/modulefile> for more
diff --git a/lib/puppet/face/module/search.rb b/lib/puppet/face/module/search.rb
index 0c48808..169f640 100644
--- a/lib/puppet/face/module/search.rb
+++ b/lib/puppet/face/module/search.rb
@@ -21,8 +21,6 @@
     arguments "<search_term>"
 
     when_invoked do |term, options|
-      server = Puppet.settings[:module_repository].sub(/^(?!https?:\/\/)/, 'http://')
-      Puppet.notice "Searching #{server} ..."
       Puppet::Module::Tool::Applications::Searcher.run(term, options)
     end
 
diff --git a/lib/puppet/forge.rb b/lib/puppet/forge.rb
index 8eeb991..722f03b 100644
--- a/lib/puppet/forge.rb
+++ b/lib/puppet/forge.rb
@@ -26,6 +26,8 @@ module Puppet::Forge
   # ]
   #
   def self.search(term)
+    server = Puppet.settings[:module_repository].sub(/^(?!https?:\/\/)/, 'http://')
+    Puppet.notice "Searching #{server} ..."
     request = Net::HTTP::Get.new("/modules.json?q=#{URI.escape(term)}")
     response = repository.make_http_request(request)
 
diff --git a/lib/puppet/forge/repository.rb b/lib/puppet/forge/repository.rb
index fd92b7d..cacfdc6 100644
--- a/lib/puppet/forge/repository.rb
+++ b/lib/puppet/forge/repository.rb
@@ -74,7 +74,7 @@ def read_response(request)
         msg = "Error: Could not connect to #{@uri}\n"
         msg << "  There was a network communications problem\n"
         msg << "    Check your network connection and try again\n"
-        $stderr << msg
+        Puppet.err msg
         exit(1)
       end
     end
diff --git a/lib/puppet/module_tool/applications/builder.rb b/lib/puppet/module_tool/applications/builder.rb
index 322020a..4fb9f26 100644
--- a/lib/puppet/module_tool/applications/builder.rb
+++ b/lib/puppet/module_tool/applications/builder.rb
@@ -61,7 +61,7 @@ def gzip
       def create_directory
         FileUtils.mkdir(@pkg_path) rescue nil
         if File.directory?(build_path)
-          FileUtils.rm_rf(build_path)
+          FileUtils.rm_rf(build_path, :secure => true)
         end
         FileUtils.mkdir(build_path)
       end
diff --git a/lib/puppet/module_tool/applications/uninstaller.rb b/lib/puppet/module_tool/applications/uninstaller.rb
index 2ee9b98..5ffaecd 100644
--- a/lib/puppet/module_tool/applications/uninstaller.rb
+++ b/lib/puppet/module_tool/applications/uninstaller.rb
@@ -22,7 +22,7 @@ def run
         begin
           find_installed_module
           validate_module
-          FileUtils.rm_rf(@installed.first.path)
+          FileUtils.rm_rf(@installed.first.path, :secure => true)
 
           results[:affected_modules] = @installed
           results[:result] = :success
diff --git a/lib/puppet/module_tool/applications/unpacker.rb b/lib/puppet/module_tool/applications/unpacker.rb
index f06c62d..67a76fb 100644
--- a/lib/puppet/module_tool/applications/unpacker.rb
+++ b/lib/puppet/module_tool/applications/unpacker.rb
@@ -41,7 +41,7 @@ def extract_module_to_install_dir
 
       def delete_existing_installation_or_abort!
         return unless @module_dir.exist?
-        FileUtils.rm_rf @module_dir
+        FileUtils.rm_rf(@module_dir, :secure => true)
       end
     end
   end
diff --git a/lib/puppet/node/environment.rb b/lib/puppet/node/environment.rb
index aca3c6b..9eb70fc 100644
--- a/lib/puppet/node/environment.rb
+++ b/lib/puppet/node/environment.rb
@@ -136,7 +136,7 @@ def modules_by_path
     modulepath.each do |path|
       Dir.chdir(path) do
         module_names = Dir.glob('*').select do |d|
-          FileTest.directory?(d) && (File.basename(d) =~ /^[-\w]+$/)
+          FileTest.directory?(d) && (File.basename(d) =~ /^[\w]+([-]{1}[\w]+)*$/)
         end
         modules_by_path[path] = module_names.sort.map do |name|
           Puppet::Module.new(name, :environment => self, :path => File.join(path, name))
diff --git a/lib/puppet/provider/package/gem.rb b/lib/puppet/provider/package/gem.rb
index 98b5ce6..9e48353 100755
--- a/lib/puppet/provider/package/gem.rb
+++ b/lib/puppet/provider/package/gem.rb
@@ -106,7 +106,7 @@ def latest
     # This always gets the latest version available.
     hash = self.class.gemlist(:justme => resource[:name])
 
-    hash[:ensure]
+    hash[:ensure][0]
   end
 
   def query
diff --git a/lib/puppet/rails/inventory_node.rb b/lib/puppet/rails/inventory_node.rb
index 8d6266e..052745a 100644
--- a/lib/puppet/rails/inventory_node.rb
+++ b/lib/puppet/rails/inventory_node.rb
@@ -10,14 +10,14 @@ class Puppet::Rails::InventoryNode < ::ActiveRecord::Base
 
   scope :has_fact_with_value, lambda { |name,value|
     {
-      :conditions => ["inventory_facts.name = ? AND inventory_facts.value = ?", name, value],
+      :conditions => ["inventory_facts.name = ? AND inventory_facts.value = ?", name, value.to_s],
       :joins => :facts
     }
   }
 
   scope :has_fact_without_value, lambda { |name,value|
     {
-      :conditions => ["inventory_facts.name = ? AND inventory_facts.value != ?", name, value],
+      :conditions => ["inventory_facts.name = ? AND inventory_facts.value != ?", name, value.to_s],
       :joins => :facts
     }
   }
diff --git a/lib/puppet/reports/tagmail.rb b/lib/puppet/reports/tagmail.rb
index aeb35b4..0eeb4b7 100644
--- a/lib/puppet/reports/tagmail.rb
+++ b/lib/puppet/reports/tagmail.rb
@@ -130,7 +130,7 @@ def process
 
   # Send the email reports.
   def send(reports)
-    pid = fork do
+    pid = Puppet::Util.safe_posix_fork do
       if Puppet[:smtpserver] != "none"
         begin
           Net::SMTP.start(Puppet[:smtpserver]) do |smtp|
diff --git a/lib/puppet/type/package.rb b/lib/puppet/type/package.rb
index 2c80aaa..1323f21 100644
--- a/lib/puppet/type/package.rb
+++ b/lib/puppet/type/package.rb
@@ -141,16 +141,20 @@ def insync?(is)
               end
             end
 
-            case is
-            when @latest
-              return true
-            when :present
-              # This will only happen on retarded packaging systems
-              # that can't query versions.
-              return true
-            else
-              self.debug "#{@resource.name} #{is.inspect} is installed, latest is #{@latest.inspect}"
+            case
+              when is.is_a?(Array) && is.include?(@latest)
+                return true
+              when is == @latest
+                return true
+              when is == :present
+                # This will only happen on retarded packaging systems
+                # that can't query versions.
+                return true
+              else
+                self.debug "#{@resource.name} #{is.inspect} is installed, latest is #{@latest.inspect}"
             end
+
+
           when :absent
             return true if is == :absent or is == :purged
           when :purged
diff --git a/lib/puppet/util.rb b/lib/puppet/util.rb
index bb83e09..4cfa793 100644
--- a/lib/puppet/util.rb
+++ b/lib/puppet/util.rb
@@ -227,8 +227,13 @@ def absolute_path?(path, platform=nil)
       :windows => %r!^(([A-Z]:#{slash})|(#{slash}#{slash}#{name}#{slash}#{name})|(#{slash}#{slash}\?#{slash}#{name}))!i,
       :posix   => %r!^/!,
     }
-    require 'puppet'
-    platform ||= Puppet.features.microsoft_windows? ? :windows : :posix
+
+    # Ruby only sets File::ALT_SEPARATOR on Windows and the Ruby standard
+    # library uses that to test what platform it's on.  Normally in Puppet we
+    # would use Puppet.features.microsoft_windows?, but this method needs to
+    # be called during the initialization of features so it can't depend on
+    # that.
+    platform ||= File::ALT_SEPARATOR ? :windows : :posix
 
     !! (path =~ regexes[platform])
   end
@@ -279,6 +284,20 @@ def uri_to_path(uri)
   end
   module_function :uri_to_path
 
+  def safe_posix_fork(stdin=$stdin, stdout=$stdout, stderr=$stderr, &block)
+    child_pid = Kernel.fork do
+      $stdin.reopen(stdin)
+      $stdout.reopen(stdout)
+      $stderr.reopen(stderr)
+
+      3.upto(256){|fd| IO::new(fd).close rescue nil}
+
+      block.call if block
+    end
+    child_pid
+  end
+  module_function :safe_posix_fork
+
   # Create an exclusive lock.
   def threadlock(resource, type = Sync::EX)
     Puppet::Util.synchronize_on(resource,type) { yield }
diff --git a/lib/puppet/util/autoload.rb b/lib/puppet/util/autoload.rb
index 0658b2a..ba4c639 100644
--- a/lib/puppet/util/autoload.rb
+++ b/lib/puppet/util/autoload.rb
@@ -167,7 +167,7 @@ def cleanpath(path)
 
   def initialize(obj, path, options = {})
     @path = path.to_s
-    raise ArgumentError, "Autoload paths cannot be fully qualified" if @path !~ /^\w/
+    raise ArgumentError, "Autoload paths cannot be fully qualified" if Puppet::Util.absolute_path?(@path)
     @object = obj
 
     self.class[obj] = self
diff --git a/lib/puppet/util/execution.rb b/lib/puppet/util/execution.rb
index 356fb4b..220cc46 100644
--- a/lib/puppet/util/execution.rb
+++ b/lib/puppet/util/execution.rb
@@ -155,7 +155,7 @@ class << self
 
   # this is private method, see call to private_class_method after method definition
   def self.execute_posix(command, arguments, stdin, stdout, stderr)
-    child_pid = Kernel.fork do
+    child_pid = Puppet::Util.safe_posix_fork(stdin, stdout, stderr) do
       # We can't just call Array(command), and rely on it returning
       # things like ['foo'], when passed ['foo'], because
       # Array(command) will call command.to_a internally, which when
@@ -164,16 +164,6 @@ def self.execute_posix(command, arguments, stdin, stdout, stderr)
       command = [command].flatten
       Process.setsid
       begin
-        $stdin.reopen(stdin)
-        $stdout.reopen(stdout)
-        $stderr.reopen(stderr)
-
-        # we are in a forked process, so we currently have access to all of the file descriptors
-        # from the parent process... which, in this case, is bad because we don't want
-        # to allow the user's command to have access to them.  Therefore, we'll close them off.
-        # (assumes that there are only 256 file descriptors used)
-        3.upto(256){|fd| IO::new(fd).close rescue nil}
-
         Puppet::Util::SUIDManager.change_privileges(arguments[:uid], arguments[:gid], true)
 
         # if the caller has requested that we override locale environment variables,
diff --git a/lib/puppet/util/settings.rb b/lib/puppet/util/settings.rb
index 90cb7d8..eef0bd7 100644
--- a/lib/puppet/util/settings.rb
+++ b/lib/puppet/util/settings.rb
@@ -1132,45 +1132,6 @@ def set_metadata(meta)
   end
 
 
-
-
-  # Private method for internal test use only; allows to assign reasonable values to the "app defaults"
-  #  settings for the purpose of test runs.
-  #
-  # @return [Hash] a hash containing the default values to use for application settings during testing.
-  def app_defaults_for_tests()
-    {
-        :run_mode   => :user,
-        :name       => :apply,
-        :logdir     => "/dev/null",
-        :confdir    => "/dev/null",
-        :vardir     => "/dev/null",
-        :rundir     => "/dev/null",
-    }
-  end
-  private :app_defaults_for_tests
-
-
-  # Private method for internal test use only; allows to assign reasonable values to the "app defaults"
-  #  settings for the purpose of test runs.
-  #
-  # @return nil
-  def initialize_everything_for_tests()
-    # Initialize "app defaults" settings to a good set of test values
-    app_defaults_for_tests.each do |key, value|
-      Puppet.settings.set_value(key, value, :application_defaults)
-    end
-
-    # Avoid opening ports to the outside world
-    Puppet.settings[:bindaddress] = "127.0.0.1"
-
-    # We don't want to depend upon the reported domain name of the
-    # machine running the tests, nor upon the DNS setup of that
-    # domain.
-    Puppet.settings[:use_srv_records] = false
-  end
-  private :initialize_everything_for_tests
-
   # Private method for internal test use only; allows to do a comprehensive clear of all settings between tests.
   #
   # @return nil
diff --git a/lib/semver.rb b/lib/semver.rb
index 53c7e69..bf66919 100644
--- a/lib/semver.rb
+++ b/lib/semver.rb
@@ -17,18 +17,21 @@ def self.find_matching(pattern, versions)
     versions.select { |v| v.matched_by?("#{pattern}") }.sort.last
   end
 
+  def self.pre(vstring)
+    vstring =~ /-/ ? vstring : vstring + '-'
+  end
+
   def self.[](range)
-    pre = proc { |vstring| vstring =~ /-/ ? vstring : vstring + '-' }
     range.gsub(/([><=])\s+/, '\1').split(/\b\s+(?!-)/).map do |r|
       case r
       when SemVer::VERSION
-        SemVer.new(pre[r]) .. SemVer.new(r)
+        SemVer.new(pre(r)) .. SemVer.new(r)
       when SemVer::SIMPLE_RANGE
         r += ".0" unless SemVer.valid?(r.gsub(/x/i, '0'))
         SemVer.new(r.gsub(/x/i, '0'))...SemVer.new(r.gsub(/(\d+)\.x/i) { "#{$1.to_i + 1}.0" } + '-')
       when /\s+-\s+/
         a, b = r.split(/\s+-\s+/)
-        SemVer.new(pre[a]) .. SemVer.new(b)
+        SemVer.new(pre(a)) .. SemVer.new(b)
       when /^~/
         ver = r.sub(/~/, '').split('.').map(&:to_i)
         start = (ver + [0] * (3 - ver.length)).join('.')
@@ -37,10 +40,10 @@ def self.[](range)
         ver[-1] = ver.last + 1
 
         finish = (ver + [0] * (3 - ver.length)).join('.')
-        SemVer.new(pre[start]) ... SemVer.new(pre[finish])
+        SemVer.new(pre(start)) ... SemVer.new(pre(finish))
       when /^>=/
         ver = r.sub(/^>=/, '')
-        SemVer.new(pre[ver]) .. SemVer::MAX
+        SemVer.new(pre(ver)) .. SemVer::MAX
       when /^<=/
         ver = r.sub(/^<=/, '')
         SemVer::MIN .. SemVer.new(ver)
@@ -54,7 +57,7 @@ def self.[](range)
         SemVer.new(ver.join('.') + '-') .. SemVer::MAX
       when /^</
         ver = r.sub(/^</, '')
-        SemVer::MIN ... SemVer.new(pre[ver])
+        SemVer::MIN ... SemVer.new(pre(ver))
       else
         (1..1)
       end
diff --git a/spec/shared_behaviours/path_parameters.rb b/spec/shared_behaviours/path_parameters.rb
index bdcd4cf..2d195a1 100755
--- a/spec/shared_behaviours/path_parameters.rb
+++ b/spec/shared_behaviours/path_parameters.rb
@@ -87,26 +87,7 @@ def instance(path)
     @param = param
   end
 
-  before :each do
-    @file_separator = File::SEPARATOR
-  end
-  after :each do
-    with_verbose_disabled do
-      verbose, $VERBOSE = $VERBOSE, nil
-      File::SEPARATOR = @file_separator
-      $VERBOSE = verbose
-    end
-  end
-
-  describe "on a Unix-like platform it" do
-    before :each do
-      with_verbose_disabled do
-        File::SEPARATOR = '/'
-      end
-      Puppet.features.stubs(:microsoft_windows?).returns(false)
-      Puppet.features.stubs(:posix?).returns(true)
-    end
-
+  describe "on a Unix-like platform it", :as_platform => :posix do
     if array then
       it_should_behave_like "all pathname parameters with arrays", false
     end
@@ -134,15 +115,7 @@ def instance(path)
     end
   end
 
-  describe "on a Windows-like platform it" do
-    before :each do
-      with_verbose_disabled do
-        File::SEPARATOR = '\\'
-      end
-      Puppet.features.stubs(:microsoft_windows?).returns(true)
-      Puppet.features.stubs(:posix?).returns(false)
-    end
-
+  describe "on a Windows-like platform it", :as_platform => :windows do
     if array then
       it_should_behave_like "all pathname parameters with arrays", true
     end
diff --git a/spec/shared_contexts/platform.rb b/spec/shared_contexts/platform.rb
new file mode 100644
index 0000000..7548a6d
--- /dev/null
+++ b/spec/shared_contexts/platform.rb
@@ -0,0 +1,43 @@
+# Contexts for stubbing platforms
+# In a describe or context block, adding :as_platform => :windows or
+# :as_platform => :posix will stub the relevant Puppet features, as well as
+# the behavior of Ruby's filesystem methods by changing File::ALT_SEPARATOR.
+
+shared_context "windows", :as_platform => :windows do
+  before :each do
+    Facter.stubs(:value).with(:operatingsystem).returns 'Windows'
+    Puppet.features.stubs(:microsoft_windows?).returns(true)
+    Puppet.features.stubs(:posix?).returns(false)
+  end
+
+  around do |example|
+    file_alt_separator = File::ALT_SEPARATOR
+    # prevent Ruby from warning about changing a constant
+    with_verbose_disabled do
+      File::ALT_SEPARATOR = '\\'
+    end
+    example.run
+    with_verbose_disabled do
+      File::ALT_SEPARATOR = file_alt_separator
+    end
+  end
+end
+
+shared_context "posix", :as_platform => :posix do
+  before :each do
+    Puppet.features.stubs(:microsoft_windows?).returns(false)
+    Puppet.features.stubs(:posix?).returns(true)
+  end
+
+  around do |example|
+    file_alt_separator = File::ALT_SEPARATOR
+    # prevent Ruby from warning about changing a constant
+    with_verbose_disabled do
+      File::ALT_SEPARATOR = nil
+    end
+    example.run
+    with_verbose_disabled do
+      File::ALT_SEPARATOR = file_alt_separator
+    end
+  end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 751e927..77abab4 100755
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,3 +1,7 @@
+# NOTE: a lot of the stuff in this file is duplicated in the "puppet_spec_helper" in the project
+#  puppetlabs_spec_helper.  We should probably eat our own dog food and get rid of most of this from here,
+#  and have the puppet core itself use puppetlabs_spec_helper
+
 dir = File.expand_path(File.dirname(__FILE__))
 $LOAD_PATH.unshift File.join(dir, 'lib')
 
@@ -25,6 +29,11 @@ module PuppetSpec
 require 'puppet_spec/database'
 require 'monkey_patches/alias_should_to_must'
 require 'monkey_patches/publicize_methods'
+require 'puppet/test/test_helper'
+
+Pathname.glob("#{dir}/shared_contexts/*.rb") do |file|
+  require file.relative_path_from(Pathname.new(dir))
+end
 
 Pathname.glob("#{dir}/shared_behaviours/**/*.rb") do |behaviour|
   require behaviour.relative_path_from(Pathname.new(dir))
@@ -35,113 +44,58 @@ module PuppetSpec
 
   config.mock_with :mocha
 
+  config.before :all do
+    Puppet::Test::TestHelper.before_all_tests()
+  end
+
+  config.after :all do
+    Puppet::Test::TestHelper.after_all_tests()
+  end
+
   config.before :each do
     # Disabling garbage collection inside each test, and only running it at
     # the end of each block, gives us an ~ 15 percent speedup, and more on
     # some platforms *cough* windows *cough* that are a little slower.
     GC.disable
 
-    # We need to preserve the current state of all our indirection cache and
-    # terminus classes.  This is pretty important, because changes to these
-    # are global and lead to order dependencies in our testing.
-    #
-    # We go direct to the implementation because there is no safe, sane public
-    # API to manage restoration of these to their default values.  This
-    # should, once the value is proved, be moved to a standard API on the
-    # indirector.
-    #
-    # To make things worse, a number of the tests stub parts of the
-    # indirector.  These stubs have very specific expectations that what
-    # little of the public API we could use is, well, likely to explode
-    # randomly in some tests.  So, direct access.  --daniel 2011-08-30
-    $saved_indirection_state = {}
-    indirections = Puppet::Indirector::Indirection.send(:class_variable_get, :@@indirections)
-    indirections.each do |indirector|
-      $saved_indirection_state[indirector.name] = {
-        :@terminus_class => indirector.instance_variable_get(:@terminus_class),
-        :@cache_class    => indirector.instance_variable_get(:@cache_class)
-      }
-    end
-
-
-    # The process environment is a shared, persistent resource.
-    $old_env = ENV.to_hash
-
-    # So is the load_path
-    $old_load_path = $LOAD_PATH.dup
-
     # REVISIT: I think this conceals other bad tests, but I don't have time to
     # fully diagnose those right now.  When you read this, please come tell me
     # I suck for letting this float. --daniel 2011-04-21
     Signal.stubs(:trap)
 
-    Puppet.settings.send(:initialize_everything_for_tests)
 
-    # Longer keys are secure, but they sure make for some slow testing - both
-    # in terms of generating keys, and in terms of anything the next step down
-    # the line doing validation or whatever.  Most tests don't care how long
-    # or secure it is, just that it exists, so these are better and faster
-    # defaults, in testing only.
+    # TODO: in a more sane world, we'd move this logging redirection into our TestHelper class.
+    #  Without doing so, external projects will all have to roll their own solution for
+    #  redirecting logging, and for validating expected log messages.  However, because the
+    #  current implementation of this involves creating an instance variable "@logs" on
+    #  EVERY SINGLE TEST CLASS, and because there are over 1300 tests that are written to expect
+    #  this instance variable to be available--we can't easily solve this problem right now.
     #
-    # I would make these even shorter, but OpenSSL doesn't support anything
-    # below 512 bits.  Sad, really, because a 0 bit key would be just fine.
-    Puppet[:req_bits]  = 512
-    Puppet[:keylength] = 512
-
-
+    # redirecting logging away from console, because otherwise the test output will be
+    #  obscured by all of the log output
     @logs = []
     Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(@logs))
 
     @log_level = Puppet::Util::Log.level
+
+    Puppet::Test::TestHelper.before_each_test()
+
   end
 
   config.after :each do
-    Puppet.settings.send(:clear_everything_for_tests)
-    Puppet::Node::Environment.clear
-    Puppet::Util::Storage.clear
-    Puppet::Util::ExecutionStub.reset
+    Puppet::Test::TestHelper.after_each_test()
 
+    # this wouldn't need to be here if we were using puppetlabs_spec_helper for puppet core.
     PuppetSpec::Files.cleanup
 
+    # TODO: this should be abstracted in the future--see comments above the '@logs' block in the
+    #  "before" code above.
+    #
+    # clean up after the logging changes that we made before each test.
     @logs.clear
     Puppet::Util::Log.close_all
     Puppet::Util::Log.level = @log_level
 
-    Puppet.clear_deprecation_warnings
-
-    # uncommenting and manipulating this can be useful when tracking down calls to deprecated code
-    #Puppet.log_deprecations_to_file("deprecations.txt", /^Puppet::Util.exec/)
-
-    # Restore the indirector configuration.  See before hook.
-    indirections = Puppet::Indirector::Indirection.send(:class_variable_get, :@@indirections)
-    indirections.each do |indirector|
-      $saved_indirection_state.fetch(indirector.name, {}).each do |variable, value|
-        indirector.instance_variable_set(variable, value)
-      end
-    end
-    $saved_indirection_state = {}
-
-    # Restore the global process environment.  Can't just assign because this
-    # is a magic variable, sadly, and doesn't do thatâ„¢.  It is sufficiently
-    # faster to use the compare-then-set model to avoid excessive work that it
-    # justifies the complexity.  --daniel 2012-03-15
-    unless ENV.to_hash == $old_env
-      ENV.clear
-      $old_env.each {|k, v| ENV[k] = v }
-    end
-
-    # Some tests can cause us to connect, in which case the lingering
-    # connection is a resource that can cause unexpected failure in later
-    # tests, as well as sharing state accidentally.
-    # We're testing if ActiveRecord::Base is defined because some test cases
-    # may stub Puppet.features.rails? which is how we should normally
-    # introspect for this functionality.
-    ActiveRecord::Base.remove_connection if defined?(ActiveRecord::Base)
-
-    # Restore the load_path late, to avoid messing with stubs from the test.
-    $LOAD_PATH.clear
-    $old_load_path.each {|x| $LOAD_PATH << x }
-
     # This will perform a GC between tests, but only if actually required.  We
     # experimented with forcing a GC run, and that was less efficient than
     # just letting it run all the time.
diff --git a/spec/unit/application/kick_spec.rb b/spec/unit/application/kick_spec.rb
index fc18aba..b60d112 100755
--- a/spec/unit/application/kick_spec.rb
+++ b/spec/unit/application/kick_spec.rb
@@ -235,14 +235,14 @@
         @kick.hosts = ['host1', 'host2', 'host3']
         Process.stubs(:wait).returns(1).then.returns(2).then.returns(3).then.raises(Errno::ECHILD)
 
-        @kick.expects(:fork).times(3).returns(1).then.returns(2).then.returns(3)
+        @kick.expects(:safe_posix_fork).times(3).returns(1).then.returns(2).then.returns(3)
 
         expect { @kick.main }.to raise_error SystemExit
       end
 
       it "should delegate to run_for_host per host" do
         @kick.hosts = ['host1', 'host2']
-        @kick.stubs(:fork).returns(1).yields
+        @kick.stubs(:safe_posix_fork).returns(1).yields
         Process.stubs(:wait).returns(1).then.raises(Errno::ECHILD)
 
         @kick.expects(:run_for_host).times(2)
diff --git a/spec/unit/node/environment_spec.rb b/spec/unit/node/environment_spec.rb
index 34afc44..236a043 100755
--- a/spec/unit/node/environment_spec.rb
+++ b/spec/unit/node/environment_spec.rb
@@ -216,6 +216,9 @@
           FileUtils.mkdir_p(File.join(@first, 'foo=bar'))
           FileUtils.mkdir_p(File.join(@first, 'foo bar'))
           FileUtils.mkdir_p(File.join(@first, 'foo.bar'))
+          FileUtils.mkdir_p(File.join(@first, '-foo'))
+          FileUtils.mkdir_p(File.join(@first, 'foo-'))
+          FileUtils.mkdir_p(File.join(@first, 'foo--bar'))
 
           env.modules_by_path[@first].collect{|mod| mod.name}.sort.should == %w{foo foo-bar foo2 foo_bar}
         end
diff --git a/spec/unit/parser/functions/generate_spec.rb b/spec/unit/parser/functions/generate_spec.rb
index 42cf988..fe779c8 100755
--- a/spec/unit/parser/functions/generate_spec.rb
+++ b/spec/unit/parser/functions/generate_spec.rb
@@ -43,11 +43,7 @@
     scope.function_generate([command]).should == 'yay'
   end
 
-  describe "on Windows" do
-    before :each do
-      Puppet.features.stubs(:microsoft_windows?).returns(true)
-    end
-
+  describe "on Windows", :as_platform => :windows do
     it "should accept lower-case drive letters" do
       command = 'd:/command/foo'
       Dir.expects(:chdir).with(File.dirname(command)).returns("yay")
@@ -75,11 +71,7 @@
     end
   end
 
-  describe "on non-Windows" do
-    before :each do
-      Puppet.features.stubs(:microsoft_windows?).returns(false)
-    end
-
+  describe "on non-Windows", :as_platform => :posix do
     it "should reject backslashes" do
       lambda { scope.function_generate(['/com\\mand']) }.should raise_error(Puppet::ParseError)
     end
diff --git a/spec/unit/provider/exec/windows_spec.rb b/spec/unit/provider/exec/windows_spec.rb
index 748646a..5e1b5c9 100755
--- a/spec/unit/provider/exec/windows_spec.rb
+++ b/spec/unit/provider/exec/windows_spec.rb
@@ -2,18 +2,12 @@
 
 require 'spec_helper'
 
-describe Puppet::Type.type(:exec).provider(:windows) do
+describe Puppet::Type.type(:exec).provider(:windows), :as_platform => :windows do
   include PuppetSpec::Files
 
   let(:resource) { Puppet::Type.type(:exec).new(:title => 'C:\foo', :provider => :windows) }
   let(:provider) { described_class.new(resource) }
 
-  before :each do
-    Facter.stubs(:value).with(:operatingsystem).returns 'Windows'
-    Puppet.features.stubs(:microsoft_windows?).returns(true)
-    Puppet.features.stubs(:posix?).returns(false)
-  end
-
   after :all do
     # This provider may not be suitable on some machines, so we want to reset
     # the default so it isn't used by mistake in future specs.
diff --git a/spec/unit/provider/package/gem_spec.rb b/spec/unit/provider/package/gem_spec.rb
index 7c3cbde..516e579 100755
--- a/spec/unit/provider/package/gem_spec.rb
+++ b/spec/unit/provider/package/gem_spec.rb
@@ -87,6 +87,21 @@
     end
   end
 
+  describe "#latest" do
+    it "should return a single value for 'latest'" do
+      #gemlist is used for retrieving both local and remote version numbers, and there are cases
+      # (particularly local) where it makes sense for it to return an array.  That doesn't make
+      # sense for '#latest', though.
+      provider.class.expects(:gemlist).with({ :justme => 'myresource'}).returns({
+          :name     => 'myresource',
+          :ensure   => ["3.0"],
+          :provider => :gem,
+          })
+      provider.latest.should == "3.0"
+    end
+  end
+
+
   describe "#instances" do
     before do
       provider_class.stubs(:command).with(:gemcmd).returns "/my/gem"
diff --git a/spec/unit/semver_spec.rb b/spec/unit/semver_spec.rb
index 8da6324..9d924a1 100644
--- a/spec/unit/semver_spec.rb
+++ b/spec/unit/semver_spec.rb
@@ -22,6 +22,16 @@
     end
   end
 
+  describe '::pre' do
+    it 'should append a dash when no dash appears in the string' do
+      SemVer.pre('1.2.3').should == '1.2.3-'
+    end
+
+    it 'should not append a dash when a dash appears in the string' do
+      SemVer.pre('1.2.3-a').should == '1.2.3-a'
+    end
+  end
+
   describe '::find_matching' do
     before :all do
       @versions = %w[
diff --git a/spec/unit/type/exec_spec.rb b/spec/unit/type/exec_spec.rb
index 6b1bd01..535d0d5 100755
--- a/spec/unit/type/exec_spec.rb
+++ b/spec/unit/type/exec_spec.rb
@@ -193,12 +193,7 @@ def exec_tester(command, exitstatus = 0, rest = {})
   end
 
   describe "when setting user" do
-    describe "on POSIX systems" do
-      before :each do
-        Puppet.features.stubs(:posix?).returns(true)
-        Puppet.features.stubs(:microsoft_windows?).returns(false)
-      end
-
+    describe "on POSIX systems", :as_platform => :posix do
       it "should fail if we are not root" do
         Puppet.features.stubs(:root?).returns(false)
         expect { Puppet::Type.type(:exec).new(:name => '/bin/true whatever', :user => 'input') }.
@@ -214,10 +209,8 @@ def exec_tester(command, exitstatus = 0, rest = {})
       end
     end
 
-    describe "on Windows systems" do
+    describe "on Windows systems", :as_platform => :windows do
       before :each do
-        Puppet.features.stubs(:posix?).returns(false)
-        Puppet.features.stubs(:microsoft_windows?).returns(true)
         Puppet.features.stubs(:root?).returns(true)
       end
 
@@ -493,13 +486,13 @@ def test(command, valid)
         end
       end
     end
+  end
 
-    describe "when setting creates" do
-      it_should_behave_like "all path parameters", :creates, :array => true do
-        def instance(path)
-          # Specify shell provider so we don't have to care about command validation
-          Puppet::Type.type(:exec).new(:name => @executable, :creates => path, :provider => :shell)
-        end
+  describe "when setting creates" do
+    it_should_behave_like "all path parameters", :creates, :array => true do
+      def instance(path)
+        # Specify shell provider so we don't have to care about command validation
+        Puppet::Type.type(:exec).new(:name => @executable, :creates => path, :provider => :shell)
       end
     end
   end
diff --git a/spec/unit/type/package_spec.rb b/spec/unit/type/package_spec.rb
index 921af54..003d1f6 100755
--- a/spec/unit/type/package_spec.rb
+++ b/spec/unit/type/package_spec.rb
@@ -270,6 +270,16 @@ def setprops(properties)
           @provider.expects(:install).never
           @catalog.apply
         end
+
+        describe "when ensure is set to 'latest'" do
+          it "should not install if the value is in the array" do
+            @provider.expects(:latest).returns("3.0")
+            @package[:ensure] = "latest"
+            @package.property(:ensure).insync?(installed_versions).should be_true
+            @provider.expects(:install).never
+            @catalog.apply
+          end
+        end
       end
     end
   end
diff --git a/spec/unit/util/execution_spec.rb b/spec/unit/util/execution_spec.rb
index 92bfcd8..2dc4776 100755
--- a/spec/unit/util/execution_spec.rb
+++ b/spec/unit/util/execution_spec.rb
@@ -94,15 +94,6 @@ def stub_process_wait(exitstatus)
         call_exec_posix('test command', {}, @stdin, @stdout, @stderr)
       end
 
-      it "should close all open file descriptors except stdin/stdout/stderr" do
-        # This is ugly, but I can't really think of a better way to do it without
-        # letting it actually close fds, which seems risky
-        (0..2).each {|n| IO.expects(:new).with(n).never}
-        (3..256).each {|n| IO.expects(:new).with(n).returns mock('io', :close) }
-
-        call_exec_posix('test command', {}, @stdin, @stdout, @stderr)
-      end
-
       it "should permanently change to the correct user and group if specified" do
         Puppet::Util::SUIDManager.expects(:change_group).with(55, true)
         Puppet::Util::SUIDManager.expects(:change_user).with(50, true)
diff --git a/spec/unit/util/log/destinations_spec.rb b/spec/unit/util/log/destinations_spec.rb
index 07052b3..1d3ab79 100755
--- a/spec/unit/util/log/destinations_spec.rb
+++ b/spec/unit/util/log/destinations_spec.rb
@@ -44,18 +44,14 @@
       end
     end
 
-    describe "on POSIX systems" do
-      before :each do Puppet.features.stubs(:microsoft_windows?).returns false end
-
+    describe "on POSIX systems", :as_platform => :posix do
       let (:abspath) { '/tmp/log' }
       let (:relpath) { 'log' }
 
       it_behaves_like "file destination"
     end
 
-    describe "on Windows systems" do
-      before :each do Puppet.features.stubs(:microsoft_windows?).returns true end
-
+    describe "on Windows systems", :as_platform => :windows do
       let (:abspath) { 'C:\\temp\\log.txt' }
       let (:relpath) { 'log.txt' }
 
diff --git a/spec/unit/util/settings_spec.rb b/spec/unit/util/settings_spec.rb
index 80e3e60..17a6ff7 100755
--- a/spec/unit/util/settings_spec.rb
+++ b/spec/unit/util/settings_spec.rb
@@ -87,9 +87,14 @@
     #  case behaviors / uses.  However, until that time... we need to make sure that our private run_mode=
     #  setter method gets properly called during app initialization.
     it "should call the hacky run mode setter method until we do a better job of separating run_mode" do
+      app_defaults = {}
+      Puppet::Util::Settings::REQUIRED_APP_SETTINGS.each do |key|
+        app_defaults[key] = "foo"
+      end
+
       @settings.define_settings(:main, PuppetSpec::Settings::TEST_APP_DEFAULT_DEFINITIONS)
-      @settings.expects(:run_mode=).with(:user)
-      @settings.initialize_app_defaults(@settings.send(:app_defaults_for_tests))
+      @settings.expects(:run_mode=).with("foo")
+      @settings.initialize_app_defaults(app_defaults)
     end
   end
 
diff --git a/spec/unit/util_spec.rb b/spec/unit/util_spec.rb
index 40df8c3..91a88e5 100755
--- a/spec/unit/util_spec.rb
+++ b/spec/unit/util_spec.rb
@@ -68,18 +68,18 @@ def get_mode(file)
   end
 
   describe "#absolute_path?" do
-    it "should default to the platform of the local system" do
-      Puppet.features.stubs(:posix?).returns(true)
-      Puppet.features.stubs(:microsoft_windows?).returns(false)
-
-      Puppet::Util.should be_absolute_path('/foo')
-      Puppet::Util.should_not be_absolute_path('C:/foo')
-
-      Puppet.features.stubs(:posix?).returns(false)
-      Puppet.features.stubs(:microsoft_windows?).returns(true)
+    describe "on posix systems", :as_platform => :posix do
+      it "should default to the platform of the local system" do
+        Puppet::Util.should be_absolute_path('/foo')
+        Puppet::Util.should_not be_absolute_path('C:/foo')
+      end
+    end
 
-      Puppet::Util.should be_absolute_path('C:/foo')
-      Puppet::Util.should_not be_absolute_path('/foo')
+    describe "on windows", :as_platform => :windows do
+      it "should default to the platform of the local system" do
+        Puppet::Util.should be_absolute_path('C:/foo')
+        Puppet::Util.should_not be_absolute_path('/foo')
+      end
     end
 
     describe "when using platform :posix" do
@@ -213,6 +213,40 @@ def get_mode(file)
     end
   end
 
+  describe "safe_posix_fork" do
+    let(:pid) { 5501 }
+
+    before :each do
+      # Most of the things this method does are bad to do during specs. :/
+      Kernel.stubs(:fork).returns(pid).yields
+
+      $stdin.stubs(:reopen)
+      $stdout.stubs(:reopen)
+      $stderr.stubs(:reopen)
+    end
+
+    it "should close all open file descriptors except stdin/stdout/stderr" do
+      # This is ugly, but I can't really think of a better way to do it without
+      # letting it actually close fds, which seems risky
+      (0..2).each {|n| IO.expects(:new).with(n).never}
+      (3..256).each {|n| IO.expects(:new).with(n).returns mock('io', :close) }
+
+      Puppet::Util.safe_posix_fork
+    end
+
+    it "should fork a child process to execute the block" do
+      Kernel.expects(:fork).returns(pid).yields
+
+      Puppet::Util.safe_posix_fork do
+        message = "Fork this!"
+      end
+    end
+
+    it "should return the pid of the child process" do
+      Puppet::Util.safe_posix_fork.should == pid
+    end
+  end
+
   describe "#which" do
     let(:base) { File.expand_path('/bin') }
     let(:path) { File.join(base, 'foo') }

    

--
You received this message because you are subscribed to the Google Groups "Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to [email protected].
For more options, visit this group at http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to