test-kitchen 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.cane +5 -0
  3. data/.travis.yml +8 -3
  4. data/CHANGELOG.md +66 -0
  5. data/Guardfile +3 -1
  6. data/README.md +3 -1
  7. data/Rakefile +1 -16
  8. data/features/kitchen_command.feature +1 -0
  9. data/features/kitchen_driver_create_command.feature +1 -0
  10. data/features/kitchen_driver_discover_command.feature +1 -0
  11. data/features/kitchen_help_command.feature +16 -0
  12. data/features/kitchen_init_command.feature +2 -0
  13. data/features/kitchen_list_command.feature +42 -0
  14. data/features/support/env.rb +25 -0
  15. data/lib/kitchen.rb +0 -1
  16. data/lib/kitchen/busser.rb +2 -2
  17. data/lib/kitchen/cli.rb +80 -233
  18. data/lib/kitchen/command.rb +117 -0
  19. data/lib/kitchen/command/action.rb +44 -0
  20. data/lib/kitchen/command/console.rb +51 -0
  21. data/lib/kitchen/command/diagnose.rb +51 -0
  22. data/lib/kitchen/command/driver_discover.rb +72 -0
  23. data/lib/kitchen/command/list.rb +86 -0
  24. data/lib/kitchen/command/login.rb +42 -0
  25. data/lib/kitchen/command/sink.rb +53 -0
  26. data/lib/kitchen/command/test.rb +50 -0
  27. data/lib/kitchen/driver/ssh_base.rb +2 -1
  28. data/lib/kitchen/loader/yaml.rb +67 -29
  29. data/lib/kitchen/provisioner/base.rb +67 -4
  30. data/lib/kitchen/provisioner/chef_base.rb +50 -65
  31. data/lib/kitchen/provisioner/chef_solo.rb +3 -2
  32. data/lib/kitchen/provisioner/chef_zero.rb +11 -9
  33. data/lib/kitchen/provisioner/shell.rb +88 -0
  34. data/lib/kitchen/state_file.rb +7 -2
  35. data/lib/kitchen/util.rb +1 -1
  36. data/lib/kitchen/version.rb +1 -1
  37. data/spec/kitchen/loader/yaml_spec.rb +327 -13
  38. data/spec/spec_helper.rb +2 -7
  39. data/support/chef-client-zero.rb +1 -0
  40. data/templates/driver/README.md.erb +1 -1
  41. data/test-kitchen.gemspec +2 -2
  42. metadata +59 -46
@@ -30,7 +30,8 @@ module Kitchen
30
30
  default_config :solo_rb, {}
31
31
 
32
32
  def create_sandbox
33
- create_chef_sandbox { prepare_solo_rb }
33
+ super
34
+ prepare_solo_rb
34
35
  end
35
36
 
36
37
  def run_command
@@ -48,7 +49,7 @@ module Kitchen
48
49
  def prepare_solo_rb
49
50
  data = default_config_rb.merge(config[:solo_rb])
50
51
 
51
- File.open(File.join(tmpdir, "solo.rb"), "wb") do |file|
52
+ File.open(File.join(sandbox_path, "solo.rb"), "wb") do |file|
52
53
  file.write(format_config_file(data))
53
54
  end
54
55
  end
@@ -29,13 +29,13 @@ module Kitchen
29
29
 
30
30
  default_config :client_rb, {}
31
31
  default_config :ruby_bindir, "/opt/chef/embedded/bin"
32
+ default_config :json_attributes, true
32
33
 
33
34
  def create_sandbox
34
- create_chef_sandbox do
35
- prepare_chef_client_zero_rb
36
- prepare_validation_pem
37
- prepare_client_rb
38
- end
35
+ super
36
+ prepare_chef_client_zero_rb
37
+ prepare_validation_pem
38
+ prepare_client_rb
39
39
  end
40
40
 
41
41
  def prepare_command
