rhc 0.98.16 → 1.0.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.
Files changed (94) hide show
  1. data/bin/rhc +7 -49
  2. data/bin/rhc-app +14 -3
  3. data/bin/rhc-chk +16 -16
  4. data/bin/rhc-create-app +2 -0
  5. data/bin/rhc-create-domain +1 -2
  6. data/bin/rhc-ctl-app +12 -3
  7. data/bin/rhc-ctl-domain +1 -2
  8. data/bin/rhc-domain +1 -2
  9. data/bin/rhc-domain-info +1 -2
  10. data/bin/rhc-port-forward +1 -2
  11. data/bin/rhc-snapshot +3 -0
  12. data/bin/rhc-sshkey +1 -2
  13. data/bin/rhc-tail-files +1 -1
  14. data/bin/rhc-user-info +1 -3
  15. data/features/application.feature +4 -1
  16. data/features/domain.feature +0 -4
  17. data/features/geared_application.feature +11 -0
  18. data/features/lib/rhc_helper/app.rb +16 -5
  19. data/features/lib/rhc_helper/cartridge.rb +25 -9
  20. data/features/lib/rhc_helper/commandify.rb +34 -7
  21. data/features/lib/rhc_helper/domain.rb +2 -2
  22. data/features/lib/rhc_helper/httpify.rb +24 -14
  23. data/features/lib/rhc_helper/persistable.rb +1 -1
  24. data/features/lib/rhc_helper/sshkey.rb +11 -7
  25. data/features/lib/rhc_helper.rb +5 -3
  26. data/features/multiple_cartridge.feature +1 -1
  27. data/features/scaled_application.feature +48 -0
  28. data/features/sshkey.feature +37 -31
  29. data/features/step_definitions/application_steps.rb +18 -7
  30. data/features/step_definitions/cartridge_steps.rb +29 -3
  31. data/features/step_definitions/domain_steps.rb +2 -2
  32. data/features/step_definitions/sshkey_steps.rb +34 -34
  33. data/features/support/assumptions.rb +21 -9
  34. data/features/support/before_hooks.rb +24 -6
  35. data/features/support/env.rb +45 -19
  36. data/lib/rhc/cartridge_helper.rb +27 -0
  37. data/lib/rhc/cli.rb +1 -1
  38. data/lib/rhc/command_runner.rb +31 -3
  39. data/lib/rhc/commands/alias.rb +38 -0
  40. data/lib/rhc/commands/app.rb +478 -0
  41. data/lib/rhc/commands/base.rb +42 -12
  42. data/lib/rhc/commands/cartridge.rb +189 -0
  43. data/lib/rhc/commands/domain.rb +11 -49
  44. data/lib/rhc/commands/port-forward.rb +0 -1
  45. data/lib/rhc/commands/setup.rb +2 -1
  46. data/lib/rhc/commands/snapshot.rb +118 -0
  47. data/lib/rhc/commands/sshkey.rb +24 -38
  48. data/lib/rhc/commands/tail.rb +24 -0
  49. data/lib/rhc/commands/threaddump.rb +16 -0
  50. data/lib/rhc/commands.rb +33 -7
  51. data/lib/rhc/config.rb +28 -12
  52. data/lib/rhc/context_helper.rb +19 -5
  53. data/lib/rhc/core_ext.rb +86 -0
  54. data/lib/rhc/exceptions.rb +44 -0
  55. data/lib/rhc/git_helper.rb +59 -0
  56. data/lib/rhc/helpers.rb +86 -5
  57. data/lib/rhc/output_helpers.rb +213 -0
  58. data/lib/rhc/rest/application.rb +134 -67
  59. data/lib/rhc/rest/base.rb +48 -0
  60. data/lib/rhc/rest/cartridge.rb +40 -44
  61. data/lib/rhc/rest/client.rb +127 -59
  62. data/lib/rhc/rest/domain.rb +29 -39
  63. data/lib/rhc/rest/gear_group.rb +10 -0
  64. data/lib/rhc/rest/key.rb +8 -23
  65. data/lib/rhc/rest/user.rb +8 -24
  66. data/lib/rhc/rest.rb +22 -11
  67. data/lib/rhc/ssh_key_helpers.rb +47 -0
  68. data/lib/rhc/usage_templates/help.erb +0 -1
  69. data/lib/rhc/version.rb +3 -3
  70. data/lib/rhc/wizard.rb +123 -225
  71. data/lib/rhc-common.rb +43 -62
  72. data/spec/rest_spec_helper.rb +159 -36
  73. data/spec/rhc/cli_spec.rb +29 -1
  74. data/spec/rhc/command_spec.rb +32 -35
  75. data/spec/rhc/commands/alias_spec.rb +123 -0
  76. data/spec/rhc/commands/app_spec.rb +414 -0
  77. data/spec/rhc/commands/cartridge_spec.rb +342 -0
  78. data/spec/rhc/commands/domain_spec.rb +8 -8
  79. data/spec/rhc/commands/setup_spec.rb +17 -6
  80. data/spec/rhc/commands/snapshot_spec.rb +140 -0
  81. data/spec/rhc/commands/sshkey_spec.rb +26 -4
  82. data/spec/rhc/commands/tail_spec.rb +34 -0
  83. data/spec/rhc/commands/threaddump_spec.rb +83 -0
  84. data/spec/rhc/config_spec.rb +39 -13
  85. data/spec/rhc/context_spec.rb +51 -0
  86. data/spec/rhc/helpers_spec.rb +52 -12
  87. data/spec/rhc/rest_application_spec.rb +16 -3
  88. data/spec/rhc/rest_client_spec.rb +144 -36
  89. data/spec/rhc/rest_spec.rb +1 -1
  90. data/spec/rhc/wizard_spec.rb +133 -232
  91. data/spec/spec_helper.rb +4 -3
  92. metadata +56 -31
  93. data/features/support/ssh.sh +0 -2
  94. data/spec/rhc/common_spec.rb +0 -49
