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,140 +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/telemeter/sender"
20
- require "chef_apply/config"
21
-
22
- RSpec.describe ChefApply::Telemeter::Sender do
23
- let(:session_files) { %w{file1 file2} }
24
- let(:enabled_flag) { true }
25
- let(:dev_mode) { false }
26
- let(:config) { double("config") }
27
-
28
- let(:subject) { ChefApply::Telemeter::Sender.new(session_files) }
29
-
30
- before do
31
- allow(config).to receive(:dev).and_return dev_mode
32
- allow(ChefApply::Config).to receive(:telemetry).and_return config
33
- allow(ChefApply::Telemeter).to receive(:enabled?).and_return enabled_flag
34
- # Ensure this is not set for each test:
35
- ENV.delete("CHEF_TELEMETRY_ENDPOINT")
36
- end
37
-
38
- describe "::start_upload_thread" do
39
- let(:sender_mock) { instance_double(ChefApply::Telemeter::Sender) }
40
- it "spawns a thread to run the send" do
41
- expect(ChefApply::Telemeter::Sender).to receive(:find_session_files).and_return session_files
42
- expect(ChefApply::Telemeter::Sender).to receive(:new).with(session_files).and_return sender_mock
43
- expect(sender_mock).to receive(:run)
44
- expect(::Thread).to receive(:new).and_yield
45
- ChefApply::Telemeter::Sender.start_upload_thread
46
- end
47
- end
48
-
49
- describe "#run" do
50
- before do
51
- expect(subject).to receive(:session_files).and_return session_files
52
- end
53
-
54
- context "when telemetry is disabled" do
55
- let(:enabled_flag) { false }
56
- it "deletes session files without sending" do
57
- expect(FileUtils).to receive(:rm_rf).with("file1")
58
- expect(FileUtils).to receive(:rm_rf).with("file2")
59
- expect(FileUtils).to receive(:rm_rf).with(ChefApply::Config.telemetry_session_file)
60
- expect(subject).to_not receive(:process_session)
61
- subject.run
62
- end
63
- end
64
-
65
- context "when telemetry is enabled" do
66
- context "and telemetry dev mode is true" do
67
- let(:dev_mode) { true }
68
- let(:session_files) { [] } # Ensure we don't send anything without mocking :allthecalls:
69
- context "and a custom telemetry endpoint is not set" do
70
- it "configures the environment to submit to the Acceptance telemetry endpoint" do
71
- subject.run
72
- expect(ENV["CHEF_TELEMETRY_ENDPOINT"]).to eq "https://telemetry-acceptance.chef.io"
73
- end
74
- end
75
-
76
- context "and a custom telemetry endpoint is already set" do
77
- before do
78
- ENV["CHEF_TELEMETRY_ENDPOINT"] = "https://localhost"
79
- end
80
- it "should not overwrite the custom value" do
81
- subject.run
82
- expect(ENV["CHEF_TELEMETRY_ENDPOINT"]).to eq "https://localhost"
83
- end
84
- end
85
- end
86
-
87
- it "submits the session capture for each session file found" do
88
- expect(subject).to receive(:process_session).with("file1")
89
- expect(subject).to receive(:process_session).with("file2")
90
- expect(FileUtils).to receive(:rm_rf).with(ChefApply::Config.telemetry_session_file)
91
- subject.run
92
- end
93
- end
94
-
95
- context "when an error occurrs" do
96
- it "logs it" do
97
- allow(config).to receive(:enabled?).and_raise("Failed")
98
- expect(ChefApply::Log).to receive(:fatal)
99
- subject.run
100
- end
101
- end
102
- end
103
-
104
- describe "::find_session_files" do
105
- it "finds all telemetry-payload-*.yml files in the telemetry directory" do
106
- expect(ChefApply::Config).to receive(:telemetry_path).and_return("/tmp")
107
- expect(Dir).to receive(:glob).with("/tmp/telemetry-payload-*.yml").and_return []
108
- ChefApply::Telemeter::Sender.find_session_files
109
- end
110
- end
111
-
112
- describe "process_session" do
113
- it "loads the sesion and submits it" do
114
- expect(subject).to receive(:load_and_clear_session).with("file1").and_return({ "version" => "1.0.0", "entries" => [] })
115
- expect(subject).to receive(:submit_session).with({ "version" => "1.0.0", "entries" => [] })
116
- subject.process_session("file1")
117
- end
118
- end
119
-
120
- describe "submit_session" do
121
- let(:telemetry) { instance_double("telemetry") }
122
- it "removes the telemetry session file and starts a new session, then submits each entry in the session" do
123
- expect(ChefApply::Config).to receive(:telemetry_session_file).and_return("/tmp/SESSION_ID")
124
- expect(FileUtils).to receive(:rm_rf).with("/tmp/SESSION_ID")
125
- expect(Telemetry).to receive(:new).and_return telemetry
126
- expect(subject).to receive(:submit_entry).with(telemetry, { "event" => "action1" }, 1, 2)
127
- expect(subject).to receive(:submit_entry).with(telemetry, { "event" => "action2" }, 2, 2)
128
- subject.submit_session( { "version" => "1.0.0",
129
- "entries" => [ { "event" => "action1" }, { "event" => "action2" } ] } )
130
- end
131
- end
132
-
133
- describe "submit_entry" do
134
- let(:telemetry) { instance_double("telemetry") }
135
- it "submits the entry to telemetry" do
136
- expect(telemetry).to receive(:deliver).with("test" => "this")
137
- subject.submit_entry(telemetry, { "test" => "this" }, 1, 1)
138
- end
139
- end
140
- end
@@ -1,191 +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/telemeter"
20
-
21
- RSpec.describe ChefApply::Telemeter do
22
- subject { ChefApply::Telemeter.instance }
23
- let(:host_platform) { "linux" }
24
-
25
- before do
26
- allow(subject).to receive(:host_platform).and_return host_platform
27
- end
28
-
29
- context "#commit" do
30
- context "when telemetry is enabled" do
31
- before do
32
- allow(subject).to receive(:enabled?).and_return true
33
- end
34
-
35
- it "writes events out and clears the queue" do
36
- subject.capture(:test)
37
- expect(subject.pending_event_count).to eq 1
38
- expect(subject).to receive(:convert_events_to_session)
39
- expect(subject).to receive(:write_session)
40
-
41
- subject.commit
42
- expect(subject.pending_event_count).to eq 0
43
- end
44
- end
45
-
46
- context "when telemetry is disabled" do
47
- before do
48
- allow(subject).to receive(:enabled?).and_return false
49
- end
50
- it "does not write any events and clears the queue" do
51
- subject.capture(:test)
52
- expect(subject.pending_event_count).to eq 1
53
- expect(subject).to_not receive(:convert_events_to_session)
54
-
55
- subject.commit
56
- expect(subject.pending_event_count).to eq 0
57
- end
58
- end
59
- end
60
-
61
- context "#timed_action_capture" do
62
- context "when a valid target_host is present" do
63
- it "invokes timed_capture with action and valid target data" do
64
- target = instance_double("TargetHost",
65
- base_os: "windows",
66
- version: "10.0.0",
67
- architecture: "x86_64",
68
- hostname: "My_Host",
69
- transport_type: "winrm")
70
- action = instance_double("Action::Base", name: "test_action",
71
- target_host: target)
72
- expected_data = {
73
- action: "test_action",
74
- target: {
75
- platform: {
76
- name: "windows",
77
- version: "10.0.0",
78
- architecture: "x86_64",
79
- },
80
- hostname_sha1: Digest::SHA1.hexdigest("my_host"),
81
- transport_type: "winrm",
82
- },
83
- }
84
- expect(subject).to receive(:timed_capture).with(:action, expected_data)
85
- subject.timed_action_capture(action) { :ok }
86
- end
87
-
88
- context "when a valid target_host is not present" do
89
- it "invokes timed_capture with empty target values" do
90
- expected_data = { action: "Base", target: { platform: {},
91
- hostname_sha1: nil,
92
- transport_type: nil } }
93
- expect(subject).to receive(:timed_capture)
94
- .with(:action, expected_data)
95
- subject.timed_action_capture(
96
- ChefApply::Action::Base.new(target_host: nil)
97
- ) { :ok }
98
- end
99
- end
100
- end
101
- end
102
-
103
- context "::enabled?" do
104
- let(:enabled_flag) { false }
105
- let(:config) { double("config") }
106
- before do
107
- allow(ChefApply::Config).to receive(:telemetry).and_return(config)
108
- allow(config).to receive(:enable).and_return(enabled_flag)
109
- end
110
-
111
- context "when config value is enabled" do
112
- let(:enabled_flag) { true }
113
- context "and CHEF_TELEMETRY_OPT_OUT is not present in env vars" do
114
- it "returns false" do
115
- ENV.delete("CHEF_TELEMETRY_OPT_OUT")
116
- expect(subject.enabled?).to eq true
117
- end
118
- end
119
- context "and CHEF_TELEMETRY_OPT_OUT is present in env vars" do
120
- it "returns false" do
121
- ENV["CHEF_TELEMETRY_OPT_OUT"] = ""
122
- expect(subject.enabled?).to eq false
123
- end
124
- end
125
- end
126
-
127
- context "when config value is disabled" do
128
- let(:enabled_flag) { false }
129
- it "returns false" do
130
- expect(subject.enabled?).to eq false
131
- end
132
- end
133
- end
134
-
135
- context "#timed_run_capture" do
136
- it "invokes timed_capture with run data" do
137
- expected_data = { arguments: [ "arg1" ] }
138
- expect(subject).to receive(:timed_capture)
139
- .with(:run, expected_data)
140
- subject.timed_run_capture(["arg1"])
141
- end
142
- end
143
-
144
- context "#timed_capture" do
145
- let(:runner) { double("capture_test") }
146
- before do
147
- expect(subject.pending_event_count).to eq 0
148
- end
149
-
150
- it "runs the requested thing and invokes #capture with duration" do
151
- expect(runner).to receive(:do_it)
152
- expect(subject).to receive(:capture) do |name, data|
153
- expect(name).to eq(:do_it_test)
154
- expect(data[:duration]).to be > 0.0
155
- end
156
- subject.timed_capture(:do_it_test) do
157
- runner.do_it
158
- end
159
- end
160
- end
161
-
162
- context "#capture" do
163
- before do
164
- expect(subject.pending_event_count).to eq 0
165
- end
166
- it "adds the captured event to the session" do
167
- subject.capture(:test, {})
168
- expect(subject.pending_event_count) == 1
169
- end
170
- end
171
-
172
- context "#make_event_payload" do
173
- before do
174
- allow(subject).to receive(:installation_id).and_return "0000"
175
- end
176
-
177
- it "adds expected properties" do
178
- payload = subject.make_event_payload(:run, { hello: "world" })
179
- expected_payload = {
180
- event: :run,
181
- properties: {
182
- installation_id: "0000",
183
- run_timestamp: subject.run_timestamp,
184
- host_platform: host_platform,
185
- event_data: { hello: "world" },
186
- },
187
- }
188
- expect(payload).to eq expected_payload
189
- end
190
- end
191
- end
@@ -1,109 +0,0 @@
1
- #
2
- # Copyright:: Copyright (c) 2017 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/text"
20
-
21
- RSpec.describe ChefApply::Text::ErrorTranslation do
22
-
23
- let(:display_defaults) do
24
- {
25
- decorations: true,
26
- header: true,
27
- footer: true,
28
- stack: false,
29
- log: false }
30
- end
31
-
32
- let(:error_table) do
33
- { display_defaults: display_defaults,
34
- TESTERROR: test_error }
35
- end
36
-
37
- let(:test_error_text) { "This is a test error" }
38
- let(:test_error) { {} }
39
-
40
- subject { ChefApply::Text::ErrorTranslation }
41
- let(:error_mock) do
42
- double("R18n::Translated",
43
- text: test_error_text )
44
- end
45
- let(:translation_mock) do
46
- double("R18n::Translated",
47
- TESTERROR: error_mock,
48
- text: test_error_text )
49
- end
50
- before do
51
- # Mock out the R18n portion - our methods care only that the key exists, and
52
- # the test focus is on the display metadata.
53
- allow(ChefApply::Text).to receive(:errors).and_return translation_mock
54
- allow(ChefApply::Text).to receive(:_error_table).and_return(error_table)
55
- end
56
-
57
- context "when some display attributes are specified" do
58
- let(:test_error) { { display: { stack: true, log: true } } }
59
- it "sets display attributes to specified values and defaults remaining" do
60
- translation = subject.new("TESTERROR")
61
- expect(translation.decorations).to be true
62
- expect(translation.header).to be true
63
- expect(translation.footer).to be true
64
- expect(translation.stack).to be true
65
- expect(translation.log).to be true
66
- expect(translation.message).to eq test_error_text
67
- end
68
- end
69
-
70
- context "when all display attributes are specified" do
71
- let(:test_error) do
72
- { display: { decorations: false, header: false,
73
- footer: false, stack: true, log: true } }
74
- end
75
- it "sets display attributes to specified values with no defaults" do
76
- translation = subject.new("TESTERROR")
77
- expect(translation.decorations).to be false
78
- expect(translation.header).to be false
79
- expect(translation.footer).to be false
80
- expect(translation.stack).to be true
81
- expect(translation.log).to be true
82
- expect(translation.message).to eq test_error_text
83
- end
84
- end
85
-
86
- context "when no attributes for an error are specified" do
87
- let(:test_error) { {} }
88
- it "sets display attribute to default values and references the correct message" do
89
- translation = subject.new("TESTERROR")
90
- expect(translation.decorations).to be true
91
- expect(translation.header).to be true
92
- expect(translation.footer).to be true
93
- expect(translation.stack).to be false
94
- expect(translation.log).to be false
95
- expect(translation.message).to eq test_error_text
96
- end
97
- end
98
-
99
- context "when invalid attributes for an error are specified" do
100
- let(:test_error) { { display: { bad_value: true } } }
101
- it "raises InvalidDisplayAttributes when invalid attributes are specified" do
102
- expect { subject.new("TESTERROR") }
103
- .to raise_error(ChefApply::Text::ErrorTranslation::InvalidDisplayAttributes) do |e|
104
- expect(e.invalid_attrs).to eq({ bad_value: true })
105
- end
106
-
107
- end
108
- end
109
- end
@@ -1,196 +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/ui/error_printer"
20
- require "chef_apply/text/error_translation"
21
- require "chef_apply/errors/standard_error_resolver"
22
- require "chef_apply/target_host"
23
-
24
- RSpec.describe ChefApply::UI::ErrorPrinter do
25
-
26
- let(:orig_exception) { StandardError.new("test") }
27
- let(:target_host) { ChefApply::TargetHost.mock_instance("mock://localhost") }
28
- let(:wrapped_exception) { ChefApply::WrappedError.new(orig_exception, target_host) }
29
-
30
- let(:show_footer) { true }
31
- let(:show_log) { true }
32
- let(:show_stack) { true }
33
- let(:has_decorations) { true }
34
- let(:show_header) { true }
35
- let(:translation_mock) do
36
- instance_double("ChefApply::Errors::ErrorTranslation",
37
- footer: show_footer,
38
- log: show_log,
39
- stack: show_stack,
40
- header: show_header,
41
- decorations: has_decorations)
42
- end
43
- subject { ChefApply::UI::ErrorPrinter.new(wrapped_exception, nil) }
44
-
45
- before do
46
- allow(ChefApply::Text::ErrorTranslation).to receive(:new).and_return translation_mock
47
- end
48
-
49
- context "#format_error" do
50
-
51
- context "and the message has decorations" do
52
- let(:has_decorations) { true }
53
- it "formats the message using the correct method" do
54
- expect(subject).to receive(:format_decorated).and_return "decorated"
55
- subject.format_error
56
- end
57
- end
58
-
59
- context "and the message does not have decorations" do
60
- let(:has_decorations) { false }
61
- it "formats the message using the correct method" do
62
- expect(subject).to receive(:format_undecorated).and_return "undecorated"
63
- subject.format_error
64
- end
65
- end
66
- end
67
-
68
- context "#format_body" do
69
- RC = ChefApply::TargetHost
70
- context "when exception is a ChefApply::Error" do
71
- let(:result) { RemoteExecResult.new(1, "", "failed") }
72
- let(:orig_exception) { RC::RemoteExecutionFailed.new("localhost", "test", result) }
73
- it "invokes the right handler" do
74
- expect(subject).to receive(:format_workstation_exception)
75
- subject.format_body
76
- end
77
- end
78
-
79
- context "when exception is a Train::Error" do
80
- # These may expand as we find error-specific messaging we can provide to customers
81
- # for more specific train exceptions
82
- let(:orig_exception) { Train::Error.new("test") }
83
- it "invokes the right handler" do
84
- expect(subject).to receive(:format_train_exception)
85
- subject.format_body
86
- end
87
- end
88
-
89
- context "when exception is something else" do
90
- # These may expand as we find error-specific messaging we can provide to customers
91
- # for more specific general exceptions
92
- it "invokes the right handler" do
93
- expect(subject).to receive(:format_other_exception)
94
- subject.format_body
95
- end
96
- end
97
- end
98
-
99
- context ".show_error" do
100
- subject { ChefApply::UI::ErrorPrinter }
101
- context "when handling a MultiJobFailure" do
102
- it "recognizes it and invokes capture_multiple_failures" do
103
- underlying_error = ChefApply::MultiJobFailure.new([])
104
- error_to_process = ChefApply::Errors::StandardErrorResolver.wrap_exception(underlying_error)
105
- expect(subject).to receive(:capture_multiple_failures).with(underlying_error)
106
- subject.show_error(error_to_process)
107
-
108
- end
109
- end
110
-
111
- context "when an error occurs in error handling" do
112
- it "processes the new failure with dump_unexpected_error" do
113
- error_to_raise = StandardError.new("this will be raised")
114
- error_to_process = ChefApply::Errors::StandardErrorResolver.wrap_exception(StandardError.new("this is being shown"))
115
- # Intercept a known call to raise an error
116
- expect(ChefApply::UI::Terminal).to receive(:output).and_raise error_to_raise
117
- expect(subject).to receive(:dump_unexpected_error).with(error_to_raise)
118
- subject.show_error(error_to_process)
119
- end
120
- end
121
-
122
- end
123
-
124
- context ".capture_multiple_failures" do
125
- subject { ChefApply::UI::ErrorPrinter }
126
- let(:file_content_capture) { StringIO.new }
127
- before do
128
- allow(ChefApply::Config).to receive(:error_output_path).and_return "/dev/null"
129
- allow(File).to receive(:open).with("/dev/null", "w").and_yield(file_content_capture)
130
- end
131
-
132
- it "should write a properly formatted error file" do
133
- # TODO - add support for test-only i18n content, so that we don't have
134
- # to rely on specific known error IDs that may change or be removed,
135
- # and arent' directly relevant to the test at hand.
136
- job1 = double("Job", target_host: double("TargetHost", hostname: "host1"),
137
- exception: ChefApply::Error.new("CHEFUPL005"))
138
- job2 = double("Job", target_host: double("TargetHost", hostname: "host2"),
139
- exception: StandardError.new("Hello World"))
140
-
141
- expected_content = File.read("spec/unit/fixtures/multi-error.out")
142
- multifailure = ChefApply::MultiJobFailure.new([job1, job2] )
143
- subject.capture_multiple_failures(multifailure)
144
- expect(file_content_capture.string).to eq expected_content
145
- end
146
- end
147
-
148
- context "#format_footer" do
149
- let(:formatter) do
150
- ChefApply::UI::ErrorPrinter.new(wrapped_exception, nil)
151
- end
152
-
153
- subject do
154
- lambda { formatter.format_footer }
155
- end
156
-
157
- context "when both log and stack wanted" do
158
- let(:show_log) { true }
159
- let(:show_stack) { true }
160
- assert_string_lookup("errors.footer.both")
161
- end
162
-
163
- context "when only log is wanted" do
164
- let(:show_log) { true }
165
- let(:show_stack) { false }
166
- assert_string_lookup("errors.footer.log_only")
167
- end
168
-
169
- context "when only stack is wanted" do
170
- let(:show_log) { false }
171
- let(:show_stack) { true }
172
- assert_string_lookup("errors.footer.stack_only")
173
- end
174
-
175
- context "when neither log nor stack wanted" do
176
- let(:show_log) { false }
177
- let(:show_stack) { false }
178
- assert_string_lookup("errors.footer.neither")
179
- end
180
- end
181
-
182
- context ".write_backtrace" do
183
- let(:inst) { double(ChefApply::UI::ErrorPrinter) }
184
- before do
185
- allow(ChefApply::UI::ErrorPrinter).to receive(:new).and_return inst
186
- end
187
-
188
- let(:orig_args) { %w{test} }
189
- it "formats and saves the backtrace" do
190
- expect(inst).to receive(:add_backtrace_header).with(anything, orig_args)
191
- expect(inst).to receive(:add_formatted_backtrace)
192
- expect(inst).to receive(:save_backtrace)
193
- ChefApply::UI::ErrorPrinter.write_backtrace(wrapped_exception, orig_args)
194
- end
195
- end
196
- end