clc-promote 0.8.7 → 0.9.4

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.
@@ -1,18 +1,21 @@
1
1
  require 'promote'
2
2
 
3
3
  describe Promote::Promoter do
4
- let(:config) { Promote::Config.new({
5
- :node_name => 'user',
6
- :cookbook_directory => '/cookbooks',
7
- :client_key => 'key',
8
- :chef_server_url => 'https://some.chef.server'}) }
4
+ let(:config) do
5
+ Promote::Config.new(
6
+ node_name: 'user',
7
+ cookbook_directory: '/cookbooks',
8
+ client_key: 'key',
9
+ chef_server_url: 'https://some.chef.server'
10
+ )
11
+ end
9
12
 
10
13
  let(:ui) { Chef::Knife::UI.new(STDOUT, STDERR, STDIN, {}) }
11
14
 
12
15
  subject { Promote::Promoter.new(config) }
13
16
 
14
- context "promote_to" do
15
- let(:fake_file){double('file')}
17
+ context 'promote_to' do
18
+ let(:fake_file) { double('file') }
16
19
  let(:env1) do
17
20
  <<-EOS
18
21
  {
@@ -37,18 +40,21 @@ describe Promote::Promoter do
37
40
  "cookbook_versions": {
38
41
  "build-essential": "1.0.0",
39
42
  "platform_haproxy": "1.0.0"
40
- }
43
+ }
41
44
  }
42
45
  EOS
43
46
  end
44
47
 
45
- before {
46
- allow(File).to receive(:read).with(/env1\.json$/).and_return(env1)
47
- allow(File).to receive(:read).with(/env2\.json$/).and_return(env2)
48
- allow(File).to receive(:open).with(/env2\.json$/, "w").and_yield(fake_file)
49
- }
48
+ before do
49
+ allow(File).to receive(:read).with(/env1\.json$/)
50
+ .and_return(env1)
51
+ allow(File).to receive(:read).with(/env2\.json$/)
52
+ .and_return(env2)
53
+ allow(File).to receive(:open).with(/env2\.json$/, 'w')
54
+ .and_yield(fake_file)
55
+ end
50
56
 
51
- it "copies the cookbook constraints" do
57
+ it 'copies the cookbook constraints' do
52
58
  expect(fake_file).to receive(:<<).with(an_instance_of(String)) do |arg|
53
59
  parsed = JSON.parse(arg)
54
60
  expect(parsed['cookbook_versions'].length).to eq(3)
@@ -56,69 +62,100 @@ describe Promote::Promoter do
56
62
  expect(parsed['cookbook_versions']['newrelic']).to eq('2.0.0')
57
63
  expect(parsed['cookbook_versions']['platform_haproxy']).to eq('2.0.0')
58
64
  end
59
- subject.promote_to("env1", "env2")
65
+ subject.promote_to('env1', 'env2')
60
66
  end
61
67
  end
62
68
 
63
- context "monitor_promotion" do
64
- let(:finder_good){ double('node_finder', :search => [good_node]) }
65
- let(:finder_bad){ double('node_finder', :search => [bad_node]) }
66
- let (:good_node) {
69
+ context 'monitor_promotion' do
70
+ let(:finder_good) { double('node_finder', search: [good_node]) }
71
+ let(:finder_bad) { double('node_finder', search: [bad_node]) }
72
+ let(:good_node) do
67
73
  node = Chef::Node.new
68
- node.name "good_node"
69
- node.default["ohai_time"] = Time.now.to_i + 3600
74
+ node.name 'good_node'
75
+ node.default['ohai_time'] = Time.now.to_i + 3600
70
76
  node
71
- }
72
- let (:bad_node) {
77
+ end
78
+ let(:bad_node) do
73
79
  node = Chef::Node.new
74
- node.name "bad_node"
75
- node.default["ohai_time"] = Time.now.to_i - 3600
80
+ node.name 'bad_node'
81
+ node.default['ohai_time'] = Time.now.to_i - 3600
76
82
  node
77
- }
83
+ end
78
84
  let(:uploader) { double('uploader') }
79
85
  let(:ui) { nil }
80
86
 
81
- before {
87
+ before do
82
88
  allow(Promote::NodeFinder).to receive(:new).and_return(finder_good)
83
89
  allow(Promote::Uploader).to receive(:new).and_return(uploader)
84
- }
90
+ end
85
91
 
86
- context "all environments succeed" do
87
- it "promotes all nodes" do
88
- %w{env2 env3 env4}.each do |env|
89
- expect(subject).to receive(:promote_to).with("env1", env, ui)
92
+ context 'all environments succeed' do
93
+ it 'promotes all nodes' do
94
+ %w(env2 env3 env4).each do |env|
95
+ expect(subject).to receive(:promote_to).with('env1', env, ui)
90
96
  expect(uploader).to receive(:upload_environment).with(env, ui)
