[Pkg-puppet-devel] [SCM] Puppet packaging for Debian branch, upstream, updated. 2.6.5-303-gfcfa26a

Paul Berry paul at puppetlabs.com
Thu Mar 17 10:48:23 UTC 2011


The following commit has been merged in the upstream branch:
commit ecb953646b2defbab3bbc53a58ce7ba98d560b50
Merge: a949a83c4f100be0254fadcb915f418f73705861 23a510a321e47a98768dc47f95cfa0bd8c1a314c
Author: Paul Berry <paul at puppetlabs.com>
Date:   Mon Feb 28 13:13:52 2011 -0800

    Merge branch 'ticket/2.6.x/4914' into maint/2.6.next/revert-6309
    
    * ticket/2.6.x/4914:
      (#4914) Improved stubbing in mount/parsed_spec tests.
      (#4914) Improved parsed_spec for mount
      (#4914) Remove mount specs
      (#4914) Specs for mounted? match new behaviour
      (#4914) Add specs for modified mount provider
      (#4914) Add specs for modified mount type
      (#4914) Update property blocks
      (#4914) Query property_hash for mountstate
      (#4914) Prefetch mountstate
      (#4914) Join lines for better readability
    
    Conflicts:
    	lib/puppet/provider/mount.rb
    	lib/puppet/provider/mount/parsed.rb
    	spec/unit/provider/mount/parsed_spec.rb
    	spec/unit/provider/mount_spec.rb
    	spec/unit/type/mount_spec.rb

diff --combined lib/puppet/provider/mount/parsed.rb
index 69a6fc0,4a64ca2..42e543c
--- a/lib/puppet/provider/mount/parsed.rb
+++ b/lib/puppet/provider/mount/parsed.rb
@@@ -8,18 -8,14 +8,17 @@@ els
    fstab = "/etc/fstab"
  end
  
 -
 -Puppet::Type.type(:mount).provide(:parsed,:parent => Puppet::Provider::ParsedFile,:default_target => fstab,:filetype => :flat) do
 +Puppet::Type.type(:mount).provide(
 +  :parsed,
 +  :parent => Puppet::Provider::ParsedFile,
 +  :default_target => fstab,
 +  :filetype => :flat
 +) do
    include Puppet::Provider::Mount
  
    commands :mountcmd => "mount", :umount => "umount"
  
-   @platform = Facter["operatingsystem"].value
-   case @platform
+   case Facter["operatingsystem"]
    when "Solaris"
      @fields = [:device, :blockdevice, :name, :fstype, :pass, :atboot, :options]
    else
@@@ -39,4 -35,56 +38,63 @@@
    text_line :incomplete, :match => /^(?!#{field_pattern}{#{mandatory_fields.length}})/
  
    record_line self.name, :fields => @fields, :separator => /\s+/, :joiner => "\t", :optional => optional_fields
+ 
+   # Every entry in fstab is :unmounted until we can prove different
+   def self.prefetch_hook(target_records)
+     target_records.collect do |record|
+       record[:ensure] = :unmounted if record[:record_type] == :parsed
+       record
+     end
+   end
+ 
+   def self.prefetch(resources = nil)
+     # Get providers for all resources the user defined and that match
+     # a record in /etc/fstab.
+     super
+     # We need to do two things now:
+     # - Update ensure from :unmounted to :mounted if the resource is mounted
+     # - Check for mounted devices that are not in fstab and
+     #   set ensure to :ghost (if the user wants to add an entry
+     #   to fstab we need to know if the device was mounted before)
+     mountinstances.each do |hash|
+       if mount = resources[hash[:name]]
+         case mount.provider.get(:ensure)
+         when :absent  # Mount not in fstab
+           mount.provider.set(:ensure => :ghost)
+         when :unmounted # Mount in fstab
+           mount.provider.set(:ensure => :mounted)
+         end
+       end
+     end
+   end
+ 
+   def self.mountinstances
+     # XXX: Will not work for mount points that have spaces in path (does fstab support this anyways?)
+     regex = case Facter.value(:operatingsystem)
+       when "Darwin"
+         / on (?:\/private\/var\/automount)?(\S*)/
+       when "Solaris", "HP-UX"
+         /^(\S*) on /
++      when "AIX"
++        /^(?:\S*\s+\S+\s+)(\S+)/
+       else
+         / on (\S*)/
+     end
+     instances = []
 -    mountcmd.split("\n").each do |line|
++    mount_output = mountcmd.split("\n")
++    if mount_output.length >= 2 and mount_output[1] =~ /^[- \t]*$/
++      # On some OSes (e.g. AIX) mount output begins with a header line
++      # followed by a line consisting of dashes and whitespace.
++      # Discard these two lines.
++      mount_output[0..1] = []
++    end
++    mount_output.each do |line|
+       if match = regex.match(line) and name = match.captures.first
+         instances << {:name => name, :mounted => :yes} # Only :name is important here
+       else
+         raise Puppet::Error, "Could not understand line #{line} from mount output"
+       end
+     end
+     instances
+   end
 -
  end
 -
diff --combined lib/puppet/type/mount.rb
index da9a70b,bcd24a1..98a1f25
--- a/lib/puppet/type/mount.rb
+++ b/lib/puppet/type/mount.rb
@@@ -21,6 -21,11 +21,11 @@@ module Puppe
          fstab and mount it. Set to `present` to add to fstab but not change
          mount/unmount status"
  
+       #  IS        -> SHOULD     In Sync  Action
+       #  ghost     -> present    NO       create
+       #  absent    -> present    NO       create
+       # (mounted   -> present    YES)
+       # (unmounted -> present    YES)
        newvalue(:defined) do
          provider.create
          return :mount_created
@@@ -28,27 -33,48 +33,48 @@@
  
        aliasvalue :present, :defined
  
+       #  IS        -> SHOULD     In Sync  Action
+       #  ghost     -> unmounted  NO       create, unmount
+       #  absent    -> unmounted  NO       create
+       #  mounted   -> unmounted  NO       unmount
        newvalue(:unmounted) do
-         if provider.mounted?
-           syncothers
+         case self.retrieve
+         when :ghost   # (not in fstab but mounted)
+           provider.create
+           @resource.flush
            provider.unmount
            return :mount_unmounted
-         else
+         when nil, :absent  # (not in fstab and not mounted)
            provider.create
            return :mount_created
+         when :mounted # (in fstab and mounted)
+           provider.unmount
+           syncothers # I guess it's more likely that the mount was originally mounted with
+                      # the wrong attributes so I sync AFTER the umount
+           return :mount_unmounted
+         else
+           raise Puppet::Error, "Unexpected change from #{current_value} to unmounted}"
          end
        end
  
+       #  IS        -> SHOULD     In Sync  Action
+       #  ghost     -> absent     NO       unmount
+       #  mounted   -> absent     NO       provider.destroy AND unmount
+       #  unmounted -> absent     NO       provider.destroy
        newvalue(:absent, :event => :mount_deleted) do
+         current_value = self.retrieve
          provider.unmount if provider.mounted?
- 
-         provider.destroy
+         provider.destroy unless current_value == :ghost
        end
  
+       #  IS        -> SHOULD     In Sync  Action
+       #  ghost     -> mounted    NO       provider.create
+       #  absent    -> mounted    NO       provider.create AND mount
+       #  unmounted -> mounted    NO       mount
        newvalue(:mounted, :event => :mount_mounted) do
          # Create the mount point if it does not already exist.
          current_value = self.retrieve
-         provider.create if current_value.nil? or current_value == :absent
+         provider.create if [nil, :absent, :ghost].include?(current_value)
  
          syncothers
  
@@@ -56,27 -82,16 +82,16 @@@
          provider.mount unless provider.mounted?
        end
  
+       # insync: mounted   -> present
+       #         unmounted -> present
        def insync?(is)
-         if should == :defined and is != :absent
+         if should == :defined and [:mounted,:unmounted].include?(is)
            true
          else
            super
          end
        end
  
-       def retrieve
-         # We need to special case :mounted; if we're absent, we still
-         # want
-         curval = super()
-         if curval == :absent
-           return :absent
-         elsif provider.mounted?
-           return :mounted
-         else
-           return :unmounted
-         end
-       end
- 
        def syncothers
          # We have to flush any changes to disk.
          currentvalues = @resource.retrieve_resource
@@@ -89,7 -104,7 +104,7 @@@
            if prop.name == :ensure
              false
            else
 -            ! prop.insync?(currentvalues[prop])
 +            ! prop.safe_insync?(currentvalues[prop])
            end
          end.each { |prop| prop.sync }.length
          @resource.flush if oos > 0
@@@ -200,7 -215,7 +215,7 @@@
        newvalues(:true, :false)
        defaultto do
          case Facter.value(:operatingsystem)
 -        when "FreeBSD", "Darwin"
 +        when "FreeBSD", "Darwin", "AIX"
            false
          else
            true
diff --combined spec/unit/provider/mount/parsed_spec.rb
index b4c2249,4d654fa..cf29bd3
--- a/spec/unit/provider/mount/parsed_spec.rb
+++ b/spec/unit/provider/mount/parsed_spec.rb
@@@ -5,15 -5,17 +5,17 @@@
  
  require File.dirname(__FILE__) + '/../../../spec_helper'
  
+ require 'puppet_spec/files'
  require 'puppettest/support/utils'
  require 'puppettest/fileparsing'
  
  module ParsedMountTesting
    include PuppetTest::Support::Utils
    include PuppetTest::FileParsing
+   include PuppetSpec::Files
  
    def fake_fstab
-     os = Facter['operatingsystem']
+     os = Facter.value(:operatingsystem)
      if os == "Solaris"
        name = "solaris.fstab"
      elsif os == "FreeBSD"
@@@ -22,161 -24,241 +24,254 @@@
        # Catchall for other fstabs
        name = "linux.fstab"
      end
      fakefile(File::join("data/types/mount", name))
    end
  
-   def mkmountargs
-     mount = nil
- 
-     if defined?(@pcount)
-       @pcount += 1
+   def fake_mountoutput
+     os = Facter.value(:operatingsystem)
+     if os == "Darwin"
+       name = "darwin.mount"
+     elsif os == "HP-UX"
+       name = "hpux.mount"
+     elsif os == "Solaris"
+       name = "solaris.mount"
++    elsif os == "AIX"
++      name = "aix.mount"
      else
-       @pcount = 1
-     end
-     args = {
-       :name => "/fspuppet#{@pcount}",
-       :device => "/dev/dsk#{@pcount}",
-     }
- 
-     @provider_class.fields(:parsed).each do |field|
-       args[field] = "fake#{field}#{@pcount}" unless args.include? field
+       # Catchall for other fstabs
+       name = "linux.mount"
      end
- 
-     args
+     fakefile(File::join("data/providers/mount/parsed", name))
    end
  
-   def mkmount
-     hash = mkmountargs
-     #hash[:provider] = @provider_class.name
- 
-     fakeresource = stub :type => :mount, :name => hash[:name]
-     fakeresource.stubs(:[]).with(:name).returns(hash[:name])
-     fakeresource.stubs(:should).with(:target).returns(nil)
- 
-     mount = @provider_class.new(fakeresource)
-     hash[:record_type] = :parsed
-     hash[:ensure] = :present
-     mount.property_hash = hash
- 
-     mount
-   end
- 
-   # Here we just create a fake host type that answers to all of the methods
-   # but does not modify our actual system.
-   def mkfaketype
-     @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
-   end
  end
  
  provider_class = Puppet::Type.type(:mount).provider(:parsed)
  
  describe provider_class do
+ 
    before :each do
      @mount_class = Puppet::Type.type(:mount)
-     @provider_class = @mount_class.provider(:parsed)
+     @provider = @mount_class.provider(:parsed)
    end
  
+   # LAK:FIXME I can't mock Facter because this test happens at parse-time.
+   it "should default to /etc/vfstab on Solaris" do
+     pending "This test only works on Solaris" unless Facter.value(:operatingsystem) == 'Solaris'
+     Puppet::Type.type(:mount).provider(:parsed).default_target.should == '/etc/vfstab'
+   end
  
-   describe provider_class do
-     include ParsedMountTesting
+   it "should default to /etc/fstab on anything else" do
+     pending "This test does not work on Solaris" if Facter.value(:operatingsystem) == 'Solaris'
+     Puppet::Type.type(:mount).provider(:parsed).default_target.should == '/etc/fstab'
+   end
  
-     it "should be able to parse all of the example mount tabs" do
-       tab = fake_fstab
-       @provider = @provider_class
+   describe "when parsing a line" do
  
-       # LAK:FIXME Again, a relatively bad test, but I don't know how to rspec-ify this.
-       # I suppose this is more of an integration test?  I dunno.
-       fakedataparse(tab) do
-         # Now just make we've got some mounts we know will be there
-         hashes = @provider_class.target_records(tab).find_all { |i| i.is_a? Hash }
-         (hashes.length > 0).should be_true
-         root = hashes.find { |i| i[:name] == "/" }
+     it "should not crash on incomplete lines in fstab" do
+       parse = @provider.parse <<-FSTAB
+ /dev/incomplete
+ /dev/device       name
+ FSTAB
+       lambda{ @provider.to_line(parse[0]) }.should_not raise_error
+     end
+ 
+ 
+     describe "on Solaris", :if => Facter.value(:operatingsystem) == 'Solaris' do
  
-         proc { @provider_class.to_file(hashes) }.should_not raise_error
+       before :each do
+         @example_line = "/dev/dsk/c0d0s0 /dev/rdsk/c0d0s0 \t\t    /  \t    ufs     1 no\t-"
        end
-     end
  
-     # LAK:FIXME I can't mock Facter because this test happens at parse-time.
-     it "should default to /etc/vfstab on Solaris and /etc/fstab everywhere else" do
-       should = case Facter.value(:operatingsystem)
-         when "Solaris"; "/etc/vfstab"
-         else
-           "/etc/fstab"
-         end
-       Puppet::Type.type(:mount).provider(:parsed).default_target.should == should
-     end
+       it "should extract device from the first field" do
+         @provider.parse_line(@example_line)[:device].should == '/dev/dsk/c0d0s0'
+       end
  
-     it "should not crash on incomplete lines in fstab" do
-       parse = @provider_class.parse <<-FSTAB
- /dev/incomplete
- /dev/device       name
-       FSTAB
+       it "should extract blockdevice from second field" do
+         @provider.parse_line(@example_line)[:blockdevice].should == "/dev/rdsk/c0d0s0"
+       end
+ 
+       it "should extract name from third field" do
+         @provider.parse_line(@example_line)[:name].should == "/"
+       end
+ 
+       it "should extract fstype from fourth field" do
+         @provider.parse_line(@example_line)[:fstype].should == "ufs"
+       end
+ 
+       it "should extract pass from fifth field" do
+         @provider.parse_line(@example_line)[:pass].should == "1"
+       end
+ 
+       it "should extract atboot from sixth field" do
+         @provider.parse_line(@example_line)[:atboot].should == "no"
+       end
+ 
+       it "should extract options from seventh field" do
+         @provider.parse_line(@example_line)[:options].should == "-"
+       end
  
-       lambda{ @provider_class.to_line(parse[0]) }.should_not raise_error
      end
-   end
  
-   describe provider_class, " when mounting an absent filesystem" do
-     include ParsedMountTesting
+     describe "on other platforms than Solaris", :if => Facter.value(:operatingsystem) != 'Solaris' do
+ 
+       before :each do
+         @example_line = "/dev/vg00/lv01\t/spare   \t  \t   ext3    defaults\t1 2"
+       end
+ 
+       it "should extract device from the first field" do
+         @provider.parse_line(@example_line)[:device].should == '/dev/vg00/lv01'
+       end
+ 
+       it "should extract name from second field" do
+         @provider.parse_line(@example_line)[:name].should == "/spare"
+       end
+ 
+       it "should extract fstype from third field" do
+         @provider.parse_line(@example_line)[:fstype].should == "ext3"
+       end
  
-     # #730 - Make sure 'flush' is called when a mount is moving from absent to mounted
-     it "should flush the fstab to disk" do
-       mount = mkmount
+       it "should extract options from fourth field" do
+         @provider.parse_line(@example_line)[:options].should == "defaults"
+       end
  
-       # Mark the mount as absent
-       mount.property_hash[:ensure] = :absent
+       it "should extract dump from fifth field" do
+         @provider.parse_line(@example_line)[:dump].should == "1"
+       end
  
-       mount.stubs(:mountcmd) # just so we don't actually try to mount anything
+       it "should extract options from sixth field" do
+         @provider.parse_line(@example_line)[:pass].should == "2"
+       end
  
-       mount.expects(:flush)
-       mount.mount
      end
+ 
    end
  
-   describe provider_class, " when modifying the filesystem tab" do
+   describe "mountinstances" do
      include ParsedMountTesting
-     before do
-       Puppet.settings.stubs(:use)
-       # Never write to disk, only to RAM.
-       #@provider_class.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
-       @provider_class.stubs(:target_object).returns(Puppet::Util::FileType.filetype(:ram).new("eh"))
-       @provider_class.clear
  
-       @mount = mkmount
-       @target = @provider_class.default_target
+     it "should get name from mountoutput found on Solaris" do
+       Facter.stubs(:value).with(:operatingsystem).returns 'Solaris'
+       @provider.stubs(:mountcmd).returns(File.read(fake_mountoutput))
+       mounts = @provider.mountinstances
+       mounts.size.should == 6
+       mounts[0].should == { :name => '/', :mounted => :yes }
+       mounts[1].should == { :name => '/proc', :mounted => :yes }
+       mounts[2].should == { :name => '/etc/mnttab', :mounted => :yes }
+       mounts[3].should == { :name => '/tmp', :mounted => :yes }
+       mounts[4].should == { :name => '/export/home', :mounted => :yes }
+       mounts[5].should == { :name => '/ghost', :mounted => :yes }
+     end
+ 
+     it "should get name from mountoutput found on HP-UX" do
+       Facter.stubs(:value).with(:operatingsystem).returns 'HP-UX'
+       @provider.stubs(:mountcmd).returns(File.read(fake_mountoutput))
+       mounts = @provider.mountinstances
+       mounts.size.should == 17
+       mounts[0].should == { :name => '/', :mounted => :yes }
+       mounts[1].should == { :name => '/devices', :mounted => :yes }
+       mounts[2].should == { :name => '/dev', :mounted => :yes }
+       mounts[3].should == { :name => '/system/contract', :mounted => :yes }
+       mounts[4].should == { :name => '/proc', :mounted => :yes }
+       mounts[5].should == { :name => '/etc/mnttab', :mounted => :yes }
+       mounts[6].should == { :name => '/etc/svc/volatile', :mounted => :yes }
+       mounts[7].should == { :name => '/system/object', :mounted => :yes }
+       mounts[8].should == { :name => '/etc/dfs/sharetab', :mounted => :yes }
+       mounts[9].should == { :name => '/lib/libc.so.1', :mounted => :yes }
+       mounts[10].should == { :name => '/dev/fd', :mounted => :yes }
+       mounts[11].should == { :name => '/tmp', :mounted => :yes }
+       mounts[12].should == { :name => '/var/run', :mounted => :yes }
+       mounts[13].should == { :name => '/export', :mounted => :yes }
+       mounts[14].should == { :name => '/export/home', :mounted => :yes }
+       mounts[15].should == { :name => '/rpool', :mounted => :yes }
+       mounts[16].should == { :name => '/ghost', :mounted => :yes }
+     end
+ 
+     it "should get name from mountoutput found on Darwin" do
+       Facter.stubs(:value).with(:operatingsystem).returns 'Darwin'
+       @provider.stubs(:mountcmd).returns(File.read(fake_mountoutput))
+       mounts = @provider.mountinstances
+       mounts.size.should == 6
+       mounts[0].should == { :name => '/', :mounted => :yes }
+       mounts[1].should == { :name => '/dev', :mounted => :yes }
+       mounts[2].should == { :name => '/net', :mounted => :yes }
+       mounts[3].should == { :name => '/home', :mounted => :yes }
+       mounts[4].should == { :name => '/usr', :mounted => :yes }
+       mounts[5].should == { :name => '/ghost', :mounted => :yes }
      end
  
-     it "should write the mount to disk when :flush is called" do
-       old_text = @provider_class.target_object(@provider_class.default_target).read
+     it "should get name from mountoutput found on Linux" do
+       Facter.stubs(:value).with(:operatingsystem).returns 'Gentoo'
+       @provider.stubs(:mountcmd).returns(File.read(fake_mountoutput))
+       mounts = @provider.mountinstances
+       mounts[0].should == { :name => '/', :mounted => :yes }
+       mounts[1].should == { :name => '/lib64/rc/init.d', :mounted => :yes }
+       mounts[2].should == { :name => '/sys', :mounted => :yes }
+       mounts[3].should == { :name => '/usr/portage', :mounted => :yes }
+       mounts[4].should == { :name => '/ghost', :mounted => :yes }
+     end
  
-       @mount.flush
++    it "should get name from mountoutput found on AIX" do
++      Facter.stubs(:value).with(:operatingsystem).returns 'AIX'
++      @provider.stubs(:mountcmd).returns(File.read(fake_mountoutput))
++      mounts = @provider.mountinstances
++      mounts[0].should == { :name => '/', :mounted => :yes }
++      mounts[1].should == { :name => '/tmp', :mounted => :yes }
++      mounts[2].should == { :name => '/home', :mounted => :yes }
++      mounts[3].should == { :name => '/usr', :mounted => :yes }
++      mounts[4].should == { :name => '/usr/code', :mounted => :yes }
++    end
 +
-       text = @provider_class.target_object(@provider_class.default_target).read
-       text.should == old_text + @mount.class.to_line(@mount.property_hash) + "\n"
+     it "should raise an error if a line is not understandable" do
+       @provider.stubs(:mountcmd).returns("bazinga!")
+       lambda { @provider.mountinstances }.should raise_error Puppet::Error
      end
+ 
    end
  
-   describe provider_class, " when parsing information about the root filesystem", :if => Facter["operatingsystem"].value != "Darwin" do
+   describe "when prefetching" do
      include ParsedMountTesting
  
-     before do
-       @mount = @mount_class.new :name => "/"
-       @provider = @mount.provider
+     before :each do
+       # Note: we have to stub default_target before creating resources
+       # because it is used by Puppet::Type::Mount.new to populate the
+       # :target property.
+       @provider.stubs(:default_target).returns fake_fstab
+ 
+       @res_ghost = Puppet::Type::Mount.new(:name => '/ghost')    # in no fake fstab
+       @res_mounted = Puppet::Type::Mount.new(:name => '/')       # in every fake fstab
+       @res_unmounted = Puppet::Type::Mount.new(:name => '/boot') # in every fake fstab
+       @res_absent = Puppet::Type::Mount.new(:name => '/absent')  # in no fake fstab
+ 
+       # Simulate transaction.rb:prefetch
+       @resource_hash = {}
+       [@res_ghost, @res_mounted, @res_unmounted, @res_absent].each do |resource|
+         @resource_hash[resource.name] = resource
+       end
+ 
+       @provider.stubs(:mountcmd).returns File.read(fake_mountoutput)
      end
  
-     it "should have a filesystem tab" do
-       FileTest.should be_exist(@provider_class.default_target)
+     it "should set :ensure to :unmounted if found in fstab but not mounted" do
+       @provider.prefetch(@resource_hash)
+       @res_unmounted.provider.get(:ensure).should == :unmounted
      end
  
-     it "should find the root filesystem" do
-       @provider_class.prefetch("/" => @mount)
-       @mount.provider.property_hash[:ensure].should == :present
+     it "should set :ensure to :mounted if found in fstab and mounted" do
+       @provider.prefetch(@resource_hash)
+       @res_ghost.provider.get(:ensure).should == :ghost
      end
  
-     it "should determine that the root fs is mounted" do
-       @provider_class.prefetch("/" => @mount)
-       @mount.provider.should be_mounted
+     it "should set :ensure to :ghost if not found in fstab but mounted" do
+       @provider.prefetch(@resource_hash)
+       @res_mounted.provider.get(:ensure).should == :mounted
      end
+ 
+     it "should set :ensure to :absent if not found in fstab and not mounted" do
+       @provider.prefetch(@resource_hash)
+       @res_absent.provider.get(:ensure).should == :absent
+     end
+ 
    end
+ 
  end
diff --combined spec/unit/type/mount_spec.rb
index 0d74042,45a6b6f..7f9a0eb
--- a/spec/unit/type/mount_spec.rb
+++ b/spec/unit/type/mount_spec.rb
@@@ -11,10 -11,14 +11,14 @@@ describe Puppet::Type.type(:mount) d
      mount = Puppet::Type.type(:mount).new(:name => "yay")
      mount.should(:ensure).should be_nil
    end
+ 
+   it "should have :name as the only keyattribut" do
+     Puppet::Type.type(:mount).key_attributes.should == [:name]
+   end
  end
  
  describe Puppet::Type.type(:mount), "when validating attributes" do
-   [:name, :remounts].each do |param|
+   [:name, :remounts, :provider].each do |param|
      it "should have a #{param} parameter" do
        Puppet::Type.type(:mount).attrtype(param).should == :param
      end
@@@ -38,9 -42,16 +42,16 @@@ describe Puppet::Type.type(:mount)::Ens
      mount.should(:ensure).should == :defined
    end
  
+   it "should support :present as a value to :ensure" do
+     Puppet::Type.type(:mount).new(:name => "yay", :ensure => :present)
+   end
+ 
+   it "should support :defined as a value to :ensure" do
+     Puppet::Type.type(:mount).new(:name => "yay", :ensure => :defined)
+   end
+ 
    it "should support :unmounted as a value to :ensure" do
-     mount = Puppet::Type.type(:mount).new(:name => "yay", :ensure => :unmounted)
-     mount.should(:ensure).should == :unmounted
+     Puppet::Type.type(:mount).new(:name => "yay", :ensure => :unmounted)
    end
  
    it "should support :absent as a value to :ensure" do
@@@ -74,134 -85,150 +85,149 @@@ describe Puppet::Type.type(:mount)::Ens
      end
    end
  
-   describe Puppet::Type.type(:mount)::Ensure, "when retrieving its current state" do
+   describe Puppet::Type.type(:mount)::Ensure, "when changing the host" do
  
-     it "should return the provider's value if it is :absent" do
-       @provider.expects(:ensure).returns(:absent)
-       @ensure.retrieve.should == :absent
-     end
+     def test_ensure_change(options)
+       @provider.stubs(:get).with(:ensure).returns options[:from]
+       @provider.stubs(:ensure).returns options[:from]
+       @provider.stubs(:mounted?).returns([:mounted,:ghost].include? options[:from])
+       @provider.expects(:create).times(options[:create] || 0)
+       @provider.expects(:destroy).times(options[:destroy] || 0)
+       @provider.expects(:mount).times(options[:mount] || 0)
+       @provider.expects(:unmount).times(options[:unmount] || 0)
+       @ensure.stubs(:syncothers)
+       @ensure.should = options[:to]
+       @ensure.sync
+    end
+ 
+    it "should create itself when changing from :ghost to :present" do
+      test_ensure_change(:from => :ghost, :to => :present, :create => 1)
+    end
+ 
+    it "should create itself when changing from :absent to :present" do
+      test_ensure_change(:from => :absent, :to => :present, :create => 1)
+    end
  
-     it "should return :mounted if the provider indicates it is mounted and the value is not :absent" do
-       @provider.expects(:ensure).returns(:present)
-       @provider.expects(:mounted?).returns(true)
-       @ensure.retrieve.should == :mounted
-     end
+    it "should create itself and unmount when changing from :ghost to :unmounted" do
+      test_ensure_change(:from => :ghost, :to => :unmounted, :create => 1, :unmount => 1)
+    end
  
-     it "should return :unmounted if the provider indicates it is not mounted and the value is not :absent" do
-       @provider.expects(:ensure).returns(:present)
-       @provider.expects(:mounted?).returns(false)
-       @ensure.retrieve.should == :unmounted
-     end
-   end
+    it "should unmount resource when changing from :mounted to :unmounted" do
+      test_ensure_change(:from => :mounted, :to => :unmounted, :unmount => 1)
+    end
+ 
+    it "should create itself when changing from :absent to :unmounted" do
+      test_ensure_change(:from => :absent, :to => :unmounted, :create => 1)
+    end
+ 
+    it "should unmount resource when changing from :ghost to :absent" do
+      test_ensure_change(:from => :ghost, :to => :absent, :unmount => 1)
+    end
+ 
+    it "should unmount and destroy itself when changing from :mounted to :absent" do
+      test_ensure_change(:from => :mounted, :to => :absent, :destroy => 1, :unmount => 1)
+    end
+ 
+    it "should destroy itself when changing from :unmounted to :absent" do
+      test_ensure_change(:from => :unmounted, :to => :absent, :destroy => 1)
+    end
  
-   describe Puppet::Type.type(:mount)::Ensure, "when changing the host" do
+    it "should create itself when changing from :ghost to :mounted" do
+      test_ensure_change(:from => :ghost, :to => :mounted, :create => 1)
+    end
  
-     it "should destroy itself if it should be absent" do
-       @provider.stubs(:mounted?).returns(false)
-       @provider.expects(:destroy)
-       @ensure.should = :absent
-       @ensure.sync
-     end
+    it "should create itself and mount when changing from :absent to :mounted" do
+      test_ensure_change(:from => :absent, :to => :mounted, :create => 1, :mount => 1)
+    end
  
-     it "should unmount itself before destroying if it is mounted and should be absent" do
-       @provider.expects(:mounted?).returns(true)
-       @provider.expects(:unmount)
-       @provider.expects(:destroy)
-       @ensure.should = :absent
-       @ensure.sync
-     end
+    it "should mount resource when changing from :unmounted to :mounted" do
+      test_ensure_change(:from => :unmounted, :to => :mounted, :mount => 1)
+    end
  
-     it "should create itself if it is absent and should be defined" do
-       @provider.stubs(:ensure).returns(:absent)
-       @provider.stubs(:mounted?).returns(true)
  
-       @provider.stubs(:mounted?).returns(false)
-       @provider.expects(:create)
-       @ensure.should = :defined
-       @ensure.sync
-     end
+    it "should be in sync if it is :absent and should be :absent" do
+      @ensure.should = :absent
 -     @ensure.insync?(:absent).should == true
++     @ensure.safe_insync?(:absent).should == true
+    end
  
-     it "should not unmount itself if it is mounted and should be defined" do
-       @provider.stubs(:ensure).returns(:mounted)
-       @provider.stubs(:mounted?).returns(true)
+    it "should be out of sync if it is :absent and should be :defined" do
+      @ensure.should = :defined
 -     @ensure.insync?(:absent).should == false
++     @ensure.safe_insync?(:absent).should == false
+    end
  
-       @provider.stubs(:create)
-       @provider.expects(:mount).never
-       @provider.expects(:unmount).never
-       @ensure.should = :defined
-       @ensure.sync
-     end
+    it "should be out of sync if it is :absent and should be :mounted" do
+      @ensure.should = :mounted
 -     @ensure.insync?(:absent).should == false
++     @ensure.safe_insync?(:absent).should == false
+    end
  
-     it "should not mount itself if it is unmounted and should be defined" do
-       @provider.stubs(:ensure).returns(:unmounted)
-       @provider.stubs(:mounted?).returns(false)
+    it "should be out of sync if it is :absent and should be :unmounted" do
+      @ensure.should = :unmounted
 -     @ensure.insync?(:absent).should == false
++     @ensure.safe_insync?(:absent).should == false
+    end
  
-       @ensure.stubs(:syncothers)
-       @provider.stubs(:create)
-       @provider.expects(:mount).never
-       @provider.expects(:unmount).never
-       @ensure.should = :present
-       @ensure.sync
-     end
 -
+    it "should be out of sync if it is :mounted and should be :absent" do
+      @ensure.should = :absent
 -     @ensure.insync?(:mounted).should == false
++     @ensure.safe_insync?(:mounted).should == false
+    end
  
-     it "should unmount itself if it is mounted and should be unmounted" do
-       @provider.stubs(:ensure).returns(:present)
-       @provider.stubs(:mounted?).returns(true)
+    it "should be in sync if it is :mounted and should be :defined" do
+      @ensure.should = :defined
 -     @ensure.insync?(:mounted).should == true
++     @ensure.safe_insync?(:mounted).should == true
+    end
  
-       @ensure.stubs(:syncothers)
-       @provider.expects(:unmount)
-       @ensure.should = :unmounted
-       @ensure.sync
-     end
+    it "should be in sync if it is :mounted and should be :mounted" do
+      @ensure.should = :mounted
 -     @ensure.insync?(:mounted).should == true
++     @ensure.safe_insync?(:mounted).should == true
+    end
  
-     it "should create and mount itself if it does not exist and should be mounted" do
-       @provider.stubs(:ensure).returns(:absent)
-       @provider.stubs(:mounted?).returns(false)
-       @provider.expects(:create)
-       @ensure.stubs(:syncothers)
-       @provider.expects(:mount)
-       @ensure.should = :mounted
-       @ensure.sync
-     end
+    it "should be out in sync if it is :mounted and should be :unmounted" do
+      @ensure.should = :unmounted
 -     @ensure.insync?(:mounted).should == false
++     @ensure.safe_insync?(:mounted).should == false
+    end
  
-     it "should mount itself if it is present and should be mounted" do
-       @provider.stubs(:ensure).returns(:present)
-       @provider.stubs(:mounted?).returns(false)
-       @ensure.stubs(:syncothers)
-       @provider.expects(:mount)
-       @ensure.should = :mounted
-       @ensure.sync
-     end
  
-     it "should create but not mount itself if it is absent and mounted and should be mounted" do
-       @provider.stubs(:ensure).returns(:absent)
-       @provider.stubs(:mounted?).returns(true)
-       @ensure.stubs(:syncothers)
-       @provider.expects(:create)
-       @ensure.should = :mounted
-       @ensure.sync
-     end
+    it "should be out of sync if it is :unmounted and should be :absent" do
+      @ensure.should = :absent
 -     @ensure.insync?(:unmounted).should == false
++     @ensure.safe_insync?(:unmounted).should == false
+    end
  
-     it "should be insync if it is mounted and should be defined" do
-       @ensure.should = :defined
-       @ensure.safe_insync?(:mounted).should == true
-     end
+    it "should be in sync if it is :unmounted and should be :defined" do
+      @ensure.should = :defined
 -     @ensure.insync?(:unmounted).should == true
++     @ensure.safe_insync?(:unmounted).should == true
+    end
+ 
+    it "should be out of sync if it is :unmounted and should be :mounted" do
+      @ensure.should = :mounted
 -     @ensure.insync?(:unmounted).should == false
++     @ensure.safe_insync?(:unmounted).should == false
+    end
+ 
+    it "should be in sync if it is :unmounted and should be :unmounted" do
+      @ensure.should = :unmounted
 -     @ensure.insync?(:unmounted).should == true
++     @ensure.safe_insync?(:unmounted).should == true
+    end
  
-     it "should be insync if it is unmounted and should be defined" do
-       @ensure.should = :defined
-       @ensure.safe_insync?(:unmounted).should == true
-     end
  
-     it "should be insync if it is mounted and should be present" do
-       @ensure.should = :present
-       @ensure.safe_insync?(:mounted).should == true
-     end
+    it "should be out of sync if it is :ghost and should be :absent" do
+      @ensure.should = :absent
 -     @ensure.insync?(:ghost).should == false
++     @ensure.safe_insync?(:ghost).should == false
+    end
  
-     it "should be insync if it is unmounted and should be present" do
-       @ensure.should = :present
-       @ensure.safe_insync?(:unmounted).should == true
-     end
-   end
+    it "should be out of sync if it is :ghost and should be :defined" do
+      @ensure.should = :defined
 -     @ensure.insync?(:ghost).should == false
++     @ensure.safe_insync?(:ghost).should == false
+    end
+ 
+    it "should be out of sync if it is :ghost and should be :mounted" do
+      @ensure.should = :mounted
 -     @ensure.insync?(:ghost).should == false
++     @ensure.safe_insync?(:ghost).should == false
+    end
+ 
+    it "should be out of sync if it is :ghost and should be :unmounted" do
+      @ensure.should = :unmounted
 -     @ensure.insync?(:ghost).should == false
++     @ensure.safe_insync?(:ghost).should == false
+    end
+ 
+  end
  
    describe Puppet::Type.type(:mount), "when responding to events" do
  
@@@ -258,4 -285,49 +284,49 @@@ describe Puppet::Type.type(:mount), "wh
  
      @catalog.apply
    end
+ 
+   it "should flush changes before mounting" do
+     syncorder = sequence('syncorder')
+     @mount.provider.expects(:options).returns 'soft'
+     @mount.provider.expects(:ensure).returns :unmounted
+     @mount.provider.expects(:mounted?).returns false
+ 
+     @mount.provider.expects(:options=).in_sequence(syncorder).with 'hard'
+     @mount.expects(:flush).in_sequence(syncorder) # Have to write with no options
+     @mount.provider.expects(:mount).in_sequence(syncorder)
+     @mount.expects(:flush).in_sequence(syncorder) # Call flush again cause we changed everything
+ 
+     @mount[:ensure] = :mounted
+     @mount[:options] = 'hard'
+ 
+     @catalog.apply
+   end
+ 
+   it "should not flush before mounting if there are no other changes" do
+     syncorder = sequence('syncorder')
+     @mount.provider.expects(:ensure).returns :unmounted
+     @mount.provider.expects(:mounted?).returns false
+     @mount.provider.expects(:mount).in_sequence(syncorder)
+     @mount.expects(:flush).in_sequence(syncorder) # Call flush cause we changed everything
+ 
+     @mount[:ensure] = :mounted
+     @catalog.apply
+   end
+ 
+   it "should umount before flushing changes to disk" do
+     syncorder = sequence('syncorder')
+     @mount.provider.expects(:options).returns 'soft'
+     @mount.provider.expects(:ensure).returns :mounted
+ 
+     @mount.provider.expects(:unmount).in_sequence(syncorder)
+     @mount.provider.expects(:options=).in_sequence(syncorder).with 'hard'
+     @mount.expects(:flush).in_sequence(syncorder) # Call inside syncothers
+     @mount.expects(:flush).in_sequence(syncorder) # I guess transaction or anything calls flush again
+ 
+     @mount[:ensure] = :unmounted
+     @mount[:options] = 'hard'
+ 
+     @catalog.apply
+   end
+ 
  end
diff --combined test/data/providers/mount/parsed/aix.mount
index 380dbc5,0000000..380dbc5
mode 100644,000000..100644
--- a/test/data/providers/mount/parsed/aix.mount
+++ b/test/data/providers/mount/parsed/aix.mount
@@@ -1,7 -1,0 +1,7 @@@
 +node   mounted          mounted over  vfs    date              options   
 +----   -------          ------------ ---  ------------   -------------------
 +       /dev/hd0         /            jfs   Dec 17 08:04   rw, log  =/dev/hd8
 +       /dev/hd3         /tmp         jfs   Dec 17 08:04   rw, log  =/dev/hd8
 +       /dev/hd1         /home        jfs   Dec 17 08:06   rw, log  =/dev/hd8
 +       /dev/hd2         /usr         jfs   Dec 17 08:06   rw, log  =/dev/hd8
 +sue    /home/local/src  /usr/code    nfs   Dec 17 08:06   ro, log  =/dev/hd8

-- 
Puppet packaging for Debian



More information about the Pkg-puppet-devel mailing list