knife-essentials 0.9.2 → 0.9.3

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.
@@ -6,27 +6,28 @@ describe 'knife upload' do
6
6
  extend IntegrationSupport
7
7
  include KnifeSupport
8
8
 
9
- when_the_chef_server "has one of each thing" do
10
- client 'x', '{}'
11
- cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"' }
12
- data_bag 'x', { 'y' => '{}' }
13
- environment 'x', '{}'
14
- node 'x', '{}'
15
- role 'x', '{}'
16
- user 'x', '{}'
17
-
18
- when_the_repository 'has only top-level directories' do
19
- directory 'clients'
20
- directory 'cookbooks'
21
- directory 'data_bags'
22
- directory 'environments'
23
- directory 'nodes'
24
- directory 'roles'
25
- directory 'users'
26
-
27
- it 'knife upload does nothing' do
28
- knife('upload /').should_succeed ''
29
- knife('diff --name-status /').should_succeed <<EOM
9
+ context 'without versioned cookbooks' do
10
+ when_the_chef_server "has one of each thing" do
11
+ client 'x', '{}'
12
+ cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"' }
13
+ data_bag 'x', { 'y' => '{}' }
14
+ environment 'x', '{}'
15
+ node 'x', '{}'
16
+ role 'x', '{}'
17
+ user 'x', '{}'
18
+
19
+ when_the_repository 'has only top-level directories' do
20
+ directory 'clients'
21
+ directory 'cookbooks'
22
+ directory 'data_bags'
23
+ directory 'environments'
24
+ directory 'nodes'
25
+ directory 'roles'
26
+ directory 'users'
27
+
28
+ it 'knife upload does nothing' do
29
+ knife('upload /').should_succeed ''
30
+ knife('diff --name-status /').should_succeed <<EOM
30
31
  D\t/cookbooks/x
31
32
  D\t/data_bags/x
32
33
  D\t/environments/_default.json
@@ -46,19 +47,19 @@ EOM
46
47
  D\t/environments/_default.json
47
48
  EOM
48
49
  end
49
- end
50
+ end
50
51
 
51
- when_the_repository 'has an identical copy of each thing' do
52
- file 'clients/x.json', <<EOM
52
+ when_the_repository 'has an identical copy of each thing' do
53
+ file 'clients/x.json', <<EOM
53
54
  {}
54
55
  EOM
55
- file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
56
- file 'data_bags/x/y.json', <<EOM
56
+ file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
57
+ file 'data_bags/x/y.json', <<EOM
57
58
  {
58
59
  "id": "y"
59
60
  }
60
61
  EOM
61
- file 'environments/_default.json', <<EOM
62
+ file 'environments/_default.json', <<EOM
62
63
  {
63
64
  "name": "_default",
64
65
  "description": "The default Chef environment",
@@ -72,7 +73,7 @@ EOM
72
73
  }
73
74
  }
74
75
  EOM
75
- file 'environments/x.json', <<EOM
76
+ file 'environments/x.json', <<EOM
76
77
  {
77
78
  "chef_type": "environment",
78
79
  "cookbook_versions": {
@@ -86,10 +87,10 @@ EOM
86
87
  }
87
88
  }
88
89
  EOM
89
- file 'nodes/x.json', <<EOM
90
+ file 'nodes/x.json', <<EOM
90
91
  {}
91
92
  EOM
92
- file 'roles/x.json', <<EOM
93
+ file 'roles/x.json', <<EOM
93
94
  {
94
95
  "chef_type": "role",
95
96
  "default_attributes": {
@@ -106,22 +107,22 @@ EOM
106
107
  ]
107
108
  }
108
109
  EOM
109
- file 'users/x.json', <<EOM
110
+ file 'users/x.json', <<EOM
110
111
  {}
111
112
  EOM
112
113
 
113
- it 'knife upload makes no changes' do
114
- knife('upload /cookbooks/x').should_succeed ''
115
- knife('diff --name-status /').should_succeed ''
116
- end
114
+ it 'knife upload makes no changes' do
115
+ knife('upload /cookbooks/x').should_succeed ''
116
+ knife('diff --name-status /').should_succeed ''
117
+ end
117
118
 
118
- it 'knife upload --purge makes no changes' do
119
- knife('upload --purge /').should_succeed ''
120
- knife('diff --name-status /').should_succeed ''
121
- end
119
+ it 'knife upload --purge makes no changes' do
120
+ knife('upload --purge /').should_succeed ''
121
+ knife('diff --name-status /').should_succeed ''
122
+ end
122
123
 
123
- context 'except the role file' do
124
- file 'roles/x.json', <<EOM
124
+ context 'except the role file' do
125
+ file 'roles/x.json', <<EOM
125
126
  {
126
127
  "chef_type": "role",
127
128
  "default_attributes": {
@@ -138,14 +139,14 @@ EOM
138
139
  ]
139
140
  }
140
141
  EOM
141
- it 'knife upload changes the role' do
142
- knife('upload /').should_succeed "Updated /roles/x.json\n"
143
- knife('diff --name-status /').should_succeed ''
142
+ it 'knife upload changes the role' do
143
+ knife('upload /').should_succeed "Updated /roles/x.json\n"
144
+ knife('diff --name-status /').should_succeed ''
145
+ end
144
146
  end
145
- end
146
147
 
147
- context 'except the role file is textually different, but not ACTUALLY different' do
148
- file 'roles/x.json', <<EOM
148
+ context 'except the role file is textually different, but not ACTUALLY different' do
149
+ file 'roles/x.json', <<EOM
149
150
  {
150
151
  "chef_type": "role",
151
152
  "default_attributes": {
@@ -162,27 +163,27 @@ EOM
162
163
  ]
163
164
  }
164
165
  EOM
165
- it 'knife upload / does not change anything' do
166
- knife('upload /').should_succeed ''
167
- knife('diff --name-status /').should_succeed ''
166
+ it 'knife upload / does not change anything' do
167
+ knife('upload /').should_succeed ''
168
+ knife('diff --name-status /').should_succeed ''
169
+ end
168
170
  end
169
- end
170
171
 
171
- context 'as well as one extra copy of each thing' do
172
- file 'clients/y.json', { 'name' => 'y' }
173
- file 'cookbooks/x/blah.rb', ''
174
- file 'cookbooks/y/metadata.rb', 'version "1.0.0"'
175
- file 'data_bags/x/z.json', <<EOM
172
+ context 'as well as one extra copy of each thing' do
173
+ file 'clients/y.json', { 'name' => 'y' }
174
+ file 'cookbooks/x/blah.rb', ''
175
+ file 'cookbooks/y/metadata.rb', 'version "1.0.0"'
176
+ file 'data_bags/x/z.json', <<EOM
176
177
  {
177
178
  "id": "z"
178
179
  }
179
180
  EOM
180
- file 'data_bags/y/zz.json', <<EOM
181
+ file 'data_bags/y/zz.json', <<EOM
181
182
  {
182
183
  "id": "zz"
183
184
  }
184
185
  EOM
185
- file 'environments/y.json', <<EOM
186
+ file 'environments/y.json', <<EOM
186
187
  {
187
188
  "chef_type": "environment",
188
189
  "cookbook_versions": {
@@ -196,8 +197,8 @@ EOM
196
197
  }
197
198
  }
198
199
  EOM
199
- file 'nodes/y.json', { 'name' => 'y' }
200
- file 'roles/y.json', <<EOM
200
+ file 'nodes/y.json', { 'name' => 'y' }
201
+ file 'roles/y.json', <<EOM
201
202
  {
202
203
  "chef_type": "role",
203
204
  "default_attributes": {
@@ -214,10 +215,10 @@ EOM
214
215
  ]
215
216
  }
216
217
  EOM