91
97
  end
92
- subject.monitor_promotion("env1", ["env2", "env3", "env4"], 0.25, false, 1, ui)
98
+ subject.monitor_promotion(
99
+ 'env1',
100
+ %w(env2 env3 env4),
101
+ 0.25,
102
+ false,
103
+ 1,
104
+ ui
105
+ )
93
106
  end
94
107
  end
95
108
 
96
- context "source environment does not fully converge" do
97
- before {
98
- allow(Promote::NodeFinder).to receive(:new).with("chef_environment:env1", config).and_return(finder_bad)
99
- }
109
+ context 'source environment does not fully converge' do
110
+ before do
111
+ allow(Promote::NodeFinder).to(
112
+ receive(:new).with('chef_environment:env1', config)
113
+ .and_return(finder_bad)
114
+ )
115
+ end
100
116
 
101
- it "promotes no nodes" do
117
+ it 'promotes no nodes' do
102
118
  expect(subject).not_to receive(:promote_to)
103
119
  expect(uploader).not_to receive(:upload_environment)
104
120
 
105
- expect{ subject.monitor_promotion("env1", ["env2", "env3", "env4"], 0.25, false, 1, ui) }.to raise_error(/env1$/)
121
+ expect do
122
+ subject.monitor_promotion(
123
+ 'env1',
124
+ %w(env2 env3 env4),
125
+ 0.25,
126
+ false,
127
+ 1,
128
+ ui
129
+ )
130
+ end.to raise_error(/env1$/)
106
131
  end
107
132
  end
108
133
 
109
- context "stops promotion when promotion fails" do
110
- before {
111
- allow(Promote::NodeFinder).to receive(:new).with("chef_environment:env3", config).and_return(finder_bad)
112
- }
134
+ context 'stops promotion when promotion fails' do
135
+ before do
136
+ allow(Promote::NodeFinder).to(
137
+ receive(:new).with('chef_environment:env3', config)
138
+ .and_return(finder_bad)
139
+ )
140
+ end
113
141
 
114
- it "stops on failure" do
115
- %w{env2 env3}.each do |env|
116
- expect(subject).to receive(:promote_to).with("env1", env, ui)
142
+ it 'stops on failure' do
143
+ %w(env2 env3).each do |env|
144
+ expect(subject).to receive(:promote_to).with('env1', env, ui)
117
145
  expect(uploader).to receive(:upload_environment).with(env, ui)
118
146
  end
119
- expect(subject).not_to receive(:promote_to).with("env1", "env4", ui)
120
- expect(uploader).not_to receive(:upload_environment).with("env4")
121
- expect{ subject.monitor_promotion("env1", ["env2", "env3", "env4"], 0.25, false, 1, ui) }.to raise_error(/env3$/)
147
+ expect(subject).not_to receive(:promote_to).with('env1', 'env4', ui)
148
+ expect(uploader).not_to receive(:upload_environment).with('env4')
149
+ expect do
150
+ subject.monitor_promotion(
151
+ 'env1',
152
+ %w(env2 env3 env4),
153
+ 0.25,
154
+ false,
155
+ 1,
156
+ ui
157
+ )
158
+ end.to raise_error(/env3$/)
122
159
  end
123
160
  end
124
161
  end
@@ -2,289 +2,289 @@ require 'promote'
2
2
  require_relative '../support/dummy_metadata'
3
3
 
4
4
  describe Promote::Uploader do
