test-kitchen 1.3.1 → 1.4.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/.cane +2 -0
  3. data/.gitignore +4 -0
  4. data/CHANGELOG.md +45 -0
  5. data/Rakefile +15 -0
  6. data/features/kitchen_action_commands.feature +12 -9
  7. data/features/kitchen_defaults.feature +38 -0
  8. data/features/kitchen_init_command.feature +0 -1
  9. data/features/kitchen_list_command.feature +2 -2
  10. data/features/kitchen_login_command.feature +7 -1
  11. data/features/kitchen_test_command.feature +4 -4
  12. data/lib/kitchen.rb +40 -11
  13. data/lib/kitchen/cli.rb +38 -22
  14. data/lib/kitchen/command/list.rb +5 -2
  15. data/lib/kitchen/config.rb +45 -18
  16. data/lib/kitchen/configurable.rb +137 -1
  17. data/lib/kitchen/data_munger.rb +248 -17
  18. data/lib/kitchen/driver.rb +1 -1
  19. data/lib/kitchen/driver/base.rb +1 -83
  20. data/lib/kitchen/driver/dummy.rb +0 -5
  21. data/lib/kitchen/driver/ssh_base.rb +177 -22
  22. data/lib/kitchen/instance.rb +140 -20
  23. data/lib/kitchen/logger.rb +43 -8
  24. data/lib/kitchen/login_command.rb +14 -5
  25. data/lib/kitchen/platform.rb +19 -0
  26. data/lib/kitchen/provisioner.rb +5 -3
  27. data/lib/kitchen/provisioner/base.rb +46 -48
  28. data/lib/kitchen/provisioner/chef/common_sandbox.rb +322 -0
  29. data/lib/kitchen/provisioner/chef_base.rb +179 -286
  30. data/lib/kitchen/provisioner/chef_solo.rb +11 -5
  31. data/lib/kitchen/provisioner/chef_zero.rb +108 -94
  32. data/lib/kitchen/provisioner/dummy.rb +47 -0
  33. data/lib/kitchen/provisioner/shell.rb +45 -12
  34. data/lib/kitchen/rake_tasks.rb +1 -1
  35. data/lib/kitchen/ssh.rb +1 -1
  36. data/lib/kitchen/thor_tasks.rb +1 -1
  37. data/lib/kitchen/transport.rb +54 -0
  38. data/lib/kitchen/transport/base.rb +146 -0
  39. data/lib/kitchen/transport/dummy.rb +75 -0
  40. data/lib/kitchen/transport/ssh.rb +325 -0
  41. data/lib/kitchen/transport/winrm.rb +508 -0
  42. data/lib/kitchen/transport/winrm/command_executor.rb +188 -0
  43. data/lib/kitchen/transport/winrm/file_transporter.rb +454 -0
  44. data/lib/kitchen/transport/winrm/logging.rb +50 -0
  45. data/lib/kitchen/transport/winrm/template.rb +74 -0
  46. data/lib/kitchen/transport/winrm/tmp_zip.rb +187 -0
  47. data/lib/kitchen/verifier.rb +55 -0
  48. data/lib/kitchen/verifier/base.rb +191 -0
  49. data/lib/kitchen/verifier/busser.rb +266 -0
  50. data/lib/kitchen/verifier/dummy.rb +75 -0
  51. data/lib/kitchen/version.rb +1 -1
  52. data/spec/kitchen/cli_spec.rb +56 -0
  53. data/spec/kitchen/config_spec.rb +61 -20
  54. data/spec/kitchen/configurable_spec.rb +327 -1
  55. data/spec/kitchen/data_munger_spec.rb +777 -14
  56. data/spec/kitchen/driver/base_spec.rb +7 -38
  57. data/spec/kitchen/driver/dummy_spec.rb +0 -29
  58. data/spec/kitchen/driver/ssh_base_spec.rb +580 -236
  59. data/spec/kitchen/driver_spec.rb +1 -0
  60. data/spec/kitchen/instance_spec.rb +383 -83
  61. data/spec/kitchen/login_command_spec.rb +29 -10
  62. data/spec/kitchen/platform_spec.rb +58 -2
  63. data/spec/kitchen/provisioner/base_spec.rb +170 -18
  64. data/spec/kitchen/provisioner/chef_base_spec.rb +454 -104
  65. data/spec/kitchen/provisioner/chef_solo_spec.rb +307 -104
  66. data/spec/kitchen/provisioner/chef_zero_spec.rb +561 -230
  67. data/spec/kitchen/provisioner/dummy_spec.rb +91 -0
  68. data/spec/kitchen/provisioner/shell_spec.rb +158 -56
  69. data/spec/kitchen/provisioner_spec.rb +37 -0
  70. data/spec/kitchen/ssh_spec.rb +19 -19
  71. data/spec/kitchen/transport/base_spec.rb +89 -0
  72. data/spec/kitchen/transport/ssh_spec.rb +1147 -0
  73. data/spec/kitchen/transport/winrm/command_executor_spec.rb +400 -0
  74. data/spec/kitchen/transport/winrm/file_transporter_spec.rb +876 -0
  75. data/spec/kitchen/transport/winrm/logging_spec.rb +92 -0
  76. data/spec/kitchen/transport/winrm/template_spec.rb +51 -0
  77. data/spec/kitchen/transport/winrm/tmp_zip_spec.rb +132 -0
  78. data/spec/kitchen/transport/winrm_spec.rb +1069 -0
  79. data/spec/kitchen/transport_spec.rb +112 -0
  80. data/spec/kitchen/verifier/base_spec.rb +310 -0
  81. data/spec/kitchen/verifier/busser_spec.rb +540 -0
  82. data/spec/kitchen/verifier/dummy_spec.rb +91 -0
  83. data/spec/kitchen/verifier_spec.rb +120 -0
  84. data/spec/kitchen_spec.rb +7 -0
  85. data/spec/spec_helper.rb +8 -0
  86. data/spec/support/powershell_max_size_spec.rb +40 -0
  87. data/support/busser_install_command.ps1 +14 -0
  88. data/support/busser_install_command.sh +15 -0
  89. data/support/check_files.ps1.erb +48 -0
  90. data/support/chef_base_init_command.ps1 +18 -0
  91. data/support/chef_base_init_command.sh +2 -0
  92. data/support/chef_base_install_command.ps1 +76 -0
  93. data/support/chef_base_install_command.sh +137 -0
  94. data/support/chef_zero_prepare_command_legacy.ps1 +9 -0
  95. data/support/chef_zero_prepare_command_legacy.sh +10 -0
  96. data/support/decode_files.ps1.erb +61 -0
  97. data/test-kitchen.gemspec +2 -0
  98. metadata +97 -8
  99. data/lib/kitchen/busser.rb +0 -316
  100. data/spec/kitchen/busser_spec.rb +0 -490
  101. data/support/chef_helpers.sh +0 -16
