diff options
Diffstat (limited to 'spec')
22 files changed, 602 insertions, 237 deletions
diff --git a/spec/integration/indirector/rest.rb b/spec/integration/indirector/rest.rb index 859648f7d..584fedde0 100755 --- a/spec/integration/indirector/rest.rb +++ b/spec/integration/indirector/rest.rb @@ -29,8 +29,6 @@ end class Puppet::TestIndirectedFoo::Rest < Puppet::Indirector::REST end -# This way the retrieval of the class by name works. -Puppet::Indirector::Terminus.register_terminus_class(Puppet::TestIndirectedFoo::Rest) describe Puppet::Indirector::REST do before do @@ -65,18 +63,11 @@ describe Puppet::Indirector::REST do ca = Puppet::SSL::CertificateAuthority.new ca.generate(Puppet[:certname]) unless Puppet::SSL::Certificate.find(Puppet[:certname]) - + @params = { :address => "127.0.0.1", :port => 34343, :handlers => [ :test_indirected_foo ], :xmlrpc_handlers => [ :status ] } @server = Puppet::Network::Server.new(@params) @server.listen end - - after do - @server.unlisten - @tmpfile.delete - Puppet.settings.clear - Puppet::Util::Cacher.invalidate - end describe "when finding a model instance over REST" do describe "when a matching model instance can be found" do @@ -87,7 +78,6 @@ describe Puppet::Indirector::REST do end it "should not fail" do - Puppet::TestIndirectedFoo.find('bar') lambda { Puppet::TestIndirectedFoo.find('bar') }.should_not raise_error end @@ -151,7 +141,15 @@ describe Puppet::Indirector::REST do end it 'should return the instance of the model class associated with the provided lookup key' do - Puppet::TestIndirectedFoo.search('bar').collect{ |x| x.value }.should == @model_instances.collect{ |x| x.value } + Puppet::TestIndirectedFoo.search('bar').collect { |i| i.value }.should == @model_instances.collect { |i| i.value } + end + + it 'should set a version timestamp on model instances' do + pending("Luke looking at why this version magic might not be working") do + Puppet::TestIndirectedFoo.search('bar').each do |result| + result.version.should_not be_nil + end + end end end @@ -264,6 +262,10 @@ describe Puppet::Indirector::REST do end end end + + after :each do + @server.unlisten + end end describe "when using mongrel" do @@ -283,7 +285,7 @@ describe Puppet::Indirector::REST do @server.listen end - after :each do + after do @server.unlisten end @@ -359,7 +361,7 @@ describe Puppet::Indirector::REST do end it 'should return the instance of the model class associated with the provided lookup key' do - Puppet::TestIndirectedFoo.search('bar').collect{ |x| x.value }.should == @model_instances.collect{ |x| x.value } + Puppet::TestIndirectedFoo.search('bar').collect { |i| i.value }.should == @model_instances.collect { |i| i.value } end it 'should set an expiration on model instances' do @@ -438,6 +440,9 @@ describe Puppet::Indirector::REST do @instance = Puppet::TestIndirectedFoo.new(42) @mock_model = stub('faked model', :from_yaml => @instance) Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:model).returns(@mock_model) + + # LAK:NOTE This stub is necessary to prevent the REST call from calling + # REST.save again, thus producing painful infinite recursion. Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).returns(@instance) end diff --git a/spec/integration/network/server/mongrel.rb b/spec/integration/network/server/mongrel.rb index 08fd49b17..180fdf7ad 100755 --- a/spec/integration/network/server/mongrel.rb +++ b/spec/integration/network/server/mongrel.rb @@ -1,46 +1,48 @@ +#!/usr/bin/env ruby + require File.dirname(__FILE__) + '/../../../spec_helper' require 'puppet/network/server' require 'socket' describe Puppet::Network::Server do - describe "when using mongrel" do - confine "Mongrel is not available" => Puppet.features.mongrel? - - before :each do - Puppet[:servertype] = 'mongrel' - @params = { :address => "127.0.0.1", :port => 34346, :handlers => [ :node ], :xmlrpc_handlers => [ :status ] } - @server = Puppet::Network::Server.new(@params) - end + describe "when using mongrel" do + confine "Mongrel is not available" => Puppet.features.mongrel? + + before :each do + Puppet[:servertype] = 'mongrel' + @params = { :address => "127.0.0.1", :port => 34346, :handlers => [ :node ] } + @server = Puppet::Network::Server.new(@params) + end - describe "before listening" do - it "should not be reachable at the specified address and port" do - lambda { TCPSocket.new('127.0.0.1', 34346) }.should raise_error(Errno::ECONNREFUSED) - end - end + describe "before listening" do + it "should not be reachable at the specified address and port" do + lambda { TCPSocket.new('127.0.0.1', 34346) }.should raise_error(Errno::ECONNREFUSED) + end + end - describe "when listening" do - it "should be reachable on the specified address and port" do - @server.listen - lambda { TCPSocket.new('127.0.0.1', 34346) }.should_not raise_error - end + describe "when listening" do + it "should be reachable on the specified address and port" do + @server.listen + lambda { TCPSocket.new('127.0.0.1', 34346) }.should_not raise_error + end - it "should not allow multiple servers to listen on the same address and port" do - @server.listen - @server2 = Puppet::Network::Server.new(@params) - lambda { @server2.listen }.should raise_error - end - end - - describe "after unlistening" do - it "should not be reachable on the port and address assigned" do - @server.listen - @server.unlisten - lambda { TCPSocket.new('127.0.0.1', 34346) }.should raise_error(Errno::ECONNREFUSED) - end + it "should not allow multiple servers to listen on the same address and port" do + @server.listen + @server2 = Puppet::Network::Server.new(@params) + lambda { @server2.listen }.should raise_error + end + end + + describe "after unlistening" do + it "should not be reachable on the port and address assigned" do + @server.listen + @server.unlisten + lambda { TCPSocket.new('127.0.0.1', 34346) }.should raise_error(Errno::ECONNREFUSED) + end + end + + after :each do + @server.unlisten if @server.listening? + end end - - after :each do - @server.unlisten if @server.listening? - end - end end diff --git a/spec/integration/network/server/webrick.rb b/spec/integration/network/server/webrick.rb index 0e66ee955..e74920782 100755 --- a/spec/integration/network/server/webrick.rb +++ b/spec/integration/network/server/webrick.rb @@ -41,13 +41,13 @@ describe Puppet::Network::Server do describe "when listening" do it "should be reachable on the specified address and port" do - @server = Puppet::Network::Server.new(@params.merge(:port => 34343)) + @server = Puppet::Network::Server.new(@params.merge(:port => 34343)) @server.listen - lambda { TCPSocket.new('127.0.0.1', 34343) }.should_not raise_error + lambda { TCPSocket.new('127.0.0.1', 34343) }.should_not raise_error end it "should not allow multiple servers to listen on the same address and port" do - @server = Puppet::Network::Server.new(@params.merge(:port => 34343)) + @server = Puppet::Network::Server.new(@params.merge(:port => 34343)) @server.listen @server2 = Puppet::Network::Server.new(@params.merge(:port => 34343)) lambda { @server2.listen }.should raise_error diff --git a/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb b/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb index e2f3d4728..0b4a5abdb 100644 --- a/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb +++ b/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb @@ -1,7 +1,7 @@ dir = File.expand_path(File.dirname(__FILE__)) [ "#{dir}/../../lib", "#{dir}/../../test/lib"].each do |dir| - fulldir = File.expand_path(dir) - $LOAD_PATH.unshift(fulldir) unless $LOAD_PATH.include?(fulldir) + fulldir = File.expand_path(dir) + $LOAD_PATH.unshift(fulldir) unless $LOAD_PATH.include?(fulldir) end require 'spec' @@ -9,35 +9,35 @@ require 'puppettest' require 'puppettest/runnable_test' module Spec - module Runner - class ExampleGroupRunner - def run - prepare - success = true - example_groups.each do |example_group| - next unless example_group.runnable? - success = success & example_group.run + module Runner + class ExampleGroupRunner + def run + prepare + success = true + example_groups.each do |example_group| + next unless example_group.runnable? + success = success & example_group.run + end + return success + ensure + finish + end end - return success - ensure - finish - end end - end end module Spec - module Example - class ExampleGroup - extend PuppetTest::RunnableTest + module Example + class ExampleGroup + extend PuppetTest::RunnableTest + end end - end end module Test - module Unit - class TestCase - extend PuppetTest::RunnableTest + module Unit + class TestCase + extend PuppetTest::RunnableTest + end end - end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a1999a333..52aed5b62 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -23,7 +23,7 @@ require 'spec' Dir["#{dir}/monkey_patches/*.rb"].map { |file| require file } Spec::Runner.configure do |config| - config.mock_with :mocha + config.mock_with :mocha # config.prepend_before :all do # setup_mocks_for_rspec diff --git a/spec/unit/executables/client/certhandler.rb b/spec/unit/executables/client/certhandler.rb new file mode 100755 index 000000000..3737c9a57 --- /dev/null +++ b/spec/unit/executables/client/certhandler.rb @@ -0,0 +1,88 @@ +#!/usr/bin/env ruby + +Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } + +require 'puppet/executables/client/certhandler' + +cert_handler = Puppet::Executables::Client::CertHandler + +describe cert_handler, "when handling certificates" do + before do + @caclient = mock('caclient') + caclient_class = mock('caclient_class') + caclient_class.stubs(:new).returns(@caclient) + Puppet::Network::Client.stubs(:ca).returns(caclient_class) + end + + it "should return true if the certificate exists" do + @caclient.expects(:read_cert).returns(true) + cert_handler.new(1,true).read_retrieve.should be_true + end + + it "should return false when getting a new cert" do + @caclient.expects(:read_cert).returns(true) + @caclient.stubs(:request_cert).returns(true) + ch = cert_handler.new(1,true) + ch.stubs(:read_cert).returns(false) + ch.read_retrieve.should be_false + end + + describe "when waiting for cert" do + before do + @caclient.stubs(:read_cert).returns false + end + + it "should loop when the cert request does not return a certificate" do + @caclient.stubs(:request_cert).times(2).returns(false).then.returns(true) + ch = cert_handler.new(1,false) + ch.expects(:sleep) + ch.expects(:read_new_cert).returns(true) + ch.read_retrieve + end + + it "should loop when the cert request raises an Error" do + @caclient.stubs(:request_cert).times(2).raises(StandardError, 'Testing').then.returns(true) + ch = cert_handler.new(1,false) + ch.expects(:sleep) + ch.expects(:read_new_cert).returns(true) + ch.read_retrieve + end + + it "should loop when the new cert can't be read" do + @caclient.stubs(:request_cert).returns(true) + ch = cert_handler.new(1,false) + ch.expects(:sleep) + ch.expects(:read_new_cert).times(2).returns(false).then.returns(true) + ch.read_retrieve + end + end + + describe "when in one time mode" do + before do + @caclient.stubs(:read_cert).returns false + end + + it "should exit if the cert request does not return a certificate" do + @caclient.stubs(:request_cert).returns(false) + ch = cert_handler.new(1,true) + ch.expects(:exit).with(1).raises(SystemExit) + lambda { ch.read_retrieve }.should raise_error(SystemExit) + end + + + it "should exit if the cert request raises an exception" do + @caclient.stubs(:request_cert).raises(StandardError, 'Testing') + ch = cert_handler.new(1,true) + ch.expects(:exit).with(23).raises(SystemExit) + lambda { ch.read_retrieve }.should raise_error(SystemExit) + end + + it "should exit if the new cert can't be read" do + @caclient.stubs(:request_cert).returns(true) + @caclient.stubs(:read_cert).returns(false) + ch = cert_handler.new(1,true) + ch.expects(:exit).with(34).raises(SystemExit) + lambda { ch.read_retrieve }.should raise_error(SystemExit) + end + end +end diff --git a/spec/unit/indirector/indirection.rb b/spec/unit/indirector/indirection.rb index e4799d3ff..e52be31e1 100755 --- a/spec/unit/indirector/indirection.rb +++ b/spec/unit/indirector/indirection.rb @@ -6,7 +6,7 @@ require 'puppet/indirector/indirection' describe "Indirection Delegator", :shared => true do it "should create a request object with the appropriate method name and all of the passed arguments" do - request = stub 'request', :options => {} + request = stub 'request', :node => nil @indirection.expects(:request).with(@method, "mystuff", :one => :two).returns request @@ -342,7 +342,7 @@ describe Puppet::Indirector::Indirection do end it "should use a request to save the object to the cache" do - request = stub 'request', :instance => @instance, :options => {} + request = stub 'request', :instance => @instance, :node => nil @indirection.expects(:request).returns request @@ -373,8 +373,8 @@ describe Puppet::Indirector::Indirection do end it "should use a request instance to search in and remove objects from the cache" do - destroy = stub 'destroy_request', :key => "/my/key", :options => {} - find = stub 'destroy_request', :key => "/my/key", :options => {} + destroy = stub 'destroy_request', :key => "/my/key", :node => nil + find = stub 'destroy_request', :key => "/my/key", :node => nil @indirection.expects(:request).with(:destroy, "/my/key").returns destroy @indirection.expects(:request).with(:find, "/my/key").returns find diff --git a/spec/unit/indirector/module_files.rb b/spec/unit/indirector/module_files.rb index 0f6dbb6df..f5b92e1fd 100755 --- a/spec/unit/indirector/module_files.rb +++ b/spec/unit/indirector/module_files.rb @@ -10,24 +10,24 @@ require 'puppet/indirector/module_files' describe Puppet::Indirector::ModuleFiles do - before :each do - Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv")) - Puppet::Indirector::Terminus.stubs(:register_terminus_class) - @model = mock 'model' - @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model - Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection) - - @module_files_class = Class.new(Puppet::Indirector::ModuleFiles) do - def self.to_s - "Testing::Mytype" - end - end - - @module_files = @module_files_class.new - - @uri = "puppetmounts://host/modules/my/local/file" - @module = Puppet::Module.new("mymod", "/module/path") - end + before :each do + Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv")) + Puppet::Indirector::Terminus.stubs(:register_terminus_class) + @model = mock 'model' + @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model + Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection) + + @module_files_class = Class.new(Puppet::Indirector::ModuleFiles) do + def self.to_s + "Testing::Mytype" + end + end + + @module_files = @module_files_class.new + + @uri = "puppetmounts://host/modules/my/local/file" + @module = Puppet::Module.new("mymod", "/module/path") + end describe Puppet::Indirector::ModuleFiles, " when finding files" do diff --git a/spec/unit/indirector/request.rb b/spec/unit/indirector/request.rb index cdb40b181..f7702f821 100755 --- a/spec/unit/indirector/request.rb +++ b/spec/unit/indirector/request.rb @@ -43,6 +43,38 @@ describe Puppet::Indirector::Request do it "should use an empty options hash if nil was provided" do Puppet::Indirector::Request.new(:ind, :method, :key, nil).options.should == {} end + + it "should default to a nil node" do + Puppet::Indirector::Request.new(:ind, :method, :key, nil).node.should be_nil + end + + it "should set its node attribute if provided in the options" do + Puppet::Indirector::Request.new(:ind, :method, :key, :node => "foo.com").node.should == "foo.com" + end + + it "should default to a nil ip" do + Puppet::Indirector::Request.new(:ind, :method, :key, nil).ip.should be_nil + end + + it "should set its ip attribute if provided in the options" do + Puppet::Indirector::Request.new(:ind, :method, :key, :ip => "192.168.0.1").ip.should == "192.168.0.1" + end + + it "should default to being unauthenticated" do + Puppet::Indirector::Request.new(:ind, :method, :key, nil).should_not be_authenticated + end + + it "should set be marked authenticated if configured in the options" do + Puppet::Indirector::Request.new(:ind, :method, :key, :authenticated => "eh").should be_authenticated + end + + it "should keep its options as a hash even if a node is specified" do + Puppet::Indirector::Request.new(:ind, :method, :key, :node => "eh").options.should be_instance_of(Hash) + end + + it "should keep its options as a hash even if another option is specified" do + Puppet::Indirector::Request.new(:ind, :method, :key, :foo => "bar").options.should be_instance_of(Hash) + end end it "should look use the Indirection class to return the appropriate indirection" do diff --git a/spec/unit/network/client.rb b/spec/unit/network/client.rb index e9467aad0..e9467aad0 100644..100755 --- a/spec/unit/network/client.rb +++ b/spec/unit/network/client.rb diff --git a/spec/unit/network/http.rb b/spec/unit/network/http.rb index 79a0a88d4..79a0a88d4 100644..100755 --- a/spec/unit/network/http.rb +++ b/spec/unit/network/http.rb diff --git a/spec/unit/network/http/mongrel.rb b/spec/unit/network/http/mongrel.rb index 1f87fd943..1f87fd943 100644..100755 --- a/spec/unit/network/http/mongrel.rb +++ b/spec/unit/network/http/mongrel.rb diff --git a/spec/unit/network/http/mongrel/rest.rb b/spec/unit/network/http/mongrel/rest.rb index b483bbd46..3df925133 100644..100755 --- a/spec/unit/network/http/mongrel/rest.rb +++ b/spec/unit/network/http/mongrel/rest.rb @@ -1,9 +1,11 @@ +#!/usr/bin/env ruby + require File.dirname(__FILE__) + '/../../../../spec_helper' require 'puppet/network/http' describe Puppet::Network::HTTP::MongrelREST, "when initializing" do confine "Mongrel is not available" => Puppet.features.mongrel? - + before do @mock_mongrel = mock('Mongrel server') @mock_mongrel.stubs(:register) @@ -11,20 +13,20 @@ describe Puppet::Network::HTTP::MongrelREST, "when initializing" do Puppet::Indirector::Indirection.stubs(:model).with(:foo).returns(@mock_model) @params = { :server => @mock_mongrel, :handler => :foo } end - + it "should require access to a Mongrel server" do Proc.new { Puppet::Network::HTTP::MongrelREST.new(@params.delete_if {|k,v| :server == k })}.should raise_error(ArgumentError) end - + it "should require an indirection name" do Proc.new { Puppet::Network::HTTP::MongrelREST.new(@params.delete_if {|k,v| :handler == k })}.should raise_error(ArgumentError) end - + it "should look up the indirection model from the indirection name" do Puppet::Indirector::Indirection.expects(:model).with(:foo).returns(@mock_model) Puppet::Network::HTTP::MongrelREST.new(@params) end - + it "should fail if the indirection is not known" do Puppet::Indirector::Indirection.expects(:model).with(:foo).returns(nil) Proc.new { Puppet::Network::HTTP::MongrelREST.new(@params) }.should raise_error(ArgumentError) @@ -33,7 +35,7 @@ end describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do confine "Mongrel is not available" => Puppet.features.mongrel? - + before do @mock_request = stub('mongrel http request') @mock_head = stub('response head') @@ -45,28 +47,28 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do Puppet::Indirector::Indirection.stubs(:model).with(:foo).returns(@mock_model_class) @handler = Puppet::Network::HTTP::MongrelREST.new(:server => @mock_mongrel, :handler => :foo) end - + def setup_find_request(params = {}) @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET', Mongrel::Const::REQUEST_PATH => '/foo/key', 'QUERY_STRING' => ''}.merge(params)) @mock_model_class.stubs(:find) end - + def setup_search_request(params = {}) @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET', Mongrel::Const::REQUEST_PATH => '/foos', 'QUERY_STRING' => '' }.merge(params)) @mock_model_class.stubs(:search).returns([]) end - + def setup_destroy_request(params = {}) @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'DELETE', Mongrel::Const::REQUEST_PATH => '/foo/key', 'QUERY_STRING' => '' }.merge(params)) @mock_model_class.stubs(:destroy) end - + def setup_save_request(params = {}) @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'PUT', Mongrel::Const::REQUEST_PATH => '/foo', @@ -75,26 +77,26 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do @mock_model_instance = stub('indirected model instance', :save => true) @mock_model_class.stubs(:from_yaml).returns(@mock_model_instance) end - + def setup_bad_request @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'POST', Mongrel::Const::REQUEST_PATH => '/foos'}) end it "should call the model find method if the request represents a singular HTTP GET" do setup_find_request - @mock_model_class.expects(:find).with('key', {}) + @mock_model_class.expects(:find).with { |key, args| key == 'key' } @handler.process(@mock_request, @mock_response) end it "should call the model search method if the request represents a plural HTTP GET" do setup_search_request - @mock_model_class.expects(:search).with({}).returns([]) + @mock_model_class.expects(:search).returns([]) @handler.process(@mock_request, @mock_response) end - + it "should call the model destroy method if the request represents an HTTP DELETE" do setup_destroy_request - @mock_model_class.expects(:destroy).with('key', {}) + @mock_model_class.expects(:destroy).with { |key, args| key == 'key' } @handler.process(@mock_request, @mock_response) end @@ -103,13 +105,13 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do @mock_model_instance.expects(:save) @handler.process(@mock_request, @mock_response) end - + it "should fail if the HTTP method isn't supported" do @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'POST', Mongrel::Const::REQUEST_PATH => '/foo'}) @mock_response.expects(:start).with(404) @handler.process(@mock_request, @mock_response) end - + it "should fail if the request's pluralization is wrong" do @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'DELETE', Mongrel::Const::REQUEST_PATH => '/foos/key'}) @mock_response.expects(:start).with(404) @@ -127,8 +129,74 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do @mock_response.expects(:start).with(404) @handler.process(@mock_request, @mock_response) end - - + + describe "and determining the request parameters", :shared => true do + before do + @mock_request.stubs(:params).returns({}) + end + + it "should include the HTTP request parameters" do + @mock_request.expects(:params).returns('QUERY_STRING' => 'foo=baz&bar=xyzzy') + result = @handler.params(@mock_request) + result["foo"].should == "baz" + result["bar"].should == "xyzzy" + end + + it "should pass the client's ip address to model find" do + @mock_request.stubs(:params).returns("REMOTE_ADDR" => "ipaddress") + @handler.params(@mock_request)[:ip].should == "ipaddress" + end + + it "should use the :ssl_client_header to determine the parameter when looking for the certificate" do + Puppet.settings.stubs(:value).returns "eh" + Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader" + @mock_request.stubs(:params).returns("myheader" => "/CN=host.domain.com") + @handler.params(@mock_request) + end + + it "should retrieve the hostname by matching the certificate parameter" do + Puppet.settings.stubs(:value).returns "eh" + Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader" + @mock_request.stubs(:params).returns("myheader" => "/CN=host.domain.com") + @handler.params(@mock_request)[:node].should == "host.domain.com" + end + + it "should use the :ssl_client_header to determine the parameter for checking whether the host certificate is valid" do + Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader" + Puppet.settings.expects(:value).with(:ssl_client_verify_header).returns "myheader" + @mock_request.stubs(:params).returns("myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com") + @handler.params(@mock_request) + end + + it "should consider the host authenticated if the validity parameter contains 'SUCCESS'" do + Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader" + Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader" + @mock_request.stubs(:params).returns("myheader" => "SUCCESS", "certheader" => "/CN=host.domain.com") + @handler.params(@mock_request)[:authenticated].should be_true + end + + it "should consider the host unauthenticated if the validity parameter does not contain 'SUCCESS'" do + Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader" + Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader" + @mock_request.stubs(:params).returns("myheader" => "whatever", "certheader" => "/CN=host.domain.com") + @handler.params(@mock_request)[:authenticated].should be_false + end + + it "should consider the host unauthenticated if no certificate information is present" do + Puppet.settings.stubs(:value).with(:ssl_client_header).returns "certheader" + Puppet.settings.stubs(:value).with(:ssl_client_verify_header).returns "myheader" + @mock_request.stubs(:params).returns("myheader" => nil, "certheader" => "SUCCESS") + @handler.params(@mock_request)[:authenticated].should be_false + end + + it "should not pass a node name to model method if no certificate information is present" do + Puppet.settings.stubs(:value).returns "eh" + Puppet.settings.expects(:value).with(:ssl_client_header).returns "myheader" + @mock_request.stubs(:params).returns("myheader" => nil) + @handler.params(@mock_request).should_not be_include(:node) + end + end + describe "when finding a model instance" do |variable| it "should fail to find model if key is not specified" do @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET', Mongrel::Const::REQUEST_PATH => '/foo'}) @@ -136,20 +204,21 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do @handler.process(@mock_request, @mock_response) end - it "should pass HTTP request parameters to model find" do + it "should use a common method for determining the request parameters" do setup_find_request('QUERY_STRING' => 'foo=baz&bar=xyzzy') + @handler.expects(:params).returns(:foo => :baz, :bar => :xyzzy) @mock_model_class.expects(:find).with do |key, args| - key == 'key' and args['foo'] == 'baz' and args['bar'] == 'xyzzy' + args[:foo] == :baz and args[:bar] == :xyzzy end @handler.process(@mock_request, @mock_response) end - + it "should generate a 200 response when a model find call succeeds" do setup_find_request @mock_response.expects(:start).with(200) @handler.process(@mock_request, @mock_response) end - + it "should return a serialized object when a model find call succeeds" do setup_find_request @mock_model_instance = stub('model instance') @@ -157,7 +226,7 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do @mock_model_class.stubs(:find).returns(@mock_model_instance) @handler.process(@mock_request, @mock_response) end - + it "should serialize a controller exception when an exception is thrown by find" do setup_find_request @mock_model_class.expects(:find).raises(ArgumentError) @@ -172,7 +241,16 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do @mock_response.expects(:start).with(404) @handler.process(@mock_request, @mock_response) end - + + it "should use a common method for determining the request parameters" do + setup_destroy_request('QUERY_STRING' => 'foo=baz&bar=xyzzy') + @handler.expects(:params).returns(:foo => :baz, :bar => :xyzzy) + @mock_model_class.expects(:destroy).with do |key, args| + args[:foo] == :baz and args[:bar] == :xyzzy + end + @handler.process(@mock_request, @mock_response) + end + it "should pass HTTP request parameters to model destroy" do setup_destroy_request('QUERY_STRING' => 'foo=baz&bar=xyzzy') @mock_model_class.expects(:destroy).with do |key, args| @@ -180,20 +258,20 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do end @handler.process(@mock_request, @mock_response) end - + it "should generate a 200 response when a model destroy call succeeds" do setup_destroy_request @mock_response.expects(:start).with(200) @handler.process(@mock_request, @mock_response) end - + it "should return a serialized success result when a model destroy call succeeds" do setup_destroy_request @mock_model_class.stubs(:destroy).returns(true) @mock_body.expects(:write).with("--- true\n") @handler.process(@mock_request, @mock_response) end - + it "should serialize a controller exception when an exception is thrown by destroy" do setup_destroy_request @mock_model_class.expects(:destroy).raises(ArgumentError) @@ -201,7 +279,7 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do @handler.process(@mock_request, @mock_response) end end - + describe "when saving a model instance" do |variable| it "should fail to save model if data is not specified" do @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'PUT', Mongrel::Const::REQUEST_PATH => '/foo'}) @@ -209,20 +287,29 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do @mock_response.expects(:start).with(404) @handler.process(@mock_request, @mock_response) end - + + it "should use a common method for determining the request parameters" do + setup_save_request('QUERY_STRING' => 'foo=baz&bar=xyzzy') + @handler.expects(:params).returns(:foo => :baz, :bar => :xyzzy) + @mock_model_instance.expects(:save).with do |args| + args[:foo] == :baz and args[:bar] == :xyzzy + end + @handler.process(@mock_request, @mock_response) + end + it "should generate a 200 response when a model save call succeeds" do setup_save_request @mock_response.expects(:start).with(200) @handler.process(@mock_request, @mock_response) end - + it "should return a serialized object when a model save call succeeds" do setup_save_request @mock_model_instance.stubs(:save).returns(@mock_model_instance) @mock_model_instance.expects(:to_yaml).returns('foo') @handler.process(@mock_request, @mock_response) end - + it "should serialize a controller exception when an exception is thrown by save" do setup_save_request @mock_model_instance.expects(:save).raises(ArgumentError) @@ -230,8 +317,17 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do @handler.process(@mock_request, @mock_response) end end - + describe "when searching for model instances" do |variable| + it "should use a common method for determining the request parameters" do + setup_search_request('QUERY_STRING' => 'foo=baz&bar=xyzzy') + @handler.expects(:params).returns(:foo => :baz, :bar => :xyzzy) + @mock_model_class.expects(:search).with do |args| + args[:foo] == :baz and args[:bar] == :xyzzy + end + @handler.process(@mock_request, @mock_response) + end + it "should pass HTTP request parameters to model search" do setup_search_request('QUERY_STRING' => 'foo=baz&bar=xyzzy') @mock_model_class.expects(:search).with do |args| @@ -245,7 +341,7 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do @mock_response.expects(:start).with(200) @handler.process(@mock_request, @mock_response) end - + it "should return a list of serialized objects when a model search call succeeds" do setup_search_request mock_matches = [1..5].collect {|i| mock("model instance #{i}", :to_yaml => "model instance #{i}") } @@ -260,7 +356,7 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do @handler.process(@mock_request, @mock_response) end end - + it "should serialize a controller exception if the request fails" do setup_bad_request @mock_response.expects(:start).with(404) diff --git a/spec/unit/network/http/mongrel/xmlrpc.rb b/spec/unit/network/http/mongrel/xmlrpc.rb index e69de29bb..e69de29bb 100644..100755 --- a/spec/unit/network/http/mongrel/xmlrpc.rb +++ b/spec/unit/network/http/mongrel/xmlrpc.rb diff --git a/spec/unit/network/http/webrick.rb b/spec/unit/network/http/webrick.rb index 6d006992c..e3c3b81c0 100644..100755 --- a/spec/unit/network/http/webrick.rb +++ b/spec/unit/network/http/webrick.rb @@ -162,7 +162,7 @@ describe Puppet::Network::HTTP::WEBrick, "when looking up the class to handle a end it "should accept a protocol" do - lambda { Puppet::Network::HTTP::WEBrick.class_for_protocol("bob") }.should_not raise_error(ArgumentError) + lambda { Puppet::Network::HTTP::WEBrick.class_for_protocol("bob") }.should_not raise_error(ArgumentError) end it "should use a WEBrick + REST class when a REST protocol is specified" do diff --git a/spec/unit/network/http/webrick/rest.rb b/spec/unit/network/http/webrick/rest.rb index b7bd33880..45e5f0bd2 100644..100755 --- a/spec/unit/network/http/webrick/rest.rb +++ b/spec/unit/network/http/webrick/rest.rb @@ -1,3 +1,5 @@ +#!/usr/bin/env ruby + require File.dirname(__FILE__) + '/../../../../spec_helper' require 'puppet/network/http' @@ -8,23 +10,23 @@ describe Puppet::Network::HTTP::WEBrickREST, "when initializing" do Puppet::Indirector::Indirection.stubs(:model).returns(@mock_model) @params = [ @mock_webrick, :foo ] end - + it "should require access to a WEBrick server" do Proc.new { @params[0] = nil Puppet::Network::HTTP::WEBrickREST.new(*@params) }.should raise_error(ArgumentError) end - + it "should require an indirection name" do Proc.new { Puppet::Network::HTTP::WEBrickREST.new(@params.first) }.should raise_error(ArgumentError) end - + it "should look up the indirection model from the indirection name" do Puppet::Indirector::Indirection.expects(:model).returns(@mock_model) Puppet::Network::HTTP::WEBrickREST.new(*@params) end - + it "should fail if the indirection is not known" do Puppet::Indirector::Indirection.expects(:model).returns(nil) Proc.new { Puppet::Network::HTTP::WEBrickREST.new(*@params) }.should raise_error(ArgumentError) @@ -33,7 +35,7 @@ end describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do before do - @mock_request = stub('webrick http request', :query => {}) + @mock_request = stub('webrick http request', :query => {}, :peeraddr => %w{eh boo host ip}, :client_cert => nil) @mock_response = stub('webrick http response', :status= => true, :body= => true) @mock_model_class = stub('indirected model class') @mock_webrick = stub('webrick http server', :mount => true, :[] => {}) @@ -46,19 +48,19 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do @mock_request.stubs(:path).returns('/foo/key') @mock_model_class.stubs(:find) end - + def setup_search_request @mock_request.stubs(:request_method).returns('GET') @mock_request.stubs(:path).returns('/foos') @mock_model_class.stubs(:search).returns([]) end - + def setup_destroy_request @mock_request.stubs(:request_method).returns('DELETE') @mock_request.stubs(:path).returns('/foo/key') @mock_model_class.stubs(:destroy) end - + def setup_save_request @mock_request.stubs(:request_method).returns('PUT') @mock_request.stubs(:path).returns('/foo') @@ -66,44 +68,48 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do @mock_model_instance = stub('indirected model instance', :save => true) @mock_model_class.stubs(:from_yaml).returns(@mock_model_instance) end - + def setup_bad_request @mock_request.stubs(:request_method).returns('POST') @mock_request.stubs(:path).returns('/foos') end - - + + it "should delegate its :service method to its :process method" do + @handler.expects(:process).with(@mock_request, @mock_response).returns "stuff" + @handler.service(@mock_request, @mock_response).should == "stuff" + end + it "should call the model find method if the request represents a singular HTTP GET" do setup_find_request - @mock_model_class.expects(:find).with('key', {}) - @handler.service(@mock_request, @mock_response) + @mock_model_class.expects(:find).with { |key, args| key == 'key' } + @handler.process(@mock_request, @mock_response) end it "should call the model search method if the request represents a plural HTTP GET" do setup_search_request @mock_model_class.expects(:search).returns([]) - @handler.service(@mock_request, @mock_response) + @handler.process(@mock_request, @mock_response) end - + it "should call the model destroy method if the request represents an HTTP DELETE" do setup_destroy_request - @mock_model_class.expects(:destroy).with('key', {}) - @handler.service(@mock_request, @mock_response) + @mock_model_class.expects(:destroy).with { |key, args| key == 'key' } + @handler.process(@mock_request, @mock_response) end it "should call the model save method if the request represents an HTTP PUT" do setup_save_request @mock_model_instance.expects(:save) - @handler.service(@mock_request, @mock_response) + @handler.process(@mock_request, @mock_response) end - + it "should fail if the HTTP method isn't supported" do @mock_request.stubs(:request_method).returns('POST') @mock_request.stubs(:path).returns('/foo') @mock_response.expects(:status=).with(404) @handler.process(@mock_request, @mock_response) end - + it "should fail if delete request's pluralization is wrong" do @mock_request.stubs(:request_method).returns('DELETE') @mock_request.stubs(:path).returns('/foos/key') @@ -125,6 +131,42 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do @handler.process(@mock_request, @mock_response) end + describe "and determining the request parameters" do + it "should include the HTTP request parameters" do + @mock_request.stubs(:query).returns(:foo => :baz, :bar => :xyzzy) + result = @handler.params(@mock_request) + result[:foo].should == :baz + result[:bar].should == :xyzzy + end + + it "should pass the client's ip address to model find" do + @mock_request.stubs(:peeraddr).returns(%w{noidea dunno hostname ipaddress}) + @handler.params(@mock_request)[:ip].should == "ipaddress" + end + + it "should set 'authenticated' to true if a certificate is present" do + cert = stub 'cert', :subject => [%w{CN host.domain.com}] + @mock_request.stubs(:client_cert).returns cert + @handler.params(@mock_request)[:authenticated].should be_true + end + + it "should set 'authenticated' to false if no certificate is present" do + @mock_request.stubs(:client_cert).returns nil + @handler.params(@mock_request)[:authenticated].should be_false + end + + it "should pass the client's certificate name to model method if a certificate is present" do + cert = stub 'cert', :subject => [%w{CN host.domain.com}] + @mock_request.stubs(:client_cert).returns cert + @handler.params(@mock_request)[:node].should == "host.domain.com" + end + + it "should not pass a node name to model method if no certificate is present" do + @mock_request.stubs(:client_cert).returns nil + @handler.params(@mock_request).should_not be_include(:node) + end + end + describe "when finding a model instance" do |variable| it "should fail to find model if key is not specified" do @mock_request.stubs(:request_method).returns('GET') @@ -132,22 +174,22 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do @mock_response.expects(:status=).with(404) @handler.process(@mock_request, @mock_response) end - - it "should pass HTTP request parameters to model find" do + + it "should use a common method for determining the request parameters" do setup_find_request - @mock_request.stubs(:query).returns(:foo => :baz, :bar => :xyzzy) + @handler.stubs(:params).returns(:foo => :baz, :bar => :xyzzy) @mock_model_class.expects(:find).with do |key, args| - key == 'key' and args[:foo] == :baz and args[:bar] == :xyzzy + args[:foo] == :baz and args[:bar] == :xyzzy end - @handler.service(@mock_request, @mock_response) + @handler.process(@mock_request, @mock_response) end - + it "should generate a 200 response when a model find call succeeds" do setup_find_request @mock_response.expects(:status=).with(200) @handler.process(@mock_request, @mock_response) end - + it "should return a serialized object when a model find call succeeds" do setup_find_request @mock_model_instance = stub('model instance') @@ -155,7 +197,7 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do @mock_model_class.stubs(:find).returns(@mock_model_instance) @handler.process(@mock_request, @mock_response) end - + it "should serialize a controller exception when an exception is thrown by find" do setup_find_request @mock_model_class.expects(:find).raises(ArgumentError) @@ -163,7 +205,7 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do @handler.process(@mock_request, @mock_response) end end - + describe "when destroying a model instance" do |variable| it "should fail to destroy model if key is not specified" do @mock_request.stubs(:request_method).returns('DELETE') @@ -171,37 +213,37 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do @mock_response.expects(:status=).with(404) @handler.process(@mock_request, @mock_response) end - - it "should pass HTTP request parameters to model destroy" do + + it "should use a common method for determining the request parameters" do setup_destroy_request - @mock_request.stubs(:query).returns(:foo => :baz, :bar => :xyzzy) + @handler.stubs(:params).returns(:foo => :baz, :bar => :xyzzy) @mock_model_class.expects(:destroy).with do |key, args| - key == 'key' and args[:foo] == :baz and args[:bar] == :xyzzy + args[:foo] == :baz and args[:bar] == :xyzzy end - @handler.service(@mock_request, @mock_response) + @handler.process(@mock_request, @mock_response) end - + it "should generate a 200 response when a model destroy call succeeds" do setup_destroy_request @mock_response.expects(:status=).with(200) @handler.process(@mock_request, @mock_response) end - + it "should return a serialized success result when a model destroy call succeeds" do setup_destroy_request @mock_model_class.stubs(:destroy).returns(true) @mock_response.expects(:body=).with("--- true\n") @handler.process(@mock_request, @mock_response) end - - it "should serialize a controller exception when an exception is thrown by search" do - setup_search_request - @mock_model_class.expects(:search).raises(ArgumentError) + + it "should serialize a controller exception when an exception is thrown by destroy" do + setup_destroy_request + @mock_model_class.expects(:destroy).raises(ArgumentError) @mock_response.expects(:status=).with(404) - @handler.process(@mock_request, @mock_response) - end + @handler.process(@mock_request, @mock_response) + end end - + describe "when saving a model instance" do it "should fail to save model if data is not specified" do @mock_request.stubs(:request_method).returns('PUT') @@ -210,20 +252,29 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do @mock_response.expects(:status=).with(404) @handler.process(@mock_request, @mock_response) end - + + it "should use a common method for determining the request parameters" do + setup_save_request + @handler.stubs(:params).returns(:foo => :baz, :bar => :xyzzy) + @mock_model_instance.expects(:save).with do |args| + args[:foo] == :baz and args[:bar] == :xyzzy + end + @handler.process(@mock_request, @mock_response) + end + it "should generate a 200 response when a model save call succeeds" do setup_save_request @mock_response.expects(:status=).with(200) @handler.process(@mock_request, @mock_response) end - + it "should return a serialized object when a model save call succeeds" do setup_save_request @mock_model_instance.stubs(:save).returns(@mock_model_instance) @mock_model_instance.expects(:to_yaml).returns('foo') @handler.process(@mock_request, @mock_response) end - + it "should serialize a controller exception when an exception is thrown by save" do setup_save_request @mock_model_instance.expects(:save).raises(ArgumentError) @@ -231,15 +282,15 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do @handler.process(@mock_request, @mock_response) end end - + describe "when searching for model instances" do - it "should pass HTTP request parameters to model search" do + it "should use a common method for determining the request parameters" do setup_search_request - @mock_request.stubs(:query).returns(:foo => :baz, :bar => :xyzzy) + @handler.stubs(:params).returns(:foo => :baz, :bar => :xyzzy) @mock_model_class.expects(:search).with do |args| args[:foo] == :baz and args[:bar] == :xyzzy - end.returns([]) - @handler.service(@mock_request, @mock_response) + end + @handler.process(@mock_request, @mock_response) end it "should generate a 200 response when a model search call succeeds" do @@ -247,20 +298,20 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do @mock_response.expects(:status=).with(200) @handler.process(@mock_request, @mock_response) end - + it "should return a list of serialized objects when a model search call succeeds" do setup_search_request mock_matches = [1..5].collect {|i| mock("model instance #{i}", :to_yaml => "model instance #{i}") } @mock_model_class.stubs(:search).returns(mock_matches) @handler.process(@mock_request, @mock_response) end - - it "should serialize a controller exception when an exception is thrown by destroy" do - setup_destroy_request - @mock_model_class.expects(:destroy).raises(ArgumentError) + + it "should serialize a controller exception when an exception is thrown by search" do + setup_search_request + @mock_model_class.expects(:search).raises(ArgumentError) @mock_response.expects(:status=).with(404) - @handler.process(@mock_request, @mock_response) - end + @handler.process(@mock_request, @mock_response) + end end it "should serialize a controller exception if the request fails" do diff --git a/spec/unit/network/http/webrick/xmlrpc.rb b/spec/unit/network/http/webrick/xmlrpc.rb index e69de29bb..e69de29bb 100644..100755 --- a/spec/unit/network/http/webrick/xmlrpc.rb +++ b/spec/unit/network/http/webrick/xmlrpc.rb diff --git a/spec/unit/network/server.rb b/spec/unit/network/server.rb index 5332964c6..5332964c6 100644..100755 --- a/spec/unit/network/server.rb +++ b/spec/unit/network/server.rb diff --git a/spec/unit/node.rb b/spec/unit/node.rb index 08afc5183..4a41dadf9 100755 --- a/spec/unit/node.rb +++ b/spec/unit/node.rb @@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../spec_helper' -describe Puppet::Node, " when initializing" do +describe Puppet::Node, "when initializing" do before do @node = Puppet::Node.new("testnode") end @@ -61,7 +61,7 @@ describe Puppet::Node, " when initializing" do end end -describe Puppet::Node, " when returning the environment" do +describe Puppet::Node, "when returning the environment" do before do Puppet.settings.stubs(:value).with(:environments).returns("one,two") Puppet.settings.stubs(:value).with(:environment).returns("one") @@ -90,7 +90,7 @@ describe Puppet::Node, " when returning the environment" do end end -describe Puppet::Node, " when merging facts" do +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")) @@ -131,7 +131,7 @@ describe Puppet::Node, " when merging facts" do end end -describe Puppet::Node, " when indirecting" do +describe Puppet::Node, "when indirecting" do it "should redirect to the indirection" do @indirection = stub 'indirection', :name => :node Puppet::Node.stubs(:indirection).returns(@indirection) @@ -159,68 +159,92 @@ describe Puppet::Node do it "should provide a method for noting that the node has connected" end -describe Puppet::Node, " when searching for nodes" do +describe Puppet::Node, "when generating the list of names to search through" do before do - @searcher = Puppet::Node @facts = Puppet::Node::Facts.new("foo", "hostname" => "yay", "domain" => "domain.com") @node = Puppet::Node.new("foo") - Puppet::Node::Facts.stubs(:find).with("foo").returns(@facts) + + Puppet::Node.stubs(:node_facts).returns @facts.values end - it "should return the first node found using the generated list of names" do - @searcher.expects(:find).with("foo").returns(nil) - @searcher.expects(:find).with("yay.domain.com").returns(@node) - @searcher.find_by_any_name("foo").should equal(@node) + it "should return an array of names" do + Puppet::Node.node_names("foo").should be_instance_of(Array) end - it "should search for the node by its key first" do - names = [] - @searcher.expects(:find).with do |name| - names << name - names == %w{foo} - end.returns(@node) - @searcher.find_by_any_name("foo").should equal(@node) + it "should have the node's fqdn as the second name" do + Puppet::Node.node_names("foo.domain.com")[1].should == "yay.domain.com" end - it "should search for the rest of the names inversely by length" do - names = [] - @facts.values["fqdn"] = "longer.than.the.normal.fqdn.com" - @searcher.stubs(:find).with do |name| - names << name + it "should set the fqdn to the node's 'fqdn' fact if it is available" do + @facts.values["fqdn"] = "boo.domain.com" + Puppet::Node.node_names("foo")[1].should == "boo.domain.com" + end + + it "should set the fqdn to the node's hostname and domain if no fqdn is available" do + Puppet::Node.node_names("foo")[1].should == "yay.domain.com" + end + + it "should contain an entry for each name available by stripping a segment of the fqdn" do + @facts.values["fqdn"] = "foo.deep.sub.domain.com" + Puppet::Node.node_names("foo")[2].should == "foo.deep.sub.domain" + Puppet::Node.node_names("foo")[3].should == "foo.deep.sub" + end + + describe "and :node_name is set to 'cert'" do + before do + Puppet.settings.stubs(:value).with(:node_name).returns "cert" end - @searcher.find_by_any_name("foo") - # Strip off the key - names.shift - # And the 'default' - names.pop + it "should use the passed-in key as the first value" do + Puppet::Node.node_names("foo")[0].should == "foo" + end + end - length = 100 - names.each do |name| - (name.length < length).should be_true - length = name.length + describe "and :node_name is set to 'facter'" do + before do + Puppet.settings.stubs(:value).with(:node_name).returns "facter" end + + it "should use the node's 'hostname' fact as the first value" do + Puppet::Node.node_names("foo")[0].should == "yay" + end + end +end + +describe Puppet::Node, "when searching for nodes" do + before do + @facts = Puppet::Node::Facts.new("foo", "hostname" => "yay", "domain" => "domain.com") + @node = Puppet::Node.new("foo") + Puppet::Node::Facts.stubs(:find).with("foo").returns(@facts) + end + + it "should use the 'node_names' method to get its list of names to search" do + Puppet::Node.expects(:node_names).with{ |*args| args[0] == "foo" }.returns %w{a b} + Puppet::Node.stubs(:find) + Puppet::Node.find_by_any_name("foo") + end + + it "should return the first node found using the generated list of names" do + Puppet::Node.expects(:node_names).returns %w{a b} + Puppet::Node.expects(:find).with("a").returns(nil) + Puppet::Node.expects(:find).with("b").returns(@node) + Puppet::Node.find_by_any_name("foo").should equal(@node) end it "should attempt to find a default node if no names are found" do names = [] - @searcher.stubs(:find).with do |name| + Puppet::Node.stubs(:find).with do |name| names << name end.returns(nil) - @searcher.find_by_any_name("foo") + Puppet::Node.find_by_any_name("foo") names[-1].should == "default" end - it "should flush the node cache using the :filetimeout parameter" do - node2 = Puppet::Node.new("foo2") - Puppet[:filetimeout] = -1 - # I couldn't get this to work with :expects - @searcher.stubs(:find).returns(@node, node2).then.raises(ArgumentError) - @searcher.find_by_any_name("foo").should equal(@node) - @searcher.find_by_any_name("foo").should equal(node2) - end + it "should set the node name to the provided key" do + Puppet::Node.stubs(:node_names).returns %w{a b} + Puppet::Node.stubs(:find).returns @node - after do - Puppet.settings.clear + @node.expects(:name=).with("foo") + Puppet::Node.find_by_any_name("foo") end end diff --git a/spec/unit/parser/collector.rb b/spec/unit/parser/collector.rb index e1ceb23ed..2dfae6786 100755 --- a/spec/unit/parser/collector.rb +++ b/spec/unit/parser/collector.rb @@ -204,6 +204,8 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do @equery = "test = true" @vquery = proc { |r| true } + Puppet.settings.stubs(:value).with(:storeconfigs).returns true + @collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, :exported) end @@ -217,6 +219,11 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do end end + it "should just return false if :storeconfigs is not enabled" do + Puppet.settings.expects(:value).with(:storeconfigs).returns false + @collector.evaluate.should be_false + end + it "should use initialize the Rails support if ActiveRecord is not connected" do @compiler.stubs(:resources).returns([]) ActiveRecord::Base.expects(:connected?).returns(false) @@ -375,6 +382,8 @@ describe Puppet::Parser::Collector, "when building its ActiveRecord query for co Puppet::Rails.stubs(:init) Puppet::Rails::Host.stubs(:find_by_name).returns(nil) Puppet::Rails::Resource.stubs(:find).returns([]) + + Puppet.settings.stubs(:value).with(:storeconfigs).returns true end it "should exclude all resources from the host if ActiveRecord contains information for this host" do diff --git a/spec/unit/util/resource_template.rb b/spec/unit/util/resource_template.rb new file mode 100755 index 000000000..b4d529e5d --- /dev/null +++ b/spec/unit/util/resource_template.rb @@ -0,0 +1,58 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../spec_helper' + +require 'puppet/util/resource_template' + +describe Puppet::Util::ResourceTemplate do + describe "when initializing" do + it "should fail if the template does not exist" do + FileTest.expects(:exist?).with("/my/template").returns false + lambda { Puppet::Util::ResourceTemplate.new("/my/template", mock('resource')) }.should raise_error(ArgumentError) + end + + it "should not create the ERB template" do + ERB.expects(:new).never + FileTest.expects(:exist?).with("/my/template").returns true + Puppet::Util::ResourceTemplate.new("/my/template", mock('resource')) + end + end + + describe "when evaluating" do + before do + FileTest.stubs(:exist?).returns true + File.stubs(:read).returns "eh" + + @template = stub 'template', :result => nil + ERB.stubs(:new).returns @template + + @resource = mock 'resource' + @wrapper = Puppet::Util::ResourceTemplate.new("/my/template", @resource) + end + + it "should set all of the resource's parameters as instance variables" do + @resource.expects(:to_hash).returns(:one => "uno", :two => "dos") + @template.expects(:result).with do |bind| + eval("@one", bind) == "uno" and eval("@two", bind) == "dos" + end + @wrapper.evaluate + end + + it "should create a template instance with the contents of the file" do + File.expects(:read).with("/my/template").returns "yay" + ERB.expects(:new).with("yay", 0, "-").returns(@template) + + @wrapper.stubs :set_resource_variables + + @wrapper.evaluate + end + + it "should return the result of the template" do + @wrapper.stubs :set_resource_variables + + @wrapper.expects(:binding).returns "mybinding" + @template.expects(:result).with("mybinding").returns "myresult" + @wrapper.evaluate.should == "myresult" + end + end +end diff --git a/spec/unit/util/warnings.rb b/spec/unit/util/warnings.rb index 46bd1cc2d..46bd1cc2d 100644..100755 --- a/spec/unit/util/warnings.rb +++ b/spec/unit/util/warnings.rb |