217
- file 'users/y.json', { 'name' => 'y' }
218
+ file 'users/y.json', { 'name' => 'y' }
218
219
 
219
- it 'knife upload adds the new files' do
220
- knife('upload /').should_succeed <<EOM
220
+ it 'knife upload adds the new files' do
221
+ knife('upload /').should_succeed <<EOM
221
222
  Updated /cookbooks/x
222
223
  Created /cookbooks/y
223
224
  Created /data_bags/x/z.json
@@ -226,352 +227,921 @@ Created /data_bags/y/zz.json
226
227
  Created /environments/y.json
227
228
  Created /roles/y.json
228
229
  EOM
229
- knife('diff --name-status /').should_succeed ''
230
+ knife('diff --name-status /').should_succeed ''
231
+ end
230
232
  end
231
233
  end
232
- end
233
234
 
234
- when_the_repository 'is empty' do
235
- it 'knife upload does nothing' do
236
- knife('upload /').should_succeed ''
237
- knife('diff --name-status /').should_succeed <<EOM
235
+ when_the_repository 'is empty' do
236
+ it 'knife upload does nothing' do
237
+ knife('upload /').should_succeed ''
238
+ knife('diff --name-status /').should_succeed <<EOM
238
239
  D\t/cookbooks
239
240
  D\t/data_bags
240
241
  D\t/environments
241
242
  D\t/roles
242
243
  EOM
243
- end
244
+ end
244
245
 
245
- it 'knife upload --purge deletes nothing' do
246
- knife('upload --purge /').should_fail <<EOM
246
+ it 'knife upload --purge deletes nothing' do
247
+ knife('upload --purge /').should_fail <<EOM
247
248
  ERROR: /cookbooks cannot be deleted.
248
249
  ERROR: /data_bags cannot be deleted.
249
250
  ERROR: /environments cannot be deleted.
250
251
  ERROR: /roles cannot be deleted.
251
252
  EOM
252
- knife('diff --name-status /').should_succeed <<EOM
253
+ knife('diff --name-status /').should_succeed <<EOM
253
254
  D\t/cookbooks
254
255
  D\t/data_bags
255
256
  D\t/environments
256
257
  D\t/roles
257
258
  EOM
258
- end
259
+ end
259
260
 
260
- context 'when current directory is top level' do
261
- cwd '.'
262
- it 'knife upload with no parameters reports an error' do
263
- knife('upload').should_fail "FATAL: Must specify at least one argument. If you want to upload everything in this directory, type \"knife upload .\"\n", :stdout => /USAGE/
261
+ context 'when current directory is top level' do
262
+ cwd '.'
263
+ it 'knife upload with no parameters reports an error' do
264
+ knife('upload').should_fail "FATAL: Must specify at least one argument. If you want to upload everything in this directory, type \"knife upload .\"\n", :stdout => /USAGE/
265
+ end
264
266
  end
265
267
  end
266
268
  end
267
- end
268
269
 
269
- # Test upload of an item when the other end doesn't even have the container
270
- when_the_chef_server 'is empty' do
271
- when_the_repository 'has two data bag items' do
272
- file 'data_bags/x/y.json', <<EOM
270
+ # Test upload of an item when the other end doesn't even have the container
271
+ when_the_chef_server 'is empty' do
272
+ when_the_repository 'has two data bag items' do
273
+ file 'data_bags/x/y.json', <<EOM
273
274
  {
274
275
  "id": "y"
275
276
  }
276
277
  EOM
277
- file 'data_bags/x/z.json', <<EOM
278
+ file 'data_bags/x/z.json', <<EOM
278
279
  {
279
280
  "id": "z"
280
281
  }
281
282
  EOM
282
- it 'knife upload of one data bag item itself succeeds' do
283
- knife('upload /data_bags/x/y.json').should_succeed <<EOM
283
+ it 'knife upload of one data bag item itself succeeds' do
284
+ knife('upload /data_bags/x/y.json').should_succeed <<EOM
284
285
  Created /data_bags/x
285
286
  Created /data_bags/x/y.json
286
287
  EOM
287
- knife('diff --name-status /data_bags').should_succeed <<EOM
288
+ knife('diff --name-status /data_bags').should_succeed <<EOM
288
289
  A\t/data_bags/x/z.json
289
290
  EOM
291
+ end
290
292
  end
291
293
  end
292
- end
293
294
 
294
- when_the_chef_server 'has three data bag items' do
295
- data_bag 'x', { 'deleted' => {}, 'modified' => {}, 'unmodified' => {} }
296
- when_the_repository 'has a modified, unmodified, added and deleted data bag item' do
297
- file 'data_bags/x/added.json', <<EOM
295
+ when_the_chef_server 'has three data bag items' do
296
+ data_bag 'x', { 'deleted' => {}, 'modified' => {}, 'unmodified' => {} }
297
+ when_the_repository 'has a modified, unmodified, added and deleted data bag item' do
298
+ file 'data_bags/x/added.json', <<EOM
298
299
  {
299
300
  "id": "added"
300
301
  }
301
302
  EOM
302
- file 'data_bags/x/modified.json', <<EOM
303
+ file 'data_bags/x/modified.json', <<EOM
303
304
  {
304
305
  "id": "modified",
305
306
  "foo": "bar"
306
307
  }
307
308
  EOM
308
- file 'data_bags/x/unmodified.json', <<EOM
309
+ file 'data_bags/x/unmodified.json', <<EOM
309
310
  {
310
311
  "id": "unmodified"
311
312
  }
312
313
  EOM
313
- it 'knife upload of the modified file succeeds' do
314
- knife('upload /data_bags/x/modified.json').should_succeed <<EOM
314
+ it 'knife upload of the modified file succeeds' do
315
+ knife('upload /data_bags/x/modified.json').should_succeed <<EOM
315
316
  Updated /data_bags/x/modified.json
316
317
  EOM
317
- knife('diff --name-status /data_bags').should_succeed <<EOM
318
+ knife('diff --name-status /data_bags').should_succeed <<EOM
318
319
  D\t/data_bags/x/deleted.json
319
320
  A\t/data_bags/x/added.json
320
321
  EOM
321
- end
322
- it 'knife upload of the unmodified file does nothing' do
323
- knife('upload /data_bags/x/unmodified.json').should_succeed ''
324
- knife('diff --name-status /data_bags').should_succeed <<EOM
322
+ end
323
+ it 'knife upload of the unmodified file does nothing' do
324
+ knife('upload /data_bags/x/unmodified.json').should_succeed ''
325
+ knife('diff --name-status /data_bags').should_succeed <<EOM
325
326
  D\t/data_bags/x/deleted.json
326
327
  M\t/data_bags/x/modified.json
327
328
  A\t/data_bags/x/added.json
328
329
  EOM
329
- end
330
- it 'knife upload of the added file succeeds' do
331
- knife('upload /data_bags/x/added.json').should_succeed <<EOM
330
+ end
331
+ it 'knife upload of the added file succeeds' do
332
+ knife('upload /data_bags/x/added.json').should_succeed <<EOM
332
333
  Created /data_bags/x/added.json
333
334
  EOM
334
- knife('diff --name-status /data_bags').should_succeed <<EOM
335
+ knife('diff --name-status /data_bags').should_succeed <<EOM
335
336
  D\t/data_bags/x/deleted.json
336
337
  M\t/data_bags/x/modified.json
337
338
  EOM
338
- end
339
- it 'knife upload of the deleted file does nothing' do
340
- knife('upload /data_bags/x/deleted.json').should_succeed ''
341
- knife('diff --name-status /data_bags').should_succeed <<EOM
339
+ end
340
+ it 'knife upload of the deleted file does nothing' do
341
+ knife('upload /data_bags/x/deleted.json').should_succeed ''
342
+ knife('diff --name-status /data_bags').should_succeed <<EOM
342
343
  D\t/data_bags/x/deleted.json
