chef-apply 0.4.6 → 0.4.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -7
  3. data/chef-apply.gemspec +3 -3
  4. data/lib/chef_apply/version.rb +1 -1
  5. metadata +3 -38
  6. data/README.md +0 -62
  7. data/spec/fixtures/custom_config.toml +0 -2
  8. data/spec/integration/chef-run_spec.rb +0 -41
  9. data/spec/integration/fixtures/chef_help.out +0 -70
  10. data/spec/integration/fixtures/chef_version.out +0 -1
  11. data/spec/integration/spec_helper.rb +0 -55
  12. data/spec/spec_helper.rb +0 -154
  13. data/spec/support/matchers/output_to_terminal.rb +0 -36
  14. data/spec/unit/action/base_spec.rb +0 -60
  15. data/spec/unit/action/converge_target/ccr_failure_mapper_spec.rb +0 -106
  16. data/spec/unit/action/converge_target_spec.rb +0 -400
  17. data/spec/unit/action/generate_local_policy_spec.rb +0 -114
  18. data/spec/unit/action/generate_temp_cookbook/recipe_lookup_spec.rb +0 -122
  19. data/spec/unit/action/generate_temp_cookbook/temp_cookbook_spec.rb +0 -198
  20. data/spec/unit/action/generate_temp_cookbook_spec.rb +0 -73
  21. data/spec/unit/action/install_chef/minimum_chef_version_spec.rb +0 -90
  22. data/spec/unit/action/install_chef_spec.rb +0 -164
  23. data/spec/unit/cli/options_spec.rb +0 -75
  24. data/spec/unit/cli/validation_spec.rb +0 -81
  25. data/spec/unit/cli_spec.rb +0 -475
  26. data/spec/unit/config_spec.rb +0 -70
  27. data/spec/unit/file_fetcher_spec.rb +0 -40
  28. data/spec/unit/fixtures/multi-error.out +0 -2
  29. data/spec/unit/log_spec.rb +0 -37
  30. data/spec/unit/startup_spec.rb +0 -323
  31. data/spec/unit/target_host/linux_spec.rb +0 -57
  32. data/spec/unit/target_host/windows_spec.rb +0 -43
  33. data/spec/unit/target_host_spec.rb +0 -297
  34. data/spec/unit/target_resolver_spec.rb +0 -380
  35. data/spec/unit/telemeter/sender_spec.rb +0 -140
  36. data/spec/unit/telemeter_spec.rb +0 -191
  37. data/spec/unit/text/error_translation_spec.rb +0 -109
  38. data/spec/unit/ui/error_printer_spec.rb +0 -196
  39. data/spec/unit/ui/terminal_spec.rb +0 -119
  40. data/spec/unit/version_spec.rb +0 -31
