chef-apply 0.1.17 → 0.1.18
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.
- checksums.yaml +4 -4
- data/Gemfile +0 -7
- data/Gemfile.lock +176 -84
- data/chef-apply.gemspec +2 -2
- data/lib/chef_apply/version.rb +1 -1
- data/spec/fixtures/custom_config.toml +2 -0
- data/spec/integration/chef-run_spec.rb +41 -0
- data/spec/integration/fixtures/chef_help.out +69 -0
- data/spec/integration/fixtures/chef_version.out +1 -0
- data/spec/integration/spec_helper.rb +55 -0
- data/spec/spec_helper.rb +114 -0
- data/spec/support/matchers/output_to_terminal.rb +36 -0
- data/spec/unit/action/base_spec.rb +89 -0
- data/spec/unit/action/converge_target_spec.rb +292 -0
- data/spec/unit/action/generate_local_policy_spec.rb +114 -0
- data/spec/unit/action/generate_temp_cookbook_spec.rb +75 -0
- data/spec/unit/action/install_chef/base_spec.rb +234 -0
- data/spec/unit/action/install_chef_spec.rb +69 -0
- data/spec/unit/cli/options_spec.rb +75 -0
- data/spec/unit/cli/validation_spec.rb +78 -0
- data/spec/unit/cli_spec.rb +440 -0
- data/spec/unit/config_spec.rb +70 -0
- data/spec/unit/errors/ccr_failure_mapper_spec.rb +103 -0
- data/spec/unit/file_fetcher_spec.rb +40 -0
- data/spec/unit/fixtures/multi-error.out +2 -0
- data/spec/unit/log_spec.rb +37 -0
- data/spec/unit/recipe_lookup_spec.rb +122 -0
- data/spec/unit/startup_spec.rb +283 -0
- data/spec/unit/target_host_spec.rb +231 -0
- data/spec/unit/target_resolver_spec.rb +380 -0
- data/spec/unit/telemeter/sender_spec.rb +140 -0
- data/spec/unit/telemeter_spec.rb +191 -0
- data/spec/unit/temp_cookbook_spec.rb +199 -0
- data/spec/unit/ui/error_printer_spec.rb +173 -0
- data/spec/unit/ui/terminal_spec.rb +109 -0
- data/spec/unit/version_spec.rb +31 -0
- data/warning.txt +3 -0
- metadata +34 -2
@@ -0,0 +1,140 @@
|
|
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
|
@@ -0,0 +1,191 @@
|
|
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
|
@@ -0,0 +1,199 @@
|
|
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/temp_cookbook"
|
20
|
+
require "tempfile"
|
21
|
+
require "securerandom"
|
22
|
+
|
23
|
+
RSpec.describe ChefApply::TempCookbook do
|
24
|
+
subject(:tc) { ChefApply::TempCookbook.new }
|
25
|
+
let(:uuid) { SecureRandom.uuid }
|
26
|
+
|
27
|
+
before do
|
28
|
+
@repo_paths = ChefApply::Config.chef.cookbook_repo_paths
|
29
|
+
ChefApply::Config.chef.cookbook_repo_paths = []
|
30
|
+
end
|
31
|
+
|
32
|
+
after do
|
33
|
+
ChefApply::Config.chef.cookbook_repo_paths = @repo_paths
|
34
|
+
tc.delete
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#from_existing_recipe" do
|
38
|
+
it "raises an error if the recipe does not have a .rb extension" do
|
39
|
+
err = ChefApply::TempCookbook::UnsupportedExtension
|
40
|
+
expect { tc.from_existing_recipe("/some/file.chef") }.to raise_error(err)
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when there is an existing cookbook" do
|
44
|
+
let(:cb) do
|
45
|
+
d = Dir.mktmpdir
|
46
|
+
File.open(File.join(d, "metadata.rb"), "w+") do |f|
|
47
|
+
f << "name \"foo\""
|
48
|
+
end
|
49
|
+
FileUtils.mkdir(File.join(d, "recipes"))
|
50
|
+
d
|
51
|
+
end
|
52
|
+
|
53
|
+
let(:existing_recipe) do
|
54
|
+
File.open(File.join(cb, "recipes/default.rb"), "w+") do |f|
|
55
|
+
f.write(uuid)
|
56
|
+
f
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
after do
|
61
|
+
FileUtils.remove_entry cb
|
62
|
+
end
|
63
|
+
|
64
|
+
it "copies the whole cookbook" do
|
65
|
+
tc.from_existing_recipe(existing_recipe.path)
|
66
|
+
expect(File.read(File.join(tc.path, "recipes/default.rb"))).to eq(uuid)
|
67
|
+
expect(File.read(File.join(tc.path, "Policyfile.rb"))).to eq <<~EXPECTED_POLICYFILE
|
68
|
+
name "foo_policy"
|
69
|
+
default_source :supermarket
|
70
|
+
run_list "foo::default"
|
71
|
+
cookbook "foo", path: "."
|
72
|
+
EXPECTED_POLICYFILE
|
73
|
+
expect(File.read(File.join(tc.path, "metadata.rb"))).to eq("name \"foo\"")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when there is only a single recipe not in a cookbook" do
|
78
|
+
let(:existing_recipe) do
|
79
|
+
t = Tempfile.new(["recipe", ".rb"])
|
80
|
+
t.write(uuid)
|
81
|
+
t.close
|
82
|
+
t
|
83
|
+
end
|
84
|
+
|
85
|
+
after do
|
86
|
+
existing_recipe.unlink
|
87
|
+
end
|
88
|
+
|
89
|
+
it "copies the existing recipe into a new cookbook" do
|
90
|
+
tc.from_existing_recipe(existing_recipe.path)
|
91
|
+
recipe_filename = File.basename(existing_recipe.path)
|
92
|
+
recipe_name = File.basename(recipe_filename, File.extname(recipe_filename))
|
93
|
+
expect(File.read(File.join(tc.path, "recipes/", recipe_filename))).to eq(uuid)
|
94
|
+
expect(File.read(File.join(tc.path, "Policyfile.rb"))).to eq <<~EXPECTED_POLICYFILE
|
95
|
+
name "cw_recipe_policy"
|
96
|
+
default_source :supermarket
|
97
|
+
run_list "cw_recipe::#{recipe_name}"
|
98
|
+
cookbook "cw_recipe", path: "."
|
99
|
+
EXPECTED_POLICYFILE
|
100
|
+
expect(File.read(File.join(tc.path, "metadata.rb"))).to eq("name \"cw_recipe\"\n")
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "#from_resource" do
|
106
|
+
it "creates a recipe containing the supplied recipe" do
|
107
|
+
tc.from_resource("directory", "/tmp/foo", [])
|
108
|
+
expect(File.read(File.join(tc.path, "recipes/default.rb"))).to eq("directory '/tmp/foo'\n")
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "#generate_metadata" do
|
113
|
+
it "generates metadata in the temp cookbook" do
|
114
|
+
f = tc.generate_metadata("foo")
|
115
|
+
expect(File.read(f)).to eq("name \"foo\"\n")
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "#generate_policyfile" do
|
120
|
+
context "when there is no existing policyfile" do
|
121
|
+
it "generates a policyfile in the temp cookbook" do
|
122
|
+
f = tc.generate_policyfile("foo", "bar")
|
123
|
+
expect(File.read(f)).to eq <<~EXPECTED_POLICYFILE
|
124
|
+
name "foo_policy"
|
125
|
+
default_source :supermarket
|
126
|
+
run_list "foo::bar"
|
127
|
+
cookbook "foo", path: "."
|
128
|
+
EXPECTED_POLICYFILE
|
129
|
+
end
|
130
|
+
|
131
|
+
context "when there are configured cookbook_repo_paths" do
|
132
|
+
it "generates a policyfile in the temp cookbook" do
|
133
|
+
ChefApply::Config.chef.cookbook_repo_paths = %w{one two}
|
134
|
+
f = tc.generate_policyfile("foo", "bar")
|
135
|
+
expect(File.read(f)).to eq <<~EXPECTED_POLICYFILE
|
136
|
+
name "foo_policy"
|
137
|
+
default_source :chef_repo, "one"
|
138
|
+
default_source :chef_repo, "two"
|
139
|
+
default_source :supermarket
|
140
|
+
run_list "foo::bar"
|
141
|
+
cookbook "foo", path: "."
|
142
|
+
EXPECTED_POLICYFILE
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context "when there is an existing policyfile" do
|
148
|
+
before do
|
149
|
+
File.open(File.join(tc.path, "Policyfile.rb"), "a") do |f|
|
150
|
+
f << "this is a policyfile"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
it "only overrides the existing run_list in the policyfile" do
|
154
|
+
f = tc.generate_policyfile("foo", "bar")
|
155
|
+
expect(File.read(f)).to eq <<~EXPECTED_POLICYFILE
|
156
|
+
this is a policyfile
|
157
|
+
# Overriding run_list with command line specified value
|
158
|
+
run_list "foo::bar"
|
159
|
+
EXPECTED_POLICYFILE
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "#create_resource_definition" do
|
165
|
+
let(:r1) { "directory" }
|
166
|
+
let(:r2) { "/tmp" }
|
167
|
+
let(:props) { nil }
|
168
|
+
context "when no properties are provided" do
|
169
|
+
it "it creates a simple resource" do
|
170
|
+
expect(tc.create_resource_definition(r1, r2, [])).to eq("directory '/tmp'\n")
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
context "when properties are provided" do
|
175
|
+
let(:props) do
|
176
|
+
{
|
177
|
+
"key1" => "value",
|
178
|
+
"key2" => 0.1,
|
179
|
+
"key3" => 100,
|
180
|
+
"key4" => true,
|
181
|
+
"key_with_underscore" => "value",
|
182
|
+
}
|
183
|
+
end
|
184
|
+
|
185
|
+
it "converts the properties to chef-client args" do
|
186
|
+
expected = <<~EXPECTED_RESOURCE
|
187
|
+
directory '/tmp' do
|
188
|
+
key1 'value'
|
189
|
+
key2 0.1
|
190
|
+
key3 100
|
191
|
+
key4 true
|
192
|
+
key_with_underscore 'value'
|
193
|
+
end
|
194
|
+
EXPECTED_RESOURCE
|
195
|
+
expect(tc.create_resource_definition(r1, r2, props)).to eq(expected)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|