rhc 0.97.17 → 0.98.16

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 (93) hide show
  1. data/bin/rhc +9 -9
  2. data/bin/rhc-port-forward +3 -0
  3. data/bin/rhc-sshkey +3 -0
  4. data/features/README.md +163 -35
  5. data/features/application.feature +24 -0
  6. data/features/cartridge.feature +24 -0
  7. data/features/client.feature +11 -0
  8. data/features/domain.feature +29 -0
  9. data/features/lib/rhc_helper.rb +14 -0
  10. data/features/lib/rhc_helper/app.rb +2 -8
  11. data/features/lib/rhc_helper/cartridge.rb +1 -7
  12. data/features/lib/rhc_helper/commandify.rb +37 -6
  13. data/features/lib/rhc_helper/domain.rb +5 -1
  14. data/features/lib/rhc_helper/httpify.rb +124 -60
  15. data/features/lib/rhc_helper/loggable.rb +0 -2
  16. data/features/lib/rhc_helper/persistable.rb +12 -2
  17. data/features/lib/rhc_helper/sshkey.rb +29 -0
  18. data/features/multiple_cartridge.feature +17 -0
  19. data/features/sshkey.feature +58 -0
  20. data/features/step_definitions/application_steps.rb +60 -52
  21. data/features/step_definitions/cartridge_steps.rb +22 -24
  22. data/features/step_definitions/client_steps.rb +9 -2
  23. data/features/step_definitions/domain_steps.rb +4 -0
  24. data/features/step_definitions/sshkey_steps.rb +56 -0
  25. data/features/support/assumptions.rb +37 -0
  26. data/features/support/before_hooks.rb +25 -0
  27. data/features/support/env.rb +84 -39
  28. data/features/support/key1 +27 -0
  29. data/features/support/key1.pub +1 -0
  30. data/features/support/key2 +27 -0
  31. data/features/support/key2.pub +1 -0
  32. data/features/support/key3.pub +1 -0
  33. data/features/support/ssh.sh +2 -0
  34. data/features/verify.feature +18 -159
  35. data/lib/rhc-common.rb +8 -21
  36. data/lib/rhc.rb +9 -5
  37. data/lib/rhc/autocomplete.rb +68 -0
  38. data/lib/rhc/autocomplete_templates/rhc.erb +33 -0
  39. data/lib/rhc/cli.rb +9 -6
  40. data/lib/rhc/command_runner.rb +108 -0
  41. data/lib/rhc/commands.rb +66 -132
  42. data/lib/rhc/commands/base.rb +95 -24
  43. data/lib/rhc/commands/domain.rb +33 -50
  44. data/lib/rhc/commands/port-forward.rb +81 -0
  45. data/lib/rhc/commands/setup.rb +1 -1
  46. data/lib/rhc/commands/sshkey.rb +95 -0
  47. data/lib/rhc/config.rb +108 -103
  48. data/lib/rhc/context_helper.rb +19 -0
  49. data/lib/rhc/coverage_helper.rb +1 -1
  50. data/lib/rhc/exceptions.rb +55 -4
  51. data/lib/rhc/help_formatter.rb +2 -3
  52. data/lib/rhc/helpers.rb +31 -23
  53. data/lib/{rhc-rest.rb → rhc/rest.rb} +95 -23
  54. data/lib/{rhc-rest → rhc/rest}/application.rb +1 -1
  55. data/lib/{rhc-rest → rhc/rest}/cartridge.rb +1 -1
  56. data/lib/{rhc-rest → rhc/rest}/client.rb +40 -9
  57. data/lib/{rhc-rest → rhc/rest}/domain.rb +1 -1
  58. data/lib/{rhc-rest → rhc/rest}/key.rb +11 -1
  59. data/lib/{rhc-rest → rhc/rest}/user.rb +1 -1
  60. data/lib/rhc/ssh_key_helpers.rb +10 -1
  61. data/lib/rhc/targz.rb +7 -8
  62. data/lib/rhc/usage_templates/command_help.erb +7 -6
  63. data/lib/rhc/usage_templates/help.erb +6 -9
  64. data/lib/rhc/usage_templates/missing_help.erb +1 -0
  65. data/lib/rhc/version.rb +2 -2
  66. data/lib/rhc/wizard.rb +4 -9
  67. data/spec/coverage_helper.rb +2 -2
  68. data/spec/rest_spec_helper.rb +66 -16
  69. data/spec/rhc/cli_spec.rb +16 -5
  70. data/spec/rhc/command_spec.rb +61 -6
  71. data/spec/rhc/commands/domain_spec.rb +50 -27
  72. data/spec/rhc/commands/port-forward_spec.rb +133 -0
  73. data/spec/rhc/commands/setup_spec.rb +2 -2
  74. data/spec/rhc/commands/sshkey_spec.rb +141 -0
  75. data/spec/rhc/common_spec.rb +1 -1
  76. data/spec/rhc/config_spec.rb +6 -4
  77. data/spec/rhc/helpers_spec.rb +0 -21
  78. data/spec/rhc/rest_application_spec.rb +7 -7
  79. data/spec/rhc/rest_client_spec.rb +87 -24
  80. data/spec/rhc/rest_spec.rb +36 -36
  81. data/spec/rhc/wizard_spec.rb +3 -3
  82. data/spec/spec.opts +1 -0
  83. data/spec/spec_helper.rb +3 -3
  84. metadata +61 -31
  85. data/lib/rhc-rest/exceptions/exceptions.rb +0 -75
  86. data/test/functional/application_test.rb +0 -71
  87. data/test/functional/domain_test.rb +0 -123
  88. data/test/functional/test_credentials.rb +0 -5
  89. data/test/sample-usage.rb +0 -122
  90. data/test/support/server.rb +0 -14
  91. data/test/support/testcase.rb +0 -3
  92. data/test/test_helper.rb +0 -4
  93. data/test/unit/command_test.rb +0 -19