343
344
  M\t/data_bags/x/modified.json
344
345
  A\t/data_bags/x/added.json
345
346
  EOM
346
- end
347
- it 'knife upload --purge of the deleted file deletes it' do
348
- knife('upload --purge /data_bags/x/deleted.json').should_succeed <<EOM
347
+ end
348
+ it 'knife upload --purge of the deleted file deletes it' do
349
+ knife('upload --purge /data_bags/x/deleted.json').should_succeed <<EOM
349
350
  Deleted extra entry /data_bags/x/deleted.json (purge is on)
350
351
  EOM
351
- knife('diff --name-status /data_bags').should_succeed <<EOM
352
+ knife('diff --name-status /data_bags').should_succeed <<EOM
352
353
  M\t/data_bags/x/modified.json
353
354
  A\t/data_bags/x/added.json
354
355
  EOM
355
- end
356
- it 'knife upload of the entire data bag uploads everything' do
357
- knife('upload /data_bags/x').should_succeed <<EOM
356
+ end
357
+ it 'knife upload of the entire data bag uploads everything' do
358
+ knife('upload /data_bags/x').should_succeed <<EOM
358
359
  Created /data_bags/x/added.json
359
360
  Updated /data_bags/x/modified.json
360
361
  EOM
361
- knife('diff --name-status /data_bags').should_succeed <<EOM
362
+ knife('diff --name-status /data_bags').should_succeed <<EOM
362
363
  D\t/data_bags/x/deleted.json
363
364
  EOM
364
- end
365
- it 'knife upload --purge of the entire data bag uploads everything' do
366
- knife('upload --purge /data_bags/x').should_succeed <<EOM
365
+ end
366
+ it 'knife upload --purge of the entire data bag uploads everything' do
367
+ knife('upload --purge /data_bags/x').should_succeed <<EOM
367
368
  Created /data_bags/x/added.json
368
369
  Updated /data_bags/x/modified.json
369
370
  Deleted extra entry /data_bags/x/deleted.json (purge is on)
370
371
  EOM
371
- knife('diff --name-status /data_bags').should_succeed ''
372
- end
373
- context 'when cwd is the /data_bags directory' do
374
- cwd 'data_bags'
375
- it 'knife upload fails' do
376
- knife('upload').should_fail "FATAL: Must specify at least one argument. If you want to upload everything in this directory, type \"knife upload .\"\n", :stdout => /USAGE/
372
+ knife('diff --name-status /data_bags').should_succeed ''
377
373
  end
378
- it 'knife upload --purge . uploads everything' do
379
- knife('upload --purge .').should_succeed <<EOM
374
+ context 'when cwd is the /data_bags directory' do
375
+ cwd 'data_bags'
376
+ it 'knife upload fails' do
377
+ knife('upload').should_fail "FATAL: Must specify at least one argument. If you want to upload everything in this directory, type \"knife upload .\"\n", :stdout => /USAGE/
378
+ end
379
+ it 'knife upload --purge . uploads everything' do
380
+ knife('upload --purge .').should_succeed <<EOM
380
381
  Created x/added.json
381
382
  Updated x/modified.json
382
383
  Deleted extra entry x/deleted.json (purge is on)
383
384
  EOM
384
- knife('diff --name-status /data_bags').should_succeed ''
385
- end
386
- it 'knife upload --purge * uploads everything' do
387
- knife('upload --purge *').should_succeed <<EOM
385
+ knife('diff --name-status /data_bags').should_succeed ''
386
+ end
387
+ it 'knife upload --purge * uploads everything' do
388
+ knife('upload --purge *').should_succeed <<EOM
388
389
  Created x/added.json
389
390
  Updated x/modified.json
390
391
  Deleted extra entry x/deleted.json (purge is on)
391
392
  EOM
392
- knife('diff --name-status /data_bags').should_succeed ''
393
+ knife('diff --name-status /data_bags').should_succeed ''
394
+ end
393
395
  end
394
396
  end
395
397
  end
396
- end
397
-
398
- # Cookbook upload is a funny thing ... direct cookbook upload works, but
399
- # upload of a file is designed not to work at present. Make sure that is the
400
- # case.
401
- when_the_chef_server 'has a cookbook' do
402
- cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"', 'z.rb' => '' }
403
- when_the_repository 'has a modified, extra and missing file for the cookbook' do
404
- file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
405
- file 'cookbooks/x/y.rb', 'hi'
406
- it 'knife upload of any individual file fails' do
407
- knife('upload /cookbooks/x/metadata.rb').should_fail "ERROR: /cookbooks/x/metadata.rb cannot be updated.\n"
408
- knife('upload /cookbooks/x/y.rb').should_fail "ERROR: /cookbooks/x cannot have a child created under it.\n"
409
- knife('upload --purge /cookbooks/x/z.rb').should_fail "ERROR: /cookbooks/x/z.rb cannot be deleted.\n"
410
- end
411
- # TODO this is a bit of an inconsistency: if we didn't specify --purge,
412
- # technically we shouldn't have deleted missing files. But ... cookbooks
413
- # are a special case.
414
- it 'knife upload of the cookbook itself succeeds' do
415
- knife('upload /cookbooks/x').should_succeed <<EOM
398
+
399
+ # Cookbook upload is a funny thing ... direct cookbook upload works, but
400
+ # upload of a file is designed not to work at present. Make sure that is the
401
+ # case.
402
+ when_the_chef_server 'has a cookbook' do
403
+ cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"', 'z.rb' => '' }
404
+ when_the_repository 'has a modified, extra and missing file for the cookbook' do
405
+ file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
406
+ file 'cookbooks/x/y.rb', 'hi'
407
+ it 'knife upload of any individual file fails' do
408
+ knife('upload /cookbooks/x/metadata.rb').should_fail "ERROR: /cookbooks/x/metadata.rb cannot be updated.\n"
409
+ knife('upload /cookbooks/x/y.rb').should_fail "ERROR: /cookbooks/x cannot have a child created under it.\n"
410
+ knife('upload --purge /cookbooks/x/z.rb').should_fail "ERROR: /cookbooks/x/z.rb cannot be deleted.\n"
411
+ end
412
+ # TODO this is a bit of an inconsistency: if we didn't specify --purge,
413
+ # technically we shouldn't have deleted missing files. But ... cookbooks
414
+ # are a special case.
415
+ it 'knife upload of the cookbook itself succeeds' do
416
+ knife('upload /cookbooks/x').should_succeed <<EOM
416
417
  Updated /cookbooks/x
417
418
  EOM
418
- knife('diff --name-status /cookbooks').should_succeed ''
419
- end
420
- it 'knife upload --purge of the cookbook itself succeeds' do
421
- knife('upload /cookbooks/x').should_succeed <<EOM
419
+ knife('diff --name-status /cookbooks').should_succeed ''
420
+ end
421
+ it 'knife upload --purge of the cookbook itself succeeds' do
422
+ knife('upload /cookbooks/x').should_succeed <<EOM
422
423
  Updated /cookbooks/x
423
424
  EOM
424
- knife('diff --name-status /cookbooks').should_succeed ''
425
+ knife('diff --name-status /cookbooks').should_succeed ''
426
+ end
425
427
  end
426
- end
427
- when_the_repository 'has a missing file for the cookbook' do
428
- file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
429
- it 'knife upload of the cookbook succeeds' do
430
- knife('upload /cookbooks/x').should_succeed <<EOM
428
+ when_the_repository 'has a missing file for the cookbook' do
429
+ file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
430
+ it 'knife upload of the cookbook succeeds' do
431
+ knife('upload /cookbooks/x').should_succeed <<EOM
431
432
  Updated /cookbooks/x
432
433
  EOM
