summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRick Bradley <rick@rickbradley.com>2008-04-02 19:29:04 -0500
committerLuke Kanies <luke@madstop.com>2008-04-11 13:11:28 -0500
commit93bc1a946f2da6e7c78a38ff90dac8a20b1bcbc7 (patch)
treeaf2894a72c59138abdf5a53bcf5e9d7b33948b29
parent99b295b8301d7a89c97ecdc1d636c2d2b7f1ae8e (diff)
downloadpuppet-93bc1a946f2da6e7c78a38ff90dac8a20b1bcbc7.tar.gz
puppet-93bc1a946f2da6e7c78a38ff90dac8a20b1bcbc7.tar.xz
puppet-93bc1a946f2da6e7c78a38ff90dac8a20b1bcbc7.zip
adding REST save support, with integration tests. A handful of unit tests in that area now need to be updated.
-rw-r--r--lib/puppet/indirector/rest.rb27
-rw-r--r--lib/puppet/network/http/handler.rb12
-rw-r--r--spec/integration/indirector/rest.rb93
-rw-r--r--spec/unit/network/server.rb2
4 files changed, 112 insertions, 22 deletions
diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb
index 33ae34006..889f63648 100644
--- a/lib/puppet/indirector/rest.rb
+++ b/lib/puppet/indirector/rest.rb
@@ -4,47 +4,46 @@ require 'uri'
# Access objects via REST
class Puppet::Indirector::REST < Puppet::Indirector::Terminus
def network_fetch(path)
- network(path, 'get')
+ Net::HTTP.start("127.0.0.1", 34343) {|x| x.get("/#{path}").body }
end
def network_delete(path)
- network(path, 'delete')
+ Net::HTTP.start("127.0.0.1", 34343) {|x| x.delete("/#{path}").body }
end
def network_put(path, data)
- network(path, 'put', data)
- end
-
- def network(path, meth, data = nil)
- # TODO: include data here, for #save
- Net::HTTP.start("127.0.0.1", 34343) {|x| x.send(meth.to_sym, "/#{path}").body } # weird-ass net/http library
+ Net::HTTP.start("127.0.0.1", 34343) {|x| x.put("/#{path}", data).body }
end
def find(name, options = {})
network_result = network_fetch("#{indirection.name}/#{name}")
raise YAML.load(network_result) if exception?(network_result)
- decoded_result = indirection.model.from_yaml(network_result)
+ indirection.model.from_yaml(network_result)
end
def search(name, options = {})
network_results = network_fetch("#{indirection.name}s/#{name}")
raise YAML.load(network_results) if exception?(network_results)
- decoded_results = YAML.load(network_results.to_s).collect {|result| indirection.model.from_yaml(result) }
+ YAML.load(network_results.to_s).collect {|result| indirection.model.from_yaml(result) }
end
def destroy(name, options = {})
network_result = network_delete("#{indirection.name}/#{name}")
raise YAML.load(network_result) if exception?(network_result)
- decoded_result = YAML.load(network_result.to_s)
+ YAML.load(network_result.to_s)
end
- def save
-
+ def save(obj, options = {})
+ network_result = network_put("#{indirection.name}/", obj.to_yaml)
+ # TODO: swap these two lines out:
+ raise network_result.inspect if exception?(network_result)
+ # raise YAML.load(network_result) if exception?(network_result)
+ indirection.model.from_yaml(network_result)
end
private
def exception?(yaml_string)
- yaml_string =~ %r{--- !ruby/exception}
+ yaml_string =~ %r{--- !ruby/exception}
end
end
diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb
index 9e6c28512..7113c92d3 100644
--- a/lib/puppet/network/http/handler.rb
+++ b/lib/puppet/network/http/handler.rb
@@ -44,13 +44,17 @@ module Puppet::Network::HTTP::Handler
end
def do_save(request, response)
- data = body(request)
+ data = body(request).to_s
raise ArgumentError, "No data to save" if !data or data.empty?
- args = params(request)
- obj = model.new
- result = obj.save(args.merge(:data => data)).to_yaml
+ # args = params(request)
+ obj = model.from_yaml(data)
+ result = save_object(obj).to_yaml
encode_result(request, response, result)
end
+
+ def save_object(obj)
+ obj.save
+ end
def do_exception(request, response, exception, status=404)
encode_result(request, response, exception.to_yaml, status)
diff --git a/spec/integration/indirector/rest.rb b/spec/integration/indirector/rest.rb
index 46a26ee91..a969a975b 100644
--- a/spec/integration/indirector/rest.rb
+++ b/spec/integration/indirector/rest.rb
@@ -9,6 +9,7 @@ class Puppet::TestIndirectedFoo
indirects :test_indirected_foo, :terminus_setting => :test_indirected_foo_terminus
attr_reader :value
+ attr_accessor :version
def initialize(value = 0)
@value = value
@@ -17,6 +18,10 @@ class Puppet::TestIndirectedFoo
def self.from_yaml(yaml)
YAML.load(yaml)
end
+
+ def name
+ "bob"
+ end
end
# empty Terminus class -- this would normally have to be in a directory findable by the autoloader, but we short-circuit that below
@@ -186,7 +191,49 @@ describe Puppet::Indirector::REST do
end
describe "when saving a model instance over REST" do
- it "needs more specs"
+ before :each do
+ @instance = Puppet::TestIndirectedFoo.new(42)
+ @mock_model = stub('faked model', :from_yaml => @instance)
+ Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:model).returns(@mock_model)
+ Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).returns(@instance)
+ end
+
+ describe "when a successful save can be performed" do
+ before :each do
+ end
+
+ it "should not fail" do
+ lambda { @instance.save }.should_not raise_error
+ end
+
+ it 'should return an instance of the model class' do
+ @instance.save.class.should == Puppet::TestIndirectedFoo
+ end
+
+ it 'should return a matching instance of the model class' do
+ @instance.save.value.should == @instance.value
+ end
+ end
+
+ describe "when a save cannot be completed" do
+ before :each do
+ Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).returns(false)
+ end
+
+ it "should return failure" do
+ @instance.save.should == false
+ end
+ end
+
+ describe "when an exception is encountered in performing a save" do
+ before :each do
+ Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:save_object).raises(RuntimeError)
+ end
+
+ it "should raise an exception" do
+ lambda { @instance.save }.should raise_error(RuntimeError)
+ end
+ end
end
after :each do
@@ -357,7 +404,49 @@ describe Puppet::Indirector::REST do
end
describe "when saving a model instance over REST" do
- it "needs more specs"
+ before :each 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)
+ Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).returns(@instance)
+ end
+
+ describe "when a successful save can be performed" do
+ before :each do
+ end
+
+ it "should not fail" do
+ lambda { @instance.save }.should_not raise_error
+ end
+
+ it 'should return an instance of the model class' do
+ @instance.save.class.should == Puppet::TestIndirectedFoo
+ end
+
+ it 'should return a matching instance of the model class' do
+ @instance.save.value.should == @instance.value
+ end
+ end
+
+ describe "when a save cannot be completed" do
+ before :each do
+ Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).returns(false)
+ end
+
+ it "should return failure" do
+ @instance.save.should == false
+ end
+ end
+
+ describe "when an exception is encountered in performing a save" do
+ before :each do
+ Puppet::Network::HTTP::MongrelREST.any_instance.stubs(:save_object).raises(RuntimeError)
+ end
+
+ it "should raise an exception" do
+ lambda { @instance.save }.should raise_error(RuntimeError)
+ end
+ end
end
after :each do
diff --git a/spec/unit/network/server.rb b/spec/unit/network/server.rb
index 2e02ffbc3..4e47c22fd 100644
--- a/spec/unit/network/server.rb
+++ b/spec/unit/network/server.rb
@@ -309,8 +309,6 @@ end
describe Class.new, "put these somewhere" do
- it "should allow indirections to deny access to services based upon which client is connecting, or whether the client is authorized"
- it "should deny access to clients based upon rules"
it "should have the ability to use a class-level from_ hook (from_yaml, from_text, etc.) that can be called, based on content-type header, to allow for different deserializations of an object"
it "should allow from_* on the inbound :data packet (look at its content_type) when doing a PUT/.new.save"
it "should prepend a rest version number on the path (w00t)"