chef-apply 0.1.17 → 0.1.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -7
  3. data/Gemfile.lock +176 -84
  4. data/chef-apply.gemspec +2 -2
  5. data/lib/chef_apply/version.rb +1 -1
  6. data/spec/fixtures/custom_config.toml +2 -0
  7. data/spec/integration/chef-run_spec.rb +41 -0
  8. data/spec/integration/fixtures/chef_help.out +69 -0
  9. data/spec/integration/fixtures/chef_version.out +1 -0
  10. data/spec/integration/spec_helper.rb +55 -0
  11. data/spec/spec_helper.rb +114 -0
  12. data/spec/support/matchers/output_to_terminal.rb +36 -0
  13. data/spec/unit/action/base_spec.rb +89 -0
  14. data/spec/unit/action/converge_target_spec.rb +292 -0
  15. data/spec/unit/action/generate_local_policy_spec.rb +114 -0
  16. data/spec/unit/action/generate_temp_cookbook_spec.rb +75 -0
  17. data/spec/unit/action/install_chef/base_spec.rb +234 -0
  18. data/spec/unit/action/install_chef_spec.rb +69 -0
  19. data/spec/unit/cli/options_spec.rb +75 -0
  20. data/spec/unit/cli/validation_spec.rb +78 -0
  21. data/spec/unit/cli_spec.rb +440 -0
  22. data/spec/unit/config_spec.rb +70 -0
  23. data/spec/unit/errors/ccr_failure_mapper_spec.rb +103 -0
  24. data/spec/unit/file_fetcher_spec.rb +40 -0
  25. data/spec/unit/fixtures/multi-error.out +2 -0
  26. data/spec/unit/log_spec.rb +37 -0
  27. data/spec/unit/recipe_lookup_spec.rb +122 -0
  28. data/spec/unit/startup_spec.rb +283 -0
  29. data/spec/unit/target_host_spec.rb +231 -0
  30. data/spec/unit/target_resolver_spec.rb +380 -0
  31. data/spec/unit/telemeter/sender_spec.rb +140 -0
  32. data/spec/unit/telemeter_spec.rb +191 -0
  33. data/spec/unit/temp_cookbook_spec.rb +199 -0
  34. data/spec/unit/ui/error_printer_spec.rb +173 -0
  35. data/spec/unit/ui/terminal_spec.rb +109 -0
  36. data/spec/unit/version_spec.rb +31 -0
  37. data/warning.txt +3 -0
  38. metadata +34 -2
