From 89779a4d487ac7dd313e16eb68732835bd13d4e4 Mon Sep 17 00:00:00 2001 From: Adam Jacob Date: Sat, 1 Aug 2009 21:26:21 -0700 Subject: Initial pass at a Chef 0.8.0 alpha Conflicts: Rakefile chef-server-slice/Rakefile chef-server-slice/app/controllers/application.rb chef-server-slice/app/controllers/exceptions.rb chef-server-slice/app/controllers/nodes.rb chef-server-slice/app/controllers/openid_consumer.rb chef-server-slice/app/controllers/openid_server.rb chef-server-slice/app/helpers/nodes_helper.rb chef-server/Rakefile chef-server/config/dependencies.rb chef-server/config/init.rb chef/Rakefile chef/lib/chef.rb chef/lib/chef/application/indexer.rb chef/lib/chef/client.rb chef/lib/chef/config.rb chef/lib/chef/node.rb chef/lib/chef/queue.rb chef/spec/unit/application/indexer_spec.rb chef/spec/unit/client_spec.rb chef/spec/unit/config_spec.rb cucumber.yml features/api/nodes/create_node_api.feature features/api/nodes/delete_node_api.feature features/api/nodes/list_nodes_api.feature features/api/nodes/show_node_api.feature features/api/nodes/update_node_api.feature features/api/roles/list_roles_api.feature features/steps/fixture_steps.rb --- chef/spec/unit/couchdb_spec.rb | 400 +++++++++++++++++++++-------------------- 1 file changed, 205 insertions(+), 195 deletions(-) (limited to 'chef/spec/unit/couchdb_spec.rb') diff --git a/chef/spec/unit/couchdb_spec.rb b/chef/spec/unit/couchdb_spec.rb index ffcc4d1a2a..5f84384a71 100644 --- a/chef/spec/unit/couchdb_spec.rb +++ b/chef/spec/unit/couchdb_spec.rb @@ -18,236 +18,245 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper")) -describe Chef::CouchDB, "new" do - before do +describe Chef::CouchDB do + before(:each) do @mock_rest = mock("Chef::REST", :null_object => true) @mock_rest.stub!(:run_request).and_return({"couchdb" => "Welcome", "version" =>"0.9.0"}) @mock_rest.stub!(:url).and_return("http://localhost:5984") Chef::REST.stub!(:new).and_return(@mock_rest) - end - - it "should create a new Chef::REST object from the default url" do - Chef::Config[:couchdb_url] = "http://monkey" - Chef::REST.should_receive(:new).with("http://monkey") - Chef::CouchDB.new + @couchdb = Chef::CouchDB.new + Chef::Nanite.stub!(:request).and_return(true) + Chef::Nanite.stub!(:in_event).and_return(true) + Chef::Nanite.stub!(:start_mapper).and_return(true) end - it "should create a new Chef::REST object from a provided url" do - Chef::REST.should_receive(:new).with("http://monkeypants") - Chef::CouchDB.new("http://monkeypants") - end -end + describe "new" do + it "should create a new Chef::REST object from the default url" do + old_url = Chef::Config[:couchdb_url] + Chef::Config[:couchdb_url] = "http://monkey" + Chef::REST.should_receive(:new).with("http://monkey", nil, nil) + Chef::CouchDB.new + Chef::Config[:couchdb_url] = old_url + end -describe Chef::CouchDB, "create_db" do - before(:each) do - @mock_rest = mock("Chef::REST", :null_object => true) - @mock_rest.stub!(:get_rest).and_return([ "chef" ]) - @mock_rest.stub!(:put_rest).and_return(true) - Chef::REST.stub!(:new).and_return(@mock_rest) - end - - def do_create_db - couch = Chef::CouchDB.new - couch.create_db - end - - it "should get a list of current databases" do - @mock_rest.should_receive(:get_rest).and_return(["chef"]) - do_create_db - end - - it "should create the chef database if it does not exist" do - @mock_rest.stub!(:get_rest).and_return([]) - @mock_rest.should_receive(:put_rest).with("chef", {}).and_return(true) - do_create_db + it "should create a new Chef::REST object from a provided url" do + Chef::REST.should_receive(:new).with("http://monkeypants", nil, nil) + Chef::CouchDB.new("http://monkeypants") + end end - - it "should not create the chef database if it does exist" do - @mock_rest.stub!(:get_rest).and_return(["chef"]) - @mock_rest.should_not_receive(:put_rest) - do_create_db - end - - it "should return 'chef'" do - do_create_db.should eql("chef") + + describe "create_db" do + before(:each) do + @couchdb.stub!(:create_design_document).and_return(true) + end + + it "should get a list of current databases" do + @mock_rest.should_receive(:get_rest).and_return(["chef"]) + @couchdb.create_db + end + + it "should create the chef database if it does not exist" do + @mock_rest.stub!(:get_rest).and_return([]) + @mock_rest.should_receive(:put_rest).with("chef", {}).and_return(true) + @couchdb.create_db + end + + it "should not create the chef database if it does exist" do + @mock_rest.stub!(:get_rest).and_return(["chef"]) + @mock_rest.should_not_receive(:put_rest) + @couchdb.create_db + end + + it "should return 'chef'" do + @couchdb.create_db.should eql("chef") + end end -end -describe Chef::CouchDB, "create_design_document" do - before(:each) do - @mock_rest = mock("Chef::REST", :null_object => true) - @mock_design = { - "version" => 1, - "_rev" => 1 - } - @mock_data = { - "version" => 1, - "language" => "javascript", - "views" => { - "all" => { - "map" => <<-EOJS - function(doc) { - if (doc.chef_type == "node") { - emit(doc.name, doc); + describe "create_design_document" do + before(:each) do + @mock_design = { + "version" => 1, + "_rev" => 1 + } + @mock_data = { + "version" => 1, + "language" => "javascript", + "views" => { + "all" => { + "map" => <<-EOJS + function(doc) { + if (doc.chef_type == "node") { + emit(doc.name, doc); + } } - } - EOJS - }, + EOJS + }, + } } - } - @mock_rest.stub!(:get_rest).and_return(@mock_design) - @mock_rest.stub!(:put_rest).and_return(true) - Chef::REST.stub!(:new).and_return(@mock_rest) - @couchdb = Chef::CouchDB.new - @couchdb.stub!(:create_db).and_return(true) - end - - def do_create_design_document - @couchdb.create_design_document("bob", @mock_data) - end - - it "should create the database if it does not exist" do - @couchdb.should_receive(:create_db).and_return(true) - do_create_design_document - end - - it "should fetch the existing design document" do - @mock_rest.should_receive(:get_rest).with("chef/_design%2Fbob") - do_create_design_document - end - - it "should populate the _rev in the new design if the versions dont match" do - @mock_data["version"] = 2 - do_create_design_document - @mock_data["_rev"].should eql(1) - end - - it "should create the view if it requires updating" do - @mock_data["version"] = 2 - @mock_rest.should_receive(:put_rest).with("chef/_design%2Fbob", @mock_data) - do_create_design_document - end - - it "should not create the view if it does not require updating" do - @mock_data["version"] = 1 - @mock_rest.should_not_receive(:put_rest) - do_create_design_document + @mock_rest.stub!(:get_rest).and_return(@mock_design) + @mock_rest.stub!(:put_rest).and_return(true) + @couchdb.stub!(:create_db).and_return(true) + end + + def do_create_design_document + @couchdb.create_design_document("bob", @mock_data) + end + + it "should create the database if it does not exist" do + @couchdb.should_receive(:create_db).and_return(true) + do_create_design_document + end + + it "should fetch the existing design document" do + @mock_rest.should_receive(:get_rest).with("chef/_design/bob") + do_create_design_document + end + + it "should populate the _rev in the new design if the versions dont match" do + @mock_data["version"] = 2 + do_create_design_document + @mock_data["_rev"].should eql(1) + end + + it "should create the view if it requires updating" do + @mock_data["version"] = 2 + @mock_rest.should_receive(:put_rest).with("chef/_design%2Fbob", @mock_data) + do_create_design_document + end + + it "should not create the view if it does not require updating" do + @mock_data["version"] = 1 + @mock_rest.should_not_receive(:put_rest) + do_create_design_document + end end -end -describe Chef::CouchDB, "store" do - it "should put the object into couchdb" do - @mock_rest = mock("Chef::REST", :null_object => true) - @mock_rest.should_receive(:put_rest).with("chef/node_bob", {}).and_return(true) - Chef::REST.stub!(:new).and_return(@mock_rest) - Chef::CouchDB.new.store("node", "bob", {}) - end -end + describe "store" do + before(:each) do + @mock_results = { + "rows" => [ + "id" => 'a0934635-e111-45d9-8223-cb58e1c9434c' + ] + } + @couchdb.stub!(:get_view).with("id_map", "name_to_id", :key => [ "node", "bob" ]).and_return(@mock_results) + end -describe Chef::CouchDB, "load" do - it "should load the object from couchdb" do - @mock_rest = mock("Chef::REST", :null_object => true) - @mock_rest.should_receive(:get_rest).with("chef/node_bob").and_return(true) - Chef::REST.stub!(:new).and_return(@mock_rest) - Chef::CouchDB.new.load("node", "bob").should eql(true) - end -end + it "should put the object into couchdb with a pre-existing GUID" do + @mock_rest.should_receive(:put_rest).with("chef/#{@mock_results["rows"][0]["id"]}", {}).and_return(true) + @couchdb.store("node", "bob", {}) + end -describe Chef::CouchDB, "delete" do - before(:each) do - @mock_current = { - "version" => 1, - "_rev" => 1 - } - @mock_rest = mock("Chef::REST", :null_object => true) - @mock_rest.stub!(:get_rest).and_return(@mock_current) - @mock_rest.stub!(:delete_rest).and_return(true) - Chef::REST.stub!(:new).and_return(@mock_rest) - end - - def do_delete(rev=nil) - Chef::REST.stub!(:new).and_return(@mock_rest) - Chef::CouchDB.new.delete("node", "bob", rev) - end - - it "should remove the object from couchdb with a specific revision" do - @mock_rest.should_receive(:delete_rest).with("chef/node_bob?rev=1") - do_delete(1) - end - - it "should remove the object from couchdb based on the couchdb_rev of the current obj" do - mock_real = mock("Inflated Object") - mock_real.stub!(:respond_to?).and_return(true) - mock_real.stub!(:couchdb_rev).and_return(2) - @mock_rest.should_receive(:get_rest).with("chef/node_bob").and_return(mock_real) - @mock_rest.should_receive(:delete_rest).with("chef/node_bob?rev=2") - do_delete - end - - it "should remove the object from couchdb based on the current objects rev" do - @mock_rest.should_receive(:delete_rest).with("chef/node_bob?rev=1") - do_delete + it "should put the object into couchdb with a new GUID" do + @mock_results = { "rows" => [] } + @couchdb.stub!(:get_view).with("id_map", "name_to_id", :key => [ "node", "bob" ]).and_return(@mock_results) + UUIDTools::UUID.stub!(:random_create).and_return("aaaaaaaa-xxxx-xxxx-xxxx-xxxxxxxxxxx") + @mock_rest.should_receive(:put_rest).with("chef/aaaaaaaa-xxxx-xxxx-xxxx-xxxxxxxxxxx", {}).and_return(true) + @couchdb.store("node", "bob", {}) + end + + it "should send the object to nanite for indexing" do + Chef::Nanite.should_receive(:request) + @couchdb.store("node", "bob", {}) + end end -end -describe Chef::CouchDB, "list" do - before(:each) do - @mock_rest = mock("Chef::REST", :null_object => true, :url => "http://monkeypants") - Chef::REST.stub!(:new).and_return(@mock_rest) - @couch = Chef::CouchDB.new("http://monkeypants") - Chef::Config.stub!(:[]).with(:couchdb_database).and_return("chef") + describe "load" do + before(:each) do + @mock_node = Chef::Node.new() + @mock_node.name("bob") + @couchdb.stub!(:find_by_name).with("node", "bob").and_return(@mock_node) + end + + it "should load the object from couchdb" do + @couchdb.load("node", "bob").should eql(@mock_node) + end end - - describe "on couchdb 0.8" do - before do - Chef::Config.stub!(:[]).with(:couchdb_version).and_return(0.8) + + describe "delete" do + before(:each) do + @mock_current = { + "version" => 1, + "_rev" => 1 + } + @mock_rest.stub!(:get_rest).and_return(@mock_current) + @mock_rest.stub!(:delete_rest).and_return(true) + @mock_node = Chef::Node.new() + @mock_node.name("bob") + @mock_node.couchdb_rev = 15 + @couchdb.stub!(:find_by_name).with("node", "bob", true).and_return([ @mock_node, "ax" ]) end - it "should get the view for all objects if inflate is true" do - @mock_rest.should_receive(:get_rest).with("chef/_view/node/all").and_return(true) - @couch.list("node", true) + def do_delete(rev=nil) + @couchdb.delete("node", "bob", rev) end - - it "should get the view for just the object id's if inflate is false" do - @mock_rest.should_receive(:get_rest).with("chef/_view/node/all_id").and_return(true) - @couch.list("node", false) + + it "should remove the object from couchdb with a specific revision" do + @mock_rest.should_receive(:delete_rest).with("chef/ax?rev=1") + do_delete(1) + end + + it "should remove the object from couchdb based on the couchdb_rev of the current obj" do + @mock_rest.should_receive(:delete_rest).with("chef/ax?rev=15") + do_delete end end - describe "on couchdb 0.9" do - before do - Chef::Config.stub!(:[]).with(:couchdb_version).and_return(0.9) + describe "list" do + before(:each) do + Chef::Config.stub!(:[]).with(:couchdb_database).and_return("chef") + @mock_response = mock("Chef::CouchDB::Response", :null_object => true) end - it "should get the view for all objects if inflate is true" do - @mock_rest.should_receive(:get_rest).with("chef/_design/node/_view/all").and_return(true) - @couch.list("node", true) + describe "on couchdb 0.8" do + before(:each) do + Chef::Config.stub!(:[]).with(:couchdb_version).and_return(0.8) + end + + it "should get the view for all objects if inflate is true" do + @mock_rest.should_receive(:get_rest).with("chef/_view/node/all").and_return(@mock_response) + @couchdb.list("node", true) + end + + it "should get the view for just the object id's if inflate is false" do + @mock_rest.should_receive(:get_rest).with("chef/_view/node/all_id").and_return(@mock_response) + @couchdb.list("node", false) + end end - it "should get the view for just the object id's if inflate is false" do - @mock_rest.should_receive(:get_rest).with("chef/_design/node/_view/all_id").and_return(true) - @couch.list("node", false) + describe "on couchdb 0.9" do + before do + Chef::Config.stub!(:[]).with(:couchdb_version).and_return(0.9) + end + + it "should get the view for all objects if inflate is true" do + @mock_rest.should_receive(:get_rest).with("chef/_design/node/_view/all").and_return(@mock_response) + @couchdb.list("node", true) + end + + it "should get the view for just the object id's if inflate is false" do + @mock_rest.should_receive(:get_rest).with("chef/_design/node/_view/all_id").and_return(@mock_response) + @couchdb.list("node", false) + end end end -end -describe Chef::CouchDB, "has_key?" do - before(:each) do - @mock_rest = mock("Chef::REST", :null_object => true) - Chef::REST.stub!(:new).and_return(@mock_rest) - end - - it "should return true if the object exists" do - @mock_rest.should_receive(:get_rest).and_return(true) - Chef::CouchDB.new.has_key?("node", "bob").should eql(true) - end - - it "should return false if the object does not exist" do - @mock_rest.should_receive(:get_rest).and_raise(ArgumentError) - Chef::CouchDB.new.has_key?("node", "bob").should eql(false) + describe "has_key?" do + it "should return true if the object exists" do + @couchdb.stub!(:find_by_name).with("node", "bob").and_return(true) + @couchdb.has_key?("node", "bob").should eql(true) + end + + it "should return false if the object does not exist" do + @couchdb.stub!(:find_by_name).and_raise(Chef::Exceptions::CouchDBNotFound) + @couchdb.has_key?("node", "bob").should eql(false) + end end + end + + + describe Chef::CouchDB, "get_view" do before do @mock_rest = mock("Chef::REST", :null_object => true, :url => "http://monkeypants") @@ -287,6 +296,7 @@ describe Chef::CouchDB, "view_uri" do @mock_rest.should_receive(:run_request).with( :GET, URI.parse("http://monkeypants/"), + {}, false, 10, false -- cgit v1.2.1