5
- let(:knife_config) {{ :cookbook_path => "path"}}
6
- let(:temp_dir) { "/tmp/berks" }
7
- let(:config) { Promote::Config.new({
8
- :node_name => 'user',
9
- :cookbook_directory => '/cookbooks',
10
- :client_key => 'key',
11
- :temp_directory => temp_dir,
12
- :chef_server_url => 'https://some.chef.server'}) }
13
-
14
- subject { Promote::Uploader.new(config) }
15
-
16
- before {
17
- Chef::Config[:chef_repo_path] = config.repo_root
18
- allow(Chef::ChefFS::FileSystem).to receive(:copy_to)
19
- }
20
-
21
- context "upload cookbooks" do
22
- let(:env_name) { "QA1" }
23
- let(:metadata) { PromoteSpecs::DummyMetadata.new({'version' => "1.1.1"}) }
24
- let(:environment) do
25
- <<-EOS
26
- {
27
- "name": "#{env_name}",
28
- "chef_type": "environment",
29
- "json_class": "Chef::Environment",
30
- "cookbook_versions": {
31
- "int_cookbook1": "1.1.1",
32
- "int_cookbook3": "1.1.1",
33
- "cookbook3": "3.3.3"
34
- }
35
- }
36
- EOS
37
- end
38
- let(:berks_cookbooks) {[
39
- "/berks/cookbook1-1.1.1",
40
- "/berks/cookbook1-1.1.2",
41
- "/berks/cookbook2-2.2.2",
42
- "/berks/cookbook3-3.3.3",
43
- "/berks/cookbook4-3.3.3",
44
- ]}
45
- let(:internal_cookbooks) {[
46
- "/cookbooks/int_cookbook1",
47
- "/cookbooks/int_cookbook2",
48
- "/cookbooks/int_cookbook3",
49
- ]}
50
- let(:server_cookbooks){{
51
- "cookbook1" => {"versions" => [{"version" => "1.1.1"}]},
52
- "cookbook2" => {"versions" => [{"version" => "1.1.1"}]},
53
- "int_cookbook1" => {"versions" => [{"version" => "1.1.1"}]},
54
- "int_cookbook2" => {"versions" => [{"version" => "2.2.2"}]}
55
- }}
56
- let(:rest){double('rest')}
57
- let(:knife) { instance_double('CookbookUpload', :run => nil) }
58
-
59
- before {
60
- allow(File).to receive(:read).with(File.join(config.environment_directory, "#{env_name}.json")).and_return(environment)
61
- allow(File).to receive(:read).with(/metadata\.json$/).and_return('')
62
- allow(Chef::REST).to receive(:new).and_return(rest)
63
- allow(rest).to receive(:get_rest).and_return(server_cookbooks)
64
- allow(Chef::Cookbook::Metadata).to receive(:new).and_return(metadata)
65
- allow(Chef::Knife::CookbookUpload).to receive(:new).and_return(knife)
66
- allow(Dir).to receive(:glob).with(File.expand_path("~/.berkshelf/cookbooks/*")).and_return(berks_cookbooks)
67
- allow(Dir).to receive(:glob).with(File.join(config.cookbook_directory, "*")).and_return(internal_cookbooks)
68
- allow(Dir).to receive(:glob).with(File.join(config.temp_directory, "*")).and_return(internal_cookbooks)
69
- allow(Dir).to receive(:mkdir)
70
- allow(Dir).to receive(:exist?).and_return(false)
71
- allow(knife).to receive(:config).and_return(knife_config)
72
- allow(FileUtils).to receive(:copy_entry)
73
- allow(File).to receive(:exist?).with(/metadata\.rb$/).and_return(true)
74
- }
75
-
76
- it "copies updated cookbooks to temp directory" do
77
- expect(FileUtils).not_to receive(:copy_entry).with("/berks/cookbook1-1.1.1", File.join(config.temp_directory, "cookbook1"))
78
- expect(FileUtils).not_to receive(:copy_entry).with("/berks/cookbook1-1.1.2", File.join(config.temp_directory, "cookbook1"))
79
- expect(FileUtils).not_to receive(:copy_entry).with("/berks/cookbook4-3.3.3", File.join(config.temp_directory, "cookbook4"))
80
- expect(FileUtils).not_to receive(:copy_entry).with("/berks/cookbook2-2.2.2", File.join(config.temp_directory, "cookbook2"))
81
- expect(FileUtils).to receive(:copy_entry).with("/berks/cookbook3-3.3.3", File.join(config.temp_directory, "cookbook3"))
82
- expect(FileUtils).not_to receive(:copy_entry).with("/cookbooks/int_cookbook2", File.join(config.temp_directory, "int_cookbook2"))
83
- expect(FileUtils).not_to receive(:copy_entry).with("/cookbooks/int_cookbook1", File.join(config.temp_directory, "int_cookbook1"))
84
- expect(FileUtils).to receive(:copy_entry).with("/cookbooks/int_cookbook3", File.join(config.temp_directory, "int_cookbook3"))
85
- subject.upload_cookbooks(env_name)
86
- end
87
- it "uploads cookbooks to chef server" do
88
- expect(knife).to receive(:run)
89
-
90
- subject.upload_cookbooks(env_name)
91
- end
92
- it "Creates temp directory" do
93
- expect(Dir).to receive(:mkdir).with(config.temp_directory)
94
-
95
- subject.upload_cookbooks(env_name)
96
- end
97
- it "uploads cookbooks from config temp path" do
98
- subject.upload_cookbooks(env_name)
99
- expect(knife.config[:cookbook_path]).to eq(config.temp_directory)
100
- end
101
- it "uploads all cookbooks" do
102
- subject.upload_cookbooks(env_name)
103
- expect(knife.config[:all]).to eq(true)
104
- end
105
- it "freezes all cookbooks" do
106
- subject.upload_cookbooks(env_name)
107
- expect(knife.config[:freeze]).to eq(true)
108
- end
109
-
110
- context "no environment is given" do
111
- it "copies updated cookbooks and does not filter by environment" do
112
- expect(FileUtils).not_to receive(:copy_entry).with("/berks/cookbook1-1.1.1", File.join(config.temp_directory, "cookbook1"))
113
- expect(FileUtils).to receive(:copy_entry).with("/berks/cookbook1-1.1.2", File.join(config.temp_directory, "cookbook1"))
114
- expect(FileUtils).to receive(:copy_entry).with("/berks/cookbook4-3.3.3", File.join(config.temp_directory, "cookbook4"))
115
- expect(FileUtils).to receive(:copy_entry).with("/berks/cookbook2-2.2.2", File.join(config.temp_directory, "cookbook2"))
116
- expect(FileUtils).to receive(:copy_entry).with("/berks/cookbook3-3.3.3", File.join(config.temp_directory, "cookbook3"))
117
- expect(FileUtils).to receive(:copy_entry).with("/cookbooks/int_cookbook2", File.join(config.temp_directory, "int_cookbook2"))
118
- expect(FileUtils).not_to receive(:copy_entry).with("/cookbooks/int_cookbook1", File.join(config.temp_directory, "int_cookbook1"))
119
- expect(FileUtils).to receive(:copy_entry).with("/cookbooks/int_cookbook3", File.join(config.temp_directory, "int_cookbook3"))
120
- subject.upload_cookbooks
121
- end
122
- end
123
-
124
- context "temp directory already exists" do
125
- before {allow(Dir).to receive(:exist?).and_return(true)}
126
-
127
- it "deletes temp directory" do
128
- expect(FileUtils).to receive(:rm_rf).with(config.temp_directory)
129
- subject.upload_cookbooks(env_name)
130
- end
131
- end
132
-
133
- context "no metadata.rb file exists for cookbook" do
134
- before {allow(File).to receive(:exist?).with(/rb$/).and_return(false)}
135
-
136
- it "loads json instead of ruby file" do
137
- expect(metadata).to receive(:from_json).at_least(1).times
138
- expect(metadata).not_to receive(:from_file)
139
- subject.upload_cookbooks(env_name)
140
- end
141
- end
142
-
143
- context "nothing to upload" do
144
- let(:berks_cookbooks) {[]}
145
- let(:internal_cookbooks) {[]}
146
-
147
- it "does not call knife" do
148
- expect(Chef::Knife::CookbookUpload).not_to receive(:new)
149
-
150
- subject.upload_cookbooks(env_name)
151
- end
152
- end
153
-
154
- context "config missing node_name" do
155
- let(:config) { Promote::Config.new({
156
- :client_key => 'key',
157
- :chef_server_url => 'https://some.chef.server'}) }
158
-
159
- it "raises error that node_name is missing" do
160
- expect{subject.upload_cookbooks(env_name)}.to raise_error(/node_name/)
161
- end
162
- end
163
-
164
- context "config missing client_key" do
165
- let(:config) { Promote::Config.new({
166
- :node_name => 'user',
167
- :chef_server_url => 'https://some.chef.server'}) }
168
-
169
- it "raises error that client_key is missing" do
170
- expect{subject.upload_cookbooks(env_name)}.to raise_error(/client_key/)
171
- end
172
- end
173
-
174
- context "config missing chef_server_url" do
175
- let(:config) { Promote::Config.new({
176
- :node_name => 'user',
177
- :client_key => 'key'}) }
178
-
179
- it "raises error that chef_server_url is missing" do
180
- expect{subject.upload_cookbooks(env_name)}.to raise_error(/chef_server_url/)
181
- end
182
- end
183
- end
184
-
185
- context "upload json artifacts" do
186
- context "upload an environment" do
187
- let(:env_name) { "my_test" }
188
-
189
- it "uploads the environment" do
190
- expect(Chef::ChefFS::FileSystem).to receive(:copy_to).with(an_instance_of(Chef::ChefFS::FilePattern), anything(), anything(), anything(), anything(), anything(), anything()) do |arg|
191
- expect(arg.pattern).to eq(File.join("/environments", "#{env_name}.json"))
192
- end
193
- subject.upload_environment(env_name)
194
- end
195
- end
196
-
197
- context "upload all environments" do
198
- it "uploads the environment" do
199
- local_environments = Chef::ChefFS::Config.new.local_fs.child_paths["environments"]
200
-
201
- expect(Chef::ChefFS::FileSystem).to receive(:copy_to).with(
202
- an_instance_of(Chef::ChefFS::FilePattern),
203
- an_instance_of(Chef::ChefFS::FileSystem::ChefRepositoryFileSystemRootDir),
204
- anything(),
205
- anything(),
206
- anything(),
207
- anything(),
208
- anything()
209
- ) do |file_pattern, source|
210
- expect(file_pattern.pattern).to eq(File.join("/environments/*.json"))
211
- expect(source.child_paths["environments"]).to eq(local_environments)
212
- end
213
- subject.upload_environments
214
- end
215
- end
216
-
217
- context "upload all roles" do
218
- it "uploads the role" do
219
- local_roles = Chef::ChefFS::Config.new.local_fs.child_paths["roles"]
220
-
221
- expect(Chef::ChefFS::FileSystem).to receive(:copy_to).with(
222
- an_instance_of(Chef::ChefFS::FilePattern),
223
- an_instance_of(Chef::ChefFS::FileSystem::ChefRepositoryFileSystemRootDir),
224
- anything(),
225
- anything(),
226
- anything(),
227
- anything(),
228
- anything()
229
- ) do |file_pattern, source|
230
- expect(file_pattern.pattern).to eq(File.join("/roles/*.json"))
231
- expect(source.child_paths["roles"]).to eq(local_roles)
232
- end
233
- subject.upload_roles
234
- end
235
- end
236
-
237
- context "upload_data_bags" do
238
- let(:temp_data_bags) { File.join(config.temp_directory, "data_bags") }
239
- let(:fake_bag_file) { File.join("bags", "bag.json") }
240
- let(:secret_key_file) { File.join("bags", "bag_secrets_keys.json") }
241
- let(:config) { Promote::Config.new({
242
- :temp_directory => "/tmp/promote_tests",
243
- :repo_root => "/tmp/promote_repo",
244
- :node_name => 'user',
245
- :client_key => 'key',
246
- :chef_server_url => 'https://some.chef.server'}) }
247
-
248
- before {
249
- fake_bag_path = File.join(config.data_bag_directory, fake_bag_file)
250
- FileUtils.mkdir_p(File.dirname(fake_bag_path))
251
- FileUtils.touch(fake_bag_path)
252
- FileUtils.touch(File.join(config.data_bag_directory, secret_key_file))
253
- }
254
-
255
- after {
256
- FileUtils.rm_rf(config.temp_directory)
257
- FileUtils.rm_rf(config.repo_root)
258
- }
259
-
260
- it "copies the data_bags to a temp folder" do
261
- subject.upload_data_bags
262
-
263
- expect(File).to exist(File.join(temp_data_bags, fake_bag_file))
264
- end
265
-
266
- it "does not copy key files" do
267
- subject.upload_data_bags
268
-
269
- expect(File).not_to exist(File.join(temp_data_bags, secret_key_file))
270
- end
271
-
272
- it "uploads the data_bags to chef" do
273
- expect(Chef::ChefFS::FileSystem).to receive(:copy_to).with(
274
- an_instance_of(Chef::ChefFS::FilePattern),
275
- an_instance_of(Chef::ChefFS::FileSystem::ChefRepositoryFileSystemRootDir),
276
- anything(),
277
- anything(),
278
- anything(),
279
- anything(),
280
- anything()
281
- ) do |file_pattern, source|
282
- expect(file_pattern.pattern).to eq("/data_bags/**/*.json")
283
- expect(source.child_paths["data_bags"]).to eq([temp_data_bags])
284
- end
285
-
286
- subject.upload_data_bags
287
- end
288
- end
289
- end
5
+ let(:knife_config) {{ :cookbook_path => 'path'}}
6
+ let(:temp_dir) { '/tmp/berks' }
7
+ let(:config) { Promote::Config.new({
8
+ :node_name => 'user',
9
+ :cookbook_directory => '/cookbooks',
10
+ :client_key => 'key',
11
+ :temp_directory => temp_dir,
12
+ :chef_server_url => 'https://some.chef.server'}) }
13
+
14
+ subject { Promote::Uploader.new(config) }
15
+
16
+ before {
17
+ Chef::Config[:chef_repo_path] = config.repo_root
18
+ allow(Chef::ChefFS::FileSystem).to receive(:copy_to)
19
+ }
20
+
21
+ context 'upload cookbooks' do
22
+ let(:env_name) { 'QA1' }
23
+ let(:metadata) { PromoteSpecs::DummyMetadata.new({'version' => '1.1.1'}) }
24
+ let(:environment) do
25
+ <<-EOS
26
+ {
27
+ "name": "#{env_name}",
28
+ "chef_type": "environment",
29
+ "json_class": "Chef::Environment",
30
+ "cookbook_versions": {
31
+ "int_cookbook1": "1.1.1",
32
+ "int_cookbook3": "1.1.1",
33
+ "cookbook3": "3.3.3"
34
+ }
35
+ }
36
+ EOS
37
+ end
38
+ let(:berks_cookbooks) {[
39
+ '/berks/cookbook1-1.1.1',
40
+ '/berks/cookbook1-1.1.2',
41
+ '/berks/cookbook2-2.2.2',
42
+ '/berks/cookbook3-3.3.3',
43
+ '/berks/cookbook4-3.3.3',
44
+ ]}
45
+ let(:internal_cookbooks) {[
46
+ '/cookbooks/int_cookbook1',
47
+ '/cookbooks/int_cookbook2',
48
+ '/cookbooks/int_cookbook3',
49
+ ]}
50
+ let(:server_cookbooks){{
51
+ 'cookbook1' => {'versions' => [{'version' => '1.1.1'}]},
52
+ 'cookbook2' => {'versions' => [{'version' => '1.1.1'}]},
53
+ 'int_cookbook1' => {'versions' => [{'version' => '1.1.1'}]},
54
+ 'int_cookbook2' => {'versions' => [{'version' => '2.2.2'}]}
55
+ }}
56
+ let(:rest){double('rest')}
57
+ let(:knife) { instance_double('CookbookUpload', :run => nil) }
58
+
59
+ before {
60
+ allow(File).to receive(:read).with(File.join(config.environment_directory, "#{env_name}.json")).and_return(environment)
61
+ allow(File).to receive(:read).with(/metadata\.json$/).and_return('')
62
+ allow(Chef::REST).to receive(:new).and_return(rest)
63
+ allow(rest).to receive(:get_rest).and_return(server_cookbooks)
64
+ allow(Chef::Cookbook::Metadata).to receive(:new).and_return(metadata)
65
+ allow(Chef::Knife::CookbookUpload).to receive(:new).and_return(knife)
66
+ allow(Dir).to receive(:glob).with(File.expand_path('~/.berkshelf/cookbooks/*')).and_return(berks_cookbooks)
67
+ allow(Dir).to receive(:glob).with(File.join(config.cookbook_directory, '*')).and_return(internal_cookbooks)
68
+ allow(Dir).to receive(:glob).with(File.join(config.temp_directory, '*')).and_return(internal_cookbooks)
69
+ allow(Dir).to receive(:mkdir)
70
+ allow(Dir).to receive(:exist?).and_return(false)
71
+ allow(knife).to receive(:config).and_return(knife_config)
72
+ allow(FileUtils).to receive(:copy_entry)
73
+ allow(File).to receive(:exist?).with(/metadata\.rb$/).and_return(true)
74
+ }
75
+
76
+ it 'copies updated cookbooks to temp directory' do
77
+ expect(FileUtils).not_to receive(:copy_entry).with('/berks/cookbook1-1.1.1', File.join(config.temp_directory, 'cookbook1'))
78
+ expect(FileUtils).not_to receive(:copy_entry).with('/berks/cookbook1-1.1.2', File.join(config.temp_directory, 'cookbook1'))
79
+ expect(FileUtils).not_to receive(:copy_entry).with('/berks/cookbook4-3.3.3', File.join(config.temp_directory, 'cookbook4'))
80
+ expect(FileUtils).not_to receive(:copy_entry).with('/berks/cookbook2-2.2.2', File.join(config.temp_directory, 'cookbook2'))
81
+ expect(FileUtils).to receive(:copy_entry).with('/berks/cookbook3-3.3.3', File.join(config.temp_directory, 'cookbook3'))
82
+ expect(FileUtils).not_to receive(:copy_entry).with('/cookbooks/int_cookbook2', File.join(config.temp_directory, 'int_cookbook2'))
83
+ expect(FileUtils).not_to receive(:copy_entry).with('/cookbooks/int_cookbook1', File.join(config.temp_directory, 'int_cookbook1'))
84
+ expect(FileUtils).to receive(:copy_entry).with('/cookbooks/int_cookbook3', File.join(config.temp_directory, 'int_cookbook3'))
85
+ subject.upload_cookbooks(env_name)
86
+ end
87
+ it 'uploads cookbooks to chef server' do
88
+ expect(knife).to receive(:run)
89
+
90
+ subject.upload_cookbooks(env_name)
91
+ end
92
+ it 'Creates temp directory' do
93
+ expect(Dir).to receive(:mkdir).with(config.temp_directory)
94
+
95
+ subject.upload_cookbooks(env_name)
96
+ end
97
+ it 'uploads cookbooks from config temp path' do
98
+ subject.upload_cookbooks(env_name)
99
+ expect(knife.config[:cookbook_path]).to eq(config.temp_directory)
100
+ end
101
+ it 'uploads all cookbooks' do
102
+ subject.upload_cookbooks(env_name)
103
+ expect(knife.config[:all]).to eq(true)
104
+ end
105
+ it 'freezes all cookbooks' do
106
+ subject.upload_cookbooks(env_name)
107
+ expect(knife.config[:freeze]).to eq(true)
108
+ end
109
+
110
+ context 'no environment is given' do
111
+ it 'copies updated cookbooks and does not filter by environment' do
112
+ expect(FileUtils).not_to receive(:copy_entry).with('/berks/cookbook1-1.1.1', File.join(config.temp_directory, 'cookbook1'))
113
+ expect(FileUtils).to receive(:copy_entry).with('/berks/cookbook1-1.1.2', File.join(config.temp_directory, 'cookbook1'))
114
+ expect(FileUtils).to receive(:copy_entry).with('/berks/cookbook4-3.3.3', File.join(config.temp_directory, 'cookbook4'))
115
+ expect(FileUtils).to receive(:copy_entry).with('/berks/cookbook2-2.2.2', File.join(config.temp_directory, 'cookbook2'))
116
+ expect(FileUtils).to receive(:copy_entry).with('/berks/cookbook3-3.3.3', File.join(config.temp_directory, 'cookbook3'))
117
+ expect(FileUtils).to receive(:copy_entry).with('/cookbooks/int_cookbook2', File.join(config.temp_directory, 'int_cookbook2'))
118
+ expect(FileUtils).not_to receive(:copy_entry).with('/cookbooks/int_cookbook1', File.join(config.temp_directory, 'int_cookbook1'))
119
+ expect(FileUtils).to receive(:copy_entry).with('/cookbooks/int_cookbook3', File.join(config.temp_directory, 'int_cookbook3'))
120
+ subject.upload_cookbooks
121
+ end
122
+ end
123
+
124
+ context 'temp directory already exists' do
125
+ before {allow(Dir).to receive(:exist?).and_return(true)}
126
+
127
+ it 'deletes temp directory' do
128
+ expect(FileUtils).to receive(:rm_rf).with(config.temp_directory)
129
+ subject.upload_cookbooks(env_name)
130
+ end
131
+ end
132
+
133
+ context 'no metadata.rb file exists for cookbook' do
134
+ before {allow(File).to receive(:exist?).with(/rb$/).and_return(false)}
135
+
136
+ it 'loads json instead of ruby file' do
137
+ expect(metadata).to receive(:from_json).at_least(1).times
138
+ expect(metadata).not_to receive(:from_file)
139
+ subject.upload_cookbooks(env_name)
140
+ end
141
+ end
142
+
143
+ context 'nothing to upload' do
144
+ let(:berks_cookbooks) {[]}
145
+ let(:internal_cookbooks) {[]}
146
+
147
+ it 'does not call knife' do
148
+ expect(Chef::Knife::CookbookUpload).not_to receive(:new)
149
+
150
+ subject.upload_cookbooks(env_name)
151
+ end
152
+ end
153
+
154
+ context 'config missing node_name' do
155
+ let(:config) { Promote::Config.new({
156
+ :client_key => 'key',
157
+ :chef_server_url => 'https://some.chef.server'}) }
158
+
159
+ it 'raises error that node_name is missing' do
160
+ expect{subject.upload_cookbooks(env_name)}.to raise_error(/node_name/)
161
+ end
162
+ end
163
+
164
+ context 'config missing client_key' do
165
+ let(:config) { Promote::Config.new({
166
+ :node_name => 'user',
167
+ :chef_server_url => 'https://some.chef.server'}) }
168
+
169
+ it 'raises error that client_key is missing' do
170
+ expect{subject.upload_cookbooks(env_name)}.to raise_error(/client_key/)
171
+ end
172
+ end
173
+
174
+ context 'config missing chef_server_url' do
175
+ let(:config) { Promote::Config.new({
176
+ :node_name => 'user',
177
+ :client_key => 'key'}) }
178
+
179
+ it 'raises error that chef_server_url is missing' do
180
+ expect{subject.upload_cookbooks(env_name)}.to raise_error(/chef_server_url/)
181
+ end
182
+ end
183
+ end
184
+
185
+ context 'upload json artifacts' do
186
+ context 'upload an environment' do
187
+ let(:env_name) { 'my_test' }
188
+
189
+ it 'uploads the environment' do
190
+ expect(Chef::ChefFS::FileSystem).to receive(:copy_to).with(an_instance_of(Chef::ChefFS::FilePattern), anything(), anything(), anything(), anything(), anything(), anything()) do |arg|
191
+ expect(arg.pattern).to eq(File.join('/environments', "#{env_name}.json"))
192
+ end
193
+ subject.upload_environment(env_name)
194
+ end
195
+ end
196
+
197
+ context 'upload all environments' do
198
+ it 'uploads the environment' do
199
+ local_environments = Chef::ChefFS::Config.new.local_fs.child_paths['environments']
200
+
201
+ expect(Chef::ChefFS::FileSystem).to receive(:copy_to).with(
202
+ an_instance_of(Chef::ChefFS::FilePattern),
203
+ an_instance_of(Chef::ChefFS::FileSystem::ChefRepositoryFileSystemRootDir),
204
+ anything(),
205
+ anything(),
206
+ anything(),
207
+ anything(),
208
+ anything()
209
+ ) do |file_pattern, source|
210
+ expect(file_pattern.pattern).to eq(File.join('/environments/*.json'))
211
+ expect(source.child_paths['environments']).to eq(local_environments)
212
+ end
213
+ subject.upload_environments
214
+ end
215
+ end
216
+
217
+ context 'upload all roles' do
218
+ it 'uploads the role' do
219
+ local_roles = Chef::ChefFS::Config.new.local_fs.child_paths['roles']
220
+
221
+ expect(Chef::ChefFS::FileSystem).to receive(:copy_to).with(
222
+ an_instance_of(Chef::ChefFS::FilePattern),
223
+ an_instance_of(Chef::ChefFS::FileSystem::ChefRepositoryFileSystemRootDir),
224
+ anything(),
225
+ anything(),
226
+ anything(),
227
+ anything(),
228
+ anything()
229
+ ) do |file_pattern, source|
230
+ expect(file_pattern.pattern).to eq(File.join('/roles/*.json'))
231
+ expect(source.child_paths['roles']).to eq(local_roles)
232
+ end
233
+ subject.upload_roles
234
+ end
235
+ end
236
+
237
+ context 'upload_data_bags' do
238
+ let(:temp_data_bags) { File.join(config.temp_directory, 'data_bags') }
239
+ let(:fake_bag_file) { File.join('bags', 'bag.json') }
240
+ let(:secret_key_file) { File.join('bags', 'bag_secrets_keys.json') }
241
+ let(:config) { Promote::Config.new({
242
+ :temp_directory => '/tmp/promote_tests',
243
+ :repo_root => '/tmp/promote_repo',
244
+ :node_name => 'user',
245
+ :client_key => 'key',
246
+ :chef_server_url => 'https://some.chef.server'}) }
247
+
248
+ before {
249
+ fake_bag_path = File.join(config.data_bag_directory, fake_bag_file)
250
+ FileUtils.mkdir_p(File.dirname(fake_bag_path))
251
+ FileUtils.touch(fake_bag_path)
252
+ FileUtils.touch(File.join(config.data_bag_directory, secret_key_file))
253
+ }
254
+
255
+ after {
256
+ FileUtils.rm_rf(config.temp_directory)
257
+ FileUtils.rm_rf(config.repo_root)
258
+ }
259
+
260
+ it 'copies the data_bags to a temp folder' do
261
+ subject.upload_data_bags
262
+
263
+ expect(File).to exist(File.join(temp_data_bags, fake_bag_file))
264
+ end
265
+
266
+ it 'does not copy key files' do
267
+ subject.upload_data_bags
268
+
269
+ expect(File).not_to exist(File.join(temp_data_bags, secret_key_file))
270
+ end
271
+
272
+ it 'uploads the data_bags to chef' do
273
+ expect(Chef::ChefFS::FileSystem).to receive(:copy_to).with(
274
+ an_instance_of(Chef::ChefFS::FilePattern),
275
+ an_instance_of(Chef::ChefFS::FileSystem::ChefRepositoryFileSystemRootDir),
276
+ anything(),
277
+ anything(),
278
+ anything(),
279
+ anything(),
280
+ anything()
281
+ ) do |file_pattern, source|
282
+ expect(file_pattern.pattern).to eq('/data_bags/**/*.json')
283
+ expect(source.child_paths['data_bags']).to eq([temp_data_bags])
284
+ end
285
+
286
+ subject.upload_data_bags
287
+ end
288
+ end
289
+ end
290
290
  end