@@ -22,28 +22,47 @@ require "kitchen/login_command"
22
22
 
23
23
  describe Kitchen::LoginCommand do
24
24
 
25
- let(:argv) { Array.new }
26
- let(:opts) { Hash.new }
25
+ let(:cmd) { "" }
26
+ let(:argv) { Array.new }
27
+ let(:opts) { Hash.new }
27
28
 
28
- let(:cmd) { Kitchen::LoginCommand.new(argv, opts) }
29
+ let(:login_command) { Kitchen::LoginCommand.new(cmd, argv, opts) }
29
30
 
30
- it "#cmd_array defaults to an empty array" do
31
- Kitchen::LoginCommand.new(nil, opts).cmd_array.must_equal []
31
+ it "#command returns the command" do
32
+ cmd << "one"
33
+
34
+ login_command.command.must_equal "one"
35
+ end
36
+
37
+ it "#arguments defaults to an empty array" do
38
+ Kitchen::LoginCommand.new("echo", nil).arguments.must_equal []
32
39
  end
33
40
 
34
- it "#cmd_array returns the command array from the constructor" do
35
- argv.concat(["one", "-o", "two"])
41
+ it "#arguments returns the command arguments" do
42
+ argv.concat(["-o", "two"])
36
43
 
37
- cmd.cmd_array.must_equal ["one", "-o", "two"]
44
+ login_command.arguments.must_equal ["-o", "two"]
38
45
  end
39
46
 
40
47
  it "#options defaults to an empty hash" do
41
- Kitchen::LoginCommand.new(argv, nil).options.must_equal {}
48
+ Kitchen::LoginCommand.new(cmd, argv, nil).options.must_equal {}
42
49
  end
43
50
 
44
51
  it "#options returns the options hash from the constructor" do
45
52
  opts[:cake] = "yummy"
46
53
 
47
- cmd.options.must_equal(:cake => "yummy")
54
+ login_command.options.must_equal(:cake => "yummy")
55
+ end
56
+
57
+ it "#exec_args returns an array of arguments for Kernel.exec" do
58
+ cmd << "alpha"
59
+ login_command.exec_args.must_equal ["alpha", {}]
60
+
61
+ argv.concat(["-o", "beta"])
62
+ login_command.exec_args.must_equal ["alpha", "-o", "beta", {}]
63
+
64
+ opts[:charlie] = "delta"
65
+ login_command.exec_args.must_equal [
66
+ "alpha", "-o", "beta", { :charlie => "delta" }]
48
67
  end
49
68
  end
@@ -24,10 +24,66 @@ require "kitchen/platform"
24
24
  describe Kitchen::Platform do
25
25
 
26
26
  let(:opts) do; { :name => "plata" }; end
27
- let(:platform) { Kitchen::Platform.new(opts) }
27
+ let(:klass) { Kitchen::Platform }
28
28
 
29
29
  it "raises an ArgumentError if name is missing" do
30
30
  opts.delete(:name)
31
- proc { Kitchen::Platform.new(opts) }.must_raise Kitchen::ClientError
31
+ proc { klass.new(opts) }.must_raise Kitchen::ClientError
32
+ end
33
+
34
+ it "#os_type returns value passed into constructor with :os_type" do
35
+ klass.new(:name => "p", :os_type => "unix").os_type.must_equal "unix"
36
+ klass.new(:name => "p", :os_type => "windows").os_type.must_equal "windows"
37
+ klass.new(:name => "p", :os_type => "unicorn").os_type.must_equal "unicorn"
38
+ klass.new(:name => "p", :os_type => nil).os_type.must_equal nil
39
+ end
40
+
41
+ it "#os_type defaults to `unix` when not provided" do
42
+ klass.new(:name => "p").os_type.must_equal "unix"
43
+ end
44
+
45
+ it "#os_type defaults to `windows` if the name starts with 'win'" do
46
+ klass.new(:name => "win").os_type.must_equal "windows"
47
+ klass.new(:name => "Win").os_type.must_equal "windows"
48
+ klass.new(:name => "win7").os_type.must_equal "windows"
49
+ klass.new(:name => "windows").os_type.must_equal "windows"
50
+ klass.new(:name => "Windows").os_type.must_equal "windows"
51
+ klass.new(:name => "windows81").os_type.must_equal "windows"
52
+ klass.new(:name => "windows-2012").os_type.must_equal "windows"
53
+ end
54
+
55
+ it "#shell_type returns value passed into constructor with :shell_type" do
56
+ klass.new(:name => "p", :shell_type => "bourne").
57
+ shell_type.must_equal "bourne"
58
+ klass.new(:name => "p", :shell_type => "powershell").
59
+ shell_type.must_equal "powershell"
60
+ klass.new(:name => "p", :shell_type => "unicorn").
61
+ shell_type.must_equal "unicorn"
62
+ klass.new(:name => "p", :shell_type => nil).
63
+ shell_type.must_equal nil
64
+ end
65
+
66
+ it "#shell_type defaults to `bourne` when not provided" do
67
+ klass.new(:name => "p").shell_type.must_equal "bourne"
68
+ end
69
+
70
+ it "#shell_type defaults to `powershell` if the name starts with 'windows'" do
71
+ klass.new(:name => "win").shell_type.must_equal "powershell"
72
+ klass.new(:name => "Win").shell_type.must_equal "powershell"
73
+ klass.new(:name => "win7").shell_type.must_equal "powershell"
74
+ klass.new(:name => "windows").shell_type.must_equal "powershell"
75
+ klass.new(:name => "Windows").shell_type.must_equal "powershell"
76
+ klass.new(:name => "windows81").shell_type.must_equal "powershell"
77
+ klass.new(:name => "windows-2012").shell_type.must_equal "powershell"
78
+ end
79
+
80
+ it "#diagnose returns a hash with sorted keys" do
81
+ opts[:os_type] = "unikitty"
82
+ opts[:shell_type] = "wundershell"
83
+
84
+ klass.new(opts).diagnose.must_equal(
85
+ :os_type => "unikitty",
86
+ :shell_type => "wundershell"
87
+ )
32
88
  end