433
- knife('diff --name-status /cookbooks').should_succeed ''
434
+ knife('diff --name-status /cookbooks').should_succeed ''
435
+ end
434
436
  end
435
- end
436
- when_the_repository 'has an extra file for the cookbook' do
437
- file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
438
- file 'cookbooks/x/z.rb', ''
439
- file 'cookbooks/x/blah.rb', ''
440
- it 'knife upload of the cookbook succeeds' do
441
- knife('upload /cookbooks/x').should_succeed <<EOM
437
+ when_the_repository 'has an extra file for the cookbook' do
438
+ file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
439
+ file 'cookbooks/x/z.rb', ''
440
+ file 'cookbooks/x/blah.rb', ''
441
+ it 'knife upload of the cookbook succeeds' do
442
+ knife('upload /cookbooks/x').should_succeed <<EOM
442
443
  Updated /cookbooks/x
443
444
  EOM
444
- knife('diff --name-status /cookbooks').should_succeed ''
445
+ knife('diff --name-status /cookbooks').should_succeed ''
446
+ end
445
447
  end
446
448
  end
447
- end
448
449
 
449
- when_the_repository 'has a cookbook' do
450
- file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
451
- file 'cookbooks/x/onlyin1.0.0.rb', 'old_text'
450
+ when_the_repository 'has a cookbook' do
451
+ file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
452
+ file 'cookbooks/x/onlyin1.0.0.rb', 'old_text'
452
453
 
453
- when_the_chef_server 'has a later version for the cookbook' do
454
- cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"', 'onlyin1.0.0.rb' => '' }
455
- cookbook 'x', '1.0.1', { 'metadata.rb' => 'version "1.0.1"', 'onlyin1.0.1.rb' => 'hi' }
454
+ when_the_chef_server 'has a later version for the cookbook' do
455
+ cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"', 'onlyin1.0.0.rb' => '' }
456
+ cookbook 'x', '1.0.1', { 'metadata.rb' => 'version "1.0.1"', 'onlyin1.0.1.rb' => 'hi' }
456
457
 
457
- it 'knife upload /cookbooks/x uploads the local version' do
458
- knife('diff --name-status /cookbooks').should_succeed <<EOM
458
+ it 'knife upload /cookbooks/x uploads the local version' do
459
+ knife('diff --name-status /cookbooks').should_succeed <<EOM
459
460
  M\t/cookbooks/x/metadata.rb
460
461
  D\t/cookbooks/x/onlyin1.0.1.rb
461
462
  A\t/cookbooks/x/onlyin1.0.0.rb
462
463
  EOM
463
- knife('upload --purge /cookbooks/x').should_succeed <<EOM
464
+ knife('upload --purge /cookbooks/x').should_succeed <<EOM
464
465
  Updated /cookbooks/x
465
466
  EOM
466
- knife('diff --name-status /cookbooks').should_succeed <<EOM
467
+ knife('diff --name-status /cookbooks').should_succeed <<EOM
467
468
  M\t/cookbooks/x/metadata.rb
468
469
  D\t/cookbooks/x/onlyin1.0.1.rb
469
470
  A\t/cookbooks/x/onlyin1.0.0.rb
470
471
  EOM
472
+ end
471
473
  end
472
- end
473
474
 
474
- when_the_chef_server 'has an earlier version for the cookbook' do
475
- cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"', 'onlyin1.0.0.rb' => ''}
476
- cookbook 'x', '0.9.9', { 'metadata.rb' => 'version "0.9.9"', 'onlyin0.9.9.rb' => 'hi' }
477
- it 'knife upload /cookbooks/x uploads the local version' do
478
- knife('upload --purge /cookbooks/x').should_succeed <<EOM
475
+ when_the_chef_server 'has an earlier version for the cookbook' do
476
+ cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"', 'onlyin1.0.0.rb' => ''}
477
+ cookbook 'x', '0.9.9', { 'metadata.rb' => 'version "0.9.9"', 'onlyin0.9.9.rb' => 'hi' }
478
+ it 'knife upload /cookbooks/x uploads the local version' do
479
+ knife('upload --purge /cookbooks/x').should_succeed <<EOM
479
480
  Updated /cookbooks/x
480
481
  EOM
481
- knife('diff --name-status /cookbooks').should_succeed ''
482
+ knife('diff --name-status /cookbooks').should_succeed ''
483
+ end
482
484
  end
483
- end
484
485
 
485
- when_the_chef_server 'has a later version for the cookbook, and no current version' do
486
- cookbook 'x', '1.0.1', { 'metadata.rb' => 'version "1.0.1"', 'onlyin1.0.1.rb' => 'hi' }
486
+ when_the_chef_server 'has a later version for the cookbook, and no current version' do
487
+ cookbook 'x', '1.0.1', { 'metadata.rb' => 'version "1.0.1"', 'onlyin1.0.1.rb' => 'hi' }
487
488
 
488
- it 'knife upload /cookbooks/x uploads the local version' do
489
- knife('diff --name-status /cookbooks').should_succeed <<EOM
489
+ it 'knife upload /cookbooks/x uploads the local version' do
490
+ knife('diff --name-status /cookbooks').should_succeed <<EOM
490
491
  M\t/cookbooks/x/metadata.rb
491
492
  D\t/cookbooks/x/onlyin1.0.1.rb
492
493
  A\t/cookbooks/x/onlyin1.0.0.rb
493
494
  EOM
494
- knife('upload --purge /cookbooks/x').should_succeed <<EOM
495
+ knife('upload --purge /cookbooks/x').should_succeed <<EOM
495
496
  Updated /cookbooks/x
496
497
  EOM
497
- knife('diff --name-status /cookbooks').should_succeed <<EOM
498
+ knife('diff --name-status /cookbooks').should_succeed <<EOM
498
499
  M\t/cookbooks/x/metadata.rb
499
500
  D\t/cookbooks/x/onlyin1.0.1.rb
500
501
  A\t/cookbooks/x/onlyin1.0.0.rb
501
502
  EOM
503
+ end
502
504
  end
503
- end
504
505
 
505
- when_the_chef_server 'has an earlier version for the cookbook, and no current version' do
506
- cookbook 'x', '0.9.9', { 'metadata.rb' => 'version "0.9.9"', 'onlyin0.9.9.rb' => 'hi' }
506
+ when_the_chef_server 'has an earlier version for the cookbook, and no current version' do
507
+ cookbook 'x', '0.9.9', { 'metadata.rb' => 'version "0.9.9"', 'onlyin0.9.9.rb' => 'hi' }
507
508
 
508
- it 'knife upload /cookbooks/x uploads the new version' do
509
- knife('upload --purge /cookbooks/x').should_succeed <<EOM
509
+ it 'knife upload /cookbooks/x uploads the new version' do
510
+ knife('upload --purge /cookbooks/x').should_succeed <<EOM
510
511
  Updated /cookbooks/x
511
512
  EOM
512
- knife('diff --name-status /cookbooks').should_succeed ''
513
+ knife('diff --name-status /cookbooks').should_succeed ''
514
+ end
513
515
  end
514
516
  end
515
- end
516
517
 
