diff options
Diffstat (limited to 'spec/unit')
72 files changed, 2046 insertions, 949 deletions
diff --git a/spec/unit/application/agent_spec.rb b/spec/unit/application/agent_spec.rb index 54726c185..151d85a58 100755 --- a/spec/unit/application/agent_spec.rb +++ b/spec/unit/application/agent_spec.rb @@ -6,6 +6,7 @@ require 'puppet/agent' require 'puppet/application/agent' require 'puppet/network/server' require 'puppet/daemon' +require 'puppet/network/handler' describe Puppet::Application::Agent do before :each do @@ -13,15 +14,16 @@ describe Puppet::Application::Agent do @puppetd.stubs(:puts) @daemon = stub_everything 'daemon' Puppet::Daemon.stubs(:new).returns(@daemon) + Puppet[:daemonize] = false @agent = stub_everything 'agent' Puppet::Agent.stubs(:new).returns(@agent) @puppetd.preinit Puppet::Util::Log.stubs(:newdestination) Puppet::Util::Log.stubs(:level=) - Puppet::Node.stubs(:terminus_class=) - Puppet::Node.stubs(:cache_class=) - Puppet::Node::Facts.stubs(:terminus_class=) + Puppet::Node.indirection.stubs(:terminus_class=) + Puppet::Node.indirection.stubs(:cache_class=) + Puppet::Node::Facts.indirection.stubs(:terminus_class=) end it "should operate in agent run_mode" do @@ -175,16 +177,13 @@ describe Puppet::Application::Agent do @puppetd.options.stubs(:[]) Puppet.stubs(:info) FileTest.stubs(:exists?).returns(true) - Puppet.stubs(:[]) - Puppet.stubs(:[]=) - Puppet.stubs(:[]).with(:libdir).returns("/dev/null/lib") - Puppet.settings.stubs(:print_config?) - Puppet.settings.stubs(:print_config) + Puppet[:libdir] = "/dev/null/lib" Puppet::SSL::Host.stubs(:ca_location=) - Puppet::Transaction::Report.stubs(:terminus_class=) - Puppet::Resource::Catalog.stubs(:terminus_class=) - Puppet::Resource::Catalog.stubs(:cache_class=) - Puppet::Node::Facts.stubs(:terminus_class=) + Puppet::Transaction::Report.indirection.stubs(:terminus_class=) + Puppet::Transaction::Report.indirection.stubs(:cache_class=) + Puppet::Resource::Catalog.indirection.stubs(:terminus_class=) + Puppet::Resource::Catalog.indirection.stubs(:cache_class=) + Puppet::Node::Facts.indirection.stubs(:terminus_class=) @host = stub_everything 'host' Puppet::SSL::Host.stubs(:new).returns(@host) Puppet.stubs(:settraps) @@ -192,7 +191,7 @@ describe Puppet::Application::Agent do describe "with --test" do before :each do - Puppet.settings.stubs(:handlearg) + #Puppet.settings.stubs(:handlearg) @puppetd.options.stubs(:[]=) end @@ -207,8 +206,9 @@ describe Puppet::Application::Agent do @puppetd.setup_test end it "should set options[:onetime] to true" do - Puppet.expects(:[]=).with(:onetime,true) + Puppet[:onetime] = false @puppetd.setup_test + Puppet[:onetime].should == true end it "should set options[:detailed_exitcodes] to true" do @puppetd.options.expects(:[]=).with(:detailed_exitcodes,true) @@ -264,7 +264,7 @@ describe Puppet::Application::Agent do it "should print puppet config if asked to in Puppet config" do @puppetd.stubs(:exit) - Puppet.settings.stubs(:print_configs?).returns(true) + Puppet[:configprint] = "pluginsync" Puppet.settings.expects(:print_configs) @@ -272,14 +272,14 @@ describe Puppet::Application::Agent do end it "should exit after printing puppet config if asked to in Puppet config" do - Puppet.settings.stubs(:print_configs?).returns(true) + Puppet[:configprint] = "pluginsync" lambda { @puppetd.setup }.should raise_error(SystemExit) end it "should set a central log destination with --centrallogs" do @puppetd.options.stubs(:[]).with(:centrallogs).returns(true) - Puppet.stubs(:[]).with(:server).returns("puppet.reductivelabs.com") + Puppet[:server] = "puppet.reductivelabs.com" Puppet::Util::Log.stubs(:newdestination).with(:syslog) Puppet::Util::Log.expects(:newdestination).with("puppet.reductivelabs.com") @@ -307,26 +307,34 @@ describe Puppet::Application::Agent do end it "should tell the report handler to use REST" do - Puppet::Transaction::Report.expects(:terminus_class=).with(:rest) + Puppet::Transaction::Report.indirection.expects(:terminus_class=).with(:rest) + + @puppetd.setup + end + + it "should tell the report handler to cache locally as yaml" do + Puppet::Transaction::Report.indirection.expects(:cache_class=).with(:yaml) @puppetd.setup end it "should change the catalog_terminus setting to 'rest'" do - Puppet.expects(:[]=).with(:catalog_terminus, :rest) + Puppet[:catalog_terminus] = :foo @puppetd.setup + Puppet[:catalog_terminus].should == :rest end it "should tell the catalog handler to use cache" do - Puppet::Resource::Catalog.expects(:cache_class=).with(:yaml) + Puppet::Resource::Catalog.indirection.expects(:cache_class=).with(:yaml) @puppetd.setup end it "should change the facts_terminus setting to 'facter'" do - Puppet.expects(:[]=).with(:facts_terminus, :facter) + Puppet[:facts_terminus] = :foo @puppetd.setup + Puppet[:facts_terminus].should == :facter end it "should create an agent" do @@ -374,7 +382,7 @@ describe Puppet::Application::Agent do end it "should daemonize if needed" do - Puppet.stubs(:[]).with(:daemonize).returns(true) + Puppet[:daemonize] = true @daemon.expects(:daemonize) @@ -397,7 +405,7 @@ describe Puppet::Application::Agent do end it "should setup listen if told to and not onetime" do - Puppet.stubs(:[]).with(:listen).returns(true) + Puppet[:listen] = true @puppetd.options.stubs(:[]).with(:onetime).returns(false) @puppetd.expects(:setup_listen) @@ -407,7 +415,7 @@ describe Puppet::Application::Agent do describe "when setting up listen" do before :each do - Puppet.stubs(:[]).with(:authconfig).returns('auth') + Puppet[:authconfig] = 'auth' FileTest.stubs(:exists?).with('auth').returns(true) File.stubs(:exist?).returns(true) @puppetd.options.stubs(:[]).with(:serve).returns([]) @@ -419,7 +427,7 @@ describe Puppet::Application::Agent do it "should exit if no authorization file" do Puppet.stubs(:err) - FileTest.stubs(:exists?).with('auth').returns(false) + FileTest.stubs(:exists?).with(Puppet[:authconfig]).returns(false) @puppetd.expects(:exit) @@ -440,9 +448,9 @@ describe Puppet::Application::Agent do end it "should use puppet default port" do - Puppet.stubs(:[]).with(:puppetport).returns(:port) + Puppet[:puppetport] = 32768 - Puppet::Network::Server.expects(:new).with { |args| args[:port] == :port } + Puppet::Network::Server.expects(:new).with { |args| args[:port] == 32768 } @puppetd.setup_listen end @@ -521,7 +529,7 @@ describe Puppet::Application::Agent do end it "should exit with report's computed exit status" do - Puppet.stubs(:[]).with(:noop).returns(false) + Puppet[:noop] = false report = stub 'report', :exit_status => 666 @agent.stubs(:run).returns(report) @puppetd.expects(:exit).with(666) @@ -530,7 +538,7 @@ describe Puppet::Application::Agent do end it "should always exit with 0 if --noop" do - Puppet.stubs(:[]).with(:noop).returns(true) + Puppet[:noop] = true report = stub 'report', :exit_status => 666 @agent.stubs(:run).returns(report) @puppetd.expects(:exit).with(0) diff --git a/spec/unit/application/apply_spec.rb b/spec/unit/application/apply_spec.rb index 877c47bcc..52b84e6f2 100755 --- a/spec/unit/application/apply_spec.rb +++ b/spec/unit/application/apply_spec.rb @@ -4,6 +4,7 @@ require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/application/apply' require 'puppet/file_bucket/dipper' +require 'puppet/configurer' describe Puppet::Application::Apply do before :each do @@ -56,6 +57,7 @@ describe Puppet::Application::Apply do Puppet.stubs(:parse_config) Puppet::FileBucket::Dipper.stubs(:new) STDIN.stubs(:read) + Puppet::Transaction::Report.indirection.stubs(:cache_class=) @apply.options.stubs(:[]).with(any_parameters) end @@ -113,6 +115,11 @@ describe Puppet::Application::Apply do lambda { @apply.setup }.should raise_error(SystemExit) end + it "should tell the report handler to cache locally as yaml" do + Puppet::Transaction::Report.indirection.expects(:cache_class=).with(:yaml) + + @apply.setup + end end describe "when executing" do @@ -142,17 +149,16 @@ describe Puppet::Application::Apply do describe "the parseonly command" do before :each do - Puppet.stubs(:[]).with(:environment) + @environment = Puppet::Node::Environment.new("env") + Puppet.stubs(:[]).with(:environment).returns(@environment) Puppet.stubs(:[]).with(:manifest).returns("site.pp") Puppet.stubs(:err) @apply.stubs(:exit) @apply.options.stubs(:[]).with(:code).returns "some code" - @collection = stub_everything - Puppet::Resource::TypeCollection.stubs(:new).returns(@collection) end - it "should use a Puppet Resource Type Collection to parse the file" do - @collection.expects(:perform_initial_import) + it "should use the environment to parse the file" do + @environment.stubs(:perform_initial_import) @apply.parseonly end @@ -162,7 +168,7 @@ describe Puppet::Application::Apply do end it "should exit with exit code 1 if error" do - @collection.stubs(:perform_initial_import).raises(Puppet::ParseError) + @environment.stubs(:perform_initial_import).raises(Puppet::ParseError) @apply.expects(:exit).with(1) @apply.parseonly end @@ -179,14 +185,14 @@ describe Puppet::Application::Apply do @apply.options.stubs(:[]) @facts = stub_everything 'facts' - Puppet::Node::Facts.stubs(:find).returns(@facts) + Puppet::Node::Facts.indirection.stubs(:find).returns(@facts) @node = stub_everything 'node' - Puppet::Node.stubs(:find).returns(@node) + Puppet::Node.indirection.stubs(:find).returns(@node) @catalog = stub_everything 'catalog' @catalog.stubs(:to_ral).returns(@catalog) - Puppet::Resource::Catalog.stubs(:find).returns(@catalog) + Puppet::Resource::Catalog.indirection.stubs(:find).returns(@catalog) STDIN.stubs(:read) @@ -194,6 +200,9 @@ describe Puppet::Application::Apply do @catalog.stubs(:apply).returns(@transaction) @apply.stubs(:exit) + + Puppet::Util::Storage.stubs(:load) + Puppet::Configurer.any_instance.stubs(:save_last_run_summary) # to prevent it from trying to write files end it "should set the code to run from --code" do @@ -239,25 +248,25 @@ describe Puppet::Application::Apply do end it "should collect the node facts" do - Puppet::Node::Facts.expects(:find).returns(@facts) + Puppet::Node::Facts.indirection.expects(:find).returns(@facts) @apply.main end it "should raise an error if we can't find the node" do - Puppet::Node::Facts.expects(:find).returns(nil) + Puppet::Node::Facts.indirection.expects(:find).returns(nil) lambda { @apply.main }.should raise_error end it "should look for the node" do - Puppet::Node.expects(:find).returns(@node) + Puppet::Node.indirection.expects(:find).returns(@node) @apply.main end it "should raise an error if we can't find the node" do - Puppet::Node.expects(:find).returns(nil) + Puppet::Node.indirection.expects(:find).returns(nil) lambda { @apply.main }.should raise_error end @@ -283,7 +292,7 @@ describe Puppet::Application::Apply do end it "should compile the catalog" do - Puppet::Resource::Catalog.expects(:find).returns(@catalog) + Puppet::Resource::Catalog.indirection.expects(:find).returns(@catalog) @apply.main end @@ -302,11 +311,8 @@ describe Puppet::Application::Apply do end it "should call the prerun and postrun commands on a Configurer instance" do - configurer = stub 'configurer' - - Puppet::Configurer.expects(:new).returns configurer - configurer.expects(:execute_prerun_command) - configurer.expects(:execute_postrun_command) + Puppet::Configurer.any_instance.expects(:execute_prerun_command) + Puppet::Configurer.any_instance.expects(:execute_postrun_command) @apply.main end @@ -317,12 +323,20 @@ describe Puppet::Application::Apply do @apply.main end + it "should save the last run summary" do + Puppet.stubs(:[]).with(:noop).returns(false) + report = stub 'report' + Puppet::Configurer.any_instance.stubs(:initialize_report).returns(report) + + Puppet::Configurer.any_instance.expects(:save_last_run_summary).with(report) + @apply.main + end + describe "with detailed_exitcodes" do it "should exit with report's computed exit status" do Puppet.stubs(:[]).with(:noop).returns(false) @apply.options.stubs(:[]).with(:detailed_exitcodes).returns(true) - report = stub 'report', :exit_status => 666 - @transaction.stubs(:report).returns(report) + Puppet::Transaction::Report.any_instance.stubs(:exit_status).returns(666) @apply.expects(:exit).with(666) @apply.main diff --git a/spec/unit/application/filebucket_spec.rb b/spec/unit/application/filebucket_spec.rb index 6e7a7b819..e6272f179 100644 --- a/spec/unit/application/filebucket_spec.rb +++ b/spec/unit/application/filebucket_spec.rb @@ -3,6 +3,7 @@ require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/application/filebucket' +require 'puppet/file_bucket/dipper' describe Puppet::Application::Filebucket do before :each do diff --git a/spec/unit/application/kick_spec.rb b/spec/unit/application/kick_spec.rb index dea7ec147..5ccf81bd0 100755 --- a/spec/unit/application/kick_spec.rb +++ b/spec/unit/application/kick_spec.rb @@ -163,7 +163,7 @@ describe Puppet::Application::Kick do @kick.options.stubs(:[]).with(:all).returns(true) @kick.stubs(:puts) - Puppet::Node.expects(:search).with("whatever",:fqdn => :something).returns([]) + Puppet::Node.indirection.expects(:search).with("whatever",:fqdn => :something).returns([]) @kick.setup end @@ -172,7 +172,7 @@ describe Puppet::Application::Kick do @kick.options.stubs(:[]).with(:all).returns(true) @kick.stubs(:puts) - Puppet::Node.expects(:search).with("whatever",:fqdn => nil).returns([]) + Puppet::Node.indirection.expects(:search).with("whatever",:fqdn => nil).returns([]) @kick.setup end @@ -182,7 +182,7 @@ describe Puppet::Application::Kick do @kick.stubs(:puts) @kick.classes = ['class'] - Puppet::Node.expects(:search).with("whatever", :class => "class", :fqdn => nil).returns([]) + Puppet::Node.indirection.expects(:search).with("whatever", :class => "class", :fqdn => nil).returns([]) @kick.setup end @@ -279,7 +279,7 @@ describe Puppet::Application::Kick do end it "should call run on a Puppet::Run for the given host" do - @agent_run.expects(:save).with('https://host:8139/production/run/host').returns(@agent_run) + Puppet::Run.indirection.expects(:save).with(@agent_run, 'https://host:8139/production/run/host').returns(@agent_run) @kick.run_for_host('host') end diff --git a/spec/unit/application/master_spec.rb b/spec/unit/application/master_spec.rb index 216c7dc90..86e38efcb 100644 --- a/spec/unit/application/master_spec.rb +++ b/spec/unit/application/master_spec.rb @@ -14,12 +14,12 @@ describe Puppet::Application::Master do Puppet::Util::Log.stubs(:newdestination) Puppet::Util::Log.stubs(:level=) - Puppet::Node.stubs(:terminus_class=) - Puppet::Node.stubs(:cache_class=) - Puppet::Node::Facts.stubs(:terminus_class=) - Puppet::Node::Facts.stubs(:cache_class=) - Puppet::Transaction::Report.stubs(:terminus_class=) - Puppet::Resource::Catalog.stubs(:terminus_class=) + Puppet::Node.indirection.stubs(:terminus_class=) + Puppet::Node.indirection.stubs(:cache_class=) + Puppet::Node::Facts.indirection.stubs(:terminus_class=) + Puppet::Node::Facts.indirection.stubs(:cache_class=) + Puppet::Transaction::Report.indirection.stubs(:terminus_class=) + Puppet::Resource::Catalog.indirection.stubs(:terminus_class=) end it "should operate in master run_mode" do @@ -183,7 +183,7 @@ describe Puppet::Application::Master do end it "should cache class in yaml" do - Puppet::Node.expects(:cache_class=).with(:yaml) + Puppet::Node.indirection.expects(:cache_class=).with(:yaml) @master.setup end @@ -257,16 +257,15 @@ describe Puppet::Application::Master do describe "the parseonly command" do before :each do - Puppet.stubs(:[]).with(:environment) + @environment = Puppet::Node::Environment.new("env") + Puppet.stubs(:[]).with(:environment).returns(@environment) Puppet.stubs(:[]).with(:manifest).returns("site.pp") Puppet.stubs(:err) @master.stubs(:exit) - @collection = stub_everything - Puppet::Resource::TypeCollection.stubs(:new).returns(@collection) end it "should use a Puppet Resource Type Collection to parse the file" do - @collection.expects(:perform_initial_import) + @environment.expects(:perform_initial_import) @master.parseonly end @@ -276,7 +275,7 @@ describe Puppet::Application::Master do end it "should exit with exit code 1 if error" do - @collection.stubs(:perform_initial_import).raises(Puppet::ParseError) + @environment.stubs(:perform_initial_import).raises(Puppet::ParseError) @master.expects(:exit).with(1) @master.parseonly end @@ -299,7 +298,7 @@ describe Puppet::Application::Master do it "should compile a catalog for the specified node" do @master.options[:node] = "foo" - Puppet::Resource::Catalog.expects(:find).with("foo").returns Puppet::Resource::Catalog.new + Puppet::Resource::Catalog.indirection.expects(:find).with("foo").returns Puppet::Resource::Catalog.new $stdout.stubs(:puts) @master.compile @@ -307,7 +306,7 @@ describe Puppet::Application::Master do it "should convert the catalog to a pure-resource catalog and use 'jj' to pretty-print the catalog" do catalog = Puppet::Resource::Catalog.new - Puppet::Resource::Catalog.expects(:find).returns catalog + Puppet::Resource::Catalog.indirection.expects(:find).returns catalog catalog.expects(:to_resource).returns("rescat") @@ -319,7 +318,7 @@ describe Puppet::Application::Master do it "should exit with error code 30 if no catalog can be found" do @master.options[:node] = "foo" - Puppet::Resource::Catalog.expects(:find).returns nil + Puppet::Resource::Catalog.indirection.expects(:find).returns nil @master.expects(:exit).with(30) $stderr.expects(:puts) @@ -328,7 +327,7 @@ describe Puppet::Application::Master do it "should exit with error code 30 if there's a failure" do @master.options[:node] = "foo" - Puppet::Resource::Catalog.expects(:find).raises ArgumentError + Puppet::Resource::Catalog.indirection.expects(:find).raises ArgumentError @master.expects(:exit).with(30) $stderr.expects(:puts) diff --git a/spec/unit/application/queue_spec.rb b/spec/unit/application/queue_spec.rb index 87c96dfff..1c65b558c 100755 --- a/spec/unit/application/queue_spec.rb +++ b/spec/unit/application/queue_spec.rb @@ -3,6 +3,7 @@ require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/application/queue' +require 'puppet/indirector/catalog/queue' describe Puppet::Application::Queue do before :each do @@ -12,7 +13,7 @@ describe Puppet::Application::Queue do Puppet::Util::Log.stubs(:newdestination) Puppet::Util::Log.stubs(:level=) - Puppet::Resource::Catalog.stubs(:terminus_class=) + Puppet::Resource::Catalog.indirection.stubs(:terminus_class=) end it "should ask Puppet::Application to parse Puppet configuration file" do @@ -79,7 +80,7 @@ describe Puppet::Application::Queue do @queue.daemon.stubs(:daemonize) Puppet.stubs(:info) Puppet.features.stubs(:stomp?).returns true - Puppet::Resource::Catalog.stubs(:terminus_class=) + Puppet::Resource::Catalog.indirection.stubs(:terminus_class=) Puppet.stubs(:settraps) Puppet.settings.stubs(:print_config?) Puppet.settings.stubs(:print_config) @@ -143,7 +144,7 @@ describe Puppet::Application::Queue do end it "should configure the Catalog class to use ActiveRecord" do - Puppet::Resource::Catalog.expects(:terminus_class=).with(:active_record) + Puppet::Resource::Catalog.indirection.expects(:terminus_class=).with(:active_record) @queue.setup end @@ -170,8 +171,8 @@ describe Puppet::Application::Queue do end it "should log and save each catalog passed by the queue" do - catalog = mock 'catalog', :name => 'eh' - catalog.expects(:save) + catalog = Puppet::Resource::Catalog.new('eh') + Puppet::Resource::Catalog.indirection.expects(:save).with(catalog) Puppet::Resource::Catalog::Queue.expects(:subscribe).yields(catalog) Puppet.expects(:notice).times(2) diff --git a/spec/unit/application/resource_spec.rb b/spec/unit/application/resource_spec.rb index b6c52b11e..df479ac89 100755 --- a/spec/unit/application/resource_spec.rb +++ b/spec/unit/application/resource_spec.rb @@ -162,21 +162,21 @@ describe Puppet::Application::Resource do @resource.stubs(:puts) @resource.host = 'host' - Puppet::Resource.stubs(:find ).never - Puppet::Resource.stubs(:search).never - Puppet::Resource.stubs(:save ).never + Puppet::Resource.indirection.stubs(:find ).never + Puppet::Resource.indirection.stubs(:search).never + Puppet::Resource.indirection.stubs(:save ).never end it "should search for resources" do @resource.command_line.stubs(:args).returns(['type']) - Puppet::Resource.expects(:search).with('https://host:8139/production/resources/type/', {}).returns([]) + Puppet::Resource.indirection.expects(:search).with('https://host:8139/production/resources/type/', {}).returns([]) @resource.main end it "should describe the given resource" do @resource.command_line.stubs(:args).returns(['type', 'name']) x = stub_everything 'resource' - Puppet::Resource.expects(:find).with('https://host:8139/production/resources/type/name').returns(x) + Puppet::Resource.indirection.expects(:find).with('https://host:8139/production/resources/type/name').returns(x) @resource.main end @@ -184,7 +184,7 @@ describe Puppet::Application::Resource do @resource.command_line.stubs(:args).returns(['type','name','param=temp']) res = stub "resource" - res.expects(:save).with('https://host:8139/production/resources/type/name').returns(res) + Puppet::Resource.indirection.expects(:save).with(res, 'https://host:8139/production/resources/type/name').returns(res) res.expects(:collect) res.expects(:to_manifest) Puppet::Resource.expects(:new).with('type', 'name', :parameters => {'param' => 'temp'}).returns(res) @@ -199,20 +199,20 @@ describe Puppet::Application::Resource do @resource.stubs(:puts) @resource.host = nil - Puppet::Resource.stubs(:find ).never - Puppet::Resource.stubs(:search).never - Puppet::Resource.stubs(:save ).never + Puppet::Resource.indirection.stubs(:find ).never + Puppet::Resource.indirection.stubs(:search).never + Puppet::Resource.indirection.stubs(:save ).never end it "should search for resources" do - Puppet::Resource.expects(:search).with('type/', {}).returns([]) + Puppet::Resource.indirection.expects(:search).with('type/', {}).returns([]) @resource.main end it "should describe the given resource" do @resource.command_line.stubs(:args).returns(['type','name']) x = stub_everything 'resource' - Puppet::Resource.expects(:find).with('type/name').returns(x) + Puppet::Resource.indirection.expects(:find).with('type/name').returns(x) @resource.main end @@ -220,7 +220,7 @@ describe Puppet::Application::Resource do @resource.command_line.stubs(:args).returns(['type','name','param=temp']) res = stub "resource" - res.expects(:save).with('type/name').returns(res) + Puppet::Resource.indirection.expects(:save).with(res, 'type/name').returns(res) res.expects(:collect) res.expects(:to_manifest) Puppet::Resource.expects(:new).with('type', 'name', :parameters => {'param' => 'temp'}).returns(res) diff --git a/spec/unit/configurer/fact_handler_spec.rb b/spec/unit/configurer/fact_handler_spec.rb index 051270144..70918c039 100755 --- a/spec/unit/configurer/fact_handler_spec.rb +++ b/spec/unit/configurer/fact_handler_spec.rb @@ -66,7 +66,7 @@ describe Puppet::Configurer::FactHandler do it "should use the Facts class with the :certname to find the facts" do Puppet.settings.expects(:value).with(:certname).returns "foo" - Puppet::Node::Facts.expects(:find).with("foo").returns "myfacts" + Puppet::Node::Facts.indirection.expects(:find).with("foo").returns "myfacts" @facthandler.stubs(:reload_facter) @facthandler.find_facts.should == "myfacts" end @@ -75,7 +75,7 @@ describe Puppet::Configurer::FactHandler do @facthandler.expects(:reload_facter) Puppet.settings.expects(:value).with(:certname).returns "myhost" - Puppet::Node::Facts.expects(:find).with("myhost") + Puppet::Node::Facts.indirection.expects(:find).with("myhost") @facthandler.find_facts end @@ -85,7 +85,7 @@ describe Puppet::Configurer::FactHandler do Puppet.settings.stubs(:value).with(:trace).returns false Puppet.settings.stubs(:value).with(:certname).returns "myhost" - Puppet::Node::Facts.expects(:find).raises RuntimeError + Puppet::Node::Facts.indirection.expects(:find).raises RuntimeError lambda { @facthandler.find_facts }.should raise_error(Puppet::Error) end diff --git a/spec/unit/configurer_spec.rb b/spec/unit/configurer_spec.rb index 0c9d06362..fc718fa58 100755 --- a/spec/unit/configurer_spec.rb +++ b/spec/unit/configurer_spec.rb @@ -89,9 +89,7 @@ describe Puppet::Configurer, "when executing a catalog run" do @catalog = Puppet::Resource::Catalog.new @catalog.stubs(:apply) @agent.stubs(:retrieve_catalog).returns @catalog - - Puppet::Util::Log.stubs(:newdestination) - Puppet::Util::Log.stubs(:close) + @agent.stubs(:save_last_run_summary) end it "should prepare for the run" do @@ -101,14 +99,14 @@ describe Puppet::Configurer, "when executing a catalog run" do end it "should initialize a transaction report if one is not provided" do - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.expects(:initialize_report).returns report @agent.run end it "should pass the new report to the catalog" do - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.stubs(:initialize_report).returns report @catalog.expects(:apply).with{|options| options[:report] == report} @@ -116,7 +114,7 @@ describe Puppet::Configurer, "when executing a catalog run" do end it "should use the provided report if it was passed one" do - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.expects(:initialize_report).never @catalog.expects(:apply).with{|options| options[:report] == report} @@ -176,7 +174,7 @@ describe Puppet::Configurer, "when executing a catalog run" do end it "should send the report" do - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.expects(:initialize_report).returns report @agent.expects(:send_report).with { |r, trans| r == report } @@ -184,7 +182,7 @@ describe Puppet::Configurer, "when executing a catalog run" do end it "should send the transaction report with a reference to the transaction if a run was actually made" do - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.expects(:initialize_report).returns report trans = stub 'transaction' @@ -198,7 +196,7 @@ describe Puppet::Configurer, "when executing a catalog run" do it "should send the transaction report even if the catalog could not be retrieved" do @agent.expects(:retrieve_catalog).returns nil - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.expects(:initialize_report).returns report @agent.expects(:send_report) @@ -208,7 +206,7 @@ describe Puppet::Configurer, "when executing a catalog run" do it "should send the transaction report even if there is a failure" do @agent.expects(:retrieve_catalog).raises "whatever" - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.expects(:initialize_report).returns report @agent.expects(:send_report) @@ -216,16 +214,16 @@ describe Puppet::Configurer, "when executing a catalog run" do end it "should remove the report as a log destination when the run is finished" do - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.expects(:initialize_report).returns report - - Puppet::Util::Log.expects(:close).with(report) + report.expects(:<<).at_least_once @agent.run + Puppet::Util::Log.destinations.should_not include(report) end it "should return the report as the result of the run" do - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.expects(:initialize_report).returns report @agent.run.should equal(report) @@ -236,8 +234,9 @@ describe Puppet::Configurer, "when sending a report" do before do Puppet.settings.stubs(:use).returns(true) @configurer = Puppet::Configurer.new + @configurer.stubs(:save_last_run_summary) - @report = stub 'report' + @report = Puppet::Transaction::Report.new @trans = stub 'transaction' end @@ -273,7 +272,7 @@ describe Puppet::Configurer, "when sending a report" do it "should save the report if reporting is enabled" do Puppet.settings[:report] = true - @report.expects(:save) + Puppet::Transaction::Report.indirection.expects(:save).with(@report) @configurer.send_report(@report) end @@ -284,16 +283,60 @@ describe Puppet::Configurer, "when sending a report" do @configurer.send_report(@report) end + it "should save the last run summary if reporting is enabled" do + Puppet.settings[:report] = true + + @configurer.expects(:save_last_run_summary).with(@report) + @configurer.send_report(@report) + end + + it "should not save the last run summary if reporting is disabled" do + Puppet.settings[:report] = false + + @configurer.expects(:save_last_run_summary).never + @configurer.send_report(@report) + end + it "should log but not fail if saving the report fails" do Puppet.settings[:report] = true - @report.expects(:save).raises "whatever" + Puppet::Transaction::Report.indirection.expects(:save).with(@report).raises "whatever" Puppet.expects(:err) lambda { @configurer.send_report(@report) }.should_not raise_error end end +describe Puppet::Configurer, "when saving the summary report file" do + before do + Puppet.settings.stubs(:use).returns(true) + @configurer = Puppet::Configurer.new + + @report = stub 'report' + @trans = stub 'transaction' + @lastrunfd = stub 'lastrunfd' + Puppet::Util::FileLocking.stubs(:writelock).yields(@lastrunfd) + end + + it "should write the raw summary to the lastrunfile setting value" do + Puppet::Util::FileLocking.expects(:writelock).with(Puppet[:lastrunfile], 0660) + @configurer.save_last_run_summary(@report) + end + + it "should write the raw summary as yaml" do + @report.expects(:raw_summary).returns("summary") + @lastrunfd.expects(:print).with(YAML.dump("summary")) + @configurer.save_last_run_summary(@report) + end + + it "should log but not fail if saving the last run summary fails" do + Puppet::Util::FileLocking.expects(:writelock).raises "exception" + Puppet.expects(:err) + lambda { @configurer.save_last_run_summary(@report) }.should_not raise_error + end + +end + describe Puppet::Configurer, "when retrieving a catalog" do before do Puppet.settings.stubs(:use).returns(true) @@ -314,15 +357,15 @@ describe Puppet::Configurer, "when retrieving a catalog" do end it "should first look in the cache for a catalog" do - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.never + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.never @agent.retrieve_catalog.should == @catalog end it "should compile a new catalog if none is found in the cache" do - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns nil - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns nil + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog @agent.retrieve_catalog.should == @catalog end @@ -331,7 +374,7 @@ describe Puppet::Configurer, "when retrieving a catalog" do describe "when not using a REST terminus for catalogs" do it "should not pass any facts when retrieving the catalog" do @agent.expects(:facts_for_uploading).never - Puppet::Resource::Catalog.expects(:find).with { |name, options| + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:facts].nil? }.returns @catalog @@ -342,7 +385,7 @@ describe Puppet::Configurer, "when retrieving a catalog" do describe "when using a REST terminus for catalogs" do it "should pass the prepared facts and the facts format as arguments when retrieving the catalog" do @agent.expects(:facts_for_uploading).returns(:facts => "myfacts", :facts_format => :foo) - Puppet::Resource::Catalog.expects(:find).with { |name, options| + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:facts] == "myfacts" and options[:facts_format] == :foo }.returns @catalog @@ -351,7 +394,7 @@ describe Puppet::Configurer, "when retrieving a catalog" do end it "should use the Catalog class to get its catalog" do - Puppet::Resource::Catalog.expects(:find).returns @catalog + Puppet::Resource::Catalog.indirection.expects(:find).returns @catalog @agent.retrieve_catalog end @@ -359,20 +402,20 @@ describe Puppet::Configurer, "when retrieving a catalog" do it "should use its certname to retrieve the catalog" do Facter.stubs(:value).returns "eh" Puppet.settings[:certname] = "myhost.domain.com" - Puppet::Resource::Catalog.expects(:find).with { |name, options| name == "myhost.domain.com" }.returns @catalog + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| name == "myhost.domain.com" }.returns @catalog @agent.retrieve_catalog end it "should default to returning a catalog retrieved directly from the server, skipping the cache" do - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog @agent.retrieve_catalog.should == @catalog end it "should log and return the cached catalog when no catalog can be retrieved from the server" do - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog Puppet.expects(:notice) @@ -380,15 +423,15 @@ describe Puppet::Configurer, "when retrieving a catalog" do end it "should not look in the cache for a catalog if one is returned from the server" do - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.never + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.never @agent.retrieve_catalog.should == @catalog end it "should return the cached catalog when retrieving the remote catalog throws an exception" do - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.raises "eh" - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.raises "eh" + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog @agent.retrieve_catalog.should == @catalog end @@ -396,7 +439,7 @@ describe Puppet::Configurer, "when retrieving a catalog" do it "should log and return nil if no catalog can be retrieved from the server and :usecacheonfailure is disabled" do Puppet.stubs(:[]) Puppet.expects(:[]).with(:usecacheonfailure).returns false - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil Puppet.expects(:warning) @@ -404,21 +447,21 @@ describe Puppet::Configurer, "when retrieving a catalog" do end it "should return nil if no cached catalog is available and no catalog can be retrieved from the server" do - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil - Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns nil + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil + Puppet::Resource::Catalog.indirection.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns nil @agent.retrieve_catalog.should be_nil end it "should convert the catalog before returning" do - Puppet::Resource::Catalog.stubs(:find).returns @catalog + Puppet::Resource::Catalog.indirection.stubs(:find).returns @catalog @agent.expects(:convert_catalog).with { |cat, dur| cat == @catalog }.returns "converted catalog" @agent.retrieve_catalog.should == "converted catalog" end it "should return nil if there is an error while retrieving the catalog" do - Puppet::Resource::Catalog.expects(:find).raises "eh" + Puppet::Resource::Catalog.indirection.expects(:find).raises "eh" @agent.retrieve_catalog.should be_nil end @@ -472,23 +515,23 @@ describe Puppet::Configurer, "when preparing for a run" do it "should initialize the metadata store" do @agent.class.stubs(:facts).returns(@facts) @agent.expects(:dostorage) - @agent.prepare + @agent.prepare({}) end it "should download fact plugins" do @agent.expects(:download_fact_plugins) - @agent.prepare + @agent.prepare({}) end it "should download plugins" do @agent.expects(:download_plugins) - @agent.prepare + @agent.prepare({}) end it "should perform the pre-run commands" do @agent.expects(:execute_prerun_command) - @agent.prepare + @agent.prepare({}) end end diff --git a/spec/unit/dsl/resource_type_api_spec.rb b/spec/unit/dsl/resource_type_api_spec.rb index 4f4eb7e01..c9a5d272f 100755 --- a/spec/unit/dsl/resource_type_api_spec.rb +++ b/spec/unit/dsl/resource_type_api_spec.rb @@ -5,62 +5,50 @@ require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/dsl/resource_type_api' describe Puppet::DSL::ResourceTypeAPI do - # Run the given block in the context of a new ResourceTypeAPI - # object. + # Verify that the block creates a single AST node through the API, + # instantiate that AST node into a types, and return that type. def test_api_call(&block) - Thread.current[:known_resource_types] = Puppet::Resource::TypeCollection.new(:env) - Puppet::DSL::ResourceTypeAPI.new.instance_eval(&block) + main_object = Puppet::DSL::ResourceTypeAPI.new + main_object.instance_eval(&block) + created_ast_objects = main_object.instance_eval { @__created_ast_objects__ } + created_ast_objects.length.should == 1 + new_types = created_ast_objects[0].instantiate('') + new_types.length.should == 1 + new_types[0] ensure - Thread.current[:known_resource_types] = nil + Thread.current[:ruby_file_parse_result] = nil end [:definition, :node, :hostclass].each do |type| method = type == :definition ? "define" : type it "should be able to create a #{type}" do - newtype = Puppet::Resource::Type.new(:hostclass, "foo") - Puppet::Resource::Type.expects(:new).with { |t, n, args| t == type }.returns newtype - test_api_call { send(method, "myname") } + newtype = test_api_call { send(method, "myname").should == nil } + newtype.should be_a(Puppet::Resource::Type) + newtype.type.should == type end it "should use the provided name when creating a #{type}" do - type = Puppet::Resource::Type.new(:hostclass, "foo") - Puppet::Resource::Type.expects(:new).with { |t, n, args| n == "myname" }.returns type - test_api_call { send(method, "myname") } + newtype = test_api_call { send(method, "myname") } + newtype.name.should == "myname" end unless type == :definition - it "should pass in any provided options" do - type = Puppet::Resource::Type.new(:hostclass, "foo") - Puppet::Resource::Type.expects(:new).with { |t, n, args| args == {:myarg => :myvalue} }.returns type - test_api_call { send(method, "myname", :myarg => :myvalue) } + it "should pass in any provided options when creating a #{type}" do + newtype = test_api_call { send(method, "myname", :line => 200) } + newtype.line.should == 200 end end it "should set any provided block as the type's ruby code" do - Puppet::Resource::Type.any_instance.expects(:ruby_code=).with { |blk| blk.call == 'foo' } - test_api_call { send(method, "myname") { 'foo' } } - end - - it "should add the type to the current environment's known resource types" do - begin - newtype = Puppet::Resource::Type.new(:hostclass, "foo") - Puppet::Resource::Type.expects(:new).returns newtype - known_resource_types = Puppet::Resource::TypeCollection.new(:env) - Thread.current[:known_resource_types] = known_resource_types - known_resource_types.expects(:add).with(newtype) - Puppet::DSL::ResourceTypeAPI.new.instance_eval { hostclass "myname" } - ensure - Thread.current[:known_resource_types] = nil - end + newtype = test_api_call { send(method, "myname") { 'method_result' } } + newtype.ruby_code.call.should == 'method_result' end end describe "when creating a definition" do it "should use the provided options to define valid arguments for the resource type" do - newtype = Puppet::Resource::Type.new(:definition, "foo") - Puppet::Resource::Type.expects(:new).returns newtype - test_api_call { define("myname", :arg1, :arg2) } - newtype.instance_eval { @arguments }.should == { 'arg1' => nil, 'arg2' => nil } + newtype = test_api_call { define("myname", :arg1, :arg2) } + newtype.arguments.should == { 'arg1' => nil, 'arg2' => nil } end end end diff --git a/spec/unit/file_bucket/dipper_spec.rb b/spec/unit/file_bucket/dipper_spec.rb index 799e899e7..46d314d1f 100755 --- a/spec/unit/file_bucket/dipper_spec.rb +++ b/spec/unit/file_bucket/dipper_spec.rb @@ -16,10 +16,9 @@ describe Puppet::FileBucket::Dipper do @dipper = Puppet::FileBucket::Dipper.new(:Path => "/my/bucket") - filemock = stub "bucketfile" - Puppet::FileBucket::File.stubs(:new).returns(filemock) - filemock.expects(:name).returns "name" - filemock.expects(:save).raises ArgumentError + Puppet::FileBucket::File.any_instance.stubs(:validate_checksum!) + file = Puppet::FileBucket::File.new(nil) + Puppet::FileBucket::File.indirection.expects(:save).raises ArgumentError lambda { @dipper.backup("/my/file") }.should raise_error(Puppet::Error) end @@ -32,10 +31,9 @@ describe Puppet::FileBucket::Dipper do File.stubs(:exist?).returns true File.stubs(:read).with("/my/file").returns "my contents" - bucketfile = stub "bucketfile" - bucketfile.stubs(:name).returns('md5/DIGEST123') - bucketfile.stubs(:checksum_data).returns("DIGEST123") - bucketfile.expects(:save).with('md5/DIGEST123') + Puppet::FileBucket::File.any_instance.stubs(:validate_checksum!) + bucketfile = Puppet::FileBucket::File.new(nil, :checksum_type => "md5", :checksum => "{md5}DIGEST123") + Puppet::FileBucket::File.indirection.expects(:save).with(bucketfile, 'md5/DIGEST123') Puppet::FileBucket::File.stubs(:new).with( @@ -60,7 +58,7 @@ describe Puppet::FileBucket::Dipper do bucketfile = stub "bucketfile" bucketfile.stubs(:to_s).returns "Content" - Puppet::FileBucket::File.expects(:find).with{|x,opts| + Puppet::FileBucket::File.indirection.expects(:find).with{|x,opts| x == 'md5/DIGEST123' }.returns(bucketfile) @@ -79,10 +77,9 @@ describe Puppet::FileBucket::Dipper do File.stubs(:exist?).returns true File.stubs(:read).with("/my/file").returns "my contents" - bucketfile = stub "bucketfile" - bucketfile.stubs(:name).returns('md5/DIGEST123') - bucketfile.stubs(:checksum_data).returns("DIGEST123") - bucketfile.expects(:save).with('https://puppetmaster:31337/production/file_bucket_file/md5/DIGEST123') + Puppet::FileBucket::File.any_instance.stubs(:validate_checksum!) + bucketfile = Puppet::FileBucket::File.new(nil, :checksum_type => "md5", :checksum => "{md5}DIGEST123") + Puppet::FileBucket::File.indirection.expects(:save).with(bucketfile, 'https://puppetmaster:31337/production/file_bucket_file/md5/DIGEST123') Puppet::FileBucket::File.stubs(:new).with( @@ -111,7 +108,7 @@ describe Puppet::FileBucket::Dipper do bucketfile = stub "bucketfile" bucketfile.stubs(:to_s).returns "Content" - Puppet::FileBucket::File.expects(:find).with{|x,opts| + Puppet::FileBucket::File.indirection.expects(:find).with{|x,opts| x == 'https://puppetmaster:31337/production/file_bucket_file/md5/DIGEST123' }.returns(bucketfile) diff --git a/spec/unit/file_bucket/file_spec.rb b/spec/unit/file_bucket/file_spec.rb index 3ad70c203..b9849b0fc 100644 --- a/spec/unit/file_bucket/file_spec.rb +++ b/spec/unit/file_bucket/file_spec.rb @@ -95,15 +95,7 @@ describe Puppet::FileBucket::File do end it "should have a :save instance method" do - Puppet::FileBucket::File.new("mysum").should respond_to(:save) - end - - it "should respond to :find" do - Puppet::FileBucket::File.should respond_to(:find) - end - - it "should respond to :destroy" do - Puppet::FileBucket::File.should respond_to(:destroy) + Puppet::FileBucket::File.indirection.should respond_to(:save) end end @@ -116,7 +108,7 @@ describe Puppet::FileBucket::File do mockfile.expects(:print).with(@contents) ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440).yields(mockfile) - Puppet::FileBucket::File.new(@contents).save + Puppet::FileBucket::File.indirection.save(Puppet::FileBucket::File.new(@contents)) end it "should make any directories necessary for storage" do @@ -127,7 +119,7 @@ describe Puppet::FileBucket::File do ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440) ::File.expects(:exist?).with("#{@dir}/contents").returns false - Puppet::FileBucket::File.new(@contents).save + Puppet::FileBucket::File.indirection.save(Puppet::FileBucket::File.new(@contents)) end it "should append the path to the paths file" do @@ -141,7 +133,7 @@ describe Puppet::FileBucket::File do mockfile.expects(:puts).with('/path/on/the/remote/box') ::File.expects(:exist?).with("#{@dir}/paths").returns false ::File.expects(:open).with("#{@dir}/paths", ::File::WRONLY|::File::CREAT|::File::APPEND).yields mockfile - Puppet::FileBucket::File.new(@contents, :path => remote_path).save + Puppet::FileBucket::File.indirection.save(Puppet::FileBucket::File.new(@contents, :path => remote_path)) end end @@ -187,7 +179,7 @@ describe Puppet::FileBucket::File do ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440) bucketfile = Puppet::FileBucket::File.new(@contents) - bucketfile.save + Puppet::FileBucket::File.indirection.save(bucketfile) end @@ -195,7 +187,7 @@ describe Puppet::FileBucket::File do it "should return nil if a file doesn't exist" do ::File.expects(:exist?).with("#{@dir}/contents").returns false - bucketfile = Puppet::FileBucket::File.find("{md5}#{@digest}") + bucketfile = Puppet::FileBucket::File.indirection.find("{md5}#{@digest}") bucketfile.should == nil end @@ -204,7 +196,7 @@ describe Puppet::FileBucket::File do ::File.expects(:exist?).with("#{@dir}/paths").returns false ::File.expects(:read).with("#{@dir}/contents").returns @contents - bucketfile = Puppet::FileBucket::File.find("{md5}#{@digest}") + bucketfile = Puppet::FileBucket::File.indirection.find("{md5}#{@digest}") bucketfile.should_not == nil end @@ -212,7 +204,7 @@ describe Puppet::FileBucket::File do it "should return nil if a file doesn't exist" do ::File.expects(:exist?).with("#{@dir}/contents").returns false - bucketfile = Puppet::FileBucket::File.find("md5/#{@digest}") + bucketfile = Puppet::FileBucket::File.indirection.find("md5/#{@digest}") bucketfile.should == nil end @@ -221,7 +213,7 @@ describe Puppet::FileBucket::File do ::File.expects(:exist?).with("#{@dir}/paths").returns false ::File.expects(:read).with("#{@dir}/contents").returns @contents - bucketfile = Puppet::FileBucket::File.find("md5/#{@digest}") + bucketfile = Puppet::FileBucket::File.indirection.find("md5/#{@digest}") bucketfile.should_not == nil end diff --git a/spec/unit/indirector/active_record_spec.rb b/spec/unit/indirector/active_record_spec.rb index 258c4e793..40af146c8 100755 --- a/spec/unit/indirector/active_record_spec.rb +++ b/spec/unit/indirector/active_record_spec.rb @@ -2,6 +2,7 @@ require File.dirname(__FILE__) + '/../../spec_helper' +require 'puppet/rails' require 'puppet/indirector/active_record' describe Puppet::Indirector::ActiveRecord do diff --git a/spec/unit/indirector/catalog/active_record_spec.rb b/spec/unit/indirector/catalog/active_record_spec.rb index 4e9d049a1..09e943376 100755 --- a/spec/unit/indirector/catalog/active_record_spec.rb +++ b/spec/unit/indirector/catalog/active_record_spec.rb @@ -80,7 +80,7 @@ describe "Puppet::Resource::Catalog::ActiveRecord" do @host.stubs(:railsmark).yields @node = stub_everything 'node', :parameters => {} - Puppet::Node.stubs(:find).returns(@node) + Puppet::Node.indirection.stubs(:find).returns(@node) Puppet::Rails::Host.stubs(:find_by_name).returns @host @catalog = Puppet::Resource::Catalog.new("foo") diff --git a/spec/unit/indirector/catalog/compiler_spec.rb b/spec/unit/indirector/catalog/compiler_spec.rb index 6c950b626..c8c53aecc 100755 --- a/spec/unit/indirector/catalog/compiler_spec.rb +++ b/spec/unit/indirector/catalog/compiler_spec.rb @@ -10,6 +10,7 @@ require 'puppet/rails' describe Puppet::Resource::Catalog::Compiler do before do + require 'puppet/rails' Puppet::Rails.stubs(:init) Facter.stubs(:to_hash).returns({}) Facter.stubs(:value).returns(Facter::Util::Fact.new("something")) @@ -31,8 +32,8 @@ describe Puppet::Resource::Catalog::Compiler do node1 = stub 'node1', :merge => nil node2 = stub 'node2', :merge => nil compiler.stubs(:compile) - Puppet::Node.stubs(:find).with('node1').returns(node1) - Puppet::Node.stubs(:find).with('node2').returns(node2) + Puppet::Node.indirection.stubs(:find).with('node1').returns(node1) + Puppet::Node.indirection.stubs(:find).with('node2').returns(node2) compiler.find(stub('request', :key => 'node1', :node => 'node1', :options => {})) compiler.find(stub('node2request', :key => 'node2', :node => 'node2', :options => {})) @@ -70,12 +71,12 @@ describe Puppet::Resource::Catalog::Compiler do @name = "me" @node = Puppet::Node.new @name @node.stubs(:merge) - Puppet::Node.stubs(:find).returns @node + Puppet::Node.indirection.stubs(:find).returns @node @request = stub 'request', :key => @name, :node => @name, :options => {} end it "should directly use provided nodes" do - Puppet::Node.expects(:find).never + Puppet::Node.indirection.expects(:find).never @compiler.expects(:compile).with(@node) @request.stubs(:options).returns(:use_node => @node) @compiler.find(@request) @@ -83,7 +84,7 @@ describe Puppet::Resource::Catalog::Compiler do it "should use the authenticated node name if no request key is provided" do @request.stubs(:key).returns(nil) - Puppet::Node.expects(:find).with(@name).returns(@node) + Puppet::Node.indirection.expects(:find).with(@name).returns(@node) @compiler.expects(:compile).with(@node) @compiler.find(@request) end @@ -91,37 +92,37 @@ describe Puppet::Resource::Catalog::Compiler do it "should use the provided node name by default" do @request.expects(:key).returns "my_node" - Puppet::Node.expects(:find).with("my_node").returns @node + Puppet::Node.indirection.expects(:find).with("my_node").returns @node @compiler.expects(:compile).with(@node) @compiler.find(@request) end it "should fail if no node is passed and none can be found" do - Puppet::Node.stubs(:find).with(@name).returns(nil) + Puppet::Node.indirection.stubs(:find).with(@name).returns(nil) proc { @compiler.find(@request) }.should raise_error(ArgumentError) end it "should fail intelligently when searching for a node raises an exception" do - Puppet::Node.stubs(:find).with(@name).raises "eh" + Puppet::Node.indirection.stubs(:find).with(@name).raises "eh" proc { @compiler.find(@request) }.should raise_error(Puppet::Error) end it "should pass the found node to the compiler for compiling" do - Puppet::Node.expects(:find).with(@name).returns(@node) + Puppet::Node.indirection.expects(:find).with(@name).returns(@node) config = mock 'config' Puppet::Parser::Compiler.expects(:compile).with(@node) @compiler.find(@request) end it "should extract and save any facts from the request" do - Puppet::Node.expects(:find).with(@name).returns @node + Puppet::Node.indirection.expects(:find).with(@name).returns @node @compiler.expects(:extract_facts_from_request).with(@request) Puppet::Parser::Compiler.stubs(:compile) @compiler.find(@request) end it "should return the results of compiling as the catalog" do - Puppet::Node.stubs(:find).returns(@node) + Puppet::Node.indirection.stubs(:find).returns(@node) config = mock 'config' result = mock 'result' @@ -130,7 +131,7 @@ describe Puppet::Resource::Catalog::Compiler do end it "should benchmark the compile process" do - Puppet::Node.stubs(:find).returns(@node) + Puppet::Node.indirection.stubs(:find).returns(@node) @compiler.stubs(:networked?).returns(true) @compiler.expects(:benchmark).with do |level, message| level == :notice and message =~ /^Compiled catalog/ @@ -140,7 +141,7 @@ describe Puppet::Resource::Catalog::Compiler do end it "should log the benchmark result" do - Puppet::Node.stubs(:find).returns(@node) + Puppet::Node.indirection.stubs(:find).returns(@node) @compiler.stubs(:networked?).returns(true) Puppet::Parser::Compiler.stubs(:compile) @@ -156,22 +157,28 @@ describe Puppet::Resource::Catalog::Compiler do @compiler = Puppet::Resource::Catalog::Compiler.new @request = stub 'request', :options => {} - @facts = stub 'facts', :save => nil + @facts = Puppet::Node::Facts.new('hostname', "fact" => "value", "architecture" => "i386") + Puppet::Node::Facts.indirection.stubs(:save).returns(nil) end it "should do nothing if no facts are provided" do - Puppet::Node::Facts.expects(:convert_from).never + Puppet::Node::Facts.indirection.expects(:convert_from).never @request.options[:facts] = nil @compiler.extract_facts_from_request(@request) end - it "should use the Facts class to deserialize the provided facts" do + it "should use the Facts class to deserialize the provided facts and update the timestamp" do @request.options[:facts_format] = "foo" @request.options[:facts] = "bar" Puppet::Node::Facts.expects(:convert_from).returns @facts + @facts.timestamp = Time.parse('2010-11-01') + @now = Time.parse('2010-11-02') + Time.expects(:now).returns(@now) + @compiler.extract_facts_from_request(@request) + @facts.timestamp.should == @now end it "should use the provided fact format" do @@ -187,7 +194,7 @@ describe Puppet::Resource::Catalog::Compiler do @request.options[:facts] = "bar" Puppet::Node::Facts.expects(:convert_from).returns @facts - @facts.expects(:save) + Puppet::Node::Facts.indirection.expects(:save).with(@facts) @compiler.extract_facts_from_request(@request) end @@ -205,7 +212,7 @@ describe Puppet::Resource::Catalog::Compiler do it "should look node information up via the Node class with the provided key" do @node.stubs :merge - Puppet::Node.expects(:find).with(@name).returns(@node) + Puppet::Node.indirection.expects(:find).with(@name).returns(@node) @compiler.find(@request) end end @@ -220,7 +227,7 @@ describe Puppet::Resource::Catalog::Compiler do @node = mock 'node' @request = stub 'request', :key => @name, :options => {} @compiler.stubs(:compile) - Puppet::Node.stubs(:find).with(@name).returns(@node) + Puppet::Node.indirection.stubs(:find).with(@name).returns(@node) end it "should add the server's Puppet version to the node's parameters as 'serverversion'" do diff --git a/spec/unit/indirector/facts/active_record_spec.rb b/spec/unit/indirector/facts/active_record_spec.rb index 0cdb70e01..0bdcfcb77 100755 --- a/spec/unit/indirector/facts/active_record_spec.rb +++ b/spec/unit/indirector/facts/active_record_spec.rb @@ -2,6 +2,7 @@ require File.dirname(__FILE__) + '/../../../spec_helper' +require 'puppet/rails' require 'puppet/node/facts' describe "Puppet::Node::Facts::ActiveRecord" do diff --git a/spec/unit/indirector/facts/yaml_spec.rb b/spec/unit/indirector/facts/yaml_spec.rb index e7bac3471..37a1bcae0 100755 --- a/spec/unit/indirector/facts/yaml_spec.rb +++ b/spec/unit/indirector/facts/yaml_spec.rb @@ -10,9 +10,9 @@ describe Puppet::Node::Facts::Yaml do Puppet::Node::Facts::Yaml.superclass.should equal(Puppet::Indirector::Yaml) end - it "should have documentation" do Puppet::Node::Facts::Yaml.doc.should_not be_nil + Puppet::Node::Facts::Yaml.doc.should_not be_empty end it "should be registered with the facts indirection" do @@ -20,7 +20,7 @@ describe Puppet::Node::Facts::Yaml do Puppet::Node::Facts::Yaml.indirection.should equal(indirection) end - it "should have its name set to :facts" do + it "should have its name set to :yaml" do Puppet::Node::Facts::Yaml.name.should == :yaml end end diff --git a/spec/unit/indirector/indirection_spec.rb b/spec/unit/indirector/indirection_spec.rb index b0e0f019c..f49d94f8e 100755 --- a/spec/unit/indirector/indirection_spec.rb +++ b/spec/unit/indirector/indirection_spec.rb @@ -386,9 +386,6 @@ describe Puppet::Indirector::Indirection do describe "and storing a model instance" do before { @method = :save } - it_should_behave_like "Indirection Delegator" - it_should_behave_like "Delegation Authorizer" - it "should return the result of the save" do @terminus.stubs(:save).returns "foo" @indirection.save(@instance).should == "foo" diff --git a/spec/unit/indirector/inventory/yaml_spec.rb b/spec/unit/indirector/inventory/yaml_spec.rb new file mode 100644 index 000000000..9f0c54353 --- /dev/null +++ b/spec/unit/indirector/inventory/yaml_spec.rb @@ -0,0 +1,221 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +require 'puppet/node/inventory' +require 'puppet/indirector/inventory/yaml' +require 'puppet/indirector/request' + +describe Puppet::Node::Inventory::Yaml do + def assert_search_matches(matching, nonmatching, query) + request = Puppet::Indirector::Request.new(:inventory, :search, nil, query) + + Dir.stubs(:glob).returns(matching.keys + nonmatching.keys) + [matching, nonmatching].each do |examples| + examples.each do |key, value| + YAML.stubs(:load_file).with(key).returns value + end + end + Puppet::Node::Inventory::Yaml.new.search(request).should =~ matching.values.map {|facts| facts.name} + end + + it "should return node names that match the search query options" do + assert_search_matches({ + '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '4'), + '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "i386", 'processor_count' => '4', 'randomfact' => 'foo') + }, + { + "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '4'), + "/path/to/nonmatching1.yaml" => Puppet::Node::Facts.new("nonmatchingnode1", "architecture" => "powerpc", 'processor_count' => '5'), + "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '5'), + "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3", 'processor_count' => '4'), + }, + {'facts.architecture' => 'i386', 'facts.processor_count' => '4'} + ) + end + + it "should return empty array when no nodes match the search query options" do + assert_search_matches({}, { + "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '10'), + "/path/to/nonmatching1.yaml" => Puppet::Node::Facts.new("nonmatchingnode1", "architecture" => "powerpc", 'processor_count' => '5'), + "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '5'), + "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3", 'processor_count' => '4'), + }, + {'facts.processor_count.lt' => '4', 'facts.processor_count.gt' => '4'} + ) + end + + + it "should return node names that match the search query options with the greater than operator" do + assert_search_matches({ + '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '5'), + '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "powerpc", 'processor_count' => '10', 'randomfact' => 'foo') + }, + { + "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '4'), + "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '3'), + "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ), + }, + {'facts.processor_count.gt' => '4'} + ) + end + + it "should return node names that match the search query options with the less than operator" do + assert_search_matches({ + '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '5'), + '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "powerpc", 'processor_count' => '30', 'randomfact' => 'foo') + }, + { + "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '50' ), + "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '100'), + "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ), + }, + {'facts.processor_count.lt' => '50'} + ) + end + + it "should return node names that match the search query options with the less than or equal to operator" do + assert_search_matches({ + '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '5'), + '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "powerpc", 'processor_count' => '50', 'randomfact' => 'foo') + }, + { + "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '100' ), + "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '5000'), + "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ), + }, + {'facts.processor_count.le' => '50'} + ) + end + + it "should return node names that match the search query options with the greater than or equal to operator" do + assert_search_matches({ + '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => "i386", 'processor_count' => '100'), + '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => "powerpc", 'processor_count' => '50', 'randomfact' => 'foo') + }, + { + "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "powerpc", 'processor_count' => '40'), + "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '9' ), + "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ), + }, + {'facts.processor_count.ge' => '50'} + ) + end + + it "should return node names that match the search query options with the not equal operator" do + assert_search_matches({ + '/path/to/matching.yaml' => Puppet::Node::Facts.new("matchingnode", "architecture" => 'arm' ), + '/path/to/matching1.yaml' => Puppet::Node::Facts.new("matchingnode1", "architecture" => 'powerpc', 'randomfact' => 'foo') + }, + { + "/path/to/nonmatching.yaml" => Puppet::Node::Facts.new("nonmatchingnode", "architecture" => "i386" ), + "/path/to/nonmatching2.yaml" => Puppet::Node::Facts.new("nonmatchingnode2", "architecture" => "i386", 'processor_count' => '9' ), + "/path/to/nonmatching3.yaml" => Puppet::Node::Facts.new("nonmatchingnode3" ), + }, + {'facts.architecture.ne' => 'i386'} + ) + end + + def apply_timestamp(facts, timestamp) + facts.timestamp = timestamp + facts + end + + it "should be able to query based on meta.timestamp.gt" do + assert_search_matches({ + '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")), + '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")), + }, + { + '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")), + '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")), + '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")), + }, + {'meta.timestamp.gt' => '2010-10-15'} + ) + end + + it "should be able to query based on meta.timestamp.le" do + assert_search_matches({ + '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")), + '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")), + '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")), + }, + { + '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")), + '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")), + }, + {'meta.timestamp.le' => '2010-10-15'} + ) + end + + it "should be able to query based on meta.timestamp.lt" do + assert_search_matches({ + '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")), + '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")), + }, + { + '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")), + '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")), + '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")), + }, + {'meta.timestamp.lt' => '2010-10-15'} + ) + end + + it "should be able to query based on meta.timestamp.ge" do + assert_search_matches({ + '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")), + '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")), + '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")), + }, + { + '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")), + '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")), + }, + {'meta.timestamp.ge' => '2010-10-15'} + ) + end + + it "should be able to query based on meta.timestamp.eq" do + assert_search_matches({ + '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")), + }, + { + '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")), + '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")), + '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")), + '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")), + }, + {'meta.timestamp.eq' => '2010-10-15'} + ) + end + + it "should be able to query based on meta.timestamp" do + assert_search_matches({ + '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")), + }, + { + '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")), + '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")), + '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")), + '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")), + }, + {'meta.timestamp' => '2010-10-15'} + ) + end + + it "should be able to query based on meta.timestamp.ne" do + assert_search_matches({ + '/path/to/2010-11-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-01", {}), Time.parse("2010-11-01")), + '/path/to/2010-11-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-11-10", {}), Time.parse("2010-11-10")), + '/path/to/2010-10-01.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-01", {}), Time.parse("2010-10-01")), + '/path/to/2010-10-10.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-10", {}), Time.parse("2010-10-10")), + }, + { + '/path/to/2010-10-15.yaml' => apply_timestamp(Puppet::Node::Facts.new("2010-10-15", {}), Time.parse("2010-10-15")), + }, + {'meta.timestamp.ne' => '2010-10-15'} + ) + end +end diff --git a/spec/unit/indirector/node/ldap_spec.rb b/spec/unit/indirector/node/ldap_spec.rb index 042e7bd54..95ec12c80 100755 --- a/spec/unit/indirector/node/ldap_spec.rb +++ b/spec/unit/indirector/node/ldap_spec.rb @@ -311,7 +311,7 @@ describe Puppet::Node::Ldap do @options = {} @request = stub 'request', :key => "foo", :options => @options - Puppet::Node::Facts.stubs(:terminus_class).returns :yaml + Puppet::Node::Facts.indirection.stubs(:terminus_class).returns :yaml end it "should find all nodes if no arguments are provided" do diff --git a/spec/unit/indirector/report/yaml_spec.rb b/spec/unit/indirector/report/yaml_spec.rb new file mode 100644 index 000000000..610c9ae43 --- /dev/null +++ b/spec/unit/indirector/report/yaml_spec.rb @@ -0,0 +1,38 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +require 'puppet/transaction/report' +require 'puppet/indirector/report/yaml' + +describe Puppet::Transaction::Report::Yaml do + it "should be a subclass of the Yaml terminus" do + Puppet::Transaction::Report::Yaml.superclass.should equal(Puppet::Indirector::Yaml) + end + + it "should have documentation" do + Puppet::Transaction::Report::Yaml.doc.should_not be_nil + end + + it "should be registered with the report indirection" do + indirection = Puppet::Indirector::Indirection.instance(:report) + Puppet::Transaction::Report::Yaml.indirection.should equal(indirection) + end + + it "should have its name set to :yaml" do + Puppet::Transaction::Report::Yaml.name.should == :yaml + end + + it "should inconditionnally save/load from the --lastrunreport setting" do + indirection = stub 'indirection', :name => :my_yaml, :register_terminus_type => nil + Puppet::Indirector::Indirection.stubs(:instance).with(:my_yaml).returns(indirection) + store_class = Class.new(Puppet::Transaction::Report::Yaml) do + def self.to_s + "MyYaml::MyType" + end + end + store = store_class.new + + store.path(:me).should == Puppet[:lastrunreport] + end +end diff --git a/spec/unit/indirector_spec.rb b/spec/unit/indirector_spec.rb index fb21532ba..7c193a9aa 100755 --- a/spec/unit/indirector_spec.rb +++ b/spec/unit/indirector_spec.rb @@ -64,24 +64,6 @@ describe Puppet::Indirector, "when registering an indirection" do end end -describe "Delegated Indirection Method", :shared => true do - it "should delegate to the indirection" do - @indirection.expects(@method) - @thingie.send(@method, "me") - end - - it "should pass all of the passed arguments directly to the indirection instance" do - @indirection.expects(@method).with("me", :one => :two) - @thingie.send(@method, "me", :one => :two) - end - - it "should return the results of the delegation as its result" do - request = mock 'request' - @indirection.expects(@method).returns "yay" - @thingie.send(@method, "me").should == "yay" - end -end - describe Puppet::Indirector, "when redirecting a model" do before do @thingie = Class.new do @@ -98,59 +80,6 @@ describe Puppet::Indirector, "when redirecting a model" do @thingie.ancestors.should be_include(Puppet::Indirector::Envelope) end - describe "when finding instances via the model" do - before { @method = :find } - it_should_behave_like "Delegated Indirection Method" - end - - describe "when destroying instances via the model" do - before { @method = :destroy } - it_should_behave_like "Delegated Indirection Method" - end - - describe "when searching for instances via the model" do - before { @method = :search } - it_should_behave_like "Delegated Indirection Method" - end - - describe "when expiring instances via the model" do - before { @method = :expire } - it_should_behave_like "Delegated Indirection Method" - end - - # This is an instance method, so it behaves a bit differently. - describe "when saving instances via the model" do - before do - @instance = @thingie.new("me") - end - - it "should delegate to the indirection" do - @indirection.expects(:save) - @instance.save - end - - it "should pass the instance and an optional key to the indirection's :save method" do - @indirection.expects(:save).with("key", @instance) - @instance.save "key" - end - - it "should return the results of the delegation as its result" do - request = mock 'request' - @indirection.expects(:save).returns "yay" - @instance.save.should == "yay" - end - end - - it "should give the model the ability to set the indirection terminus class" do - @indirection.expects(:terminus_class=).with(:myterm) - @thingie.terminus_class = :myterm - end - - it "should give the model the ability to set the indirection cache class" do - @indirection.expects(:cache_class=).with(:mycache) - @thingie.cache_class = :mycache - end - after do @indirection.delete end diff --git a/spec/unit/network/http/api/v1_spec.rb b/spec/unit/network/http/api/v1_spec.rb index c593242c0..84b98ddaf 100644 --- a/spec/unit/network/http/api/v1_spec.rb +++ b/spec/unit/network/http/api/v1_spec.rb @@ -32,7 +32,7 @@ describe Puppet::Network::HTTP::API::V1 do end it "should use the first field of the URI as the environment" do - @tester.uri2indirection("GET", "/env/foo/bar", {}).environment.should == Puppet::Node::Environment.new("env") + @tester.uri2indirection("GET", "/env/foo/bar", {})[3][:environment].should == "env" end it "should fail if the environment is not alphanumeric" do @@ -40,11 +40,11 @@ describe Puppet::Network::HTTP::API::V1 do end it "should use the environment from the URI even if one is specified in the parameters" do - @tester.uri2indirection("GET", "/env/foo/bar", {:environment => "otherenv"}).environment.should == Puppet::Node::Environment.new("env") + @tester.uri2indirection("GET", "/env/foo/bar", {:environment => "otherenv"})[3][:environment].should == "env" end it "should use the second field of the URI as the indirection name" do - @tester.uri2indirection("GET", "/env/foo/bar", {}).indirection_name.should == :foo + @tester.uri2indirection("GET", "/env/foo/bar", {})[0].should == "foo" end it "should fail if the indirection name is not alphanumeric" do @@ -52,11 +52,11 @@ describe Puppet::Network::HTTP::API::V1 do end it "should use the remainder of the URI as the indirection key" do - @tester.uri2indirection("GET", "/env/foo/bar", {}).key.should == "bar" + @tester.uri2indirection("GET", "/env/foo/bar", {})[2].should == "bar" end it "should support the indirection key being a /-separated file path" do - @tester.uri2indirection("GET", "/env/foo/bee/baz/bomb", {}).key.should == "bee/baz/bomb" + @tester.uri2indirection("GET", "/env/foo/bee/baz/bomb", {})[2].should == "bee/baz/bomb" end it "should fail if no indirection key is specified" do @@ -65,19 +65,31 @@ describe Puppet::Network::HTTP::API::V1 do end it "should choose 'find' as the indirection method if the http method is a GET and the indirection name is singular" do - @tester.uri2indirection("GET", "/env/foo/bar", {}).method.should == :find + @tester.uri2indirection("GET", "/env/foo/bar", {})[1].should == :find end it "should choose 'search' as the indirection method if the http method is a GET and the indirection name is plural" do - @tester.uri2indirection("GET", "/env/foos/bar", {}).method.should == :search + @tester.uri2indirection("GET", "/env/foos/bar", {})[1].should == :search + end + + it "should choose 'find' as the indirection method if the http method is a GET and the indirection name is facts" do + @tester.uri2indirection("GET", "/env/facts/bar", {})[1].should == :find + end + + it "should choose 'save' as the indirection method if the http method is a PUT and the indirection name is facts" do + @tester.uri2indirection("PUT", "/env/facts/bar", {})[1].should == :save + end + + it "should choose 'search' as the indirection method if the http method is a GET and the indirection name is inventory" do + @tester.uri2indirection("GET", "/env/inventory/search", {})[1].should == :search end it "should choose 'delete' as the indirection method if the http method is a DELETE and the indirection name is singular" do - @tester.uri2indirection("DELETE", "/env/foo/bar", {}).method.should == :destroy + @tester.uri2indirection("DELETE", "/env/foo/bar", {})[1].should == :destroy end it "should choose 'save' as the indirection method if the http method is a PUT and the indirection name is singular" do - @tester.uri2indirection("PUT", "/env/foo/bar", {}).method.should == :save + @tester.uri2indirection("PUT", "/env/foo/bar", {})[1].should == :save end it "should fail if an indirection method cannot be picked" do @@ -86,7 +98,8 @@ describe Puppet::Network::HTTP::API::V1 do it "should URI unescape the indirection key" do escaped = URI.escape("foo bar") - @tester.uri2indirection("GET", "/env/foo/#{escaped}", {}).key.should == "foo bar" + indirection_name, method, key, params = @tester.uri2indirection("GET", "/env/foo/#{escaped}", {}) + key.should == "foo bar" end end diff --git a/spec/unit/network/http/handler_spec.rb b/spec/unit/network/http/handler_spec.rb index 76a9c5530..e14b5739d 100755 --- a/spec/unit/network/http/handler_spec.rb +++ b/spec/unit/network/http/handler_spec.rb @@ -46,6 +46,8 @@ describe Puppet::Network::HTTP::Handler do @request.stubs(:[]).returns "foo" @response = stub('http response') @model_class = stub('indirected model class') + @indirection = stub('indirection') + @model_class.stubs(:indirection).returns(@indirection) @result = stub 'result', :render => "mytext" @@ -79,37 +81,22 @@ describe Puppet::Network::HTTP::Handler do @handler.process(@request, @response) end - it "should call the 'do' method associated with the indirection method" do - request = stub 'request' - @handler.expects(:uri2indirection).returns request + it "should call the 'do' method and delegate authorization to the RestAuthorization layer" do + @handler.expects(:uri2indirection).returns(["facts", :mymethod, "key", {:node => "name"}]) - request.expects(:method).returns "mymethod" + @handler.expects(:do_mymethod).with("facts", "key", {:node => "name"}, @request, @response) - @handler.expects(:do_mymethod).with(request, @request, @response) - - @handler.process(@request, @response) - end - - it "should delegate authorization to the RestAuthorization layer" do - request = stub 'request' - @handler.expects(:uri2indirection).returns request - - request.expects(:method).returns "mymethod" - - @handler.expects(:do_mymethod).with(request, @request, @response) - - @handler.expects(:check_authorization).with(request) + @handler.expects(:check_authorization).with("facts", :mymethod, "key", {:node => "name"}) @handler.process(@request, @response) end it "should return 403 if the request is not authorized" do - request = stub 'request' - @handler.expects(:uri2indirection).returns request + @handler.expects(:uri2indirection).returns(["facts", :mymethod, "key", {:node => "name"}]) @handler.expects(:do_mymethod).never - @handler.expects(:check_authorization).with(request).raises(Puppet::Network::AuthorizationError.new("forbindden")) + @handler.expects(:check_authorization).with("facts", :mymethod, "key", {:node => "name"}).raises(Puppet::Network::AuthorizationError.new("forbidden")) @handler.expects(:set_response).with { |response, body, status| status == 403 } @@ -117,7 +104,7 @@ describe Puppet::Network::HTTP::Handler do end it "should serialize a controller exception when an exception is thrown while finding the model instance" do - @handler.expects(:uri2indirection).returns stub("request", :method => :find) + @handler.expects(:uri2indirection).returns(["facts", :find, "key", {:node => "name"}]) @handler.expects(:do_find).raises(ArgumentError, "The exception") @handler.expects(:set_response).with { |response, body, status| body == "The exception" and status == 400 } @@ -141,9 +128,8 @@ describe Puppet::Network::HTTP::Handler do describe "when finding a model instance" do before do - @irequest = stub 'indirection_request', :method => :find, :indirection_name => "my_handler", :to_hash => {}, :key => "my_result", :model => @model_class - - @model_class.stubs(:find).returns @result + @indirection.stubs(:find).returns @result + Puppet::Indirector::Indirection.expects(:instance).with(:my_handler).returns( stub "indirection", :model => @model_class ) @format = stub 'format', :suitable? => true, :mime => "text/format", :name => "format" Puppet::Network::FormatHandler.stubs(:format).returns @format @@ -153,40 +139,37 @@ describe Puppet::Network::HTTP::Handler do end it "should use the indirection request to find the model class" do - @irequest.expects(:model).returns @model_class - - @handler.do_find(@irequest, @request, @response) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end it "should use the escaped request key" do - @model_class.expects(:find).with do |key, args| + @indirection.expects(:find).with do |key, args| key == "my_result" end.returns @result - @handler.do_find(@irequest, @request, @response) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end it "should use a common method for determining the request parameters" do - @irequest.stubs(:to_hash).returns(:foo => :baz, :bar => :xyzzy) - @model_class.expects(:find).with do |key, args| + @indirection.expects(:find).with do |key, args| args[:foo] == :baz and args[:bar] == :xyzzy end.returns @result - @handler.do_find(@irequest, @request, @response) + @handler.do_find("my_handler", "my_result", {:foo => :baz, :bar => :xyzzy}, @request, @response) end it "should set the content type to the first format specified in the accept header" do @handler.expects(:accept_header).with(@request).returns "one,two" @handler.expects(:set_content_type).with(@response, @oneformat) - @handler.do_find(@irequest, @request, @response) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end it "should fail if no accept header is provided" do @handler.expects(:accept_header).with(@request).returns nil - lambda { @handler.do_find(@irequest, @request, @response) }.should raise_error(ArgumentError) + lambda { @handler.do_find("my_handler", "my_result", {}, @request, @response) }.should raise_error(ArgumentError) end it "should fail if the accept header does not contain a valid format" do @handler.expects(:accept_header).with(@request).returns "" - lambda { @handler.do_find(@irequest, @request, @response) }.should raise_error(RuntimeError) + lambda { @handler.do_find("my_handler", "my_result", {}, @request, @response) }.should raise_error(RuntimeError) end it "should not use an unsuitable format" do @@ -198,7 +181,7 @@ describe Puppet::Network::HTTP::Handler do @handler.expects(:set_content_type).with(@response, bar) # the suitable one - @handler.do_find(@irequest, @request, @response) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end it "should render the result using the first format specified in the accept header" do @@ -206,12 +189,12 @@ describe Puppet::Network::HTTP::Handler do @handler.expects(:accept_header).with(@request).returns "one,two" @result.expects(:render).with(@oneformat) - @handler.do_find(@irequest, @request, @response) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end it "should use the default status when a model find call succeeds" do @handler.expects(:set_response).with { |response, body, status| status.nil? } - @handler.do_find(@irequest, @request, @response) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end it "should return a serialized object when a model find call succeeds" do @@ -219,24 +202,24 @@ describe Puppet::Network::HTTP::Handler do @model_instance.expects(:render).returns "my_rendered_object" @handler.expects(:set_response).with { |response, body, status| body == "my_rendered_object" } - @model_class.stubs(:find).returns(@model_instance) - @handler.do_find(@irequest, @request, @response) + @indirection.stubs(:find).returns(@model_instance) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end it "should return a 404 when no model instance can be found" do @model_class.stubs(:name).returns "my name" @handler.expects(:set_response).with { |response, body, status| status == 404 } - @model_class.stubs(:find).returns(nil) - @handler.do_find(@irequest, @request, @response) + @indirection.stubs(:find).returns(nil) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end it "should write a log message when no model instance can be found" do @model_class.stubs(:name).returns "my name" - @model_class.stubs(:find).returns(nil) + @indirection.stubs(:find).returns(nil) Puppet.expects(:info).with("Could not find my_handler for 'my_result'") - @handler.do_find(@irequest, @request, @response) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end @@ -245,21 +228,21 @@ describe Puppet::Network::HTTP::Handler do @handler.expects(:format_to_use).returns(@oneformat) @model_instance.expects(:render).with(@oneformat).returns "my_rendered_object" - @model_class.stubs(:find).returns(@model_instance) - @handler.do_find(@irequest, @request, @response) + @indirection.stubs(:find).returns(@model_instance) + @handler.do_find("my_handler", "my_result", {}, @request, @response) end end describe "when searching for model instances" do before do - @irequest = stub 'indirection_request', :method => :find, :indirection_name => "my_handler", :to_hash => {}, :key => "key", :model => @model_class + Puppet::Indirector::Indirection.expects(:instance).with(:my_handler).returns( stub "indirection", :model => @model_class ) @result1 = mock 'result1' @result2 = mock 'results' @result = [@result1, @result2] @model_class.stubs(:render_multiple).returns "my rendered instances" - @model_class.stubs(:search).returns(@result) + @indirection.stubs(:search).returns(@result) @format = stub 'format', :suitable? => true, :mime => "text/format", :name => "format" Puppet::Network::FormatHandler.stubs(:format).returns @format @@ -269,112 +252,109 @@ describe Puppet::Network::HTTP::Handler do end it "should use the indirection request to find the model" do - @irequest.expects(:model).returns @model_class - - @handler.do_search(@irequest, @request, @response) + @handler.do_search("my_handler", "my_result", {}, @request, @response) end it "should use a common method for determining the request parameters" do - @irequest.stubs(:to_hash).returns(:foo => :baz, :bar => :xyzzy) - @model_class.expects(:search).with do |key, args| + @indirection.expects(:search).with do |key, args| args[:foo] == :baz and args[:bar] == :xyzzy end.returns @result - @handler.do_search(@irequest, @request, @response) + @handler.do_search("my_handler", "my_result", {:foo => :baz, :bar => :xyzzy}, @request, @response) end it "should use the default status when a model search call succeeds" do - @model_class.stubs(:search).returns(@result) - @handler.do_search(@irequest, @request, @response) + @indirection.stubs(:search).returns(@result) + @handler.do_search("my_handler", "my_result", {}, @request, @response) end it "should set the content type to the first format returned by the accept header" do @handler.expects(:accept_header).with(@request).returns "one,two" @handler.expects(:set_content_type).with(@response, @oneformat) - @handler.do_search(@irequest, @request, @response) + @handler.do_search("my_handler", "my_result", {}, @request, @response) end it "should return a list of serialized objects when a model search call succeeds" do @handler.expects(:accept_header).with(@request).returns "one,two" - @model_class.stubs(:search).returns(@result) + @indirection.stubs(:search).returns(@result) @model_class.expects(:render_multiple).with(@oneformat, @result).returns "my rendered instances" @handler.expects(:set_response).with { |response, data| data == "my rendered instances" } - @handler.do_search(@irequest, @request, @response) + @handler.do_search("my_handler", "my_result", {}, @request, @response) end - it "should return a 404 when searching returns an empty array" do - @model_class.stubs(:name).returns "my name" - @handler.expects(:set_response).with { |response, body, status| status == 404 } - @model_class.stubs(:search).returns([]) - @handler.do_search(@irequest, @request, @response) + it "should return [] when searching returns an empty array" do + @handler.expects(:accept_header).with(@request).returns "one,two" + @indirection.stubs(:search).returns([]) + @model_class.expects(:render_multiple).with(@oneformat, []).returns "[]" + + + @handler.expects(:set_response).with { |response, data| data == "[]" } + @handler.do_search("my_handler", "my_result", {}, @request, @response) end it "should return a 404 when searching returns nil" do @model_class.stubs(:name).returns "my name" @handler.expects(:set_response).with { |response, body, status| status == 404 } - @model_class.stubs(:search).returns([]) - @handler.do_search(@irequest, @request, @response) + @indirection.stubs(:search).returns(nil) + @handler.do_search("my_handler", "my_result", {}, @request, @response) end end describe "when destroying a model instance" do before do - @irequest = stub 'indirection_request', :method => :destroy, :indirection_name => "my_handler", :to_hash => {}, :key => "key", :model => @model_class + Puppet::Indirector::Indirection.expects(:instance).with(:my_handler).returns( stub "indirection", :model => @model_class ) @result = stub 'result', :render => "the result" - @model_class.stubs(:destroy).returns @result + @indirection.stubs(:destroy).returns @result end it "should use the indirection request to find the model" do - @irequest.expects(:model).returns @model_class - - @handler.do_destroy(@irequest, @request, @response) + @handler.do_destroy("my_handler", "my_result", {}, @request, @response) end it "should use the escaped request key to destroy the instance in the model" do - @irequest.expects(:key).returns "foo bar" - @model_class.expects(:destroy).with do |key, args| + @indirection.expects(:destroy).with do |key, args| key == "foo bar" end - @handler.do_destroy(@irequest, @request, @response) + @handler.do_destroy("my_handler", "foo bar", {}, @request, @response) end it "should use a common method for determining the request parameters" do - @irequest.stubs(:to_hash).returns(:foo => :baz, :bar => :xyzzy) - @model_class.expects(:destroy).with do |key, args| + @indirection.expects(:destroy).with do |key, args| args[:foo] == :baz and args[:bar] == :xyzzy end - @handler.do_destroy(@irequest, @request, @response) + @handler.do_destroy("my_handler", "my_result", {:foo => :baz, :bar => :xyzzy}, @request, @response) end it "should use the default status code a model destroy call succeeds" do @handler.expects(:set_response).with { |response, body, status| status.nil? } - @handler.do_destroy(@irequest, @request, @response) + @handler.do_destroy("my_handler", "my_result", {}, @request, @response) end it "should return a yaml-encoded result when a model destroy call succeeds" do @result = stub 'result', :to_yaml => "the result" - @model_class.expects(:destroy).returns(@result) + @indirection.expects(:destroy).returns(@result) @handler.expects(:set_response).with { |response, body, status| body == "the result" } - @handler.do_destroy(@irequest, @request, @response) + @handler.do_destroy("my_handler", "my_result", {}, @request, @response) end end describe "when saving a model instance" do before do - @irequest = stub 'indirection_request', :method => :save, :indirection_name => "my_handler", :to_hash => {}, :key => "key", :model => @model_class + Puppet::Indirector::Indirection.stubs(:instance).with(:my_handler).returns( stub "indirection", :model => @model_class ) @handler.stubs(:body).returns('my stuff') @handler.stubs(:content_type_header).returns("text/yaml") @result = stub 'result', :render => "the result" - @model_instance = stub('indirected model instance', :save => true) + @model_instance = stub('indirected model instance') @model_class.stubs(:convert_from).returns(@model_instance) + @indirection.stubs(:save) @format = stub 'format', :suitable? => true, :name => "format", :mime => "text/format" Puppet::Network::FormatHandler.stubs(:format).returns @format @@ -383,43 +363,41 @@ describe Puppet::Network::HTTP::Handler do end it "should use the indirection request to find the model" do - @irequest.expects(:model).returns @model_class - - @handler.do_save(@irequest, @request, @response) + @handler.do_save("my_handler", "my_result", {}, @request, @response) end it "should use the 'body' hook to retrieve the body of the request" do @handler.expects(:body).returns "my body" @model_class.expects(:convert_from).with { |format, body| body == "my body" }.returns @model_instance - @handler.do_save(@irequest, @request, @response) + @handler.do_save("my_handler", "my_result", {}, @request, @response) end it "should fail to save model if data is not specified" do @handler.stubs(:body).returns('') - lambda { @handler.do_save(@irequest, @request, @response) }.should raise_error(ArgumentError) + lambda { @handler.do_save("my_handler", "my_result", {}, @request, @response) }.should raise_error(ArgumentError) end it "should use a common method for determining the request parameters" do - @model_instance.expects(:save).with('key').once - @handler.do_save(@irequest, @request, @response) + @indirection.expects(:save).with(@model_instance, 'key').once + @handler.do_save("my_handler", "key", {}, @request, @response) end it "should use the default status when a model save call succeeds" do @handler.expects(:set_response).with { |response, body, status| status.nil? } - @handler.do_save(@irequest, @request, @response) + @handler.do_save("my_handler", "my_result", {}, @request, @response) end it "should return the yaml-serialized result when a model save call succeeds" do - @model_instance.stubs(:save).returns(@model_instance) + @indirection.stubs(:save).returns(@model_instance) @model_instance.expects(:to_yaml).returns('foo') - @handler.do_save(@irequest, @request, @response) + @handler.do_save("my_handler", "my_result", {}, @request, @response) end it "should set the content to yaml" do @handler.expects(:set_content_type).with(@response, @yamlformat) - @handler.do_save(@irequest, @request, @response) + @handler.do_save("my_handler", "my_result", {}, @request, @response) end it "should use the content-type header to know the body format" do @@ -428,7 +406,7 @@ describe Puppet::Network::HTTP::Handler do @model_class.expects(:convert_from).with { |format, body| format == "format" }.returns @model_instance - @handler.do_save(@irequest, @request, @response) + @handler.do_save("my_handler", "my_result", {}, @request, @response) end end end diff --git a/spec/unit/network/http/rack/xmlrpc_spec.rb b/spec/unit/network/http/rack/xmlrpc_spec.rb index 63ba28bf2..870438f2c 100755 --- a/spec/unit/network/http/rack/xmlrpc_spec.rb +++ b/spec/unit/network/http/rack/xmlrpc_spec.rb @@ -1,6 +1,7 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../../../spec_helper' +require 'puppet/network/handler' require 'puppet/network/http/rack' if Puppet.features.rack? require 'puppet/network/http/rack/xmlrpc' if Puppet.features.rack? diff --git a/spec/unit/network/http/rack_spec.rb b/spec/unit/network/http/rack_spec.rb index df42a1ffa..8be9ccb50 100755 --- a/spec/unit/network/http/rack_spec.rb +++ b/spec/unit/network/http/rack_spec.rb @@ -1,6 +1,7 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../../spec_helper' +require 'puppet/network/handler' require 'puppet/network/http/rack' if Puppet.features.rack? describe "Puppet::Network::HTTP::Rack" do diff --git a/spec/unit/network/http/webrick_spec.rb b/spec/unit/network/http/webrick_spec.rb index 2a6ef2268..91a35435a 100755 --- a/spec/unit/network/http/webrick_spec.rb +++ b/spec/unit/network/http/webrick_spec.rb @@ -4,6 +4,7 @@ # Copyright (c) 2007. All rights reserved. require File.dirname(__FILE__) + '/../../../spec_helper' +require 'puppet/network/handler' require 'puppet/network/http' require 'puppet/network/http/webrick' @@ -281,7 +282,7 @@ describe Puppet::Network::HTTP::WEBrick do @cert = stub 'cert', :content => "mycert" @host = stub 'host', :key => @key, :certificate => @cert, :name => "yay", :ssl_store => "mystore" - Puppet::SSL::Certificate.stubs(:find).with('ca').returns @cert + Puppet::SSL::Certificate.indirection.stubs(:find).with('ca').returns @cert Puppet::SSL::Host.stubs(:localhost).returns @host end @@ -298,7 +299,7 @@ describe Puppet::Network::HTTP::WEBrick do end it "should fail if no CA certificate can be found" do - Puppet::SSL::Certificate.stubs(:find).with('ca').returns nil + Puppet::SSL::Certificate.indirection.stubs(:find).with('ca').returns nil lambda { @server.setup_ssl }.should raise_error(Puppet::Error) end diff --git a/spec/unit/network/rest_authconfig_spec.rb b/spec/unit/network/rest_authconfig_spec.rb index 06436e723..10dbb76f6 100755 --- a/spec/unit/network/rest_authconfig_spec.rb +++ b/spec/unit/network/rest_authconfig_spec.rb @@ -29,9 +29,6 @@ describe Puppet::Network::RestAuthConfig do @acl = stub_everything 'rights' @authconfig.rights = @acl - - @request = stub 'request', :indirection_name => "path", :key => "to/resource", :ip => "127.0.0.1", - :node => "me", :method => :save, :environment => :env, :authenticated => true end it "should use the puppet default rest authorization file" do @@ -40,16 +37,10 @@ describe Puppet::Network::RestAuthConfig do Puppet::Network::RestAuthConfig.new(nil, false) end - it "should read the config file when needed" do - @authconfig.expects(:read) - - @authconfig.allowed?(@request) - end - it "should ask for authorization to the ACL subsystem" do @acl.expects(:fail_on_deny).with("/path/to/resource", :node => "me", :ip => "127.0.0.1", :method => :save, :environment => :env, :authenticated => true) - @authconfig.allowed?(@request) + @authconfig.allowed?("path", :save, "to/resource", :ip => "127.0.0.1", :node => "me", :environment => :env, :authenticated => true) end describe "when defining an acl with mk_acl" do diff --git a/spec/unit/network/rest_authorization_spec.rb b/spec/unit/network/rest_authorization_spec.rb deleted file mode 100755 index 0cb0bcee9..000000000 --- a/spec/unit/network/rest_authorization_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env ruby - -require File.dirname(__FILE__) + '/../../spec_helper' - -require 'puppet/network/rest_authorization' - -class RestAuthorized - include Puppet::Network::RestAuthorization -end - - -describe Puppet::Network::RestAuthorization do - before :each do - @auth = RestAuthorized.new - @authconig = stub 'authconfig' - @auth.stubs(:authconfig).returns(@authconfig) - - @request = stub_everything 'request' - @request.stubs(:method).returns(:find) - @request.stubs(:node).returns("node") - @request.stubs(:ip).returns("ip") - end - - describe "when testing request authorization" do - it "should delegate to the current rest authconfig" do - @authconfig.expects(:allowed?).with(@request).returns(true) - - @auth.check_authorization(@request) - end - - it "should raise an AuthorizationError if authconfig raises an AuthorizationError" do - @authconfig.expects(:allowed?).with(@request).raises(Puppet::Network::AuthorizationError.new("forbidden")) - - lambda { @auth.check_authorization(@request) }.should raise_error(Puppet::Network::AuthorizationError) - end - - it "should not raise an AuthorizationError if request is allowed" do - @authconfig.expects(:allowed?).with(@request).returns(true) - - lambda { @auth.check_authorization(@request) }.should_not raise_error(Puppet::Network::AuthorizationError) - end - end -end diff --git a/spec/unit/network/xmlrpc/client_spec.rb b/spec/unit/network/xmlrpc/client_spec.rb index 0b9b2b095..8440d39fa 100755 --- a/spec/unit/network/xmlrpc/client_spec.rb +++ b/spec/unit/network/xmlrpc/client_spec.rb @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +require 'puppet/network/client' Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } diff --git a/spec/unit/node/environment_spec.rb b/spec/unit/node/environment_spec.rb index 6edcce56c..be2980879 100755 --- a/spec/unit/node/environment_spec.rb +++ b/spec/unit/node/environment_spec.rb @@ -52,7 +52,7 @@ describe Puppet::Node::Environment do before do @env = Puppet::Node::Environment.new("dev") @collection = Puppet::Resource::TypeCollection.new(@env) - @collection.stubs(:perform_initial_import) + @env.stubs(:perform_initial_import).returns(Puppet::Parser::AST::Hostclass.new('')) Thread.current[:known_resource_types] = nil end @@ -66,9 +66,8 @@ describe Puppet::Node::Environment do end it "should perform the initial import when creating a new collection" do - @collection.expects(:perform_initial_import) - Puppet::Resource::TypeCollection.expects(:new).returns @collection - + @env = Puppet::Node::Environment.new("dev") + @env.expects(:perform_initial_import).returns(Puppet::Parser::AST::Hostclass.new('')) @env.known_resource_types end @@ -274,4 +273,56 @@ describe Puppet::Node::Environment do @helper.environment.name.should == :foo end end + + describe "when performing initial import" do + before do + @parser = stub 'parser', :file= => nil, :string => nil, :parse => nil + Puppet::Parser::Parser.stubs(:new).returns @parser + @env = Puppet::Node::Environment.new("env") + end + + it "should create a new parser instance" do + Puppet::Parser::Parser.expects(:new).returns @parser + @env.instance_eval { perform_initial_import } + end + + it "should set the parser's string to the 'code' setting and parse if code is available" do + Puppet.settings[:code] = "my code" + @parser.expects(:string=).with "my code" + @parser.expects(:parse) + @env.instance_eval { perform_initial_import } + end + + it "should set the parser's file to the 'manifest' setting and parse if no code is available and the manifest is available" do + File.stubs(:expand_path).with("/my/file").returns "/my/file" + File.expects(:exist?).with("/my/file").returns true + Puppet.settings[:manifest] = "/my/file" + @parser.expects(:file=).with "/my/file" + @parser.expects(:parse) + @env.instance_eval { perform_initial_import } + end + + it "should not attempt to load a manifest if none is present" do + File.stubs(:expand_path).with("/my/file").returns "/my/file" + File.expects(:exist?).with("/my/file").returns false + Puppet.settings[:manifest] = "/my/file" + @parser.expects(:file=).never + @parser.expects(:parse).never + @env.instance_eval { perform_initial_import } + end + + it "should fail helpfully if there is an error importing" do + File.stubs(:exist?).returns true + @parser.expects(:parse).raises ArgumentError + lambda { @env.instance_eval { perform_initial_import } }.should raise_error(Puppet::Error) + end + + it "should not do anything if the ignore_import settings is set" do + Puppet.settings[:ignoreimport] = true + @parser.expects(:string=).never + @parser.expects(:file=).never + @parser.expects(:parse).never + @env.instance_eval { perform_initial_import } + end + end end diff --git a/spec/unit/node/facts_spec.rb b/spec/unit/node/facts_spec.rb index 394db7913..de2cd554f 100755 --- a/spec/unit/node/facts_spec.rb +++ b/spec/unit/node/facts_spec.rb @@ -76,16 +76,10 @@ describe Puppet::Node::Facts, "when indirecting" do @facts = Puppet::Node::Facts.new("me", "one" => "two") end - it "should redirect to the specified fact store for retrieval" do - Puppet::Node::Facts.stubs(:indirection).returns(@indirection) - @indirection.expects(:find) - Puppet::Node::Facts.find(:my_facts) - end - it "should redirect to the specified fact store for storage" do Puppet::Node::Facts.stubs(:indirection).returns(@indirection) @indirection.expects(:save) - @facts.save + Puppet::Node::Facts.indirection.save(@facts) end describe "when the Puppet application is 'master'" do @@ -109,5 +103,29 @@ describe Puppet::Node::Facts, "when indirecting" do facts = Puppet::Node::Facts.new("me", "one" => "two", "three" => "four") facts.values[:_timestamp].should be_instance_of(Time) end + + describe "using pson" do + before :each do + @timestamp = Time.parse("Thu Oct 28 11:16:31 -0700 2010") + @expiration = Time.parse("Thu Oct 28 11:21:31 -0700 2010") + end + + it "should accept properly formatted pson" do + pson = %Q({"name": "foo", "expiration": "#{@expiration}", "timestamp": "#{@timestamp}", "values": {"a": "1", "b": "2", "c": "3"}}) + format = Puppet::Network::FormatHandler.format('pson') + facts = format.intern(Puppet::Node::Facts,pson) + facts.name.should == 'foo' + facts.expiration.should == @expiration + facts.values.should == {'a' => '1', 'b' => '2', 'c' => '3', :_timestamp => @timestamp} + end + + it "should generate properly formatted pson" do + Time.stubs(:now).returns(@timestamp) + facts = Puppet::Node::Facts.new("foo", {'a' => 1, 'b' => 2, 'c' => 3}) + facts.expiration = @expiration + pson = PSON.parse(facts.to_pson) + pson.should == {"name"=>"foo", "timestamp"=>@timestamp.to_s, "expiration"=>@expiration.to_s, "values"=>{"a"=>1, "b"=>2, "c"=>3}} + end + end end end diff --git a/spec/unit/node_spec.rb b/spec/unit/node_spec.rb index 36334ea05..725075cb3 100755 --- a/spec/unit/node_spec.rb +++ b/spec/unit/node_spec.rb @@ -84,11 +84,11 @@ end describe Puppet::Node, "when merging facts" do before do @node = Puppet::Node.new("testnode") - Puppet::Node::Facts.stubs(:find).with(@node.name).returns(Puppet::Node::Facts.new(@node.name, "one" => "c", "two" => "b")) + Puppet::Node::Facts.indirection.stubs(:find).with(@node.name).returns(Puppet::Node::Facts.new(@node.name, "one" => "c", "two" => "b")) end it "should fail intelligently if it cannot find facts" do - Puppet::Node::Facts.expects(:find).with(@node.name).raises "foo" + Puppet::Node::Facts.indirection.expects(:find).with(@node.name).raises "foo" lambda { @node.fact_merge }.should raise_error(Puppet::Error) end @@ -128,13 +128,6 @@ describe Puppet::Node, "when merging facts" do end describe Puppet::Node, "when indirecting" do - it "should redirect to the indirection" do - @indirection = stub 'indirection', :name => :node - Puppet::Node.stubs(:indirection).returns(@indirection) - @indirection.expects(:find) - Puppet::Node.find(:my_node.to_s) - end - it "should default to the 'plain' node terminus" do Puppet::Node.indirection.terminus_class.should == :plain end diff --git a/spec/unit/parser/ast/astarray_spec.rb b/spec/unit/parser/ast/astarray_spec.rb index f79d6c533..8794848b6 100755 --- a/spec/unit/parser/ast/astarray_spec.rb +++ b/spec/unit/parser/ast/astarray_spec.rb @@ -23,43 +23,26 @@ describe Puppet::Parser::AST::ASTArray do operator.evaluate(@scope) end - it "should evaluate childrens of type ASTArray" do - item1 = stub "item1", :is_a? => true - item2 = stub "item2" - item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true) - item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true) - item2.stubs(:each).yields(item1) - - item1.expects(:safeevaluate).with(@scope).returns(123) - - operator = Puppet::Parser::AST::ASTArray.new :children => [item2] - operator.evaluate(@scope).should == [123] - end - - it "should flatten children coming from children ASTArray" do - item1 = stub "item1", :is_a? => true - item2 = stub "item2" - item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true) - item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true) - item2.stubs(:each).yields([item1]) - - item1.expects(:safeevaluate).with(@scope).returns(123) - - operator = Puppet::Parser::AST::ASTArray.new :children => [item2] - operator.evaluate(@scope).should == [123] + it "should not flatten children coming from children ASTArray" do + item = Puppet::Parser::AST::String.new :value => 'foo' + inner_array = Puppet::Parser::AST::ASTArray.new :children => [item, item] + operator = Puppet::Parser::AST::ASTArray.new :children => [inner_array, inner_array] + operator.evaluate(@scope).should == [['foo', 'foo'], ['foo', 'foo']] end it "should not flatten the results of children evaluation" do - item1 = stub "item1", :is_a? => true - item2 = stub "item2" - item2.stubs(:is_a?).with(Puppet::Parser::AST).returns(true) - item2.stubs(:instance_of?).with(Puppet::Parser::AST::ASTArray).returns(true) - item2.stubs(:each).yields([item1]) - - item1.expects(:safeevaluate).with(@scope).returns([123]) + item = Puppet::Parser::AST::String.new :value => 'foo' + item.stubs(:evaluate).returns(['foo']) + operator = Puppet::Parser::AST::ASTArray.new :children => [item, item] + operator.evaluate(@scope).should == [['foo'], ['foo']] + end - operator = Puppet::Parser::AST::ASTArray.new :children => [item2] - operator.evaluate(@scope).should == [[123]] + it "should discard nil results from children evaluation" do + item1 = Puppet::Parser::AST::String.new :value => 'foo' + item2 = Puppet::Parser::AST::String.new :value => 'foo' + item2.stubs(:evaluate).returns(nil) + operator = Puppet::Parser::AST::ASTArray.new :children => [item1, item2] + operator.evaluate(@scope).should == ['foo'] end it "should return a valid string with to_s" do diff --git a/spec/unit/parser/ast/definition_spec.rb b/spec/unit/parser/ast/definition_spec.rb new file mode 100644 index 000000000..b7b2c851c --- /dev/null +++ b/spec/unit/parser/ast/definition_spec.rb @@ -0,0 +1,22 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +describe Puppet::Parser::AST::Definition do + it "should make its context available through an accessor" do + definition = Puppet::Parser::AST::Definition.new('foo', :line => 5) + definition.context.should == {:line => 5} + end + + describe "when instantiated" do + it "should create a definition with the proper type, name, context, and module name" do + definition = Puppet::Parser::AST::Definition.new('foo', :line => 5) + instantiated_definitions = definition.instantiate('modname') + instantiated_definitions.length.should == 1 + instantiated_definitions[0].type.should == :definition + instantiated_definitions[0].name.should == 'foo' + instantiated_definitions[0].line.should == 5 + instantiated_definitions[0].module_name.should == 'modname' + end + end +end diff --git a/spec/unit/parser/ast/hostclass_spec.rb b/spec/unit/parser/ast/hostclass_spec.rb new file mode 100644 index 000000000..b22eba98b --- /dev/null +++ b/spec/unit/parser/ast/hostclass_spec.rb @@ -0,0 +1,73 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +describe Puppet::Parser::AST::Hostclass do + def ast + Puppet::Parser::AST + end + + def newarray(*elems) + ast::ASTArray.new({}).push(*elems) + end + + it "should make its name and context available through accessors" do + hostclass = ast::Hostclass.new('foo', :line => 5) + hostclass.name.should == 'foo' + hostclass.context.should == {:line => 5} + end + + it "should make its code available through an accessor" do + code = newarray + hostclass = ast::Hostclass.new('foo', :code => code) + hostclass.code.should be_equal(code) + end + + describe "when instantiated" do + it "should create a class with the proper type, code, name, context, and module name" do + code = newarray + hostclass = ast::Hostclass.new('foo', :code => code, :line => 5) + instantiated_class = hostclass.instantiate('modname')[0] + instantiated_class.type.should == :hostclass + instantiated_class.name.should == 'foo' + instantiated_class.code.should be_equal(code) + instantiated_class.line.should == 5 + instantiated_class.module_name.should == 'modname' + end + + it "should instantiate all nested classes, defines, and nodes with the same module name." do + nested_objects = newarray(ast::Hostclass.new('foo::child1'), + ast::Definition.new('foo::child2'), + ast::Definition.new('child3')) + hostclass = ast::Hostclass.new('foo', :code => nested_objects) + instantiated_classes = hostclass.instantiate('modname') + instantiated_classes.length.should == 4 + instantiated_classes[0].name.should == 'foo' + instantiated_classes[1].name.should == 'foo::child1' + instantiated_classes[2].name.should == 'foo::child2' + instantiated_classes[3].name.should == 'child3' + instantiated_classes.each { |cls| cls.module_name.should == 'modname' } + end + + it "should handle a nested class that contains its own nested classes." do + foo_bar_baz = ast::Hostclass.new('foo::bar::baz') + foo_bar = ast::Hostclass.new('foo::bar', :code => newarray(foo_bar_baz)) + foo = ast::Hostclass.new('foo', :code => newarray(foo_bar)) + instantiated_classes = foo.instantiate('') + instantiated_classes.length.should == 3 + instantiated_classes[0].name.should == 'foo' + instantiated_classes[1].name.should == 'foo::bar' + instantiated_classes[2].name.should == 'foo::bar::baz' + end + + it "should skip nested elements that are not classes, definitions, or nodes." do + func = ast::Function.new(:name => 'biz', :arguments => newarray(ast::Name.new(:value => 'baz'))) + foo = ast::Hostclass.new('foo', :code => newarray(func)) + instantiated_classes = foo.instantiate('') + instantiated_classes.length.should == 1 + instantiated_classes[0].should be_a(Puppet::Resource::Type) + instantiated_classes[0].name.should == 'foo' + end + end +end + diff --git a/spec/unit/parser/ast/node_spec.rb b/spec/unit/parser/ast/node_spec.rb new file mode 100644 index 000000000..3e8017de0 --- /dev/null +++ b/spec/unit/parser/ast/node_spec.rb @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +describe Puppet::Parser::AST::Node do + describe "when instantiated" do + it "should make its names and context available through accessors" do + node = Puppet::Parser::AST::Node.new(['foo', 'bar'], :line => 5) + node.names.should == ['foo', 'bar'] + node.context.should == {:line => 5} + end + + it "should create a node with the proper type, name, context, and module name" do + node = Puppet::Parser::AST::Node.new(['foo'], :line => 5) + instantiated_nodes = node.instantiate('modname') + instantiated_nodes.length.should == 1 + instantiated_nodes[0].type.should == :node + instantiated_nodes[0].name.should == 'foo' + instantiated_nodes[0].line.should == 5 + instantiated_nodes[0].module_name.should == 'modname' + end + + it "should handle multiple names" do + node = Puppet::Parser::AST::Node.new(['foo', 'bar']) + instantiated_nodes = node.instantiate('modname') + instantiated_nodes.length.should == 2 + instantiated_nodes[0].name.should == 'foo' + instantiated_nodes[1].name.should == 'bar' + end + end +end diff --git a/spec/unit/parser/ast/resource_spec.rb b/spec/unit/parser/ast/resource_spec.rb index 721c31a8d..3f7fa229a 100755 --- a/spec/unit/parser/ast/resource_spec.rb +++ b/spec/unit/parser/ast/resource_spec.rb @@ -11,14 +11,15 @@ describe Puppet::Parser::AST::Resource do @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode")) @scope = Puppet::Parser::Scope.new(:compiler => @compiler) @scope.stubs(:resource).returns(stub_everything) - @resource = ast::Resource.new(:title => @title, :type => "file", :parameters => ast::ASTArray.new(:children => []) ) + @instance = ast::ResourceInstance.new(:title => @title, :parameters => ast::ASTArray.new(:children => [])) + @resource = ast::Resource.new(:type => "file", :instances => ast::ASTArray.new(:children => [@instance])) @resource.stubs(:qualified_type).returns("Resource") end it "should evaluate all its parameters" do param = stub 'param' param.expects(:safeevaluate).with(@scope).returns Puppet::Parser::Resource::Param.new(:name => "myparam", :value => "myvalue", :source => stub("source")) - @resource.stubs(:parameters).returns [param] + @instance.stubs(:parameters).returns [param] @resource.evaluate(@scope) end @@ -35,7 +36,7 @@ describe Puppet::Parser::AST::Resource do array = Puppet::Parser::AST::ASTArray.new(:children => titles) - @resource.title = array + @instance.title = array result = @resource.evaluate(@scope).collect { |r| r.title } result.should be_include("one") result.should be_include("two") @@ -49,12 +50,19 @@ describe Puppet::Parser::AST::Resource do array = Puppet::Parser::AST::ASTArray.new(:children => titles) - @resource.title = array + @instance.title = array result = @resource.evaluate(@scope).collect { |r| r.title } result.should be_include("one") result.should be_include("two") end + it "should implicitly iterate over instances" do + new_title = Puppet::Parser::AST::String.new(:value => "other_title") + new_instance = ast::ResourceInstance.new(:title => new_title, :parameters => ast::ASTArray.new(:children => [])) + @resource.instances.push(new_instance) + @resource.evaluate(@scope).collect { |r| r.title }.should == ["mytitle", "other_title"] + end + it "should handover resources to the compiler" do titles = [] %w{one two}.each do |title| @@ -63,7 +71,7 @@ describe Puppet::Parser::AST::Resource do array = Puppet::Parser::AST::ASTArray.new(:children => titles) - @resource.title = array + @instance.title = array result = @resource.evaluate(@scope) result.each do |res| @@ -91,16 +99,19 @@ describe Puppet::Parser::AST::Resource do before do @scope = Puppet::Parser::Scope.new :compiler => Puppet::Parser::Compiler.new(Puppet::Node.new("mynode")) @parser = Puppet::Parser::Parser.new(Puppet::Node::Environment.new) - @parser.newdefine "one" - @parser.newdefine "one::two" - @parser.newdefine "three" + ["one", "one::two", "three"].each do |name| + @parser.environment.known_resource_types.add(Puppet::Resource::Type.new(:definition, name, {})) + end @twoscope = @scope.newscope(:namespace => "one") @twoscope.resource = @scope.resource end def resource(type, params = nil) params ||= Puppet::Parser::AST::ASTArray.new(:children => []) - Puppet::Parser::AST::Resource.new(:type => type, :title => Puppet::Parser::AST::String.new(:value => "myresource"), :parameters => params) + instance = Puppet::Parser::AST::ResourceInstance.new( + :title => Puppet::Parser::AST::String.new(:value => "myresource"), :parameters => params) + Puppet::Parser::AST::Resource.new(:type => type, + :instances => Puppet::Parser::AST::ASTArray.new(:children => [instance])) end it "should be able to generate resources with fully qualified type information" do @@ -141,7 +152,8 @@ describe Puppet::Parser::AST::Resource do @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("mynode")) @scope = Puppet::Parser::Scope.new(:compiler => @compiler) @scope.stubs(:resource).returns(stub_everything) - @resource = ast::Resource.new(:title => @title, :type => "Class", :parameters => ast::ASTArray.new(:children => []) ) + @instance = ast::ResourceInstance.new(:title => @title, :parameters => ast::ASTArray.new(:children => [])) + @resource = ast::Resource.new(:type => "Class", :instances => ast::ASTArray.new(:children => [@instance])) @resource.stubs(:qualified_type).returns("Resource") @type = Puppet::Resource::Type.new(:hostclass, "classname") @compiler.known_resource_types.add(@type) diff --git a/spec/unit/parser/collector_spec.rb b/spec/unit/parser/collector_spec.rb index 15808d6ff..908cda63a 100755 --- a/spec/unit/parser/collector_spec.rb +++ b/spec/unit/parser/collector_spec.rb @@ -2,6 +2,7 @@ require File.dirname(__FILE__) + '/../../spec_helper' +require 'puppet/rails' require 'puppet/parser/collector' describe Puppet::Parser::Collector, "when initializing" do diff --git a/spec/unit/parser/parser_spec.rb b/spec/unit/parser/parser_spec.rb index 07e2d220b..ab43194e9 100755 --- a/spec/unit/parser/parser_spec.rb +++ b/spec/unit/parser/parser_spec.rb @@ -4,7 +4,7 @@ require File.dirname(__FILE__) + '/../../spec_helper' describe Puppet::Parser do - ast = Puppet::Parser::AST + Puppet::Parser::AST before :each do @known_resource_types = Puppet::Resource::TypeCollection.new("development") @@ -64,35 +64,37 @@ describe Puppet::Parser do lambda { @parser.parse("$var += ") }.should raise_error end - it "should call ast::VarDef with append=true" do - ast::VarDef.expects(:new).with { |h| h[:append] == true } - @parser.parse("$var += 2") + it "should create ast::VarDef with append=true" do + vardef = @parser.parse("$var += 2").code[0] + vardef.should be_a(Puppet::Parser::AST::VarDef) + vardef.append.should == true end it "should work with arrays too" do - ast::VarDef.expects(:new).with { |h| h[:append] == true } - @parser.parse("$var += ['test']") + vardef = @parser.parse("$var += ['test']").code[0] + vardef.should be_a(Puppet::Parser::AST::VarDef) + vardef.append.should == true end end describe "when parsing 'if'" do it "not, it should create the correct ast objects" do - ast::Not.expects(:new).with { |h| h[:value].is_a?(ast::Boolean) } + Puppet::Parser::AST::Not.expects(:new).with { |h| h[:value].is_a?(Puppet::Parser::AST::Boolean) } @parser.parse("if ! true { $var = 1 }") end it "boolean operation, it should create the correct ast objects" do - ast::BooleanOperator.expects(:new).with { - |h| h[:rval].is_a?(ast::Boolean) and h[:lval].is_a?(ast::Boolean) and h[:operator]=="or" + Puppet::Parser::AST::BooleanOperator.expects(:new).with { + |h| h[:rval].is_a?(Puppet::Parser::AST::Boolean) and h[:lval].is_a?(Puppet::Parser::AST::Boolean) and h[:operator]=="or" } @parser.parse("if true or true { $var = 1 }") end it "comparison operation, it should create the correct ast objects" do - ast::ComparisonOperator.expects(:new).with { - |h| h[:lval].is_a?(ast::Name) and h[:rval].is_a?(ast::Name) and h[:operator]=="<" + Puppet::Parser::AST::ComparisonOperator.expects(:new).with { + |h| h[:lval].is_a?(Puppet::Parser::AST::Name) and h[:rval].is_a?(Puppet::Parser::AST::Name) and h[:operator]=="<" } @parser.parse("if 1 < 2 { $var = 1 }") @@ -103,13 +105,13 @@ describe Puppet::Parser do describe "when parsing if complex expressions" do it "should create a correct ast tree" do aststub = stub_everything 'ast' - ast::ComparisonOperator.expects(:new).with { - |h| h[:rval].is_a?(ast::Name) and h[:lval].is_a?(ast::Name) and h[:operator]==">" + Puppet::Parser::AST::ComparisonOperator.expects(:new).with { + |h| h[:rval].is_a?(Puppet::Parser::AST::Name) and h[:lval].is_a?(Puppet::Parser::AST::Name) and h[:operator]==">" }.returns(aststub) - ast::ComparisonOperator.expects(:new).with { - |h| h[:rval].is_a?(ast::Name) and h[:lval].is_a?(ast::Name) and h[:operator]=="==" + Puppet::Parser::AST::ComparisonOperator.expects(:new).with { + |h| h[:rval].is_a?(Puppet::Parser::AST::Name) and h[:lval].is_a?(Puppet::Parser::AST::Name) and h[:operator]=="==" }.returns(aststub) - ast::BooleanOperator.expects(:new).with { + Puppet::Parser::AST::BooleanOperator.expects(:new).with { |h| h[:rval]==aststub and h[:lval]==aststub and h[:operator]=="and" } @parser.parse("if (1 > 2) and (1 == 2) { $var = 1 }") @@ -132,9 +134,8 @@ describe Puppet::Parser do end it "should create an ast::ResourceReference" do - ast::Resource.stubs(:new) - ast::ResourceReference.expects(:new).with { |arg| - arg[:line]==1 and arg[:type]=="File" and arg[:title].is_a?(ast::ASTArray) + Puppet::Parser::AST::ResourceReference.expects(:new).with { |arg| + arg[:line]==1 and arg[:type]=="File" and arg[:title].is_a?(Puppet::Parser::AST::ASTArray) } @parser.parse('exec { test: command => File["a","b"] }') end @@ -151,10 +152,14 @@ describe Puppet::Parser do end it "should create an ast::ResourceOverride" do - ast::ResourceOverride.expects(:new).with { |arg| - arg[:line]==1 and arg[:object].is_a?(ast::ResourceReference) and arg[:parameters].is_a?(ast::ResourceParam) - } - @parser.parse('Resource["title1","title2"] { param => value }') + #Puppet::Parser::AST::ResourceOverride.expects(:new).with { |arg| + # arg[:line]==1 and arg[:object].is_a?(Puppet::Parser::AST::ResourceReference) and arg[:parameters].is_a?(Puppet::Parser::AST::ResourceParam) + #} + ro = @parser.parse('Resource["title1","title2"] { param => value }').code[0] + ro.should be_a(Puppet::Parser::AST::ResourceOverride) + ro.line.should == 1 + ro.object.should be_a(Puppet::Parser::AST::ResourceReference) + ro.parameters[0].should be_a(Puppet::Parser::AST::ResourceParam) end end @@ -174,17 +179,17 @@ describe Puppet::Parser do end it "should create a nop node for empty branch" do - ast::Nop.expects(:new) + Puppet::Parser::AST::Nop.expects(:new) @parser.parse("if true { }") end it "should create a nop node for empty else branch" do - ast::Nop.expects(:new) + Puppet::Parser::AST::Nop.expects(:new) @parser.parse("if true { notice('test') } else { }") end it "should build a chain of 'ifs' if there's an 'elsif'" do - ast = @parser.parse(<<-PP) + lambda { @parser.parse(<<-PP) }.should_not raise_error if true { notice('test') } elsif true {} else { } PP end @@ -288,24 +293,6 @@ describe Puppet::Parser do end end - describe "when creating a node" do - before :each do - @lexer = stub 'lexer' - @lexer.stubs(:getcomment) - @parser.stubs(:lexer).returns(@lexer) - @node = stub_everything 'node' - @parser.stubs(:ast_context).returns({}) - @parser.stubs(:node).returns(nil) - - @nodename = stub 'nodename', :is_a? => false, :value => "foo" - @nodename.stubs(:is_a?).with(Puppet::Parser::AST::HostName).returns(true) - end - - it "should return an array of nodes" do - @parser.newnode(@nodename).should be_instance_of(Array) - end - end - describe "when retrieving a specific node" do it "should delegate to the known_resource_types node" do @known_resource_types.expects(:node).with("node") @@ -358,30 +345,28 @@ describe Puppet::Parser do @parser.stubs(:known_resource_types).returns @krt end - it "should create new classes" do - @parser.parse("class foobar {}") - @krt.hostclass("foobar").should be_instance_of(Puppet::Resource::Type) + it "should not create new classes" do + @parser.parse("class foobar {}").code[0].should be_a(Puppet::Parser::AST::Hostclass) + @krt.hostclass("foobar").should be_nil end it "should correctly set the parent class when one is provided" do - @parser.parse("class foobar inherits yayness {}") - @krt.hostclass("foobar").parent.should == "yayness" + @parser.parse("class foobar inherits yayness {}").code[0].instantiate('')[0].parent.should == "yayness" end it "should correctly set the parent class for multiple classes at a time" do - @parser.parse("class foobar inherits yayness {}\nclass boo inherits bar {}") - @krt.hostclass("foobar").parent.should == "yayness" - @krt.hostclass("boo").parent.should == "bar" + statements = @parser.parse("class foobar inherits yayness {}\nclass boo inherits bar {}").code + statements[0].instantiate('')[0].parent.should == "yayness" + statements[1].instantiate('')[0].parent.should == "bar" end it "should define the code when some is provided" do - @parser.parse("class foobar { $var = val }") - @krt.hostclass("foobar").code.should_not be_nil + @parser.parse("class foobar { $var = val }").code[0].code.should_not be_nil end it "should define parameters when provided" do - @parser.parse("class foobar($biz,$baz) {}") - @krt.hostclass("foobar").arguments.should == {"biz" => nil, "baz" => nil} + foobar = @parser.parse("class foobar($biz,$baz) {}").code[0].instantiate('')[0] + foobar.arguments.should == {"biz" => nil, "baz" => nil} end end @@ -398,13 +383,37 @@ describe Puppet::Parser do end it "should correctly mark exported resources as exported" do - @parser.parse("@@file { '/file': }") - @krt.hostclass("").code[0].exported.should be_true + @parser.parse("@@file { '/file': }").code[0].exported.should be_true end it "should correctly mark virtual resources as virtual" do - @parser.parse("@file { '/file': }") - @krt.hostclass("").code[0].virtual.should be_true + @parser.parse("@file { '/file': }").code[0].virtual.should be_true + end + end + + describe "when parsing nodes" do + it "should be able to parse a node with a single name" do + node = @parser.parse("node foo { }").code[0] + node.should be_a Puppet::Parser::AST::Node + node.names.length.should == 1 + node.names[0].value.should == "foo" + end + + it "should be able to parse a node with two names" do + node = @parser.parse("node foo, bar { }").code[0] + node.should be_a Puppet::Parser::AST::Node + node.names.length.should == 2 + node.names[0].value.should == "foo" + node.names[1].value.should == "bar" + end + + it "should be able to parse a node with three names" do + node = @parser.parse("node foo, bar, baz { }").code[0] + node.should be_a Puppet::Parser::AST::Node + node.names.length.should == 3 + node.names[0].value.should == "foo" + node.names[1].value.should == "bar" + node.names[2].value.should == "baz" end end end diff --git a/spec/unit/parser/scope_spec.rb b/spec/unit/parser/scope_spec.rb index 9895f446b..2e390a53b 100755 --- a/spec/unit/parser/scope_spec.rb +++ b/spec/unit/parser/scope_spec.rb @@ -29,8 +29,7 @@ describe Puppet::Parser::Scope do end it "should be able to retrieve its parent module name from the source of its parent type" do - @topscope.source = Puppet::Resource::Type.new(:hostclass, :foo) - @topscope.source.module_name = "foo" + @topscope.source = Puppet::Resource::Type.new(:hostclass, :foo, :module_name => "foo") @scope.parent_module_name.should == "foo" end diff --git a/spec/unit/parser/templatewrapper_spec.rb b/spec/unit/parser/templatewrapper_spec.rb index d4d1d1b8e..68d90a1cc 100755 --- a/spec/unit/parser/templatewrapper_spec.rb +++ b/spec/unit/parser/templatewrapper_spec.rb @@ -1,6 +1,7 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../spec_helper' +require 'puppet/parser/templatewrapper' describe Puppet::Parser::TemplateWrapper do before(:each) do diff --git a/spec/unit/parser/type_loader_spec.rb b/spec/unit/parser/type_loader_spec.rb index 02d543b02..cfa68871d 100644 --- a/spec/unit/parser/type_loader_spec.rb +++ b/spec/unit/parser/type_loader_spec.rb @@ -28,85 +28,20 @@ describe Puppet::Parser::TypeLoader do describe "when loading names from namespaces" do it "should do nothing if the name to import is an empty string" do @loader.expects(:name2files).never - @loader.load_until(["foo"], "") { |f| false }.should be_nil - end - - it "should turn the provided namespaces and name into a list of files" do - @loader.expects(:name2files).with(["foo"], "bar").returns [] - @loader.load_until(["foo"], "bar") { |f| false } + @loader.try_load_fqname(:hostclass, "") { |filename, modname| raise :should_not_occur }.should be_nil end it "should attempt to import each generated name" do - @loader.expects(:name2files).returns %w{foo bar} - @loader.expects(:import).with("foo",nil) - @loader.expects(:import).with("bar",nil) - @loader.load_until(["foo"], "bar") { |f| false } - end - - it "should yield after each import" do - yielded = [] - @loader.expects(:name2files).returns %w{foo bar} - @loader.expects(:import).with("foo",nil) - @loader.expects(:import).with("bar",nil) - @loader.load_until(["foo"], "bar") { |f| yielded << f; false } - yielded.should == %w{foo bar} - end - - it "should stop importing when the yielded block returns true" do - yielded = [] - @loader.expects(:name2files).returns %w{foo bar baz} - @loader.expects(:import).with("foo",nil) - @loader.expects(:import).with("bar",nil) - @loader.expects(:import).with("baz",nil).never - @loader.load_until(["foo"], "bar") { |f| true if f == "bar" } - end - - it "should return the result of the block" do - yielded = [] - @loader.expects(:name2files).returns %w{foo bar baz} - @loader.expects(:import).with("foo",nil) - @loader.expects(:import).with("bar",nil) - @loader.expects(:import).with("baz",nil).never - @loader.load_until(["foo"], "bar") { |f| 10 if f == "bar" }.should == 10 - end - - it "should return nil if the block never returns true" do - @loader.expects(:name2files).returns %w{foo bar} - @loader.expects(:import).with("foo",nil) - @loader.expects(:import).with("bar",nil) - @loader.load_until(["foo"], "bar") { |f| false }.should be_nil - end - - it "should set the module name on any created resource types" do - type = Puppet::Resource::Type.new(:hostclass, "mytype") - - Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{one}] - @loader.stubs(:parse_file) - @loader.load_until(["foo"], "one") { |f| type } - - type.module_name.should == "modname" - end - end - - describe "when mapping names to files" do - { - [["foo"], "::bar::baz"] => %w{bar/baz}, - [[""], "foo::bar"] => %w{foo foo/bar}, - [%w{foo}, "bar"] => %w{foo foo/bar bar}, - [%w{a b}, "bar"] => %w{a a/bar b b/bar bar}, - [%w{a::b::c}, "bar"] => %w{a a/b/c/bar bar}, - [%w{a::b}, "foo::bar"] => %w{a a/b/foo/bar foo/bar} - }.each do |inputs, outputs| - it "should produce #{outputs.inspect} from the #{inputs[0].inspect} namespace and #{inputs[1]} name" do - @loader.name2files(*inputs).should == outputs - end + @loader.expects(:import).with("foo/bar",nil).returns([]) + @loader.expects(:import).with("foo",nil).returns([]) + @loader.try_load_fqname(:hostclass, "foo::bar") { |f| false } end end describe "when importing" do before do Puppet::Parser::Files.stubs(:find_manifests).returns ["modname", %w{file}] - Puppet::Parser::Parser.any_instance.stubs(:parse) + Puppet::Parser::Parser.any_instance.stubs(:parse).returns(Puppet::Parser::AST::Hostclass.new('')) Puppet::Parser::Parser.any_instance.stubs(:file=) end @@ -138,19 +73,19 @@ describe Puppet::Parser::TypeLoader do it "should parse each found file" do Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}] - @loader.expects(:parse_file).with("/one") + @loader.expects(:parse_file).with("/one").returns(Puppet::Parser::AST::Hostclass.new('')) @loader.import("myfile") end it "should make each file qualified before attempting to parse it" do Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{one}] - @loader.expects(:parse_file).with("/current/one") + @loader.expects(:parse_file).with("/current/one").returns(Puppet::Parser::AST::Hostclass.new('')) @loader.import("myfile", "/current/file") end it "should not attempt to import files that have already been imported" do Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}] - Puppet::Parser::Parser.any_instance.expects(:parse).once + Puppet::Parser::Parser.any_instance.expects(:parse).once.returns(Puppet::Parser::AST::Hostclass.new('')) @loader.import("myfile") # This will fail if it tries to reimport the file. @@ -161,7 +96,7 @@ describe Puppet::Parser::TypeLoader do describe "when parsing a file" do before do @parser = Puppet::Parser::Parser.new(@loader.environment) - @parser.stubs(:parse) + @parser.stubs(:parse).returns(Puppet::Parser::AST::Hostclass.new('')) @parser.stubs(:file=) Puppet::Parser::Parser.stubs(:new).with(@loader.environment).returns @parser end @@ -173,7 +108,7 @@ describe Puppet::Parser::TypeLoader do it "should assign the parser its file and parse" do @parser.expects(:file=).with("/my/file") - @parser.expects(:parse) + @parser.expects(:parse).returns(Puppet::Parser::AST::Hostclass.new('')) @loader.parse_file("/my/file") end end @@ -185,4 +120,15 @@ describe Puppet::Parser::TypeLoader do @loader.known_resource_types.hostclass("foo").should be_instance_of(Puppet::Resource::Type) end + + describe "when deciding where to look for files" do + { 'foo' => ['foo'], + 'foo::bar' => ['foo/bar', 'foo'], + 'foo::bar::baz' => ['foo/bar/baz', 'foo/bar', 'foo'] + }.each do |fqname, expected_paths| + it "should look for #{fqname.inspect} in #{expected_paths.inspect}" do + @loader.instance_eval { name2files(fqname) }.should == expected_paths + end + end + end end diff --git a/spec/unit/provider/augeas/augeas_spec.rb b/spec/unit/provider/augeas/augeas_spec.rb index 07b632083..0cedbdbc3 100644 --- a/spec/unit/provider/augeas/augeas_spec.rb +++ b/spec/unit/provider/augeas/augeas_spec.rb @@ -316,6 +316,30 @@ describe provider_class do provider.stubs(:get_augeas_version).returns("0.3.5") provider.need_to_run?.should == false end + + #Ticket 5211 testing + it "should return true when a size != the provided value" do + resource = stub("resource") + resource.stubs(:[]).returns(false).then.returns("match path size != 17").then.returns("") + provider = provider_class.new(resource) + augeas_stub = stub("augeas", :match => ["set", "of", "values"]) + augeas_stub.stubs("close") + provider.aug= augeas_stub + provider.stubs(:get_augeas_version).returns("0.3.5") + provider.need_to_run?.should == true + end + + #Ticket 5211 testing + it "should return false when a size doeas equal the provided value" do + resource = stub("resource") + resource.stubs(:[]).returns(false).then.returns("match path size != 3").then.returns("") + provider = provider_class.new(resource) + augeas_stub = stub("augeas", :match => ["set", "of", "values"]) + augeas_stub.stubs("close") + provider.aug= augeas_stub + provider.stubs(:get_augeas_version).returns("0.3.5") + provider.need_to_run?.should == false + end end describe "augeas execution integration" do diff --git a/spec/unit/provider/host/parsed_spec.rb b/spec/unit/provider/host/parsed_spec.rb new file mode 100644 index 000000000..239e3bd86 --- /dev/null +++ b/spec/unit/provider/host/parsed_spec.rb @@ -0,0 +1,196 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +require 'puppet_spec/files' +require 'puppettest/support/utils' +require 'puppettest/fileparsing' + +provider_class = Puppet::Type.type(:host).provider(:parsed) + +describe provider_class do + include PuppetSpec::Files + extend PuppetTest::Support::Utils + include PuppetTest::FileParsing + + before do + @host_class = Puppet::Type.type(:host) + @provider = @host_class.provider(:parsed) + @hostfile = tmpfile('hosts') + @provider.any_instance.stubs(:target).returns @hostfile + end + + after :each do + @provider.initvars + end + + def mkhost(args) + hostresource = Puppet::Type::Host.new(:name => args[:name]) + hostresource.stubs(:should).with(:target).returns @hostfile + + # Using setters of provider + host = @provider.new(hostresource) + args.each do |property,value| + host.send("#{property}=", value) + end + host + end + + def genhost(host) + @provider.stubs(:filetype).returns(Puppet::Util::FileType::FileTypeRam) + File.stubs(:chown) + File.stubs(:chmod) + Puppet::Util::SUIDManager.stubs(:asuser).yields + host.flush + @provider.target_object(@hostfile).read + end + + describe "when parsing a line with ip and hostname" do + + it "should parse an ipv4 from the first field" do + @provider.parse_line("127.0.0.1 localhost")[:ip].should == "127.0.0.1" + end + + it "should parse an ipv6 from the first field" do + @provider.parse_line("::1 localhost")[:ip].should == "::1" + end + + it "should parse the name from the second field" do + @provider.parse_line("::1 localhost")[:name].should == "localhost" + end + + it "should set an empty comment" do + @provider.parse_line("::1 localhost")[:comment].should == "" + end + + end + + describe "when parsing a line with ip, hostname and comment" do + before do + @testline = "127.0.0.1 localhost # A comment with a #-char" + end + + it "should parse the ip from the first field" do + @provider.parse_line(@testline)[:ip].should == "127.0.0.1" + end + + it "should parse the hostname from the second field" do + @provider.parse_line(@testline)[:name].should == "localhost" + end + + it "should parse the comment after the first '#' character" do + @provider.parse_line(@testline)[:comment].should == 'A comment with a #-char' + end + + end + + describe "when parsing a line with ip, hostname and aliases" do + + it "should parse alias from the third field" do + @provider.parse_line("127.0.0.1 localhost localhost.localdomain")[:host_aliases].should == ["localhost.localdomain"] + end + + it "should parse multiple aliases" do + @provider.parse_line("127.0.0.1 host alias1 alias2")[:host_aliases].should == ['alias1', 'alias2'] + @provider.parse_line("127.0.0.1 host alias1\talias2")[:host_aliases].should == ['alias1', 'alias2'] + @provider.parse_line("127.0.0.1 host alias1\talias2 alias3")[:host_aliases].should == ['alias1', 'alias2', 'alias3'] + end + + end + + describe "when parsing a line with ip, hostname, aliases and comment" do + + before do + # Just playing with a few different delimiters + @testline = "127.0.0.1\t host alias1\talias2 alias3 # A comment with a #-char" + end + + it "should parse the ip from the first field" do + @provider.parse_line(@testline)[:ip].should == "127.0.0.1" + end + + it "should parse the hostname from the second field" do + @provider.parse_line(@testline)[:name].should == "host" + end + + it "should parse all host_aliases from the third field" do + @provider.parse_line(@testline)[:host_aliases].should == ['alias1' ,'alias2', 'alias3'] + end + + it "should parse the comment after the first '#' character" do + @provider.parse_line(@testline)[:comment].should == 'A comment with a #-char' + end + + end + + describe "when operating on /etc/hosts like files" do + fakedata("data/providers/host/parsed","valid*").each do |file| + it "should be able to parse #{file}" do + fakedataparse(file) + end + end + + it "should be able to generate a simple hostfile entry" do + host = mkhost( + :name => 'localhost', + :ip => '127.0.0.1', + :ensure => :present + ) + genhost(host).should == "127.0.0.1\tlocalhost\n" + end + + it "should be able to generate an entry with one alias" do + host = mkhost( + :name => 'localhost.localdomain', + :ip => '127.0.0.1', + :host_aliases => ['localhost'], + :ensure => :present + ) + genhost(host).should == "127.0.0.1\tlocalhost.localdomain\tlocalhost\n" + end + + it "should be able to generate an entry with more than one alias" do + host = mkhost( + :name => 'host', + :ip => '192.0.0.1', + :host_aliases => [ 'a1','a2','a3','a4' ], + :ensure => :present + ) + genhost(host).should == "192.0.0.1\thost\ta1\ta2\ta3\ta4\n" + end + + it "should be able to generate a simple hostfile entry with comments" do + host = mkhost( + :name => 'localhost', + :ip => '127.0.0.1', + :comment => 'Bazinga!', + :ensure => :present + ) + genhost(host).should == "127.0.0.1\tlocalhost\t# Bazinga!\n" + end + + it "should be able to generate an entry with one alias and a comment" do + host = mkhost( + :name => 'localhost.localdomain', + :ip => '127.0.0.1', + :host_aliases => ['localhost'], + :comment => 'Bazinga!', + :ensure => :present + ) + genhost(host).should == "127.0.0.1\tlocalhost.localdomain\tlocalhost\t# Bazinga!\n" + end + + it "should be able to generate an entry with more than one alias and a comment" do + host = mkhost( + :name => 'host', + :ip => '192.0.0.1', + :host_aliases => [ 'a1','a2','a3','a4' ], + :comment => 'Bazinga!', + :ensure => :present + ) + genhost(host).should == "192.0.0.1\thost\ta1\ta2\ta3\ta4\t# Bazinga!\n" + end + + end + +end diff --git a/spec/unit/provider/package/yum_spec.rb b/spec/unit/provider/package/yum_spec.rb new file mode 100644 index 000000000..f6a99aa78 --- /dev/null +++ b/spec/unit/provider/package/yum_spec.rb @@ -0,0 +1,67 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +provider = Puppet::Type.type(:package).provider(:yum) + +describe provider do + before do + # Create a mock resource + @resource = stub 'resource' + @resource.stubs(:[]).with(:name).returns 'mypackage' + @provider = provider.new(@resource) + @provider.stubs(:resource).returns @resource + @provider.stubs(:yum).returns 'yum' + @provider.stubs(:rpm).returns 'rpm' + @provider.stubs(:get).with(:name).returns 'mypackage' + @provider.stubs(:get).with(:version).returns '1' + @provider.stubs(:get).with(:release).returns '1' + @provider.stubs(:get).with(:arch).returns 'i386' + end + # provider should repond to the following methods + [:install, :latest, :update, :purge].each do |method| + it "should have a(n) #{method}" do + @provider.should respond_to(method) + end + end + + describe 'when installing' do + it 'should call yum install for :installed' do + @resource.stubs(:should).with(:ensure).returns :installed + @provider.expects(:yum).with('-d', '0', '-e', '0', '-y', :install, 'mypackage') + @provider.install + end + it 'should use :install to update' do + @provider.expects(:install) + @provider.update + end + it 'should be able to set version' do + @resource.stubs(:should).with(:ensure).returns '1.2' + @provider.expects(:yum).with('-d', '0', '-e', '0', '-y', :install, 'mypackage-1.2') + @provider.stubs(:query).returns :ensure => '1.2' + @provider.install + end + it 'should be able to downgrade' do + @resource.stubs(:should).with(:ensure).returns '1.0' + @provider.expects(:yum).with('-d', '0', '-e', '0', '-y', :downgrade, 'mypackage-1.0') + @provider.stubs(:query).returns(:ensure => '1.2').then.returns(:ensure => '1.0') + @provider.install + end + end + + describe 'when uninstalling' do + it 'should use erase to purge' do + @provider.expects(:yum).with('-y', :erase, 'mypackage') + @provider.purge + end + it 'should use rpm to uninstall' do + @provider.expects(:rpm).with('-e', 'mypackage-1-1.i386') + @provider.uninstall + end + end + + it 'should be versionable' do + provider.should be_versionable + end +end + diff --git a/spec/unit/provider/service/upstart.rb b/spec/unit/provider/service/upstart.rb new file mode 100644 index 000000000..9fde9e67f --- /dev/null +++ b/spec/unit/provider/service/upstart.rb @@ -0,0 +1,49 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +provider_class = Puppet::Type.type(:service).provider(:upstart) + +describe provider_class do + describe "#instances" do + it "should be able to find all instances" do + processes = ["rc stop/waiting", "ssh start/running, process 712"] + provider_class.stubs(:execpipe).yields(processes) + provider_class.instances.map {|provider| provider.name}.should =~ ["rc","ssh"] + end + + it "should attach the interface name for network interfaces" do + processes = ["network-interface (eth0)"] + provider_class.stubs(:execpipe).yields(processes) + provider_class.instances.first.name.should == "network-interface INTERFACE=eth0" + end + end + + describe "#status" do + it "should allow the user to override the status command" do + resource = Puppet::Type.type(:service).new(:name => "foo", :provider => :upstart, :status => "/bin/foo") + provider = provider_class.new(resource) + + provider.expects(:ucommand).with { `true`; true } + provider.status.should == :running + end + + it "should use the default status command if none is specified" do + resource = Puppet::Type.type(:service).new(:name => "foo", :provider => :upstart) + provider = provider_class.new(resource) + + provider.expects(:status_exec).with(["foo"]).returns("foo start/running, process 1000") + Process::Status.any_instance.stubs(:exitstatus).returns(0) + provider.status.should == :running + end + + it "should properly handle services with 'start' in their name" do + resource = Puppet::Type.type(:service).new(:name => "foostartbar", :provider => :upstart) + provider = provider_class.new(resource) + + provider.expects(:status_exec).with(["foostartbar"]).returns("foostartbar stop/waiting") + Process::Status.any_instance.stubs(:exitstatus).returns(0) + provider.status.should == :stopped + end + end +end diff --git a/spec/unit/rails/param_value_spec.rb b/spec/unit/rails/param_value_spec.rb index d6dc7d57b..243456e89 100755 --- a/spec/unit/rails/param_value_spec.rb +++ b/spec/unit/rails/param_value_spec.rb @@ -1,6 +1,7 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../spec_helper' +require 'puppet/rails' describe "Puppet::Rails::ParamValue" do confine "Cannot test without ActiveRecord" => Puppet.features.rails? diff --git a/spec/unit/rails/resource_spec.rb b/spec/unit/rails/resource_spec.rb index 73c7f7af4..6e23d2020 100755 --- a/spec/unit/rails/resource_spec.rb +++ b/spec/unit/rails/resource_spec.rb @@ -1,6 +1,7 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../spec_helper' +require 'puppet/rails' describe "Puppet::Rails::Resource" do confine "Cannot test without ActiveRecord" => Puppet.features.rails? diff --git a/spec/unit/resource/catalog_spec.rb b/spec/unit/resource/catalog_spec.rb index 2b6beb5e9..672bb8ffc 100755 --- a/spec/unit/resource/catalog_spec.rb +++ b/spec/unit/resource/catalog_spec.rb @@ -374,7 +374,7 @@ describe Puppet::Resource::Catalog, "when compiling" do @original.add_edge(@r1,@r2) @original.filter do |r| r == @r1 - end.edge(@r1,@r2).should be_empty + end.edge?(@r1,@r2).should_not be end end @@ -818,12 +818,6 @@ describe Puppet::Resource::Catalog, "when compiling" do Puppet::Util::Cacher.expire end - it "should redirect to the indirection for retrieval" do - Puppet::Resource::Catalog.stubs(:indirection).returns(@indirection) - @indirection.expects(:find) - Puppet::Resource::Catalog.find(:myconfig) - end - it "should use the value of the 'catalog_terminus' setting to determine its terminus class" do # Puppet only checks the terminus setting the first time you ask # so this returns the object to the clean state @@ -933,8 +927,8 @@ describe Puppet::Resource::Catalog, "when converting to pson" do @catalog.add_edge(one, two) @catalog.add_edge(two, three) - @catalog.edge(one, two ).expects(:to_pson_data_hash).returns "one_two_pson" - @catalog.edge(two, three).expects(:to_pson_data_hash).returns "two_three_pson" + @catalog.edges_between(one, two )[0].expects(:to_pson_data_hash).returns "one_two_pson" + @catalog.edges_between(two, three)[0].expects(:to_pson_data_hash).returns "two_three_pson" PSON.parse(@catalog.to_pson,:create_additions => false)['data']['edges'].sort.should == %w{one_two_pson two_three_pson}.sort end diff --git a/spec/unit/resource/type_collection_spec.rb b/spec/unit/resource/type_collection_spec.rb index 577aea42b..b8da3cf58 100644 --- a/spec/unit/resource/type_collection_spec.rb +++ b/spec/unit/resource/type_collection_spec.rb @@ -89,6 +89,34 @@ describe Puppet::Resource::TypeCollection do loader.node("node").should be_nil end + describe "when resolving namespaces" do + [ ['', '::foo', ['foo']], + ['a', '::foo', ['foo']], + ['a::b', '::foo', ['foo']], + [['a::b'], '::foo', ['foo']], + [['a::b', 'c'], '::foo', ['foo']], + [['A::B', 'C'], '::Foo', ['foo']], + ['', '', ['']], + ['a', '', ['']], + ['a::b', '', ['']], + [['a::b'], '', ['']], + [['a::b', 'c'], '', ['']], + [['A::B', 'C'], '', ['']], + ['', 'foo', ['foo']], + ['a', 'foo', ['a::foo', 'foo']], + ['a::b', 'foo', ['a::b::foo', 'a::foo', 'foo']], + ['A::B', 'Foo', ['a::b::foo', 'a::foo', 'foo']], + [['a::b'], 'foo', ['a::b::foo', 'a::foo', 'foo']], + [['a', 'b'], 'foo', ['a::foo', 'foo', 'b::foo']], + [['a::b', 'c::d'], 'foo', ['a::b::foo', 'a::foo', 'foo', 'c::d::foo', 'c::foo']], + [['a::b', 'a::c'], 'foo', ['a::b::foo', 'a::foo', 'foo', 'a::c::foo']], + ].each do |namespaces, name, expected_result| + it "should resolve #{name.inspect} in namespaces #{namespaces.inspect} correctly" do + @code.instance_eval { resolve_namespaces(namespaces, name) }.should == expected_result + end + end + end + describe "when looking up names" do before do @type = Puppet::Resource::Type.new(:hostclass, "ns::klass") @@ -107,29 +135,32 @@ describe Puppet::Resource::TypeCollection do describe "that need to be loaded" do it "should use the loader to load the files" do - @code.loader.expects(:load_until).with(["ns"], "klass") - @code.find_or_load(["ns"], "klass", :hostclass) + @code.loader.expects(:try_load_fqname).with(:hostclass, "ns::klass") + @code.loader.expects(:try_load_fqname).with(:hostclass, "klass") + @code.find_hostclass(["ns"], "klass") end it "should downcase the name and downcase and array-fy the namespaces before passing to the loader" do - @code.loader.expects(:load_until).with(["ns"], "klass") - @code.find_or_load("Ns", "Klass", :hostclass) + @code.loader.expects(:try_load_fqname).with(:hostclass, "ns::klass") + @code.loader.expects(:try_load_fqname).with(:hostclass, "klass") + @code.find_hostclass("Ns", "Klass") end - it "should attempt to find the type when the loader yields" do - @code.loader.expects(:load_until).yields - @code.expects(:find).with(["ns"], "klass", :hostclass).times(2).returns(false).then.returns(true) - @code.find_or_load("ns", "klass", :hostclass) + it "should use the class returned by the loader" do + @code.loader.expects(:try_load_fqname).returns(:klass) + @code.expects(:hostclass).with("ns::klass").returns(false) + @code.find_hostclass("ns", "klass").should == :klass end - it "should return the result of 'load_until'" do - @code.loader.expects(:load_until).returns "foo" - @code.find_or_load("Ns", "Klass", :hostclass).should == "foo" + it "should return nil if the name isn't found" do + @code.stubs(:try_load_fqname).returns(nil) + @code.find_hostclass("Ns", "Klass").should be_nil end - it "should return nil if the name isn't found" do - @code.stubs(:load_until).returns(nil) - @code.find_or_load("Ns", "Klass", :hostclass).should be_nil + it "already-loaded names at broader scopes should not shadow autoloaded names" do + @code.add Puppet::Resource::Type.new(:hostclass, "bar") + @code.loader.expects(:try_load_fqname).with(:hostclass, "foo::bar").returns(:foobar) + @code.find_hostclass("foo", "bar").should == :foobar end end end @@ -195,68 +226,68 @@ describe Puppet::Resource::TypeCollection do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo::bar") loader.add instance - loader.find("namespace", "::foo::bar", :hostclass).should equal(instance) + loader.find_hostclass("namespace", "::foo::bar").should equal(instance) end it "should return nil if the instance name is fully qualified and no such instance exists" do loader = Puppet::Resource::TypeCollection.new("env") - loader.find("namespace", "::foo::bar", :hostclass).should be_nil + loader.find_hostclass("namespace", "::foo::bar").should be_nil end it "should be able to find classes in the base namespace" do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo") loader.add instance - loader.find("", "foo", :hostclass).should equal(instance) + loader.find_hostclass("", "foo").should equal(instance) end it "should return the partially qualified object if it exists in a provided namespace" do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz") loader.add instance - loader.find("foo", "bar::baz", :hostclass).should equal(instance) + loader.find_hostclass("foo", "bar::baz").should equal(instance) end it "should be able to find partially qualified objects in any of the provided namespaces" do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz") loader.add instance - loader.find(["nons", "foo", "otherns"], "bar::baz", :hostclass).should equal(instance) + loader.find_hostclass(["nons", "foo", "otherns"], "bar::baz").should equal(instance) end it "should return the unqualified object if it exists in a provided namespace" do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo::bar") loader.add instance - loader.find("foo", "bar", :hostclass).should equal(instance) + loader.find_hostclass("foo", "bar").should equal(instance) end it "should return the unqualified object if it exists in the parent namespace" do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo::bar") loader.add instance - loader.find("foo::bar::baz", "bar", :hostclass).should equal(instance) + loader.find_hostclass("foo::bar::baz", "bar").should equal(instance) end it "should should return the partially qualified object if it exists in the parent namespace" do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz") loader.add instance - loader.find("foo::bar", "bar::baz", :hostclass).should equal(instance) + loader.find_hostclass("foo::bar", "bar::baz").should equal(instance) end it "should return the qualified object if it exists in the root namespace" do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz") loader.add instance - loader.find("foo::bar", "foo::bar::baz", :hostclass).should equal(instance) + loader.find_hostclass("foo::bar", "foo::bar::baz").should equal(instance) end it "should return nil if the object cannot be found" do loader = Puppet::Resource::TypeCollection.new("env") instance = Puppet::Resource::Type.new(:hostclass, "foo::bar::baz") loader.add instance - loader.find("foo::bar", "eh", :hostclass).should be_nil + loader.find_hostclass("foo::bar", "eh").should be_nil end describe "when topscope has a class that has the same name as a local class" do @@ -268,11 +299,11 @@ describe Puppet::Resource::TypeCollection do end it "should favor the local class, if the name is unqualified" do - @loader.find("foo", "bar", :hostclass).name.should == 'foo::bar' + @loader.find_hostclass("foo", "bar").name.should == 'foo::bar' end it "should only look in the topclass, if the name is qualified" do - @loader.find("foo", "::bar", :hostclass).name.should == 'bar' + @loader.find_hostclass("foo", "::bar").name.should == 'bar' end end @@ -281,15 +312,16 @@ describe Puppet::Resource::TypeCollection do @loader = Puppet::Resource::TypeCollection.new("env") @loader.add Puppet::Resource::Type.new(:hostclass, "foo::bar") - @loader.find("foo", "::bar", :hostclass).should == nil + @loader.find_hostclass("foo", "::bar").should == nil end end - it "should use the generic 'find' method with an empty namespace to find nodes" do + it "should be able to find nodes" do + node = Puppet::Resource::Type.new(:node, "bar") loader = Puppet::Resource::TypeCollection.new("env") - loader.expects(:find).with("", "bar", :node) - loader.find_node(stub("ignored"), "bar") + loader.add(node) + loader.find_node(stub("ignored"), "bar").should == node end it "should use the 'find_or_load' method to find hostclasses" do @@ -384,58 +416,6 @@ describe Puppet::Resource::TypeCollection do end end - describe "when performing initial import" do - before do - @parser = stub 'parser', :file= => nil, :string => nil, :parse => nil - Puppet::Parser::Parser.stubs(:new).returns @parser - @code = Puppet::Resource::TypeCollection.new("env") - end - - it "should create a new parser instance" do - Puppet::Parser::Parser.expects(:new).returns @parser - @code.perform_initial_import - end - - it "should set the parser's string to the 'code' setting and parse if code is available" do - Puppet.settings[:code] = "my code" - @parser.expects(:string=).with "my code" - @parser.expects(:parse) - @code.perform_initial_import - end - - it "should set the parser's file to the 'manifest' setting and parse if no code is available and the manifest is available" do - File.stubs(:expand_path).with("/my/file").returns "/my/file" - File.expects(:exist?).with("/my/file").returns true - Puppet.settings[:manifest] = "/my/file" - @parser.expects(:file=).with "/my/file" - @parser.expects(:parse) - @code.perform_initial_import - end - - it "should not attempt to load a manifest if none is present" do - File.stubs(:expand_path).with("/my/file").returns "/my/file" - File.expects(:exist?).with("/my/file").returns false - Puppet.settings[:manifest] = "/my/file" - @parser.expects(:file=).never - @parser.expects(:parse).never - @code.perform_initial_import - end - - it "should fail helpfully if there is an error importing" do - File.stubs(:exist?).returns true - @parser.expects(:parse).raises ArgumentError - lambda { @code.perform_initial_import }.should raise_error(Puppet::Error) - end - - it "should not do anything if the ignore_import settings is set" do - Puppet.settings[:ignoreimport] = true - @parser.expects(:string=).never - @parser.expects(:file=).never - @parser.expects(:parse).never - @code.perform_initial_import - end - end - describe "when determining the configuration version" do before do @code = Puppet::Resource::TypeCollection.new("env") diff --git a/spec/unit/resource/type_spec.rb b/spec/unit/resource/type_spec.rb index 7b240bb82..ef45712e6 100755 --- a/spec/unit/resource/type_spec.rb +++ b/spec/unit/resource/type_spec.rb @@ -322,7 +322,7 @@ describe Puppet::Resource::Type do end it "should set its module name in the scope if available" do - @type.module_name = "mymod" + @type.instance_eval { @module_name = "mymod" } @type.set_resource_parameters(@resource, @scope) @@ -531,8 +531,7 @@ describe Puppet::Resource::Type do @compiler.add_resource @scope, @parent_resource @type.resource_type_collection = @scope.known_resource_types - @type.resource_type_collection.stubs(:node).with("parent").returns(@parent_type) - @type.resource_type_collection.stubs(:node).with("Parent").returns(@parent_type) + @type.resource_type_collection.add(@parent_type) end it "should evaluate the parent's resource" do diff --git a/spec/unit/simple_graph_spec.rb b/spec/unit/simple_graph_spec.rb index 2ca8888c5..fa0bcb06a 100755 --- a/spec/unit/simple_graph_spec.rb +++ b/spec/unit/simple_graph_spec.rb @@ -31,12 +31,6 @@ describe Puppet::SimpleGraph do proc { @graph.to_dot_graph }.should_not raise_error end - it "should always put its edges first when printing yaml" do - @graph = Puppet::SimpleGraph.new - @graph.add_edge(:one, :two) - @graph.to_yaml_properties[0].should == "@edges" - end - describe "when managing vertices" do before do @graph = Puppet::SimpleGraph.new @@ -117,16 +111,31 @@ describe Puppet::SimpleGraph do @graph.edge?(:one, :two).should be_true end - it "should provide a method for retrieving an edge label" do - edge = Puppet::Relationship.new(:one, :two, :callback => :awesome) - @graph.add_edge(edge) - @graph.edge_label(:one, :two).should == {:callback => :awesome} - end + describe "when retrieving edges between two nodes" do + it "should handle the case of nodes not in the graph" do + @graph.edges_between(:one, :two).should == [] + end - it "should provide a method for retrieving an edge" do - edge = Puppet::Relationship.new(:one, :two) - @graph.add_edge(edge) - @graph.edge(:one, :two).should equal(edge) + it "should handle the case of nodes with no edges between them" do + @graph.add_vertex(:one) + @graph.add_vertex(:two) + @graph.edges_between(:one, :two).should == [] + end + + it "should handle the case of nodes connected by a single edge" do + edge = Puppet::Relationship.new(:one, :two) + @graph.add_edge(edge) + @graph.edges_between(:one, :two).length.should == 1 + @graph.edges_between(:one, :two)[0].should equal(edge) + end + + it "should handle the case of nodes connected by multiple edges" do + edge1 = Puppet::Relationship.new(:one, :two, :callback => :foo) + edge2 = Puppet::Relationship.new(:one, :two, :callback => :bar) + @graph.add_edge(edge1) + @graph.add_edge(edge2) + Set.new(@graph.edges_between(:one, :two)).should == Set.new([edge1, edge2]) + end end it "should add the edge source as a vertex if it is not already" do @@ -253,7 +262,7 @@ describe Puppet::SimpleGraph do it "should retain labels on edges" do @graph.add_edge(:one, :two, :callback => :awesome) - edge = @graph.reversal.edge(:two, :one) + edge = @graph.reversal.edges_between(:two, :one)[0] edge.label.should == {:callback => :awesome} end end @@ -522,14 +531,14 @@ describe Puppet::SimpleGraph do it "should not add labels to edges that have none" do @depgraph.add_edge(@two, @three) splice - @depgraph.edge_label("c", "i").should == {} + @depgraph.edges_between("c", "i")[0].label.should == {} end it "should copy labels over edges that have none" do @depgraph.add_edge("c", @three, {:callback => :refresh}) splice # And make sure the label got copied. - @depgraph.edge_label("c", "i").should == {:callback => :refresh} + @depgraph.edges_between("c", "i")[0].label.should == {:callback => :refresh} end it "should not replace a label with a nil label" do @@ -537,7 +546,7 @@ describe Puppet::SimpleGraph do @depgraph.add_edge(@middle, @three) @depgraph.add_edge("c", @three, {:callback => :refresh}) splice - @depgraph.edge_label("c", "i").should == {:callback => :refresh} + @depgraph.edges_between("c", "i")[0].label.should == {:callback => :refresh} end it "should copy labels to all created edges" do @@ -547,8 +556,207 @@ describe Puppet::SimpleGraph do @three.each do |child| edge = Puppet::Relationship.new("c", child) @depgraph.should be_edge(edge.source, edge.target) - @depgraph.edge_label(edge.source, edge.target).should == {:callback => :refresh} + @depgraph.edges_between(edge.source, edge.target)[0].label.should == {:callback => :refresh} + end + end + end + + it "should serialize to YAML using the old format by default" do + Puppet::SimpleGraph.use_new_yaml_format.should == false + end + + describe "(yaml tests)" do + def empty_graph(graph) + end + + def one_vertex_graph(graph) + graph.add_vertex(:a) + end + + def graph_without_edges(graph) + [:a, :b, :c].each { |x| graph.add_vertex(x) } + end + + def one_edge_graph(graph) + graph.add_edge(:a, :b) + end + + def many_edge_graph(graph) + graph.add_edge(:a, :b) + graph.add_edge(:a, :c) + graph.add_edge(:b, :d) + graph.add_edge(:c, :d) + end + + def labeled_edge_graph(graph) + graph.add_edge(:a, :b, :callback => :foo, :event => :bar) + end + + def overlapping_edge_graph(graph) + graph.add_edge(:a, :b, :callback => :foo, :event => :bar) + graph.add_edge(:a, :b, :callback => :biz, :event => :baz) + end + + def self.all_test_graphs + [:empty_graph, :one_vertex_graph, :graph_without_edges, :one_edge_graph, :many_edge_graph, :labeled_edge_graph, + :overlapping_edge_graph] + end + + def object_ids(enumerable) + # Return a sorted list of the object id's of the elements of an + # enumerable. + enumerable.collect { |x| x.object_id }.sort + end + + def graph_to_yaml(graph, which_format) + previous_use_new_yaml_format = Puppet::SimpleGraph.use_new_yaml_format + Puppet::SimpleGraph.use_new_yaml_format = (which_format == :new) + ZAML.dump(graph) + ensure + Puppet::SimpleGraph.use_new_yaml_format = previous_use_new_yaml_format + end + + # Test serialization of graph to YAML. + [:old, :new].each do |which_format| + all_test_graphs.each do |graph_to_test| + it "should be able to serialize #{graph_to_test} to YAML (#{which_format} format)" do + graph = Puppet::SimpleGraph.new + send(graph_to_test, graph) + yaml_form = graph_to_yaml(graph, which_format) + + # Hack the YAML so that objects in the Puppet namespace get + # changed to YAML::DomainType objects. This lets us inspect + # the serialized objects easily without invoking any + # yaml_initialize hooks. + yaml_form.gsub!('!ruby/object:Puppet::', '!hack/object:Puppet::') + serialized_object = YAML.load(yaml_form) + + # Check that the object contains instance variables @edges and + # @vertices only. @reversal is also permitted, but we don't + # check it, because it is going to be phased out. + serialized_object.type_id.should == 'object:Puppet::SimpleGraph' + serialized_object.value.keys.reject { |x| x == 'reversal' }.sort.should == ['edges', 'vertices'] + + # Check edges by forming a set of tuples (source, target, + # callback, event) based on the graph and the YAML and make sure + # they match. + edges = serialized_object.value['edges'] + edges.should be_a(Array) + expected_edge_tuples = graph.edges.collect { |edge| [edge.source, edge.target, edge.callback, edge.event] } + actual_edge_tuples = edges.collect do |edge| + edge.type_id.should == 'object:Puppet::Relationship' + %w{source target}.each { |x| edge.value.keys.should include(x) } + edge.value.keys.each { |x| ['source', 'target', 'callback', 'event'].should include(x) } + %w{source target callback event}.collect { |x| edge.value[x] } + end + Set.new(actual_edge_tuples).should == Set.new(expected_edge_tuples) + actual_edge_tuples.length.should == expected_edge_tuples.length + + # Check vertices one by one. + vertices = serialized_object.value['vertices'] + if which_format == :old + vertices.should be_a(Hash) + Set.new(vertices.keys).should == Set.new(graph.vertices) + vertices.each do |key, value| + value.type_id.should == 'object:Puppet::SimpleGraph::VertexWrapper' + value.value.keys.sort.should == %w{adjacencies vertex} + value.value['vertex'].should equal(key) + adjacencies = value.value['adjacencies'] + adjacencies.should be_a(Hash) + Set.new(adjacencies.keys).should == Set.new([:in, :out]) + [:in, :out].each do |direction| + adjacencies[direction].should be_a(Hash) + expected_adjacent_vertices = Set.new(graph.adjacent(key, :direction => direction, :type => :vertices)) + Set.new(adjacencies[direction].keys).should == expected_adjacent_vertices + adjacencies[direction].each do |adj_key, adj_value| + # Since we already checked edges, just check consistency + # with edges. + desired_source = direction == :in ? adj_key : key + desired_target = direction == :in ? key : adj_key + expected_edges = edges.select do |edge| + edge.value['source'] == desired_source && edge.value['target'] == desired_target + end + adj_value.should be_a(Set) + if object_ids(adj_value) != object_ids(expected_edges) + raise "For vertex #{key.inspect}, direction #{direction.inspect}: expected adjacencies #{expected_edges.inspect} but got #{adj_value.inspect}" + end + end + end + end + else + vertices.should be_a(Array) + Set.new(vertices).should == Set.new(graph.vertices) + vertices.length.should == graph.vertices.length + end + end + end + + # Test deserialization of graph from YAML. This presumes the + # correctness of serialization to YAML, which has already been + # tested. + all_test_graphs.each do |graph_to_test| + it "should be able to deserialize #{graph_to_test} from YAML (#{which_format} format)" do + reference_graph = Puppet::SimpleGraph.new + send(graph_to_test, reference_graph) + yaml_form = graph_to_yaml(reference_graph, which_format) + recovered_graph = YAML.load(yaml_form) + + # Test that the recovered vertices match the vertices in the + # reference graph. + expected_vertices = reference_graph.vertices.to_a + recovered_vertices = recovered_graph.vertices.to_a + Set.new(recovered_vertices).should == Set.new(expected_vertices) + recovered_vertices.length.should == expected_vertices.length + + # Test that the recovered edges match the edges in the + # reference graph. + expected_edge_tuples = reference_graph.edges.collect do |edge| + [edge.source, edge.target, edge.callback, edge.event] + end + recovered_edge_tuples = recovered_graph.edges.collect do |edge| + [edge.source, edge.target, edge.callback, edge.event] + end + Set.new(recovered_edge_tuples).should == Set.new(expected_edge_tuples) + recovered_edge_tuples.length.should == expected_edge_tuples.length + + # We ought to test that the recovered graph is self-consistent + # too. But we're not going to bother with that yet because + # the internal representation of the graph is about to change. + end + end + + it "should be able to serialize a graph where the vertices contain backreferences to the graph (#{which_format} format)" do + reference_graph = Puppet::SimpleGraph.new + vertex = Object.new + vertex.instance_eval { @graph = reference_graph } + reference_graph.add_edge(vertex, :other_vertex) + yaml_form = graph_to_yaml(reference_graph, which_format) + recovered_graph = YAML.load(yaml_form) + + recovered_graph.vertices.length.should == 2 + recovered_vertex = recovered_graph.vertices.reject { |x| x.is_a?(Symbol) }[0] + recovered_vertex.instance_eval { @graph }.should equal(recovered_graph) + recovered_graph.edges.length.should == 1 + recovered_edge = recovered_graph.edges[0] + recovered_edge.source.should equal(recovered_vertex) + recovered_edge.target.should == :other_vertex + end + end + + it "should serialize properly when used as a base class" do + class Puppet::TestDerivedClass < Puppet::SimpleGraph + attr_accessor :foo end + derived = Puppet::TestDerivedClass.new + derived.add_edge(:a, :b) + derived.foo = 1234 + recovered_derived = YAML.load(YAML.dump(derived)) + recovered_derived.class.should equal(Puppet::TestDerivedClass) + recovered_derived.edges.length.should == 1 + recovered_derived.edges[0].source.should == :a + recovered_derived.edges[0].target.should == :b + recovered_derived.vertices.length.should == 2 + recovered_derived.foo.should == 1234 end end end diff --git a/spec/unit/ssl/certificate_authority_spec.rb b/spec/unit/ssl/certificate_authority_spec.rb index 39fee3f0a..7198e33ad 100755 --- a/spec/unit/ssl/certificate_authority_spec.rb +++ b/spec/unit/ssl/certificate_authority_spec.rb @@ -138,18 +138,18 @@ describe Puppet::SSL::CertificateAuthority do it "should return any found CRL instance" do crl = mock 'crl' - Puppet::SSL::CertificateRevocationList.expects(:find).returns crl + Puppet::SSL::CertificateRevocationList.indirection.expects(:find).returns crl @ca.crl.should equal(crl) end it "should create, generate, and save a new CRL instance of no CRL can be found" do - crl = mock 'crl' - Puppet::SSL::CertificateRevocationList.expects(:find).returns nil + crl = Puppet::SSL::CertificateRevocationList.new("fakename") + Puppet::SSL::CertificateRevocationList.indirection.expects(:find).returns nil Puppet::SSL::CertificateRevocationList.expects(:new).returns crl crl.expects(:generate).with(@ca.host.certificate.content, @ca.host.key.content) - crl.expects(:save) + Puppet::SSL::CertificateRevocationList.indirection.expects(:save).with(crl) @ca.crl.should equal(crl) end @@ -235,12 +235,13 @@ describe Puppet::SSL::CertificateAuthority do @name = "myhost" @real_cert = stub 'realcert', :sign => nil - @cert = stub 'certificate', :content => @real_cert + @cert = Puppet::SSL::Certificate.new(@name) + @cert.content = @real_cert Puppet::SSL::Certificate.stubs(:new).returns @cert @cert.stubs(:content=) - @cert.stubs(:save) + Puppet::SSL::Certificate.indirection.stubs(:save) # Stub out the factory @factory = stub 'factory', :result => "my real cert" @@ -252,7 +253,7 @@ describe Puppet::SSL::CertificateAuthority do @inventory = stub 'inventory', :add => nil @ca.stubs(:inventory).returns @inventory - Puppet::SSL::CertificateRequest.stubs(:destroy) + Puppet::SSL::CertificateRequest.indirection.stubs(:destroy) end describe "and calculating the next certificate serial number" do @@ -295,7 +296,7 @@ describe Puppet::SSL::CertificateAuthority do end it "should not look up a certificate request for the host" do - Puppet::SSL::CertificateRequest.expects(:find).never + Puppet::SSL::CertificateRequest.indirection.expects(:find).never @ca.sign(@name, :ca, @request) end @@ -329,7 +330,7 @@ describe Puppet::SSL::CertificateAuthority do end it "should save the resulting certificate" do - @cert.expects(:save) + Puppet::SSL::Certificate.indirection.expects(:save).with(@cert) @ca.sign(@name, :ca, @request) end @@ -340,8 +341,8 @@ describe Puppet::SSL::CertificateAuthority do @serial = 10 @ca.stubs(:next_serial).returns @serial - Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request - @cert.stubs :save + Puppet::SSL::CertificateRequest.indirection.stubs(:find).with(@name).returns @request + Puppet::SSL::CertificateRequest.indirection.stubs :save end it "should use a certificate type of :server" do @@ -353,13 +354,13 @@ describe Puppet::SSL::CertificateAuthority do end it "should use look up a CSR for the host in the :ca_file terminus" do - Puppet::SSL::CertificateRequest.expects(:find).with(@name).returns @request + Puppet::SSL::CertificateRequest.indirection.expects(:find).with(@name).returns @request @ca.sign(@name) end it "should fail if no CSR can be found for the host" do - Puppet::SSL::CertificateRequest.expects(:find).with(@name).returns nil + Puppet::SSL::CertificateRequest.indirection.expects(:find).with(@name).returns nil lambda { @ca.sign(@name) }.should raise_error(ArgumentError) end @@ -390,12 +391,12 @@ describe Puppet::SSL::CertificateAuthority do end it "should save the resulting certificate" do - @cert.expects(:save) + Puppet::SSL::Certificate.indirection.stubs(:save).with(@cert) @ca.sign(@name) end it "should remove the host's certificate request" do - Puppet::SSL::CertificateRequest.expects(:destroy).with(@name) + Puppet::SSL::CertificateRequest.indirection.expects(:destroy).with(@name) @ca.sign(@name) end @@ -405,8 +406,8 @@ describe Puppet::SSL::CertificateAuthority do @serial = 10 @ca.stubs(:next_serial).returns @serial - Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request - @cert.stubs :save + Puppet::SSL::CertificateRequest.indirection.stubs(:find).with(@name).returns @request + Puppet::SSL::Certificate.indirection.stubs :save Puppet::SSL::Certificate.expects(:new).with(@name).returns @cert @ca.sign(@name) @@ -414,8 +415,8 @@ describe Puppet::SSL::CertificateAuthority do it "should return the certificate instance" do @ca.stubs(:next_serial).returns @serial - Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request - @cert.stubs :save + Puppet::SSL::CertificateRequest.indirection.stubs(:find).with(@name).returns @request + Puppet::SSL::Certificate.indirection.stubs :save @ca.sign(@name).should equal(@cert) end @@ -423,8 +424,8 @@ describe Puppet::SSL::CertificateAuthority do @ca.stubs(:next_serial).returns @serial @inventory.expects(:add).with(@cert) - Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request - @cert.stubs :save + Puppet::SSL::CertificateRequest.indirection.stubs(:find).with(@name).returns @request + Puppet::SSL::Certificate.indirection.stubs :save @ca.sign(@name) end @@ -436,7 +437,7 @@ describe Puppet::SSL::CertificateAuthority do it "should do nothing if autosign is disabled" do Puppet.settings.expects(:value).with(:autosign).returns 'false' - Puppet::SSL::CertificateRequest.expects(:search).never + Puppet::SSL::CertificateRequest.indirection.expects(:search).never @ca.autosign end @@ -444,7 +445,7 @@ describe Puppet::SSL::CertificateAuthority do Puppet.settings.expects(:value).with(:autosign).returns '/auto/sign' FileTest.expects(:exist?).with("/auto/sign").returns false - Puppet::SSL::CertificateRequest.expects(:search).never + Puppet::SSL::CertificateRequest.indirection.expects(:search).never @ca.autosign end @@ -454,7 +455,7 @@ describe Puppet::SSL::CertificateAuthority do FileTest.stubs(:exist?).with("/auto/sign").returns true File.stubs(:readlines).with("/auto/sign").returns ["one\n", "two\n"] - Puppet::SSL::CertificateRequest.stubs(:search).returns [] + Puppet::SSL::CertificateRequest.indirection.stubs(:search).returns [] @store = stub 'store', :allow => nil Puppet::Network::AuthStore.stubs(:new).returns @store @@ -495,13 +496,13 @@ describe Puppet::SSL::CertificateAuthority do it "should sign all CSRs whose hostname matches the autosign configuration" do csr1 = mock 'csr1' csr2 = mock 'csr2' - Puppet::SSL::CertificateRequest.stubs(:search).returns [csr1, csr2] + Puppet::SSL::CertificateRequest.indirection.stubs(:search).returns [csr1, csr2] end it "should not sign CSRs whose hostname does not match the autosign configuration" do csr1 = mock 'csr1' csr2 = mock 'csr2' - Puppet::SSL::CertificateRequest.stubs(:search).returns [csr1, csr2] + Puppet::SSL::CertificateRequest.indirection.stubs(:search).returns [csr1, csr2] end end end @@ -548,7 +549,7 @@ describe Puppet::SSL::CertificateAuthority do it "should be able to list waiting certificate requests" do req1 = stub 'req1', :name => "one" req2 = stub 'req2', :name => "two" - Puppet::SSL::CertificateRequest.expects(:search).with("*").returns [req1, req2] + Puppet::SSL::CertificateRequest.indirection.expects(:search).with("*").returns [req1, req2] @ca.waiting?.should == %w{one two} end @@ -566,19 +567,19 @@ describe Puppet::SSL::CertificateAuthority do it "should list certificates as the sorted list of all existing signed certificates" do cert1 = stub 'cert1', :name => "cert1" cert2 = stub 'cert2', :name => "cert2" - Puppet::SSL::Certificate.expects(:search).with("*").returns [cert1, cert2] + Puppet::SSL::Certificate.indirection.expects(:search).with("*").returns [cert1, cert2] @ca.list.should == %w{cert1 cert2} end describe "and printing certificates" do it "should return nil if the certificate cannot be found" do - Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil + Puppet::SSL::Certificate.indirection.expects(:find).with("myhost").returns nil @ca.print("myhost").should be_nil end it "should print certificates by calling :to_text on the host's certificate" do cert1 = stub 'cert1', :name => "cert1", :to_text => "mytext" - Puppet::SSL::Certificate.expects(:find).with("myhost").returns cert1 + Puppet::SSL::Certificate.indirection.expects(:find).with("myhost").returns cert1 @ca.print("myhost").should == "mytext" end end @@ -586,19 +587,19 @@ describe Puppet::SSL::CertificateAuthority do describe "and fingerprinting certificates" do before :each do @cert = stub 'cert', :name => "cert", :fingerprint => "DIGEST" - Puppet::SSL::Certificate.stubs(:find).with("myhost").returns @cert - Puppet::SSL::CertificateRequest.stubs(:find).with("myhost") + Puppet::SSL::Certificate.indirection.stubs(:find).with("myhost").returns @cert + Puppet::SSL::CertificateRequest.indirection.stubs(:find).with("myhost") end it "should raise an error if the certificate or CSR cannot be found" do - Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil - Puppet::SSL::CertificateRequest.expects(:find).with("myhost").returns nil + Puppet::SSL::Certificate.indirection.expects(:find).with("myhost").returns nil + Puppet::SSL::CertificateRequest.indirection.expects(:find).with("myhost").returns nil lambda { @ca.fingerprint("myhost") }.should raise_error end it "should try to find a CSR if no certificate can be found" do - Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil - Puppet::SSL::CertificateRequest.expects(:find).with("myhost").returns @cert + Puppet::SSL::Certificate.indirection.expects(:find).with("myhost").returns nil + Puppet::SSL::CertificateRequest.indirection.expects(:find).with("myhost").returns @cert @cert.expects(:fingerprint) @ca.fingerprint("myhost") end @@ -623,7 +624,7 @@ describe Puppet::SSL::CertificateAuthority do Puppet.settings.stubs(:value).returns "crtstuff" @cert = stub 'cert', :content => "mycert" - Puppet::SSL::Certificate.stubs(:find).returns @cert + Puppet::SSL::Certificate.indirection.stubs(:find).returns @cert @crl = stub('crl', :content => "mycrl") @@ -631,7 +632,7 @@ describe Puppet::SSL::CertificateAuthority do end it "should fail if the host's certificate cannot be found" do - Puppet::SSL::Certificate.expects(:find).with("me").returns(nil) + Puppet::SSL::Certificate.indirection.expects(:find).with("me").returns(nil) lambda { @ca.verify("me") }.should raise_error(ArgumentError) end @@ -694,7 +695,7 @@ describe Puppet::SSL::CertificateAuthority do @real_cert = stub 'real_cert', :serial => 15 @cert = stub 'cert', :content => @real_cert - Puppet::SSL::Certificate.stubs(:find).returns @cert + Puppet::SSL::Certificate.indirection.stubs(:find).returns @cert end @@ -714,7 +715,7 @@ describe Puppet::SSL::CertificateAuthority do it "should get the serial number from the local certificate if it exists" do @ca.crl.expects(:revoke).with { |serial, key| serial == 15 } - Puppet::SSL::Certificate.expects(:find).with("host").returns @cert + Puppet::SSL::Certificate.indirection.expects(:find).with("host").returns @cert @ca.revoke('host') end @@ -722,7 +723,7 @@ describe Puppet::SSL::CertificateAuthority do it "should get the serial number from inventory if no local certificate exists" do real_cert = stub 'real_cert', :serial => 15 cert = stub 'cert', :content => real_cert - Puppet::SSL::Certificate.expects(:find).with("host").returns nil + Puppet::SSL::Certificate.indirection.expects(:find).with("host").returns nil @ca.inventory.expects(:serial).with("host").returns 16 @@ -739,13 +740,13 @@ describe Puppet::SSL::CertificateAuthority do before do @host = stub 'host', :generate_certificate_request => nil Puppet::SSL::Host.stubs(:new).returns @host - Puppet::SSL::Certificate.stubs(:find).returns nil + Puppet::SSL::Certificate.indirection.stubs(:find).returns nil @ca.stubs(:sign) end it "should fail if a certificate already exists for the host" do - Puppet::SSL::Certificate.expects(:find).with("him").returns "something" + Puppet::SSL::Certificate.indirection.expects(:find).with("him").returns "something" lambda { @ca.generate("him") }.should raise_error(ArgumentError) end diff --git a/spec/unit/ssl/certificate_request_spec.rb b/spec/unit/ssl/certificate_request_spec.rb index 437fc0556..fb4b5a134 100755 --- a/spec/unit/ssl/certificate_request_spec.rb +++ b/spec/unit/ssl/certificate_request_spec.rb @@ -187,22 +187,17 @@ describe Puppet::SSL::CertificateRequest do end describe "when a CSR is saved" do - it "should allow arguments" do - csr = Puppet::SSL::CertificateRequest.new("me") - csr.class.indirection.stubs(:save) - - lambda { csr.save :ipaddress => "foo" }.should_not raise_error - end - describe "and a CA is available" do it "should save the CSR and trigger autosigning" do ca = mock 'ca', :autosign Puppet::SSL::CertificateAuthority.expects(:instance).returns ca csr = Puppet::SSL::CertificateRequest.new("me") - Puppet::SSL::CertificateRequest.indirection.expects(:save).with(nil, csr) + terminus = mock 'terminus' + Puppet::SSL::CertificateRequest.indirection.expects(:prepare).returns(terminus) + terminus.expects(:save).with { |request| puts request.key.inspect; request.instance == csr && request.key == "me" } - csr.save + Puppet::SSL::CertificateRequest.indirection.save(csr) end end @@ -211,9 +206,11 @@ describe Puppet::SSL::CertificateRequest do Puppet::SSL::CertificateAuthority.expects(:instance).returns nil csr = Puppet::SSL::CertificateRequest.new("me") - Puppet::SSL::CertificateRequest.indirection.expects(:save).with(nil, csr) + terminus = mock 'terminus' + Puppet::SSL::CertificateRequest.indirection.expects(:prepare).returns(terminus) + terminus.expects(:save).with { |request| puts request.key.inspect; request.instance == csr && request.key == "me" } - csr.save + Puppet::SSL::CertificateRequest.indirection.save(csr) end end end diff --git a/spec/unit/ssl/certificate_revocation_list_spec.rb b/spec/unit/ssl/certificate_revocation_list_spec.rb index f9993d52e..3bf12fa0a 100755 --- a/spec/unit/ssl/certificate_revocation_list_spec.rb +++ b/spec/unit/ssl/certificate_revocation_list_spec.rb @@ -119,7 +119,7 @@ describe Puppet::SSL::CertificateRevocationList do @crl.generate(@cert, @key) @crl.content.stubs(:sign) - @crl.stubs :save + Puppet::SSL::CertificateRevocationList.indirection.stubs :save @key = mock 'key' end @@ -161,7 +161,7 @@ describe Puppet::SSL::CertificateRevocationList do end it "should save the CRL" do - @crl.expects :save + Puppet::SSL::CertificateRevocationList.indirection.expects(:save).with(@crl, nil) @crl.revoke(1, @key) end end diff --git a/spec/unit/ssl/host_spec.rb b/spec/unit/ssl/host_spec.rb index b2e43393c..77911091e 100755 --- a/spec/unit/ssl/host_spec.rb +++ b/spec/unit/ssl/host_spec.rb @@ -22,7 +22,7 @@ describe Puppet::SSL::Host do it "should retrieve its public key from its private key" do realkey = mock 'realkey' key = stub 'key', :content => realkey - Puppet::SSL::Key.stubs(:find).returns(key) + Puppet::SSL::Key.indirection.stubs(:find).returns(key) pubkey = mock 'public_key' realkey.expects(:public_key).returns pubkey @@ -142,8 +142,8 @@ describe Puppet::SSL::Host do describe "when specifying the CA location" do before do [Puppet::SSL::Key, Puppet::SSL::Certificate, Puppet::SSL::CertificateRequest, Puppet::SSL::CertificateRevocationList].each do |klass| - klass.stubs(:terminus_class=) - klass.stubs(:cache_class=) + klass.indirection.stubs(:terminus_class=) + klass.indirection.stubs(:cache_class=) end end @@ -169,23 +169,23 @@ describe Puppet::SSL::Host do describe "as 'local'" do it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do - Puppet::SSL::Certificate.expects(:cache_class=).with :file - Puppet::SSL::CertificateRequest.expects(:cache_class=).with :file - Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with :file + Puppet::SSL::Certificate.indirection.expects(:cache_class=).with :file + Puppet::SSL::CertificateRequest.indirection.expects(:cache_class=).with :file + Puppet::SSL::CertificateRevocationList.indirection.expects(:cache_class=).with :file Puppet::SSL::Host.ca_location = :local end it "should set the terminus class for Key as :file" do - Puppet::SSL::Key.expects(:terminus_class=).with :file + Puppet::SSL::Key.indirection.expects(:terminus_class=).with :file Puppet::SSL::Host.ca_location = :local end it "should set the terminus class for Certificate, CertificateRevocationList, and CertificateRequest as :ca" do - Puppet::SSL::Certificate.expects(:terminus_class=).with :ca - Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :ca - Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :ca + Puppet::SSL::Certificate.indirection.expects(:terminus_class=).with :ca + Puppet::SSL::CertificateRequest.indirection.expects(:terminus_class=).with :ca + Puppet::SSL::CertificateRevocationList.indirection.expects(:terminus_class=).with :ca Puppet::SSL::Host.ca_location = :local end @@ -193,23 +193,23 @@ describe Puppet::SSL::Host do describe "as 'remote'" do it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do - Puppet::SSL::Certificate.expects(:cache_class=).with :file - Puppet::SSL::CertificateRequest.expects(:cache_class=).with :file - Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with :file + Puppet::SSL::Certificate.indirection.expects(:cache_class=).with :file + Puppet::SSL::CertificateRequest.indirection.expects(:cache_class=).with :file + Puppet::SSL::CertificateRevocationList.indirection.expects(:cache_class=).with :file Puppet::SSL::Host.ca_location = :remote end it "should set the terminus class for Key as :file" do - Puppet::SSL::Key.expects(:terminus_class=).with :file + Puppet::SSL::Key.indirection.expects(:terminus_class=).with :file Puppet::SSL::Host.ca_location = :remote end it "should set the terminus class for Certificate, CertificateRevocationList, and CertificateRequest as :rest" do - Puppet::SSL::Certificate.expects(:terminus_class=).with :rest - Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :rest - Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :rest + Puppet::SSL::Certificate.indirection.expects(:terminus_class=).with :rest + Puppet::SSL::CertificateRequest.indirection.expects(:terminus_class=).with :rest + Puppet::SSL::CertificateRevocationList.indirection.expects(:terminus_class=).with :rest Puppet::SSL::Host.ca_location = :remote end @@ -217,18 +217,18 @@ describe Puppet::SSL::Host do describe "as 'only'" do it "should set the terminus class for Key, Certificate, CertificateRevocationList, and CertificateRequest as :ca" do - Puppet::SSL::Key.expects(:terminus_class=).with :ca - Puppet::SSL::Certificate.expects(:terminus_class=).with :ca - Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :ca - Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :ca + Puppet::SSL::Key.indirection.expects(:terminus_class=).with :ca + Puppet::SSL::Certificate.indirection.expects(:terminus_class=).with :ca + Puppet::SSL::CertificateRequest.indirection.expects(:terminus_class=).with :ca + Puppet::SSL::CertificateRevocationList.indirection.expects(:terminus_class=).with :ca Puppet::SSL::Host.ca_location = :only end it "should reset the cache class for Certificate, CertificateRevocationList, and CertificateRequest to nil" do - Puppet::SSL::Certificate.expects(:cache_class=).with nil - Puppet::SSL::CertificateRequest.expects(:cache_class=).with nil - Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with nil + Puppet::SSL::Certificate.indirection.expects(:cache_class=).with nil + Puppet::SSL::CertificateRequest.indirection.expects(:cache_class=).with nil + Puppet::SSL::CertificateRevocationList.indirection.expects(:cache_class=).with nil Puppet::SSL::Host.ca_location = :only end @@ -236,10 +236,10 @@ describe Puppet::SSL::Host do describe "as 'none'" do it "should set the terminus class for Key, Certificate, CertificateRevocationList, and CertificateRequest as :file" do - Puppet::SSL::Key.expects(:terminus_class=).with :file - Puppet::SSL::Certificate.expects(:terminus_class=).with :file - Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :file - Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :file + Puppet::SSL::Key.indirection.expects(:terminus_class=).with :file + Puppet::SSL::Certificate.indirection.expects(:terminus_class=).with :file + Puppet::SSL::CertificateRequest.indirection.expects(:terminus_class=).with :file + Puppet::SSL::CertificateRevocationList.indirection.expects(:terminus_class=).with :file Puppet::SSL::Host.ca_location = :none end @@ -252,21 +252,21 @@ describe Puppet::SSL::Host do describe "when destroying a host's SSL files" do before do - Puppet::SSL::Key.stubs(:destroy).returns false - Puppet::SSL::Certificate.stubs(:destroy).returns false - Puppet::SSL::CertificateRequest.stubs(:destroy).returns false + Puppet::SSL::Key.indirection.stubs(:destroy).returns false + Puppet::SSL::Certificate.indirection.stubs(:destroy).returns false + Puppet::SSL::CertificateRequest.indirection.stubs(:destroy).returns false end it "should destroy its certificate, certificate request, and key" do - Puppet::SSL::Key.expects(:destroy).with("myhost") - Puppet::SSL::Certificate.expects(:destroy).with("myhost") - Puppet::SSL::CertificateRequest.expects(:destroy).with("myhost") + Puppet::SSL::Key.indirection.expects(:destroy).with("myhost") + Puppet::SSL::Certificate.indirection.expects(:destroy).with("myhost") + Puppet::SSL::CertificateRequest.indirection.expects(:destroy).with("myhost") Puppet::SSL::Host.destroy("myhost") end it "should return true if any of the classes returned true" do - Puppet::SSL::Certificate.expects(:destroy).with("myhost").returns true + Puppet::SSL::Certificate.indirection.expects(:destroy).with("myhost").returns true Puppet::SSL::Host.destroy("myhost").should be_true end @@ -301,16 +301,17 @@ describe Puppet::SSL::Host do describe "when managing its private key" do before do @realkey = "mykey" - @key = stub 'key', :content => @realkey + @key = Puppet::SSL::Key.new("mykey") + @key.content = @realkey end it "should return nil if the key is not set and cannot be found" do - Puppet::SSL::Key.expects(:find).with("myname").returns(nil) + Puppet::SSL::Key.indirection.expects(:find).with("myname").returns(nil) @host.key.should be_nil end it "should find the key in the Key class and return the Puppet instance" do - Puppet::SSL::Key.expects(:find).with("myname").returns(@key) + Puppet::SSL::Key.indirection.expects(:find).with("myname").returns(@key) @host.key.should equal(@key) end @@ -318,7 +319,7 @@ describe Puppet::SSL::Host do Puppet::SSL::Key.expects(:new).with("myname").returns(@key) @key.expects(:generate) - @key.expects(:save) + Puppet::SSL::Key.indirection.expects(:save) @host.generate_key.should be_true @host.key.should equal(@key) @@ -328,14 +329,14 @@ describe Puppet::SSL::Host do Puppet::SSL::Key.expects(:new).with("myname").returns(@key) @key.stubs(:generate) - @key.expects(:save).raises "eh" + Puppet::SSL::Key.indirection.expects(:save).raises "eh" lambda { @host.generate_key }.should raise_error @host.key.should be_nil end it "should return any previously found key without requerying" do - Puppet::SSL::Key.expects(:find).with("myname").returns(@key).once + Puppet::SSL::Key.indirection.expects(:find).with("myname").returns(@key).once @host.key.should equal(@key) @host.key.should equal(@key) end @@ -344,16 +345,17 @@ describe Puppet::SSL::Host do describe "when managing its certificate request" do before do @realrequest = "real request" - @request = stub 'request', :content => @realrequest + @request = Puppet::SSL::CertificateRequest.new("myname") + @request.content = @realrequest end it "should return nil if the key is not set and cannot be found" do - Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns(nil) + Puppet::SSL::CertificateRequest.indirection.expects(:find).with("myname").returns(nil) @host.certificate_request.should be_nil end it "should find the request in the Key class and return it and return the Puppet SSL request" do - Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns @request + Puppet::SSL::CertificateRequest.indirection.expects(:find).with("myname").returns @request @host.certificate_request.should equal(@request) end @@ -367,7 +369,7 @@ describe Puppet::SSL::Host do @host.expects(:generate_key).returns(key) @request.stubs(:generate) - @request.stubs(:save) + Puppet::SSL::CertificateRequest.indirection.stubs(:save) @host.generate_certificate_request end @@ -378,14 +380,14 @@ describe Puppet::SSL::Host do key = stub 'key', :public_key => mock("public_key"), :content => "mycontent" @host.stubs(:key).returns(key) @request.expects(:generate).with("mycontent") - @request.expects(:save) + Puppet::SSL::CertificateRequest.indirection.expects(:save).with(@request) @host.generate_certificate_request.should be_true @host.certificate_request.should equal(@request) end it "should return any previously found request without requerying" do - Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns(@request).once + Puppet::SSL::CertificateRequest.indirection.expects(:find).with("myname").returns(@request).once @host.certificate_request.should equal(@request) @host.certificate_request.should equal(@request) @@ -397,11 +399,14 @@ describe Puppet::SSL::Host do key = stub 'key', :public_key => mock("public_key"), :content => "mycontent" @host.stubs(:key).returns(key) @request.stubs(:generate) - @request.expects(:save).raises "eh" + @request.stubs(:name).returns("myname") + terminus = stub 'terminus' + Puppet::SSL::CertificateRequest.indirection.expects(:prepare).returns(terminus) + terminus.expects(:save).with { |req| req.instance == @request && req.key == "myname" }.raises "eh" lambda { @host.generate_certificate_request }.should raise_error - @host.certificate_request.should be_nil + @host.instance_eval { @certificate_request }.should be_nil end end @@ -415,36 +420,36 @@ describe Puppet::SSL::Host do end it "should find the CA certificate if it does not have a certificate" do - Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") - Puppet::SSL::Certificate.stubs(:find).with("myname").returns @cert + Puppet::SSL::Certificate.indirection.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") + Puppet::SSL::Certificate.indirection.stubs(:find).with("myname").returns @cert @host.certificate end it "should not find the CA certificate if it is the CA host" do @host.expects(:ca?).returns true - Puppet::SSL::Certificate.stubs(:find) - Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).never + Puppet::SSL::Certificate.indirection.stubs(:find) + Puppet::SSL::Certificate.indirection.expects(:find).with(Puppet::SSL::CA_NAME).never @host.certificate end it "should return nil if it cannot find a CA certificate" do - Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns nil - Puppet::SSL::Certificate.expects(:find).with("myname").never + Puppet::SSL::Certificate.indirection.expects(:find).with(Puppet::SSL::CA_NAME).returns nil + Puppet::SSL::Certificate.indirection.expects(:find).with("myname").never @host.certificate.should be_nil end it "should find the key if it does not have one" do - Puppet::SSL::Certificate.stubs(:find) + Puppet::SSL::Certificate.indirection.stubs(:find) @host.expects(:key).returns mock("key") @host.certificate end it "should generate the key if one cannot be found" do - Puppet::SSL::Certificate.stubs(:find) + Puppet::SSL::Certificate.indirection.stubs(:find) @host.expects(:key).returns nil @host.expects(:generate_key) @@ -453,8 +458,8 @@ describe Puppet::SSL::Host do end it "should find the certificate in the Certificate class and return the Puppet certificate instance" do - Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") - Puppet::SSL::Certificate.expects(:find).with("myname").returns @cert + Puppet::SSL::Certificate.indirection.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") + Puppet::SSL::Certificate.indirection.expects(:find).with("myname").returns @cert @host.certificate.should equal(@cert) end @@ -462,14 +467,14 @@ describe Puppet::SSL::Host do it "should fail if the found certificate does not match the private key" do @host.expects(:certificate_matches_key?).returns false - Puppet::SSL::Certificate.stubs(:find).returns @cert + Puppet::SSL::Certificate.indirection.stubs(:find).returns @cert lambda { @host.certificate }.should raise_error(Puppet::Error) end it "should return any previously found certificate" do - Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") - Puppet::SSL::Certificate.expects(:find).with("myname").returns(@cert).once + Puppet::SSL::Certificate.indirection.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") + Puppet::SSL::Certificate.indirection.expects(:find).with("myname").returns(@cert).once @host.certificate.should equal(@cert) @host.certificate.should equal(@cert) @@ -482,30 +487,30 @@ describe Puppet::SSL::Host do describe "when listing certificate hosts" do it "should default to listing all clients with any file types" do - Puppet::SSL::Key.expects(:search).returns [] - Puppet::SSL::Certificate.expects(:search).returns [] - Puppet::SSL::CertificateRequest.expects(:search).returns [] + Puppet::SSL::Key.indirection.expects(:search).returns [] + Puppet::SSL::Certificate.indirection.expects(:search).returns [] + Puppet::SSL::CertificateRequest.indirection.expects(:search).returns [] Puppet::SSL::Host.search end it "should be able to list only clients with a key" do - Puppet::SSL::Key.expects(:search).returns [] - Puppet::SSL::Certificate.expects(:search).never - Puppet::SSL::CertificateRequest.expects(:search).never + Puppet::SSL::Key.indirection.expects(:search).returns [] + Puppet::SSL::Certificate.indirection.expects(:search).never + Puppet::SSL::CertificateRequest.indirection.expects(:search).never Puppet::SSL::Host.search :for => Puppet::SSL::Key end it "should be able to list only clients with a certificate" do - Puppet::SSL::Key.expects(:search).never - Puppet::SSL::Certificate.expects(:search).returns [] - Puppet::SSL::CertificateRequest.expects(:search).never + Puppet::SSL::Key.indirection.expects(:search).never + Puppet::SSL::Certificate.indirection.expects(:search).returns [] + Puppet::SSL::CertificateRequest.indirection.expects(:search).never Puppet::SSL::Host.search :for => Puppet::SSL::Certificate end it "should be able to list only clients with a certificate request" do - Puppet::SSL::Key.expects(:search).never - Puppet::SSL::Certificate.expects(:search).never - Puppet::SSL::CertificateRequest.expects(:search).returns [] + Puppet::SSL::Key.indirection.expects(:search).never + Puppet::SSL::Certificate.indirection.expects(:search).never + Puppet::SSL::CertificateRequest.indirection.expects(:search).returns [] Puppet::SSL::Host.search :for => Puppet::SSL::CertificateRequest end @@ -514,9 +519,9 @@ describe Puppet::SSL::Host do cert = stub 'cert', :name => "cert" csr = stub 'csr', :name => "csr" - Puppet::SSL::Key.expects(:search).returns [key] - Puppet::SSL::Certificate.expects(:search).returns [cert] - Puppet::SSL::CertificateRequest.expects(:search).returns [csr] + Puppet::SSL::Key.indirection.expects(:search).returns [key] + Puppet::SSL::Certificate.indirection.expects(:search).returns [cert] + Puppet::SSL::CertificateRequest.indirection.expects(:search).returns [csr] returned = [] %w{key cert csr}.each do |name| @@ -606,7 +611,7 @@ describe Puppet::SSL::Host do Puppet.settings.stubs(:value).with(:localcacert).returns "ssl_host_testing" - Puppet::SSL::CertificateRevocationList.stubs(:find).returns(nil) + Puppet::SSL::CertificateRevocationList.indirection.stubs(:find).returns(nil) end it "should accept a purpose" do @@ -628,7 +633,7 @@ describe Puppet::SSL::Host do describe "and a CRL is available" do before do @crl = stub 'crl', :content => "real_crl" - Puppet::SSL::CertificateRevocationList.stubs(:find).returns @crl + Puppet::SSL::CertificateRevocationList.indirection.stubs(:find).returns @crl Puppet.settings.stubs(:value).with(:certificate_revocation).returns true end diff --git a/spec/unit/ssl/inventory_spec.rb b/spec/unit/ssl/inventory_spec.rb index a57d6fafc..008fece0b 100755 --- a/spec/unit/ssl/inventory_spec.rb +++ b/spec/unit/ssl/inventory_spec.rb @@ -40,7 +40,7 @@ describe Puppet::SSL::Inventory do Puppet.settings.stubs(:write) FileTest.stubs(:exist?).with("/inven/tory").returns false - Puppet::SSL::Certificate.stubs(:search).returns [] + Puppet::SSL::Certificate.indirection.stubs(:search).returns [] end it "should log that it is building a new inventory file" do @@ -67,7 +67,7 @@ describe Puppet::SSL::Inventory do cert1 = mock 'cert1' cert2 = mock 'cert2' - Puppet::SSL::Certificate.expects(:search).with("*").returns [cert1, cert2] + Puppet::SSL::Certificate.indirection.expects(:search).with("*").returns [cert1, cert2] @class.any_instance.expects(:add).with(cert1) @class.any_instance.expects(:add).with(cert2) diff --git a/spec/unit/status_spec.rb b/spec/unit/status_spec.rb index 71bfa4a44..938bbdf84 100644 --- a/spec/unit/status_spec.rb +++ b/spec/unit/status_spec.rb @@ -4,8 +4,8 @@ require File.dirname(__FILE__) + '/../spec_helper' describe Puppet::Status do it "should implement find" do - Puppet::Status.find( :default ).should be_is_a(Puppet::Status) - Puppet::Status.find( :default ).status["is_alive"].should == true + Puppet::Status.indirection.find( :default ).should be_is_a(Puppet::Status) + Puppet::Status.indirection.find( :default ).status["is_alive"].should == true end it "should default to is_alive is true" do diff --git a/spec/unit/transaction/report_spec.rb b/spec/unit/transaction/report_spec.rb index 7e0b0554b..1f1fdb080 100755 --- a/spec/unit/transaction/report_spec.rb +++ b/spec/unit/transaction/report_spec.rb @@ -53,20 +53,13 @@ describe Puppet::Transaction::Report do end describe "when using the indirector" do - it "should redirect :find to the indirection" do - @indirection = stub 'indirection', :name => :report - Puppet::Transaction::Report.stubs(:indirection).returns(@indirection) - @indirection.expects(:find) - Puppet::Transaction::Report.find(:report) - end - 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 @indirection.expects(:save) - report.save + Puppet::Transaction::Report.indirection.save(report) end it "should default to the 'processor' terminus" do @@ -225,8 +218,19 @@ describe Puppet::Transaction::Report do @report.calculate_metrics end - %w{Changes Total Resources}.each do |main| - it "should include information on #{main} in the summary" do + %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 diff --git a/spec/unit/type/file/source_spec.rb b/spec/unit/type/file/source_spec.rb index a45a1f74e..b6833f77c 100755 --- a/spec/unit/type/file/source_spec.rb +++ b/spec/unit/type/file/source_spec.rb @@ -54,22 +54,22 @@ describe Puppet::Type.type(:file).attrclass(:source) do it "should collect its metadata using the Metadata class if it is not already set" do @source = source.new(:resource => @resource, :value => "/foo/bar") - Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").returns @metadata + Puppet::FileServing::Metadata.indirection.expects(:find).with("/foo/bar").returns @metadata @source.metadata end it "should use the metadata from the first found source" do metadata = stub 'metadata', :source= => nil @source = source.new(:resource => @resource, :value => ["/foo/bar", "/fee/booz"]) - Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").returns nil - Puppet::FileServing::Metadata.expects(:find).with("/fee/booz").returns metadata + Puppet::FileServing::Metadata.indirection.expects(:find).with("/foo/bar").returns nil + Puppet::FileServing::Metadata.indirection.expects(:find).with("/fee/booz").returns metadata @source.metadata.should equal(metadata) end it "should store the found source as the metadata's source" do metadata = mock 'metadata' @source = source.new(:resource => @resource, :value => "/foo/bar") - Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").returns metadata + Puppet::FileServing::Metadata.indirection.expects(:find).with("/foo/bar").returns metadata metadata.expects(:source=).with("/foo/bar") @source.metadata @@ -77,7 +77,7 @@ describe Puppet::Type.type(:file).attrclass(:source) do it "should fail intelligently if an exception is encountered while querying for metadata" do @source = source.new(:resource => @resource, :value => "/foo/bar") - Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").raises RuntimeError + Puppet::FileServing::Metadata.indirection.expects(:find).with("/foo/bar").raises RuntimeError @source.expects(:fail).raises ArgumentError lambda { @source.metadata }.should raise_error(ArgumentError) @@ -85,7 +85,7 @@ describe Puppet::Type.type(:file).attrclass(:source) do it "should fail if no specified sources can be found" do @source = source.new(:resource => @resource, :value => "/foo/bar") - Puppet::FileServing::Metadata.expects(:find).with("/foo/bar").returns nil + Puppet::FileServing::Metadata.indirection.expects(:find).with("/foo/bar").returns nil @source.expects(:fail).raises RuntimeError @@ -96,7 +96,7 @@ describe Puppet::Type.type(:file).attrclass(:source) do expirer = stub 'expired', :dependent_data_expired? => true metadata = stub 'metadata', :source= => nil - Puppet::FileServing::Metadata.expects(:find).with("/fee/booz").returns metadata + Puppet::FileServing::Metadata.indirection.expects(:find).with("/fee/booz").returns metadata @source = source.new(:resource => @resource, :value => ["/fee/booz"]) @source.metadata = "foo" diff --git a/spec/unit/type/file_spec.rb b/spec/unit/type/file_spec.rb index 7d93dfd64..943a3c38a 100755 --- a/spec/unit/type/file_spec.rb +++ b/spec/unit/type/file_spec.rb @@ -510,47 +510,47 @@ describe Puppet::Type.type(:file) do describe "when executing a recursive search" do it "should use Metadata to do its recursion" do - Puppet::FileServing::Metadata.expects(:search) + Puppet::FileServing::Metadata.indirection.expects(:search) @file.perform_recursion(@file[:path]) end it "should use the provided path as the key to the search" do - Puppet::FileServing::Metadata.expects(:search).with { |key, options| key == "/foo" } + Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| key == "/foo" } @file.perform_recursion("/foo") end it "should return the results of the metadata search" do - Puppet::FileServing::Metadata.expects(:search).returns "foobar" + Puppet::FileServing::Metadata.indirection.expects(:search).returns "foobar" @file.perform_recursion(@file[:path]).should == "foobar" end it "should pass its recursion value to the search" do @file[:recurse] = true - Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:recurse] == true } + Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:recurse] == true } @file.perform_recursion(@file[:path]) end it "should pass true if recursion is remote" do @file[:recurse] = :remote - Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:recurse] == true } + Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:recurse] == true } @file.perform_recursion(@file[:path]) end it "should pass its recursion limit value to the search" do @file[:recurselimit] = 10 - Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:recurselimit] == 10 } + Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:recurselimit] == 10 } @file.perform_recursion(@file[:path]) end it "should configure the search to ignore or manage links" do @file[:links] = :manage - Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:links] == :manage } + Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:links] == :manage } @file.perform_recursion(@file[:path]) end it "should pass its 'ignore' setting to the search if it has one" do @file[:ignore] = %w{.svn CVS} - Puppet::FileServing::Metadata.expects(:search).with { |key, options| options[:ignore] == %w{.svn CVS} } + Puppet::FileServing::Metadata.indirection.expects(:search).with { |key, options| options[:ignore] == %w{.svn CVS} } @file.perform_recursion(@file[:path]) end end @@ -597,7 +597,7 @@ describe Puppet::Type.type(:file) do it "should set checksum_type to none if this file checksum is none" do @file[:checksum] = :none - Puppet::FileServing::Metadata.expects(:search).with { |path,params| params[:checksum_type] == :none }.returns [@metadata] + Puppet::FileServing::Metadata.indirection.expects(:search).with { |path,params| params[:checksum_type] == :none }.returns [@metadata] @file.expects(:newchild).with("my/file").returns "fiebar" @file.recurse_local end diff --git a/spec/unit/type/host_spec.rb b/spec/unit/type/host_spec.rb new file mode 100755 index 000000000..12ae2af08 --- /dev/null +++ b/spec/unit/type/host_spec.rb @@ -0,0 +1,83 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../spec_helper' + +ssh_authorized_key = Puppet::Type.type(:ssh_authorized_key) + +describe Puppet::Type.type(:host) do + before do + @class = Puppet::Type.type(:host) + @catalog = Puppet::Resource::Catalog.new + end + + it "should have :name be its namevar" do + @class.key_attributes.should == [:name] + end + + describe "when validating attributes" do + [:name, :provider ].each do |param| + it "should have a #{param} parameter" do + @class.attrtype(param).should == :param + end + end + + [:ip, :target, :host_aliases, :comment, :ensure].each do |property| + it "should have a #{property} property" do + @class.attrtype(property).should == :property + end + end + end + + describe "when validating values" do + it "should support present as a value for ensure" do + proc { @class.new(:name => "foo", :ensure => :present) }.should_not raise_error + end + + it "should support absent as a value for ensure" do + proc { @class.new(:name => "foo", :ensure => :absent) }.should_not raise_error + end + + it "should accept IPv4 addresses" do + proc { @class.new(:name => "foo", :ip => '10.96.0.1') }.should_not raise_error + end + + it "should accept long IPv6 addresses" do + # Taken from wikipedia article about ipv6 + proc { @class.new(:name => "foo", :ip => '2001:0db8:85a3:08d3:1319:8a2e:0370:7344') }.should_not raise_error + end + + it "should accept one host_alias" do + proc { @class.new(:name => "foo", :host_aliases => 'alias1') }.should_not raise_error + end + + it "should accept multiple host_aliases" do + proc { @class.new(:name => "foo", :host_aliases => [ 'alias1', 'alias2' ]) }.should_not raise_error + end + + it "should accept shortened IPv6 addresses" do + proc { @class.new(:name => "foo", :ip => '2001:db8:0:8d3:0:8a2e:70:7344') }.should_not raise_error + proc { @class.new(:name => "foo", :ip => '::ffff:192.0.2.128') }.should_not raise_error + proc { @class.new(:name => "foo", :ip => '::1') }.should_not raise_error + end + + it "should not accept malformed IPv4 addresses like 192.168.0.300" do + proc { @class.new(:name => "foo", :ip => '192.168.0.300') }.should raise_error + end + + it "should not accept malformed IP addresses like 2001:0dg8:85a3:08d3:1319:8a2e:0370:7344" do + proc { @class.new(:name => "foo", :ip => '2001:0dg8:85a3:08d3:1319:8a2e:0370:7344') }.should raise_error + end + + it "should not accept spaces in resourcename" do + proc { @class.new(:name => "foo bar") }.should raise_error + end + + it "should not accept host_aliases with spaces" do + proc { @class.new(:name => "foo", :host_aliases => [ 'well_formed', 'not wellformed' ]) }.should raise_error + end + + it "should not accept empty host_aliases" do + proc { @class.new(:name => "foo", :host_aliases => ['alias1','']) }.should raise_error + end + end +end diff --git a/spec/unit/type/mount_spec.rb b/spec/unit/type/mount_spec.rb index ce82cb516..4aa9baf70 100755 --- a/spec/unit/type/mount_spec.rb +++ b/spec/unit/type/mount_spec.rb @@ -203,23 +203,45 @@ describe Puppet::Type.type(:mount)::Ensure do end end - describe Puppet::Type.type(:mount), "when responding to events" do + describe Puppet::Type.type(:mount), "when responding to refresh" do - it "should remount if it is currently mounted" do - @provider.expects(:mounted?).returns(true) + it "should remount if it is supposed to be mounted" do + @mount[:ensure] = "mounted" @provider.expects(:remount) @mount.refresh end - it "should not remount if it is not currently mounted" do - @provider.expects(:mounted?).returns(false) + it "should not remount if it is supposed to be present" do + @mount[:ensure] = "present" + @provider.expects(:remount).never + + @mount.refresh + end + + it "should not remount if it is supposed to be absent" do + @mount[:ensure] = "absent" + @provider.expects(:remount).never + + @mount.refresh + end + + it "should not remount if it is supposed to be defined" do + @mount[:ensure] = "defined" + @provider.expects(:remount).never + + @mount.refresh + end + + it "should not remount if it is supposed to be unmounted" do + @mount[:ensure] = "unmounted" @provider.expects(:remount).never @mount.refresh end it "should not remount swap filesystems" do + @mount[:ensure] = "mounted" @mount[:fstype] = "swap" @provider.expects(:remount).never diff --git a/spec/unit/type/service_spec.rb b/spec/unit/type/service_spec.rb index 0958a69fa..77628670a 100755 --- a/spec/unit/type/service_spec.rb +++ b/spec/unit/type/service_spec.rb @@ -66,6 +66,10 @@ describe Puppet::Type.type(:service), "when validating attribute values" do Puppet::Type.type(:service).new(:name => "yay", :hasstatus => :false) end + it "should specify :true as the default value of hasstatus" do + Puppet::Type.type(:service).new(:name => "yay")[:hasstatus].should == :true + end + it "should support :true as a value to :hasrestart" do Puppet::Type.type(:service).new(:name => "yay", :hasrestart => :true) end diff --git a/spec/unit/type/sshkey_spec.rb b/spec/unit/type/sshkey_spec.rb new file mode 100644 index 000000000..966ca7099 --- /dev/null +++ b/spec/unit/type/sshkey_spec.rb @@ -0,0 +1,71 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../spec_helper' + +sshkey = Puppet::Type.type(:sshkey) + +describe sshkey do + before do + @class = sshkey + end + + it "should have :name its namevar" do + @class.key_attributes.should == [:name] + end + + describe "when validating attributes" do + [:name, :provider].each do |param| + it "should have a #{param} parameter" do + @class.attrtype(param).should == :param + end + end + + [:host_aliases, :ensure, :key, :type].each do |property| + it "should have a #{property} property" do + @class.attrtype(property).should == :property + end + end + end + + describe "when validating values" do + + it "should support ssh-dss as a type value" do + proc { @class.new(:name => "foo", :type => "ssh-dss") }.should_not raise_error + end + + it "should support ssh-rsa as a type value" do + proc { @class.new(:name => "whev", :type => "ssh-rsa") }.should_not raise_error + end + + it "should alias :dsa to ssh-dss as a value for type" do + key = @class.new(:name => "whev", :type => :dsa) + key.should(:type).should == :'ssh-dss' + end + + it "should alias :rsa to ssh-rsa as a value for type" do + key = @class.new(:name => "whev", :type => :rsa) + key.should(:type).should == :'ssh-rsa' + end + + it "should not support values other than ssh-dss, ssh-rsa, dsa, rsa for type" do + proc { @class.new(:name => "whev", :type => :'ssh-dsa') }.should raise_error(Puppet::Error) + end + + it "should accept one host_alias" do + proc { @class.new(:name => "foo", :host_aliases => 'foo.bar.tld') }.should_not raise_error + end + + it "should accept multiple host_aliases as an array" do + proc { @class.new(:name => "foo", :host_aliases => ['foo.bar.tld','10.0.9.9']) }.should_not raise_error + end + + it "should not accept spaces in any host_alias" do + proc { @class.new(:name => "foo", :host_aliases => ['foo.bar.tld','foo bar']) }.should raise_error(Puppet::Error) + end + + it "should not accept aliases in the resourcename" do + proc { @class.new(:name => 'host,host.domain,ip') }.should raise_error(Puppet::Error) + end + + end +end diff --git a/spec/unit/type/tidy_spec.rb b/spec/unit/type/tidy_spec.rb index 11edbfbf3..1573ead1b 100755 --- a/spec/unit/type/tidy_spec.rb +++ b/spec/unit/type/tidy_spec.rb @@ -110,7 +110,8 @@ describe tidy do :b => 0, :kb => 1, :mb => 2, - :gb => 3 + :gb => 3, + :tb => 4 } convertors.each do |unit, multiple| diff --git a/spec/unit/util/log_spec.rb b/spec/unit/util/log_spec.rb index 7d96fe190..ea5d59859 100755 --- a/spec/unit/util/log_spec.rb +++ b/spec/unit/util/log_spec.rb @@ -7,7 +7,7 @@ require 'puppet/util/log' describe Puppet::Util::Log do it "should write a given message to the specified destination" do arraydest = [] - Puppet::Util::Log.newdestination(arraydest) + Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(arraydest)) Puppet::Util::Log.new(:level => :notice, :message => "foo") message = arraydest.last.message message.should == "foo" @@ -87,7 +87,7 @@ describe Puppet::Util::Log do it "should flush the log queue when the first destination is specified" do Puppet::Util::Log.close_all Puppet::Util::Log.expects(:flushqueue) - Puppet::Util::Log.newdestination([]) + Puppet::Util::Log.newdestination(:console) end it "should convert the level to a symbol if it's passed in as a string" do diff --git a/spec/unit/util/monkey_patches_spec.rb b/spec/unit/util/monkey_patches_spec.rb index b0f61c808..049ed1044 100644 --- a/spec/unit/util/monkey_patches_spec.rb +++ b/spec/unit/util/monkey_patches_spec.rb @@ -5,3 +5,29 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f require 'puppet/util/monkey_patches' + +describe "yaml deserialization" do + it "should call yaml_initialize when deserializing objects that have that method defined" do + class Puppet::TestYamlInitializeClass + attr_reader :foo + + def yaml_initialize(tag, var) + var.should == {'foo' => 100} + instance_variables.should == [] + @foo = 200 + end + end + + obj = YAML.load("--- !ruby/object:Puppet::TestYamlInitializeClass\n foo: 100") + obj.foo.should == 200 + end + + it "should not call yaml_initialize if not defined" do + class Puppet::TestYamlNonInitializeClass + attr_reader :foo + end + + obj = YAML.load("--- !ruby/object:Puppet::TestYamlNonInitializeClass\n foo: 100") + obj.foo.should == 100 + end +end diff --git a/spec/unit/util/pson_spec.rb b/spec/unit/util/pson_spec.rb index d02d28517..474ddafa4 100755 --- a/spec/unit/util/pson_spec.rb +++ b/spec/unit/util/pson_spec.rb @@ -35,4 +35,19 @@ describe Puppet::Util::Pson do bin_string = (1..20000).collect { |i| ((17*i+13*i*i) % 255).chr }.join PSON.parse(%Q{{ "type": "foo", "data": #{bin_string.to_pson} }})["data"].should == bin_string end + + it "should be able to handle UTF8 that isn't a real unicode character" do + s = ["\355\274\267"] + PSON.parse( [s].to_pson ).should == [s] + end + + it "should be able to handle UTF8 for \\xFF" do + s = ["\xc3\xbf"] + PSON.parse( [s].to_pson ).should == [s] + end + + it "should be able to handle invalid UTF8 bytes" do + s = ["\xc3\xc3"] + PSON.parse( [s].to_pson ).should == [s] + end end diff --git a/spec/unit/util/rdoc/parser_spec.rb b/spec/unit/util/rdoc/parser_spec.rb index 28c33c295..04713f293 100755 --- a/spec/unit/util/rdoc/parser_spec.rb +++ b/spec/unit/util/rdoc/parser_spec.rb @@ -20,7 +20,7 @@ describe RDoc::Parser do @parser.stubs(:scan_top_level) parser = stub 'parser' Puppet::Parser::Parser.stubs(:new).returns(parser) - parser.expects(:parse) + parser.expects(:parse).returns(Puppet::Parser::AST::Hostclass.new('')) parser.expects(:file=).with("module/manifests/init.pp") @parser.scan @@ -29,6 +29,7 @@ describe RDoc::Parser do it "should scan the ast for Puppet files" do parser = stub_everything 'parser' Puppet::Parser::Parser.stubs(:new).returns(parser) + parser.expects(:parse).returns(Puppet::Parser::AST::Hostclass.new('')) @parser.expects(:scan_top_level) @@ -38,6 +39,7 @@ describe RDoc::Parser do it "should return a PuppetTopLevel to RDoc" do parser = stub_everything 'parser' Puppet::Parser::Parser.stubs(:new).returns(parser) + parser.expects(:parse).returns(Puppet::Parser::AST::Hostclass.new('')) @parser.expects(:scan_top_level) @@ -47,8 +49,8 @@ describe RDoc::Parser do describe "when scanning top level entities" do before :each do - @resource_type_collection = stub_everything 'resource_type_collection' - @parser.ast = @resource_type_collection + @resource_type_collection = resource_type_collection = stub_everything('resource_type_collection') + @parser.instance_eval { @known_resource_types = resource_type_collection } @parser.stubs(:split_module).returns("module") @topcontainer = stub_everything 'topcontainer' @@ -141,8 +143,8 @@ describe RDoc::Parser do @definition = stub_everything 'definition', :file => "module/manifests/init.pp", :type => :definition, :name => "mydef" @node = stub_everything 'node', :file => "module/manifests/init.pp", :type => :node, :name => "mynode" - @resource_type_collection = Puppet::Resource::TypeCollection.new("env") - @parser.ast = @resource_type_collection + @resource_type_collection = resource_type_collection = Puppet::Resource::TypeCollection.new("env") + @parser.instance_eval { @known_resource_types = resource_type_collection } @container = stub_everything 'container' end @@ -437,9 +439,13 @@ describe RDoc::Parser do @class = stub_everything 'class' @stmt = Puppet::Parser::AST::Resource.new( :type => "File", - :title => "myfile", - :doc => 'mydoc', - :parameters => Puppet::Parser::AST::ASTArray.new(:children => []) + :instances => Puppet::Parser::AST::ASTArray.new(:children => [ + Puppet::Parser::AST::ResourceInstance.new( + :title => Puppet::Parser::AST::Name.new(:value => "myfile"), + :parameters => Puppet::Parser::AST::ASTArray.new(:children => []) + ) + ]), + :doc => 'mydoc' ) @code = stub_everything 'code' diff --git a/spec/unit/util/zaml_spec.rb b/spec/unit/util/zaml_spec.rb index f2bcefe01..358c6aa11 100755 --- a/spec/unit/util/zaml_spec.rb +++ b/spec/unit/util/zaml_spec.rb @@ -35,5 +35,29 @@ describe "Pure ruby yaml implementation" do lambda { YAML.load(o.to_yaml) }.should_not raise_error end } -end + it "should emit proper labels and backreferences for common objects" do + # Note: this test makes assumptions about the names ZAML chooses + # for labels. + x = [1, 2] + y = [3, 4] + z = [x, y, x, y] + z.to_yaml.should == "--- \n - &id001\n - 1\n - 2\n - &id002\n - 3\n - 4\n - *id001\n - *id002" + z2 = YAML.load(z.to_yaml) + z2.should == z + z2[0].should equal(z2[2]) + z2[1].should equal(z2[3]) + end + + it "should emit proper labels and backreferences for recursive objects" do + x = [1, 2] + x << x + x.to_yaml.should == "--- &id001\n \n - 1\n - 2\n - *id001" + x2 = YAML.load(x.to_yaml) + x2.should be_a(Array) + x2.length.should == 3 + x2[0].should == 1 + x2[1].should == 2 + x2[2].should equal(x2) + end +end |