@@ -62,9 +62,11 @@ module Kitchen
62
62
  def run_command
63
63
  args = [
64
64
  "--config #{config[:root_path]}/client.rb",
65
- "--json-attributes #{config[:root_path]}/dna.json",
66
65
  "--log_level #{config[:log_level]}"
67
66
  ]
67
+ if config[:json_attributes]
68
+ args << "--json-attributes #{config[:root_path]}/dna.json"
69
+ end
68
70
 
69
71
  if local_mode_supported?
70
72
  ["#{sudo('chef-client')} -z"].concat(args).join(" ")
@@ -84,19 +86,19 @@ module Kitchen
84
86
 
85
87
  source = File.join(File.dirname(__FILE__),
86
88
  %w{.. .. .. support chef-client-zero.rb})
87
- FileUtils.cp(source, File.join(tmpdir, "chef-client-zero.rb"))
89
+ FileUtils.cp(source, File.join(sandbox_path, "chef-client-zero.rb"))
88
90
  end
89
91
 
90
92
  def prepare_validation_pem
91
93
  source = File.join(File.dirname(__FILE__),
92
94
  %w{.. .. .. support dummy-validation.pem})
93
- FileUtils.cp(source, File.join(tmpdir, "validation.pem"))
95
+ FileUtils.cp(source, File.join(sandbox_path, "validation.pem"))
94
96
  end
95
97
 
96
98
  def prepare_client_rb
97
99
  data = default_config_rb.merge(config[:client_rb])
98
100
 
99
- File.open(File.join(tmpdir, "client.rb"), "wb") do |file|
101
+ File.open(File.join(sandbox_path, "client.rb"), "wb") do |file|
100
102
  file.write(format_config_file(data))
101
103
  end
102
104
  end
