summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Berry <paul@puppetlabs.com>2011-02-28 13:13:52 -0800
committerPaul Berry <paul@puppetlabs.com>2011-02-28 13:13:52 -0800
commitecb953646b2defbab3bbc53a58ce7ba98d560b50 (patch)
treec86769e10eade8ffb7bcc6e94299416ac2e709f7
parenta949a83c4f100be0254fadcb915f418f73705861 (diff)
parent23a510a321e47a98768dc47f95cfa0bd8c1a314c (diff)
downloadpuppet-ecb953646b2defbab3bbc53a58ce7ba98d560b50.tar.gz
puppet-ecb953646b2defbab3bbc53a58ce7ba98d560b50.tar.xz
puppet-ecb953646b2defbab3bbc53a58ce7ba98d560b50.zip
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
-rw-r--r--lib/puppet/provider/mount.rb28
-rwxr-xr-xlib/puppet/provider/mount/parsed.rb62
-rwxr-xr-xlib/puppet/type/mount.rb55
-rwxr-xr-xspec/unit/provider/mount/parsed_spec.rb307
-rwxr-xr-xspec/unit/provider/mount_spec.rb107
-rwxr-xr-xspec/unit/type/mount_spec.rb291
-rw-r--r--test/data/providers/mount/parsed/aix.mount7
-rw-r--r--test/data/providers/mount/parsed/darwin.mount6
-rw-r--r--test/data/providers/mount/parsed/hpux.mount17
-rw-r--r--test/data/providers/mount/parsed/linux.mount5
-rw-r--r--test/data/providers/mount/parsed/solaris.mount6
-rw-r--r--test/data/types/mount/linux.fstab1
-rw-r--r--test/data/types/mount/solaris.fstab1
13 files changed, 586 insertions, 307 deletions
diff --git a/lib/puppet/provider/mount.rb b/lib/puppet/provider/mount.rb
index 354ddb16d..65296eed2 100644
--- a/lib/puppet/provider/mount.rb
+++ b/lib/puppet/provider/mount.rb
@@ -14,8 +14,11 @@ module Puppet::Provider::Mount
args << "-o" << self.options if self.options and self.options != :absent
args << resource[:name]
- flush if respond_to?(:flush)
mountcmd(*args)
+ case get(:ensure)
+ when :absent; set(:ensure => :ghost)
+ when :unmounted; set(:ensure => :mounted)
+ end
end
def remount
@@ -30,24 +33,17 @@ module Puppet::Provider::Mount
# This only works when the mount point is synced to the fstab.
def unmount
- umount resource[:name]
+ umount(resource[:name])
+
+ # Update property hash for future queries (e.g. refresh is called)
+ case get(:ensure)
+ when :mounted; set(:ensure => :unmounted)
+ when :ghost; set(:ensure => :absent)
+ end
end
# Is the mount currently mounted?
def mounted?
- platform = Facter.value("operatingsystem")
- name = resource[:name]
- mounts = mountcmd.split("\n").find do |line|
- case platform
- when "Darwin"
- line =~ / on #{name} / or line =~ %r{ on /private/var/automount#{name}}
- when "Solaris", "HP-UX"
- line =~ /^#{name} on /
- when "AIX"
- line.split(/\s+/)[2] == name
- else
- line =~ / on #{name} /
- end
- end
+ [:mounted, :ghost].include?(get(:ensure))
end
end
diff --git a/lib/puppet/provider/mount/parsed.rb b/lib/puppet/provider/mount/parsed.rb
index 69a6fc06b..42e543c15 100755
--- a/lib/puppet/provider/mount/parsed.rb
+++ b/lib/puppet/provider/mount/parsed.rb
@@ -18,8 +18,7 @@ Puppet::Type.type(:mount).provide(
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 +38,63 @@ Puppet::Type.type(:mount).provide(
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 = []
+ 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 --git a/lib/puppet/type/mount.rb b/lib/puppet/type/mount.rb
index da9a70bdf..98a1f2509 100755
--- a/lib/puppet/type/mount.rb
+++ b/lib/puppet/type/mount.rb
@@ -21,6 +21,11 @@ module Puppet
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 @@ module Puppet
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 @@ module Puppet
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
diff --git a/spec/unit/provider/mount/parsed_spec.rb b/spec/unit/provider/mount/parsed_spec.rb
index b4c2249fd..cf29bd358 100755
--- a/spec/unit/provider/mount/parsed_spec.rb
+++ b/spec/unit/provider/mount/parsed_spec.rb
@@ -5,15 +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,254 @@ module ParsedMountTesting
# Catchall for other fstabs
name = "linux.fstab"
end
- oldpath = @provider_class.default_target
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 --git a/spec/unit/provider/mount_spec.rb b/spec/unit/provider/mount_spec.rb
index f567a4a40..3fc8a8664 100755
--- a/spec/unit/provider/mount_spec.rb
+++ b/spec/unit/provider/mount_spec.rb
@@ -19,18 +19,13 @@ describe Puppet::Provider::Mount do
describe Puppet::Provider::Mount, " when mounting" do
- it "should use the 'mountcmd' method to mount" do
- @mounter.stubs(:options).returns(nil)
- @mounter.expects(:mountcmd)
-
- @mounter.mount
+ before :each do
+ @mounter.stubs(:get).with(:ensure).returns(:mounted)
end
- it "should flush before mounting if a flush method exists" do
- @mounter.meta_def(:flush) { }
- @mounter.expects(:flush)
- @mounter.stubs(:mountcmd)
+ it "should use the 'mountcmd' method to mount" do
@mounter.stubs(:options).returns(nil)
+ @mounter.expects(:mountcmd)
@mounter.mount
end
@@ -48,6 +43,23 @@ describe Puppet::Provider::Mount do
@mounter.mount
end
+
+ it "should update the :ensure state to :mounted if it was :unmounted before" do
+ @mounter.expects(:mountcmd)
+ @mounter.stubs(:options).returns(nil)
+ @mounter.expects(:get).with(:ensure).returns(:unmounted)
+ @mounter.expects(:set).with(:ensure => :mounted)
+ @mounter.mount
+ end
+
+ it "should update the :ensure state to :ghost if it was :absent before" do
+ @mounter.expects(:mountcmd)
+ @mounter.stubs(:options).returns(nil)
+ @mounter.expects(:get).with(:ensure).returns(:absent)
+ @mounter.expects(:set).with(:ensure => :ghost)
+ @mounter.mount
+ end
+
end
describe Puppet::Provider::Mount, " when remounting" do
@@ -77,69 +89,58 @@ describe Puppet::Provider::Mount do
describe Puppet::Provider::Mount, " when unmounting" do
+ before :each do
+ @mounter.stubs(:get).with(:ensure).returns(:unmounted)
+ end
+
it "should call the :umount command with the resource name" do
@mounter.expects(:umount).with(@name)
@mounter.unmount
end
- end
-
- describe Puppet::Provider::Mount, " when determining if it is mounted" do
-
- it "should parse the results of running the mount command with no arguments" do
- Facter.stubs(:value).returns("whatever")
- @mounter.expects(:mountcmd).returns("")
- @mounter.mounted?
+ it "should update the :ensure state to :absent if it was :ghost before" do
+ @mounter.expects(:umount).with(@name).returns true
+ @mounter.expects(:get).with(:ensure).returns(:ghost)
+ @mounter.expects(:set).with(:ensure => :absent)
+ @mounter.unmount
end
- it "should match ' on /private/var/automount<name>' if the operating system is Darwin" do
- Facter.stubs(:value).with("operatingsystem").returns("Darwin")
- @mounter.expects(:mountcmd).returns("/dev/whatever on /private/var/automount/\ndevfs on /dev")
-
- @mounter.should be_mounted
+ it "should update the :ensure state to :unmounted if it was :mounted before" do
+ @mounter.expects(:umount).with(@name).returns true
+ @mounter.expects(:get).with(:ensure).returns(:mounted)
+ @mounter.expects(:set).with(:ensure => :unmounted)
+ @mounter.unmount
end
- it "should match ' on <name>' if the operating system is Darwin" do
- Facter.stubs(:value).with("operatingsystem").returns("Darwin")
- @mounter.expects(:mountcmd).returns("/dev/disk03 on / (local, journaled)\ndevfs on /dev")
-
- @mounter.should be_mounted
- end
+ end
- it "should match '^<name> on' if the operating system is Solaris" do
- Facter.stubs(:value).with("operatingsystem").returns("Solaris")
- @mounter.expects(:mountcmd).returns("/ on /dev/dsk/whatever\n/var on /dev/dsk/other")
+ describe Puppet::Provider::Mount, " when determining if it is mounted" do
- @mounter.should be_mounted
+ it "should query the property_hash" do
+ @mounter.expects(:get).with(:ensure).returns(:mounted)
+ @mounter.mounted?
end
- it "should match '^<name> on' if the operating system is HP-UX" do
- Facter.stubs(:value).with("operatingsystem").returns("HP-UX")
- @mounter.expects(:mountcmd).returns("/ on /dev/dsk/whatever\n/var on /dev/dsk/other")
-
- @mounter.should be_mounted
+ it "should return true if prefetched value is :mounted" do
+ @mounter.stubs(:get).with(:ensure).returns(:mounted)
+ @mounter.mounted? == true
end
- it "should match mounted devices if the operating system is AIX" do
- Facter.stubs(:value).with("operatingsystem").returns("AIX")
- mount_data = File.read(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'unit', 'provider', 'mount', 'mount-output.aix.txt'))
- @mounter.expects(:mountcmd).returns(mount_data)
-
- @mounter.should be_mounted
+ it "should return true if prefetched value is :ghost" do
+ @mounter.stubs(:get).with(:ensure).returns(:ghost)
+ @mounter.mounted? == true
end
- it "should match ' on <name>' if the operating system is not Darwin, Solaris, or HP-UX" do
- Facter.stubs(:value).with("operatingsystem").returns("Debian")
- @mounter.expects(:mountcmd).returns("/dev/dsk/whatever on / and stuff\n/dev/other/disk on /var and stuff")
-
- @mounter.should be_mounted
+ it "should return false if prefetched value is :absent" do
+ @mounter.stubs(:get).with(:ensure).returns(:absent)
+ @mounter.mounted? == false
end
- it "should not be considered mounted if it did not match the mount output" do
- Facter.stubs(:value).with("operatingsystem").returns("Debian")
- @mounter.expects(:mountcmd).returns("/dev/dsk/whatever on /something/else and stuff\n/dev/other/disk on /var and stuff")
-
- @mounter.should_not be_mounted
+ it "should return false if prefetched value is :unmounted" do
+ @mounter.stubs(:get).with(:ensure).returns(:unmounted)
+ @mounter.mounted? == false
end
+
end
+
end
diff --git a/spec/unit/type/mount_spec.rb b/spec/unit/type/mount_spec.rb
index 0d74042e3..7f9a0eba6 100755
--- a/spec/unit/type/mount_spec.rb
+++ b/spec/unit/type/mount_spec.rb
@@ -11,10 +11,14 @@ describe Puppet::Type.type(:mount) do
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 @@ describe Puppet::Type.type(:mount)::Ensure, "when validating values" do
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,149 @@ describe Puppet::Type.type(:mount)::Ensure do
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.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.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.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.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.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.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.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.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.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.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.safe_insync?(:unmounted).should == false
+ end
+
+ it "should be in sync if it is :unmounted and should be :unmounted" do
+ @ensure.should = :unmounted
+ @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.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.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.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.safe_insync?(:ghost).should == false
+ end
+
+ end
describe Puppet::Type.type(:mount), "when responding to events" do
@@ -258,4 +284,49 @@ describe Puppet::Type.type(:mount), "when modifying an existing mount entry" do
@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 --git a/test/data/providers/mount/parsed/aix.mount b/test/data/providers/mount/parsed/aix.mount
new file mode 100644
index 000000000..380dbc5ae
--- /dev/null
+++ b/test/data/providers/mount/parsed/aix.mount
@@ -0,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
diff --git a/test/data/providers/mount/parsed/darwin.mount b/test/data/providers/mount/parsed/darwin.mount
new file mode 100644
index 000000000..1bdfcf89a
--- /dev/null
+++ b/test/data/providers/mount/parsed/darwin.mount
@@ -0,0 +1,6 @@
+/dev/disk0s2 on / (hfs, local, journaled)
+devfs on /dev (devfs, local, nobrowse)
+map -hosts on /net (autofs, nosuid, automounted, nobrowse)
+map auto_home on /home (autofs, automounted, nobrowse)
+/dev/disk0s3 on /usr (hfs, local, journaled)
+/dev/fake on /ghost (hfs, local, journaled)
diff --git a/test/data/providers/mount/parsed/hpux.mount b/test/data/providers/mount/parsed/hpux.mount
new file mode 100644
index 000000000..d414fa47a
--- /dev/null
+++ b/test/data/providers/mount/parsed/hpux.mount
@@ -0,0 +1,17 @@
+/ on rpool/ROOT/opensolaris read/write/setuid/devices/dev=2d90002 on Wed Dec 31 16:00:00 1969
+/devices on /devices read/write/setuid/devices/dev=4a00000 on Thu Feb 17 14:34:02 2011
+/dev on /dev read/write/setuid/devices/dev=4a40000 on Thu Feb 17 14:34:02 2011
+/system/contract on ctfs read/write/setuid/devices/dev=4ac0001 on Thu Feb 17 14:34:02 2011
+/proc on proc read/write/setuid/devices/dev=4b00000 on Thu Feb 17 14:34:02 2011
+/etc/mnttab on mnttab read/write/setuid/devices/dev=4b40001 on Thu Feb 17 14:34:02 2011
+/etc/svc/volatile on swap read/write/setuid/devices/xattr/dev=4b80001 on Thu Feb 17 14:34:02 2011
+/system/object on objfs read/write/setuid/devices/dev=4bc0001 on Thu Feb 17 14:34:02 2011
+/etc/dfs/sharetab on sharefs read/write/setuid/devices/dev=4c00001 on Thu Feb 17 14:34:02 2011
+/lib/libc.so.1 on /usr/lib/libc/libc_hwcap1.so.1 read/write/setuid/devices/dev=2d90002 on Thu Feb 17 14:34:14 2011
+/dev/fd on fd read/write/setuid/devices/dev=4d00001 on Thu Feb 17 14:34:18 2011
+/tmp on swap read/write/setuid/devices/xattr/dev=4b80002 on Thu Feb 17 14:34:19 2011
+/var/run on swap read/write/setuid/devices/xattr/dev=4b80003 on Thu Feb 17 14:34:19 2011
+/export on rpool/export read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90006 on Thu Feb 17 14:37:48 2011
+/export/home on rpool/export/home read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90007 on Thu Feb 17 14:37:48 2011
+/rpool on rpool read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90009 on Thu Feb 17 14:37:48 2011
+/ghost on /dev/fake read/write/setuid/devices/nonbmand/exec/xattr/atime/dev=2d90009 on Thu Feb 17 14:37:48 2011
diff --git a/test/data/providers/mount/parsed/linux.mount b/test/data/providers/mount/parsed/linux.mount
new file mode 100644
index 000000000..75dd71fd4
--- /dev/null
+++ b/test/data/providers/mount/parsed/linux.mount
@@ -0,0 +1,5 @@
+/dev/root on / type jfs (rw,noatime)
+rc-svcdir on /lib64/rc/init.d type tmpfs (rw,nosuid,nodev,noexec,relatime,size=1024k,mode=755)
+sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
+/dev/sda9 on /usr/portage type jfs (rw)
+/dev/fake on /ghost type jfs (rw)
diff --git a/test/data/providers/mount/parsed/solaris.mount b/test/data/providers/mount/parsed/solaris.mount
new file mode 100644
index 000000000..26fabc575
--- /dev/null
+++ b/test/data/providers/mount/parsed/solaris.mount
@@ -0,0 +1,6 @@
+/ on /dev/dsk/c0t0d0s0 read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200000 on Mon Mar 18 08:48:45 2002
+/proc on /proc read/write/setuid/dev=4300000 on Mon Mar 18 08:48:44 2002
+/etc/mnttab on mnttab read/write/setuid/dev=43c0000 on Mon Mar 18 08:48:44 2002
+/tmp on swap read/write/setuid/xattr/dev=2 on Mon Mar 18 08:48:52 2002
+/export/home on /dev/dsk/c0t0d0s7 read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200007 on Mon Mar 18
+/ghost on /dev/dsk/c0t1d0s7 read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200007 on Mon Mar 18
diff --git a/test/data/types/mount/linux.fstab b/test/data/types/mount/linux.fstab
index b1debff9c..c94ec7fa8 100644
--- a/test/data/types/mount/linux.fstab
+++ b/test/data/types/mount/linux.fstab
@@ -9,3 +9,4 @@ proc /proc proc defaults 0 0
/dev/vg00/lv01 /spare ext3 defaults 1 2
sysfs /sys sysfs defaults 0 0
LABEL=SWAP-hda6 swap swap defaults 0 0
+/dev/sda1 /usr xfs noatime 0 0
diff --git a/test/data/types/mount/solaris.fstab b/test/data/types/mount/solaris.fstab
index 54afc898c..348b9d50b 100644
--- a/test/data/types/mount/solaris.fstab
+++ b/test/data/types/mount/solaris.fstab
@@ -9,3 +9,4 @@ fd - /dev/fd fd - no -
ctfs - /system/contract ctfs - no -
objfs - /system/object objfs - no -
#swap - /tmp tmpfs - yes -
+/dev/dsk/c0d0s2 /dev/rdsk/c0d0s2 /usr ufs 1 no -