@@ -0,0 +1,173 @@
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/errors/standard_error_resolver"
21
+ require "chef_apply/target_host"
22
+
23
+ RSpec.describe ChefApply::UI::ErrorPrinter do
24
+ let(:orig_exception) { StandardError.new("test") }
25
+ let(:target_host) { ChefApply::TargetHost.instance_for_url("mock://localhost") }
26
+ let(:wrapped_exception) { ChefApply::WrappedError.new(orig_exception, target_host) }
27
+ subject(:printer) { ChefApply::UI::ErrorPrinter.new(wrapped_exception, nil) }
28
+
29
+ context "#format_error" do
30
+ it "formats the message" do
31
+ expect(subject).to receive(:format_header).and_return "header"
32
+ expect(subject).to receive(:format_body).and_return "body"
33
+ expect(subject).to receive(:format_footer).and_return "footer"
34
+ expect(subject.format_error).to eq "\nheader\n\nbody\nfooter\n"
35
+ end
36
+ end
37
+
38
+ context "#format_body" do
39
+ RC = ChefApply::TargetHost
40
+ context "when exception is a ChefApply::Error" do
41
+ let(:result) { RemoteExecResult.new(1, "", "failed") }
42
+ let(:orig_exception) { RC::RemoteExecutionFailed.new("localhost", "test", result) }
43
+ it "invokes the right handler" do
44
+ expect(subject).to receive(:format_workstation_exception)
45
+ subject.format_body
46
+ end
47
+ end
48
+
49
+ context "when exception is a Train::Error" do
50
+ # These may expand as we find error-specific messaging we can provide to customers
51
+ # for more specific train exceptions
52
+ let(:orig_exception) { Train::Error.new("test") }
53
+ it "invokes the right handler" do
54
+ expect(subject).to receive(:format_train_exception)
55
+ subject.format_body
56
+ end
57
+ end
58
+
59
+ context "when exception is something else" do
60
+ # These may expand as we find error-specific messaging we can provide to customers
61
+ # for more specific general exceptions
62
+ it "invokes the right handler" do
63
+ expect(subject).to receive(:format_other_exception)
64
+ subject.format_body
65
+ end
66
+ end
67
+ end
68
+
69
+ context ".show_error" do
70
+ subject { ChefApply::UI::ErrorPrinter }
71
+ context "when handling a MultiJobFailure" do
72
+ it "recognizes it and invokes capture_multiple_failures" do
73
+ underlying_error = ChefApply::MultiJobFailure.new([])
74
+ error_to_process = ChefApply::Errors::StandardErrorResolver.wrap_exception(underlying_error)
75
+ expect(subject).to receive(:capture_multiple_failures).with(underlying_error)
76
+ subject.show_error(error_to_process)
77
+
78
+ end
79
+ end
80
+
81
+ context "when an error occurs in error handling" do
82
+ it "processes the new failure with dump_unexpected_error" do
83
+ error_to_raise = StandardError.new("this will be raised")
84
+ error_to_process = ChefApply::Errors::StandardErrorResolver.wrap_exception(StandardError.new("this is being shown"))
85
+ # Intercept a known call to raise an error
86
+ expect(ChefApply::UI::Terminal).to receive(:output).and_raise error_to_raise
87
+ expect(subject).to receive(:dump_unexpected_error).with(error_to_raise)
88
+ subject.show_error(error_to_process)
89
+ end
90
+ end
91
+
92
+ end
93
+
94
+ context ".capture_multiple_failures" do
95
+ subject { ChefApply::UI::ErrorPrinter }
96
+ let(:file_content_capture) { StringIO.new }
97
+ before do
98
+ allow(ChefApply::Config).to receive(:error_output_path).and_return "/dev/null"
99
+ allow(File).to receive(:open).with("/dev/null", "w").and_yield(file_content_capture)
100
+ end
101
+
102
+ it "should write a properly formatted error file" do
103
+ # TODO - add support for test-only i18n content, so that we don't have
104
+ # to rely on specific known error IDs that may change or be removed,
105
+ # and arent' directly relevant to the test at hand.
106
+ job1 = double("Job", target_host: double("TargetHost", hostname: "host1"),
107
+ exception: ChefApply::Error.new("CHEFUPL005"))
108
+ job2 = double("Job", target_host: double("TargetHost", hostname: "host2"),
109
+ exception: StandardError.new("Hello World"))
110
+
111
+ expected_content = File.read("spec/unit/fixtures/multi-error.out")
112
+ multifailure = ChefApply::MultiJobFailure.new([job1, job2] )
113
+ subject.capture_multiple_failures(multifailure)
114
+ expect(file_content_capture.string).to eq expected_content
115
+ end
116
+ end
117
+
118
+ context "#format_footer" do
119
+ let(:show_log) { true }
120
+ let(:show_stack) { true }
121
+ let(:formatter) do
122
+ ChefApply::UI::ErrorPrinter.new(wrapped_exception, nil)
123
+ end
124
+
125
+ subject(:format_footer) do
126
+ lambda { formatter.format_footer }
127
+ end
128
+
129
+ before do
130
+ allow(formatter).to receive(:show_log).and_return show_log
131
+ allow(formatter).to receive(:show_stack).and_return show_stack
132
+ end
133
+
134
+ context "when both log and stack wanted" do
135
+ let(:show_log) { true }
136
+ let(:show_stack) { true }
137
+ assert_string_lookup("errors.footer.both")
138
+ end
139
+
140
+ context "when only log is wanted" do
141
+ let(:show_log) { true }
142
+ let(:show_stack) { false }
143
+ assert_string_lookup("errors.footer.log_only")
144
+ end
145
+
146
+ context "when only stack is wanted" do
147
+ let(:show_log) { false }
148
+ let(:show_stack) { true }
149
+ assert_string_lookup("errors.footer.stack_only")
150
+ end
151
+
152
+ context "when neither log nor stack wanted" do
153
+ let(:show_log) { false }
154
+ let(:show_stack) { false }
155
+ assert_string_lookup("errors.footer.neither")
156
+ end
157
+ end
158
+
159
+ context ".write_backtrace" do
160
+ let(:inst) { double(ChefApply::UI::ErrorPrinter) }
161
+ before do
162
+ allow(ChefApply::UI::ErrorPrinter).to receive(:new).and_return inst
163
+ end
164
+
165
+ let(:orig_args) { %w{test} }
166
+ it "formats and saves the backtrace" do
167
+ expect(inst).to receive(:add_backtrace_header).with(anything(), orig_args)
168
+ expect(inst).to receive(:add_formatted_backtrace)
169
+ expect(inst).to receive(:save_backtrace)
170
+ ChefApply::UI::ErrorPrinter.write_backtrace(wrapped_exception, orig_args)
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,109 @@
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/terminal"
20
+
21
+ RSpec.describe ChefApply::UI::Terminal do
22
+ Terminal = ChefApply::UI::Terminal
23
+ # Lets send our Terminal output somewhere so it does not clutter the
24
+ # test output
25
+ Terminal.location = StringIO.new
26
+
27
+ it "correctly outputs a message" do
28
+ expect { Terminal.output("test") }
29
+ .to output("test\n").to_terminal
30
+ end
31
+
32
+ context "#render_job" do
33
+ it "executes the provided block" do
34
+ @ran = false
35
+ Terminal.render_job("a message") { |reporter| @ran = true }
36
+ expect(@ran).to eq true
37
+ end
38
+ end
39
+
40
+ context "#render_parallel_jobs" do
41
+ it "executes the provided job instances" do
42
+ @job1ran = false
43
+ @job2ran = false
44
+ job1 = Terminal::Job.new("prefix", nil) do
45
+ @job1ran = true
46
+ end
47
+ job2 = Terminal::Job.new("prefix", nil) do
48
+ @job2ran = true
49
+ end
50
+ Terminal.render_parallel_jobs("a message", [job1, job2])
51
+ expect(@job1ran).to eq true
52
+ expect(@job2ran).to eq true
53
+ end
54
+ end
55
+
56
+ describe ChefApply::UI::Terminal::Job do
57
+ subject { ChefApply::UI::Terminal::Job }
58
+ context "#exception" do
59
+ context "when no exception occurs in execution" do
60
+ context "and it's been invoked directly" do
61
+ it "exception is nil" do
62
+ job = subject.new("", nil) { 0 }
63
+ job.run(ChefApply::MockReporter.new)
64
+ expect(job.exception).to eq nil
65
+ end
66
+ end
67
+ context "and it's running in a thread alongside other jobs" do
68
+ it "exception is nil for each job" do
69
+ job1 = subject.new("", nil) { 0 }
70
+ job2 = subject.new("", nil) { 0 }
71
+ threads = []
72
+ threads << Thread.new { job1.run(ChefApply::MockReporter.new) }
73
+ threads << Thread.new { job2.run(ChefApply::MockReporter.new) }
74
+ threads.each(&:join)
75
+ expect(job1.exception).to eq nil
76
+ expect(job2.exception).to eq nil
77
+
78
+ end
79
+ end
80
+ end
81
+ context "when an exception occurs in execution" do
82
+ context "and it's been invoked directly" do
83
+ it "captures the exception in #exception" do
84
+ expected_exception = StandardError.new("exception 1")
85
+ job = subject.new("", nil) { |arg| raise expected_exception }
86
+ job.run(ChefApply::MockReporter.new)
87
+ expect(job.exception).to eq expected_exception
88
+ end
89
+ end
90
+
91
+ context "and it's running in a thread alongside other jobs" do
92
+ it "each job holds its own exception" do
93
+ e1 = StandardError.new("exception 1")
94
+ e2 = StandardError.new("exception 2")
95
+
96
+ job1 = subject.new("", nil) { |_| raise e1 }
97
+ job2 = subject.new("", nil) { |_| raise e2 }
98
+ threads = []
99
+ threads << Thread.new { job1.run(ChefApply::MockReporter.new) }
100
+ threads << Thread.new { job2.run(ChefApply::MockReporter.new) }
101
+ threads.each(&:join)
102
+ expect(job1.exception).to eq e1
103
+ expect(job2.exception).to eq e2
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,31 @@
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/version"
20
+
21
+ RSpec.describe ChefApply::VERSION do
22
+ subject(:version) do
23
+ ChefApply::VERSION
24
+ end
25
+
26
+ context "VERSION" do
27
+ it "returns the version" do
28
+ expect(Gem::Version.correct?(version)).to be_truthy
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ Chef Apply is not meant to be installed as a gem. It is meant to be installed
2
+ as part of the Chef Workstation omnibus package. Please download and install
3
+ that from https://downloads.chef.io/chef-dk/
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-apply
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.17
4
+ version: 0.1.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chef Software, Inc
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-30 00:00:00.000000000 Z
11
+ date: 2018-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mixlib-cli
@@ -356,6 +356,38 @@ files:
356
356
  - lib/chef_apply/ui/plain_text_element.rb
