diff options
author | Daniel DeLeo <dan@opscode.com> | 2011-03-03 19:37:05 -0800 |
---|---|---|
committer | Daniel DeLeo <dan@opscode.com> | 2011-03-03 19:37:05 -0800 |
commit | be142d2dfbdd6e921fbc1b0a821a23eec7f52330 (patch) | |
tree | 979cc0e29853b186b96693d56a1758fc265a5be6 | |
parent | af9c8f898cf2a635176bcaf90b37dcd5db25a684 (diff) | |
parent | 012ed1926c485e8d9d6f2245d4e0e35bd1778834 (diff) | |
download | chef-be142d2dfbdd6e921fbc1b0a821a23eec7f52330.tar.gz |
Merge branch 'upgrade-to-rspec-2'
40 files changed, 774 insertions, 860 deletions
diff --git a/chef/.rspec b/chef/.rspec new file mode 100644 index 0000000000..7bfa3f20e6 --- /dev/null +++ b/chef/.rspec @@ -0,0 +1,2 @@ +--color +-fs diff --git a/chef/lib/chef/application/client.rb b/chef/lib/chef/application/client.rb index 3d708b59b2..221bf28ed0 100644 --- a/chef/lib/chef/application/client.rb +++ b/chef/lib/chef/application/client.rb @@ -138,6 +138,8 @@ class Chef::Application::Client < Chef::Application :proc => lambda {|v| puts "Chef: #{::Chef::VERSION}"}, :exit => 0 + attr_reader :chef_client_json + def initialize super diff --git a/chef/lib/chef/application/knife.rb b/chef/lib/chef/application/knife.rb index c6da3d1661..439504da83 100644 --- a/chef/lib/chef/application/knife.rb +++ b/chef/lib/chef/application/knife.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -35,13 +35,13 @@ class Chef::Application::Knife < Chef::Application banner "Usage: #{$0} sub-command (options)" - option :config_file, + option :config_file, :short => "-c CONFIG", :long => "--config CONFIG", :description => "The configuration file to use", :proc => lambda { |path| File.expand_path(path, Dir.pwd) } - option :log_level, + option :log_level, :short => "-l LEVEL", :long => "--log_level LEVEL", :description => "Set the log level (debug, info, warn, error, fatal)", @@ -63,20 +63,20 @@ class Chef::Application::Knife < Chef::Application :long => "--editor EDITOR", :description => "Set the editor to use for interactive commands", :default => ENV['EDITOR'] - + option :no_editor, :short => "-n", :long => "--no-editor", :description => "Do not open EDITOR, just accept the data as is", :boolean => true - + option :help, :short => "-h", :long => "--help", :description => "Show this message", :on => :tail, :boolean => true - + option :node_name, :short => "-u USER", :long => "--user USER", @@ -121,16 +121,16 @@ class Chef::Application::Knife < Chef::Application :proc => lambda {|v| puts "Chef: #{::Chef::VERSION}"}, :exit => 0 - # Run knife + # Run knife def run Mixlib::Log::Formatter.show_time = false validate_and_parse_options Chef::Knife.run(ARGV, options) exit 0 end - + private - + def validate_and_parse_options # Checking ARGV validity *before* parse_options because parse_options # mangles ARGV in some situations @@ -139,16 +139,16 @@ class Chef::Application::Knife < Chef::Application elsif no_subcommand_given? if (want_help? || want_version?) print_help_and_exit - else + else print_help_and_exit(2, NO_COMMAND_GIVEN) end end end - + def no_subcommand_given? ARGV[0] =~ /^-/ end - + def no_command_given? ARGV.empty? end @@ -160,10 +160,10 @@ class Chef::Application::Knife < Chef::Application def want_version? ARGV[0] =~ /^(--version|-v)$/ end - + def print_help_and_exit(exitcode=1, fatal_message=nil) Chef::Log.error(fatal_message) if fatal_message - + begin self.parse_options rescue OptionParser::InvalidOption => e @@ -174,5 +174,5 @@ class Chef::Application::Knife < Chef::Application Chef::Knife.list_commands exit exitcode end - + end diff --git a/chef/lib/chef/application/solo.rb b/chef/lib/chef/application/solo.rb index 896daef49d..3162ab4b95 100644 --- a/chef/lib/chef/application/solo.rb +++ b/chef/lib/chef/application/solo.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -26,14 +26,14 @@ require 'open-uri' require 'fileutils' class Chef::Application::Solo < Chef::Application - - option :config_file, + + option :config_file, :short => "-c CONFIG", :long => "--config CONFIG", :default => "/etc/chef/solo.rb", :description => "The configuration file to use" - option :log_level, + option :log_level, :short => "-l LEVEL", :long => "--log_level LEVEL", :description => "Set the log level (debug, info, warn, error, fatal)", @@ -101,7 +101,7 @@ class Chef::Application::Solo < Chef::Application :long => "--recipe-url RECIPE_URL", :description => "Pull down a remote gzipped tarball of recipes and untar it to the cookbook cache.", :proc => nil - + option :version, :short => "-v", :long => "--version", @@ -110,21 +110,23 @@ class Chef::Application::Solo < Chef::Application :proc => lambda {|v| puts "Chef: #{::Chef::VERSION}"}, :exit => 0 + attr_reader :chef_solo_json + def initialize super @chef_solo = nil @chef_solo_json = nil end - + def reconfigure super - + Chef::Config[:solo] = true if Chef::Config[:daemonize] Chef::Config[:interval] ||= 1800 end - + if Chef::Config[:json_attribs] begin json_io = case Chef::Config[:json_attribs] @@ -151,7 +153,7 @@ class Chef::Application::Solo < Chef::Application Chef::Application.fatal!("Could not parse the provided JSON file (#{Chef::Config[:json_attribs]})!: " + error.message, 2) end end - + if Chef::Config[:recipe_url] cookbooks_path = Array(Chef::Config[:cookbook_path]).detect{|e| e =~ /\/cookbooks\/*$/ } recipes_path = File.expand_path(File.join(cookbooks_path, '..')) @@ -168,11 +170,11 @@ class Chef::Application::Solo < Chef::Application Chef::Mixin::Command.run_command(:command => "tar zxvfC #{path} #{recipes_path}") end end - + def setup_application Chef::Daemon.change_privilege end - + def run_application if Chef::Config[:daemonize] Chef::Daemon.daemonize("chef-client") diff --git a/chef/spec/spec.opts b/chef/spec/spec.opts deleted file mode 100644 index 13ba36467a..0000000000 --- a/chef/spec/spec.opts +++ /dev/null @@ -1,5 +0,0 @@ ---color ---loadby -mtime --b --fs
\ No newline at end of file diff --git a/chef/spec/spec_helper.rb b/chef/spec/spec_helper.rb index 332a8c809d..29b33cd546 100644 --- a/chef/spec/spec_helper.rb +++ b/chef/spec/spec_helper.rb @@ -23,6 +23,7 @@ module Shef end require 'rubygems' +require 'rspec/mocks' $:.unshift(File.join(File.dirname(__FILE__), "..", "lib")) diff --git a/chef/spec/unit/application/client_spec.rb b/chef/spec/unit/application/client_spec.rb index b9b01c9b1e..1b394aa082 100644 --- a/chef/spec/unit/application/client_spec.rb +++ b/chef/spec/unit/application/client_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -72,47 +72,43 @@ describe Chef::Application::Client, "reconfigure" do describe "and the json_attribs matches a HTTP regex" do before do - @json = mock("Tempfile", :read => {:a=>"b"}.to_json, :null_object => true) - @rest = mock("Chef::REST", :get_rest => @json, :null_object => true) + @json = StringIO.new({:a=>"b"}.to_json) + @json_tempfile = mock("Tempfile for remote JSON", :open => @json) + @rest = mock("Chef::REST", :get_rest => @json_tempfile) Chef::Config[:json_attribs] = "https://foo.com/foo.json" Chef::REST.stub!(:new).with("https://foo.com/foo.json", nil, nil).and_return(@rest) @app.stub!(:open).with("/etc/chef/dna.json").and_return(@json) end - it "should create a new Chef::REST" do - Chef::REST.should_receive(:new).with("https://foo.com/foo.json", nil, nil).and_return(@rest) - @app.reconfigure - end - it "should perform a RESTful GET on the supplied URL" do - @rest.should_receive(:get_rest).with("https://foo.com/foo.json", true).and_return(@json) @app.reconfigure + @app.chef_client_json.should == {"a" => "b"} end end describe "and the json_attribs does not match the HTTP regex" do before do Chef::Config[:json_attribs] = "/etc/chef/dna.json" - @json = mock("Tempfile", :read => {:a=>"b"}.to_json, :null_object => true) + @json = StringIO.new({:a=>"b"}.to_json) @app.stub!(:open).with("/etc/chef/dna.json").and_return(@json) end it "should parse the json out of the file" do - Chef::JSONCompat.should_receive(:from_json).with(@json.read) @app.reconfigure + @app.chef_client_json.should == {"a" => "b"} end end - + describe "when parsing fails" do before do Chef::Config[:json_attribs] = "/etc/chef/dna.json" - @json = mock("Tempfile", :read => {:a=>"b"}.to_json, :null_object => true) + @json = mock("Tempfile", :read => {:a=>"b"}.to_json) @app.stub!(:open).with("/etc/chef/dna.json").and_return(@json) Chef::JSONCompat.stub!(:from_json).with(@json.read).and_raise(JSON::ParserError) Chef::Application.stub!(:fatal!).and_return(true) end - + it "should hard fail the application" do Chef::Application.should_receive(:fatal!).with("Could not parse the provided JSON file (/etc/chef/dna.json)!: JSON::ParserError", 2).and_return(true) @app.reconfigure @@ -129,7 +125,7 @@ describe Chef::Application::Client, "setup_application" do @app.stub!(:configure_chef).and_return(true) @app.stub!(:configure_logging).and_return(true) end - + it "should change privileges" do Chef::Daemon.should_receive(:change_privilege).and_return(true) @app.setup_application diff --git a/chef/spec/unit/application/knife_spec.rb b/chef/spec/unit/application/knife_spec.rb index 1cd2e2374d..73867dfccd 100644 --- a/chef/spec/unit/application/knife_spec.rb +++ b/chef/spec/unit/application/knife_spec.rb @@ -18,15 +18,12 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper")) require "#{CHEF_SPEC_DATA}/knife_subcommand/test_yourself" - -describe Chef::Application::Knife do - before(:all) do - class NoopKnifeCommand < Chef::Knife - def run - end - end +class NoopKnifeCommand < Chef::Knife + def run end +end +describe Chef::Application::Knife do before(:each) do @knife = Chef::Application::Knife.new @knife.stub!(:puts) @@ -48,7 +45,7 @@ describe Chef::Application::Knife do it "should run a sub command with the applications command line option prototype" do with_argv(*%w{noop knife command with some args}) do - knife = mock(Chef::Knife, :null_object => true) + knife = mock(Chef::Knife) Chef::Knife.should_receive(:run).with(ARGV, @knife.options).and_return(knife) @knife.should_receive(:exit).with(0) @knife.run @@ -136,7 +133,7 @@ describe Chef::Application::Knife do it "should run a sub command with the applications command line option prototype" do with_argv(*%w{noop knife command with some args}) do - knife = mock(Chef::Knife, :null_object => true) + knife = mock(Chef::Knife) Chef::Knife.should_receive(:run).with(ARGV, @knife.options).and_return(knife) @knife.should_receive(:exit).with(0) @knife.run diff --git a/chef/spec/unit/application/solo_spec.rb b/chef/spec/unit/application/solo_spec.rb index a308f43c9a..8b367529b1 100644 --- a/chef/spec/unit/application/solo_spec.rb +++ b/chef/spec/unit/application/solo_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -31,7 +31,7 @@ describe Chef::Application::Solo do Chef::Config[:splay] = nil Chef::Config[:solo] = true end - + after do Chef::Config[:solo] = nil Chef::Config.configuration.replace(@original_config) @@ -60,42 +60,38 @@ describe Chef::Application::Solo do describe "and the json_attribs matches a HTTP regex" do before do - @json = mock("Tempfile", :read => {:a=>"b"}.to_json, :null_object => true) - @rest = mock("Chef::REST", :get_rest => @json, :null_object => true) + @json = StringIO.new({:a=>"b"}.to_json) + @json_tempfile = mock("Tempfile (mock)", :open => @json) + @rest = mock("Chef::REST", :get_rest => @json_tempfile) Chef::Config[:json_attribs] = "https://foo.com/foo.json" Chef::REST.stub!(:new).with("https://foo.com/foo.json", nil, nil).and_return(@rest) @app.stub!(:open).with("/etc/chef/dna.json").and_return(@json) end - it "should create a new Chef::REST" do - Chef::REST.should_receive(:new).with("https://foo.com/foo.json", nil, nil).and_return(@rest) - @app.reconfigure - end - it "should perform a RESTful GET on the supplied URL" do - @rest.should_receive(:get_rest).with("https://foo.com/foo.json", true).and_return(@json) @app.reconfigure + @app.chef_solo_json.should == {"a" => "b"} end end describe "and the json_attribs does not match the HTTP regex" do before do Chef::Config[:json_attribs] = "/etc/chef/dna.json" - @json = mock("Tempfile", :read => {:a=>"b"}.to_json, :null_object => true) + @json = StringIO.new({:a=>"b"}.to_json) @app.stub!(:open).with("/etc/chef/dna.json").and_return(@json) end it "should parse the json out of the file" do - Chef::JSONCompat.should_receive(:from_json).with(@json.read) @app.reconfigure + @app.chef_solo_json.should == {"a" => "b"} end end describe "when parsing fails" do before do Chef::Config[:json_attribs] = "/etc/chef/dna.json" - @json = mock("Tempfile", :read => {:a=>"b"}.to_json, :null_object => true) + @json = mock("Tempfile", :read => {:a=>"b"}.to_json) @app.stub!(:open).with("/etc/chef/dna.json").and_return(@json) Chef::JSONCompat.stub!(:from_json).with(@json.read).and_raise(JSON::ParserError) Chef::Application.stub!(:fatal!).and_return(true) @@ -115,10 +111,10 @@ describe Chef::Application::Solo do Chef::Config[:cookbook_path] = "/tmp/chef-solo/cookbooks" Chef::Config[:recipe_url] = "http://junglist.gen.nz/recipes.tgz" FileUtils.stub!(:mkdir_p).and_return(true) - @tarfile = mock("Tempfile", :null_object => true, :read => "blah") + @tarfile = StringIO.new("remote_tarball_content") @app.stub!(:open).with("http://junglist.gen.nz/recipes.tgz").and_yield(@tarfile) - @target_file = mock("Tempfile", :null_object => true) + @target_file = StringIO.new File.stub!(:open).with("/tmp/chef-solo/recipes.tgz", "wb").and_yield(@target_file) Chef::Mixin::Command.stub!(:run_command).and_return(true) @@ -135,8 +131,8 @@ describe Chef::Application::Solo do end it "should write the recipes to the target path" do - @target_file.should_receive(:write).with("blah").and_return(true) @app.reconfigure + @target_file.string.should == "remote_tarball_content" end it "should untar the target file to the parent of the cookbook path" do @@ -152,7 +148,7 @@ describe Chef::Application::Solo do Chef::Config[:solo] = true Chef::Daemon.stub!(:change_privilege) - @chef_client = mock("Chef::Client", :null_object => true) + @chef_client = mock("Chef::Client") Chef::Client.stub!(:new).and_return(@chef_client) @app = Chef::Application::Solo.new # this is all stuff the reconfigure method needs diff --git a/chef/spec/unit/config_spec.rb b/chef/spec/unit/config_spec.rb index 088d206d9d..211a005481 100644 --- a/chef/spec/unit/config_spec.rb +++ b/chef/spec/unit/config_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -25,23 +25,23 @@ describe Chef::Config do end it "should set the registration url" do - Chef::Config.registration_url.should == "https://junglist.gen.nz" + Chef::Config.registration_url.should == "https://junglist.gen.nz" end it "should set the template url" do - Chef::Config.template_url.should == "https://junglist.gen.nz" + Chef::Config.template_url.should == "https://junglist.gen.nz" end it "should set the remotefile url" do - Chef::Config.remotefile_url.should == "https://junglist.gen.nz" + Chef::Config.remotefile_url.should == "https://junglist.gen.nz" end it "should set the search url" do - Chef::Config.search_url.should == "https://junglist.gen.nz" + Chef::Config.search_url.should == "https://junglist.gen.nz" end it "should set the role url" do - Chef::Config.role_url.should == "https://junglist.gen.nz" + Chef::Config.role_url.should == "https://junglist.gen.nz" end end @@ -50,15 +50,15 @@ describe Chef::Config do Chef::FileCache.stub!(:load).and_return(true) Chef::FileCache.stub!(:has_key?).with("chef_server_cookie_id").and_return(false) end - + it "should generate and store a chef server cookie id" do Chef::FileCache.should_receive(:store).with("chef_server_cookie_id", /\w{40}/).and_return(true) Chef::Config.manage_secret_key end - + describe "when the filecache has a chef server cookie id key" do before do - Chef::FileCache.stub!(:has_key?).with("chef_server_cookie_id").and_return(true) + Chef::FileCache.stub!(:has_key?).with("chef_server_cookie_id").and_return(true) end it "should not generate and store a chef server cookie id" do @@ -66,9 +66,9 @@ describe Chef::Config do Chef::Config.manage_secret_key end end - + end - + describe "config attribute writer: log_method=" do describe "when given an object that responds to sync= e.g. IO" do it "should configure itself to use the IO as log_location" do @@ -76,12 +76,10 @@ describe Chef::Config do Chef::Config.log_location.should == STDOUT end end - + describe "when given an object that is stringable (to_str)" do before do - @mockfile = mock("File", - :path => "/var/log/chef/client.log", - :null_object => true) + @mockfile = mock("File", :path => "/var/log/chef/client.log", :sync= => true) File.should_receive(:new). with("/var/log/chef/client.log", "a"). and_return(@mockfile) @@ -93,13 +91,13 @@ describe Chef::Config do end end end - - describe "class method: openid_providers=" do + + describe "class method: openid_providers=" do it "should not log an appropriate deprecation info message" do Chef::Log.should_not_receive(:info).with("DEPRECATION: openid_providers will be removed, please use authorized_openid_providers").and_return(true) Chef::Config.openid_providers = %w{opscode.com junglist.gen.nz} - end - + end + it "should internally configure authorized_openid_providers with the value given" do Chef::Config.should_receive(:configure).and_return(%w{opscode.com junglist.gen.nz}) Chef::Config.openid_providers = %w{opscode.com junglist.gen.nz} diff --git a/chef/spec/unit/couchdb_spec.rb b/chef/spec/unit/couchdb_spec.rb index ac5e6805a5..cc96a507d1 100644 --- a/chef/spec/unit/couchdb_spec.rb +++ b/chef/spec/unit/couchdb_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,10 +21,10 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper")) describe Chef::CouchDB do before(:each) do Chef::Config[:couchdb_database] = "chef" - @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) + @rest = mock("Chef::REST") + @rest.stub!(:run_request).and_return({"couchdb" => "Welcome", "version" =>"0.9.0"}) + @rest.stub!(:url).and_return("http://localhost:5984") + Chef::REST.stub!(:new).and_return(@rest) @couchdb = Chef::CouchDB.new end @@ -40,32 +40,33 @@ describe Chef::CouchDB do 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 end 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"]) + @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) + @rest.stub!(:get_rest).and_return([]) + @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) + @rest.stub!(:get_rest).and_return(["chef"]) + @rest.should_not_receive(:put_rest) @couchdb.create_db end - + it "should return 'chef'" do + @rest.should_receive(:get_rest).with("_all_dbs").and_return(%w{chef}) @couchdb.create_db.should eql("chef") end end @@ -82,7 +83,7 @@ describe Chef::CouchDB do "views" => { "all" => { "map" => <<-EOJS - function(doc) { + function(doc) { if (doc.chef_type == "node") { emit(doc.name, doc); } @@ -91,46 +92,46 @@ describe Chef::CouchDB do }, } } - @mock_rest.stub!(:get_rest).and_return(@mock_design) - @mock_rest.stub!(:put_rest).and_return(true) + @rest.stub!(:get_rest).and_return(@mock_design) + @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") + @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) + @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) + @rest.should_not_receive(:put_rest) do_create_design_document end end describe "store" do - before(:each) do + before(:each) do @mock_results = { "rows" => [ "id" => 'a0934635-e111-45d9-8223-cb58e1c9434c' @@ -142,7 +143,7 @@ describe Chef::CouchDB do it "should put the object into couchdb with a pre-existing GUID" do item_to_store = {} item_to_store.should_receive(:add_to_index) - @mock_rest.should_receive(:put_rest).with("chef/#{@mock_results["rows"][0]["id"]}", item_to_store).and_return(true) + @rest.should_receive(:put_rest).with("chef/#{@mock_results["rows"][0]["id"]}", item_to_store).and_return(true) @couchdb.store("node", "bob", item_to_store) end @@ -152,7 +153,7 @@ describe Chef::CouchDB do item_to_store.should_receive(:add_to_index).with(:database => "chef", :id => "aaaaaaaa-xxxx-xxxx-xxxx-xxxxxxxxxxx", :type => "node") @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", item_to_store).and_return(true) + @rest.should_receive(:put_rest).with("chef/aaaaaaaa-xxxx-xxxx-xxxx-xxxxxxxxxxx", item_to_store).and_return(true) @couchdb.store("node", "bob", item_to_store) end @@ -160,21 +161,21 @@ describe Chef::CouchDB do describe "when fetching the database status" do it "gets couchdb's version string'" do - @mock_rest.should_receive(:get_rest).with('/').and_return({"couchdb" => "Welcome","version" => "1.0.1"}) + @rest.should_receive(:get_rest).with('/').and_return({"couchdb" => "Welcome","version" => "1.0.1"}) @couchdb.server_stats.should == {"couchdb" => "Welcome","version" => "1.0.1"} end it "gets database stats" do db_stats = {"db_name" => "opscode_account","doc_count" => 206,"doc_del_count" => 1,"update_seq" => 208,"purge_seq" => 0, "compact_running" => false,"disk_size" => 122969,"instance_start_time" => "1298070021394804","disk_format_version" => 5,"committed_update_seq" => 208} - @mock_rest.should_receive(:get_rest).with('/chef').and_return(db_stats) + @rest.should_receive(:get_rest).with('/chef').and_return(db_stats) @couchdb.db_stats.should == db_stats end end describe "load" do - before(:each) 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) @@ -191,27 +192,27 @@ describe Chef::CouchDB do "version" => 1, "_rev" => 1 } - @mock_rest.stub!(:get_rest).and_return(@mock_current) - @mock_rest.stub!(:delete_rest).and_return(true) + @rest.stub!(:get_rest).and_return(@mock_current) + @rest.stub!(:delete_rest).and_return(true) @node = Chef::Node.new() @node.name("bob") @node.couchdb_rev = 15 @couchdb.stub!(:find_by_name).with("node", "bob", true).and_return([ @node, "ax" ]) end - + def do_delete(rev=nil) @couchdb.delete("node", "bob", rev) end - + it "should remove the object from couchdb with a specific revision" do @node.should_receive(:delete_from_index) - @mock_rest.should_receive(:delete_rest).with("chef/ax?rev=1") - do_delete(1) + @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 @node.should_receive(:delete_from_index) - @mock_rest.should_receive(:delete_rest).with("chef/ax?rev=15") + @rest.should_receive(:delete_rest).with("chef/ax?rev=15") do_delete end end @@ -219,21 +220,21 @@ describe Chef::CouchDB do describe "list" do before(:each) do Chef::Config.stub!(:[]).with(:couchdb_database).and_return("chef") - @mock_response = mock("Chef::CouchDB::Response", :null_object => true) + @mock_response = {"rows" => []} end - + 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) + @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) + @rest.should_receive(:get_rest).with("chef/_design/node/_view/all_id").and_return(@mock_response) @couchdb.list("node", false) end end @@ -244,7 +245,7 @@ describe Chef::CouchDB 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) @@ -253,12 +254,12 @@ describe Chef::CouchDB do describe "get_view" do it "should construct a call to the view for the proper design document" do - @mock_rest.should_receive(:get_rest).with("chef/_design/nodes/_view/mastodon") + @rest.should_receive(:get_rest).with("chef/_design/nodes/_view/mastodon") @couchdb.get_view("nodes", "mastodon") end it "should allow arguments to the view" do - @mock_rest.should_receive(:get_rest).with("chef/_design/nodes/_view/mastodon?startkey=%22dont%20stay%22") + @rest.should_receive(:get_rest).with("chef/_design/nodes/_view/mastodon?startkey=%22dont%20stay%22") @couchdb.get_view("nodes", "mastodon", :startkey => "dont stay") end diff --git a/chef/spec/unit/daemon_spec.rb b/chef/spec/unit/daemon_spec.rb index 71706badf7..17437f9a45 100644 --- a/chef/spec/unit/daemon_spec.rb +++ b/chef/spec/unit/daemon_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,7 +17,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper")) -describe Chef::Daemon do +describe Chef::Daemon do before do @original_config = Chef::Config.configuration end @@ -25,43 +25,43 @@ describe Chef::Daemon do after do Chef::Config.configuration.replace(@original_config) end - + describe ".running?" do - + before do Chef::Daemon.name = "spec" end - + describe "when a pid file exists" do - + before do Chef::Daemon.stub!(:pid_from_file).and_return(1337) end - + it "should check that there is a process matching the pidfile" do Process.should_receive(:kill).with(0, 1337) Chef::Daemon.running? end - + end - + describe "when the pid file is nonexistent" do - + before do Chef::Daemon.stub!(:pid_from_file).and_return(nil) end - + it "should return false" do Chef::Daemon.running?.should be_false end - + end end - + describe ".pid_file" do - + describe "when the pid_file option has been set" do - + before do Chef::Config[:pid_file] = "/var/run/chef/chef-client.pid" end @@ -74,35 +74,35 @@ describe Chef::Daemon do Chef::Daemon.pid_file.should eql("/var/run/chef/chef-client.pid") end end - + describe "without the pid_file option set" do - + before do Chef::Config[:pid_file] = nil Chef::Daemon.name = "chef-client" end - + it "should return a valued based on @name" do Chef::Daemon.pid_file.should eql("/tmp/chef-client.pid") end - + end end - + describe ".pid_from_file" do - + before do Chef::Config[:pid_file] = "/var/run/chef/chef-client.pid" end - + it "should suck the pid out of pid_file" do File.should_receive(:read).with("/var/run/chef/chef-client.pid").and_return("1337") Chef::Daemon.pid_from_file end end - + describe ".save_pid_file" do - + before do Process.stub!(:pid).and_return(1337) Chef::Config[:pid_file] = "/var/run/chef/chef-client.pid" @@ -110,59 +110,59 @@ describe Chef::Daemon do @f_mock = mock(File, { :print => true, :close => true, :write => true }) File.stub!(:open).with("/var/run/chef/chef-client.pid", "w").and_yield(@f_mock) end - + it "should try and create the parent directory" do FileUtils.should_receive(:mkdir_p).with("/var/run/chef") Chef::Daemon.save_pid_file end - + it "should open the pid file for writing" do File.should_receive(:open).with("/var/run/chef/chef-client.pid", "w") Chef::Daemon.save_pid_file end - + it "should write the pid, converted to string, to the pid file" do @f_mock.should_receive(:write).with("1337").once.and_return(true) Chef::Daemon.save_pid_file end - + end - + describe ".remove_pid_file" do before do Chef::Config[:pid_file] = "/var/run/chef/chef-client.pid" end - + describe "when the pid file exists" do - + before do File.stub!(:exists?).with("/var/run/chef/chef-client.pid").and_return(true) end - + it "should remove the file" do FileUtils.should_receive(:rm).with("/var/run/chef/chef-client.pid") Chef::Daemon.remove_pid_file end - - + + end - + describe "when the pid file does not exist" do - + before do File.stub!(:exists?).with("/var/run/chef/chef-client.pid").and_return(false) end - + it "should not remove the file" do FileUtils.should_not_receive(:rm) Chef::Daemon.remove_pid_file - end - + end + end end - + describe ".change_privilege" do - + before do Chef::Application.stub!(:fatal!).and_return(true) Chef::Config[:user] = 'aj' @@ -176,79 +176,79 @@ describe Chef::Daemon do end describe "when the user and group options are supplied" do - + before do Chef::Config[:group] = 'staff' end - + it "should log an appropriate info message" do Chef::Log.should_receive(:info).with("About to change privilege to aj:staff") Chef::Daemon.change_privilege end - + it "should call _change_privilege with the user and group" do Chef::Daemon.should_receive(:_change_privilege).with("aj", "staff") Chef::Daemon.change_privilege end end - + describe "when just the user option is supplied" do before do Chef::Config[:group] = nil end - + it "should log an appropriate info message" do Chef::Log.should_receive(:info).with("About to change privilege to aj") Chef::Daemon.change_privilege end - + it "should call _change_privilege with just the user" do Chef::Daemon.should_receive(:_change_privilege).with("aj") Chef::Daemon.change_privilege end end end - + describe "._change_privilege" do - + before do Process.stub!(:euid).and_return(0) Process.stub!(:egid).and_return(0) - + Process::UID.stub!(:change_privilege).and_return(nil) Process::GID.stub!(:change_privilege).and_return(nil) - - @pw_user = mock("Struct::Passwd", :null_object => true, :uid => 501) - @pw_group = mock("Struct::Group", :null_object => true, :gid => 20) - + + @pw_user = mock("Struct::Passwd", :uid => 501) + @pw_group = mock("Struct::Group", :gid => 20) + Process.stub!(:initgroups).and_return(true) - + Etc.stub!(:getpwnam).and_return(@pw_user) Etc.stub!(:getgrnam).and_return(@pw_group) end - describe "with sufficient privileges" do + describe "with sufficient privileges" do before do Process.stub!(:euid).and_return(0) Process.stub!(:egid).and_return(0) end - + it "should initialize the supplemental group list" do Process.should_receive(:initgroups).with("aj", 20) Chef::Daemon._change_privilege("aj") end - + it "should attempt to change the process GID" do Process::GID.should_receive(:change_privilege).with(20).and_return(20) Chef::Daemon._change_privilege("aj") end - + it "should attempt to change the process UID" do Process::UID.should_receive(:change_privilege).with(501).and_return(501) Chef::Daemon._change_privilege("aj") end end - + describe "with insufficient privileges" do before do Process.stub!(:euid).and_return(999) @@ -266,5 +266,5 @@ describe Chef::Daemon do end end - end + end end diff --git a/chef/spec/unit/knife/cookbook_show_spec.rb b/chef/spec/unit/knife/cookbook_show_spec.rb index ed62c55bd4..7158387975 100644 --- a/chef/spec/unit/knife/cookbook_show_spec.rb +++ b/chef/spec/unit/knife/cookbook_show_spec.rb @@ -25,7 +25,7 @@ describe Chef::Knife::CookbookShow do @knife = Chef::Knife::CookbookShow.new @knife.config = { } @knife.name_args = [ "cookbook_name" ] - @rest = mock(Chef::REST, :null_object => true) + @rest = mock(Chef::REST) @knife.stub!(:rest).and_return(@rest) @knife.stub!(:pretty_print).and_return(true) @knife.stub!(:output).and_return(true) diff --git a/chef/spec/unit/provider/cron/solaris_spec.rb b/chef/spec/unit/provider/cron/solaris_spec.rb index 5f9cf9926e..6b99899c1a 100644 --- a/chef/spec/unit/provider/cron/solaris_spec.rb +++ b/chef/spec/unit/provider/cron/solaris_spec.rb @@ -34,9 +34,18 @@ describe Chef::Provider::Cron::Solaris do end describe "when examining the current system state" do + before do + @status = mock("Status", :exitstatus => 0) + @stdin = StringIO.new + @stderr = StringIO.new + @stdout = StringIO.new(<<-CRON) +# Chef Name: cronhole some stuff +* 5 * * * /bin/true +CRON + @pid = 2342 + end it "should report if it can't find the cron entry" do - @status = mock("Status", :exitstatus => 0) @provider.stub!(:popen4).and_return(@status) Chef::Log.should_receive(:debug).with("Cron '#{@new_resource.name}' not found") @provider.load_current_resource @@ -50,25 +59,16 @@ describe Chef::Provider::Cron::Solaris do end it "should report finding a match if the entry exists" do - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: cronhole some stuff\n").and_yield("* 5 * * * /bin/true\n") @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) Chef::Log.should_receive(:debug).with("Found cron '#{@new_resource.name}'") @provider.load_current_resource end it "should not fail if there's an existing cron with a numerical argument" do - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each).and_yield("# Chef Name: foo[bar] (baz)\n"). - and_yield("21 */4 * * * some_prog 1234567\n") + @stdout = StringIO.new(<<-CRON) +# Chef Name: foo[bar] (baz) +21 */4 * * * some_prog 1234567 +CRON @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) lambda { @provider.load_current_resource @@ -84,6 +84,15 @@ describe Chef::Provider::Cron::Solaris do @current_resource.command "/bin/true" @provider.current_resource = @current_resource + + @status = mock("Status", :exitstatus => 0) + @stdin = StringIO.new + @stdout = StringIO.new(<<-CRON) +# Chef Name: bar +* 10 * * * /bin/false +CRON + @stderr = StringIO.new + @pid = 2342 end @@ -104,28 +113,18 @@ describe Chef::Provider::Cron::Solaris do describe Chef::Provider::Cron::Solaris, "action_create" do it "should add the cron entry if cron exists" do - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: bar\n"). - and_yield("* 10 * * * /bin/false\n") @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) Chef::Log.should_receive(:info).with("Added cron '#{@new_resource.name}'") @provider.action_create end it "should create the cron entry even if cron is empty" do - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: bar\n"). - and_yield("* 10 * * * /bin/false\n"). - and_yield("# Chef Name: foo[bar] (baz)\n"). - and_yield("* 5 * * * /bin/true\n") + @stdout = StringIO.new(<<-CRON) +# Chef Name: bar +* 10 * * * /bin/false +# Chef Name: foo[bar] (baz) +* 5 * * * /bin/true +CRON @provider.cron_empty=true @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) Chef::Log.should_receive(:info).with("Added cron '#{@new_resource.name}'") @@ -134,15 +133,12 @@ describe Chef::Provider::Cron::Solaris do it "should update the cron entry if it exists and has changed" do @provider.current_resource = @current_resource - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: bar\n"). - and_yield("* 10 * * * /bin/false\n"). - and_yield("# Chef Name: foo[bar] (baz)\n"). - and_yield("* 5 * * * /bin/true\n") + @stdout = StringIO.new(<<-CRON) +# Chef Name: bar +* 10 * * * /bin/false +# Chef Name: foo[bar] (baz) +* 5 * * * /bin/true +CRON @provider.cron_exists=true @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) Chef::Log.should_receive(:info).with("Updated cron '#{@new_resource.name}'") @@ -151,15 +147,12 @@ describe Chef::Provider::Cron::Solaris do end it "should not update the cron entry if it exists and has not changed" do - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: bar\n"). - and_yield("* 10 * * * /bin/false\n"). - and_yield("# Chef Name: foo[bar] (baz)\n"). - and_yield("30 * * * * /bin/true\n") + @stdout = StringIO.new(<<-CRON) +# Chef Name: bar +* 10 * * * /bin/false +# Chef Name: foo[bar] (baz) +30 * * * * /bin/true +CRON @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) Chef::Log.should_not_receive(:info).with("Updated cron '#{@new_resource.name}'") Chef::Log.should_receive(:debug).with("Skipping existing cron entry '#{@new_resource.name}'") @@ -170,16 +163,13 @@ describe Chef::Provider::Cron::Solaris do it "should update the cron entry if it exists and has changed environment variables" do @provider.current_resource = @current_resource - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: bar\n"). - and_yield("* 10 * * * /bin/false\n"). - and_yield("# Chef Name: foo[bar] (baz)\n"). - and_yield("MAILTO=warn@example.com\n"). - and_yield("30 * * * * /bin/true\n") + @stdout = StringIO.new(<<-CRON) +# Chef Name: bar +* 10 * * * /bin/false +# Chef Name: foo[bar] (baz) +MAILTO=warn@example.com +30 * * * * /bin/true +CRON @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) Chef::Log.should_receive(:info).with("Updated cron '#{@new_resource.name}'") @provider.cron_exists = true @@ -204,15 +194,12 @@ describe Chef::Provider::Cron::Solaris do provider = Chef::Provider::Cron::Solaris.new(resource, @run_context) provider.current_resource = @current_resource - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: lobster rage\n"). - and_yield("* 10 * * * /bin/false\n"). - and_yield("# Chef Name: foo[bar] (baz)\n"). - and_yield("30 * * * * /bin/true\n") + @stdout = StringIO.new(<<-CRON) +# Chef Name: lobster rage +* 10 * * * /bin/false +# Chef Name: foo[bar] (baz) +30 * * * * /bin/true +CRON provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) Chef::Log.should_receive(:info).with("Updated cron 'lobster rage'") provider.cron_exists = true @@ -223,15 +210,12 @@ describe Chef::Provider::Cron::Solaris do describe Chef::Provider::Cron::Solaris, "action_delete" do it "should delete the cron entry if it exists" do - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: bar\n"). - and_yield("* 10 * * * /bin/false\n"). - and_yield("# Chef Name: foo[bar] (baz)\n"). - and_yield("* 30 * * * /bin/true\n") + @stdout = StringIO.new(<<-C) +# Chef Name: bar +* 10 * * * /bin/false +# Chef Name: foo[bar] (baz) +* 30 * * * /bin/true +C @provider.cron_exists=true @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) Chef::Log.should_receive(:info).with("Deleted cron '#{@new_resource.name}'") @@ -240,13 +224,10 @@ describe Chef::Provider::Cron::Solaris do end it "should not delete the cron entry if it does not exist" do - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: bar"). - and_yield("* 10 * * * /bin/false") + @stdout = StringIO.new(<<-C) +# Chef Name: bar +* 10 * * * /bin/false +C @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) Chef::Log.should_not_receive(:info).with("Deleted cron '#{@new_resource.name}'") @provider.action_delete diff --git a/chef/spec/unit/provider/cron_spec.rb b/chef/spec/unit/provider/cron_spec.rb index 9b035a02ee..0437365bfb 100644 --- a/chef/spec/unit/provider/cron_spec.rb +++ b/chef/spec/unit/provider/cron_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,7 +19,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper")) describe Chef::Provider::Cron do - before(:each) do + before do @node = Chef::Node.new @run_context = Chef::RunContext.new(@node, {}) @new_resource = Chef::Resource::Cron.new("cronhole some stuff") @@ -32,6 +32,18 @@ describe Chef::Provider::Cron do end describe "when examining the current system state" do + before do + @status = mock("Status", :exitstatus => 0) + @stdout = StringIO.new(<<-CRONTAB) +# Chef Name: cronhole some stuff +* 5 * * * /bin/true +CRONTAB + + @stdin = StringIO.new + @stderr = StringIO.new + @pid = 2342 + @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) + end it "should report if it can't find the cron entry" do @status = mock("Status", :exitstatus => 0) @@ -48,32 +60,22 @@ describe Chef::Provider::Cron do end it "should report finding a match if the entry exists" do - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: cronhole some stuff\n").and_yield("* 5 * * * /bin/true\n") - @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) Chef::Log.should_receive(:debug).with("Found cron '#{@new_resource.name}'") @provider.load_current_resource end - + it "should not fail if there's an existing cron with a numerical argument" do - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each).and_yield("# Chef Name: foo[bar] (baz)\n"). - and_yield("21 */4 * * * some_prog 1234567\n") + @stdout = StringIO.new(<<-CRON) +# Chef Name: foo[bar] (baz) +21 */4 * * * some_prog 1234567 +CRON @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) lambda { @provider.load_current_resource }.should_not raise_error end end - + describe "when the current crontab state is known" do before do @current_resource = Chef::Resource::Cron.new("cronhole some stuff") @@ -83,11 +85,11 @@ describe Chef::Provider::Cron do @provider.current_resource = @current_resource end - + describe Chef::Provider::Cron, "compare_cron" do %w{ minute hour day month weekday command mailto path shell home }.each do |attribute| - it "should return true if #{attribute} doesn't match" do + it "should return true if #{attribute} doesn't match" do @new_resource.should_receive(attribute).exactly(2).times.and_return(true) @current_resource.should_receive(attribute).once.and_return(false) @provider.compare_cron.should eql(true) @@ -100,136 +102,121 @@ describe Chef::Provider::Cron do end - describe Chef::Provider::Cron, "action_create" do + describe "when creating a new crontab entry" do + before do + @stdout, @stderr, @stdin = StringIO.new, StringIO.new, StringIO.new + end it "should add the cron entry if cron exists" do - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: bar\n"). - and_yield("* 10 * * * /bin/false\n") + @stdout = StringIO.new(<<-CRONTAB) +# Chef Name: bar +* 10 * * * /bin/false +CRONTAB @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) Chef::Log.should_receive(:info).with("Added cron '#{@new_resource.name}'") @provider.action_create end - it "should create the cron entry even if cron is empty" do - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: bar\n"). - and_yield("* 10 * * * /bin/false\n"). - and_yield("# Chef Name: foo[bar] (baz)\n"). - and_yield("* 5 * * * /bin/true\n") - @provider.cron_empty=true - @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) - Chef::Log.should_receive(:info).with("Added cron '#{@new_resource.name}'") - @provider.action_create - end + describe "and there is existing content in the crontab" do + before do + @stdout = StringIO.new(<<-CRON) +# Chef Name: bar +* 10 * * * /bin/false +# Chef Name: foo[bar] (baz) +* 5 * * * /bin/true +CRON - it "should update the cron entry if it exists and has changed" do - @provider.current_resource = @current_resource - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: bar\n"). - and_yield("* 10 * * * /bin/false\n"). - and_yield("# Chef Name: foo[bar] (baz)\n"). - and_yield("* 5 * * * /bin/true\n") - @provider.cron_exists=true - @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) - Chef::Log.should_receive(:info).with("Updated cron '#{@new_resource.name}'") - @provider.should_receive(:compare_cron).once.and_return(true) - @provider.action_create - end + end - it "should not update the cron entry if it exists and has not changed" do - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: bar\n"). - and_yield("* 10 * * * /bin/false\n"). - and_yield("# Chef Name: foo[bar] (baz)\n"). - and_yield("30 * * * * /bin/true\n") - @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) - Chef::Log.should_not_receive(:info).with("Updated cron '#{@new_resource.name}'") - Chef::Log.should_receive(:debug).with("Skipping existing cron entry '#{@new_resource.name}'") - @provider.should_receive(:compare_cron).once.and_return(false) - @provider.cron_exists = true - @provider.action_create - end + it "should create the cron entry even if cron is empty" do + @provider.cron_empty=true + @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) + Chef::Log.should_receive(:info).with("Added cron '#{@new_resource.name}'") + @provider.action_create + end - it "should update the cron entry if it exists and has changed environment variables" do - @provider.current_resource = @current_resource - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: bar\n"). - and_yield("* 10 * * * /bin/false\n"). - and_yield("# Chef Name: foo[bar] (baz)\n"). - and_yield("MAILTO=warn@example.com\n"). - and_yield("30 * * * * /bin/true\n") - @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) - Chef::Log.should_receive(:info).with("Updated cron '#{@new_resource.name}'") - @provider.cron_exists = true - @provider.should_receive(:compare_cron).once.and_return(true) - @provider.action_create - end + it "should update the cron entry if it exists and has changed" do + @provider.current_resource = @current_resource + @provider.cron_exists=true + @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) + Chef::Log.should_receive(:info).with("Updated cron '#{@new_resource.name}'") + @provider.should_receive(:compare_cron).once.and_return(true) + @provider.action_create + end + + it "should not update the cron entry if it exists and has not changed" do + @stdout =StringIO.new(<<-CRON) +# Chef Name: bar +* 10 * * * /bin/false +# Chef Name: foo[bar] (baz) +30 * * * * /bin/true +CRON + @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) + Chef::Log.should_not_receive(:info).with("Updated cron '#{@new_resource.name}'") + Chef::Log.should_receive(:debug).with("Skipping existing cron entry '#{@new_resource.name}'") + @provider.should_receive(:compare_cron).once.and_return(false) + @provider.cron_exists = true + @provider.action_create + end - it "should update the cron entry if it exists and has no environment variables" do - resource = Chef::Resource::Cron.new("lobster rage") - resource.name "lobster rage" - resource.minute "30" - resource.hour "*" - resource.day "*" - resource.month "*" - resource.weekday "*" - resource.mailto "test@example.com" - resource.path nil - resource.shell nil - resource.home nil - resource.command "/bin/true" - - provider = Chef::Provider::Cron.new(resource, @run_context) - provider.current_resource = @current_resource - - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: lobster rage\n"). - and_yield("* 10 * * * /bin/false\n"). - and_yield("# Chef Name: foo[bar] (baz)\n"). - and_yield("30 * * * * /bin/true\n") - provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) - Chef::Log.should_receive(:info).with("Updated cron 'lobster rage'") - provider.cron_exists = true - provider.should_receive(:compare_cron).once.and_return(true) - provider.action_create + it "should update the cron entry if it exists and has changed environment variables" do + @provider.current_resource = @current_resource + @stdout = StringIO.new(<<-CRON) +# Chef Name: bar +* 10 * * * /bin/false +# Chef Name: foo[bar] (baz) +MAILTO=warn@example.com +30 * * * * /bin/true +CRON + @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) + Chef::Log.should_receive(:info).with("Updated cron '#{@new_resource.name}'") + @provider.cron_exists = true + @provider.should_receive(:compare_cron).once.and_return(true) + @provider.action_create + end + + it "should update the cron entry if it exists and has no environment variables" do + resource = Chef::Resource::Cron.new("lobster rage") + resource.name "lobster rage" + resource.minute "30" + resource.hour "*" + resource.day "*" + resource.month "*" + resource.weekday "*" + resource.mailto "test@example.com" + resource.path nil + resource.shell nil + resource.home nil + resource.command "/bin/true" + + provider = Chef::Provider::Cron.new(resource, @run_context) + provider.current_resource = @current_resource + + @stdout = StringIO.new(<<-CRON) +# Chef Name: lobster rage +* 10 * * * /bin/false +# Chef Name: foo[bar] (baz) +30 * * * * /bin/true +CRON + provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) + Chef::Log.should_receive(:info).with("Updated cron 'lobster rage'") + provider.cron_exists = true + provider.should_receive(:compare_cron).once.and_return(true) + provider.action_create + end end end describe Chef::Provider::Cron, "action_delete" do + before do + @stdin = StringIO.new + end it "should delete the cron entry if it exists" do - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: bar\n"). - and_yield("* 10 * * * /bin/false\n"). - and_yield("# Chef Name: foo[bar] (baz)\n"). - and_yield("* 30 * * * /bin/true\n") + @stdout = StringIO.new(<<-CRON) +# Chef Name: bar +* 10 * * * /bin/false +# Chef Name: foo[bar] (baz) +* 30 * * * /bin/true +CRON @provider.cron_exists=true @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) Chef::Log.should_receive(:debug).with("Deleted cron '#{@new_resource.name}'") @@ -238,13 +225,10 @@ describe Chef::Provider::Cron do end it "should not delete the cron entry if it does not exist" do - @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) - @stdout.stub!(:each_line).and_yield("# Chef Name: bar"). - and_yield("* 10 * * * /bin/false") + @stdout = StringIO.new(<<-CRON) +# Chef Name: bar +* 10 * * * /bin/false +CRON @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) Chef::Log.should_not_receive(:debug).with("Deleted cron '#{@new_resource.name}'") @provider.action_delete diff --git a/chef/spec/unit/provider/deploy/revision_spec.rb b/chef/spec/unit/provider/deploy/revision_spec.rb index f61d709562..aea87ae2b3 100644 --- a/chef/spec/unit/provider/deploy/revision_spec.rb +++ b/chef/spec/unit/provider/deploy/revision_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,7 +19,7 @@ require File.expand_path(File.join(File.dirname(__FILE__),"..", "..", "..", "spec_helper")) describe Chef::Provider::Deploy::Revision do - + before do Chef::Config[:file_cache_path] = '/tmp/foo' @resource = Chef::Resource::Deploy.new("/my/deploy/dir") @@ -28,27 +28,27 @@ describe Chef::Provider::Deploy::Revision do @run_context = Chef::RunContext.new(@node, {}) @provider = Chef::Provider::Deploy::Revision.new(@resource, @run_context) @provider.load_current_resource - @runner = mock("runnah", :null_object => true) + @runner = mock("runnah") Chef::Runner.stub!(:new).and_return(@runner) @expected_release_dir = "/my/deploy/dir/releases/8a3195bf3efa246f743c5dfa83683201880f935c" end - + after do # Make sure we don't keep any state in our tests FileUtils.rspec_reset FileUtils.rm_rf '/tmp/foo' if File.directory?("/tmp/foo") end - - + + it "uses the resolved revision from the SCM as the release slug" do @provider.scm_provider.stub!(:revision_slug).and_return("uglySlugly") @provider.send(:release_slug).should == "uglySlugly" end - + it "deploys to a dir named after the revision" do @provider.release_path.should == @expected_release_dir end - + it "stores the release dir in the file cache when copying the cached repo" do FileUtils.stub!(:mkdir_p) @provider.stub!(:run_command).and_return(true) @@ -57,10 +57,10 @@ describe Chef::Provider::Deploy::Revision do @provider.load_current_resource @provider.copy_cached_repo second_release = "/my/deploy/dir/releases/73219b87e977d9c7ba1aa57e9ad1d88fa91a0ec2" - + @provider.all_releases.should == [@expected_release_dir,second_release] end - + it "removes a release from the file cache when it's used again in another release and append it to the end" do FileUtils.stub!(:mkdir_p) @provider.stub!(:run_command).and_return(true) @@ -76,18 +76,18 @@ describe Chef::Provider::Deploy::Revision do @provider.copy_cached_repo @provider.all_releases.should == [second_release, @expected_release_dir] end - + it "removes a release from the file cache when it's deleted by :cleanup!" do %w{first second third fourth fifth latest}.each do |release_name| @provider.send(:release_created, release_name) end @provider.all_releases.should == %w{first second third fourth fifth latest} - + FileUtils.stub!(:rm_rf) @provider.cleanup! @provider.all_releases.should == %w{second third fourth fifth latest} end - + it "regenerates the file cache if it's not available" do oldest = "/my/deploy/dir/releases/oldest" latest = "/my/deploy/dir/releases/latest" diff --git a/chef/spec/unit/provider/deploy/timestamped_spec.rb b/chef/spec/unit/provider/deploy/timestamped_spec.rb index f524b29128..06e58c52d5 100644 --- a/chef/spec/unit/provider/deploy/timestamped_spec.rb +++ b/chef/spec/unit/provider/deploy/timestamped_spec.rb @@ -28,7 +28,7 @@ describe Chef::Provider::Deploy::Timestamped do @node = Chef::Node.new @run_context = Chef::RunContext.new(@node, {}) @timestamped_deploy = Chef::Provider::Deploy::Timestamped.new(@resource, @run_context) - @runner = mock("runnah", :null_object => true) + @runner = mock("runnah") Chef::Runner.stub!(:new).and_return(@runner) end diff --git a/chef/spec/unit/provider/deploy_spec.rb b/chef/spec/unit/provider/deploy_spec.rb index d6e1c1211d..6e1474665b 100644 --- a/chef/spec/unit/provider/deploy_spec.rb +++ b/chef/spec/unit/provider/deploy_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,7 +19,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper")) describe Chef::Provider::Deploy do - + before do @release_time = Time.utc( 2004, 8, 15, 16, 23, 42) Time.stub!(:now).and_return(@release_time) @@ -31,12 +31,12 @@ describe Chef::Provider::Deploy do @provider.stub!(:release_slug) @provider.stub!(:release_path).and_return(@expected_release_dir) end - + it "supports :deploy and :rollback actions" do @provider.should respond_to(:action_deploy) @provider.should respond_to(:action_rollback) end - + it "updates and copies the repo, then does a migrate, symlink, restart, restart, cleanup on deploy" do @provider.should_receive(:enforce_ownership).twice @provider.should_receive(:update_cached_repo) @@ -52,7 +52,7 @@ describe Chef::Provider::Deploy do @provider.should_receive(:cleanup!) @provider.deploy end - + it "should not deploy if there is already a deploy at release_path, and it is the current release" do @provider.stub!(:all_releases).and_return([@expected_release_dir]) @provider.should_not_receive(:deploy) @@ -64,33 +64,33 @@ describe Chef::Provider::Deploy do @provider.should_receive(:action_rollback) @provider.action_deploy end - + it "calls deploy when deploying a new release" do @provider.stub!(:all_releases).and_return([]) @provider.should_receive(:deploy) @provider.action_deploy end - + it "runs action svn_force_export when new_resource.svn_force_export is true" do @resource.svn_force_export true @provider.scm_provider.should_receive(:action_force_export) @provider.svn_force_export end - + it "Removes the old release before deploying when force deploying over it" do @provider.stub!(:all_releases).and_return([@expected_release_dir]) FileUtils.should_receive(:rm_rf).with(@expected_release_dir) @provider.should_receive(:deploy) @provider.action_force_deploy end - + it "deploys as normal when force deploying and there's no prior release at the same path" do @provider.stub!(:all_releases).and_return([]) @provider.should_receive(:deploy) @provider.action_force_deploy end - - + + describe "on systems without broken Dir.glob results" do it "sets the release path to the penultimate release when one is not specified, symlinks, and rm's the last release on rollback" do @provider.stub!(:release_path).and_return("/my/deploy/dir/releases/3") @@ -148,7 +148,7 @@ describe Chef::Provider::Deploy do Dir.stub!(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases) lambda {@provider.action_rollback}.should raise_error(RuntimeError) end - + it "runs the new resource collection in the runner during a callback" do @runner = mock("Runner") Chef::Runner.stub!(:new).and_return(@runner) @@ -156,7 +156,7 @@ describe Chef::Provider::Deploy do callback_code = Proc.new { :noop } @provider.callback(:whatevs, callback_code) end - + it "loads callback files from the release/ dir if the file exists" do foo_callback = @expected_release_dir + "/deploy/foo.rb" ::File.should_receive(:exist?).with(foo_callback).twice.and_return(true) @@ -164,13 +164,13 @@ describe Chef::Provider::Deploy do @provider.should_receive(:from_file).with(foo_callback) @provider.callback(:foo, "deploy/foo.rb") end - + it "raises a runtime error if a callback file is explicitly specified but does not exist" do baz_callback = @expected_release_dir + "/deploy/baz.rb" ::File.should_receive(:exist?).with(baz_callback).and_return(false) lambda {@provider.callback(:foo, "deploy/baz.rb")}.should raise_error(RuntimeError) end - + it "runs a default callback if the callback code is nil" do bar_callback = @expected_release_dir + "/deploy/bar.rb" ::File.should_receive(:exist?).with(bar_callback).and_return(true) @@ -178,51 +178,51 @@ describe Chef::Provider::Deploy do @provider.should_receive(:from_file).with(bar_callback) @provider.callback(:bar, nil) end - + it "skips an eval callback if the file doesn't exist" do barbaz_callback = @expected_release_dir + "/deploy/barbaz.rb" ::File.should_receive(:exist?).with(barbaz_callback).and_return(false) @provider.should_not_receive(:from_file) @provider.callback(:barbaz, nil) end - + it "gets a SCM provider as specified by its resource" do @provider.scm_provider.should be_an_instance_of(Chef::Provider::Git) @provider.scm_provider.new_resource.destination.should eql("/my/deploy/dir/shared/cached-copy") end - + it "syncs the cached copy of the repo" do @provider.scm_provider.should_receive(:action_sync) @provider.update_cached_repo end - + it "makes a copy of the cached repo in releases dir" do - FileUtils.should_receive(:mkdir_p).with("/my/deploy/dir/releases") + FileUtils.should_receive(:mkdir_p).with("/my/deploy/dir/releases") @provider.should_receive(:run_command).with({:command => "cp -RPp /my/deploy/dir/shared/cached-copy/. #{@expected_release_dir}"}) @provider.copy_cached_repo end - + it "calls the internal callback :release_created when copying the cached repo" do FileUtils.stub!(:mkdir_p) @provider.stub!(:run_command).and_return(true) @provider.should_receive(:release_created) @provider.copy_cached_repo end - + it "chowns the whole release dir to user and group specified in the resource" do @resource.user "foo" @resource.group "bar" FileUtils.should_receive(:chown_R).with("foo", "bar", "/my/deploy/dir") @provider.enforce_ownership end - + it "skips the migration when resource.migrate => false but runs symlinks before migration" do @resource.migrate false @provider.should_not_receive :run_command @provider.should_receive :run_symlinks_before_migrate @provider.migrate end - + it "links the database.yml and runs resource.migration_command when resource.migrate #=> true" do @resource.migrate true @resource.migration_command "migration_foo" @@ -231,19 +231,19 @@ describe Chef::Provider::Deploy do @resource.environment "RAILS_ENV" => "production" FileUtils.should_receive(:ln_sf).with("/my/deploy/dir/shared/config/database.yml", @expected_release_dir + "/config/database.yml") @provider.should_receive(:enforce_ownership) - @provider.should_receive(:run_command).with(:command => "migration_foo", :cwd => @expected_release_dir, - :user => "deployNinja", :group => "deployNinjas", + @provider.should_receive(:run_command).with(:command => "migration_foo", :cwd => @expected_release_dir, + :user => "deployNinja", :group => "deployNinjas", :environment => {"RAILS_ENV"=>"production"}) @provider.migrate end - + it "purges the current release's /log /tmp/pids/ and /public/system directories" do FileUtils.should_receive(:rm_rf).with(@expected_release_dir + "/log") FileUtils.should_receive(:rm_rf).with(@expected_release_dir + "/tmp/pids") FileUtils.should_receive(:rm_rf).with(@expected_release_dir + "/public/system") @provider.purge_tempfiles_from_current_release end - + it "symlinks temporary files and logs from the shared dir into the current release" do FileUtils.should_receive(:mkdir_p).with(@expected_release_dir + "/tmp") FileUtils.should_receive(:mkdir_p).with(@expected_release_dir + "/public") @@ -255,23 +255,23 @@ describe Chef::Provider::Deploy do @provider.should_receive(:enforce_ownership) @provider.link_tempfiles_to_current_release end - + it "symlinks the current release dir into production" do FileUtils.should_receive(:rm_f).with("/my/deploy/dir/current") FileUtils.should_receive(:ln_sf).with(@expected_release_dir, "/my/deploy/dir/current") @provider.should_receive(:enforce_ownership) @provider.link_current_release_to_production end - + context "with a customized app layout" do - + before do @resource.purge_before_symlink(%w{foo bar}) @resource.create_dirs_before_symlink(%w{baz qux}) @resource.symlinks "foo/bar" => "foo/bar", "baz" => "qux/baz" @resource.symlink_before_migrate "radiohead/in_rainbows.yml" => "awesome" end - + it "purges the purge_before_symlink directories" do FileUtils.should_receive(:rm_rf).with(@expected_release_dir + "/foo") FileUtils.should_receive(:rm_rf).with(@expected_release_dir + "/bar") @@ -289,27 +289,27 @@ describe Chef::Provider::Deploy do end end - + it "does nothing for restart if restart_command is empty" do @provider.should_not_receive(:run_command) @provider.restart end - + it "runs the restart command in the current application dir when the resource has a restart_command" do @resource.restart_command "restartcmd" @provider.should_receive(:run_command).with(:command => "restartcmd", :cwd => "/my/deploy/dir/current") @provider.restart end - + it "lists all available releases" do - all_releases = ["/my/deploy/dir/20040815162342", "/my/deploy/dir/20040700000000", + all_releases = ["/my/deploy/dir/20040815162342", "/my/deploy/dir/20040700000000", "/my/deploy/dir/20040600000000", "/my/deploy/dir/20040500000000"].sort! Dir.should_receive(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases) @provider.all_releases.should eql(all_releases) end - + it "removes all but the 5 newest releases" do - all_releases = ["/my/deploy/dir/20040815162342", "/my/deploy/dir/20040700000000", + all_releases = ["/my/deploy/dir/20040815162342", "/my/deploy/dir/20040700000000", "/my/deploy/dir/20040600000000", "/my/deploy/dir/20040500000000", "/my/deploy/dir/20040400000000", "/my/deploy/dir/20040300000000", "/my/deploy/dir/20040200000000", "/my/deploy/dir/20040100000000"].sort! @@ -319,9 +319,9 @@ describe Chef::Provider::Deploy do FileUtils.should_receive(:rm_rf).with("/my/deploy/dir/20040300000000") @provider.cleanup! end - + it "fires a callback for :release_deleted when deleting an old release" do - all_releases = ["/my/deploy/dir/20040815162342", "/my/deploy/dir/20040700000000", + all_releases = ["/my/deploy/dir/20040815162342", "/my/deploy/dir/20040700000000", "/my/deploy/dir/20040600000000", "/my/deploy/dir/20040500000000", "/my/deploy/dir/20040400000000", "/my/deploy/dir/20040300000000"].sort! @provider.stub!(:all_releases).and_return(all_releases) @@ -329,27 +329,27 @@ describe Chef::Provider::Deploy do @provider.should_receive(:release_deleted).with("/my/deploy/dir/20040300000000") @provider.cleanup! end - + it "puts resource.to_hash in @configuration for backwards compat with capistano-esque deploy hooks" do @provider.instance_variable_get(:@configuration).should == @resource.to_hash end - + it "sets @configuration[:environment] to the value of RAILS_ENV for backwards compat reasons" do resource = Chef::Resource::Deploy.new("/my/deploy/dir") - resource.environment "production" + resource.environment "production" provider = Chef::Provider::Deploy.new(resource, @run_context) provider.instance_variable_get(:@configuration)[:environment].should eql("production") end - + it "shouldn't give a no method error on migrate if the environment is nil" do @provider.stub!(:enforce_ownership) @provider.stub!(:run_symlinks_before_migrate) @provider.stub!(:run_command) @provider.migrate end - + context "using inline recipes for callbacks" do - + it "runs an inline recipe with the provided block for :callback_name == {:recipe => &block} " do snitch = nil recipe_code = Proc.new {snitch = 42} @@ -357,14 +357,14 @@ describe Chef::Provider::Deploy do @provider.callback(:whateverz, recipe_code) snitch.should == 42 end - + it "loads a recipe file from the specified path and from_file evals it" do ::File.should_receive(:exist?).with(@expected_release_dir + "/chefz/foobar_callback.rb").twice.and_return(true) ::Dir.should_receive(:chdir).with(@expected_release_dir).and_yield @provider.should_receive(:from_file).with(@expected_release_dir + "/chefz/foobar_callback.rb") @provider.callback(:whateverz, "chefz/foobar_callback.rb") end - + it "instance_evals a block/proc for restart command" do snitch = nil restart_cmd = Proc.new {snitch = 42} @@ -372,9 +372,9 @@ describe Chef::Provider::Deploy do @provider.restart snitch.should == 42 end - + end - + describe "API bridge to capistrano" do it "defines sudo as a forwarder to execute" do @provider.should_receive(:execute).with("the moon, fool") @@ -392,16 +392,16 @@ describe Chef::Provider::Deploy do mock_execution.should_receive(:group).with("Ggroup") mock_execution.should_receive(:cwd){|*args| if args.empty? - nil - else + nil + else args.size.should == 1 args.first.should == @provider.release_path end }.twice mock_execution.should_receive(:environment){ |*args| - if args.empty? - nil - else + if args.empty? + nil + else args.size.should == 1 args.first.should == {"APP_ENV" => "staging"} end @@ -420,43 +420,44 @@ describe Chef::Provider::Deploy do end it "converts sudo and run to exec resources in hooks" do - runner = mock("tehRunner", :null_object => true) + runner = mock("tehRunner") Chef::Runner.stub!(:new).and_return(runner) - + snitch = nil @resource.user("tehCat") - + callback_code = Proc.new do snitch = 42 temp_collection = self.resource_collection run("tehMice") snitch = temp_collection.lookup("execute[tehMice]") end - + + runner.should_receive(:converge) @provider.callback(:phony, callback_code) snitch.should be_an_instance_of(Chef::Resource::Execute) snitch.user.should == "tehCat" end end - + describe "installing gems from a gems.yml" do - + before do ::File.stub!(:exist?).with("#{@expected_release_dir}/gems.yml").and_return(true) @gem_list = [{:name=>"eventmachine", :version=>"0.12.9"}] end - + it "reads a gems.yml file, creating gem providers for each with action :upgrade" do IO.should_receive(:read).with("#{@expected_release_dir}/gems.yml").and_return("cookie") YAML.should_receive(:load).with("cookie").and_return(@gem_list) - + gems = @provider.send(:gem_packages) - + gems.map { |g| g.action }.should == [[:install]] gems.map { |g| g.name }.should == %w{eventmachine} gems.map { |g| g.version }.should == %w{0.12.9} end - + it "takes a list of gem providers converges them" do IO.stub!(:read) YAML.stub!(:load).and_return(@gem_list) @@ -466,7 +467,7 @@ describe Chef::Provider::Deploy do actual = gem_runner.run_context.resource_collection.all_resources.map { |r| [r.name, r.version] } actual.should == expected_gem_resources end - + end - + end diff --git a/chef/spec/unit/provider/directory_spec.rb b/chef/spec/unit/provider/directory_spec.rb index 2aa5c83543..bb0443e17b 100644 --- a/chef/spec/unit/provider/directory_spec.rb +++ b/chef/spec/unit/provider/directory_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -25,17 +25,17 @@ describe Chef::Provider::Directory do @new_resource = Chef::Resource::Directory.new('/tmp') @new_resource.owner(500) @new_resource.group(500) - @new_resource.mode(0644) + @new_resource.mode(0644) @node = Chef::Node.new @run_context = Chef::RunContext.new(@node, {}) - + @directory = Chef::Provider::Directory.new(@new_resource, @run_context) end - + it "should load the current resource based on the new resource" do File.stub!(:exist?).and_return(true) File.should_receive(:directory?).once.and_return(true) - cstats = mock("stats", :null_object => true) + cstats = mock("stats") cstats.stub!(:uid).and_return(500) cstats.stub!(:gid).and_return(500) cstats.stub!(:mode).and_return(0755) @@ -46,7 +46,7 @@ describe Chef::Provider::Directory do @directory.current_resource.group.should eql(500) @directory.current_resource.mode.should eql("755") end - + it "should create a new directory on create, setting updated to true" do load_mock_provider File.should_receive(:exists?).once.and_return(false) @@ -57,7 +57,7 @@ describe Chef::Provider::Directory do @directory.action_create @directory.new_resource.should be_updated end - + it "should not create the directory if it already exists" do load_mock_provider File.should_receive(:exists?).once.and_return(true) @@ -65,9 +65,9 @@ describe Chef::Provider::Directory do @directory.stub!(:set_owner).and_return(true) @directory.stub!(:set_group).and_return(true) @directory.stub!(:set_mode).and_return(true) - @directory.action_create + @directory.action_create end - + it "should delete the directory if it exists, and is writable with action_delete" do load_mock_provider File.should_receive(:directory?).once.and_return(true) @@ -75,18 +75,18 @@ describe Chef::Provider::Directory do Dir.should_receive(:delete).with(@new_resource.path).once.and_return(true) @directory.action_delete end - + it "should raise an exception if it cannot delete the file due to bad permissions" do load_mock_provider File.stub!(:exists?).and_return(true) File.stub!(:writable?).and_return(false) lambda { @directory.action_delete }.should raise_error(RuntimeError) end - + def load_mock_provider File.stub!(:exist?).and_return(true) File.stub!(:directory?).and_return(true) - cstats = mock("stats", :null_object => true) + cstats = mock("stats") cstats.stub!(:uid).and_return(500) cstats.stub!(:gid).and_return(500) cstats.stub!(:mode).and_return(0755) diff --git a/chef/spec/unit/provider/erl_call_spec.rb b/chef/spec/unit/provider/erl_call_spec.rb index e685c80606..5f9f6e5df6 100644 --- a/chef/spec/unit/provider/erl_call_spec.rb +++ b/chef/spec/unit/provider/erl_call_spec.rb @@ -33,7 +33,7 @@ describe Chef::Provider::ErlCall do @provider.stub!(:popen4).and_return(@status) @stdin = StringIO.new @stdout = StringIO.new('{ok, woohoo}') - @stderr = mock("STDERR", :null_object => true) + @stderr = StringIO.new @pid = 2342999 end diff --git a/chef/spec/unit/provider/group/dscl_spec.rb b/chef/spec/unit/provider/group/dscl_spec.rb index 876dbb7f4b..1e8fe5d20f 100644 --- a/chef/spec/unit/provider/group/dscl_spec.rb +++ b/chef/spec/unit/provider/group/dscl_spec.rb @@ -26,13 +26,11 @@ describe Chef::Provider::Group::Dscl do @current_resource = Chef::Resource::Group.new("aj") @provider = Chef::Provider::Group::Dscl.new(@new_resource, @run_context) @provider.current_resource = @current_resource - @status = mock("Process::Status", :null_object => true, :exitstatus => 0) - @pid = mock("PID", :null_object => true) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @stdout.stub!(:each).and_yield("\n") - @stderr.stub!(:each).and_yield("") + @status = mock("Process::Status", :exitstatus => 0) + @pid = 2342 + @stdin = StringIO.new + @stdout = StringIO.new("\n") + @stderr = StringIO.new("") @provider.stub!(:popen4).and_yield(@pid,@stdin,@stdout,@stderr).and_return(@status) end @@ -50,9 +48,7 @@ describe Chef::Provider::Group::Dscl do describe "safe_dscl" do before do @node = Chef::Node.new - @new_resource = mock("Chef::Resource::Group", :null_object => true, :group_name => "aj") @provider = Chef::Provider::Group::Dscl.new(@node, @new_resource) - @status = mock("Process::Status", :null_object => true, :exitstatus => 0) @provider.stub!(:dscl).and_return(["cmd", @status, "stdout", "stderr"]) end @@ -63,7 +59,7 @@ describe Chef::Provider::Group::Dscl do describe "with the dscl command returning a non zero exit status for a delete" do before do - @status = mock("Process::Status", :null_object => true, :exitstatus => 1) + @status = mock("Process::Status", :exitstatus => 1) @provider.stub!(:dscl).and_return(["cmd", @status, "stdout", "stderr"]) end @@ -80,7 +76,6 @@ describe Chef::Provider::Group::Dscl do describe "with the dscl command returning no such key" do before do - # @status = mock("Process::Status", :null_object => true, :exitstatus => 0) @provider.stub!(:dscl).and_return(["cmd", @status, "No such key: ", "stderr"]) end @@ -101,7 +96,6 @@ describe Chef::Provider::Group::Dscl do describe "get_free_gid" do before do @node = Chef::Node.new - @new_resource = mock("Chef::Resource::Group", :null_object => true, :group_name => "aj") @provider = Chef::Provider::Group::Dscl.new(@node, @new_resource) @provider.stub!(:safe_dscl).and_return("\naj 200\njt 201\n") end @@ -124,7 +118,6 @@ describe Chef::Provider::Group::Dscl do describe "gid_used?" do before do @node = Chef::Node.new - @new_resource = mock("Chef::Resource::Group", :null_object => true, :group_name => "aj") @provider = Chef::Provider::Group::Dscl.new(@node, @new_resource) @provider.stub!(:safe_dscl).and_return("\naj 500\n") end diff --git a/chef/spec/unit/provider/group/groupadd_spec.rb b/chef/spec/unit/provider/group/groupadd_spec.rb index 6e16817b97..7822f9c6fd 100644 --- a/chef/spec/unit/provider/group/groupadd_spec.rb +++ b/chef/spec/unit/provider/group/groupadd_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -22,38 +22,32 @@ describe Chef::Provider::Group::Groupadd, "set_options" do before do @node = Chef::Node.new @run_context = Chef::RunContext.new(@node, {}) - @new_resource = mock("Chef::Resource::Group", - :null_object => true, - :group_name => "aj", - :gid => 50, - :members => [ "root", "aj"] - ) - @current_resource = mock("Chef::Resource::Group", - :null_object => true, - :group_name => "aj", - :gid => 50, - :members => [ "root", "aj"] - ) + @new_resource = Chef::Resource::Group.new("aj") + @new_resource.gid(50) + @new_resource.members(["root", "aj"]) + @current_resource = Chef::Resource::Group.new("aj") + @current_resource.gid(50) + @current_resource.members(["root", "aj"]) @provider = Chef::Provider::Group::Groupadd.new(@new_resource, @run_context) - @provider.current_resource = @current_resource + @provider.current_resource = @current_resource end - + field_list = { :gid => "-g" } - + field_list.each do |attribute, option| it "should check for differences in #{attribute.to_s} between the current and new resources" do @new_resource.should_receive(attribute) @current_resource.should_receive(attribute) - @provider.set_options - end + @provider.set_options + end it "should set the option for #{attribute} if the new resources #{attribute} is not null" do @new_resource.stub!(attribute).and_return("wowaweea") @provider.set_options.should eql(" #{option} '#{@new_resource.send(attribute)}' #{@new_resource.group_name}") end end - + it "should combine all the possible options" do match_string = "" field_list.sort{ |a,b| a[0] <=> b[0] }.each do |attribute, option| @@ -68,18 +62,18 @@ end describe Chef::Provider::Group::Groupadd, "create_group" do before do @node = Chef::Node.new - @new_resource = mock("Chef::Resource::Group", :null_object => true) + @new_resource = Chef::Resource::Group.new("aj") @provider = Chef::Provider::Group::Groupadd.new(@node, @new_resource) @provider.stub!(:run_command).and_return(true) @provider.stub!(:set_options).and_return(" monkey") @provider.stub!(:modify_group_members).and_return(true) end - + it "should run groupadd with the return of set_options" do @provider.should_receive(:run_command).with({ :command => "groupadd monkey" }).and_return(true) @provider.create_group end - + it "should modify the group members" do @provider.should_receive(:modify_group_members).and_return(true) @provider.create_group @@ -90,18 +84,18 @@ describe Chef::Provider::Group::Groupadd, "manage_group" do before do @node = Chef::Node.new @run_context = Chef::RunContext.new(@node, {}) - @new_resource = mock("Chef::Resource::Group", :null_object => true) + @new_resource = Chef::Resource::Group.new("aj") @provider = Chef::Provider::Group::Groupadd.new(@new_resource, @run_context) @provider.stub!(:run_command).and_return(true) @provider.stub!(:set_options).and_return(" monkey") @provider.stub!(:modify_group_members).and_return(true) end - + it "should run groupmod with the return of set_options" do @provider.should_receive(:run_command).with({ :command => "groupmod monkey" }).and_return(true) @provider.manage_group end - + it "should modify the group members" do @provider.should_receive(:modify_group_members).and_return(true) @provider.manage_group @@ -112,14 +106,11 @@ describe Chef::Provider::Group::Groupadd, "remove_group" do before do @node = Chef::Node.new @run_context = Chef::RunContext.new(@node, {}) - @new_resource = mock("Chef::Resource::Group", - :null_object => true, - :group_name => "aj" - ) + @new_resource = Chef::Resource::Group.new("aj") @provider = Chef::Provider::Group::Groupadd.new(@new_resource, @run_context) @provider.stub!(:run_command).and_return(true) end - + it "should run groupdel with the new resources group name" do @provider.should_receive(:run_command).with({ :command => "groupdel aj" }).and_return(true) @provider.remove_group @@ -130,13 +121,9 @@ describe Chef::Provider::Group::Groupadd, "modify_group_members" do before do @node = Chef::Node.new @run_context = Chef::RunContext.new(@node, {}) - @new_resource = mock("Chef::Resource::Group", - :null_object => true, - :group_name => "aj", - :members => [ "all", "your", "base" ], - :append => false - ) - @new_resource.stub!(:to_s).and_return("group[aj]") + @new_resource = Chef::Resource::Group.new("aj") + @new_resource.members(["all", "your", "base"]) + @new_resource.append(false) @provider = Chef::Provider::Group::Groupadd.new(@new_resource, @run_context) @provider.stub!(:run_command).and_return(true) end @@ -151,7 +138,7 @@ describe Chef::Provider::Group::Usermod, "load_current_resource" do @node = Chef::Node.new @run_context = Chef::RunContext.new(@node, {}) Chef::Node.stub!(:new).and_return(@node) - @new_resource = mock("Chef::Resource::Group", :null_object => true, :group_name => "aj") + @new_resource = Chef::Resource::Group.new("aj") @provider = Chef::Provider::Group::Usermod.new(@new_resource, @run_context) File.stub!(:exists?).and_return(false) end diff --git a/chef/spec/unit/provider/link_spec.rb b/chef/spec/unit/provider/link_spec.rb index b556c2f64e..98676d9433 100644 --- a/chef/spec/unit/provider/link_spec.rb +++ b/chef/spec/unit/provider/link_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -22,7 +22,7 @@ describe Chef::Resource::Link do before do @node = Chef::Node.new @run_context = Chef::RunContext.new(@node, {}) - + @new_resource = Chef::Resource::Link.new("/tmp/fofile-link") @new_resource.to "/tmp/fofile" @@ -34,7 +34,7 @@ describe Chef::Resource::Link do File.stub!(:delete).and_return("") File.stub!(:symlink).and_return("") - lstat = mock("stats", :null_object => true) + lstat = mock("stats", :ino => 5) lstat.stub!(:uid).and_return(501) lstat.stub!(:gid).and_return(501) @@ -46,25 +46,25 @@ describe Chef::Resource::Link do @provider.load_current_resource @provider.current_resource.target_file.should == "/tmp/fofile-link" end - + it "should set the link type" do @provider.load_current_resource @provider.current_resource.link_type.should == :symbolic end - + describe "when the link type is symbolic" do - + before do @new_resource.link_type(:symbolic) end - + describe "and the target exists and is a symlink" do before do File.stub!(:exists?).with("/tmp/fofile-link").and_return(true) File.stub!(:symlink?).with("/tmp/fofile-link").and_return(true) File.stub!(:readlink).with("/tmp/fofile-link").and_return("/tmp/fofile") end - + it "should update the source of the existing link with the links target" do @provider.load_current_resource @provider.current_resource.to.should == "/tmp/fofile" @@ -73,72 +73,70 @@ describe Chef::Resource::Link do @provider.load_current_resource @provider.current_resource.owner.should == 501 end - + it "should set the group" do @provider.load_current_resource @provider.current_resource.group.should == 501 end end - + describe "and the target doesn't exist" do before do File.should_receive(:exists?).with("/tmp/fofile-link").and_return(false) end - + it "should update the source of the existing link to an empty string" do @provider.load_current_resource @provider.current_resource.to.should == '' end - + end - + describe "and the target isn't a symlink" do before do File.should_receive(:symlink?).with("/tmp/fofile-link").and_return(false) end - + it "should update the current source of the existing link with an empty string" do @provider.load_current_resource @provider.current_resource.to.should == '' end end end - + describe "when the link type is hard, " do before do @new_resource.stub!(:link_type).and_return(:hard) end - + describe "the target file and source file both exist" do before do File.should_receive(:exists?).with("/tmp/fofile-link").and_return(true) File.should_receive(:exists?).with("/tmp/fofile").and_return(true) end - + describe "and the inodes match" do before do - stat = mock("stats", :null_object => true) + stat = mock("stats") stat.stub!(:ino).and_return(1) File.should_receive(:stat).with("/tmp/fofile-link").and_return(stat) File.should_receive(:stat).with("/tmp/fofile").and_return(stat) end - + it "should update the source of the existing link to the target file" do @provider.load_current_resource @provider.current_resource.to.should == "/tmp/fofile" end end - + describe "and the inodes don't match" do before do - stat = mock("stats", :null_object => true) - stat.stub!(:ino).and_return(1) - stat_two = mock("stats", :null_object => true) - stat.stub!(:ino).and_return(2) + stat = mock("stats", :ino => 1) + stat_two = mock("stats", :ino => 2) File.should_receive(:stat).with("/tmp/fofile-link").and_return(stat) File.should_receive(:stat).with("/tmp/fofile").and_return(stat_two) end - + it "should set the source of the existing link to an empty string" do @provider.load_current_resource @provider.current_resource.to.should == '' @@ -149,7 +147,7 @@ describe Chef::Resource::Link do before do File.should_receive(:exists?).with("/tmp/fofile-link").and_return(false) end - + it "should set the source of the existing link to an empty string" do @provider.load_current_resource @provider.current_resource.to.should == '' @@ -159,7 +157,7 @@ describe Chef::Resource::Link do before do File.should_receive(:exists?).with("/tmp/fofile").and_return(false) end - + it "should set the source of the existing link to an empty string" do @provider.load_current_resource @provider.current_resource.to.should == '' @@ -175,7 +173,7 @@ describe Chef::Resource::Link do @current_resource.to "/tmp/fofile" @provider.current_resource = @current_resource end - + describe "when the resource specifies the create action" do before do getpwnam = OpenStruct.new :name => "adam", :passwd => "foo", :uid => 501, @@ -196,36 +194,36 @@ describe Chef::Resource::Link do @provider.action_create end end - + describe "when the source for the link doesn't match" do before do @new_resource.to("/tmp/lolololol") end - + it "should log an appropriate message" do Chef::Log.should_receive(:info).with("Creating a symbolic link from /tmp/lolololol -> /tmp/fofile-link for link[/tmp/fofile-link]") @provider.action_create end - + describe "and we're building a symbolic link" do before do @new_resource.group('wheel') - + @new_resource.link_type(:symbolic) @new_resource.owner('toor') end - + it "should compare the current owner with the requested owner" do @provider.current_resource.owner(501) @provider.compare_owner.should eql(true) - + @provider.current_resource.owner(777) @provider.compare_owner.should eql(false) - + @provider.new_resource.owner(501) @provider.current_resource.owner(501) @provider.compare_owner.should eql(true) - + @provider.new_resource.owner("501") @provider.current_resource.owner(501) @provider.compare_owner.should eql(true) @@ -247,22 +245,22 @@ describe Chef::Resource::Link do it "should compare the current group with the requested group" do Etc.stub!(:getgrnam).and_return(OpenStruct.new(:name => "adam",:gid => 501)) - + @provider.current_resource.group(501) @provider.compare_group.should eql(true) - + @provider.current_resource.group(777) @provider.compare_group.should eql(false) - + @provider.new_resource.group(501) @provider.current_resource.group(501) @provider.compare_group.should eql(true) - + @provider.new_resource.group("501") @provider.current_resource.group(501) @provider.compare_group.should eql(true) end - + it "should set the group on the file to the requested group" do @provider.new_resource.stub!(:group).and_return(9982398) File.stub!(:lchown).and_return(1) @@ -287,17 +285,17 @@ describe Chef::Resource::Link do @provider.action_create end end - + describe "and we're building a hard link" do before do @new_resource.stub!(:link_type).and_return(:hard) end - + it "should use the ruby builtin to create the link" do File.should_receive(:link).with("/tmp/lolololol", "/tmp/fofile-link").and_return(true) @provider.action_create end - + it "we should not attempt to set owner or group" do File.should_receive(:link).with("/tmp/lolololol", "/tmp/fofile-link") @provider.should_not_receive(:set_owner) @@ -305,13 +303,13 @@ describe Chef::Resource::Link do @provider.action_create end end - + it "should set updated to true" do @provider.action_create @new_resource.should be_updated end end - + end describe "when deleting the link" do @@ -319,65 +317,65 @@ describe Chef::Resource::Link do before do @new_resource.link_type(:symbolic) end - + describe "and when the symlink exists" do before do File.should_receive(:symlink?).with("/tmp/fofile-link").and_return(true) end - + it "should log an appropriate error message" do Chef::Log.should_receive(:info).with("Deleting link[/tmp/fofile-link] at /tmp/fofile-link") @provider.action_delete end - + it "deletes the link and marks the resource as updated" do File.should_receive(:delete).with("/tmp/fofile-link").and_return(true) @provider.action_delete @new_resource.should be_updated end end - + describe "and when the file is not a symbolic link but does exist" do before(:each) do File.should_receive(:symlink?).with("/tmp/fofile-link").and_return(false) File.should_receive(:exists?).with("/tmp/fofile-link").and_return(true) end - + it "should raise a Link error" do lambda { @provider.action_delete }.should raise_error(Chef::Exceptions::Link) end end - + describe "and when the symbolic link and file do not exist" do before do File.should_receive(:symlink?).with("/tmp/fofile-link").and_return(false) File.should_receive(:exists?).with("/tmp/fofile-link").and_return(false) end - + it "should not raise a Link error" do lambda { @provider.action_delete }.should_not raise_error(Chef::Exceptions::Link) end end end - + describe "when we're building a hard link" do before do @new_resource.link_type(:hard) end - + describe "and when the file exists" do before do File.should_receive(:exists?).with("/tmp/fofile-link").and_return(true) end - + describe "and the inodes match" do before do - stat = mock("stats", :null_object => true) + stat = mock("stats") stat.stub!(:ino).and_return(1) File.should_receive(:stat).with("/tmp/fofile-link").and_return(stat) File.should_receive(:stat).with("/tmp/fofile").and_return(stat) end - + it "deletes the link and marks the resource updated" do Chef::Log.should_receive(:info).with("Deleting link[/tmp/fofile-link] at /tmp/fofile-link") File.should_receive(:delete).with("/tmp/fofile-link").and_return(true) @@ -385,29 +383,27 @@ describe Chef::Resource::Link do @new_resource.should be_updated end end - + describe "and the inodes don't match" do before do - stat = mock("stats", :null_object => true) - stat.stub!(:ino).and_return(1) - stat_two = mock("stats", :null_object => true) - stat.stub!(:ino).and_return(2) + stat = mock("stats", :ino => 1) + stat_two = mock("stats", :ino => 2) File.should_receive(:stat).with("/tmp/fofile-link").and_return(stat) File.should_receive(:stat).with("/tmp/fofile").and_return(stat_two) end - + it "should raise a Link error" do lambda { @provider.action_delete }.should raise_error(Chef::Exceptions::Link) end end - + end - + describe "and when file does not exist" do before do File.should_receive(:exists?).with("/tmp/fofile-link").and_return(false) end - + it "should not raise a Link error" do lambda { @provider.action_delete }.should_not raise_error(Chef::Exceptions::Link) end diff --git a/chef/spec/unit/provider/package/apt_spec.rb b/chef/spec/unit/provider/package/apt_spec.rb index 55b183d1da..d4298fa374 100644 --- a/chef/spec/unit/provider/package/apt_spec.rb +++ b/chef/spec/unit/provider/package/apt_spec.rb @@ -30,14 +30,15 @@ describe Chef::Provider::Package::Apt do @provider = Chef::Provider::Package::Apt.new(@new_resource, @run_context) Chef::Resource::Package.stub!(:new).and_return(@current_resource) @provider.stub!(:popen4).and_return(@status) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stdout.stub!(:each).and_yield("emacs:"). - and_yield(" Installed: (none)"). - and_yield(" Candidate: 0.1.1"). - and_yield(" Version Table:") - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) + @stdin = StringIO.new + @stdout = StringIO.new(<<-SAMPLE_STDOUT) +emacs: + Installed: (none) + Candidate: 0.1.1 + Version Table: +SAMPLE_STDOUT + @stderr = StringIO.new + @pid = mock("PID") end describe "when loading current resource" do diff --git a/chef/spec/unit/provider/package/dpkg_spec.rb b/chef/spec/unit/provider/package/dpkg_spec.rb index e10fef1baa..6293fdab8c 100644 --- a/chef/spec/unit/provider/package/dpkg_spec.rb +++ b/chef/spec/unit/provider/package/dpkg_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -27,23 +27,23 @@ describe Chef::Provider::Package::Dpkg do @provider = Chef::Provider::Package::Dpkg.new(@new_resource, @run_context) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) + @stdin = StringIO.new + @stdout = StringIO.new @status = mock("Status", :exitstatus => 0) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) + @stderr = StringIO.new + @pid = mock("PID") @provider.stub!(:popen4).and_return(@status) ::File.stub!(:exists?).and_return(true) end - + describe "when loading the current resource state" do - + it "should create a current resource with the name of the new_resource" do @provider.load_current_resource @provider.current_resource.package_name.should == "wget" end - + it "should raise an exception if a source is supplied but not found" do ::File.stub!(:exists?).and_return(false) lambda { @provider.load_current_resource }.should raise_error(Chef::Exceptions::Package) @@ -56,7 +56,7 @@ describe Chef::Provider::Package::Dpkg do @provider.current_resource.package_name.should == "wget" @new_resource.version.should == '1.11.4-1ubuntu1' end - + it "gets the source package name from dpkg-deb correctly when the package name has `-' or `+' characters" do @stdout = StringIO.new("foo-pkg++2\t1.11.4-1ubuntu1") @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) @@ -85,11 +85,11 @@ Depends: libc6 (>= 2.8~20080505), libssl0.9.8 (>= 0.9.8f-5) Conflicts: wget-ssl DPKG_S @provider.stub!(:popen4).with("dpkg -s wget").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) - + @provider.load_current_resource @provider.current_resource.version.should == "1.11.4-1ubuntu1" end - + it "should raise an exception if dpkg fails to run" do @status = mock("Status", :exitstatus => -1) @provider.stub!(:popen4).and_return(@status) diff --git a/chef/spec/unit/provider/package/easy_install_spec.rb b/chef/spec/unit/provider/package/easy_install_spec.rb index c88c61e6d3..57c0044d3f 100644 --- a/chef/spec/unit/provider/package/easy_install_spec.rb +++ b/chef/spec/unit/provider/package/easy_install_spec.rb @@ -31,11 +31,11 @@ describe Chef::Provider::Package::EasyInstall do @provider = Chef::Provider::Package::EasyInstall.new(@new_resource, @run_context) Chef::Resource::Package.stub!(:new).and_return(@current_resource) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) + @stdin = StringIO.new + @stdout = StringIO.new @status = mock("Status", :exitstatus => 0) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) + @stderr = StringIO.new + @pid = 2342 @provider.stub!(:popen4).and_return(@status) end @@ -63,19 +63,6 @@ describe Chef::Provider::Package::EasyInstall do end describe "actions_on_package" do - # before(:each) do - # @node = Chef::Node.new - # @new_resource = mock("Chef::Resource::Package", - # :null_object => true, - # :name => "boto", - # :version => nil, - # :package_name => "boto", - # :easy_install_binary => nil - # ) - # - # @provider = Chef::Provider::Package::EasyInstall.new(@node, @new_resource) - # end - it "should run easy_install with the package name and version" do @provider.should_receive(:run_command).with({ :command => "easy_install \"boto==1.8d\"" diff --git a/chef/spec/unit/provider/package/macports_spec.rb b/chef/spec/unit/provider/package/macports_spec.rb index e0ebadbced..389e394095 100644 --- a/chef/spec/unit/provider/package/macports_spec.rb +++ b/chef/spec/unit/provider/package/macports_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -29,10 +29,10 @@ describe Chef::Provider::Package::Macports do Chef::Resource::Package.stub!(:new).and_return(@current_resource) @status = mock("Status", :exitstatus => 0) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) + @stdin = StringIO.new + @stdout = StringIO.new + @stderr = StringIO.new + @pid = 2342 end describe "load_current_resource" do @@ -43,11 +43,11 @@ describe Chef::Provider::Package::Macports do @provider.load_current_resource @provider.current_resource.name.should == "zsh" end - + it "should create a current resource with the version if the package is installed" do @provider.should_receive(:macports_candidate_version).and_return("4.2.7") @provider.should_receive(:current_installed_version).and_return("4.2.7") - + @provider.load_current_resource @provider.candidate_version.should == "4.2.7" end diff --git a/chef/spec/unit/provider/package/pacman_spec.rb b/chef/spec/unit/provider/package/pacman_spec.rb index c6652c2407..5bec3d57de 100644 --- a/chef/spec/unit/provider/package/pacman_spec.rb +++ b/chef/spec/unit/provider/package/pacman_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -24,55 +24,56 @@ describe Chef::Provider::Package::Pacman do @run_context = Chef::RunContext.new(@node, {}) @new_resource = Chef::Resource::Package.new("nano") @current_resource = Chef::Resource::Package.new("nano") - + @status = mock("Status", :exitstatus => 0) @provider = Chef::Provider::Package::Pacman.new(@new_resource, @run_context) Chef::Resource::Package.stub!(:new).and_return(@current_resource) @provider.stub!(:popen4).and_return(@status) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stdout.stub!(:each).and_yield("error: package \"nano\" not found") - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) + @stdin = StringIO.new + @stdout = StringIO.new(<<-ERR) +error: package "nano" not found +ERR + @stderr = StringIO.new + @pid = 2342 end - + describe "when determining the current package state" do it "should create a current resource with the name of the new_resource" do Chef::Resource::Package.should_receive(:new).and_return(@current_resource) @provider.load_current_resource end - + it "should set the current resources package name to the new resources package name" do @current_resource.should_receive(:package_name).with(@new_resource.package_name) @provider.load_current_resource end - + it "should run pacman query with the package name" do @provider.should_receive(:popen4).with("pacman -Qi #{@new_resource.package_name}").and_return(@status) @provider.load_current_resource end - + it "should read stdout on pacman" do @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) @stdout.should_receive(:each).and_return(true) @provider.load_current_resource end - + it "should set the installed version to nil on the current resource if pacman installed version not exists" do @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) @current_resource.should_receive(:version).with(nil).and_return(true) @provider.load_current_resource end - + it "should set the installed version if pacman has one" do @stdout = StringIO.new(<<-PACMAN) Name : nano Version : 2.2.2-1 URL : http://www.nano-editor.org -Licenses : GPL -Groups : base +Licenses : GPL +Groups : base Provides : None -Depends On : glibc ncurses +Depends On : glibc ncurses Optional Deps : None Required By : None Conflicts With : None @@ -90,7 +91,7 @@ PACMAN @provider.load_current_resource @current_resource.version.should == "2.2.2-1" end - + it "should set the candidate version if pacman has one" do @stdout.stub!(:each).and_yield("core/nano 2.2.3-1 (base)"). and_yield(" Pico editor clone with enhancements"). @@ -100,23 +101,23 @@ PACMAN @provider.load_current_resource @provider.candidate_version.should eql("2.2.3-1") end - + it "should raise an exception if pacman fails" do @status.should_receive(:exitstatus).and_return(2) lambda { @provider.load_current_resource }.should raise_error(Chef::Exceptions::Package) end - + it "should not raise an exception if pacman succeeds" do @status.should_receive(:exitstatus).and_return(0) lambda { @provider.load_current_resource }.should_not raise_error(Chef::Exceptions::Package) end - + it "should raise an exception if pacman does not return a candidate version" do @stdout.stub!(:each).and_yield("") @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) lambda { @provider.candidate_version }.should raise_error(Chef::Exceptions::Package) end - + it "should return the current resouce" do @provider.load_current_resource.should eql(@current_resource) end @@ -135,7 +136,7 @@ PACMAN :command => "pacman --sync --noconfirm --noprogressbar --debug nano" }) @new_resource.stub!(:options).and_return("--debug") - + @provider.install_package("nano", "1.0") end end diff --git a/chef/spec/unit/provider/package/rubygems_spec.rb b/chef/spec/unit/provider/package/rubygems_spec.rb index 26acf6a74d..173e762f0d 100644 --- a/chef/spec/unit/provider/package/rubygems_spec.rb +++ b/chef/spec/unit/provider/package/rubygems_spec.rb @@ -31,6 +31,7 @@ end require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "spec_helper")) require 'ostruct' + describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment do include GemspecBackcompatCreator @@ -48,11 +49,13 @@ describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment do @gem_env.installed_versions(Gem::Dependency.new('rspec', nil)).should == gems end - it "determines the installed versions of gems from the source index (part2: the unmockening)" do - expected = ['rspec', Gem::Version.new(Spec::VERSION::STRING)] - actual = @gem_env.installed_versions(Gem::Dependency.new('rspec', nil)).map { |spec| [spec.name, spec.version] } - actual.should include(expected) - end + + # RSpec 2.5.0 reports its version as 2.5.1, which screws us. Thx. + #it "determines the installed versions of gems from the source index (part2: the unmockening)" do + #expected = ['rspec', Gem::Version.new()] + #actual = @gem_env.installed_versions(Gem::Dependency.new('rspec', nil)).map { |spec| [spec.name, spec.version] } + #actual.should include(expected) + #end it "yields to a block with an alternate source list set" do sources_in_block = nil @@ -195,14 +198,15 @@ describe Chef::Provider::Package::Rubygems::AlternateGemEnvironment do @gem_env.installed_versions(Gem::Dependency.new('rspec', nil)).should == gems end - it "determines the installed versions of gems from the source index (part2: the unmockening)" do - path_to_gem = `which gem`.strip - pending("cant find your gem executable") if path_to_gem.empty? - gem_env = Chef::Provider::Package::Rubygems::AlternateGemEnvironment.new(path_to_gem) - expected = ['rspec', Gem::Version.new(Spec::VERSION::STRING)] - actual = gem_env.installed_versions(Gem::Dependency.new('rspec', nil)).map { |s| [s.name, s.version] } - actual.should include(expected) - end + # RSpec 2.5.0 reports its version as 2.5.1 :/ + #it "determines the installed versions of gems from the source index (part2: the unmockening)" do + #path_to_gem = `which gem`.strip + #pending("cant find your gem executable") if path_to_gem.empty? + #gem_env = Chef::Provider::Package::Rubygems::AlternateGemEnvironment.new(path_to_gem) + #expected = ['rspec', Gem::Version.new(Rspec::Core::Version::STRING)] + #actual = gem_env.installed_versions(Gem::Dependency.new('rspec', nil)).map { |s| [s.name, s.version] } + #actual.should include(expected) + #end it "detects when the target gem environment is the jruby platform" do gem_env_out=<<-JRUBY_GEM_ENV @@ -299,7 +303,8 @@ describe Chef::Provider::Package::Rubygems do before(:each) do @node = Chef::Node.new @new_resource = Chef::Resource::GemPackage.new("rspec") - @spec_version = @new_resource.version Spec::VERSION::STRING + #@spec_version = @new_resource.version RSpec::Core::Version::STRING + @spec_version = Gem.source_index.search(Gem::Dependency.new("rspec")).last.version.to_s @run_context = Chef::RunContext.new(@node, {}) @provider = Chef::Provider::Package::Rubygems.new(@new_resource, @run_context) @@ -327,7 +332,7 @@ describe Chef::Provider::Package::Rubygems do end it "converts the new resource into a gem dependency" do - @provider.gem_dependency.should == Gem::Dependency.new('rspec', @spec_version) + @provider.gem_dependency.should == Gem::Dependency.new('rspec', nil) @new_resource.version('~> 1.2.0') @provider.gem_dependency.should == Gem::Dependency.new('rspec', '~> 1.2.0') end @@ -356,11 +361,13 @@ describe Chef::Provider::Package::Rubygems do describe "when determining the candidate version to install" do it "does not query for available versions when the current version is the target version" do + @new_resource.version("2.5.0") @provider.current_resource = @new_resource.dup @provider.candidate_version.should be_nil end it "determines the candidate version by querying the remote gem servers" do + @new_resource.version("2.5.0") @new_resource.source('http://mygems.example.com') version = Gem::Version.new(@spec_version) @provider.gem_env.should_receive(:candidate_version_from_remote). @@ -382,7 +389,7 @@ describe Chef::Provider::Package::Rubygems do before do @current_resource = Chef::Resource::GemPackage.new('rspec') @provider.current_resource = @current_resource - @gem_dep = Gem::Dependency.new('rspec', @spec_version) + @gem_dep = Gem::Dependency.new('rspec') end describe "in the current gem environment" do @@ -416,6 +423,20 @@ describe Chef::Provider::Package::Rubygems do @provider.gem_env.should_receive(:install).with(@gem_dep, :sources => nil, :install_dir => '/alt/install/location') @provider.action_install.should be_true end + describe "at a specific version" do + before do + @current_resource = Chef::Resource::GemPackage.new("rspec") + @current_resource.version("2.4.0") + + @new_resource.version("2.5.0") + @gem_dep = Gem::Dependency.new('rspec', @spec_version) + end + + it "installs the gem via the gems api" do + @provider.gem_env.should_receive(:install).with(@gem_dep, :sources => nil) + @provider.action_install.should be_true + end + end end describe "in an alternate gem environment" do diff --git a/chef/spec/unit/provider/package/yum_spec.rb b/chef/spec/unit/provider/package/yum_spec.rb index 834c4f0883..e2810523d5 100644 --- a/chef/spec/unit/provider/package/yum_spec.rb +++ b/chef/spec/unit/provider/package/yum_spec.rb @@ -34,8 +34,8 @@ describe Chef::Provider::Package::Yum do ) Chef::Provider::Package::Yum::YumCache.stub!(:instance).and_return(@yum_cache) @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) + @stderr = StringIO.new + @pid = mock("PID") end describe "when loading the current system state" do diff --git a/chef/spec/unit/provider/package/zypper_spec.rb b/chef/spec/unit/provider/package/zypper_spec.rb index e304a4294c..5b6e9f93b5 100644 --- a/chef/spec/unit/provider/package/zypper_spec.rb +++ b/chef/spec/unit/provider/package/zypper_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -27,57 +27,57 @@ describe Chef::Provider::Package::Zypper do @current_resource = Chef::Resource::Package.new("cups") @status = mock("Status", :exitstatus => 0) - + @provider = Chef::Provider::Package::Zypper.new(@new_resource, @run_context) Chef::Resource::Package.stub!(:new).and_return(@current_resource) @provider.stub!(:popen4).and_return(@status) - @stderr = mock("STDERR", :null_object => true) - @stdout = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) + @stderr = StringIO.new + @stdout = StringIO.new + @pid = mock("PID") end - + describe "when loading the current package state" do it "should create a current resource with the name of the new_resource" do Chef::Resource::Package.should_receive(:new).and_return(@current_resource) @provider.load_current_resource end - + it "should set the current resources package name to the new resources package name" do @current_resource.should_receive(:package_name).with(@new_resource.package_name) @provider.load_current_resource end - + it "should run zypper info with the package name" do @provider.should_receive(:popen4).with("zypper info #{@new_resource.package_name}").and_return(@status) @provider.load_current_resource end - + it "should set the installed version to nil on the current resource if zypper info installed version is (none)" do @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) @current_resource.should_receive(:version).with(nil).and_return(true) @provider.load_current_resource end - + it "should set the installed version if zypper info has one" do @stdout = StringIO.new("Version: 1.0\nInstalled: Yes\n") @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) @current_resource.should_receive(:version).with("1.0").and_return(true) @provider.load_current_resource end - + it "should set the candidate version if zypper info has one" do @stdout = StringIO.new("Version: 1.0\nInstalled: No\nStatus: out-of-date (version 0.9 installed)") - + @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) @provider.load_current_resource @provider.candidate_version.should eql("1.0") end - + it "should raise an exception if zypper info fails" do @status.should_receive(:exitstatus).and_return(1) lambda { @provider.load_current_resource }.should raise_error(Chef::Exceptions::Package) end - + it "should not raise an exception if zypper info succeeds" do @status.should_receive(:exitstatus).and_return(0) lambda { @provider.load_current_resource }.should_not raise_error(Chef::Exceptions::Package) @@ -89,7 +89,7 @@ describe Chef::Provider::Package::Zypper do end describe "install_package" do - + it "should run zypper install with the package name and version" do @provider.should_receive(:run_command).with({ :command => "zypper -n --no-gpg-checks install -l emacs=1.0", diff --git a/chef/spec/unit/provider/service/insserv_service_spec.rb b/chef/spec/unit/provider/service/insserv_service_spec.rb index dcbe925483..2fa1d0bdb3 100644 --- a/chef/spec/unit/provider/service/insserv_service_spec.rb +++ b/chef/spec/unit/provider/service/insserv_service_spec.rb @@ -27,8 +27,9 @@ describe Chef::Provider::Service::Insserv do @new_resource = Chef::Resource::Service.new("initgrediant") @current_resource = Chef::Resource::Service.new("initgrediant") - @provider.stub!(:popen4).and_return(@status) @provider = Chef::Provider::Service::Insserv.new(@new_resource, @run_context) + @status = mock("Process::Status mock", :exitstatus => 0) + @provider.stub!(:popen4).and_return(@status) end describe "load_current_resource" do diff --git a/chef/spec/unit/provider/service/simple_service_spec.rb b/chef/spec/unit/provider/service/simple_service_spec.rb index 7294b93bb1..cc9087174b 100644 --- a/chef/spec/unit/provider/service/simple_service_spec.rb +++ b/chef/spec/unit/provider/service/simple_service_spec.rb @@ -32,13 +32,14 @@ describe Chef::Provider::Service::Simple, "load_current_resource" do @status = mock("Status", :exitstatus => 0) @provider.stub!(:popen4).and_return(@status) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stdout.stub!(:each).and_yield("aj 7842 5057 0 21:26 pts/2 00:00:06 vi init.rb"). - and_yield("aj 7903 5016 0 21:26 pts/5 00:00:00 /bin/bash"). - and_yield("aj 8119 6041 0 21:34 pts/3 00:00:03 vi simple_service_spec.rb") - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) + @stdin = StringIO.new + @stdout = StringIO.new(<<-NOMOCKINGSTRINGSPLZ) +aj 7842 5057 0 21:26 pts/2 00:00:06 vi init.rb +aj 7903 5016 0 21:26 pts/5 00:00:00 /bin/bash +aj 8119 6041 0 21:34 pts/3 00:00:03 vi simple_service_spec.rb +NOMOCKINGSTRINGSPLZ + @stderr = StringIO.new + @pid = mock("PID") end it "should create a current resource with the name of the new resource" do diff --git a/chef/spec/unit/provider/service/solaris_smf_service_spec.rb b/chef/spec/unit/provider/service/solaris_smf_service_spec.rb index 78f71694e4..79560611be 100644 --- a/chef/spec/unit/provider/service/solaris_smf_service_spec.rb +++ b/chef/spec/unit/provider/service/solaris_smf_service_spec.rb @@ -30,10 +30,10 @@ describe Chef::Provider::Service::Solaris do @provider = Chef::Provider::Service::Solaris.new(@new_resource, @run_context) Chef::Resource::Service.stub!(:new).and_return(@current_resource) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) + @stdin = StringIO.new + @stdout = StringIO.new + @stderr = StringIO.new + @pid = 2342 @stdout_string = "state disabled" @stdout.stub!(:gets).and_return(@stdout_string) end diff --git a/chef/spec/unit/provider/service/upstart_service_spec.rb b/chef/spec/unit/provider/service/upstart_service_spec.rb index 22cca477b6..2e1cd971e0 100644 --- a/chef/spec/unit/provider/service/upstart_service_spec.rb +++ b/chef/spec/unit/provider/service/upstart_service_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -24,9 +24,9 @@ describe Chef::Provider::Service::Upstart do @node[:name] = 'upstarter' @node[:platform] = 'ubuntu' @node[:platform_version] = '9.10' - + @run_context = Chef::RunContext.new(@node, {}) - + @new_resource = Chef::Resource::Service.new("rsyslog") @provider = Chef::Provider::Service::Upstart.new(@new_resource, @run_context) end @@ -35,7 +35,7 @@ describe Chef::Provider::Service::Upstart do before do @platform = nil end - + it "should return /etc/event.d as the upstart job directory when running on Ubuntu 9.04" do @node[:platform_version] = '9.04' #Chef::Platform.stub!(:find_platform_and_version).and_return([ "ubuntu", "9.04" ]) @@ -68,10 +68,10 @@ describe Chef::Provider::Service::Upstart do @status = mock("Status", :exitstatus => 0) @provider.stub!(:popen4).and_return(@status) - @stdin = mock("STDIN", :null_object => true) - @stdout = mock("STDOUT", :null_object => true) - @stderr = mock("STDERR", :null_object => true) - @pid = mock("PID", :null_object => true) + @stdin = StringIO.new + @stdout = StringIO.new + @stderr = StringIO.new + @pid = mock("PID") ::File.stub!(:exists?).and_return(true) ::File.stub!(:open).and_return(true) @@ -95,7 +95,7 @@ describe Chef::Provider::Service::Upstart do describe "when the status command uses the new format" do before do end - + it "should set running to true if the the status command returns 0" do @stdout = StringIO.new("rsyslog start/running") @provider.stub!(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status) @@ -139,14 +139,14 @@ describe Chef::Provider::Service::Upstart do @current_resource.should_receive(:running).with(false) @provider.load_current_resource end - + it "should set enabled to false when it finds '#starts on'" do @lines = mock("start on filesystem", :gets => "#start on filesystem") ::File.stub!(:open).and_yield(@lines) @current_resource.should_receive(:running).with(false) @provider.load_current_resource end - + it "should assume disable when no job configuration file is found" do ::File.stub!(:exists?).and_return(false) @current_resource.should_receive(:running).with(false) @@ -170,7 +170,7 @@ describe Chef::Provider::Service::Upstart do @provider.load_current_resource end end - + it "should return the current resource" do @provider.load_current_resource.should eql(@current_resource) end @@ -179,24 +179,6 @@ describe Chef::Provider::Service::Upstart do describe "enable and disable service" do before(:each) do - # @node = Chef::Node.new - # @new_resource = mock("Chef::Resource::Service", - # :null_object => true, - # :name => "rsyslog", - # :service_name => "rsyslog", - # :running => false, - # :enabled => false - # ) - # - # @current_resource = mock("Chef::Resource::Service", - # :null_object => true, - # :name => "rsyslog", - # :service_name => "rsyslog", - # :running => false, - # :enabled => false - # ) - - # @provider = Chef::Provider::Service::Upstart.new(@node, @new_resource) Chef::Resource::Service.stub!(:new).and_return(@current_resource) @provider.current_resource = @current_resource Chef::Util::FileEdit.stub!(:new) @@ -210,7 +192,7 @@ describe Chef::Provider::Service::Upstart do @file.should_receive(:write_file) @provider.enable_service() end - + it "should disable the service if it is enabled" do @file = Object.new Chef::Util::FileEdit.stub!(:new).and_return(@file) @@ -219,7 +201,7 @@ describe Chef::Provider::Service::Upstart do @file.should_receive(:write_file) @provider.disable_service() end - + end describe "start and stop service" do diff --git a/chef/spec/unit/resource/link_spec.rb b/chef/spec/unit/resource/link_spec.rb index ef9ac2f5fd..6af32c3eff 100644 --- a/chef/spec/unit/resource/link_spec.rb +++ b/chef/spec/unit/resource/link_spec.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -22,21 +22,21 @@ describe Chef::Resource::Link do before(:each) do @resource = Chef::Resource::Link.new("fakey_fakerton") - end + end it "should create a new Chef::Resource::Link" do @resource.should be_a_kind_of(Chef::Resource) @resource.should be_a_kind_of(Chef::Resource::Link) end - + it "should have a name" do @resource.name.should eql("fakey_fakerton") end - + it "should have a default action of 'create'" do @resource.action.should eql(:create) end - + { :create => false, :delete => false, :blues => true }.each do |action,bad_value| it "should #{bad_value ? 'not' : ''} accept #{action.to_s}" do if bad_value @@ -46,42 +46,42 @@ describe Chef::Resource::Link do end end end - + it "should use the object name as the target_file by default" do @resource.target_file.should eql("fakey_fakerton") end - + it "should accept a string as the link source via 'to'" do lambda { @resource.to "/tmp" }.should_not raise_error(ArgumentError) end - + it "should not accept a Hash for the link source via 'to'" do lambda { @resource.to Hash.new }.should raise_error(ArgumentError) end - + it "should allow you to set a link source via 'to'" do @resource.to "/tmp/foo" @resource.to.should eql("/tmp/foo") end - + it "should allow you to specify the link type" do @resource.link_type "symbolic" @resource.link_type.should eql(:symbolic) end - + it "should default to a symbolic link" do @resource.link_type.should eql(:symbolic) end - + it "should accept a hard link_type" do @resource.link_type :hard @resource.link_type.should eql(:hard) end - + it "should reject any other link_type but :hard and :symbolic" do lambda { @resource.link_type "x-men" }.should raise_error(ArgumentError) end - + it "should accept a group name or id for group" do lambda { @resource.group "root" }.should_not raise_error(ArgumentError) lambda { @resource.group 123 }.should_not raise_error(ArgumentError) diff --git a/chef/spec/unit/runner_spec.rb b/chef/spec/unit/runner_spec.rb index 441cf43ea2..56e70e6990 100644 --- a/chef/spec/unit/runner_spec.rb +++ b/chef/spec/unit/runner_spec.rb @@ -53,7 +53,8 @@ class SnitchyProvider < Chef::Provider end describe Chef::Runner do - def new_runner + + before(:each) do @node = Chef::Node.new @node.name "latte" @node.platform "mac_os_x" @@ -67,32 +68,24 @@ describe Chef::Runner do ) @runner = Chef::Runner.new(@run_context) end - - before(:each) do - @mock_node = mock("Node", :null_object => true) - @mock_collection = mock("Resource Collection", :null_object => true) - @mock_provider = mock("Provider", :null_object => true) - @mock_resource = mock("Resource", :null_object => true) - new_runner - end - + it "should pass each resource in the collection to a provider" do @run_context.resource_collection.should_receive(:execute_each_resource).once @runner.converge end - + it "should use the provider specified by the resource (if it has one)" do provider = Chef::Provider::Easy.new(@run_context.resource_collection[0], @run_context) @run_context.resource_collection[0].should_receive(:provider).once.and_return(Chef::Provider::Easy) Chef::Provider::Easy.should_receive(:new).once.and_return(provider) @runner.converge end - + it "should use the platform provider if it has one" do Chef::Platform.should_receive(:find_provider_for_node).once.and_return(Chef::Provider::SnakeOil) @runner.converge end - + it "should run the action for each resource" do Chef::Platform.should_receive(:find_provider_for_node).once.and_return(Chef::Provider::SnakeOil) provider = Chef::Provider::SnakeOil.new(@run_context.resource_collection[0], @run_context) @@ -107,7 +100,7 @@ describe Chef::Runner do provider.stub!(:action_sell).once.and_raise(ArgumentError) lambda { @runner.converge }.should raise_error(ArgumentError) end - + it "should not raise exceptions thrown by providers if the resource has ignore_failure set to true" do @run_context.resource_collection[0].stub!(:ignore_failure).and_return(true) provider = Chef::Provider::SnakeOil.new(@run_context.resource_collection[0], @run_context) @@ -115,7 +108,7 @@ describe Chef::Runner do provider.stub!(:action_sell).once.and_raise(ArgumentError) lambda { @runner.converge }.should_not raise_error(ArgumentError) end - + it "should execute immediate actions on changed resources" do notifying_resource = Chef::Resource::Cat.new("peanut", @run_context) notifying_resource.action = :purr # only action that will set updated on the resource @@ -149,10 +142,9 @@ describe Chef::Runner do middle_resource.should be_updated # by notification from last_resource @first_resource.should be_updated # by notification from middle_resource end - - it "should execute delayed actions on changed resources" do - @first_resource.action = :nothing + it "should execute delayed actions on changed resources" do + @first_resource.action = :nothing second_resource = Chef::Resource::Cat.new("peanut", @run_context) second_resource.action = :purr @@ -163,7 +155,7 @@ describe Chef::Runner do @first_resource.should be_updated end - + it "does not duplicate delayed notifications" do SnitchyProvider.clear_action_record @@ -279,3 +271,4 @@ describe Chef::Runner do end end + diff --git a/chef/spec/unit/search/query_spec.rb b/chef/spec/unit/search/query_spec.rb index f9d72fa53a..75723ea1d8 100644 --- a/chef/spec/unit/search/query_spec.rb +++ b/chef/spec/unit/search/query_spec.rb @@ -21,7 +21,7 @@ require 'chef/search/query' describe Chef::Search::Query do before(:each) do - @rest = mock("Chef::REST", :null_object => true) + @rest = mock("Chef::REST") Chef::REST.stub!(:new).and_return(@rest) @query = Chef::Search::Query.new end diff --git a/chef/spec/unit/solr_query_spec.rb b/chef/spec/unit/solr_query_spec.rb index 9432e4cc2f..5a95347ec0 100644 --- a/chef/spec/unit/solr_query_spec.rb +++ b/chef/spec/unit/solr_query_spec.rb @@ -15,13 +15,15 @@ # limitations under the License. # -require File.expand_path(File.join("#{File.dirname(__FILE__)}", '..', 'spec_helper')) +require File.expand_path("../../spec_helper", __FILE__) require 'chef/solr_query' require 'net/http' +#require 'rspec/mocks' + describe Chef::SolrQuery do - before(:all) do + before do Chef::SolrQuery::SolrHTTPRequest.solr_url = "http://example.com:8983" @http_response = mock( diff --git a/chef/tasks/rspec.rb b/chef/tasks/rspec.rb index 4a572ddf45..e2ea2f47cb 100644 --- a/chef/tasks/rspec.rb +++ b/chef/tasks/rspec.rb @@ -23,27 +23,27 @@ require 'rake' CHEF_ROOT = File.join(File.dirname(__FILE__), "..") begin - require 'spec/rake/spectask' + require 'rspec/core/rake_task' task :default => :spec desc "Run all specs in spec directory" - Spec::Rake::SpecTask.new(:spec) do |t| - t.spec_opts = ['--options', "\"#{CHEF_ROOT}/spec/spec.opts\""] - t.spec_files = FileList['spec/unit/**/*_spec.rb'] + RSpec::Core::RakeTask.new(:spec) do |t| + t.rspec_opts = ['--options', "\"#{CHEF_ROOT}/.rspec\""] + t.pattern = FileList['spec/unit/**/*_spec.rb'] end desc "Run all functional specs (in functional/ directory)" - Spec::Rake::SpecTask.new(:functional) do |t| - t.spec_opts = ['--options', "\"#{CHEF_ROOT}/spec/spec.opts\""] - t.spec_files = FileList['spec/functional/**/*_spec.rb'] + RSpec::Core::RakeTask.new(:functional) do |t| + t.rspec_opts = ['--options', "\"#{CHEF_ROOT}/spec/spec.opts\""] + t.pattern = FileList['spec/functional/**/*_spec.rb'] end namespace :spec do desc "Run all specs in spec directory with RCov" - Spec::Rake::SpecTask.new(:rcov) do |t| - t.spec_opts = ['--options', "\"#{CHEF_ROOT}/spec/spec.opts\""] - t.spec_files = FileList['spec/**/*_spec.rb'] + RSpec::Core::RakeTask.new(:rcov) do |t| + t.rspec_opts = ['--options', "\"#{CHEF_ROOT}/spec/spec.opts\""] + t.pattern = FileList['spec/**/*_spec.rb'] t.rcov = true t.rcov_opts = lambda do IO.readlines("#{CHEF_ROOT}/spec/rcov.opts").map {|l| l.chomp.split " "}.flatten @@ -51,26 +51,19 @@ begin end desc "Print Specdoc for all specs" - Spec::Rake::SpecTask.new(:doc) do |t| - t.spec_opts = ["--format", "specdoc", "--dry-run"] - t.spec_files = FileList['spec/**/*_spec.rb'] + RSpec::Core::RakeTask.new(:doc) do |t| + t.rspec_opts = ["--format", "specdoc", "--dry-run"] + t.pattern = FileList['spec/**/*_spec.rb'] end [:unit].each do |sub| desc "Run the specs under spec/#{sub}" - Spec::Rake::SpecTask.new(sub) do |t| - t.spec_opts = ['--options', "\"#{CHEF_ROOT}/spec/spec.opts\""] - t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"] + RSpec::Core::RakeTask.new(sub) do |t| + t.rspec_opts = ['--options', "\"#{CHEF_ROOT}/spec/spec.opts\""] + t.pattern = FileList["spec/#{sub}/**/*_spec.rb"] end end - - desc "Translate/upgrade specs using the built-in translator" - task :translate do - translator = ::Spec::Translator.new - dir = CHEF_ROOT + '/spec' - translator.translate(dir, dir) - end end rescue LoadError - STDERR.puts "\n*** Rspec not available. (sudo) gem install rspec to run unit tests. ***\n\n" + STDERR.puts "\n*** RSpec not available. (sudo) gem install rspec to run unit tests. ***\n\n" end |