517
- when_the_chef_server 'has an environment' do
518
- environment 'x', {}
519
- when_the_repository 'has an environment with bad JSON' do
520
- file 'environments/x.json', '{'
521
- it 'knife upload tries and fails' do
522
- knife('upload /environments/x.json').should_fail "WARN: Parse error reading #{path_to('environments/x.json')} as JSON: A JSON text must at least contain two octets!\nERROR: /environments/x.json failed to write: Parse error reading JSON: A JSON text must at least contain two octets!\n"
523
- knife('diff --name-status /environments/x.json').should_succeed "M\t/environments/x.json\n", :stderr => "WARN: Parse error reading #{path_to('environments/x.json')} as JSON: A JSON text must at least contain two octets!\n"
518
+ when_the_chef_server 'has an environment' do
519
+ environment 'x', {}
520
+ when_the_repository 'has an environment with bad JSON' do
521
+ file 'environments/x.json', '{'
522
+ it 'knife upload tries and fails' do
523
+ knife('upload /environments/x.json').should_fail "WARN: Parse error reading #{path_to('environments/x.json')} as JSON: A JSON text must at least contain two octets!\nERROR: /environments/x.json failed to write: Parse error reading JSON: A JSON text must at least contain two octets!\n"
524
+ knife('diff --name-status /environments/x.json').should_succeed "M\t/environments/x.json\n", :stderr => "WARN: Parse error reading #{path_to('environments/x.json')} as JSON: A JSON text must at least contain two octets!\n"
525
+ end
526
+ end
527
+
528
+ when_the_repository 'has the same environment with the wrong name in the file' do
529
+ file 'environments/x.json', { 'name' => 'y' }
530
+ it 'knife upload fails' do
531
+ knife('upload /environments/x.json').should_fail "ERROR: /environments/x.json failed to write: Name in remote/environments/x.json/x.json must be 'x' (is 'y')\n"
532
+ knife('diff --name-status /environments/x.json').should_succeed "M\t/environments/x.json\n"
533
+ end
534
+ end
535
+
536
+ when_the_repository 'has the same environment with no name in the file' do
537
+ file 'environments/x.json', { 'description' => 'hi' }
538
+ it 'knife upload succeeds' do
539
+ knife('upload /environments/x.json').should_succeed "Updated /environments/x.json\n"
540
+ knife('diff --name-status /environments/x.json').should_succeed ''
541
+ end
524
542
  end
525
543
  end
526
544
 
527
- when_the_repository 'has the same environment with the wrong name in the file' do
528
- file 'environments/x.json', { 'name' => 'y' }
529
- it 'knife upload fails' do
530
- knife('upload /environments/x.json').should_fail "ERROR: /environments/x.json failed to write: Name in remote/environments/x.json/x.json must be 'x' (is 'y')\n"
531
- knife('diff --name-status /environments/x.json').should_succeed "M\t/environments/x.json\n"
545
+ when_the_chef_server 'is empty' do
546
+ when_the_repository 'has an environment with bad JSON' do
547
+ file 'environments/x.json', '{'
548
+ it 'knife upload tries and fails' do
549
+ knife('upload /environments/x.json').should_fail "ERROR: /environments failed to create_child: Parse error reading JSON creating child 'x.json': A JSON text must at least contain two octets!\n"
550
+ knife('diff --name-status /environments/x.json').should_succeed "A\t/environments/x.json\n"
551
+ end
552
+ end
553
+
554
+ when_the_repository 'has an environment with the wrong name in the file' do
555
+ file 'environments/x.json', { 'name' => 'y' }
556
+ it 'knife upload fails' do
557
+ knife('upload /environments/x.json').should_fail "ERROR: /environments failed to create_child: Name in remote/environments/x.json must be 'x' (is 'y')\n"
558
+ knife('diff --name-status /environments/x.json').should_succeed "A\t/environments/x.json\n"
559
+ end
560
+ end
561
+
562
+ when_the_repository 'has an environment with no name in the file' do
563
+ file 'environments/x.json', { 'description' => 'hi' }
564
+ it 'knife upload succeeds' do
565
+ knife('upload /environments/x.json').should_succeed "Created /environments/x.json\n"
566
+ knife('diff --name-status /environments/x.json').should_succeed ''
567
+ end
568
+ end
569
+
570
+ when_the_repository 'has a data bag with no id in the file' do
571
+ file 'data_bags/bag/x.json', { 'foo' => 'bar' }
572
+ it 'knife upload succeeds' do
573
+ knife('upload /data_bags/bag/x.json').should_succeed "Created /data_bags/bag\nCreated /data_bags/bag/x.json\n"
574
+ knife('diff --name-status /data_bags/bag/x.json').should_succeed ''
575
+ end
532
576
  end
533
577
  end
578
+ end # without versioned cookbooks
534
579
 