357
357
  - lib/chef_apply/ui/terminal.rb
358
358
  - lib/chef_apply/version.rb
359
+ - spec/fixtures/custom_config.toml
360
+ - spec/integration/chef-run_spec.rb
361
+ - spec/integration/fixtures/chef_help.out
362
+ - spec/integration/fixtures/chef_version.out
363
+ - spec/integration/spec_helper.rb
364
+ - spec/spec_helper.rb
365
+ - spec/support/matchers/output_to_terminal.rb
366
+ - spec/unit/action/base_spec.rb
367
+ - spec/unit/action/converge_target_spec.rb
368
+ - spec/unit/action/generate_local_policy_spec.rb
369
+ - spec/unit/action/generate_temp_cookbook_spec.rb
370
+ - spec/unit/action/install_chef/base_spec.rb
371
+ - spec/unit/action/install_chef_spec.rb
372
+ - spec/unit/cli/options_spec.rb
373
+ - spec/unit/cli/validation_spec.rb
374
+ - spec/unit/cli_spec.rb
375
+ - spec/unit/config_spec.rb
376
+ - spec/unit/errors/ccr_failure_mapper_spec.rb
377
+ - spec/unit/file_fetcher_spec.rb
378
+ - spec/unit/fixtures/multi-error.out
379
+ - spec/unit/log_spec.rb
380
+ - spec/unit/recipe_lookup_spec.rb
381
+ - spec/unit/startup_spec.rb
382
+ - spec/unit/target_host_spec.rb
383
+ - spec/unit/target_resolver_spec.rb
384
+ - spec/unit/telemeter/sender_spec.rb
385
+ - spec/unit/telemeter_spec.rb
386
+ - spec/unit/temp_cookbook_spec.rb
387
+ - spec/unit/ui/error_printer_spec.rb
388
+ - spec/unit/ui/terminal_spec.rb
389
+ - spec/unit/version_spec.rb
390
+ - warning.txt
359
391
  homepage: https://github.com/chef/chef-apply
360
392
  licenses:
361
393
  - Apache-2.0