diff --git a/spec/unit/type/mount_spec.rb b/spec/unit/type/mount_spec.rb index ce82cb516..45a6b6f5c 100755 --- a/spec/unit/type/mount_spec.rb +++ b/spec/unit/type/mount_spec.rb @@ -1,261 +1,333 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../spec_helper' describe Puppet::Type.type(:mount) do it "should have a :refreshable feature that requires the :remount method" do Puppet::Type.type(:mount).provider_feature(:refreshable).methods.should == [:remount] end it "should have no default value for :ensure" 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 end [:ensure, :device, :blockdevice, :fstype, :options, :pass, :dump, :atboot, :target].each do |param| it "should have a #{param} property" do Puppet::Type.type(:mount).attrtype(param).should == :property end end end describe Puppet::Type.type(:mount)::Ensure, "when validating values" do before do @provider = stub 'provider', :class => Puppet::Type.type(:mount).defaultprovider, :clear => nil Puppet::Type.type(:mount).defaultprovider.expects(:new).returns(@provider) end it "should alias :present to :defined as a value to :ensure" do mount = Puppet::Type.type(:mount).new(:name => "yay", :ensure => :present) 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 Puppet::Type.type(:mount).new(:name => "yay", :ensure => :absent) end it "should support :mounted as a value to :ensure" do Puppet::Type.type(:mount).new(:name => "yay", :ensure => :mounted) end end describe Puppet::Type.type(:mount)::Ensure do before :each do @provider = stub 'provider', :class => Puppet::Type.type(:mount).defaultprovider, :clear => nil, :satisfies? => true, :name => :mock Puppet::Type.type(:mount).defaultprovider.stubs(:new).returns(@provider) @mount = Puppet::Type.type(:mount).new(:name => "yay", :check => :ensure) @ensure = @mount.property(:ensure) end def mount_stub(params) Puppet::Type.type(:mount).validproperties.each do |prop| unless params[prop] params[prop] = :absent @mount[prop] = :absent end end params.each do |param, value| @provider.stubs(param).returns(value) 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 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 when changing from :ghost to :present" do + test_ensure_change(:from => :ghost, :to => :present, :create => 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 create itself when changing from :absent to :present" do + test_ensure_change(:from => :absent, :to => :present, :create => 1) + end - describe Puppet::Type.type(:mount)::Ensure, "when changing the host" do + 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 destroy itself if it should be absent" do - @provider.stubs(:mounted?).returns(false) - @provider.expects(:destroy) - @ensure.should = :absent - @ensure.sync - end + it "should unmount resource when changing from :mounted to :unmounted" do + test_ensure_change(:from => :mounted, :to => :unmounted, :unmount => 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 create itself when changing from :absent to :unmounted" do + test_ensure_change(:from => :absent, :to => :unmounted, :create => 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) + it "should unmount resource when changing from :ghost to :absent" do + test_ensure_change(:from => :ghost, :to => :absent, :unmount => 1) + end - @provider.stubs(:mounted?).returns(false) - @provider.expects(:create) - @ensure.should = :defined - @ensure.sync - 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 not unmount itself if it is mounted and should be defined" do - @provider.stubs(:ensure).returns(:mounted) - @provider.stubs(:mounted?).returns(true) + it "should destroy itself when changing from :unmounted to :absent" do + test_ensure_change(:from => :unmounted, :to => :absent, :destroy => 1) + end - @provider.stubs(:create) - @provider.expects(:mount).never - @provider.expects(:unmount).never - @ensure.should = :defined - @ensure.sync - end + it "should create itself when changing from :ghost to :mounted" do + test_ensure_change(:from => :ghost, :to => :mounted, :create => 1) + 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 create itself and mount when changing from :absent to :mounted" do + test_ensure_change(:from => :absent, :to => :mounted, :create => 1, :mount => 1) + end - @ensure.stubs(:syncothers) - @provider.stubs(:create) - @provider.expects(:mount).never - @provider.expects(:unmount).never - @ensure.should = :present - @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 unmount itself if it is mounted and should be unmounted" do - @provider.stubs(:ensure).returns(:present) - @provider.stubs(:mounted?).returns(true) - @ensure.stubs(:syncothers) - @provider.expects(:unmount) - @ensure.should = :unmounted - @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 + 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 of sync if it is :absent and should be :defined" do + @ensure.should = :defined + @ensure.insync?(:absent).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 be out of sync if it is :absent and should be :mounted" do + @ensure.should = :mounted + @ensure.insync?(:absent).should == false + 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 :absent and should be :unmounted" do + @ensure.should = :unmounted + @ensure.insync?(:absent).should == false + end - it "should be insync if it is mounted and should be defined" do - @ensure.should = :defined - @ensure.insync?(:mounted).should == true - end - it "should be insync if it is unmounted and should be defined" do - @ensure.should = :defined - @ensure.insync?(:unmounted).should == true - end + it "should be out of sync if it is :mounted and should be :absent" do + @ensure.should = :absent + @ensure.insync?(:mounted).should == false + end - it "should be insync if it is mounted and should be present" do - @ensure.should = :present - @ensure.insync?(:mounted).should == true - end + it "should be in sync if it is :mounted and should be :defined" do + @ensure.should = :defined + @ensure.insync?(:mounted).should == true + end - it "should be insync if it is unmounted and should be present" do - @ensure.should = :present - @ensure.insync?(:unmounted).should == true - end - end + it "should be in sync if it is :mounted and should be :mounted" do + @ensure.should = :mounted + @ensure.insync?(:mounted).should == true + end + + it "should be out in sync if it is :mounted and should be :unmounted" do + @ensure.should = :unmounted + @ensure.insync?(:mounted).should == false + end + + + it "should be out of sync if it is :unmounted and should be :absent" do + @ensure.should = :absent + @ensure.insync?(:unmounted).should == false + end + + it "should be in sync if it is :unmounted and should be :defined" do + @ensure.should = :defined + @ensure.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 + end + + it "should be in sync if it is :unmounted and should be :unmounted" do + @ensure.should = :unmounted + @ensure.insync?(:unmounted).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 + end + + it "should be out of sync if it is :ghost and should be :defined" do + @ensure.should = :defined + @ensure.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 + end + + it "should be out of sync if it is :ghost and should be :unmounted" do + @ensure.should = :unmounted + @ensure.insync?(:ghost).should == false + end + + end describe Puppet::Type.type(:mount), "when responding to events" do it "should remount if it is currently mounted" do @provider.expects(:mounted?).returns(true) @provider.expects(:remount) @mount.refresh end it "should not remount if it is not currently mounted" do @provider.expects(:mounted?).returns(false) @provider.expects(:remount).never @mount.refresh end it "should not remount swap filesystems" do @mount[:fstype] = "swap" @provider.expects(:remount).never @mount.refresh end end end describe Puppet::Type.type(:mount), "when modifying an existing mount entry" do before do @provider = stub 'provider', :class => Puppet::Type.type(:mount).defaultprovider, :clear => nil, :satisfies? => true, :name => :mock, :remount => nil Puppet::Type.type(:mount).defaultprovider.stubs(:new).returns(@provider) @mount = Puppet::Type.type(:mount).new(:name => "yay", :ensure => :mounted) {:device => "/foo/bar", :blockdevice => "/other/bar", :target => "/what/ever", :fstype => 'eh', :options => "", :pass => 0, :dump => 0, :atboot => 0, :ensure => :mounted}.each do |param, value| @mount.provider.stubs(param).returns value @mount[param] = value end @mount.provider.stubs(:mounted?).returns true # stub this to not try to create state.yaml Puppet::Util::Storage.stubs(:store) @catalog = Puppet::Resource::Catalog.new @catalog.add_resource @mount end it "should use the provider to change the dump value" do @mount.provider.expects(:dump).returns 0 @mount.provider.expects(:dump=).with(1) @mount[:dump] = 1 @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