535
- when_the_repository 'has the same environment with no name in the file' do
536
- file 'environments/x.json', { 'description' => 'hi' }
537
- it 'knife upload succeeds' do
538
- knife('upload /environments/x.json').should_succeed "Updated /environments/x.json\n"
539
- knife('diff --name-status /environments/x.json').should_succeed ''
580
+ with_versioned_cookbooks do
581
+ when_the_chef_server "has one of each thing" do
582
+ client 'x', '{}'
583
+ cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"' }
584
+ data_bag 'x', { 'y' => '{}' }
585
+ environment 'x', '{}'
586
+ node 'x', '{}'
587
+ role 'x', '{}'
588
+ user 'x', '{}'
589
+
590
+ when_the_repository 'has only top-level directories' do
591
+ directory 'clients'
592
+ directory 'cookbooks'
593
+ directory 'data_bags'
594
+ directory 'environments'
595
+ directory 'nodes'
596
+ directory 'roles'
597
+ directory 'users'
598
+
599
+ it 'knife upload does nothing' do
600
+ knife('upload /').should_succeed ''
601
+ knife('diff --name-status /').should_succeed <<EOM
602
+ D\t/cookbooks/x-1.0.0
603
+ D\t/data_bags/x
604
+ D\t/environments/_default.json
605
+ D\t/environments/x.json
606
+ D\t/roles/x.json
607
+ EOM
608
+ end
609
+
610
+ it 'knife upload --purge deletes everything' do
611
+ knife('upload --purge /').should_succeed(<<EOM, :stderr => "WARNING: /environments/_default.json cannot be deleted (default environment cannot be modified).\n")
612
+ Deleted extra entry /cookbooks/x-1.0.0 (purge is on)
613
+ Deleted extra entry /data_bags/x (purge is on)
614
+ Deleted extra entry /environments/x.json (purge is on)
615
+ Deleted extra entry /roles/x.json (purge is on)
616
+ EOM
617
+ knife('diff --name-status /').should_succeed <<EOM
618
+ D\t/environments/_default.json
619
+ EOM
620
+ end
621
+ end
622
+
623
+ when_the_repository 'has an identical copy of each thing' do
624
+ file 'clients/x.json', <<EOM
625
+ {}
626
+ EOM
627
+ file 'cookbooks/x-1.0.0/metadata.rb', 'version "1.0.0"'
628
+ file 'data_bags/x/y.json', <<EOM
629
+ {
630
+ "id": "y"
631
+ }
632
+ EOM
633
+ file 'environments/_default.json', <<EOM
634
+ {
635
+ "name": "_default",
636
+ "description": "The default Chef environment",
637
+ "cookbook_versions": {
638
+ },
639
+ "json_class": "Chef::Environment",
640
+ "chef_type": "environment",
641
+ "default_attributes": {
642
+ },
643
+ "override_attributes": {
644
+ }
645
+ }
646
+ EOM
647
+ file 'environments/x.json', <<EOM
648
+ {
649
+ "chef_type": "environment",
650
+ "cookbook_versions": {
651
+ },
652
+ "default_attributes": {
653
+ },
654
+ "description": "",
655
+ "json_class": "Chef::Environment",
656
+ "name": "x",
657
+ "override_attributes": {
658
+ }
659
+ }
660
+ EOM
661
+ file 'nodes/x.json', <<EOM
662
+ {}
663
+ EOM
664
+ file 'roles/x.json', <<EOM
665
+ {
666
+ "chef_type": "role",
667
+ "default_attributes": {
668
+ },
669
+ "description": "",
670
+ "env_run_lists": {
671
+ },
672
+ "json_class": "Chef::Role",
673
+ "name": "x",
674
+ "override_attributes": {
675
+ },
676
+ "run_list": [
677
+
678
+ ]
679
+ }
680
+ EOM
681
+ file 'users/x.json', <<EOM
682
+ {}
683
+ EOM
684
+
685
+ it 'knife upload makes no changes' do
686
+ knife('upload /cookbooks/x-1.0.0').should_succeed ''
687
+ knife('diff --name-status /').should_succeed ''
688
+ end
689
+
690
+ it 'knife upload --purge makes no changes' do
691
+ knife('upload --purge /').should_succeed ''
692
+ knife('diff --name-status /').should_succeed ''
693
+ end
694
+
695
+ context 'except the role file' do
696
+ file 'roles/x.json', <<EOM
697
+ {
698
+ "chef_type": "role",
699
+ "default_attributes": {
700
+ },
701
+ "description": "blarghle",
702
+ "env_run_lists": {
703
+ },
704
+ "json_class": "Chef::Role",
705
+ "name": "x",
706
+ "override_attributes": {
707
+ },
708
+ "run_list": [
709
+
710
+ ]
711
+ }
712
+ EOM
713
+ it 'knife upload changes the role' do
714
+ knife('upload /').should_succeed "Updated /roles/x.json\n"
715
+ knife('diff --name-status /').should_succeed ''
716
+ end
717
+ end
718
+
719
+ context 'except the role file is textually different, but not ACTUALLY different' do
720
+ file 'roles/x.json', <<EOM
721
+ {
722
+ "chef_type": "role",
723
+ "default_attributes": {
724
+ },
725
+ "env_run_lists": {
726
+ },
727
+ "json_class": "Chef::Role",
728
+ "name": "x",
729
+ "description": "",
730
+ "override_attributes": {
731
+ },
732
+ "run_list": [
733
+
734
+ ]
735
+ }
736
+ EOM
737
+ it 'knife upload / does not change anything' do
738
+ knife('upload /').should_succeed ''
739
+ knife('diff --name-status /').should_succeed ''
740
+ end
741
+ end
742
+
743
+ context 'as well as one extra copy of each thing' do
744
+ file 'clients/y.json', { 'name' => 'y' }
745
+ file 'cookbooks/x-1.0.0/blah.rb', ''
746
+ file 'cookbooks/x-2.0.0/metadata.rb', 'version "2.0.0"'
747
+ file 'cookbooks/y-1.0.0/metadata.rb', 'version "1.0.0"'
748
+ file 'data_bags/x/z.json', <<EOM
749
+ {
750
+ "id": "z"
751
+ }
752
+ EOM
753
+ file 'data_bags/y/zz.json', <<EOM
754
+ {
755
+ "id": "zz"
756
+ }
757
+ EOM
758
+ file 'environments/y.json', <<EOM
759
+ {
760
+ "chef_type": "environment",
761
+ "cookbook_versions": {
762
+ },
763
+ "default_attributes": {
764
+ },
765
+ "description": "",
766
+ "json_class": "Chef::Environment",
767
+ "name": "y",
768
+ "override_attributes": {
769
+ }
770
+ }
771
+ EOM
772
+ file 'nodes/y.json', { 'name' => 'y' }
773
+ file 'roles/y.json', <<EOM
774
+ {
775
+ "chef_type": "role",
776
+ "default_attributes": {
777
+ },
778
+ "description": "",
779
+ "env_run_lists": {
780
+ },
781
+ "json_class": "Chef::Role",
782
+ "name": "y",
783
+ "override_attributes": {
784
+ },
785
+ "run_list": [
786
+
787
+ ]
788
+ }
789
+ EOM
790
+ file 'users/y.json', { 'name' => 'y' }
791
+
792
+ it 'knife upload adds the new files' do
793
+ knife('upload /').should_succeed <<EOM
794
+ Updated /cookbooks/x-1.0.0
795
+ Created /cookbooks/x-2.0.0
796
+ Created /cookbooks/y-1.0.0
797
+ Created /data_bags/x/z.json
798
+ Created /data_bags/y
799
+ Created /data_bags/y/zz.json
800
+ Created /environments/y.json
801
+ Created /roles/y.json
802
+ EOM
803
+ knife('diff --name-status /').should_succeed ''
804
+ end
805
+ end
806
+ end
807
+
808
+ when_the_repository 'is empty' do
809
+ it 'knife upload does nothing' do
810
+ knife('upload /').should_succeed ''
811
+ knife('diff --name-status /').should_succeed <<EOM
812
+ D\t/cookbooks
813
+ D\t/data_bags
814
+ D\t/environments
815
+ D\t/roles
816
+ EOM
817
+ end
818
+
819
+ it 'knife upload --purge deletes nothing' do
820
+ knife('upload --purge /').should_fail <<EOM
821
+ ERROR: /cookbooks cannot be deleted.
822
+ ERROR: /data_bags cannot be deleted.
823
+ ERROR: /environments cannot be deleted.
824
+ ERROR: /roles cannot be deleted.
825
+ EOM
826
+ knife('diff --name-status /').should_succeed <<EOM
827
+ D\t/cookbooks
828
+ D\t/data_bags
829
+ D\t/environments
830
+ D\t/roles
831
+ EOM
832
+ end
833
+
834
+ context 'when current directory is top level' do
835
+ cwd '.'
836
+ it 'knife upload with no parameters reports an error' do
837
+ knife('upload').should_fail "FATAL: Must specify at least one argument. If you want to upload everything in this directory, type \"knife upload .\"\n", :stdout => /USAGE/
838
+ end
839
+ end
540
840
  end
541
841
  end
542
- end
543
842
 
544
- when_the_chef_server 'is empty' do
545
- when_the_repository 'has an environment with bad JSON' do
546
- file 'environments/x.json', '{'
547
- it 'knife upload tries and fails' do
548
- knife('upload /environments/x.json').should_fail "ERROR: /environments failed to create_child: Parse error reading JSON creating child 'x.json': A JSON text must at least contain two octets!\n"
549
- knife('diff --name-status /environments/x.json').should_succeed "A\t/environments/x.json\n"
843
+ # Test upload of an item when the other end doesn't even have the container
844
+ when_the_chef_server 'is empty' do
845
+ when_the_repository 'has two data bag items' do
846
+ file 'data_bags/x/y.json', <<EOM
847
+ {
848
+ "id": "y"
849
+ }
850
+ EOM
851
+ file 'data_bags/x/z.json', <<EOM
852
+ {
853
+ "id": "z"
854
+ }
855
+ EOM
856
+ it 'knife upload of one data bag item itself succeeds' do
857
+ knife('upload /data_bags/x/y.json').should_succeed <<EOM
858
+ Created /data_bags/x
859
+ Created /data_bags/x/y.json
860
+ EOM
861
+ knife('diff --name-status /data_bags').should_succeed <<EOM
862
+ A\t/data_bags/x/z.json
863
+ EOM
864
+ end
550
865
  end
551
866
  end
552
867
 
