summaryrefslogtreecommitdiffstats
path: root/spec/unit/network/xmlrpc
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2009-02-11 16:49:40 -0600
committerJames Turnbull <james@lovedthanlost.net>2009-02-12 17:08:48 +1100
commitaf3f3ae93ba1e43ac8231e4cf4e5a1f0ed8f3acb (patch)
tree61167f4c608377aefc5af1a5a3d057fa6f1b3f98 /spec/unit/network/xmlrpc
parentf0ac3aef53a08e271a5c243f17785cdb58f1f5ef (diff)
downloadpuppet-af3f3ae93ba1e43ac8231e4cf4e5a1f0ed8f3acb.tar.gz
puppet-af3f3ae93ba1e43ac8231e4cf4e5a1f0ed8f3acb.tar.xz
puppet-af3f3ae93ba1e43ac8231e4cf4e5a1f0ed8f3acb.zip
Refactoring the XMLRPC::Client error-handling
I split it all into smaller, manageable chunks, and used methods for each step, instead of having one huge call. Note that I made all of the tests first, then refactored the code, so I'm confident there's no behavior change. I don't know that this is actually a lot cleaner, but it seems that way to me. I'm open to skipping this, but I think it makes the whole thing a lot cleaner. Signed-off-by: Luke Kanies <luke@madstop.com>
Diffstat (limited to 'spec/unit/network/xmlrpc')
-rwxr-xr-xspec/unit/network/xmlrpc/client.rb150
1 files changed, 143 insertions, 7 deletions
diff --git a/spec/unit/network/xmlrpc/client.rb b/spec/unit/network/xmlrpc/client.rb
index a0a2e77fb..76ef5c799 100755
--- a/spec/unit/network/xmlrpc/client.rb
+++ b/spec/unit/network/xmlrpc/client.rb
@@ -2,12 +2,148 @@
Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
-describe Puppet::Network do
- it "should raise an XMLRPCClientError if a generated class raises a Timeout::Error" do
- http = mock 'http'
- Puppet::Network::HttpPool.stubs(:http_instance).returns http
- file = Puppet::Network::Client.file.new({:Server => "foo.com"})
- http.stubs(:post2).raises Timeout::Error
- lambda { file.retrieve }.should raise_error(Puppet::Network::XMLRPCClientError)
+describe Puppet::Network::XMLRPCClient do
+ describe "when performing the rpc call" do
+ before do
+ @client = Puppet::Network::Client.report.xmlrpc_client.new
+ @client.stubs(:call).returns "foo"
+
+ end
+
+ it "should call the specified namespace and method, with the specified arguments" do
+ @client.expects(:call).with("puppetreports.report", "eh").returns "foo"
+ @client.report("eh")
+ end
+
+ it "should return the results from the call" do
+ @client.expects(:call).returns "foo"
+ @client.report("eh").should == "foo"
+ end
+
+ describe "when returning the http instance" do
+ it "should use the http pool to create the instance" do
+ @client.instance_variable_set("@http", nil)
+ @client.expects(:host).returns "myhost"
+ @client.expects(:port).returns "myport"
+ Puppet::Network::HttpPool.expects(:http_instance).with("myhost", "myport", true).returns "http"
+
+ @client.http.should == "http"
+ end
+
+ it "should reuse existing instances" do
+ @client.http.should equal(@client.http)
+ end
+ end
+
+ describe "when recycling the connection" do
+ it "should close the existing instance if it's open" do
+ http = mock 'http'
+ @client.stubs(:http).returns http
+
+ http.expects(:started?).returns true
+ http.expects(:finish)
+
+ @client.recycle_connection
+ end
+
+ it "should force creation of a new instance" do
+ Puppet::Network::HttpPool.expects(:http_instance).returns "second_http"
+
+ @client.recycle_connection
+
+ @client.http.should == "second_http"
+ end
+ end
+
+ describe "and an exception is raised" do
+ it "should raise XMLRPCClientError if XMLRPC::FaultException is raised" do
+ error = XMLRPC::FaultException.new("foo", "bar")
+
+ @client.expects(:call).raises(error)
+
+ lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
+ end
+
+ it "should raise XMLRPCClientError if Errno::ECONNREFUSED is raised" do
+ @client.expects(:call).raises(Errno::ECONNREFUSED)
+
+ lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
+ end
+
+ it "should log and raise XMLRPCClientError if Timeout::Error is raised" do
+ Puppet.expects(:err)
+ @client.expects(:call).raises(Timeout::Error)
+
+ lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
+ end
+
+ it "should log and raise XMLRPCClientError if SocketError is raised" do
+ Puppet.expects(:err)
+ @client.expects(:call).raises(SocketError)
+
+ lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
+ end
+
+ it "should log, recycle the connection, and retry if Errno::EPIPE is raised" do
+ @client.expects(:call).times(2).raises(Errno::EPIPE).then.returns "eh"
+
+ Puppet.expects(:warning)
+ @client.expects(:recycle_connection)
+
+ @client.report("eh")
+ end
+
+ it "should log, recycle the connection, and retry if EOFError is raised" do
+ @client.expects(:call).times(2).raises(EOFError).then.returns "eh"
+
+ Puppet.expects(:warning)
+ @client.expects(:recycle_connection)
+
+ @client.report("eh")
+ end
+
+ it "should log and retry if an exception containing 'Wrong size' is raised" do
+ error = RuntimeError.new("Wrong size. Was 15, should be 30")
+ @client.expects(:call).times(2).raises(error).then.returns "eh"
+
+ Puppet.expects(:warning)
+
+ @client.report("eh")
+ end
+
+ it "should raise XMLRPCClientError if OpenSSL::SSL::SSLError is raised" do
+ @client.expects(:call).raises(OpenSSL::SSL::SSLError)
+
+ lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
+ end
+
+ it "should log and raise XMLRPCClientError if OpenSSL::SSL::SSLError is raised with certificate issues" do
+ error = OpenSSL::SSL::SSLError.new("hostname was not match")
+ @client.expects(:call).raises(error)
+
+ Puppet.expects(:warning)
+
+ lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
+ end
+
+ it "should log, recycle the connection, and retry if OpenSSL::SSL::SSLError is raised containing 'bad write retry'" do
+ error = OpenSSL::SSL::SSLError.new("bad write retry")
+ @client.expects(:call).times(2).raises(error).then.returns "eh"
+
+ @client.expects(:recycle_connection)
+
+ Puppet.expects(:warning)
+
+ @client.report("eh")
+ end
+
+ it "should log and raise XMLRPCClientError if any other exception is raised" do
+ @client.expects(:call).raises(RuntimeError)
+
+ Puppet.expects(:err)
+
+ lambda { @client.report("eh") }.should raise_error(Puppet::Network::XMLRPCClientError)
+ end
+ end
end
end