@@ -0,0 +1,342 @@
1
+ require 'spec_helper'
2
+ require 'rest_spec_helper'
3
+ require 'rhc/commands/cartridge'
4
+ require 'rhc/config'
5
+
6
+ describe RHC::Commands::Cartridge do
7
+
8
+ def exit_with_code_and_message(code, message = nil)
9
+ expect{ run }.should exit_with_code(code)
10
+ run_output.should match(message) if message
11
+ end
12
+
13
+ def succeed_with_message(message = "Success")
14
+ exit_with_code_and_message(0,message)
15
+ end
16
+
17
+ def fail_with_message(message,code = 1)
18
+ exit_with_code_and_message(code, message)
19
+ end
20
+
21
+ def fail_with_code(code = 1)
22
+ exit_with_code_and_message(code)
23
+ end
24
+
25
+
26
+ before(:each) do
27
+ RHC::Config.set_defaults
28
+ end
29
+
30
+ describe 'run' do
31
+ let(:arguments) { ['cartridge', '--trace', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
32
+
33
+ context 'when run' do
34
+ before(:each) do
35
+ @rc = MockRestClient.new
36
+ end
37
+ it {
38
+ succeed_with_message "mock_cart-1, mock_cart-2, unique_mock_cart-1"
39
+ }
40
+ end
41
+ end
42
+
43
+ describe 'alias app cartridge' do
44
+ let(:arguments) { ['app', 'cartridge', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
45
+
46
+ context 'when run' do
47
+ before(:each) do
48
+ @rc = MockRestClient.new
49
+ end
50
+ it {
51
+ succeed_with_message "mock_cart-1, mock_cart-2, unique_mock_cart-1"
52
+ }
53
+ end
54
+ end
55
+
56
+ describe 'cartridge add' do
57
+ let(:arguments) { ['cartridge', 'add', 'mock_cart-1', '--app', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
58
+
59
+ context 'when run' do
60
+ before(:each) do
61
+ @rc = MockRestClient.new
62
+ domain = @rc.add_domain("mock_domain")
63
+ app = domain.add_application("app1", "mock_type")
64
+ end
65
+ it {
66
+ succeed_with_message
67
+ }
68
+ end
69
+ end
70
+
71
+ describe 'cartridge add with app context' do
72
+ let(:arguments) { ['cartridge', 'add', 'mock_cart-1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
73
+
74
+ context 'when run' do
75
+ before(:each) do
76
+ @rc = MockRestClient.new
77
+ domain = @rc.add_domain("mock_domain")
78
+ app = domain.add_application("app1", "mock_type")
79
+ instance = RHC::Commands::Cartridge.new
80
+ instance.stub(:git_config_get) { |key| app.uuid if key == "rhc.app-uuid" }
81
+ RHC::Commands::Cartridge.stub(:new) { instance }
82
+ end
83
+ it {
84
+ succeed_with_message
85
+ }
86
+ end
87
+ end
88
+
89
+ describe 'cartridge add with no app context' do
90
+ let(:arguments) { ['cartridge', 'add', 'mock_cart-1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
91
+
92
+ context 'when run' do
93
+ before(:each) do
94
+ @rc = MockRestClient.new
95
+ domain = @rc.add_domain("mock_domain")
96
+ app = domain.add_application("app1", "mock_type")
97
+ instance = RHC::Commands::Cartridge.new
98
+ instance.stub(:git_config_get) { |key| "" if key == "rhc.app-uuid" }
99
+ RHC::Commands::Cartridge.stub(:new) { instance }
100
+ end
101
+ it {
102
+ fail_with_code
103
+ }
104
+ end
105
+ end
106
+
107
+ describe 'alias app cartridge add' do
108
+ let(:arguments) { ['app', 'cartridge', 'add', 'unique_mock_cart', '--app', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
109
+
110
+ context 'when run' do
111
+ before(:each) do
112
+ @rc = MockRestClient.new
113
+ domain = @rc.add_domain("mock_domain")
114
+ app = domain.add_application("app1", "mock_type")
115
+ end
116
+ it {
117
+ succeed_with_message
118
+ }
119
+ end
120
+ end
121
+
122
+ describe 'cartridge add no cart found error' do
123
+ let(:arguments) { ['cartridge', 'add', 'nomatch_cart', '--app', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
124
+
125
+ context 'when run' do
126
+ before(:each) do
127
+ @rc = MockRestClient.new
128
+ domain = @rc.add_domain("mock_domain")
129
+ app = domain.add_application("app1", "mock_type")
130
+ end
131
+ it {
132
+ fail_with_code 154
133
+ }
134
+ end
135
+ end
136
+
137
+ describe 'cartridge add too many carts found error' do
138
+ let(:arguments) { ['cartridge', 'add', 'mock_cart', '-a', 'app1','--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
139
+
140
+ context 'when run' do
141
+ before(:each) do
142
+ @rc = MockRestClient.new
143
+ domain = @rc.add_domain("mock_domain")
144
+ app = domain.add_application("app1", "mock_type")
145
+ end
146
+ it {
147
+ fail_with_code 155
148
+ }
149
+ end
150
+ end
151
+
152
+ describe 'cartridge remove without confirming' do
153
+ let(:arguments) { ['cartridge', 'remove', 'mock_cart-1', '-a', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
154
+
155
+ context 'when run' do
156
+ before(:each) do
157
+ @rc = MockRestClient.new
158
+ domain = @rc.add_domain("mock_domain")
159
+ app = domain.add_application("app1", "mock_type")
160
+ app.add_cartridge('mock_cart-1')
161
+ end
162
+ it {
163
+ fail_with_message "Removing a cartridge is a destructive operation"
164
+ }
165
+ end
166
+ end
167
+
168
+ describe 'cartridge remove' do
169
+ let(:arguments) { ['cartridge', 'remove', 'mock_cart-1', '--confirm', '--trace', '-a', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
170
+
171
+ context 'when run' do
172
+ before(:each) do
173
+ @rc = MockRestClient.new
174
+ domain = @rc.add_domain("mock_domain")
175
+ @app = domain.add_application("app1", "mock_type")
176
+ end
177
+ it "should remove cartridge" do
178
+ @app.add_cartridge('mock_cart-1')
179
+ expect { run }.should exit_with_code(0)
180
+ # framework cart should be the only one listed
181
+ @app.cartridges.length.should == 1
182
+ end
183
+ it "should raise cartridge not found exception" do
184
+ expect { run }.should raise_error RHC::CartridgeNotFoundException
185
+ end
186
+ end
187
+ end
188
+
189
+ describe 'cartridge status' do
190
+ let(:arguments) { ['cartridge', 'status', 'mock_cart-1', '-a', 'app1','--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
191
+
192
+ before(:each) do
193
+ @rc = MockRestClient.new
194
+ @domain = @rc.add_domain("mock_domain")
195
+ @app = @domain.add_application("app1", "mock_type")
196
+ @app.add_cartridge('mock_cart-1')
197
+ end
198
+
199
+ context 'when run' do
200
+ it { run_output.should match('started') }
201
+ end
202
+
203
+ context 'when run with cart stopped' do
204
+ before(:each) { @app.find_cartridge('mock_cart-1').stop }
205
+ it { run_output.should match('stopped') }
206
+ end
207
+ end
208
+
209
+ describe 'cartridge start' do
210
+ let(:arguments) { ['cartridge', 'start', 'mock_cart-1', '-a', 'app1','--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
211
+
212
+ context 'when run' do
213
+ before(:each) do
214
+ @rc = MockRestClient.new
215
+ domain = @rc.add_domain("mock_domain")
216
+ app = domain.add_application("app1", "mock_type")
217
+ app.add_cartridge('mock_cart-1')
218
+ end
219
+ it { run_output.should match('start') }
220
+ end
221
+ end
222
+
223
+ describe 'cartridge stop' do
224
+ let(:arguments) { ['cartridge', 'stop', 'mock_cart-1', '-a', 'app1','--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
225
+
226
+ context 'when run' do
227
+ before(:each) do
228
+ @rc = MockRestClient.new
229
+ domain = @rc.add_domain("mock_domain")
230
+ app = domain.add_application("app1", "mock_type")
231
+ app.add_cartridge('mock_cart-1')
232
+ end
233
+ it { run_output.should match('stop') }
234
+ end
235
+ end
236
+
237
+ describe 'cartridge restart' do
238
+ let(:arguments) { ['cartridge', 'restart', 'mock_cart-1', '-a', 'app1','--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
239
+
240
+ context 'when run' do
241
+ before(:each) do
242
+ @rc = MockRestClient.new
243
+ domain = @rc.add_domain("mock_domain")
244
+ app = domain.add_application("app1", "mock_type")
245
+ app.add_cartridge('mock_cart-1')
246
+ end
247
+ it { run_output.should match('restart') }
248
+ end
249
+ end
250
+
251
+ describe 'cartridge reload' do
252
+ let(:arguments) { ['cartridge', 'reload', 'mock_cart-1', '-a', 'app1','--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
253
+
254
+ context 'when run' do
255
+ before(:each) do
256
+ @rc = MockRestClient.new
257
+ domain = @rc.add_domain("mock_domain")
258
+ app = domain.add_application("app1", "mock_type")
259
+ app.add_cartridge('mock_cart-1')
260
+ end
261
+ it { run_output.should match('reload') }
262
+ end
263
+ end
264
+
265
+ describe 'cartridge show' do
266
+ let(:arguments) { ['cartridge', 'show', 'mock_cart-1', '-a', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
267
+
268
+ before(:each) do
269
+ @rc = MockRestClient.new
270
+ domain = @rc.add_domain("mock_domain")
271
+ app = domain.add_application("app1", "mock_type")
272
+ app.add_cartridge('mock_cart-1')
273
+ end
274
+
275
+ context 'when run' do
276
+ it { run_output.should match('Connection URL = http://fake.url') }
277
+ end
278
+ end
279
+
280
+ describe 'cartridge show scaled' do
281
+ let(:arguments) { ['cartridge', 'show', 'mock_type', '-a', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
282
+
283
+ context 'when run' do
284
+ before(:each) do
285
+ @rc = MockRestClient.new
286
+ domain = @rc.add_domain("mock_domain")
287
+ app = domain.add_application("app1", "mock_type", true)
288
+ end
289
+ it { run_output.should match('Scaling Info') }
290
+ it { run_output.should match('Current = 2') }
291
+ it { run_output.should match('Minimum = 2') }
292
+ it { run_output.should match('Maximum = available gears') }
293
+ end
294
+ end
295
+
296
+ describe 'cartridge scale' do
297
+ let(:arguments) { ['cartridge', 'scale', @cart_type || 'mock_type', '-a', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] | (@extra_args || []) }
298
+
299
+ before(:each) do
300
+ @rc = MockRestClient.new
301
+ domain = @rc.add_domain("mock_domain")
302
+ app = domain.add_application("app1", "mock_type", scalable)
303
+ end
304
+
305
+ context 'when run with scalable app' do
306
+ let(:scalable){ true }
307
+
308
+ it "with no values" do
309
+ fail_with_message "Must provide either a min or max"
310
+ end
311
+
312
+ it "with a min value" do
313
+ @extra_args = ["--min","6"]
314
+ succeed_with_message "Minimum = 6"
315
+ end
316
+
317
+ it "with a max value" do
318
+ @extra_args = ["--max","3"]
319
+ succeed_with_message 'Maximum = 3'
320
+ end
321
+
322
+ it "with an invalid min value" do
323
+ @extra_args = ["--min","a"]
324
+ fail_with_message "invalid argument: --min"
325
+ end
326
+
327
+ it "with an invalid max value" do
328
+ @extra_args = ["--max","a"]
329
+ fail_with_message "invalid argument: --max"
330
+ end
331
+ end
332
+
333
+ context 'when run with a nonscalable app' do
334
+ let(:scalable){ false }
335
+
336
+ it "with a min value" do
337
+ @extra_args = ["--min","6"]
338
+ fail_with_message "Cartridge is not scalable"
339
+ end
340
+ end
341
+ end
342
+ end
@@ -39,8 +39,8 @@ describe RHC::Commands::Domain do
39
39
  it { expect { run }.should exit_with_code(0) }
40
40
  it "should match output" do
41
41
  output = run_output
42
- output.should match(/Applications in onedomain\:/)
43
- output.should match(/No applications. You can use/)
42
+ output.should match(/Applications in onedomain/)
43
+ output.should match(/No applications. You can use/)
44
44
  end
45
45
  end
46
46
 
@@ -53,8 +53,8 @@ describe RHC::Commands::Domain do
53
53
  it { expect { run }.should exit_with_code(0) }
54
54
  it "should match output" do
55
55
  output = run_output
56
- output.should match("Applications in firstdomain\:")
57
- output.should_not match("Applications in seconddomain\:")
56
+ output.should match("Applications in firstdomain")
57
+ output.should_not match("Applications in seconddomain")
58
58
  end
59
59
  end
60
60
 
@@ -90,7 +90,7 @@ describe RHC::Commands::Domain do
90
90
  it "should match output" do
91
91
  output = run_output
92
92
  output.should match("app_no_carts")
93
- output.should match("Cartridges: none")
93
+ output.should match(/Cartridges$\n\s+[=]*\s+None/)
94
94
  end
95
95
  end
96
96
  end
@@ -112,7 +112,7 @@ describe RHC::Commands::Domain do
112
112
  end
113
113
 
114
114
  describe 'update' do
115
- let(:arguments) { ['domain', 'update', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password', 'alterednamespace'] }
115
+ let(:arguments) { ['domain', 'update', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password', 'olddomain', 'alterednamespace'] }
116
116
 
117
117
  context 'when no issues with ' do
118
118
  before(:each) do
@@ -136,12 +136,12 @@ describe RHC::Commands::Domain do
136
136
  expect { run }.should exit_with_code(127)
137
137
  @rc.domains.empty?.should be_true
138
138
  end
139
- it { run_output.should match("No domains are registered to the user test@test.foo") }
139
+ it { run_output.should match("does not exist") }
140
140
  end
141
141
  end
142
142
 
143
143
  describe 'alter alias' do
144
- let(:arguments) { ['domain', 'alter', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password', 'alterednamespace'] }
144
+ let(:arguments) { ['domain', 'alter', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password', 'olddomain', 'alterednamespace'] }
145
145
 
146
146
  context 'when no issues with ' do
147
147
  before(:each) do
@@ -7,17 +7,15 @@ require 'webmock/rspec'
7
7
  # just test the command runner as we already have extensive wizard tests
8
8
  describe RHC::Commands::Setup do
9
9
 
10
- before(:each) do
11
- RHC::Config.set_defaults
12
- end
10
+ before(:each) { RHC::Config.set_defaults }
13
11
 
14
12
  describe 'run' do
15
13
  let(:arguments) { ['setup', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
16
14
 
17
15
  before(:each) do
18
- @wizard = mock('wizard')
19
- @wizard.stub!(:run).and_return(true)
20
- RHC::RerunWizard.stub!(:new) { @wizard }
16
+ @wizard = mock('wizard')
17
+ @wizard.stub!(:run).and_return(true)
18
+ RHC::RerunWizard.stub!(:new) { @wizard }
21
19
  end
22
20
 
23
21
  context 'when no issues' do
@@ -34,6 +32,19 @@ describe RHC::Commands::Setup do
34
32
  end
35
33
  end
36
34
 
35
+ context 'when -l is used to specify the user name' do
36
+ let(:arguments) { ['setup', '-l', 'test@test.foo'] }
37
+ # 'y' for the password prompt
38
+ let(:input) { ['', 'y', '', ''] }
39
+
40
+ before(:each){ @rc = MockRestClient.new }
41
+
42
+ it("succeeds"){ FakeFS{ expect { run input }.should exit_with_code 0 } }
43
+ it("sets the user name to the value given by the command line") do
44
+ FakeFS{ run_output( input ).should match 'test@test.foo' }
45
+ end
46
+ end
47
+
37
48
  describe 'help' do
38
49
  let(:arguments) { ['setup', '--help'] }
39
50
 
@@ -0,0 +1,140 @@
1
+ require 'spec_helper'
2
+ require 'rest_spec_helper'
3
+ require 'rhc/commands/snapshot'
4
+ require 'rhc/config'
5
+
6
+ describe RHC::Commands::Snapshot do
7
+
8
+ APP_NAME = 'mockapp'
9
+
10
+ before(:each) do
11
+ RHC::Config.set_defaults
12
+ @rc = MockRestClient.new
13
+ @app = @rc.add_domain("mockdomain").add_application APP_NAME, 'mock-1.0'
14
+ @ssh_uri = URI.parse @app.ssh_url
15
+ filename = APP_NAME + '.tar.gz'
16
+ FileUtils.cp(File.expand_path('../../assets/targz_sample.tar.gz', __FILE__), filename)
17
+ end
18
+
19
+ after(:each) do
20
+ filename = APP_NAME + '.tar.gz'
21
+ File.delete filename if File.exist? filename
22
+ end
23
+
24
+ describe 'snapshot save' do
25
+ let(:arguments) {['snapshot', 'save', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password', '--app', 'mockapp']}
26
+
27
+ context 'when saving a snapshot' do
28
+ before(:each) do
29
+ `(exit 0)`
30
+ Kernel.should_receive(:`).with("ssh #{@ssh_uri.user}@#{@ssh_uri.host} 'snapshot' > #{@app.name}.tar.gz")
31
+ end
32
+ it { expect { run }.should exit_with_code(0) }
33
+ end
34
+
35
+ context 'when failing to save a snapshot' do
36
+ before(:each) do
37
+ `(exit 1)`
38
+ Kernel.should_receive(:`).with("ssh #{@ssh_uri.user}@#{@ssh_uri.host} 'snapshot' > #{@app.name}.tar.gz")
39
+ end
40
+ it { expect { run }.should exit_with_code(130) }
41
+ end
42
+
43
+ context 'when saving a snapshot on windows' do
44
+ before(:each) do
45
+ RHC::Helpers.stub(:windows?) do ; true; end
46
+ RHC::Helpers.stub(:jruby?) do ; false ; end
47
+ RHC::Helpers.stub(:linux?) do ; false ; end
48
+ ssh = mock(Net::SSH)
49
+ Net::SSH.should_receive(:start).with(@ssh_uri.host, @ssh_uri.user).and_yield(ssh)
50
+ ssh.should_receive(:exec!).with("snapshot").and_yield(nil, :stdout, 'foo').and_yield(nil, :stderr, 'foo')
51
+ end
52
+ it { expect { run }.should exit_with_code(0) }
53
+ it { run_output.should match("Success") }
54
+ end
55
+
56
+ context 'when timing out on windows' do
57
+ before(:each) do
58
+ RHC::Helpers.stub(:windows?) do ; true; end
59
+ RHC::Helpers.stub(:jruby?) do ; false ; end
60
+ RHC::Helpers.stub(:linux?) do ; false ; end
61
+ ssh = mock(Net::SSH)
62
+ Net::SSH.should_receive(:start).with(@ssh_uri.host, @ssh_uri.user).and_raise(Timeout::Error)
63
+ end
64
+ it { expect { run }.should exit_with_code(130) }
65
+ end
66
+
67
+ end
68
+
69
+ describe 'snapshot restore' do
70
+ let(:arguments) {['snapshot', 'restore', '--noprompt', '-l', 'test@test.foo', '-p', 'password', '--app', 'mockapp']}
71
+
72
+ context 'when restoring a snapshot' do
73
+ before(:each) do
74
+ File.stub!(:exists?).and_return(true)
75
+ RHC::TarGz.stub!(:contains).and_return(true)
76
+ `(exit 0)`
77
+ Kernel.should_receive(:`).with("cat #{@app.name}.tar.gz | ssh #{@ssh_uri.user}@#{@ssh_uri.host} 'restore INCLUDE_GIT'")
78
+ end
79
+ it { expect { run }.should exit_with_code(0) }
80
+ end
81
+
82
+ context 'when restoring a snapshot and failing to ssh' do
83
+ before(:each) do
84
+ File.stub!(:exists?).and_return(true)
85
+ RHC::TarGz.stub!(:contains).and_return(true)
86
+ Kernel.should_receive(:`).with("cat #{@app.name}.tar.gz | ssh #{@ssh_uri.user}@#{@ssh_uri.host} 'restore INCLUDE_GIT'")
87
+ $?.stub(:exitstatus) { 1 }
88
+ end
89
+ it { expect { run }.should exit_with_code(130) }
90
+ end
91
+
92
+ context 'when restoring a snapshot on windows' do
93
+ before(:each) do
94
+ RHC::Helpers.stub(:windows?) do ; true; end
95
+ RHC::Helpers.stub(:jruby?) do ; false ; end
96
+ RHC::Helpers.stub(:linux?) do ; false ; end
97
+ ssh = mock(Net::SSH)
98
+ session = mock(Net::SSH::Connection::Session)
99
+ channel = mock(Net::SSH::Connection::Channel)
100
+ Net::SSH.should_receive(:start).with(@ssh_uri.host, @ssh_uri.user).and_return(session)
101
+ session.should_receive(:open_channel).and_yield(channel)
102
+ channel.should_receive(:exec).with("restore INCLUDE_GIT").and_yield(nil, nil)
103
+ channel.should_receive(:on_data).and_yield(nil, 'foo')
104
+ channel.should_receive(:on_extended_data).and_yield(nil, nil, 'foo')
105
+ channel.should_receive(:on_close).and_yield(nil)
106
+ lines = ''
107
+ File.open(File.expand_path('../../assets/targz_sample.tar.gz', __FILE__), 'rb') do |file|
108
+ file.chunk(1024) do |chunk|
109
+ lines << chunk
110
+ end
111
+ end
112
+ channel.should_receive(:send_data).with(lines)
113
+ channel.should_receive(:eof!)
114
+ session.should_receive(:loop)
115
+ end
116
+ it { expect { run }.should exit_with_code(0) }
117
+ end
118
+
119
+ context 'when timing out on windows' do
120
+ before(:each) do
121
+ RHC::Helpers.stub(:windows?) do ; true; end
122
+ RHC::Helpers.stub(:jruby?) do ; false ; end
123
+ RHC::Helpers.stub(:linux?) do ; false ; end
124
+ ssh = mock(Net::SSH)
125
+ Net::SSH.should_receive(:start).with(@ssh_uri.host, @ssh_uri.user).and_raise(Timeout::Error)
126
+ end
127
+ it { expect { run }.should exit_with_code(130) }
128
+ end
129
+
130
+ end
131
+
132
+ describe 'snapshot restore file not found' do
133
+ let(:arguments) {['snapshot', 'restore', '--noprompt', '-l', 'test@test.foo', '-p', 'password', '--app', 'mockapp', '-f', 'foo.tar.gz']}
134
+ context 'when restoring a snapshot' do
135
+ it { expect { run }.should exit_with_code(130) }
136
+ end
137
+ end
138
+
139
+ end
140
+
@@ -58,14 +58,14 @@ describe RHC::Commands::Sshkey do
58
58
  end
59
59
  end
60
60
  end
61
-
61
+
62
62
  context "when adding an invalid key" do
63
63
  let(:arguments) { %w[sshkey add --noprompt --config test.conf -l test@test.foo -p password foobar id_rsa.pub] }
64
-
64
+
65
65
  before :each do
66
66
  @rc = MockRestClient.new
67
67
  end
68
-
68
+
69
69
  it "fails to add the key" do
70
70
  FakeFS do
71
71
  keys = @rc.sshkeys
@@ -74,11 +74,33 @@ describe RHC::Commands::Sshkey do
74
74
  f << 'ssh-rsa AADAQABAAABAQCnCOqK7/mmvZ9AtCAerxjAasJ1rSpfuWT4vNm1+O/Fh0Di3chTWjY9a0M2hEnqkqnVG589L9CqCUeT0kdc3Vgw3JEcacSUr1z7tLr9kO+p/D5lSdQYzDGGRFOZ0H6lc/y8iNxWV1VO/sJvKx6cr5zvKIn8Q6GvhVNOxlai0IOb9FJxLGK95GLpZ+elzh8Tc9giy7KfwheAwhV2JoF9uRltE5JP/CNs7w/E29i1Z+jlueuu8RVotLmhSVNJm91Ey7OCtoI1iBE0Wv/SucFe32Qi08RWTM/MaGGz93KQNOVRGjNkosJjPmP1qU6WGBfliDkJAZXB0b6sEcnx1fbVikwZ'
75
75
  end
76
76
  expect { run }.should exit_with_code(128)
77
+ expect { run_output.should match("Name: mockkey") }
77
78
  @rc.sshkeys.length.should == num_keys
78
79
  end
79
80
  end
80
81
  end
81
82
 
83
+ context "when adding an invalid key with --confirm" do
84
+ let(:arguments) { %w[sshkey add --noprompt --confirm --config test.conf -l test@test.foo -p password foobar id_rsa.pub] }
85
+
86
+ before :each do
87
+ @rc = MockRestClient.new
88
+ end
89
+
90
+ it "warns and then adds the key" do
91
+ FakeFS do
92
+ keys = @rc.sshkeys
93
+ num_keys = keys.length
94
+ File.open('id_rsa.pub', 'w') do |f|
95
+ f << 'ssh-rsa AADAQABAAABAQCnCOqK7/mmvZ9AtCAerxjAasJ1rSpfuWT4vNm1+O/Fh0Di3chTWjY9a0M2hEnqkqnVG589L9CqCUeT0kdc3Vgw3JEcacSUr1z7tLr9kO+p/D5lSdQYzDGGRFOZ0H6lc/y8iNxWV1VO/sJvKx6cr5zvKIn8Q6GvhVNOxlai0IOb9FJxLGK95GLpZ+elzh8Tc9giy7KfwheAwhV2JoF9uRltE5JP/CNs7w/E29i1Z+jlueuu8RVotLmhSVNJm91Ey7OCtoI1iBE0Wv/SucFe32Qi08RWTM/MaGGz93KQNOVRGjNkosJjPmP1qU6WGBfliDkJAZXB0b6sEcnx1fbVikwZ'
96
+ end
97
+ expect { run }.should exit_with_code(0)
98
+ expect { run_output.should match("key you are uploading is not recognized") }
99
+ @rc.sshkeys.length.should == num_keys + 1
100
+ end
101
+ end
102
+ end
103
+
82
104
  context "when adding a nonexistent key" do
83
105
  let(:arguments) { %w[sshkey add --noprompt --config test.conf -l test@test.foo -p password foobar id_rsa.pub] }
84
106
 
@@ -138,4 +160,4 @@ describe RHC::Commands::Sshkey do
138
160
  end
139
161
  end
140
162
  end
141
- end
163
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'rest_spec_helper'
3
+ require 'rhc/commands/tail'
4
+ require 'rhc/config'
5
+ describe RHC::Commands::Tail do
6
+ before(:each) do
7
+ RHC::Config.set_defaults
8
+ @rc = MockRestClient.new
9
+ domain = @rc.add_domain("mock-domain-0")
10
+ @app = domain.add_application("mock-app-0", "ruby-1.8.7")
11
+ end
12
+
13
+ describe 'help' do
14
+ let(:arguments) { ['tail', '--help'] }
15
+
16
+ context 'help is run' do
17
+ it "should display help" do
18
+ expect { run }.should exit_with_code(0)
19
+ end
20
+ it('should output usage') { run_output.should match("Usage: rhc tail") }
21
+ end
22
+ end
23
+
24
+ describe 'tail' do
25
+ let(:arguments) { ['tail', 'mock-app-0', '--noprompt', '--trace', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
26
+ context 'tail is run on an unreachable domain' do
27
+ it { expect { run }.should raise_error(SocketError) }
28
+ end
29
+ context 'tail succeeds and exits on Interrupt' do
30
+ before (:each) { @app.stub(:tail) { raise Interrupt.new } }
31
+ it { expect { run }.should exit_with_code(0) }
32
+ end
33
+ end
34
+ end