553
- when_the_repository 'has an environment with the wrong name in the file' do
554
- file 'environments/x.json', { 'name' => 'y' }
555
- it 'knife upload fails' do
556
- knife('upload /environments/x.json').should_fail "ERROR: /environments failed to create_child: Name in remote/environments/x.json must be 'x' (is 'y')\n"
557
- knife('diff --name-status /environments/x.json').should_succeed "A\t/environments/x.json\n"
868
+ when_the_chef_server 'has three data bag items' do
869
+ data_bag 'x', { 'deleted' => {}, 'modified' => {}, 'unmodified' => {} }
870
+ when_the_repository 'has a modified, unmodified, added and deleted data bag item' do
871
+ file 'data_bags/x/added.json', <<EOM
872
+ {
873
+ "id": "added"
874
+ }
875
+ EOM
876
+ file 'data_bags/x/modified.json', <<EOM
877
+ {
878
+ "id": "modified",
879
+ "foo": "bar"
880
+ }
881
+ EOM
882
+ file 'data_bags/x/unmodified.json', <<EOM
883
+ {
884
+ "id": "unmodified"
885
+ }
886
+ EOM
887
+ it 'knife upload of the modified file succeeds' do
888
+ knife('upload /data_bags/x/modified.json').should_succeed <<EOM
889
+ Updated /data_bags/x/modified.json
890
+ EOM
891
+ knife('diff --name-status /data_bags').should_succeed <<EOM
892
+ D\t/data_bags/x/deleted.json
893
+ A\t/data_bags/x/added.json
894
+ EOM
895
+ end
896
+ it 'knife upload of the unmodified file does nothing' do
897
+ knife('upload /data_bags/x/unmodified.json').should_succeed ''
898
+ knife('diff --name-status /data_bags').should_succeed <<EOM
899
+ D\t/data_bags/x/deleted.json
900
+ M\t/data_bags/x/modified.json
901
+ A\t/data_bags/x/added.json
902
+ EOM
903
+ end
904
+ it 'knife upload of the added file succeeds' do
905
+ knife('upload /data_bags/x/added.json').should_succeed <<EOM
906
+ Created /data_bags/x/added.json
907
+ EOM
908
+ knife('diff --name-status /data_bags').should_succeed <<EOM
909
+ D\t/data_bags/x/deleted.json
910
+ M\t/data_bags/x/modified.json
911
+ EOM
912
+ end
913
+ it 'knife upload of the deleted file does nothing' do
914
+ knife('upload /data_bags/x/deleted.json').should_succeed ''
915
+ knife('diff --name-status /data_bags').should_succeed <<EOM
916
+ D\t/data_bags/x/deleted.json
917
+ M\t/data_bags/x/modified.json
918
+ A\t/data_bags/x/added.json
919
+ EOM
920
+ end
921
+ it 'knife upload --purge of the deleted file deletes it' do
922
+ knife('upload --purge /data_bags/x/deleted.json').should_succeed <<EOM
923
+ Deleted extra entry /data_bags/x/deleted.json (purge is on)
924
+ EOM
925
+ knife('diff --name-status /data_bags').should_succeed <<EOM
926
+ M\t/data_bags/x/modified.json
927
+ A\t/data_bags/x/added.json
928
+ EOM
929
+ end
930
+ it 'knife upload of the entire data bag uploads everything' do
931
+ knife('upload /data_bags/x').should_succeed <<EOM
932
+ Created /data_bags/x/added.json
933
+ Updated /data_bags/x/modified.json
934
+ EOM
935
+ knife('diff --name-status /data_bags').should_succeed <<EOM
936
+ D\t/data_bags/x/deleted.json
937
+ EOM
938
+ end
939
+ it 'knife upload --purge of the entire data bag uploads everything' do
940
+ knife('upload --purge /data_bags/x').should_succeed <<EOM
941
+ Created /data_bags/x/added.json
942
+ Updated /data_bags/x/modified.json
943
+ Deleted extra entry /data_bags/x/deleted.json (purge is on)
944
+ EOM
945
+ knife('diff --name-status /data_bags').should_succeed ''
946
+ end
947
+ context 'when cwd is the /data_bags directory' do
948
+ cwd 'data_bags'
949
+ it 'knife upload fails' do
950
+ knife('upload').should_fail "FATAL: Must specify at least one argument. If you want to upload everything in this directory, type \"knife upload .\"\n", :stdout => /USAGE/
951
+ end
952
+ it 'knife upload --purge . uploads everything' do
953
+ knife('upload --purge .').should_succeed <<EOM
954
+ Created x/added.json
955
+ Updated x/modified.json
956
+ Deleted extra entry x/deleted.json (purge is on)
957
+ EOM
958
+ knife('diff --name-status /data_bags').should_succeed ''
959
+ end
960
+ it 'knife upload --purge * uploads everything' do
961
+ knife('upload --purge *').should_succeed <<EOM
962
+ Created x/added.json
963
+ Updated x/modified.json
964
+ Deleted extra entry x/deleted.json (purge is on)
965
+ EOM
966
+ knife('diff --name-status /data_bags').should_succeed ''
967
+ end
968
+ end
969
+ end
970
+ end
971
+
972
+ # Cookbook upload is a funny thing ... direct cookbook upload works, but
973
+ # upload of a file is designed not to work at present. Make sure that is the
974
+ # case.
975
+ when_the_chef_server 'has a cookbook' do
976
+ cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"', 'z.rb' => '' }
977
+ when_the_repository 'has a modified, extra and missing file for the cookbook' do
978
+ file 'cookbooks/x-1.0.0/metadata.rb', 'version "1.0.0"'
979
+ file 'cookbooks/x-1.0.0/y.rb', 'hi'
980
+ it 'knife upload of any individual file fails' do
981
+ knife('upload /cookbooks/x-1.0.0/metadata.rb').should_fail "ERROR: /cookbooks/x-1.0.0/metadata.rb cannot be updated.\n"
982
+ knife('upload /cookbooks/x-1.0.0/y.rb').should_fail "ERROR: /cookbooks/x-1.0.0 cannot have a child created under it.\n"
983
+ knife('upload --purge /cookbooks/x-1.0.0/z.rb').should_fail "ERROR: /cookbooks/x-1.0.0/z.rb cannot be deleted.\n"
984
+ end
985
+ # TODO this is a bit of an inconsistency: if we didn't specify --purge,
986
+ # technically we shouldn't have deleted missing files. But ... cookbooks
987
+ # are a special case.
988
+ it 'knife upload of the cookbook itself succeeds' do
989
+ knife('upload /cookbooks/x-1.0.0').should_succeed <<EOM
990
+ Updated /cookbooks/x-1.0.0
991
+ EOM
992
+ knife('diff --name-status /cookbooks').should_succeed ''
993
+ end
994
+ it 'knife upload --purge of the cookbook itself succeeds' do
995
+ knife('upload /cookbooks/x-1.0.0').should_succeed <<EOM
996
+ Updated /cookbooks/x-1.0.0
997
+ EOM
998
+ knife('diff --name-status /cookbooks').should_succeed ''
999
+ end
1000
+ end
1001
+ when_the_repository 'has a missing file for the cookbook' do
1002
+ file 'cookbooks/x-1.0.0/metadata.rb', 'version "1.0.0"'
1003
+ it 'knife upload of the cookbook succeeds' do
1004
+ knife('upload /cookbooks/x-1.0.0').should_succeed <<EOM
1005
+ Updated /cookbooks/x-1.0.0
1006
+ EOM
1007
+ knife('diff --name-status /cookbooks').should_succeed ''
1008
+ end
1009
+ end
1010
+ when_the_repository 'has an extra file for the cookbook' do
1011
+ file 'cookbooks/x-1.0.0/metadata.rb', 'version "1.0.0"'
1012
+ file 'cookbooks/x-1.0.0/z.rb', ''
1013
+ file 'cookbooks/x-1.0.0/blah.rb', ''
1014
+ it 'knife upload of the cookbook succeeds' do
1015
+ knife('upload /cookbooks/x-1.0.0').should_succeed <<EOM
1016
+ Updated /cookbooks/x-1.0.0
1017
+ EOM
1018
+ knife('diff --name-status /cookbooks').should_succeed ''
1019
+ end
558
1020
  end
559
1021
  end
560
1022
 