@@ -0,0 +1,88 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Chris Lundquist (<chris.lundquist@github.com>)
4
+ #
5
+ # Copyright (C) 2013, Chris Lundquist
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require 'kitchen/provisioner/base'
20
+
21
+ module Kitchen
22
+
23
+ module Provisioner
24
+
25
+ # Basic shell provisioner.
26
+ #
27
+ # @author Chris Lundquist (<chris.ludnquist@github.com>)
28
+ class Shell < Base
29
+
30
+ default_config :script do |provisioner|
31
+ provisioner.calculate_path("bootstrap.sh", :script)
32
+ end
33
+ expand_path_for :script
34
+
35
+ default_config :data_path do |provisioner|
36
+ provisioner.calculate_path("data")
37
+ end
38
+ expand_path_for :data_path
39
+
40
+ def create_sandbox
41
+ super
42
+ prepare_data
43
+ prepare_script
44
+ end
45
+
46
+ def init_command
47
+ data = File.join(config[:root_path], "data")
48
+ "#{sudo('rm')} -rf #{data} ; mkdir -p #{config[:root_path]}"
49
+ end
50
+
51
+ def run_command
52
+ sudo(File.join(config[:root_path], File.basename(config[:script])))
53
+ end
54
+
55
+ protected
56
+
57
+ def prepare_data
58
+ return unless config[:data_path]
59
+
60
+ info("Preparing data")
61
+ debug("Using data from #{config[:data_path]}")
62
+
63
+ tmpdata_dir = File.join(sandbox_path, "data")
64
+ FileUtils.mkdir_p(tmpdata_dir)
65
+ FileUtils.cp_r(Dir.glob("#{config[:data_path]}/*"), tmpdata_dir)
66
+ end
67
+
68
+ def prepare_script
69
+ info("Preparing script")
70
+
71
+ if config[:script]
72
+ debug("Using script from #{config[:script]}")
73
+ FileUtils.cp_r(config[:script], sandbox_path)
74
+ else
75
+ config[:script] = File.join(sandbox_path, "bootstrap.sh")
76
+ info("#{File.basename(config[:script])} not found " +
77
+ "so Kitchen will run a stubbed script. Is this intended?")
78
+ File.open(config[:script], "wb") do |file|
79
+ file.write(%{#!/bin/sh\necho "NO BOOTSTRAP SCRIPT PRESENT"\n})
80
+ end
81
+ end
82
+
83
+ FileUtils.chmod(0755,
84
+ File.join(sandbox_path, File.basename(config[:script])))
85
+ end
86
+ end
87
+ end
88
+ end
@@ -16,7 +16,12 @@
16
16
  # See the License for the specific language governing permissions and
17
17
  # limitations under the License.
18
18
 
19
- require 'safe_yaml'
19
+ if RUBY_VERSION <= "1.9.3"
20
+ # ensure that Psych and not Syck is used for Ruby 1.9.2
21
+ require 'yaml'
22
+ YAML::ENGINE.yamler = 'psych'
23
+ end
24
+ require 'safe_yaml/load'
20
25
 
21
26
  module Kitchen
22
27
 
@@ -86,7 +91,7 @@ module Kitchen
86
91
  end
87
92
 
88
93
  def deserialize_string(string)
89
- ::YAML.safe_load(string)
94
+ SafeYAML.load(string)
90
95
  rescue SyntaxError, Psych::SyntaxError => ex
91
96
  raise StateFileLoadError, "Error parsing #{file_name} (#{ex.message})"
92
97
  end
data/lib/kitchen/util.rb CHANGED
@@ -184,7 +184,7 @@ module Kitchen
184
184
 
185
185
  # do_download URL FILENAME
186
186
  do_download() {
187
- PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
187
+ PATH=/opt/local/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
188
188
  export PATH
189
189
 
190
190
  echo "downloading $1"
@@ -18,5 +18,5 @@
18
18
 
19
19
  module Kitchen
20
20
 
21
- VERSION = "1.1.1"
21
+ VERSION = "1.2.0"
22
22
  end
@@ -28,7 +28,9 @@ end
28
28
 
29
29
  describe Kitchen::Loader::YAML do
30
30
 
31
- let(:loader) { Kitchen::Loader::YAML.new("/tmp/.kitchen.yml") }
31
+ let(:loader) do
32
+ Kitchen::Loader::YAML.new(:project_config => "/tmp/.kitchen.yml")
33
+ end
32
34
 
33
35
  before do
34
36
  FakeFS.activate!
@@ -42,17 +44,64 @@ describe Kitchen::Loader::YAML do
42
44
 
43
45
  describe ".initialize" do
44
46
 
45
- it "sets config_file based on Dir.pwd by default" do
47
+ it "sets project_config based on Dir.pwd by default" do
48
+ stub_file(File.join(Dir.pwd, '.kitchen.yml'), Hash.new)
46
49
  loader = Kitchen::Loader::YAML.new
47
50
 
48
- loader.config_file.must_equal File.expand_path(
49
- File.join(Dir.pwd, '.kitchen.yml'))
51
+ loader.diagnose[:project_config][:filename].
52
+ must_equal File.expand_path(File.join(Dir.pwd, '.kitchen.yml'))
50
53
  end
51
54
 
52
- it "sets config_file from parameter, if given" do
53
- loader = Kitchen::Loader::YAML.new('/tmp/crazyfunkytown.file')
55
+ it "sets project_config from parameter, if given" do
56
+ stub_file('/tmp/crazyfunkytown.file', Hash.new)
57
+ loader = Kitchen::Loader::YAML.new(
58
+ :project_config => '/tmp/crazyfunkytown.file')
54
59
 
55
- loader.config_file.must_equal '/tmp/crazyfunkytown.file'
60
+ loader.diagnose[:project_config][:filename].
61
+ must_match %r{/tmp/crazyfunkytown.file$}
62
+ end
63
+
64
+ it "sets local_config based on Dir.pwd by default" do
65
+ stub_file(File.join(Dir.pwd, '.kitchen.local.yml'), Hash.new)
66
+ loader = Kitchen::Loader::YAML.new
67
+
68
+ loader.diagnose[:local_config][:filename].
69
+ must_equal File.expand_path(File.join(Dir.pwd, '.kitchen.local.yml'))
70
+ end
71
+
72
+ it "sets local_config based on location of project_config by default" do
73
+ stub_file('/tmp/.kitchen.local.yml', Hash.new)
74
+ loader = Kitchen::Loader::YAML.new(
75
+ :project_config => '/tmp/.kitchen.yml')
76
+
77
+ loader.diagnose[:local_config][:filename].
78
+ must_match %r{/tmp/.kitchen.local.yml$}
79
+ end
80
+
81
+ it "sets local_config from parameter, if given" do
82
+ stub_file('/tmp/crazyfunkytown.file', Hash.new)
83
+ loader = Kitchen::Loader::YAML.new(
84
+ :local_config => '/tmp/crazyfunkytown.file')
85
+
86
+ loader.diagnose[:local_config][:filename].
87
+ must_match %r{/tmp/crazyfunkytown.file$}
88
+ end
89
+
90
+ it "sets global_config based on ENV['HOME'] by default" do
91
+ stub_file(File.join(ENV['HOME'], '.kitchen/config.yml'), Hash.new)
92
+ loader = Kitchen::Loader::YAML.new
93
+
94
+ loader.diagnose[:global_config][:filename].must_equal File.expand_path(
95
+ File.join(ENV['HOME'], '.kitchen/config.yml'))
96
+ end
97
+
98
+ it "sets global_config from parameter, if given" do
99
+ stub_file('/tmp/crazyfunkytown.file', Hash.new)
100
+ loader = Kitchen::Loader::YAML.new(
101
+ :global_config => '/tmp/crazyfunkytown.file')
102
+
103
+ loader.diagnose[:global_config][:filename].
104
+ must_match %r{/tmp/crazyfunkytown.file$}
56
105
  end
57
106
  end
58
107
 
@@ -326,14 +375,25 @@ describe Kitchen::Loader::YAML do
326
375
  FileUtils.mkdir_p "/tmp"
327
376
  File.open("/tmp/.kitchen.yml", "wb") { |f| f.write '&*%^*' }
328
377
 
329
- proc { loader.read }.must_raise Kitchen::UserError
378
+ err = proc { loader.read }.must_raise Kitchen::UserError
379
+ err.message.must_match Regexp.new(
380
+ "Error parsing ([a-zA-Z]:)?\/tmp\/\.kitchen\.yml")
330
381
  end
331
382
 
332
383
  it "raises a UserError if kitchen.yml cannot be parsed" do
333
384
  FileUtils.mkdir_p "/tmp"
334
385
  File.open("/tmp/.kitchen.yml", "wb") { |f| f.write 'uhoh' }
335
386
 
336
- proc { loader.read }.must_raise Kitchen::UserError
387
+ err = proc { loader.read }.must_raise Kitchen::UserError
388
+ err.message.must_match Regexp.new(
389
+ "Error parsing ([a-zA-Z]:)?\/tmp\/\.kitchen\.yml")
390
+ end
391
+
392
+ it "handles a kitchen.yml if it is a commented out YAML document" do
393
+ FileUtils.mkdir_p "/tmp"
394
+ File.open("/tmp/.kitchen.yml", "wb") { |f| f.write '#---\n' }
395
+
396
+ loader.read.must_equal(Hash.new)
337
397
  end
338
398
 
339
399
  it "raises a UserError if kitchen.local.yml cannot be parsed" do
@@ -356,6 +416,20 @@ describe Kitchen::Loader::YAML do
356
416
  loader.read.must_equal({ :name => "ahhchoo" })
357
417
  end
358
418
 
419
+ it "raises a UserError if there is an ERB processing error" do
420
+ FileUtils.mkdir_p "/tmp"
421
+ File.open("/tmp/.kitchen.yml", "wb") do |f|
422
+ f.write <<-'YAML'.gsub(/^ {10}/, '')
423
+ ---
424
+ <%= poop %>: yep
425
+ YAML
426
+ end
427
+
428
+ err = proc { loader.read }.must_raise Kitchen::UserError
429
+ err.message.must_match Regexp.new(
430
+ "Error parsing ERB content in ([a-zA-Z]:)?\/tmp\/\.kitchen\.yml")
431
+ end
432
+
359
433
  it "evaluates kitchen.local.yml through erb before loading by default" do
360
434
  FileUtils.mkdir_p "/tmp"
361
435
  File.open("/tmp/.kitchen.local.yml", "wb") do |f|
@@ -377,7 +451,7 @@ describe Kitchen::Loader::YAML do
377
451
 
378
452
  it "skips evaluating kitchen.yml through erb if disabled" do
379
453
  loader = Kitchen::Loader::YAML.new(
380
- '/tmp/.kitchen.yml', :process_erb => false)
454
+ :project_config => '/tmp/.kitchen.yml', :process_erb => false)
381
455
  FileUtils.mkdir_p "/tmp"
382
456
  File.open("/tmp/.kitchen.yml", "wb") do |f|
383
457
  f.write <<-'YAML'.gsub(/^ {10}/, '')
@@ -391,7 +465,7 @@ describe Kitchen::Loader::YAML do
391
465
 
392
466
  it "skips evaluating kitchen.local.yml through erb if disabled" do
393
467
  loader = Kitchen::Loader::YAML.new(
394
- '/tmp/.kitchen.yml', :process_erb => false)
468
+ :project_config => '/tmp/.kitchen.yml', :process_erb => false)
395
469
  FileUtils.mkdir_p "/tmp"
396
470
  File.open("/tmp/.kitchen.local.yml", "wb") do |f|
397
471
  f.write <<-'YAML'.gsub(/^ {10}/, '')
@@ -406,7 +480,7 @@ describe Kitchen::Loader::YAML do
406
480
 
407
481
  it "skips kitchen.local.yml if disabled" do
408
482
  loader = Kitchen::Loader::YAML.new(
409
- '/tmp/.kitchen.yml', :process_local => false)
483
+ :project_config => '/tmp/.kitchen.yml', :process_local => false)
410
484
  stub_yaml!(".kitchen.yml", {
411
485
  'a' => 'b'
412
486
  })
