diff options
Diffstat (limited to 'spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb')
-rw-r--r-- | spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb | 202 |
1 files changed, 202 insertions, 0 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 new file mode 100644 index 0000000000..e1f8f28bb9 --- /dev/null +++ b/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb @@ -0,0 +1,202 @@ +# +# Author:: Daniel DeLeo (<dan@opscode.com>) +# Copyright:: Copyright (c) 2012 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# 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. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'spec_helper' + +BAD_RECIPE=<<-E +# +# Cookbook Name:: syntax-err +# Recipe:: default +# +# Copyright 2012, YOUR_COMPANY_NAME +# +# All rights reserved - Do Not Redistribute +# + + +file "/tmp/explode-me" do + mode 0655 + owner "root" + this_is_not_a_valid_method +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::Outputter.new(StringIO.new, STDERR) + #@outputter = Chef::Formatters::Outputter.new(STDOUT, STDERR) + end + + 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. + Chef::Config.stub!(: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) + + @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'", + ] + @inspector.filtered_bt.should == @expected_filtered_trace + end + end + + describe "when explaining an error in the compile phase" do + before do + Chef::Config.stub!(:cookbook_path).and_return([ "/var/chef/cache/cookbooks" ]) + recipe_lines = BAD_RECIPE.split("\n").map {|l| l << "\n" } + IO.should_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 + + it "finds the line number of the error from the stacktrace" do + @inspector.culprit_line.should == 14 + end + + it "prints a pretty message" do + @description.display(@outputter) + end + end + + describe "when explaining an error on windows" do + before do + Chef::Config.stub!(:cookbook_path).and_return([ "C:/opscode/chef/var/cache/cookbooks" ]) + recipe_lines = BAD_RECIPE.split("\n").map {|l| l << "\n" } + IO.should_receive(:readlines).at_least(1).times.with(/:\/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 + + + describe "and examining the stack trace for a recipe" do + it "find the culprit recipe name when the drive letter is upper case" do + @inspector.culprit_file.should == "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) + @inspector.culprit_file.should == "c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb" + end + end + + it "finds the line number of the error from the stack trace" do + @inspector.culprit_line.should == 14 + end + + it "prints a pretty message" do + @description.display(@outputter) + end + end + + describe "when explaining an error on windows, and the backtrace lowercases the drive letter" do + before do + Chef::Config.stub!(:cookbook_path).and_return([ "C:/opscode/chef/var/cache/cookbooks" ]) + recipe_lines = BAD_RECIPE.split("\n").map {|l| l << "\n" } + IO.should_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 + + it "finds the culprit recipe name from the stacktrace" do + @inspector.culprit_file.should == "c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb" + end + + it "finds the line number of the error from the stack trace" do + @inspector.culprit_line.should == 14 + end + + it "prints a pretty message" do + @description.display(@outputter) + end + end + +end |