33
89
  end
@@ -22,49 +22,201 @@ require "stringio"
22
22
 
23
23
  require "kitchen"
24
24
 
25
+ module Kitchen
26
+
27
+ module Provisioner
28
+
29
+ class TestingDummy < Kitchen::Provisioner::Base
30
+
31
+ attr_reader :called_create_sandbox, :called_cleanup_sandbox
32
+
33
+ def install_command
34
+ "install"
35
+ end
36
+
37
+ def init_command
38
+ "init"
39
+ end
40
+
41
+ def prepare_command
42
+ "prepare"
43
+ end
44
+
45
+ def run_command
46
+ "run"
47
+ end
48
+
49
+ def create_sandbox
50
+ @called_create_sandbox = true
51
+ end
52
+
53
+ def cleanup_sandbox
54
+ @called_cleanup_sandbox = true
55
+ end
56
+
57
+ def sandbox_path
58
+ "/tmp/sandbox"
59
+ end
60
+ end
61
+ end
62
+ end
63
+
25
64
  describe Kitchen::Provisioner::Base do
26
65
 
27
66
  let(:logged_output) { StringIO.new }
28
67
  let(:logger) { Logger.new(logged_output) }
68
+ let(:platform) { stub(:os_type => nil, :shell_type => nil) }
29
69
  let(:config) { Hash.new }
30
70
 
71
+ let(:transport) do
72
+ t = mock("transport")
73
+ t.responds_like_instance_of(Kitchen::Transport::Base)
74
+ t
75
+ end
76
+
31
77
  let(:instance) do
32
- stub(:name => "coolbeans", :logger => logger)
78
+ stub(
79
+ :name => "coolbeans",
80
+ :to_str => "instance",
81
+ :logger => logger,
82
+ :platform => platform,
83
+ :transport => transport
84
+ )
33
85
  end
34
86
 
35
87
  let(:provisioner) do
36
88
  Kitchen::Provisioner::Base.new(config).finalize_config!(instance)
37
89
  end
38
90
 
39
- it "#name returns the name of the provisioner" do
40
- provisioner.name.must_equal "Base"
41
- end
42
-
43
91
  describe "configuration" do
44
92
 
45
- it ":root_path defaults to /tmp/kitchen" do
46
- provisioner[:root_path].must_equal "/tmp/kitchen"
93
+ describe "for unix operating systems" do
94
+
95
+ before { platform.stubs(:os_type).returns("unix") }
96
+
97
+ it ":root_path defaults to /tmp/kitchen" do
98
+ provisioner[:root_path].must_equal "/tmp/kitchen"
99
+ end
100
+
101
+ it ":sudo defaults to true" do
102
+ provisioner[:sudo].must_equal true
103
+ end
104
+ end
105
+
106
+ describe "for windows operating systems" do
107
+
108
+ before { platform.stubs(:os_type).returns("windows") }
109
+
110
+ it ":root_path defaults to $env:TEMP\\kitchen" do
111
+ provisioner[:root_path].must_equal "$env:TEMP\\kitchen"
112
+ end
113
+
114
+ it ":sudo defaults to nil" do
115
+ provisioner[:sudo].must_equal nil
116
+ end
117
+ end
118
+
119
+ it ":http_proxy defaults to nil" do
120
+ provisioner[:http_proxy].must_equal nil
47
121
  end
48
122
 
49
- it ":sudo defaults to true" do
50
- provisioner[:sudo].must_equal true
123
+ it ":http_proxys defaults to nil" do
124
+ provisioner[:https_proxy].must_equal nil
51
125
  end
52
126
  end
53
127
 
54
- describe "#logger" do
128
+ describe "#call" do
129
+
130
+ let(:state) { Hash.new }
131
+ let(:cmd) { provisioner.call(state) }
132
+
133
+ let(:connection) do
134
+ c = mock("transport_connection")
135
+ c.responds_like_instance_of(Kitchen::Transport::Base::Connection)
136
+ c
137
+ end
138
+
139
+ let(:provisioner) do
140
+ Kitchen::Provisioner::TestingDummy.new(config).finalize_config!(instance)
141
+ end
142
+
143
+ before do
144
+ FakeFS.activate!
145
+ FileUtils.mkdir_p(File.join(provisioner.sandbox_path, "stuff"))
146
+ transport.stubs(:connection).yields(connection)
147
+ connection.stubs(:execute)
148
+ connection.stubs(:upload)
149
+ end
150
+
151
+ after do
152
+ FakeFS.deactivate!
153
+ FakeFS::FileSystem.clear
154
+ end
155
+
156
+ it "creates the sandbox" do
157
+ provisioner.expects(:create_sandbox)
158
+
159
+ cmd
160
+ end
161
+
162
+ it "ensures that the sandbox is cleanup up" do
163
+ transport.stubs(:connection).raises
164
+ provisioner.expects(:cleanup_sandbox)
165
+
166
+ begin
167
+ cmd
168
+ rescue # rubocop:disable Lint/HandleExceptions
169
+ end
170
+ end
171
+
172
+ it "yields a connection given the state" do
173
+ state[:a] = "b"
174
+ transport.expects(:connection).with(state).yields(connection)
175
+
176
+ cmd
177
+ end
178
+
179
+ it "invokes the provisioner commands over the transport" do
180
+ order = sequence("order")
181
+ connection.expects(:execute).with("install").in_sequence(order)
182
+ connection.expects(:execute).with("init").in_sequence(order)
183
+ connection.expects(:execute).with("prepare").in_sequence(order)
184
+ connection.expects(:execute).with("run").in_sequence(order)
185
+
186
+ cmd
187
+ end
188
+
189
+ it "logs to info" do
190
+ cmd
191
+
192
+ logged_output.string.
193
+ must_match(/INFO -- : Transferring files to instance$/)
194
+ end
195
+
196
+ it "uploads sandbox files" do
197
+ connection.expects(:upload).with(["/tmp/sandbox/stuff"], "/tmp/kitchen")
198
+
199
+ cmd
200
+ end
201
+
202
+ it "logs to debug" do
203
+ cmd
204
+
205
+ logged_output.string.must_match(/DEBUG -- : Transfer complete$/)
206
+ end
55
207
 