@@ -419,7 +493,7 @@ describe Kitchen::Loader::YAML do
419
493
 
420
494
  it "skips the global config if disabled" do
421
495
  loader = Kitchen::Loader::YAML.new(
422
- '/tmp/.kitchen.yml', :process_global => false)
496
+ :project_config => '/tmp/.kitchen.yml', :process_global => false)
423
497
  stub_yaml!(".kitchen.yml", {
424
498
  'a' => 'b'
425
499
  })
@@ -431,6 +505,246 @@ describe Kitchen::Loader::YAML do
431
505
  end
432
506
  end
433
507
 
508
+ describe "#diagnose" do
509
+
510
+ it "returns a Hash" do
511
+ stub_yaml!(Hash.new)
512
+
513
+ loader.diagnose.must_be_kind_of(Hash)
514
+ end
515
+
516
+ it "contains erb processing information when true" do
517
+ stub_yaml!(Hash.new)
518
+
519
+ loader.diagnose[:process_erb].must_equal true
520
+ end
521
+
522
+ it "contains erb processing information when false" do
523
+ stub_yaml!(Hash.new)
524
+ loader = Kitchen::Loader::YAML.new(
525
+ :project_config => '/tmp/.kitchen.yml', :process_erb => false)
526
+
527
+ loader.diagnose[:process_erb].must_equal false
528
+ end
529
+
530
+ it "contains local processing information when true" do
531
+ stub_yaml!(Hash.new)
532
+
533
+ loader.diagnose[:process_local].must_equal true
534
+ end
535
+
536
+ it "contains local processing information when false" do
537
+ stub_yaml!(Hash.new)
538
+ loader = Kitchen::Loader::YAML.new(
539
+ :project_config => '/tmp/.kitchen.yml', :process_local => false)
540
+
541
+ loader.diagnose[:process_local].must_equal false
542
+ end
543
+
544
+ it "contains global processing information when true" do
545
+ stub_yaml!(Hash.new)
546
+
547
+ loader.diagnose[:process_global].must_equal true
548
+ end
549
+
550
+ it "contains global processing information when false" do
551
+ stub_yaml!(Hash.new)
552
+ loader = Kitchen::Loader::YAML.new(
553
+ :project_config => '/tmp/.kitchen.yml', :process_global => false)
554
+
555
+ loader.diagnose[:process_global].must_equal false
556
+ end
557
+
558
+ describe "for yaml files" do
559
+
560
+ before do
561
+ stub_yaml!(".kitchen.yml", {
562
+ "from_project" => "project",
563
+ "common" => { "p" => "pretty" }
564
+ })
565
+ stub_yaml!(".kitchen.local.yml", {
566
+ "from_local" => "local",
567
+ "common" => { "l" => "looky" }
568
+ })
569
+ stub_global!({
570
+ "from_global" => "global",
571
+ "common" => { "g" => "goody" }
572
+ })
573
+ end
574
+
575
+ it "global config contains a filename" do
576
+ loader.diagnose[:global_config][:filename].
577
+ must_equal File.join(ENV["HOME"], ".kitchen/config.yml")
578
+ end
579
+
580
+ it "global config contains raw data" do
581
+ loader.diagnose[:global_config][:raw_data].must_equal({
582
+ "from_global" => "global",
583
+ "common" => { "g" => "goody" }
584
+ })
585
+ end
586
+
587
+ it "project config contains a filename" do
588
+ loader.diagnose[:project_config][:filename].
589
+ must_match %r{/tmp/.kitchen.yml$}
590
+ end
591
+
592
+ it "project config contains raw data" do
593
+ loader.diagnose[:project_config][:raw_data].must_equal({
594
+ "from_project" => "project",
595
+ "common" => { "p" => "pretty" }
596
+ })
597
+ end
598
+
599
+ it "local config contains a filename" do
600
+ loader.diagnose[:local_config][:filename].
601
+ must_match %r{/tmp/.kitchen.local.yml$}
602
+ end
603
+
604
+ it "local config contains raw data" do
605
+ loader.diagnose[:local_config][:raw_data].must_equal({
606
+ "from_local" => "local",
607
+ "common" => { "l" => "looky" }
608
+ })
609
+ end
610
+
611
+ it "combined config contains a nil filename" do
612
+ loader.diagnose[:combined_config][:filename].
613
+ must_equal nil
614
+ end
615
+
616
+ it "combined config contains raw data" do
617
+ loader.diagnose[:combined_config][:raw_data].must_equal({
618
+ "from_global" => "global",
619
+ "from_project" => "project",
620
+ "from_local" => "local",
621
+ "common" => {
622
+ "g" => "goody",
623
+ "p" => "pretty",
624
+ "l" => "looky"
625
+ }
626
+ })
627
+ end
628
+
629
+ describe "for global on error" do
630
+
631
+ before do
632
+ FileUtils.mkdir_p(File.join(ENV["HOME"], ".kitchen"))
633
+ File.open(File.join(ENV["HOME"], ".kitchen/config.yml"), "wb") do |f|
634
+ f.write '&*%^*'
635
+ end
636
+ end
637
+
638
+ it "uses an error hash with the raw file contents" do
639
+ loader.diagnose[:global_config][:raw_data][:error][:raw_file].
640
+ must_equal "&*%^*"
641
+ end
642
+
643
+ it "uses an error hash with the exception" do
644
+ loader.diagnose[:global_config][:raw_data][:error][:exception].
645
+ must_match %r{Kitchen::UserError}
646
+ end
647
+
648
+ it "uses an error hash with the exception message" do
649
+ loader.diagnose[:global_config][:raw_data][:error][:message].
650
+ must_match %r{Error parsing}
651
+ end
652
+
653
+ it "uses an error hash with the exception backtrace" do
654
+ loader.diagnose[:global_config][:raw_data][:error][:backtrace].
655
+ must_be_kind_of Array
656
+ end
657
+ end
658
+
659
+ describe "for project on error" do
660
+
661
+ before do
662
+ File.open("/tmp/.kitchen.yml", "wb") do |f|
663
+ f.write '&*%^*'
664
+ end
665
+ end
666
+
667
+ it "uses an error hash with the raw file contents" do
668
+ loader.diagnose[:project_config][:raw_data][:error][:raw_file].
669
+ must_equal "&*%^*"
670
+ end
671
+
672
+ it "uses an error hash with the exception" do
673
+ loader.diagnose[:project_config][:raw_data][:error][:exception].
674
+ must_match %r{Kitchen::UserError}
675
+ end
676
+
677
+ it "uses an error hash with the exception message" do
678
+ loader.diagnose[:project_config][:raw_data][:error][:message].
679
+ must_match %r{Error parsing}
680
+ end
681
+
682
+ it "uses an error hash with the exception backtrace" do
683
+ loader.diagnose[:project_config][:raw_data][:error][:backtrace].
684
+ must_be_kind_of Array
685
+ end
686
+ end
687
+
688
+ describe "for local on error" do
689
+
690
+ before do
691
+ File.open("/tmp/.kitchen.local.yml", "wb") do |f|
692
+ f.write '&*%^*'
693
+ end
694
+ end
695
+
696
+ it "uses an error hash with the raw file contents" do
697
+ loader.diagnose[:local_config][:raw_data][:error][:raw_file].
698
+ must_equal "&*%^*"
699
+ end
700
+
701
+ it "uses an error hash with the exception" do
702
+ loader.diagnose[:local_config][:raw_data][:error][:exception].
703
+ must_match %r{Kitchen::UserError}
704
+ end
705
+
706
+ it "uses an error hash with the exception message" do
707
+ loader.diagnose[:local_config][:raw_data][:error][:message].
708
+ must_match %r{Error parsing}
709
+ end
710
+
711
+ it "uses an error hash with the exception backtrace" do
712
+ loader.diagnose[:local_config][:raw_data][:error][:backtrace].
713
+ must_be_kind_of Array
714
+ end
715
+ end
716
+
717
+ describe "for combined on error" do
718
+
719
+ before do
720
+ File.open("/tmp/.kitchen.yml", "wb") do |f|
721
+ f.write '&*%^*'
722
+ end
723
+ end
724
+
725
+ it "uses an error hash with nil raw file contents" do
726
+ loader.diagnose[:combined_config][:raw_data][:error][:raw_file].
727
+ must_equal nil
728
+ end
729
+
730
+ it "uses an error hash with the exception" do
731
+ loader.diagnose[:combined_config][:raw_data][:error][:exception].
732
+ must_match %r{Kitchen::UserError}
733
+ end
734
+
735
+ it "uses an error hash with the exception message" do
736
+ loader.diagnose[:combined_config][:raw_data][:error][:message].
737
+ must_match %r{Error parsing}
738
+ end
739
+
740
+ it "uses an error hash with the exception backtrace" do
741
+ loader.diagnose[:combined_config][:raw_data][:error][:backtrace].
742
+ must_be_kind_of Array
743
+ end
744
+ end
745
+ end
746
+ end
747
+
434
748
  private
435
749
 
436
750
  def stub_file(path, hash)