diff --git a/spec/unit/property_spec.rb b/spec/unit/property_spec.rb index 99d4bc7c5..e8ab98a9c 100755 --- a/spec/unit/property_spec.rb +++ b/spec/unit/property_spec.rb @@ -1,409 +1,409 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/property' describe Puppet::Property do before do @class = Class.new(Puppet::Property) do @name = :foo end @class.initvars @provider = mock 'provider' @resource = stub 'resource', :provider => @provider @resource.stub_everything @property = @class.new :resource => @resource end it "should return its name as a string when converted to a string" do @property.to_s.should == @property.name.to_s end it "should be able to look up the modified name for a given value" do @class.newvalue(:foo) @class.value_name("foo").should == :foo end it "should be able to look up the modified name for a given value matching a regex" do @class.newvalue(%r{.}) @class.value_name("foo").should == %r{.} end it "should be able to look up a given value option" do @class.newvalue(:foo, :event => :whatever) @class.value_option(:foo, :event).should == :whatever end it "should be able to specify required features" do @class.should respond_to(:required_features=) end {"one" => [:one],:one => [:one],%w{a} => [:a],[:b] => [:b],%w{one two} => [:one,:two],[:a,:b] => [:a,:b]}.each { |in_value,out_value| it "should always convert required features into an array of symbols (e.g. #{in_value.inspect} --> #{out_value.inspect})" do @class.required_features = in_value @class.required_features.should == out_value end } it "should be able to shadow metaparameters" do @property.must respond_to(:shadow) end describe "when returning the default event name" do before do @resource = stub 'resource' @instance = @class.new(:resource => @resource) @instance.stubs(:should).returns "myval" end it "should use the current 'should' value to pick the event name" do @instance.expects(:should).returns "myvalue" @class.expects(:value_option).with('myvalue', :event).returns :event_name @instance.event_name end it "should return any event defined with the specified value" do @instance.expects(:should).returns :myval @class.expects(:value_option).with(:myval, :event).returns :event_name @instance.event_name.should == :event_name end describe "and the property is 'ensure'" do before do @instance.stubs(:name).returns :ensure @resource.expects(:type).returns :mytype end it "should use _created if the 'should' value is 'present'" do @instance.expects(:should).returns :present @instance.event_name.should == :mytype_created end it "should use _removed if the 'should' value is 'absent'" do @instance.expects(:should).returns :absent @instance.event_name.should == :mytype_removed end it "should use _changed if the 'should' value is not 'absent' or 'present'" do @instance.expects(:should).returns :foo @instance.event_name.should == :mytype_changed end it "should use _changed if the 'should value is nil" do @instance.expects(:should).returns nil @instance.event_name.should == :mytype_changed end end it "should use _changed if the property is not 'ensure'" do @instance.stubs(:name).returns :myparam @instance.expects(:should).returns :foo @instance.event_name.should == :myparam_changed end it "should use _changed if no 'should' value is set" do @instance.stubs(:name).returns :myparam @instance.expects(:should).returns nil @instance.event_name.should == :myparam_changed end end - describe "when creating an event", :fails_on_windows => true do + describe "when creating an event" do before do @event = Puppet::Transaction::Event.new # Use a real resource so we can test the event creation integration - @resource = Puppet::Type.type(:mount).new :name => "foo" + @resource = Puppet::Type.type(:host).new :name => "foo" @instance = @class.new(:resource => @resource) @instance.stubs(:should).returns "myval" end it "should use an event from the resource as the base event" do event = Puppet::Transaction::Event.new @resource.expects(:event).returns event @instance.event.should equal(event) end it "should have the default event name" do @instance.expects(:event_name).returns :my_event @instance.event.name.should == :my_event end it "should have the property's name" do @instance.event.property.should == @instance.name.to_s end it "should have the 'should' value set" do @instance.stubs(:should).returns "foo" @instance.event.desired_value.should == "foo" end it "should provide its path as the source description" do @instance.stubs(:path).returns "/my/param" @instance.event.source_description.should == "/my/param" end end describe "when shadowing metaparameters" do before do @shadow_class = Class.new(Puppet::Property) do @name = :alias end @shadow_class.initvars end it "should create an instance of the metaparameter at initialization" do Puppet::Type.metaparamclass(:alias).expects(:new).with(:resource => @resource) @shadow_class.new :resource => @resource end it "should munge values using the shadow's munge method" do shadow = mock 'shadow' Puppet::Type.metaparamclass(:alias).expects(:new).returns shadow shadow.expects(:munge).with "foo" property = @shadow_class.new :resource => @resource property.munge("foo") end end describe "when defining new values" do it "should define a method for each value created with a block that's not a regex" do @class.newvalue(:foo) { } @property.must respond_to(:set_foo) end end describe "when assigning the value" do it "should just set the 'should' value" do @property.value = "foo" @property.should.must == "foo" end it "should validate each value separately" do @property.expects(:validate).with("one") @property.expects(:validate).with("two") @property.value = %w{one two} end it "should munge each value separately and use any result as the actual value" do @property.expects(:munge).with("one").returns :one @property.expects(:munge).with("two").returns :two # Do this so we get the whole array back. @class.array_matching = :all @property.value = %w{one two} @property.should.must == [:one, :two] end it "should return any set value" do (@property.value = :one).should == :one end end describe "when returning the value" do it "should return nil if no value is set" do @property.should.must be_nil end it "should return the first set 'should' value if :array_matching is set to :first" do @class.array_matching = :first @property.should = %w{one two} @property.should.must == "one" end it "should return all set 'should' values as an array if :array_matching is set to :all" do @class.array_matching = :all @property.should = %w{one two} @property.should.must == %w{one two} end it "should default to :first array_matching" do @class.array_matching.should == :first end it "should unmunge the returned value if :array_matching is set to :first" do @property.class.unmunge do |v| v.to_sym end @class.array_matching = :first @property.should = %w{one two} @property.should.must == :one end it "should unmunge all the returned values if :array_matching is set to :all" do @property.class.unmunge do |v| v.to_sym end @class.array_matching = :all @property.should = %w{one two} @property.should.must == [:one, :two] end end describe "when validating values" do it "should do nothing if no values or regexes have been defined" do lambda { @property.should = "foo" }.should_not raise_error end it "should fail if the value is not a defined value or alias and does not match a regex" do @class.newvalue(:foo) lambda { @property.should = "bar" }.should raise_error end it "should succeeed if the value is one of the defined values" do @class.newvalue(:foo) lambda { @property.should = :foo }.should_not raise_error end it "should succeeed if the value is one of the defined values even if the definition uses a symbol and the validation uses a string" do @class.newvalue(:foo) lambda { @property.should = "foo" }.should_not raise_error end it "should succeeed if the value is one of the defined values even if the definition uses a string and the validation uses a symbol" do @class.newvalue("foo") lambda { @property.should = :foo }.should_not raise_error end it "should succeed if the value is one of the defined aliases" do @class.newvalue("foo") @class.aliasvalue("bar", "foo") lambda { @property.should = :bar }.should_not raise_error end it "should succeed if the value matches one of the regexes" do @class.newvalue(/./) lambda { @property.should = "bar" }.should_not raise_error end it "should validate that all required features are present" do @class.newvalue(:foo, :required_features => [:a, :b]) @provider.expects(:satisfies?).with([:a, :b]).returns true @property.should = :foo end it "should fail if required features are missing" do @class.newvalue(:foo, :required_features => [:a, :b]) @provider.expects(:satisfies?).with([:a, :b]).returns false lambda { @property.should = :foo }.should raise_error(Puppet::Error) end it "should internally raise an ArgumentError if required features are missing" do @class.newvalue(:foo, :required_features => [:a, :b]) @provider.expects(:satisfies?).with([:a, :b]).returns false lambda { @property.validate_features_per_value :foo }.should raise_error(ArgumentError) end it "should validate that all required features are present for regexes" do value = @class.newvalue(/./, :required_features => [:a, :b]) @provider.expects(:satisfies?).with([:a, :b]).returns true @property.should = "foo" end it "should support specifying an individual required feature" do value = @class.newvalue(/./, :required_features => :a) @provider.expects(:satisfies?).returns true @property.should = "foo" end end describe "when munging values" do it "should do nothing if no values or regexes have been defined" do @property.munge("foo").should == "foo" end it "should return return any matching defined values" do @class.newvalue(:foo) @property.munge("foo").should == :foo end it "should return any matching aliases" do @class.newvalue(:foo) @class.aliasvalue(:bar, :foo) @property.munge("bar").should == :foo end it "should return the value if it matches a regex" do @class.newvalue(/./) @property.munge("bar").should == "bar" end it "should return the value if no other option is matched" do @class.newvalue(:foo) @property.munge("bar").should == "bar" end end describe "when syncing the 'should' value" do it "should set the value" do @class.newvalue(:foo) @property.should = :foo @property.expects(:set).with(:foo) @property.sync end end describe "when setting a value" do it "should catch exceptions and raise Puppet::Error" do @class.newvalue(:foo) { raise "eh" } lambda { @property.set(:foo) }.should raise_error(Puppet::Error) end describe "that was defined without a block" do it "should call the settor on the provider" do @class.newvalue(:bar) @provider.expects(:foo=).with :bar @property.set(:bar) end end describe "that was defined with a block" do it "should call the method created for the value if the value is not a regex" do @class.newvalue(:bar) {} @property.expects(:set_bar) @property.set(:bar) end it "should call the provided block if the value is a regex" do @class.newvalue(/./) { self.test } @property.expects(:test) @property.set("foo") end end end describe "when producing a change log" do it "should say 'defined' when the current value is 'absent'" do @property.change_to_s(:absent, "foo").should =~ /^defined/ end it "should say 'undefined' when the new value is 'absent'" do @property.change_to_s("foo", :absent).should =~ /^undefined/ end it "should say 'changed' when neither value is 'absent'" do @property.change_to_s("foo", "bar").should =~ /changed/ end end end diff --git a/spec/unit/transaction/report_spec.rb b/spec/unit/transaction/report_spec.rb index 0a6ab8b5f..fe5c2e218 100755 --- a/spec/unit/transaction/report_spec.rb +++ b/spec/unit/transaction/report_spec.rb @@ -1,308 +1,308 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/transaction/report' describe Puppet::Transaction::Report do include PuppetSpec::Files before do Puppet::Util::Storage.stubs(:store) end it "should set its host name to the node_name_value" do Puppet[:node_name_value] = 'mynode' Puppet::Transaction::Report.new("apply").host.should == "mynode" end it "should return its host name as its name" do r = Puppet::Transaction::Report.new("apply") r.name.should == r.host end it "should create an initialization timestamp" do Time.expects(:now).returns "mytime" Puppet::Transaction::Report.new("apply").time.should == "mytime" end it "should take a 'kind' as an argument" do Puppet::Transaction::Report.new("inspect").kind.should == "inspect" end it "should take a 'configuration_version' as an argument" do Puppet::Transaction::Report.new("inspect", "some configuration version").configuration_version.should == "some configuration version" end it "should be able to set configuration_version" do report = Puppet::Transaction::Report.new("inspect") report.configuration_version = "some version" report.configuration_version.should == "some version" end it "should not include whits" do Puppet::FileBucket::File.indirection.stubs(:save) filename = tmpfile('whit_test') file = Puppet::Type.type(:file).new(:path => filename) catalog = Puppet::Resource::Catalog.new catalog.add_resource(file) report = Puppet::Transaction::Report.new("apply") catalog.apply(:report => report) report.finalize_report report.resource_statuses.values.any? {|res| res.resource_type =~ /whit/i}.should be_false report.metrics['time'].values.any? {|metric| metric.first =~ /whit/i}.should be_false end describe "when accepting logs" do before do @report = Puppet::Transaction::Report.new("apply") end it "should add new logs to the log list" do @report << "log" @report.logs[-1].should == "log" end it "should return self" do r = @report << "log" r.should equal(@report) end end describe "when accepting resource statuses" do before do @report = Puppet::Transaction::Report.new("apply") end it "should add each status to its status list" do status = stub 'status', :resource => "foo" @report.add_resource_status status @report.resource_statuses["foo"].should equal(status) end end describe "when using the indirector" do it "should redirect :save to the indirection" do Facter.stubs(:value).returns("eh") @indirection = stub 'indirection', :name => :report Puppet::Transaction::Report.stubs(:indirection).returns(@indirection) report = Puppet::Transaction::Report.new("apply") @indirection.expects(:save) Puppet::Transaction::Report.indirection.save(report) end it "should default to the 'processor' terminus" do Puppet::Transaction::Report.indirection.terminus_class.should == :processor end it "should delegate its name attribute to its host method" do report = Puppet::Transaction::Report.new("apply") report.expects(:host).returns "me" report.name.should == "me" end end describe "when computing exit status" do it "should produce 2 if changes are present" do report = Puppet::Transaction::Report.new("apply") report.add_metric("changes", {"total" => 1}) report.add_metric("resources", {"failed" => 0}) report.exit_status.should == 2 end it "should produce 4 if failures are present" do report = Puppet::Transaction::Report.new("apply") report.add_metric("changes", {"total" => 0}) report.add_metric("resources", {"failed" => 1}) report.exit_status.should == 4 end it "should produce 6 if both changes and failures are present" do report = Puppet::Transaction::Report.new("apply") report.add_metric("changes", {"total" => 1}) report.add_metric("resources", {"failed" => 1}) report.exit_status.should == 6 end end describe "before finalizing the report" do it "should have a status of 'failed'" do report = Puppet::Transaction::Report.new("apply") report.status.should == 'failed' end end describe "when finalizing the report" do before do @report = Puppet::Transaction::Report.new("apply") end def metric(name, value) if metric = @report.metrics[name.to_s] metric[value] else nil end end def add_statuses(count, type = :file) count.times do |i| status = Puppet::Resource::Status.new(Puppet::Type.type(type).new(:title => make_absolute("/my/path#{i}"))) yield status if block_given? @report.add_resource_status status end end [:time, :resources, :changes, :events].each do |type| it "should add #{type} metrics" do @report.finalize_report @report.metrics[type.to_s].should be_instance_of(Puppet::Transaction::Metric) end end describe "for resources" do it "should provide the total number of resources" do add_statuses(3) @report.finalize_report metric(:resources, "total").should == 3 end Puppet::Resource::Status::STATES.each do |state| it "should provide the number of #{state} resources as determined by the status objects" do add_statuses(3) { |status| status.send(state.to_s + "=", true) } @report.finalize_report metric(:resources, state.to_s).should == 3 end end it "should mark the report as 'failed' if there are failing resources" do add_statuses(1) { |status| status.failed = true } @report.finalize_report @report.status.should == 'failed' end end describe "for changes" do it "should provide the number of changes from the resource statuses and mark the report as 'changed'" do add_statuses(3) { |status| 3.times { status << Puppet::Transaction::Event.new(:status => 'success') } } @report.finalize_report metric(:changes, "total").should == 9 @report.status.should == 'changed' end it "should provide a total even if there are no changes, and mark the report as 'unchanged'" do @report.finalize_report metric(:changes, "total").should == 0 @report.status.should == 'unchanged' end end describe "for times" do - it "should provide the total amount of time for each resource type", :fails_on_windows => true do + it "should provide the total amount of time for each resource type" do add_statuses(3, :file) do |status| status.evaluation_time = 1 end add_statuses(3, :exec) do |status| status.evaluation_time = 2 end - add_statuses(3, :mount) do |status| + add_statuses(3, :tidy) do |status| status.evaluation_time = 3 end @report.finalize_report metric(:time, "file").should == 3 metric(:time, "exec").should == 6 - metric(:time, "mount").should == 9 + metric(:time, "tidy").should == 9 end it "should add any provided times from external sources" do @report.add_times :foobar, 50 @report.finalize_report metric(:time, "foobar").should == 50 end it "should have a total time" do add_statuses(3, :file) do |status| status.evaluation_time = 1.25 end @report.add_times :config_retrieval, 0.5 @report.finalize_report metric(:time, "total").should == 4.25 end end describe "for events" do it "should provide the total number of events" do add_statuses(3) do |status| 3.times { |i| status.add_event(Puppet::Transaction::Event.new :status => 'success') } end @report.finalize_report metric(:events, "total").should == 9 end it "should provide the total even if there are no events" do @report.finalize_report metric(:events, "total").should == 0 end Puppet::Transaction::Event::EVENT_STATUSES.each do |status_name| it "should provide the number of #{status_name} events" do add_statuses(3) do |status| 3.times do |i| event = Puppet::Transaction::Event.new event.status = status_name status.add_event(event) end end @report.finalize_report metric(:events, status_name).should == 9 end end end end describe "when producing a summary" do before do resource = Puppet::Type.type(:notify).new(:name => "testing") catalog = Puppet::Resource::Catalog.new catalog.add_resource resource trans = catalog.apply @report = trans.report @report.finalize_report end %w{changes time resources events}.each do |main| it "should include the key #{main} in the raw summary hash" do @report.raw_summary.should be_key main end end it "should include the last run time in the raw summary hash" do Time.stubs(:now).returns(Time.utc(2010,11,10,12,0,24)) @report.raw_summary["time"]["last_run"].should == 1289390424 end %w{Changes Total Resources Time Events}.each do |main| it "should include information on #{main} in the textual summary" do @report.summary.should be_include(main) end end end describe "when outputting yaml" do it "should not include @external_times" do report = Puppet::Transaction::Report.new('apply') report.add_times('config_retrieval', 1.0) report.to_yaml_properties.should_not include('@external_times') end end end diff --git a/spec/unit/util/logging_spec.rb b/spec/unit/util/logging_spec.rb index 2953f54a4..4c2f4cc60 100755 --- a/spec/unit/util/logging_spec.rb +++ b/spec/unit/util/logging_spec.rb @@ -1,119 +1,119 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/util/logging' class LoggingTester include Puppet::Util::Logging end describe Puppet::Util::Logging do before do @logger = LoggingTester.new end Puppet::Util::Log.eachlevel do |level| it "should have a method for sending '#{level}' logs" do @logger.should respond_to(level) end end it "should have a method for sending a log with a specified log level" do @logger.expects(:to_s).returns "I'm a string!" Puppet::Util::Log.expects(:create).with { |args| args[:source] == "I'm a string!" and args[:level] == "loglevel" and args[:message] == "mymessage" } @logger.send_log "loglevel", "mymessage" end describe "when sending a log" do it "should use the Log's 'create' entrance method" do Puppet::Util::Log.expects(:create) @logger.notice "foo" end it "should send itself converted to a string as the log source" do @logger.expects(:to_s).returns "I'm a string!" Puppet::Util::Log.expects(:create).with { |args| args[:source] == "I'm a string!" } @logger.notice "foo" end it "should queue logs sent without a specified destination" do Puppet::Util::Log.close_all Puppet::Util::Log.expects(:queuemessage) @logger.notice "foo" end - it "should use the path of any provided resource type", :fails_on_windows => true do - resource = Puppet::Type.type(:mount).new :name => "foo" + it "should use the path of any provided resource type" do + resource = Puppet::Type.type(:host).new :name => "foo" - resource.expects(:path).returns "/path/to/mount".to_sym + resource.expects(:path).returns "/path/to/host".to_sym - Puppet::Util::Log.expects(:create).with { |args| args[:source] == "/path/to/mount" } + Puppet::Util::Log.expects(:create).with { |args| args[:source] == "/path/to/host" } resource.notice "foo" end - it "should use the path of any provided resource parameter", :fails_on_windows => true do - resource = Puppet::Type.type(:mount).new :name => "foo" + it "should use the path of any provided resource parameter" do + resource = Puppet::Type.type(:host).new :name => "foo" param = resource.parameter(:name) param.expects(:path).returns "/path/to/param".to_sym Puppet::Util::Log.expects(:create).with { |args| args[:source] == "/path/to/param" } param.notice "foo" end it "should send the provided argument as the log message" do Puppet::Util::Log.expects(:create).with { |args| args[:message] == "foo" } @logger.notice "foo" end it "should join any provided arguments into a single string for the message" do Puppet::Util::Log.expects(:create).with { |args| args[:message] == "foo bar baz" } @logger.notice ["foo", "bar", "baz"] end [:file, :line, :tags].each do |attr| it "should include #{attr} if available" do @logger.singleton_class.send(:attr_accessor, attr) @logger.send(attr.to_s + "=", "myval") Puppet::Util::Log.expects(:create).with { |args| args[attr] == "myval" } @logger.notice "foo" end end end describe "when sending a deprecation warning" do before do @logger.clear_deprecation_warnings end it "should the message with warn" do @logger.expects(:warning).with('foo') @logger.deprecation_warning 'foo' end it "should only log each unique message once" do @logger.expects(:warning).with('foo').once 5.times { @logger.deprecation_warning 'foo' } end it "should only log the first 100 messages" do (1..100).each { |i| @logger.expects(:warning).with(i).once @logger.deprecation_warning i } @logger.expects(:warning).with(101).never @logger.deprecation_warning 101 end end end