56
- before { @klog = Kitchen.logger }
57
- after { Kitchen.logger = @klog }
208
+ it "raises an ActionFailed on transfer when TransportFailed is raised" do
209
+ connection.stubs(:upload).
210
+ raises(Kitchen::Transport::TransportFailed.new("dang"))
58
211
 
59
- it "returns the instance's logger" do
60
- provisioner.send(:logger).must_equal logger
212
+ proc { cmd }.must_raise Kitchen::ActionFailed
61
213
  end
62
214
 
63
- it "returns the default logger if instance's logger is not set" do
64
- provisioner = Kitchen::Provisioner::Base.new(config)
65
- Kitchen.logger = "yep"
215
+ it "raises an ActionFailed on execute when TransportFailed is raised" do
216
+ connection.stubs(:execute).
217
+ raises(Kitchen::Transport::TransportFailed.new("dang"))
66
218
 
67
- provisioner.send(:logger).must_equal Kitchen.logger
219
+ proc { cmd }.must_raise Kitchen::ActionFailed
68
220
  end
69
221
  end
70
222
 
@@ -25,17 +25,20 @@ describe Kitchen::Provisioner::ChefBase do
25
25
 
26
26
  let(:logged_output) { StringIO.new }
27
27
  let(:logger) { Logger.new(logged_output) }
28
+ let(:platform) { stub(:os_type => nil) }
29
+ let(:suite) { stub(:name => "fries") }
28
30
 
29
31
  let(:config) do
30
32
  { :test_base_path => "/basist", :kitchen_root => "/rooty" }
31
33
  end
32
34
 
33
- let(:suite) do
34
- stub(:name => "fries")
35
- end
36
-
37
35
  let(:instance) do
38
- stub(:name => "coolbeans", :logger => logger, :suite => suite)
36
+ stub(
37
+ :name => "coolbeans",
38
+ :logger => logger,
39
+ :suite => suite,
40
+ :platform => platform
41
+ )
39
42
  end
40
43
 
41
44
  let(:provisioner) do
@@ -48,17 +51,127 @@ describe Kitchen::Provisioner::ChefBase do
48
51
 
49
52
  describe "configuration" do
50
53
 
51
- it ":require_chef_omnibus defaults to true" do
52
- provisioner[:require_chef_omnibus].must_equal true
54
+ describe "for unix operating systems" do
55
+
56
+ before { platform.stubs(:os_type).returns("unix") }
57
+
58
+ it ":chef_omnibus_root has a default" do
59
+ provisioner[:chef_omnibus_root].must_equal "/opt/chef"
60
+ end
61
+
62
+ it ":chef_omnibus_url has a default" do
63
+ provisioner[:chef_omnibus_url].
64
+ must_equal "https://www.chef.io/chef/install.sh"
65
+ end
66
+
67
+ it ":chef_metadata_url defaults to nil" do
68
+ provisioner[:chef_metadata_url].must_equal(nil)
69
+ end
53
70
  end
54
71
 