@@ -8,7 +8,7 @@ describe RHC::Commands::Domain do
8
8
  RHC::Config.set_defaults
9
9
  end
10
10
 
11
- describe 'run' do
11
+ describe 'default action' do
12
12
  let(:arguments) { ['domain', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
13
13
 
14
14
  context 'when run with no domains' do
@@ -16,7 +16,19 @@ describe RHC::Commands::Domain do
16
16
  @rc = MockRestClient.new
17
17
  end
18
18
  it { expect { run }.should exit_with_code(0) }
19
- it { run_output.should match("Namespace: No namespaces found") }
19
+ it { run_output.should match(/No domain exists. You can use/) }
20
+ end
21
+ end
22
+
23
+ describe 'show' do
24
+ let(:arguments) { ['domain', 'show', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
25
+
26
+ context 'when run with no domains' do
27
+ before(:each) do
28
+ @rc = MockRestClient.new
29
+ end
30
+ it { expect { run }.should exit_with_code(0) }
31
+ it { run_output.should match(/No domain exists. You can use/) }
20
32
  end
21
33
 
22
34
  context 'when run with one domain no apps' do
@@ -27,8 +39,8 @@ describe RHC::Commands::Domain do
27
39
  it { expect { run }.should exit_with_code(0) }
28
40
  it "should match output" do
29
41
  output = run_output
30
- output.should match("Namespace onedomain's Applications")
31
- output.should match("No applications found")
42
+ output.should match(/Applications in onedomain\:/)
43
+ output.should match(/No applications. You can use/)
32
44
  end
33
45
  end
34
46
 
@@ -41,10 +53,8 @@ describe RHC::Commands::Domain do
41
53
  it { expect { run }.should exit_with_code(0) }
42
54
  it "should match output" do
43
55
  output = run_output
44
- output.should match("Namespace\\(0\\): firstdomain")
45
- output.should match("Namespace\\(1\\): seconddomain")
46
- output.should match("Namespace firstdomain's Applications")
47
- output.should match("Namespace seconddomain's Applications")
56
+ output.should match("Applications in firstdomain\:")
57
+ output.should_not match("Applications in seconddomain\:")
48
58
  end
49
59
  end
50
60
 
@@ -62,7 +72,6 @@ describe RHC::Commands::Domain do
62
72
  it "should match output" do
63
73
  output = run_output
64
74
  output.should match("app_no_carts")
65
- output.should match("None")
66
75
  output.should match("app_multi_carts")
67
76
  output.should match("testframework-1.0")
68
77
  output.should match("testcart-1")
@@ -70,6 +79,20 @@ describe RHC::Commands::Domain do
70
79
  output.should match("testcart-3")
71
80
  end
72
81
  end
82
+
83
+ context 'when run with an app without cartridges' do
84
+ before(:each) do
85
+ @rc = MockRestClient.new
86
+ d = @rc.add_domain("appdomain")
87
+ a = d.add_application("app_no_carts")
88
+ end
89
+ it { expect { run }.should exit_with_code(0) }
90
+ it "should match output" do
91
+ output = run_output
92
+ output.should match("app_no_carts")
93
+ output.should match("Cartridges: none")
94
+ end
95
+ end
73
96
  end
74
97
 
75
98
  describe 'create' do
@@ -84,7 +107,7 @@ describe RHC::Commands::Domain do
84
107
  expect { run }.should exit_with_code(0)
85
108
  @rc.domains[0].id.should == 'testnamespace'
86
109
  end
87
- it { run_output.should match(/'testnamespace'\n\nRESULT:\n.*Success/m) }
110
+ it { run_output.should match(/'testnamespace'.*?RESULT:.*?Success/m) }
88
111
  end
89
112
  end
90
113
 
@@ -101,7 +124,7 @@ describe RHC::Commands::Domain do
101
124
  expect { run }.should exit_with_code(0)
102
125
  @rc.domains[0].id.should == 'alterednamespace'
103
126
  end
104
- it { run_output.should match(/Updating domain 'olddomain' to namespace 'alterednamespace'\n\nRESULT:\n.*Success/m) }
127
+ it { run_output.should match(/Changing namespace 'olddomain' to 'alterednamespace'.*?RESULT:.*?Success/m) }
105
128
  end
106
129
 
107
130
  context 'when there is no domain' do
@@ -130,7 +153,7 @@ describe RHC::Commands::Domain do
130
153
  expect { run }.should exit_with_code(0)
131
154
  @rc.domains[0].id.should == 'alterednamespace'
132
155
  end
133
- it { run_output.should match(/Updating domain 'olddomain' to namespace 'alterednamespace'\n\nRESULT:\n.*Success/m) }
156
+ it { run_output.should match(/Changing namespace 'olddomain' to 'alterednamespace'.*?RESULT:.*?Success/m) }
134
157
  end
135
158
  end
136
159
 
@@ -161,6 +184,19 @@ describe RHC::Commands::Domain do
161
184
  end
162
185
  it { run_output.should match("Domain deleteme does not exist") }
163
186
  end
187
+
188
+ context 'when there are applications on the domain' do
189
+ before(:each) do
190
+ @rc = MockRestClient.new
191
+ domain = @rc.add_domain("deleteme")
192
+ domain.add_application 'testapp1', 'mock-1.0'
193
+ end
194
+ it "should error out" do
195
+ expect { run }.should exit_with_code(128)
196
+ @rc.domains[0].id.should == 'deleteme'
197
+ end
198
+ it { run_output.should match("Domain contains applications.*?Delete applications first.") }
199
+ end
164
200
  end
165
201
 
166
202
  describe 'alias destroy' do
@@ -177,26 +213,13 @@ describe RHC::Commands::Domain do
177
213
  @rc.domains.empty?.should be_true
178
214
  end
179
215
  end
180
-
181
- context 'when domain contains app' do
182
- before(:each) do
183
- @rc = MockRestClient.new
184
- d = @rc.add_domain("deleteme")
185
- d.add_application("app1", "testframework-1.0")
186
- end
187
-
188
- it "should fail to delete domain" do
189
- expect { run }.should exit_with_code(128)
190
- @rc.domains.empty?.should be_false
191
- end
192
- end
193
216
  end
194
217
 
195
218
  describe 'status' do
196
219
  let(:arguments) { ['domain', 'status', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
197
220
 
198
221
  before(:each) do
199
- Kernel.stub!(:system) do |cmd|
222
+ Kernel.stub!(:system) do |cmd|
200
223
  @cmd = cmd
201
224
  # run the true command to get $?.exitstatus == 0
202
225
  system("true")
@@ -213,7 +236,7 @@ describe RHC::Commands::Domain do
213
236
  end
214
237
 
215
238
  describe 'help' do
216
- let(:arguments) { ['domain', 'help'] }
239
+ let(:arguments) { ['domain', '--help'] }
217
240
 
218
241
  context 'help is run' do
219
242
  it "should display help" do
@@ -0,0 +1,133 @@
1
+ require 'spec_helper'
2
+ require 'rhc/commands/port-forward'
3
+ require 'rhc/config'
4
+ require 'uri'
5
+
6
+ describe RHC::Commands::PortForward do
7
+
8
+ before(:each) do
9
+ RHC::Config.set_defaults
10
+ end
11
+
12
+ describe 'run' do
13
+ let(:arguments) { ['port-forward', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password', '--app', 'mockapp'] }
14
+
15
+ context 'when port forwarding a scaled app' do
16
+ before(:each) do
17
+ @rc = MockRestClient.new
18
+ domain = @rc.add_domain("mockdomain")
19
+ domain.add_application 'mockapp', 'mock-1.0', true
20
+ end
21
+ it "should error out" do
22
+ expect { run }.should exit_with_code(128)
23
+ end
24
+ it "should match the app state" do
25
+ @rc.domains[0].id.should == 'mockdomain'
26
+ @rc.domains[0].applications.size.should == 1
27
+ @rc.domains[0].applications[0].name.should == 'mockapp'
28
+ end
29
+ it { run_output.should match("This utility does not currently support scaled applications. You will need to set up port forwarding manually.") }
30
+ end
31
+
32
+ context 'when port forwarding an app without ports to forward' do
33
+ before(:each) do
34
+ @rc = MockRestClient.new
35
+ domain = @rc.add_domain("mockdomain")
36
+ app = domain.add_application 'mockapp', 'mock-1.0'
37
+ uri = URI.parse app.ssh_url
38
+ ssh = mock(Net::SSH)
39
+ Net::SSH.should_receive(:start).with(uri.host, uri.user).and_yield(ssh)
40
+ ssh.should_receive(:exec!).with("rhc-list-ports").and_yield(nil, :stderr, '127.0.0.1:3306')
41
+ end
42
+ it "should error out as no ports to forward" do
43
+ expect { run }.should exit_with_code(102)
44
+ @rc.domains[0].id.should == 'mockdomain'
45
+ @rc.domains[0].applications.size.should == 1
46
+ @rc.domains[0].applications[0].name.should == 'mockapp'
47
+ end
48
+ it { run_output.should match("no available ports to forward.") }
49
+ end
50
+
51
+ context 'when port forwarding an app with permission denied ports' do
52
+ before(:each) do
53
+ @rc = MockRestClient.new
54
+ domain = @rc.add_domain("mockdomain")
55
+ app = domain.add_application 'mockapp', 'mock-1.0'
56
+ ssh = mock(Net::SSH)
57
+ uri = URI.parse app.ssh_url
58
+ Net::SSH.should_receive(:start).with(uri.host, uri.user).and_yield(ssh)
59
+ ssh.should_receive(:exec!).with("rhc-list-ports").and_yield(nil, :stderr, 'permission denied')
60
+ end
61
+ it "should error out as permission denied" do
62
+ expect { run }.should exit_with_code(129)
63
+ @rc.domains[0].id.should == 'mockdomain'
64
+ @rc.domains[0].applications.size.should == 1
65
+ @rc.domains[0].applications[0].name.should == 'mockapp'
66
+ end
67
+ it { run_output.should match("Permission denied") }
68
+ end
69
+
70
+ context 'when port forwarding an app with ports to forward' do
71
+ before(:each) do
72
+ @rc = MockRestClient.new
73
+ domain = @rc.add_domain("mockdomain")
74
+ app = domain.add_application 'mockapp', 'mock-1.0'
75
+ ssh = mock(Net::SSH)
76
+ uri = URI.parse app.ssh_url
77
+ Net::SSH.should_receive(:start).with(uri.host, uri.user).and_yield(ssh).twice
78
+ ssh.should_receive(:exec!).with("rhc-list-ports").and_yield(nil, :stdout, '127.0.0.1:3306')
79
+ forward = mock(Net::SSH::Service::Forward)
80
+ ssh.should_receive(:forward).and_return(forward)
81
+ forward.should_receive(:local).with('127.0.0.1', 3306, '127.0.0.1', 3306)
82
+ ssh.should_receive(:loop)
83
+ end
84
+ it "should error out as no ports to forward" do
85
+ expect { run }.should exit_with_code(0)
86
+ @rc.domains[0].id.should == 'mockdomain'
87
+ @rc.domains[0].applications.size.should == 1
88
+ @rc.domains[0].applications[0].name.should == 'mockapp'
89
+ end
90
+ it { run_output.should include("Forwarding ports, use ctl + c to stop") }
91
+ end
92
+
93
+ context 'when port forwarding an app with ports to forward' do
94
+ before(:each) do
95
+ @rc = MockRestClient.new
96
+ domain = @rc.add_domain("mockdomain")
97
+ app = domain.add_application 'mockapp', 'mock-1.0'
98
+ end
99
+ it "should error out if ssh host is unreachable" do
100
+ expect { run }.should exit_with_code(1)
101
+ @rc.domains[0].id.should == 'mockdomain'
102
+ @rc.domains[0].applications.size.should == 1
103
+ @rc.domains[0].applications[0].name.should == 'mockapp'
104
+ end
105
+ it { run_output.should include("Error trying to forward ports.") }
106
+ end
107
+
108
+ context 'when port forwarding an app with ports to forward' do
109
+ before(:each) do
110
+ @rc = MockRestClient.new
111
+ domain = @rc.add_domain("mockdomain")
112
+ app = domain.add_application 'mockapp', 'mock-1.0'
113
+ ssh = mock(Net::SSH)
114
+ uri = URI.parse app.ssh_url
115
+ Net::SSH.should_receive(:start).with(uri.host, uri.user).and_yield(ssh).twice
116
+ ssh.should_receive(:exec!).with("rhc-list-ports").and_yield(nil, :stdout, '127.0.0.1:3306')
117
+ forward = mock(Net::SSH::Service::Forward)
118
+ ssh.should_receive(:forward).and_return(forward)
119
+ forward.should_receive(:local).with('127.0.0.1', 3306, '127.0.0.1', 3306)
120
+ ssh.should_receive(:loop).and_raise(Interrupt.new)
121
+ end
122
+ it "should exit when user interrupts" do
123
+ expect { run }.should exit_with_code(0)
124
+ @rc.domains[0].id.should == 'mockdomain'
125
+ @rc.domains[0].applications.size.should == 1
126
+ @rc.domains[0].applications[0].name.should == 'mockapp'
127
+ end
128
+ it { run_output.should include("Ending port forward") }
129
+ end
130
+
131
+ end
132
+ end
133
+
@@ -35,14 +35,14 @@ describe RHC::Commands::Setup do
35
35
  end
36
36
 
37
37
  describe 'help' do
38
- let(:arguments) { ['setup', 'help'] }
38
+ let(:arguments) { ['setup', '--help'] }
39
39
 
40
40
  context 'help is run' do
41
41
  it "should display help" do
42
42
  @wizard.stub!(:run).and_return(true)
43
43
  expect { run }.should exit_with_code(0)
44
44
  end
45
- it('should output usage') { run_output.should match("Runs the setup wizard") }
45
+ it('should output usage') { run_output.should match("Easy to use wizard for getting started") }
46
46
  end
47
47
  end
48
48
  end
@@ -0,0 +1,141 @@
1
+ require 'spec_helper'
2
+ require 'rhc/commands/sshkey'
3
+ require 'rhc/config'
4
+
5
+
6
+ describe RHC::Commands::Sshkey do
7
+ before(:each) do
8
+ RHC::Config.set_defaults
9
+ end
10
+
11
+ describe 'list' do
12
+
13
+ context "when run with list command" do
14
+
15
+ let(:arguments) { %w[sshkey list --noprompt --config test.conf -l test@test.foo -p password --trace] }
16
+
17
+ before(:each) do
18
+ @rc = MockRestClient.new
19
+ end
20
+
21
+ it { expect { run }.should exit_with_code(0) }
22
+ it { run_output.should match("Name: mockkey") }
23
+ end
24
+ end
25
+
26
+ describe 'show' do
27
+
28
+ context "when run with show command" do
29
+
30
+ let(:arguments) { %w[sshkey show mockkey1 --noprompt --config test.conf -l test@test.foo -p password --trace] }
31
+
32
+ before(:each) do
33
+ @rc = MockRestClient.new
34
+ end
35
+
36
+ it { expect { run }.should exit_with_code(0) }
37
+ it { run_output.should match("Name: mockkey1") }
38
+ end
39
+ end
40
+
41
+ describe "add" do
42
+ context "when adding a valid key" do
43
+ let(:arguments) { %w[sshkey add --noprompt --config test.conf -l test@test.foo -p password foobar id_rsa.pub] }
44
+
45
+ before :each do
46
+ @rc = MockRestClient.new
47
+ end
48
+
49
+ it 'adds the key' do
50
+ FakeFS do
51
+ keys = @rc.sshkeys
52
+ num_keys = keys.length
53
+ File.open('id_rsa.pub', 'w') do |f|
54
+ f << 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCnCOqK7/mmvZ9AtCAerxjAasJ1rSpfuWT4vNm1+O/Fh0Di3chTWjY9a0M2hEnqkqnVG589L9CqCUeT0kdc3Vgw3JEcacSUr1z7tLr9kO+p/D5lSdQYzDGGRFOZ0H6lc/y8iNxWV1VO/sJvKx6cr5zvKIn8Q6GvhVNOxlai0IOb9FJxLGK95GLpZ+elzh8Tc9giy7KfwheAwhV2JoF9uRltE5JP/CNs7w/E29i1Z+jlueuu8RVotLmhSVNJm91Ey7OCtoI1iBE0Wv/SucFe32Qi08RWTM/MaGGz93KQNOVRGjNkosJjPmP1qU6WGBfliDkJAZXB0b6sEcnx1fbVikwZ'
55
+ end
56
+ expect { run }.should exit_with_code(0)
57
+ @rc.sshkeys.length.should == num_keys + 1
58
+ end
59
+ end
60
+ end
61
+
62
+ context "when adding an invalid key" do
63
+ let(:arguments) { %w[sshkey add --noprompt --config test.conf -l test@test.foo -p password foobar id_rsa.pub] }
64
+
65
+ before :each do
66
+ @rc = MockRestClient.new
67
+ end
68
+
69
+ it "fails to add the key" do
70
+ FakeFS do
71
+ keys = @rc.sshkeys
72
+ num_keys = keys.length
73
+ File.open('id_rsa.pub', 'w') do |f|
74
+ f << 'ssh-rsa AADAQABAAABAQCnCOqK7/mmvZ9AtCAerxjAasJ1rSpfuWT4vNm1+O/Fh0Di3chTWjY9a0M2hEnqkqnVG589L9CqCUeT0kdc3Vgw3JEcacSUr1z7tLr9kO+p/D5lSdQYzDGGRFOZ0H6lc/y8iNxWV1VO/sJvKx6cr5zvKIn8Q6GvhVNOxlai0IOb9FJxLGK95GLpZ+elzh8Tc9giy7KfwheAwhV2JoF9uRltE5JP/CNs7w/E29i1Z+jlueuu8RVotLmhSVNJm91Ey7OCtoI1iBE0Wv/SucFe32Qi08RWTM/MaGGz93KQNOVRGjNkosJjPmP1qU6WGBfliDkJAZXB0b6sEcnx1fbVikwZ'
75
+ end
76
+ expect { run }.should exit_with_code(128)
77
+ @rc.sshkeys.length.should == num_keys
78
+ end
79
+ end
80
+ end
81
+
82
+ context "when adding a nonexistent key" do
83
+ let(:arguments) { %w[sshkey add --noprompt --config test.conf -l test@test.foo -p password foobar id_rsa.pub] }
84
+
85
+ it "exits with status code Errno::ENOENT::Errno" do
86
+ expect { run }.should exit_with_code(128)
87
+ end
88
+ end
89
+
90
+ context "when attempting to add an existing but inaccessible key" do
91
+ let(:arguments) { %w[sshkey add --noprompt --config test.conf -l test@test.foo -p password foobar inaccessible_key.pub] }
92
+
93
+ before :all do
94
+ @inaccessible_key = 'inaccessible_key.pub'
95
+ File.new(@inaccessible_key, 'w+')
96
+ File.chmod(0000, @inaccessible_key)
97
+ end
98
+
99
+ after :all do
100
+ File.delete @inaccessible_key
101
+ end
102
+
103
+ it "exits with status code Errno::EACCES::Errno" do
104
+ expect { run }.should exit_with_code(128)
105
+ end
106
+
107
+ end
108
+ end
109
+
110
+ describe "remove" do
111
+ context "when removing an existing key" do
112
+ let (:arguments) { %w[sshkey remove --noprompt --config test.conf -l test@test.foo -p password mockkey2] }
113
+
114
+ before :each do
115
+ @rc = MockRestClient.new
116
+ end
117
+
118
+ it 'deletes the key' do
119
+ keys = @rc.sshkeys
120
+ num_keys = keys.length
121
+ expect {run}.should exit_with_code(0)
122
+ @rc.sshkeys.length.should == num_keys - 1
123
+ end
124
+ end
125
+
126
+ context "when removing a nonexistent key" do
127
+ let (:arguments) { %w[sshkey remove --noprompt --config test.conf -l test@test.foo -p password no_match] }
128
+
129
+ before :each do
130
+ @rc = MockRestClient.new
131
+ @keys = @rc.sshkeys
132
+ end
133
+
134
+ it 'leaves keys untouched' do
135
+ num_keys = @keys.length
136
+ expect {run}.should exit_with_code(0)
137
+ @rc.sshkeys.length.should == num_keys
138
+ end
139
+ end
140
+ end
141
+ end