diff options
-rw-r--r-- | lib/chef/config_fetcher.rb | 5 | ||||
-rw-r--r-- | spec/unit/application/client_spec.rb | 46 | ||||
-rw-r--r-- | spec/unit/application/solo_spec.rb | 46 | ||||
-rw-r--r-- | spec/unit/config_fetcher_spec.rb | 96 |
4 files changed, 118 insertions, 75 deletions
diff --git a/lib/chef/config_fetcher.rb b/lib/chef/config_fetcher.rb index 369d36c459..129d8bed62 100644 --- a/lib/chef/config_fetcher.rb +++ b/lib/chef/config_fetcher.rb @@ -13,7 +13,7 @@ class Chef begin Chef::JSONCompat.from_json(config_data) rescue JSON::ParserError => error - Chef::Application.fatal!("Could not parse the provided JSON file (#{config_location})!: " + error.message, 2) + Chef::Application.fatal!("Could not parse the provided JSON file (#{config_location}): " + error.message, 2) end end @@ -26,7 +26,6 @@ class Chef end def fetch_remote_config - http = Chef::HTTP::Simple.new(config_location) http.get("") rescue SocketError, SystemCallError => error Chef::Application.fatal!("Cannot fetch config '#{config_location}': '#{error.class}: #{error.message}", 2) @@ -35,7 +34,7 @@ class Chef def read_local_config ::File.read(config_location) rescue Errno::ENOENT => error - Chef::Application.fatal!("I cannot find #{config_location}", 2) + Chef::Application.fatal!("Cannot load configuration from #{config_location}", 2) rescue Errno::EACCES => error Chef::Application.fatal!("Permissions are incorrect on #{config_location}. Please chmod a+r #{config_location}", 2) end diff --git a/spec/unit/application/client_spec.rb b/spec/unit/application/client_spec.rb index 25ed8b36b6..c4387890cd 100644 --- a/spec/unit/application/client_spec.rb +++ b/spec/unit/application/client_spec.rb @@ -69,45 +69,19 @@ describe Chef::Application::Client, "reconfigure" do describe "when the json_attribs configuration option is specified" do - describe "and the json_attribs matches a HTTP regex" do - before do - @json = {:a=>"b"}.to_json - @http = double("Chef::HTTP::Simple", :get => @json) - - Chef::Config[:json_attribs] = "https://foo.com/foo.json" - Chef::HTTP::Simple.should_receive(:new).with("https://foo.com/foo.json").and_return(@http) - end - - it "should perform a RESTful GET on the supplied URL" do - @app.reconfigure - @app.chef_client_json.should == {"a" => "b"} - end - end + let(:json_attribs) { {"a" => "b"} } + let(:config_fetcher) { double(Chef::ConfigFetcher, :fetch_json => json_attribs) } + let(:json_source) { "https://foo.com/foo.json" } - describe "and the json_attribs does not match the HTTP regex" do - before do - Chef::Config[:json_attribs] = "/etc/chef/dna.json" - @json = {:a=>"b"}.to_json - ::File.should_receive(:read).with("/etc/chef/dna.json").and_return(@json) - end - - it "should parse the json out of the file" do - @app.reconfigure - @app.chef_client_json.should == {"a" => "b"} - end + before do + Chef::Config[:json_attribs] = json_source + Chef::ConfigFetcher.should_receive(:new).with(json_source). + and_return(config_fetcher) end - describe "when parsing fails" do - before do - Chef::Config[:json_attribs] = "/etc/chef/dna.json" - @json = %q[{"syntax-error": "missing quote}] - ::File.should_receive(:read).with("/etc/chef/dna.json").and_return(@json) - end - - it "should hard fail the application" do - Chef::Application.should_receive(:fatal!).with(%r[Could not parse the provided JSON file \(/etc/chef/dna.json\)], 2) - @app.reconfigure - end + it "reads the JSON attributes from the specified source" do + @app.reconfigure + @app.chef_client_json.should == json_attribs end end end diff --git a/spec/unit/application/solo_spec.rb b/spec/unit/application/solo_spec.rb index 5fe5ec9702..6dd8c8f147 100644 --- a/spec/unit/application/solo_spec.rb +++ b/spec/unit/application/solo_spec.rb @@ -48,45 +48,19 @@ describe Chef::Application::Solo do describe "when the json_attribs configuration option is specified" do - describe "and the json_attribs matches a HTTP regex" do - before do - @json = {:a=>"b"}.to_json - @http = double("Chef::HTTP::Simple", :get => @json) - - Chef::Config[:json_attribs] = "https://foo.com/foo.json" - Chef::HTTP::Simple.should_receive(:new).with("https://foo.com/foo.json").and_return(@http) - end - - it "should perform a RESTful GET on the supplied URL" do - @app.reconfigure - @app.chef_solo_json.should == {"a" => "b"} - end - end + let(:json_attribs) { {"a" => "b"} } + let(:config_fetcher) { double(Chef::ConfigFetcher, :fetch_json => json_attribs) } + let(:json_source) { "https://foo.com/foo.json" } - describe "and the json_attribs does not match the HTTP regex" do - before do - Chef::Config[:json_attribs] = "/etc/chef/dna.json" - @json = {:a=>"b"}.to_json - ::File.should_receive(:read).with("/etc/chef/dna.json").and_return(@json) - end - - it "should parse the json out of the file" do - @app.reconfigure - @app.chef_solo_json.should == {"a" => "b"} - end + before do + Chef::Config[:json_attribs] = json_source + Chef::ConfigFetcher.should_receive(:new).with(json_source). + and_return(config_fetcher) end - describe "when parsing fails" do - before do - Chef::Config[:json_attribs] = "/etc/chef/dna.json" - @json = %q[{"syntax-error": "missing quote}] - ::File.should_receive(:read).with("/etc/chef/dna.json").and_return(@json) - end - - it "should hard fail the application" do - Chef::Application.should_receive(:fatal!).with(%r[Could not parse the provided JSON file \(/etc/chef/dna.json\)], 2) - @app.reconfigure - end + it "reads the JSON attributes from the specified source" do + @app.reconfigure + @app.chef_solo_json.should == json_attribs end end diff --git a/spec/unit/config_fetcher_spec.rb b/spec/unit/config_fetcher_spec.rb new file mode 100644 index 0000000000..f6d5436a11 --- /dev/null +++ b/spec/unit/config_fetcher_spec.rb @@ -0,0 +1,96 @@ +require 'spec_helper' +require 'chef/config_fetcher' +describe Chef::ConfigFetcher do + let(:valid_json) { {:a=>"b"}.to_json } + let(:invalid_json) { %q[{"syntax-error": "missing quote}] } + let(:http) { double("Chef::HTTP::Simple") } + + let(:config_location_regex) { Regexp.escape(config_location) } + let(:invalid_json_error_regex) { %r[Could not parse the provided JSON file \(#{config_location_regex}\)] } + + let(:fetcher) { Chef::ConfigFetcher.new(config_location) } + + context "when loading a local file" do + let(:config_location) { "/etc/chef/client.rb" } + let(:config_content) { "# The client.rb content" } + + it "reads the file from disk" do + ::File.should_receive(:read). + with(config_location). + and_return(config_content) + fetcher.read_config.should == config_content + end + + context "and consuming JSON" do + + let(:config_location) { "/etc/chef/first-boot.json" } + + + it "returns the parsed JSON" do + ::File.should_receive(:read). + with(config_location). + and_return(valid_json) + + fetcher.fetch_json.should == {"a" => "b"} + end + + context "and the JSON is invalid" do + + it "reports the JSON error" do + + + ::File.should_receive(:read). + with(config_location). + and_return(invalid_json) + + Chef::Application.should_receive(:fatal!). + with(invalid_json_error_regex, 2) + fetcher.fetch_json + end + end + end + + end + + context "when loading a file over HTTP" do + + let(:config_location) { "https://example.com/client.rb" } + let(:config_content) { "# The client.rb content" } + + before do + Chef::HTTP::Simple.should_receive(:new). + with(config_location). + and_return(http) + end + + it "reads the file over HTTP" do + http.should_receive(:get). + with("").and_return(config_content) + fetcher.read_config.should == config_content + end + + context "and consuming JSON" do + let(:config_location) { "https://example.com/foo.json" } + + it "fetches the file and parses it" do + http.should_receive(:get). + with("").and_return(valid_json) + fetcher.fetch_json.should == {"a" => "b"} + end + + context "and the JSON is invalid" do + it "reports the JSON error" do + http.should_receive(:get). + with("").and_return(invalid_json) + + Chef::Application.should_receive(:fatal!). + with(invalid_json_error_regex, 2) + fetcher.fetch_json + end + end + end + + end + + +end |