55
- it ":chef_omnibus_url has a default" do
56
- provisioner[:chef_omnibus_url].
57
- must_equal "https://www.chef.io/chef/install.sh"
72
+ describe "for windows operating systems" do
73
+
74
+ before { platform.stubs(:os_type).returns("windows") }
75
+
76
+ it ":chef_omnibus_root has a default" do
77
+ provisioner[:chef_omnibus_root].
78
+ must_equal "$env:systemdrive\\opscode\\chef"
79
+ end
80
+
81
+ it ":chef_omnibus_url has a default" do
82
+ provisioner[:chef_omnibus_url].
83
+ must_equal "https://www.chef.io/chef/install.sh"
84
+ end
85
+
86
+ describe ":chef_metadata_url" do
87
+
88
+ let(:base_url) { "https://www.chef.io/chef/metadata" }
89
+
90
+ it "uses :chef_omnibus_url as url base if it ends in install.sh" do
91
+ config[:chef_omnibus_url] = "https://woot/install.sh"
92
+
93
+ provisioner[:chef_metadata_url].must_equal(
94
+ "https://woot/metadata?p=windows&m=x86_64&pv=2008r2&v=latest"
95
+ )
96
+ end
97
+
98
+ it "ignores :chef_omnibus_url if it doesn't end in install.sh" do
99
+ config[:chef_omnibus_url] = "https://woot/other"
100
+
101
+ provisioner[:chef_metadata_url].
102
+ must_equal "#{base_url}?p=windows&m=x86_64&pv=2008r2&v=latest"
103
+ end
104
+
105
+ it "defaults to latest package with :require_chef_omnibus = true" do
106
+ config[:require_chef_omnibus] = true
107
+
108
+ provisioner[:chef_metadata_url].
109
+ must_equal "#{base_url}?p=windows&m=x86_64&pv=2008r2&v=latest"
110
+ end
111
+
112
+ it "defaults to latest package with :require_chef_omnibus = latest" do
113
+ config[:require_chef_omnibus] = "latest"
114
+
115
+ provisioner[:chef_metadata_url].
116
+ must_equal "#{base_url}?p=windows&m=x86_64&pv=2008r2&v=latest"
117
+ end
118
+
119
+ it "defaults to a specific package from :require_chef_omnibus" do
120
+ config[:require_chef_omnibus] = "11.12.13"
121
+
122
+ provisioner[:chef_metadata_url].
123
+ must_equal "#{base_url}?p=windows&m=x86_64&pv=2008r2&v=11.12.13"
124
+ end
125
+
126
+ it "defaults to a maj/min version package from :require_chef_omnibus" do
127
+ config[:require_chef_omnibus] = 12.1
128
+
129
+ provisioner[:chef_metadata_url].
130
+ must_equal "#{base_url}?p=windows&m=x86_64&pv=2008r2&v=12.1"
131
+ end
132
+
133
+ it "defaults to a major package version from :require_chef_omnibus" do
134
+ config[:require_chef_omnibus] = "16"
135
+
136
+ provisioner[:chef_metadata_url].
137
+ must_equal "#{base_url}?p=windows&m=x86_64&pv=2008r2&v=16"
138
+ end
139
+
140
+ it "defaults to a prerelease package from :require_chef_omnibus" do
141
+ config[:require_chef_omnibus] = "11.6.0.RC.1"
142
+
143
+ provisioner[:chef_metadata_url].
144
+ must_equal "#{base_url}?p=windows&m=x86_64&pv=2008r2&v=11.6.0.rc.1"
145
+ end
146
+
147
+ it "defaults to a chefdk package from :chef_omnibus_install_options" do
148
+ config[:require_chef_omnibus] = true
149
+ config[:chef_omnibus_install_options] = "-P chefdk"
150
+
151
+ provisioner[:chef_metadata_url].
152
+ must_equal "#{base_url}-chefdk?p=windows&m=x86_64&pv=2008r2&v=latest"
153
+ end
154
+
155
+ it "defaults to a specfic chefdk from :chef_omnibus_install_options" do
156
+ config[:require_chef_omnibus] = "0.3.6"
157
+ config[:chef_omnibus_install_options] = "-a other -P chefdk -B okay"
158
+
159
+ provisioner[:chef_metadata_url].
160
+ must_equal "#{base_url}-chefdk?p=windows&m=x86_64&pv=2008r2&v=0.3.6"
161
+ end
162
+
163
+ it "defaults to a maj/min chefdk from :chef_omnibus_install_options" do
164
+ config[:require_chef_omnibus] = "0.3"
165
+ config[:chef_omnibus_install_options] = "-P chefdk -B okay"
166
+
167
+ provisioner[:chef_metadata_url].
168
+ must_equal "#{base_url}-chefdk?p=windows&m=x86_64&pv=2008r2&v=0.3"
169
+ end
170
+ end
58
171
  end
59
172
 
60
- it ":chef_omnibus_root has a default" do
61
- provisioner[:chef_omnibus_root].must_equal "/opt/chef"
173
+ it ":require_chef_omnibus defaults to true" do
174
+ provisioner[:require_chef_omnibus].must_equal true
62
175
  end
63
176
 
64
177
  it ":chef_omnibus_install_options defaults to nil" do
@@ -114,136 +227,373 @@ describe Kitchen::Provisioner::ChefBase do
114
227
 
115
228
  describe "#install_command" do
116
229
 
117
- it "returns nil if :require_chef_omnibus is falsey" do
118
- config[:require_chef_omnibus] = false
230
+ let(:cmd) { provisioner.install_command }
119
231
 
120
- provisioner.install_command.must_equal nil
121
- end
232
+ describe "for bourne shells" do
122
233
 
