diff options
author | danielsdeleo <dan@getchef.com> | 2015-05-19 15:33:42 -0700 |
---|---|---|
committer | danielsdeleo <dan@getchef.com> | 2015-05-20 10:42:28 -0700 |
commit | 2fce76b2fa8bd56b56d12618ab3677a2d88f4188 (patch) | |
tree | 67863277f7bae7560a5412b6f3204d5d6555f27f | |
parent | c8462b7818f4d5eef70074edfafde20f95105a56 (diff) | |
download | chef-2fce76b2fa8bd56b56d12618ab3677a2d88f4188.tar.gz |
Modernize compile error inspector spec
-rw-r--r-- | spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb | 214 |
1 files changed, 101 insertions, 113 deletions
diff --git a/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb b/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb index ac19e91922..c28c9bdca3 100644 --- a/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb +++ b/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb @@ -37,69 +37,81 @@ end E describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do - before do - @node_name = "test-node.example.com" - @description = Chef::Formatters::ErrorDescription.new("Error Evaluating File:") - @exception = NoMethodError.new("undefined method `this_is_not_a_valid_method' for Chef::Resource::File") - @outputter = Chef::Formatters::IndentableOutputStream.new(StringIO.new, STDERR) - #@outputter = Chef::Formatters::IndentableOutputStream.new(STDOUT, STDERR) - end + let(:node_name) { "test-node.example.com" } - describe "when scrubbing backtraces" do - it "shows backtrace lines from cookbook files" do - # Error inspector originally used file_cache_path which is incorrect on - # chef-solo. Using cookbook_path should do the right thing for client and - # solo. - allow(Chef::Config).to receive(:cookbook_path).and_return([ "/home/someuser/dev-laptop/cookbooks" ]) - @trace = [ - "/home/someuser/dev-laptop/cookbooks/syntax-err/recipes/default.rb:14:in `from_file'", - "/home/someuser/dev-laptop/cookbooks/syntax-err/recipes/default.rb:11:in `from_file'", - "/home/someuser/.multiruby/gems/chef/lib/chef/client.rb:123:in `run'" - ] - @exception.set_backtrace(@trace) - @path = "/var/chef/cache/cookbooks/syntax-err/recipes/default.rb" - @inspector = described_class.new(@path, @exception) + let(:description) { Chef::Formatters::ErrorDescription.new("Error Evaluating File:") } - @expected_filtered_trace = [ - "/home/someuser/dev-laptop/cookbooks/syntax-err/recipes/default.rb:14:in `from_file'", - "/home/someuser/dev-laptop/cookbooks/syntax-err/recipes/default.rb:11:in `from_file'", - ] - expect(@inspector.filtered_bt).to eq(@expected_filtered_trace) - end + let(:exception) do + e = NoMethodError.new("undefined method `this_is_not_a_valid_method' for Chef::Resource::File") + e.set_backtrace(trace) + e end - describe "when explaining an error in the compile phase" do - before do - allow(Chef::Config).to receive(:cookbook_path).and_return([ "/var/chef/cache/cookbooks" ]) - recipe_lines = BAD_RECIPE.split("\n").map {|l| l << "\n" } - expect(IO).to receive(:readlines).with("/var/chef/cache/cookbooks/syntax-err/recipes/default.rb").and_return(recipe_lines) - @trace = [ - "/var/chef/cache/cookbooks/syntax-err/recipes/default.rb:14:in `from_file'", - "/var/chef/cache/cookbooks/syntax-err/recipes/default.rb:11:in `from_file'", - "/usr/local/lib/ruby/gems/chef/lib/chef/client.rb:123:in `run'" # should not display - ] - @exception.set_backtrace(@trace) - @path = "/var/chef/cache/cookbooks/syntax-err/recipes/default.rb" - @inspector = described_class.new(@path, @exception) - @inspector.add_explanation(@description) - end + # Change to $stdout to print error messages for manual inspection + let(:stdout) { StringIO.new } - it "finds the line number of the error from the stacktrace" do - expect(@inspector.culprit_line).to eq(14) - end + let(:outputter) { Chef::Formatters::IndentableOutputStream.new(StringIO.new, STDERR) } + + subject(:inspector) { described_class.new(path_to_failed_file, exception) } + + describe "finding the code responsible for the error" do + + context "when the stacktrace includes cookbook files" do + + let(:trace) do + [ + "/home/someuser/dev-laptop/cookbooks/syntax-err/recipes/default.rb:14:in `from_file'", + "/home/someuser/dev-laptop/cookbooks/syntax-err/recipes/default.rb:11:in `from_file'", + "/home/someuser/.multiruby/gems/chef/lib/chef/client.rb:123:in `run'" + ] + end - it "prints a pretty message" do - @description.display(@outputter) + let(:expected_filtered_trace) do + [ + "/home/someuser/dev-laptop/cookbooks/syntax-err/recipes/default.rb:14:in `from_file'", + "/home/someuser/dev-laptop/cookbooks/syntax-err/recipes/default.rb:11:in `from_file'", + ] + end + + let(:path_to_failed_file) { "/home/someuser/dev-laptop/cookbooks/syntax-err/recipes/default.rb" } + + before do + # Error inspector originally used file_cache_path which is incorrect on + # chef-solo. Using cookbook_path should do the right thing for client and + # solo. + allow(Chef::Config).to receive(:cookbook_path).and_return([ "/home/someuser/dev-laptop/cookbooks" ]) + end + + describe "when scrubbing backtraces" do + it "shows backtrace lines from cookbook files" do + expect(inspector.filtered_bt).to eq(expected_filtered_trace) + end + end + + describe "when explaining an error in the compile phase" do + before do + recipe_lines = BAD_RECIPE.split("\n").map {|l| l << "\n" } + expect(IO).to receive(:readlines).with(path_to_failed_file).and_return(recipe_lines) + inspector.add_explanation(description) + end + + it "finds the line number of the error from the stacktrace" do + expect(inspector.culprit_line).to eq(14) + end + + it "prints a pretty message" do + description.display(outputter) + end + end end + end describe "when explaining an error on windows" do - before do - allow(Chef::Config).to receive(:cookbook_path).and_return([ "C:/opscode/chef/var/cache/cookbooks" ]) - recipe_lines = BAD_RECIPE.split("\n").map {|l| l << "\n" } - expect(IO).to receive(:readlines).at_least(1).times.with(/:\/opscode\/chef\/var\/cache\/cookbooks\/foo\/recipes\/default.rb/).and_return(recipe_lines) - @trace = [ + + let(:trace_with_upcase_drive) do + [ "C:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb:14 in `from_file'", "C:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:144:in `rescue in block in load_libraries'", "C:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:138:in `block in load_libraries'", @@ -122,81 +134,57 @@ describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do "C:/opscode/chef/bin/chef-client:19:in `load'", "C:/opscode/chef/bin/chef-client:19:in `<main>'" ] - @exception.set_backtrace(@trace) - @path = "/var/chef/cache/cookbooks/syntax-err/recipes/default.rb" - @inspector = described_class.new(@path, @exception) - @inspector.add_explanation(@description) end + let(:trace) { trace_with_upcase_drive } + + let(:path_to_failed_file) { "/var/cache/cookbooks/foo/recipes/default.rb" } + + before do + allow(Chef::Config).to receive(:cookbook_path).and_return([ "C:/opscode/chef/var/cache/cookbooks" ]) + recipe_lines = BAD_RECIPE.split("\n").map {|l| l << "\n" } + expect(IO).to receive(:readlines).at_least(1).times.with(full_path_to_failed_file).and_return(recipe_lines) + inspector.add_explanation(description) + end + + context "when the drive letter in the path is uppercase" do - describe "and examining the stack trace for a recipe" do - it "find the culprit recipe name when the drive letter is upper case" do - expect(@inspector.culprit_file).to eq("C:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb") + let(:full_path_to_failed_file) { "C:/opscode/chef#{path_to_failed_file}" } + + it "finds the culprit recipe name" do + expect(inspector.culprit_file).to eq("C:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb") end - it "find the culprit recipe name when the drive letter is lower case" do - @trace.each { |line| line.gsub!(/^C:/, "c:") } - @exception.set_backtrace(@trace) - @inspector = described_class.new(@path, @exception) - @inspector.add_explanation(@description) - expect(@inspector.culprit_file).to eq("c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb") + it "finds the line number of the error from the stack trace" do + expect(inspector.culprit_line).to eq(14) end - end - it "finds the line number of the error from the stack trace" do - expect(@inspector.culprit_line).to eq(14) + it "prints a pretty message" do + description.display(outputter) + end end - it "prints a pretty message" do - @description.display(@outputter) - end - end + context "when the drive letter in the path is lowercase" do - describe "when explaining an error on windows, and the backtrace lowercases the drive letter" do - before do - allow(Chef::Config).to receive(:cookbook_path).and_return([ "C:/opscode/chef/var/cache/cookbooks" ]) - recipe_lines = BAD_RECIPE.split("\n").map {|l| l << "\n" } - expect(IO).to receive(:readlines).with("c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb").and_return(recipe_lines) - @trace = [ - "c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb:14 in `from_file'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:144:in `rescue in block in load_libraries'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:138:in `block in load_libraries'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:230:in `call'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:230:in `block (2 levels) in foreach_cookbook_load_segment'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:229:in `each'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:229:in `block in foreach_cookbook_load_segment'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:227:in `each'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:227:in `foreach_cookbook_load_segment'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:137:in `load_libraries'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:62:in `load'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/client.rb:198:in `setup_run_context'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/client.rb:418:in `do_run'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/client.rb:176:in `run'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/application/client.rb:283:in `block in run_application'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/application/client.rb:270:in `loop'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/application/client.rb:270:in `run_application'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/application.rb:70:in `run'", - "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/bin/chef-client:26:in `<top (required)>'", - "c:/opscode/chef/bin/chef-client:19:in `load'", - "c:/opscode/chef/bin/chef-client:19:in `<main>'" - ] - @exception.set_backtrace(@trace) - @path = "/var/chef/cache/cookbooks/syntax-err/recipes/default.rb" - @inspector = described_class.new(@path, @exception) - @inspector.add_explanation(@description) - end + let(:trace) do + trace_with_upcase_drive.map { |line| line.gsub(/^C:/, "c:") } + end - it "finds the culprit recipe name from the stacktrace" do - expect(@inspector.culprit_file).to eq("c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb") - end + let(:full_path_to_failed_file) { "c:/opscode/chef#{path_to_failed_file}" } - it "finds the line number of the error from the stack trace" do - expect(@inspector.culprit_line).to eq(14) - end + it "finds the culprit recipe name from the stacktrace" do + expect(inspector.culprit_file).to eq("c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb") + end + + it "finds the line number of the error from the stack trace" do + expect(inspector.culprit_line).to eq(14) + end - it "prints a pretty message" do - @description.display(@outputter) + it "prints a pretty message" do + description.display(outputter) + end end + end end |