chef-apply 0.4.6 → 0.4.9

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 (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