123
- it "uses bourne shell (sh)" do
124
- provisioner.install_command.must_match(/\Ash -c '$/)
125
- end
234
+ before { platform.stubs(:shell_type).returns("bourne") }
126
235
 
127
- it "ends with a single quote" do
128
- provisioner.install_command.must_match(/'\Z/)
129
- end
236
+ it "returns nil if :require_chef_omnibus is falsey" do
237
+ config[:require_chef_omnibus] = false
130
238
 
131
- it "installs chef using :chef_omnibus_url, if necessary" do
132
- config[:chef_omnibus_url] = "FROM_HERE"
239
+ cmd.must_equal nil
240
+ end
133
241
 
134
- provisioner.install_command.must_match regexify(
135
- "do_download FROM_HERE /tmp/install.sh")
136
- end
242
+ it "uses bourne shell (sh)" do
243
+ cmd.must_match(/\Ash -c '$/)
244
+ end
137
245
 
138
- it "will install a specific version of chef, if necessary" do
139
- config[:require_chef_omnibus] = "1.2.3"
246
+ it "ends with a single quote" do
247
+ cmd.must_match(/'\Z/)
248
+ end
140
249
 
141
- provisioner.install_command.must_match regexify(
142
- "sudo -E sh /tmp/install.sh -v 1.2.3")
143
- provisioner.install_command.must_match regexify(
144
- "Installing Chef Omnibus (1.2.3)", :partial_line)
145
- end
250
+ it "exports http_proxy & HTTP_PROXY when :http_proxy is set" do
251
+ config[:http_proxy] = "http://proxy"
146
252
 
147
- it "will install a major/minor version of chef, if necessary" do
148
- config[:require_chef_omnibus] = "11.10"
253
+ cmd.lines.to_a[1..2].must_equal([
254
+ %{http_proxy="http://proxy"; export http_proxy\n},
255
+ %{HTTP_PROXY="http://proxy"; export HTTP_PROXY\n}
256
+ ])
257
+ end
149
258
 
150
- provisioner.install_command.must_match regexify(
151
- "sudo -E sh /tmp/install.sh -v 11.10")
152
- provisioner.install_command.must_match regexify(
153
- "Installing Chef Omnibus (11.10)", :partial_line)
154
- end
259
+ it "exports https_proxy & HTTPS_PROXY when :https_proxy is set" do
260
+ config[:https_proxy] = "https://proxy"
155
261
 
156
- it "will install a major version of chef, if necessary" do
157
- config[:require_chef_omnibus] = "12"
262
+ cmd.lines.to_a[1..2].must_equal([
263
+ %{https_proxy="https://proxy"; export https_proxy\n},
264
+ %{HTTPS_PROXY="https://proxy"; export HTTPS_PROXY\n}
265
+ ])
266
+ end
158
267
 
159
- provisioner.install_command.must_match regexify(
160
- "sudo -E sh /tmp/install.sh -v 12")
161
- provisioner.install_command.must_match regexify(
162
- "Installing Chef Omnibus (12)", :partial_line)
163
- end
268
+ it "exports all http proxy variables when both are set" do
269
+ config[:http_proxy] = "http://proxy"
270
+ config[:https_proxy] = "https://proxy"
164
271
 
165
- it "will install a downcaased version string of chef, if necessary" do
166
- config[:require_chef_omnibus] = "10.1.0.RC.1"
272
+ cmd.lines.to_a[1..4].must_equal([
273
+ %{http_proxy="http://proxy"; export http_proxy\n},
274
+ %{HTTP_PROXY="http://proxy"; export HTTP_PROXY\n},
275
+ %{https_proxy="https://proxy"; export https_proxy\n},
276
+ %{HTTPS_PROXY="https://proxy"; export HTTPS_PROXY\n}
277
+ ])
278
+ end
167
279
 
168
- provisioner.install_command.must_match regexify(
169
- "sudo -E sh /tmp/install.sh -v 10.1.0.rc.1")
170
- provisioner.install_command.must_match regexify(
171
- "Installing Chef Omnibus (10.1.0.rc.1)", :partial_line)
172
- end
280
+ it "installs chef using :chef_omnibus_url, if necessary" do
281
+ config[:chef_omnibus_url] = "FROM_HERE"
173
282
 
174
- it "will install the latest of chef, if necessary" do
175
- config[:require_chef_omnibus] = "latest"
283
+ cmd.must_match regexify(%{chef_omnibus_url="FROM_HERE"})
284
+ end
176
285
 
177
- provisioner.install_command.must_match regexify(
178
- "sudo -E sh /tmp/install.sh ")
179
- provisioner.install_command.must_match regexify(
180
- "Installing Chef Omnibus (always install latest version)",
181
- :partial_line
182
- )
183
- end
286
+ it "will install a specific version of chef, if necessary" do
287
+ config[:require_chef_omnibus] = "1.2.3"
184
288
 
185
- it "will install a of chef, unless it exists" do
186
- config[:require_chef_omnibus] = true
289
+ cmd.must_match regexify(%{install_flags="-v 1.2.3"})
290
+ cmd.must_match regexify(%{pretty_version="1.2.3"})
291
+ cmd.must_match regexify(%{version="1.2.3"})
292
+ end
187
293
 
188
- provisioner.install_command.must_match regexify(
189
- "sudo -E sh /tmp/install.sh ")
190
- provisioner.install_command.must_match regexify(
191
- "Installing Chef Omnibus (install only if missing)", :partial_line)
192
- end
294
+ it "will install a major/minor version of chef, if necessary" do
295
+ config[:require_chef_omnibus] = "11.10"
296
+
297
+ cmd.must_match regexify(%{install_flags="-v 11.10"})
298
+ cmd.must_match regexify(%{pretty_version="11.10"})
299
+ cmd.must_match regexify(%{version="11.10"})
300
+ end
301
+
302
+ it "will install a major version of chef, if necessary" do
303
+ config[:require_chef_omnibus] = "12"
304
+
305
+ cmd.must_match regexify(%{install_flags="-v 12"})
306
+ cmd.must_match regexify(%{pretty_version="12"})
307
+ cmd.must_match regexify(%{version="12"})
308
+ end
309
+
310
+ it "will install a downcaased version string of chef, if necessary" do
311
+ config[:require_chef_omnibus] = "10.1.0.RC.1"
312
+
313
+ cmd.must_match regexify(%{install_flags="-v 10.1.0.rc.1"})
314
+ cmd.must_match regexify(%{pretty_version="10.1.0.rc.1"})
315
+ cmd.must_match regexify(%{version="10.1.0.rc.1"})
316
+ end
317
+
318
+ it "will install the latest of chef, if necessary" do
319
+ config[:require_chef_omnibus] = "latest"
320
+
321
+ cmd.must_match regexify(%{install_flags=""})
322
+ cmd.must_match regexify(%{pretty_version="always install latest version"})
323
+ cmd.must_match regexify(%{version="latest"})
324
+ end
325
+
326
+ it "will install a of chef, unless it exists" do
327
+ config[:require_chef_omnibus] = true
328
+
329
+ cmd.must_match regexify(%{install_flags=""})
330
+ cmd.must_match regexify(%{pretty_version="install only if missing"})
331
+ cmd.must_match regexify(%{version="true"})
332
+ end
333
+
334
+ it "will pass install options, when given" do
335
+ config[:chef_omnibus_install_options] = "-P chefdk"
336
+
337
+ cmd.must_match regexify(%{install_flags="-P chefdk"})
338
+ cmd.must_match regexify(%{pretty_version="install only if missing"})
339
+ cmd.must_match regexify(%{version="true"})
340
+ end
341
+
342
+ it "will pass install options and version info, when given" do
343
+ config[:require_chef_omnibus] = "11"
344
+ config[:chef_omnibus_install_options] = "-d /tmp/place"
345
+
346
+ cmd.must_match regexify(%{install_flags="-v 11 -d /tmp/place"})
347
+ cmd.must_match regexify(%{pretty_version="11"})
348
+ cmd.must_match regexify(%{version="11"})
349
+ end
350
+
351
+ it "prepends sudo for sh commands when :sudo is set" do
352
+ config[:sudo] = true
353
+
354
+ cmd.must_match regexify(%{sudo_sh="sudo -E sh"})
355
+ end
193
356
 
194
- it "will pass install options, when given" do
195
- config[:chef_omnibus_install_options] = "-P chefdk"
357
+ it "does not sudo for sh commands when :sudo is falsey" do
358
+ config[:sudo] = false
196
359
 
197
- provisioner.install_command.must_match regexify(
198
- "sudo -E sh /tmp/install.sh -P chefdk")
199
- provisioner.install_command.must_match regexify(
200
- "Installing Chef Omnibus (install only if missing)", :partial_line)
360
+ cmd.must_match regexify(%{sudo_sh="sh"})
361
+ end
201
362
  end
202
363
 
203
- it "will pass install options and version info, when given" do
204
- config[:require_chef_omnibus] = "11"
205
- config[:chef_omnibus_install_options] = "-d /tmp/place"
364
+ describe "for powershell shells on windows os types" do
365
+
366
+ before do
367
+ platform.stubs(:shell_type).returns("powershell")
368
+ platform.stubs(:os_type).returns("windows")
369
+ end
370
+
371
+ it "exports http_proxy & HTTP_PROXY when :http_proxy is set" do
372
+ config[:http_proxy] = "http://proxy"
373
+
374
+ cmd.lines.to_a[0..1].must_equal([
375
+ %{$env:http_proxy = "http://proxy"\n},
376
+ %{$env:HTTP_PROXY = "http://proxy"\n}
377
+ ])
378
+ end
379
+
380
+ it "exports https_proxy & HTTPS_PROXY when :https_proxy is set" do
381
+ config[:https_proxy] = "https://proxy"
382
+
383
+ cmd.lines.to_a[0..1].must_equal([
384
+ %{$env:https_proxy = "https://proxy"\n},
385
+ %{$env:HTTPS_PROXY = "https://proxy"\n}
386
+ ])
387
+ end
388
+
389
+ it "exports all http proxy variables when both are set" do
390
+ config[:http_proxy] = "http://proxy"
391
+ config[:https_proxy] = "https://proxy"
392
+
393
+ cmd.lines.to_a[0..3].must_equal([
394
+ %{$env:http_proxy = "http://proxy"\n},
395
+ %{$env:HTTP_PROXY = "http://proxy"\n},
396
+ %{$env:https_proxy = "https://proxy"\n},
397
+ %{$env:HTTPS_PROXY = "https://proxy"\n}
398
+ ])
399
+ end
400
+
401
+ it "returns nil if :require_chef_omnibus is falsey" do
402
+ config[:require_chef_omnibus] = false
403
+
404
+ cmd.must_equal nil
405
+ end
406
+
407
+ it "installs chef using :chef_metadata_url, if necessary" do
408
+ config[:chef_metadata_url] = "FROM_HERE"
409
+
410
+ cmd.must_match regexify(%{$chef_metadata_url = "FROM_HERE"})
411
+ end
412
+
413
+ it "sets an root path from :chef_omnibus_root" do
414
+ config[:chef_omnibus_root] = "\\a\\b"
415
+
416
+ cmd.must_match regexify(%{$chef_omnibus_root = "\\a\\b"})
417
+ end
418
+
419
+ it "sets a path for the msi pacakge based on version" do
420
+ config[:require_chef_omnibus] = "1.2.3"
421
+
422
+ cmd.must_match regexify(%{$msi = "$env:TEMP\\chef-1.2.3.msi"})
423
+ end
424
+
425
+ it "will install a specific version of chef, if necessary" do
426
+ config[:require_chef_omnibus] = "1.2.3"
427
+
428
+ cmd.must_match regexify(%{$pretty_version = "1.2.3"})
429
+ cmd.must_match regexify(%{$version = "1.2.3"})
430
+ end
431
+
432
+ it "will install a major/minor version of chef, if necessary" do
433
+ config[:require_chef_omnibus] = "11.10"
434
+
435
+ cmd.must_match regexify(%{$pretty_version = "11.10"})
436
+ cmd.must_match regexify(%{$version = "11.10"})
437
+ end
438
+
439
+ it "will install a major version of chef, if necessary" do
440
+ config[:require_chef_omnibus] = "12"
441
+
442
+ cmd.must_match regexify(%{$pretty_version = "12"})
443
+ cmd.must_match regexify(%{$version = "12"})
444
+ end
445
+
446
+ it "will install a downcaased version string of chef, if necessary" do
447
+ config[:require_chef_omnibus] = "10.1.0.RC.1"
448
+
449
+ cmd.must_match regexify(%{$pretty_version = "10.1.0.rc.1"})
450
+ cmd.must_match regexify(%{$version = "10.1.0.rc.1"})
451
+ end
452
+
453
+ it "will install the latest of chef, if necessary" do
454
+ config[:require_chef_omnibus] = "latest"
206
455
 
207
- provisioner.install_command.must_match regexify(
208
- "sudo -E sh /tmp/install.sh -v 11 -d /tmp/place")
456
+ cmd.must_match regexify(%{$pretty_version = "always install latest version"})
457
+ cmd.must_match regexify(%{$version = "latest"})
458
+ end
459
+
460
+ it "will install a of chef, unless it exists" do
461
+ config[:require_chef_omnibus] = true
462
+
463
+ cmd.must_match regexify(%{$pretty_version = "install only if missing"})
464
+ cmd.must_match regexify(%{$version = "true"})
465
+ end
209
466
  end
210
467
  end
211
468
 
212
469
  describe "#init_command" do
213
470
 
214
- it "uses bourne shell" do
215
- provisioner.init_command.must_match(/\Ash -c '$/)
216
- provisioner.init_command.must_match(/'\Z/)
217
- end
471
+ let(:cmd) { provisioner.init_command }
218
472
 
219
- it "uses sudo for rm when configured" do
220
- config[:sudo] = true
473
+ describe "for bourne shells" do
221
474
 
222
- provisioner.init_command.
223
- must_match regexify("sudo -E rm -rf ", :partial_line)
224
- end
475
+ before { platform.stubs(:shell_type).returns("bourne") }
225
476
 
226
- it "does not use sudo for rm when configured" do
227
- config[:sudo] = false
477
+ it "uses bourne shell" do
478
+ cmd.must_match(/\Ash -c '$/)
479
+ cmd.must_match(/'\Z/)
480
+ end
228
481
 
229
- provisioner.init_command.
230
- must_match regexify("rm -rf ", :partial_line)
231
- provisioner.init_command.
232
- wont_match regexify("sudo -E rm -rf ", :partial_line)
233
- end
482
+ it "ends with a single quote" do
483
+ cmd.must_match(/'\Z/)
484
+ end
485
+
486
+ it "exports http_proxy & HTTP_PROXY when :http_proxy is set" do
487
+ config[:http_proxy] = "http://proxy"
488
+
489
+ cmd.lines.to_a[1..2].must_equal([
490
+ %{http_proxy="http://proxy"; export http_proxy\n},
491
+ %{HTTP_PROXY="http://proxy"; export HTTP_PROXY\n}
492
+ ])
493
+ end
494
+
495
+ it "exports https_proxy & HTTPS_PROXY when :https_proxy is set" do
496
+ config[:https_proxy] = "https://proxy"
497
+
498
+ cmd.lines.to_a[1..2].must_equal([
499
+ %{https_proxy="https://proxy"; export https_proxy\n},
500
+ %{HTTPS_PROXY="https://proxy"; export HTTPS_PROXY\n}
501
+ ])
502
+ end
503
+
504
+ it "exports all http proxy variables when both are set" do
505
+ config[:http_proxy] = "http://proxy"
506
+ config[:https_proxy] = "https://proxy"
507
+
508
+ cmd.lines.to_a[1..4].must_equal([
509
+ %{http_proxy="http://proxy"; export http_proxy\n},
510
+ %{HTTP_PROXY="http://proxy"; export HTTP_PROXY\n},
511
+ %{https_proxy="https://proxy"; export https_proxy\n},
512
+ %{HTTPS_PROXY="https://proxy"; export HTTPS_PROXY\n}
513
+ ])
514
+ end
515
+
516
+ it "prepends sudo for rm when :sudo is set" do
517
+ config[:sudo] = true
518
+
519
+ cmd.must_match regexify(%{sudo_rm="sudo -E rm"})
520
+ end
521
+
522
+ it "does not sudo for sh commands when :sudo is falsey" do
523
+ config[:sudo] = false
234
524
 
235
- %w[cookbooks data data_bags environments roles clients].each do |dir|
236
- it "removes the #{dir} directory" do
525
+ cmd.must_match regexify(%{sudo_rm="rm"})
526
+ end
527
+
528
+ it "sets chef component dirs for deletion" do
237
529
  config[:root_path] = "/route"
530
+ dirs = %W[
531
+ /route/clients /route/cookbooks /route/data /route/data_bags
532
+ /route/environments /route/roles
533
+ ].join(" ")
534
+
535
+ cmd.must_match regexify(%{dirs="#{dirs}"})
536
+ end
537
+
538
+ it "sets the root_path from :root_path" do
539
+ config[:root_path] = "RIGHT_HERE"
238
540
 
239
- provisioner.init_command.must_match %r{rm -rf\b.*\s+/route/#{dir}\s+}
541
+ cmd.must_match regexify(%{root_path="RIGHT_HERE"})
240
542
  end
241
543
  end
242
544
 
243
- it "creates :root_path directory" do
244
- config[:root_path] = "/root/path"
545
+ describe "for powershell shells on windows os types" do
546
+
547
+ before do
548
+ platform.stubs(:shell_type).returns("powershell")
549
+ platform.stubs(:os_type).returns("windows")
550
+ end
551
+
552
+ it "exports http_proxy & HTTP_PROXY when :http_proxy is set" do
553
+ config[:http_proxy] = "http://proxy"
554
+
555
+ cmd.lines.to_a[0..1].must_equal([
556
+ %{$env:http_proxy = "http://proxy"\n},
557
+ %{$env:HTTP_PROXY = "http://proxy"\n}
558
+ ])
559
+ end
560
+
561
+ it "exports https_proxy & HTTPS_PROXY when :https_proxy is set" do
562
+ config[:https_proxy] = "https://proxy"
563
+
564
+ cmd.lines.to_a[0..1].must_equal([
565
+ %{$env:https_proxy = "https://proxy"\n},
566
+ %{$env:HTTPS_PROXY = "https://proxy"\n}
567
+ ])
568
+ end
569
+
570
+ it "exports all http proxy variables when both are set" do
571
+ config[:http_proxy] = "http://proxy"
572
+ config[:https_proxy] = "https://proxy"
573
+
574
+ cmd.lines.to_a[0..3].must_equal([
575
+ %{$env:http_proxy = "http://proxy"\n},
576
+ %{$env:HTTP_PROXY = "http://proxy"\n},
577
+ %{$env:https_proxy = "https://proxy"\n},
578
+ %{$env:HTTPS_PROXY = "https://proxy"\n}
579
+ ])
580
+ end
245
581
 
246
- provisioner.init_command.must_match regexify("mkdir -p /root/path")
582
+ it "sets chef component dirs for deletion" do
583
+ config[:root_path] = "\\route"
584
+ dirs = %W[
585
+ "\\route\\clients" "\\route\\cookbooks" "\\route\\data"
586
+ "\\route\\data_bags" "\\route\\environments" "\\route\\roles"
587
+ ].join(", ")
588
+
589
+ cmd.must_match regexify(%{$dirs = @(#{dirs})})
590
+ end
591
+
592
+ it "sets the root_path from :root_path" do
593
+ config[:root_path] = "RIGHT_HERE"
594
+
595
+ cmd.must_match regexify(%{$root_path = "RIGHT_HERE"})
596
+ end
247
597
  end
248
598
  end
249
599