continuum-stager-api 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +22 -0
  3. data/.travis.yml +15 -0
  4. data/CHANGELOG.md +16 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE +21 -0
  7. data/README.md +37 -0
  8. data/Rakefile +7 -0
  9. data/apcera-stager-api-contrib.gemspec +25 -0
  10. data/lib/apcera/stager/error.rb +6 -0
  11. data/lib/apcera/stager/loader.rb +10 -0
  12. data/lib/apcera/stager/stager.rb +270 -0
  13. data/lib/continuum-stager-api.rb +1 -0
  14. data/spec/apcera/stager/stager_spec.rb +496 -0
  15. data/spec/fixtures/cassettes/complete.yml +55 -0
  16. data/spec/fixtures/cassettes/dependencies_add.yml +53 -0
  17. data/spec/fixtures/cassettes/dependencies_remove.yml +53 -0
  18. data/spec/fixtures/cassettes/done.yml +28 -0
  19. data/spec/fixtures/cassettes/download.yml +37400 -0
  20. data/spec/fixtures/cassettes/environment_add.yml +53 -0
  21. data/spec/fixtures/cassettes/environment_remove.yml +53 -0
  22. data/spec/fixtures/cassettes/fail.yml +28 -0
  23. data/spec/fixtures/cassettes/invalid/complete.yml +55 -0
  24. data/spec/fixtures/cassettes/invalid/dependencies_add.yml +53 -0
  25. data/spec/fixtures/cassettes/invalid/dependencies_remove.yml +53 -0
  26. data/spec/fixtures/cassettes/invalid/done.yml +55 -0
  27. data/spec/fixtures/cassettes/invalid/download.yml +54 -0
  28. data/spec/fixtures/cassettes/invalid/environment_add.yml +53 -0
  29. data/spec/fixtures/cassettes/invalid/environment_remove.yml +53 -0
  30. data/spec/fixtures/cassettes/invalid/fail.yml +28 -0
  31. data/spec/fixtures/cassettes/invalid/metadata.yml +28 -0
  32. data/spec/fixtures/cassettes/invalid/provides_add.yml +53 -0
  33. data/spec/fixtures/cassettes/invalid/provides_remove.yml +53 -0
  34. data/spec/fixtures/cassettes/invalid/relaunch.yml +53 -0
  35. data/spec/fixtures/cassettes/invalid/snapshot.yml +53 -0
  36. data/spec/fixtures/cassettes/invalid/templates_add.yml +53 -0
  37. data/spec/fixtures/cassettes/invalid/templates_remove.yml +53 -0
  38. data/spec/fixtures/cassettes/invalid/upload.yml +55 -0
  39. data/spec/fixtures/cassettes/metadata.yml +51 -0
  40. data/spec/fixtures/cassettes/provides_add.yml +53 -0
  41. data/spec/fixtures/cassettes/provides_remove.yml +116 -0
  42. data/spec/fixtures/cassettes/relaunch.yml +28 -0
  43. data/spec/fixtures/cassettes/snapshot.yml +28 -0
  44. data/spec/fixtures/cassettes/templates_add.yml +53 -0
  45. data/spec/fixtures/cassettes/templates_remove.yml +53 -0
  46. data/spec/fixtures/cassettes/upload.yml +30 -0
  47. data/spec/spec_helper.rb +31 -0
  48. metadata +189 -0