@@ -1,36 +0,0 @@
1
- require "rspec/matchers/built_in/output"
2
- require "chef_apply/ui/terminal"
3
-
4
- # Custom behavior for the builtin output matcher
5
- # to allow it to handle to_terminal, which integrates
6
- # with our UI::Terminal interface.
7
- module RSpec
8
- module Matchers
9
- module BuiltIn
10
- class Output < BaseMatcher
11
- # @api private
12
- # Provides the implementation for `output`.
13
- # Not intended to be instantiated directly.
14
- def to_terminal
15
- @stream_capturer = CaptureTerminal
16
- self
17
- end
18
- module CaptureTerminal
19
- def self.name
20
- "terminal"
21
- end
22
-
23
- def self.capture(block)
24
- captured_stream = StringIO.new
25
- original_stream = ::ChefApply::UI::Terminal.location
26
- ::ChefApply::UI::Terminal.location = captured_stream
27
- block.call
28
- captured_stream.string
29
- ensure
30
- ::ChefApply::UI::Terminal.location = original_stream
31
- end
32
- end
33
- end
34
- end
35
- end
36
- end
@@ -1,60 +0,0 @@
1
- #
2
- # Copyright:: Copyright (c) 2018 Chef Software Inc.
3
- # License:: Apache License, Version 2.0
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
- #
17
-
18
- require "spec_helper"
19
- require "chef_apply/action/base"
20
- require "chef_apply/telemeter"
21
- require "chef_apply/target_host"
22
-
23
- RSpec.describe ChefApply::Action::Base do
24
- let(:family) { "windows" }
25
- let(:target_host) do
26
- p = double("platform", family: family)
27
- instance_double(ChefApply::TargetHost, platform: p)
28
- end
29
- let(:opts) do
30
- { target_host: target_host,
31
- other: "something-else" }
32
- end
33
- subject(:action) { ChefApply::Action::Base.new(opts) }
34
-
35
- context "#initialize" do
36
- it "properly initializes exposed attr readers" do
37
- expect(action.target_host).to eq target_host
38
- expect(action.config).to eq({ other: "something-else" })
39
- end
40
- end
41
-
42
- context "#run" do
43
- it "runs the underlying action, capturing timing via telemetry" do
44
- expect(ChefApply::Telemeter).to receive(:timed_action_capture).with(subject).and_yield
45
- expect(action).to receive(:perform_action)
46
- action.run
47
- end
48
-
49
- it "invokes an action handler when actions occur and a handler is provided" do
50
- @run_action = nil
51
- @args = nil
52
- expect(ChefApply::Telemeter).to receive(:timed_action_capture).with(subject).and_yield
53
- expect(action).to receive(:perform_action) { action.notify(:test_success, "some arg", "some other arg") }
54
- action.run { |action, args| @run_action = action; @args = args }
55
- expect(@run_action).to eq :test_success
56
- expect(@args).to eq ["some arg", "some other arg"]
57
- end
58
- end
59
-
60
- end
@@ -1,106 +0,0 @@
1
- #
2
- # Copyright:: Copyright (c) 2018 Chef Software Inc.
3
- # License:: Apache License, Version 2.0
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
- #
17
-
18
- require "spec_helper"
19
- require "chef_apply/action/converge_target/ccr_failure_mapper"
20
-
21
- RSpec.describe ChefApply::Action::ConvergeTarget::CCRFailureMapper do
22
- let(:cause_line) { nil }
23
- let(:resource) { "apt_package" }
24
- let(:params) do
25
- { resource: resource, resource_name: "a-test-thing",
26
- stderr: "an error", stdout: "other output" }
27
- end
28
- subject { ChefApply::Action::ConvergeTarget::CCRFailureMapper.new(cause_line, params) }
29
-
30
- describe "#exception_args_from_cause" do
31
- context "when resource properties have valid names but invalid values" do
32
- context "and the property is 'action'" do
33
- let(:cause_line) { "Chef::Exceptions::ValidationFailed: Option action must be equal to one of: nothing, install, upgrade, remove, purge, reconfig, lock, unlock! You passed :marve." }
34
- it "returns a correct CHEFCCR003" do
35
- expect(subject.exception_args_from_cause).to eq(
36
- ["CHEFCCR003", "marve",
37
- "nothing, install, upgrade, remove, purge, reconfig, lock, unlock"]
38
- )
39
- end
40
- end
41
-
42
- context "and the property is something else" do
43
- context "and details are available" do
44
- let(:cause_line) { "Chef::Exceptions::ValidationFailed: Option force must be a kind of [TrueClass, FalseClass]! You passed \"purle\"." }
45
- it "returns a correct CHEFCCR004 when details are available" do
46
- expect(subject.exception_args_from_cause).to eq(
47
- ["CHEFCCR004",
48
- "Option force must be a kind of [TrueClass, FalseClass]! You passed \"purle\"."]
49
- )
50
- end
51
- end
52
- context "And less detail is available" do
53
- let(:cause_line) { "Chef::Exceptions::User: linux_user[marc] ((chef-client cookbook)::(chef-client recipe) line 1) had an error: Chef::Exceptions::User: Couldn't lookup integer GID for group name blah" }
54
- it "returns a correct CHEFCCR002" do
55
- expect(subject.exception_args_from_cause).to eq(
56
- ["CHEFCCR002", "Couldn't lookup integer GID for group name blah"]
57
- )
58
- end
59
- end
60
- end
61
- end
62
-
63
- context "when resource is not a known Chef resource" do
64
- let(:cause_line) { "NoMethodError: undefined method `useraaa' for cookbook: (chef-client cookbook), recipe: (chef-client recipe) :Chef::Recipe" }
65
- let(:resource) { "useraaa" }
66
- it "returns a correct CHEFCCR005" do
67
- expect(subject.exception_args_from_cause).to eq(["CHEFCCR005", resource])
68
- end
69
- end
70
-
71
- context "when a resource property does not exist for the given resource" do
72
- let(:cause_line) { "NoMethodError: undefined method `badresourceprop' for Chef::Resource::User::LinuxUser" }
73
- it "returns a correct CHEFCCR006 " do
74
- expect(subject.exception_args_from_cause).to eq(
75
- ["CHEFCCR006", "badresourceprop", "Chef::Resource::User::LinuxUser"]
76
- )
77
- end
78
- end
79
- end
80
-
81
- describe "#raise_mapped_exception!" do
82
- context "when no cause is provided" do
83
- let(:cause_line) { nil }
84
- it "raises a RemoteChefRunFailedToResolveError" do
85
- expect { subject.raise_mapped_exception! }.to raise_error(ChefApply::Action::ConvergeTarget::CCRFailureMapper::RemoteChefRunFailedToResolveError)
86
-
87
- end
88
- end
89
-
90
- context "when a cause is provided" do
91
- context "but can't resolve it" do
92
- let(:cause_line) { "unparseable mess" }
93
- it "raises a RemoteChefClientRunFailedUnknownReason" do
94
- expect { subject.raise_mapped_exception! }.to raise_error(ChefApply::Action::ConvergeTarget::CCRFailureMapper::RemoteChefClientRunFailedUnknownReason)
95
- end
96
- end
97
-
98
- context "and can resolve the cause" do
99
- let(:cause_line) { "NoMethodError: undefined method `badresourceprop' for Chef::Resource::User::LinuxUser" }
100
- it "raises a RemoteChefClientRunFailed" do
101
- expect { subject.raise_mapped_exception! }.to raise_error(ChefApply::Action::ConvergeTarget::CCRFailureMapper::RemoteChefClientRunFailed)
102
- end
103
- end
104
- end
105
- end
106
- end
@@ -1,400 +0,0 @@
1
- #
2
- # Copyright:: Copyright (c) 2018 Chef Software Inc.
3
- # License:: Apache License, Version 2.0
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
- #
17
-
18
- require "spec_helper"
19
- require "chef_apply/target_host"
20
- require "chef_apply/action/converge_target"
21
- require "chef_apply/action/converge_target/ccr_failure_mapper"
22
-
23
- RSpec.describe ChefApply::Action::ConvergeTarget do
24
- let(:archive) { "archive.tgz" }
25
- let(:cache_path) { "/var/chef-workstation" }
26
- let(:platform_family) { "windows" }
27
- let(:base_os) { :windows }
28
- let(:target_host) do
29
- p = double("platform", family: platform_family)
30
- double(ChefApply::TargetHost,
31
- platform: p, base_os: base_os, ws_cache_path: cache_path)
32
- end
33
- let(:local_policy_path) { "/local/policy/path/archive.tgz" }
34
- let(:opts) { { target_host: target_host, local_policy_path: local_policy_path } }
35
- subject { ChefApply::Action::ConvergeTarget.new(opts) }
36
-
37
- before do
38
- allow(target_host).to receive(:normalize_path) { |arg| arg }
39
- end
40
- describe "#create_remote_policy" do
41
- let(:remote_archive) { File.join(cache_path, File.basename(archive)) }
42
-
43
- it "pushes it to the remote machine" do
44
- expect(target_host).to receive(:upload_file).with(local_policy_path, remote_archive)
45
- expect(subject.create_remote_policy(local_policy_path, cache_path)).to eq(remote_archive)
46
- end
47
-
48
- it "raises an error if the upload fails" do
49
- expect(target_host).to receive(:upload_file).with(local_policy_path, remote_archive).and_raise("foo")
50
- err = ChefApply::Action::ConvergeTarget::PolicyUploadFailed
51
- expect { subject.create_remote_policy(local_policy_path, cache_path) }.to raise_error(err)
52
- end
53
- end
54
-
55
- describe "#create_remote_config" do
56
-
57
- @closed = false # tempfile close indicator
58
- let(:remote_folder) { "/tmp/foo" }
59
- let(:remote_config_path) { "#{remote_folder}/workstation.rb" }
60
- # TODO - mock this, I think we're leaving things behind in /tmp in test runs.
61
- let!(:local_tempfile) { Tempfile.new }
62
-
63
- before do
64
- allow(Tempfile).to receive(:new).and_return(local_tempfile)
65
- end
66
-
67
- it "pushes it to the remote machine" do
68
- expect(target_host).to receive(:upload_file).with(local_tempfile.path, remote_config_path)
69
- expect(subject.create_remote_config(remote_folder)).to eq(remote_config_path)
70
- # ensure the tempfile is deleted locally
71
- expect(local_tempfile.closed?).to eq(true)
72
- end
73
-
74
- it "raises an error if the upload fails" do
75
- expect(target_host).to receive(:upload_file).with(local_tempfile.path, remote_config_path).and_raise("foo")
76
- err = ChefApply::Action::ConvergeTarget::ConfigUploadFailed
77
- expect { subject.create_remote_config(remote_folder) }.to raise_error(err)
78
- # ensure the tempfile is deleted locally
79
- expect(local_tempfile.closed?).to eq(true)
80
- end
81
-
82
- describe "when chef_license is configured" do
83
- before do
84
- ChefApply::Config.chef.chef_license = "accept-no-persist"
85
- end
86
-
87
- after do
88
- ChefApply::Config.reset
89
- end
90
-
91
- it "creates a config file with chef_license set and quoted" do
92
- expect(Tempfile).to receive(:new).and_return(local_tempfile)
93
- expect(local_tempfile).to receive(:write).with(<<~EOM
94
- local_mode true
95
- color false
96
- cache_path "#{cache_path}"
97
- chef_repo_path "#{cache_path}"
98
- require_relative "reporter"
99
- reporter = ChefApply::Reporter.new
100
- report_handlers << reporter
101
- exception_handlers << reporter
102
- chef_license "accept-no-persist"
103
- EOM
104
- )
105
- expect(target_host).to receive(:upload_file).with(local_tempfile.path, remote_config_path)
106
- expect(subject.create_remote_config(remote_folder)).to eq(remote_config_path)
107
- expect(local_tempfile.closed?).to eq(true)
108
- end
109
- end
110
-
111
- describe "when target_level is left default" do
112
- before do
113
- ChefApply::Config.reset
114
- end
115
- # TODO - this is a windows config, but we don't set windows?
116
- it "creates a config file without a specific log_level (leaving default for chef-client)" do
117
- expect(Tempfile).to receive(:new).and_return(local_tempfile)
118
- expect(local_tempfile).to receive(:write).with(<<~EOM
119
- local_mode true
120
- color false
121
- cache_path "#{cache_path}"
122
- chef_repo_path "#{cache_path}"
123
- require_relative "reporter"
124
- reporter = ChefApply::Reporter.new
125
- report_handlers << reporter
126
- exception_handlers << reporter
127
- EOM
128
- )
129
- expect(target_host).to receive(:upload_file).with(local_tempfile.path, remote_config_path)
130
- expect(subject.create_remote_config(remote_folder)).to eq(remote_config_path)
131
- expect(local_tempfile.closed?).to eq(true)
132
- end
133
- end
134
-
135
- describe "when target_level is set to a value" do
136
- before do
137
- ChefApply::Config.log.target_level = "info"
138
- end
139
-
140
- after do
141
- ChefApply::Config.reset
142
- end
143
-
144
- it "creates a config file with the log_level set to the right value" do
145
- expect(Tempfile).to receive(:new).and_return(local_tempfile)
146
- expect(local_tempfile).to receive(:write).with(<<~EOM
147
- local_mode true
148
- color false
149
- cache_path "#{cache_path}"
150
- chef_repo_path "#{cache_path}"
151
- require_relative "reporter"
152
- reporter = ChefApply::Reporter.new
153
- report_handlers << reporter
154
- exception_handlers << reporter
155
- log_level :info
156
- EOM
157
- )
158
- expect(target_host).to receive(:upload_file).with(local_tempfile.path, remote_config_path)
159
- expect(subject.create_remote_config(remote_folder)).to eq(remote_config_path)
160
- expect(local_tempfile.closed?).to eq(true)
161
- end
162
- end
163
-
164
- describe "when data_collector is set in config" do
165
- before do
166
- ChefApply::Config.data_collector.url = "dc.url"
167
- ChefApply::Config.data_collector.token = "dc.token"
168
- end
169
-
170
- after do
171
- ChefApply::Config.reset
172
- end
173
-
174
- it "creates a config file with data collector config values" do
175
- expect(Tempfile).to receive(:new).and_return(local_tempfile)
176
- expect(local_tempfile).to receive(:write).with(<<~EOM
177
- local_mode true
178
- color false
179
- cache_path "#{cache_path}"
180
- chef_repo_path "#{cache_path}"
181
- require_relative "reporter"
182
- reporter = ChefApply::Reporter.new
183
- report_handlers << reporter
184
- exception_handlers << reporter
185
- data_collector.server_url "dc.url"
186
- data_collector.token "dc.token"
187
- data_collector.mode :solo
188
- data_collector.organization "Chef Workstation"
189
- EOM
190
- )
191
- expect(target_host).to receive(:upload_file).with(local_tempfile.path, remote_config_path)
192
- expect(subject.create_remote_config(remote_folder)).to eq(remote_config_path)
193
- # ensure the tempfile is deleted locally
194
- expect(local_tempfile.closed?).to eq(true)
195
- end
196
- end
197
-
198
- describe "when data_collector is not set" do
199
- before do
200
- ChefApply::Config.data_collector.url = nil
201
- ChefApply::Config.data_collector.token = nil
202
- end
203
-
204
- it "creates a config file without data collector config values" do
205
- expect(Tempfile).to receive(:new).and_return(local_tempfile)
206
- expect(local_tempfile).to receive(:write).with(<<~EOM
207
- local_mode true
208
- color false
209
- cache_path "#{cache_path}"
210
- chef_repo_path "#{cache_path}"
211
- require_relative "reporter"
212
- reporter = ChefApply::Reporter.new
213
- report_handlers << reporter
214
- exception_handlers << reporter
215
- EOM
216
- )
217
- expect(target_host).to receive(:upload_file).with(local_tempfile.path, remote_config_path)
218
- expect(subject.create_remote_config(remote_folder)).to eq(remote_config_path)
219
- # ensure the tempfile is deleted locally
220
- expect(local_tempfile.closed?).to eq(true)
221
- end
222
- end
223
- end
224
-
225
- describe "#create_remote_handler" do
226
- let(:remote_folder) { "/tmp/foo" }
227
- let(:remote_reporter) { "#{remote_folder}/reporter.rb" }
228
- let!(:local_tempfile) { Tempfile.new }
229
-
230
- it "pushes it to the remote machine" do
231
- expect(Tempfile).to receive(:new).and_return(local_tempfile)
232
- expect(target_host).to receive(:upload_file).with(local_tempfile.path, remote_reporter)
233
- expect(subject.create_remote_handler(remote_folder)).to eq(remote_reporter)
234
- # ensure the tempfile is deleted locally
235
- expect(local_tempfile.closed?).to eq(true)
236
- end
237
-
238
- it "raises an error if the upload fails" do
239
- expect(Tempfile).to receive(:new).and_return(local_tempfile)
240
- expect(target_host).to receive(:upload_file).with(local_tempfile.path, remote_reporter).and_raise("foo")
241
- err = ChefApply::Action::ConvergeTarget::HandlerUploadFailed
242
- expect { subject.create_remote_handler(remote_folder) }.to raise_error(err)
243
- # ensure the tempfile is deleted locally
244
- expect(local_tempfile.closed?).to eq(true)
245
- end
246
- end
247
-
248
- describe "#upload_trusted_certs" do
249
- let(:remote_folder) { "/tmp/foo" }
250
- let(:remote_tcd) { File.join(remote_folder, "trusted_certs") }
251
- let(:tmpdir) { Dir.mktmpdir }
252
- let(:certs_dir) { File.join(tmpdir, "weird/glob/chars[/") }
253
-
254
- before do
255
- ChefApply::Config.chef.trusted_certs_dir = certs_dir
256
- FileUtils.mkdir_p(certs_dir)
257
- end
258
-
259
- after do
260
- ChefApply::Config.reset
261
- FileUtils.remove_entry tmpdir
262
- end
263
-
264
- context "when there are local certificates" do
265
- let!(:cert1) { FileUtils.touch(File.join(certs_dir, "1.crt"))[0] }
266
- let!(:cert2) { FileUtils.touch(File.join(certs_dir, "2.pem"))[0] }
267
-
268
- it "uploads the local certs" do
269
- expect(target_host).to receive(:make_directory).with(remote_tcd)
270
- expect(target_host).to receive(:upload_file).with(cert1, File.join(remote_tcd, File.basename(cert1)))
271
- expect(target_host).to receive(:upload_file).with(cert2, File.join(remote_tcd, File.basename(cert2)))
272
- subject.upload_trusted_certs(remote_folder)
273
- end
274
- end
275
-
276
- context "when there are no local certificates" do
277
- it "does not upload any certs" do
278
- expect(target_host).to_not receive(:run_command)
279
- expect(target_host).to_not receive(:upload_file)
280
- subject.upload_trusted_certs(remote_folder)
281
- end
282
- end
283
-
284
- end
285
-
286
- describe "#perform_action" do
287
- let(:remote_folder) { "/tmp/foo" }
288
- let(:remote_archive) { File.join(remote_folder, File.basename(archive)) }
289
- let(:remote_config) { "#{remote_folder}/workstation.rb" }
290
- let(:remote_handler) { "#{remote_folder}/reporter.rb" }
291
- let(:tmpdir) { remote_folder }
292
- before do
293
- expect(target_host).to receive(:temp_dir).and_return(tmpdir)
294
- expect(subject).to receive(:create_remote_policy).with(local_policy_path, remote_folder).and_return(remote_archive)
295
- expect(subject).to receive(:create_remote_config).with(remote_folder).and_return(remote_config)
296
- expect(subject).to receive(:create_remote_handler).with(remote_folder).and_return(remote_handler)
297
- expect(subject).to receive(:upload_trusted_certs).with(remote_folder)
298
- end
299
- let(:result) { double("command result", exit_status: 0, stdout: "") }
300
-
301
- it "runs the converge and reports back success" do
302
- # Note we're only ensuring the command looks the same as #run_chef_cmd - we verify that run_chef_cmd
303
- # is correct in its own test elsewhere in this file
304
- expect(target_host).to receive(:run_command).with(subject.run_chef_cmd(remote_folder,
305
- "workstation.rb",
306
- "archive.tgz")).and_return result
307
- expect(target_host).to receive(:del_dir).with(remote_folder).and_return result
308
-
309
- %i{running_chef success}.each do |n|
310
- expect(subject).to receive(:notify).with(n)
311
- end
312
- subject.perform_action
313
- end
314
-
315
- context "when chef schedules restart" do
316
- let(:result) { double("command result", exit_status: 35) }
317
-
318
- it "runs the converge and reports back reboot" do
319
- expect(target_host).to receive(:run_command).with(subject.run_chef_cmd(remote_folder,
320
- "workstation.rb",
321
- "archive.tgz")).and_return result
322
- expect(target_host).to receive(:del_dir).with(remote_folder).and_return result
323
- %i{running_chef reboot}.each do |n|
324
- expect(subject).to receive(:notify).with(n)
325
- end
326
- subject.perform_action
327
- end
328
- end
329
-
330
- context "when command fails" do
331
- let(:result) { double("command result", exit_status: 1, stdout: "", stderr: "") }
332
- let(:report_result) { '{ "exception": "thing" }' }
333
- let(:exception_mapper) { double("mapper") }
334
- before do
335
- expect(ChefApply::Action::ConvergeTarget::CCRFailureMapper).to receive(:new)
336
- .and_return exception_mapper
337
- end
338
-
339
- it "reports back failure and reads the remote report" do
340
- expect(target_host).to receive(:run_command).with(subject.run_chef_cmd(remote_folder,
341
- "workstation.rb",
342
- "archive.tgz")).and_return result
343
- expect(target_host).to receive(:del_dir).with(remote_folder).and_return result
344
- %i{running_chef converge_error}.each do |n|
345
- expect(subject).to receive(:notify).with(n)
346
- end
347
- expect(target_host).to receive(:fetch_file_contents).with(subject.chef_report_path).and_return(report_result)
348
- expect(target_host).to receive(:del_file).with(subject.chef_report_path)
349
- expect(exception_mapper).to receive(:raise_mapped_exception!)
350
- subject.perform_action
351
- end
352
-
353
- context "when remote report cannot be read" do
354
- let(:report_result) { nil }
355
- it "reports back failure" do
356
- expect(target_host).to receive(:run_command).with(subject.run_chef_cmd(remote_folder,
357
- "workstation.rb",
358
- "archive.tgz")).and_return result
359
- expect(target_host).to receive(:del_dir).with(remote_folder).and_return result
360
- %i{running_chef converge_error}.each do |n|
361
- expect(subject).to receive(:notify).with(n)
362
- end
363
- expect(target_host).to receive(:fetch_file_contents).with(subject.chef_report_path).and_return(report_result)
364
- expect(exception_mapper).to receive(:raise_mapped_exception!)
365
- subject.perform_action
366
- end
367
- end
368
- end
369
-
370
- end
371
-
372
- context "#run_chef_cmd" do
373
- describe "when connecting to a windows target" do
374
- let(:base_os) { :windows }
375
- # BOOTSTRAP TODO - can't find these examples anywhere - not sure how this was passing
376
- # include_examples "check path fetching"
377
-
378
- it "correctly returns chef run string" do
379
- expect(subject.run_chef_cmd("a", "b", "c")).to eq(
380
- "Set-Location -Path a; " \
381
- "chef-client -z --config #{File.join("a", "b")} --recipe-url #{File.join("a", "c")} | Out-Null; " \
382
- "Set-Location C:/; " \
383
- "exit $LASTEXITCODE"
384
- )
385
- end
386
- end
387
-
388
- describe "when connecting to a non-windows target" do
389
- let(:base_os) { :linux }
390
- # BOOTSTRAP TODO - can't find these examples anywhere - not sure how this was passing
391
- # include_examples "check path fetching"
392
-
393
- it "correctly returns chef run string" do
394
- expect(subject.run_chef_cmd("a", "b", "c")).to eq("bash -c 'cd a; chef-client -z --config a/b --recipe-url a/c'")
395
- end
396
- end
397
-
398
- end
399
-
400
- end