561
- when_the_repository 'has an environment with no name in the file' do
562
- file 'environments/x.json', { 'description' => 'hi' }
563
- it 'knife upload succeeds' do
564
- knife('upload /environments/x.json').should_succeed "Created /environments/x.json\n"
565
- knife('diff --name-status /environments/x.json').should_succeed ''
1023
+ when_the_repository 'has a cookbook' do
1024
+ file 'cookbooks/x-1.0.0/metadata.rb', 'version "1.0.0"'
1025
+ file 'cookbooks/x-1.0.0/onlyin1.0.0.rb', 'old_text'
1026
+
1027
+ when_the_chef_server 'has a later version for the cookbook' do
1028
+ cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"', 'onlyin1.0.0.rb' => '' }
1029
+ cookbook 'x', '1.0.1', { 'metadata.rb' => 'version "1.0.1"', 'onlyin1.0.1.rb' => 'hi' }
1030
+
1031
+ it 'knife upload /cookbooks uploads the local version' do
1032
+ knife('diff --name-status /cookbooks').should_succeed <<EOM
1033
+ M\t/cookbooks/x-1.0.0/onlyin1.0.0.rb
1034
+ D\t/cookbooks/x-1.0.1
1035
+ EOM
1036
+ knife('upload --purge /cookbooks').should_succeed <<EOM
1037
+ Updated /cookbooks/x-1.0.0
1038
+ Deleted extra entry /cookbooks/x-1.0.1 (purge is on)
1039
+ EOM
1040
+ knife('diff --name-status /cookbooks').should_succeed ''
1041
+ end
1042
+ end
1043
+
1044
+ when_the_chef_server 'has an earlier version for the cookbook' do
1045
+ cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"', 'onlyin1.0.0.rb' => ''}
1046
+ cookbook 'x', '0.9.9', { 'metadata.rb' => 'version "0.9.9"', 'onlyin0.9.9.rb' => 'hi' }
1047
+ it 'knife upload /cookbooks uploads the local version' do
1048
+ knife('upload --purge /cookbooks').should_succeed <<EOM
1049
+ Updated /cookbooks/x-1.0.0
1050
+ Deleted extra entry /cookbooks/x-0.9.9 (purge is on)
1051
+ EOM
1052
+ knife('diff --name-status /cookbooks').should_succeed ''
1053
+ end
1054
+ end
1055
+
1056
+ when_the_chef_server 'has a later version for the cookbook, and no current version' do
1057
+ cookbook 'x', '1.0.1', { 'metadata.rb' => 'version "1.0.1"', 'onlyin1.0.1.rb' => 'hi' }
1058
+
1059
+ it 'knife upload /cookbooks/x uploads the local version' do
1060
+ knife('diff --name-status /cookbooks').should_succeed <<EOM
1061
+ D\t/cookbooks/x-1.0.1
1062
+ A\t/cookbooks/x-1.0.0
1063
+ EOM
1064
+ knife('upload --purge /cookbooks').should_succeed <<EOM
1065
+ Created /cookbooks/x-1.0.0
1066
+ Deleted extra entry /cookbooks/x-1.0.1 (purge is on)
1067
+ EOM
1068
+ knife('diff --name-status /cookbooks').should_succeed ''
1069
+ end
1070
+ end
1071
+
1072
+ when_the_chef_server 'has an earlier version for the cookbook, and no current version' do
1073
+ cookbook 'x', '0.9.9', { 'metadata.rb' => 'version "0.9.9"', 'onlyin0.9.9.rb' => 'hi' }
1074
+
1075
+ it 'knife upload /cookbooks/x uploads the new version' do
1076
+ knife('upload --purge /cookbooks').should_succeed <<EOM
1077
+ Created /cookbooks/x-1.0.0
1078
+ Deleted extra entry /cookbooks/x-0.9.9 (purge is on)
1079
+ EOM
1080
+ knife('diff --name-status /cookbooks').should_succeed ''
1081
+ end
566
1082
  end
567
1083
  end
568
1084
 
569
- when_the_repository 'has a data bag with no id in the file' do
570
- file 'data_bags/bag/x.json', { 'foo' => 'bar' }
571
- it 'knife upload succeeds' do
572
- knife('upload /data_bags/bag/x.json').should_succeed "Created /data_bags/bag\nCreated /data_bags/bag/x.json\n"
573
- knife('diff --name-status /data_bags/bag/x.json').should_succeed ''
1085
+ when_the_chef_server 'has an environment' do
1086
+ environment 'x', {}
1087
+ when_the_repository 'has an environment with bad JSON' do
1088
+ file 'environments/x.json', '{'
1089
+ it 'knife upload tries and fails' do
1090
+ knife('upload /environments/x.json').should_fail "WARN: Parse error reading #{path_to('environments/x.json')} as JSON: A JSON text must at least contain two octets!\nERROR: /environments/x.json failed to write: Parse error reading JSON: A JSON text must at least contain two octets!\n"
1091
+ knife('diff --name-status /environments/x.json').should_succeed "M\t/environments/x.json\n", :stderr => "WARN: Parse error reading #{path_to('environments/x.json')} as JSON: A JSON text must at least contain two octets!\n"
1092
+ end
1093
+ end
1094
+
1095
+ when_the_repository 'has the same environment with the wrong name in the file' do
1096
+ file 'environments/x.json', { 'name' => 'y' }
1097
+ it 'knife upload fails' do
1098
+ knife('upload /environments/x.json').should_fail "ERROR: /environments/x.json failed to write: Name in remote/environments/x.json/x.json must be 'x' (is 'y')\n"
1099
+ knife('diff --name-status /environments/x.json').should_succeed "M\t/environments/x.json\n"
1100
+ end
1101
+ end
1102
+
1103
+ when_the_repository 'has the same environment with no name in the file' do
1104
+ file 'environments/x.json', { 'description' => 'hi' }
1105
+ it 'knife upload succeeds' do
1106
+ knife('upload /environments/x.json').should_succeed "Updated /environments/x.json\n"
1107
+ knife('diff --name-status /environments/x.json').should_succeed ''
1108
+ end
574
1109
  end
575
1110
  end
576
- end
1111
+
1112
+ when_the_chef_server 'is empty' do
1113
+ when_the_repository 'has an environment with bad JSON' do
1114
+ file 'environments/x.json', '{'
1115
+ it 'knife upload tries and fails' do
1116
+ knife('upload /environments/x.json').should_fail "ERROR: /environments failed to create_child: Parse error reading JSON creating child 'x.json': A JSON text must at least contain two octets!\n"
1117
+ knife('diff --name-status /environments/x.json').should_succeed "A\t/environments/x.json\n"
1118
+ end
1119
+ end
1120
+
1121
+ when_the_repository 'has an environment with the wrong name in the file' do
1122
+ file 'environments/x.json', { 'name' => 'y' }
1123
+ it 'knife upload fails' do
1124
+ knife('upload /environments/x.json').should_fail "ERROR: /environments failed to create_child: Name in remote/environments/x.json must be 'x' (is 'y')\n"
1125
+ knife('diff --name-status /environments/x.json').should_succeed "A\t/environments/x.json\n"
1126
+ end
1127
+ end
1128
+
1129
+ when_the_repository 'has an environment with no name in the file' do
1130
+ file 'environments/x.json', { 'description' => 'hi' }
1131
+ it 'knife upload succeeds' do
1132
+ knife('upload /environments/x.json').should_succeed "Created /environments/x.json\n"
1133
+ knife('diff --name-status /environments/x.json').should_succeed ''
1134
+ end
1135
+ end
1136
+
1137
+ when_the_repository 'has a data bag with no id in the file' do
1138
+ file 'data_bags/bag/x.json', { 'foo' => 'bar' }
1139
+ it 'knife upload succeeds' do
1140
+ knife('upload /data_bags/bag/x.json').should_succeed "Created /data_bags/bag\nCreated /data_bags/bag/x.json\n"
1141
+ knife('diff --name-status /data_bags/bag/x.json').should_succeed ''
1142
+ end
1143
+ end
1144
+ end
1145
+ end # with versioned cookbooks
1146
+
577
1147
  end