@@ -0,0 +1 @@
1
+ require File.join('apcera', 'stager', 'loader.rb')
@@ -0,0 +1,496 @@
1
+ require 'spec_helper'
2
+
3
+ describe Apcera::Stager do
4
+ before do
5
+ @appdir = "site"
6
+
7
+ # See mock server directory for setup!
8
+ @stager_url = "http://example.com"
9
+ end
10
+
11
+ it "should raise an exception when initialized without a stager url" do
12
+ expect { Apcera::Stager.new }.to raise_error(Apcera::Error::StagerURLRequired)
13
+ end
14
+
15
+ it "should initialize with the stager url passed as an argument" do
16
+ stager = Apcera::Stager.new({:stager_url => @stager_url})
17
+ stager.class.should == Apcera::Stager
18
+ stager.stager_url.should == @stager_url
19
+ end
20
+
21
+ it "should initialize when the ENV variable STAGER_URL is present" do
22
+ begin
23
+ ENV["STAGER_URL"] = @stager_url
24
+ stager = Apcera::Stager.new
25
+ stager.class.should == Apcera::Stager
26
+ stager.stager_url.should == @stager_url
27
+ ensure
28
+ ENV["STAGER_URL"] = nil
29
+ end
30
+ end
31
+
32
+ context do
33
+ before do
34
+ @stager = Apcera::Stager.new({:stager_url => @stager_url})
35
+
36
+ # Best way to get our current path is to get the gem_dir!
37
+ spec = Gem::Specification.find_by_name("continuum-stager-api").gem_dir
38
+
39
+ # Lets write files in spec/tmp for tests!
40
+ @stager.root_path = File.join(spec, "spec", "tmp")
41
+ @stager.pkg_path = File.join(@stager.root_path, "pkg.tar.gz")
42
+ @stager.updated_pkg_path = File.join(@stager.root_path, "updated.tar.gz")
43
+ @stager.system_options = { :out => "/dev/null", :err => "/dev/null" }
44
+
45
+ # We don't want to exit in tests.
46
+ @stager.stub(:exit0r)
47
+ @stager.stub(:output_error)
48
+ @stager.stub(:output)
49
+ end
50
+
51
+ after do
52
+ # Don't trust urls above, they could be changed in tests.
53
+ # This does an actual delete and we want to be specific.
54
+ spec = Gem::Specification.find_by_name("continuum-stager-api").gem_dir
55
+ test_files = File.join(spec, "spec", "tmp", "*")
56
+
57
+ # Remove the test files.
58
+ FileUtils.rm_rf Dir.glob(test_files)
59
+ end
60
+
61
+ context "download" do
62
+ it "should download the app package to pkg.tar.gz" do
63
+ VCR.use_cassette('download') do
64
+ @stager.download
65
+ end
66
+ File.exists?(@stager.pkg_path).should == true
67
+ end
68
+
69
+ it "should bubble errors to fail" do
70
+ @stager.should_receive(:exit0r).with(1) { raise }
71
+
72
+ VCR.use_cassette('invalid/download') do
73
+ expect { @stager.download }.to raise_error(RestClient::ResourceNotFound, "404 Resource Not Found")
74
+ end
75
+ end
76
+ end
77
+
78
+ context "extract" do
79
+ it "should decompress the package to a supplied path" do
80
+ VCR.use_cassette('download') do
81
+ @stager.download
82
+ end
83
+
84
+ @stager.extract(@appdir)
85
+ File.exists?(File.join(@stager.root_path, @appdir)).should == true
86
+ end
87
+
88
+ it "should bubble errors to fail" do
89
+ @stager.should_receive(:exit0r).with(1) { raise }
90
+
91
+ err = Apcera::Error::ExecuteError.new
92
+ @stager.should_receive(:execute_app).and_raise(err)
93
+
94
+ VCR.use_cassette('download') do
95
+ @stager.download
96
+ end
97
+
98
+ expect { @stager.extract(@appdir) }.to raise_error(err)
99
+ end
100
+ end
101
+
102
+ context "execute" do
103
+ it "should execute commands with clean bundler environment" do
104
+ Bundler.should_receive(:with_clean_env).at_least(:once).and_yield
105
+
106
+ VCR.use_cassette('download') do
107
+ @stager.download
108
+ end
109
+
110
+ @stager.extract(@appdir)
111
+
112
+ @stager.execute("cat thing").should == nil
113
+ @stager.execute("cat #{File.join(@stager.app_path, "app", "Gemfile")}").should == true
114
+ end
115
+
116
+ it "should bubble errors to fail" do
117
+ @stager.should_receive(:exit0r).with(1) { raise }
118
+
119
+ VCR.use_cassette('download') do
120
+ @stager.download
121
+ end
122
+
123
+ @stager.extract(@appdir)
124
+
125
+ cmd = "cat thing"
126
+ expect {@stager.execute(cmd) }.to raise_error(Apcera::Error::ExecuteError, "failed to execute: #{cmd}.\n")
127
+ end
128
+ end
129
+
130
+ context "execute_app" do
131
+ it "should execute commands in app dir with clean bundler environment" do
132
+ Bundler.should_receive(:with_clean_env).at_least(:once).and_yield
133
+
134
+ VCR.use_cassette('download') do
135
+ @stager.download
136
+ end
137
+
138
+ @stager.extract(@appdir)
139
+
140
+ @stager.execute_app("cat thing").should == nil
141
+ @stager.execute_app("cat #{File.join("app", "Gemfile")}").should == true
142
+ end
143
+
144
+ it "should bubble errors to fail" do
145
+ @stager.should_receive(:exit0r).with(1) { raise }
146
+
147
+ VCR.use_cassette('download') do
148
+ @stager.download
149
+ end
150
+
151
+ @stager.extract(@appdir)
152
+
153
+ cmd = "cat thing"
154
+ expect {@stager.execute_app(cmd) }.to raise_error(Apcera::Error::ExecuteError, "failed to execute: #{cmd}.\n")
155
+ end
156
+ end
157
+
158
+ context "upload" do
159
+ it "should compress a new package and send to the staging coordinator" do
160
+ VCR.use_cassette('download') do
161
+ @stager.download
162
+ end
163
+
164
+ @stager.extract(@appdir)
165
+
166
+ VCR.use_cassette('upload') do
167
+ @stager.upload
168
+ end
169
+
170
+ File.exists?(File.join(@stager.root_path, "#{@appdir}.tar.gz"))
171
+ end
172
+
173
+ it "should bubble errors to fail" do
174
+ @stager.should_receive(:exit0r).with(1) { raise }
175
+
176
+ VCR.use_cassette('download') do
177
+ @stager.download
178
+ end
179
+
180
+ @stager.extract(@appdir)
181
+
182
+ VCR.use_cassette('invalid/upload') do
183
+ expect { @stager.upload }.to raise_error(RestClient::ResourceNotFound, "404 Resource Not Found")
184
+ end
185
+ end
186
+ end
187
+
188
+ context "complete" do
189
+ it "should compress a new package and send to the staging coordinator then be done" do
190
+ VCR.use_cassette('download') do
191
+ @stager.download
192
+ end
193
+
194
+ @stager.extract(@appdir)
195
+
196
+ VCR.use_cassette('complete') do
197
+ @stager.complete
198
+ end
199
+
200
+ File.exists?(File.join(@stager.root_path, "#{@appdir}.tar.gz"))
201
+ end
202
+
203
+ it "should bubble errors to fail" do
204
+ @stager.should_receive(:exit0r).with(1) { raise }
205
+
206
+ VCR.use_cassette('download') do
207
+ @stager.download
208
+ end
209
+
210
+ @stager.extract(@appdir)
211
+
212
+ VCR.use_cassette('invalid/complete') do
213
+ expect { @stager.complete }.to raise_error(RestClient::ResourceNotFound, "404 Resource Not Found")
214
+ end
215
+ end
216
+ end
217
+
218
+ context "done" do
219
+ it "should send done to the staging coordinator" do
220
+ @stager.should_receive(:exit0r).with(0)
221
+
222
+ VCR.use_cassette('done') do
223
+ @stager.done
224
+ end
225
+ end
226
+
227
+ it "should bubble errors to fail" do
228
+ @stager.should_receive(:exit0r).with(1) { raise }
229
+
230
+ VCR.use_cassette('invalid/done') do
231
+ expect { @stager.done }.to raise_error(RestClient::ResourceNotFound, "404 Resource Not Found")
232
+ end
233
+ end
234
+ end
235
+
236
+ context "snapshot" do
237
+ it "should send a snapshot request to the staging coordinator" do
238
+ VCR.use_cassette('download') do
239
+ @stager.download
240
+ end
241
+ @stager.extract(@appdir)
242
+ VCR.use_cassette('snapshot') do
243
+ @stager.snapshot
244
+ end
245
+ VCR.use_cassette('done') do
246
+ @stager.done
247
+ end
248
+ end
249
+
250
+ it "should bubble errors to fail" do
251
+ @stager.should_receive(:exit0r).with(1) { raise }
252
+
253
+ VCR.use_cassette('download') do
254
+ @stager.download
255
+ end
256
+ @stager.extract(@appdir)
257
+ VCR.use_cassette('invalid/snapshot') do
258
+ expect { @stager.snapshot }.to raise_error(RestClient::ResourceNotFound, "404 Resource Not Found")
259
+ end
260
+ end
261
+ end
262
+
263
+ context "fail" do
264
+ it "should have a fail hook that exits with exit code 1" do
265
+ # Make sure we don't exit and that we called exit 1.
266
+ @stager.should_receive(:exit0r).with(1)
267
+
268
+ VCR.use_cassette('fail') do
269
+ @stager.fail.should == "OK"
270
+ end
271
+ end
272
+ end
273
+
274
+ context "meta" do
275
+ it "should recieve package metadata and cache it" do
276
+ VCR.use_cassette('metadata') do
277
+ @stager.meta.class.should == Hash
278
+ end
279
+ end
280
+
281
+ it "should throw errors" do
282
+ VCR.use_cassette('invalid/metadata') do
283
+ expect { @stager.meta }.to raise_error(RestClient::ResourceNotFound, "404 Resource Not Found")
284
+ end
285
+ end
286
+ end
287
+
288
+ context "relaunch" do
289
+ it "should allow you to trigger a stager relaunch" do
290
+ @stager.should_receive(:exit0r).with(0) { 0 }
291
+
292
+ VCR.use_cassette('relaunch') do
293
+ @stager.relaunch.should == 0
294
+ end
295
+ end
296
+
297
+ it "should bubble errors to fail" do
298
+ @stager.should_receive(:exit0r).with(1) { raise }
299
+
300
+ VCR.use_cassette('invalid/relaunch') do
301
+ expect { @stager.relaunch }.to raise_error(RestClient::ResourceNotFound, "404 Resource Not Found")
302
+ end
303
+ end
304
+ end
305
+
306
+ context "start_command" do
307
+ it "should return the package start command" do
308
+ VCR.use_cassette('metadata') do
309
+ @stager.start_command.should == "./startme"
310
+ end
311
+ end
312
+
313
+ it "should allow you to set the start command" do
314
+ VCR.use_cassette('environment_add') do
315
+ @stager.start_command = "./startme"
316
+ end
317
+ end
318
+ end
319
+
320
+ context "start_path" do
321
+ it "should return the package start path" do
322
+ VCR.use_cassette('metadata') do
323
+ @stager.start_path.should == "/app"
324
+ end
325
+ end
326
+
327
+ it "should allow you to set the start path" do
328
+ VCR.use_cassette('environment_add') do
329
+ @stager.start_path = "/app"
330
+ end
331
+ end
332
+ end
333
+
334
+ context "environment_add" do
335
+ it "should add an environment variable" do
336
+ VCR.use_cassette('environment_add') do
337
+ @stager.environment_add("TEST_VAR", "foo")
338
+ end
339
+ end
340
+
341
+ it "should bubble errors to fail" do
342
+ @stager.should_receive(:exit0r).with(1) { raise }
343
+
344
+ VCR.use_cassette('invalid/environment_add') do
345
+ expect { @stager.environment_add("TEST_VAR", "foo") }.to raise_error
346
+ end
347
+ end
348
+ end
349
+
350
+ context "environment_remove" do
351
+ it "should environment_remove an environment variable" do
352
+ VCR.use_cassette('environment_remove') do
353
+ @stager.environment_remove("TEST_VAR", "foo")
354
+ end
355
+ end
356
+
357
+ it "should bubble errors to fail" do
358
+ @stager.should_receive(:exit0r).with(1) { raise }
359
+
360
+ VCR.use_cassette('invalid/environment_remove') do
361
+ expect { @stager.environment_remove("TEST_VAR", "foo") }.to raise_error
362
+ end
363
+ end
364
+ end
365
+
366
+ context "provides_add" do
367
+ it "should add to its list of provides" do
368
+ VCR.use_cassette('provides_add') do
369
+ @stager.provides_add("os", "linux")
370
+ end
371
+ end
372
+
373
+ it "should bubble errors to fail" do
374
+ @stager.should_receive(:exit0r).with(1) { raise }
375
+
376
+ VCR.use_cassette('invalid/provides_add') do
377
+ expect { @stager.provides_add("os", "linux") }.to raise_error
378
+ end
379
+ end
380
+ end
381
+
382
+ context "provides_remove" do
383
+ it "should remove from its list of provides" do
384
+ VCR.use_cassette('provides_remove') do
385
+ @stager.provides_remove("os", "linux")
386
+ end
387
+ end
388
+
389
+ it "should bubble errors to fail" do
390
+ @stager.should_receive(:exit0r).with(1) { raise }
391
+
392
+ VCR.use_cassette('invalid/provides_remove') do
393
+ expect { @stager.provides_remove("os", "linux") }.to raise_error
394
+ end
395
+ end
396
+ end
397
+
398
+ context "dependencies_add" do
399
+ it "should add to its list of dependencies" do
400
+ VCR.use_cassette('dependencies_add') do
401
+ @stager.dependencies_add("os", "linux")
402
+ end
403
+ end
404
+
405
+ it "should bubble errors to fail" do
406
+ @stager.should_receive(:exit0r).with(1) { raise }
407
+
408
+ VCR.use_cassette('invalid/dependencies_add') do
409
+ expect { @stager.dependencies_add("os", "linux") }.to raise_error
410
+ end
411
+ end
412
+ end
413
+
414
+ context "dependencies_remove" do
415
+ it "should remove from its list of dependencies" do
416
+ VCR.use_cassette('dependencies_remove') do
417
+ @stager.dependencies_remove("os", "linux")
418
+ end
419
+ end
420
+
421
+ it "should bubble errors to fail" do
422
+ @stager.should_receive(:exit0r).with(1) { raise }
423
+
424
+ VCR.use_cassette('invalid/dependencies_remove') do
425
+ expect { @stager.dependencies_remove("os", "linux") }.to raise_error
426
+ end
427
+ end
428
+ end
429
+
430
+ context "templates_add" do
431
+ it "should add to its list of templates" do
432
+ VCR.use_cassette('templates_add') do
433
+ @stager.templates_add("/path/to/template")
434
+ end
435
+ end
436
+
437
+ it "should add to its list of templates with delimiters" do
438
+ VCR.use_cassette('templates_add') do
439
+ @stager.templates_add("/path/to/template", "{{", "}}")
440
+ end
441
+ end
442
+
443
+ it "should bubble errors to fail" do
444
+ @stager.should_receive(:exit0r).with(1) { raise }
445
+
446
+ VCR.use_cassette('invalid/templates_add') do
447
+ expect { @stager.templates_add("/path/to/template") }.to raise_error
448
+ end
449
+ end
450
+ end
451
+
452
+ context "templates_remove" do
453
+ it "should remove from its list of templates" do
454
+ VCR.use_cassette('templates_remove') do
455
+ @stager.templates_remove("/path/to/template")
456
+ end
457
+ end
458
+
459
+ it "should remove from its list of templates with delimiters" do
460
+ VCR.use_cassette('templates_remove') do
461
+ @stager.templates_remove("/path/to/template", "{{", "}}")
462
+ end
463
+ end
464
+
465
+ it "should bubble errors to fail" do
466
+ @stager.should_receive(:exit0r).with(1) { raise }
467
+
468
+ VCR.use_cassette('invalid/templates_remove') do
469
+ expect { @stager.templates_remove("/path/to/template") }.to raise_error
470
+ end
471
+ end
472
+ end
473
+
474
+ context "exit0r" do
475
+ before do
476
+ @stager.unstub(:exit0r)
477
+ end
478
+
479
+ it "should wrap successful exit" do
480
+ begin
481
+ @stager.exit0r(0)
482
+ rescue SystemExit => e
483
+ e.status.should == 0
484
+ end
485
+ end
486
+
487
+ it "should wrap errored exit" do
488
+ begin
489
+ @stager.exit0r(1)
490
+ rescue SystemExit => e
491
+ e.status.should == 1
492
+ end
493
+ end
494
+ end
495
+ end
496
+ end