rhc 0.98.16 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/rhc +7 -49
- data/bin/rhc-app +14 -3
- data/bin/rhc-chk +16 -16
- data/bin/rhc-create-app +2 -0
- data/bin/rhc-create-domain +1 -2
- data/bin/rhc-ctl-app +12 -3
- data/bin/rhc-ctl-domain +1 -2
- data/bin/rhc-domain +1 -2
- data/bin/rhc-domain-info +1 -2
- data/bin/rhc-port-forward +1 -2
- data/bin/rhc-snapshot +3 -0
- data/bin/rhc-sshkey +1 -2
- data/bin/rhc-tail-files +1 -1
- data/bin/rhc-user-info +1 -3
- data/features/application.feature +4 -1
- data/features/domain.feature +0 -4
- data/features/geared_application.feature +11 -0
- data/features/lib/rhc_helper/app.rb +16 -5
- data/features/lib/rhc_helper/cartridge.rb +25 -9
- data/features/lib/rhc_helper/commandify.rb +34 -7
- data/features/lib/rhc_helper/domain.rb +2 -2
- data/features/lib/rhc_helper/httpify.rb +24 -14
- data/features/lib/rhc_helper/persistable.rb +1 -1
- data/features/lib/rhc_helper/sshkey.rb +11 -7
- data/features/lib/rhc_helper.rb +5 -3
- data/features/multiple_cartridge.feature +1 -1
- data/features/scaled_application.feature +48 -0
- data/features/sshkey.feature +37 -31
- data/features/step_definitions/application_steps.rb +18 -7
- data/features/step_definitions/cartridge_steps.rb +29 -3
- data/features/step_definitions/domain_steps.rb +2 -2
- data/features/step_definitions/sshkey_steps.rb +34 -34
- data/features/support/assumptions.rb +21 -9
- data/features/support/before_hooks.rb +24 -6
- data/features/support/env.rb +45 -19
- data/lib/rhc/cartridge_helper.rb +27 -0
- data/lib/rhc/cli.rb +1 -1
- data/lib/rhc/command_runner.rb +31 -3
- data/lib/rhc/commands/alias.rb +38 -0
- data/lib/rhc/commands/app.rb +478 -0
- data/lib/rhc/commands/base.rb +42 -12
- data/lib/rhc/commands/cartridge.rb +189 -0
- data/lib/rhc/commands/domain.rb +11 -49
- data/lib/rhc/commands/port-forward.rb +0 -1
- data/lib/rhc/commands/setup.rb +2 -1
- data/lib/rhc/commands/snapshot.rb +118 -0
- data/lib/rhc/commands/sshkey.rb +24 -38
- data/lib/rhc/commands/tail.rb +24 -0
- data/lib/rhc/commands/threaddump.rb +16 -0
- data/lib/rhc/commands.rb +33 -7
- data/lib/rhc/config.rb +28 -12
- data/lib/rhc/context_helper.rb +19 -5
- data/lib/rhc/core_ext.rb +86 -0
- data/lib/rhc/exceptions.rb +44 -0
- data/lib/rhc/git_helper.rb +59 -0
- data/lib/rhc/helpers.rb +86 -5
- data/lib/rhc/output_helpers.rb +213 -0
- data/lib/rhc/rest/application.rb +134 -67
- data/lib/rhc/rest/base.rb +48 -0
- data/lib/rhc/rest/cartridge.rb +40 -44
- data/lib/rhc/rest/client.rb +127 -59
- data/lib/rhc/rest/domain.rb +29 -39
- data/lib/rhc/rest/gear_group.rb +10 -0
- data/lib/rhc/rest/key.rb +8 -23
- data/lib/rhc/rest/user.rb +8 -24
- data/lib/rhc/rest.rb +22 -11
- data/lib/rhc/ssh_key_helpers.rb +47 -0
- data/lib/rhc/usage_templates/help.erb +0 -1
- data/lib/rhc/version.rb +3 -3
- data/lib/rhc/wizard.rb +123 -225
- data/lib/rhc-common.rb +43 -62
- data/spec/rest_spec_helper.rb +159 -36
- data/spec/rhc/cli_spec.rb +29 -1
- data/spec/rhc/command_spec.rb +32 -35
- data/spec/rhc/commands/alias_spec.rb +123 -0
- data/spec/rhc/commands/app_spec.rb +414 -0
- data/spec/rhc/commands/cartridge_spec.rb +342 -0
- data/spec/rhc/commands/domain_spec.rb +8 -8
- data/spec/rhc/commands/setup_spec.rb +17 -6
- data/spec/rhc/commands/snapshot_spec.rb +140 -0
- data/spec/rhc/commands/sshkey_spec.rb +26 -4
- data/spec/rhc/commands/tail_spec.rb +34 -0
- data/spec/rhc/commands/threaddump_spec.rb +83 -0
- data/spec/rhc/config_spec.rb +39 -13
- data/spec/rhc/context_spec.rb +51 -0
- data/spec/rhc/helpers_spec.rb +52 -12
- data/spec/rhc/rest_application_spec.rb +16 -3
- data/spec/rhc/rest_client_spec.rb +144 -36
- data/spec/rhc/rest_spec.rb +1 -1
- data/spec/rhc/wizard_spec.rb +133 -232
- data/spec/spec_helper.rb +4 -3
- metadata +56 -31
- data/features/support/ssh.sh +0 -2
- data/spec/rhc/common_spec.rb +0 -49
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rest_spec_helper'
|
3
|
+
require 'rhc/commands/threaddump'
|
4
|
+
require 'rhc/config'
|
5
|
+
describe RHC::Commands::Threaddump do
|
6
|
+
let(:client_links) { mock_response_links(mock_client_links) }
|
7
|
+
let(:domain_0_links) { mock_response_links(mock_domain_links('mock_domain_0')) }
|
8
|
+
let(:domain_1_links) { mock_response_links(mock_domain_links('mock_domain_1')) }
|
9
|
+
let(:app_0_links) { mock_response_links(mock_app_links('mock_domain_0', 'mock_app_0')) }
|
10
|
+
before(:each) do
|
11
|
+
RHC::Config.set_defaults
|
12
|
+
@rc = MockRestClient.new
|
13
|
+
@rc.add_domain("mock_domain_0").add_application("mock_app_0", "ruby-1.8.7")
|
14
|
+
stub_api_request(:any, client_links['LIST_DOMAINS']['relative']).with(:headers => {'Accept-Encoding'=>'gzip, deflate'}).
|
15
|
+
to_return({ :body => {
|
16
|
+
:type => 'domains',
|
17
|
+
:data =>
|
18
|
+
[{ :id => 'mock_domain_0',
|
19
|
+
:links => mock_response_links(mock_domain_links('mock_domain_0')),
|
20
|
+
},
|
21
|
+
{ :id => 'mock_domain_1',
|
22
|
+
:links => mock_response_links(mock_domain_links('mock_domain_1')),
|
23
|
+
}]
|
24
|
+
}.to_json,
|
25
|
+
:status => 200
|
26
|
+
})
|
27
|
+
stub_api_request(:any, domain_0_links['LIST_APPLICATIONS']['relative']).with(:headers => {'Accept-Encoding'=>'gzip, deflate'}).
|
28
|
+
to_return({ :body => {
|
29
|
+
:type => 'applications',
|
30
|
+
:data =>
|
31
|
+
[{ :domain_id => 'mock_domain_0',
|
32
|
+
:name => 'mock_app_0',
|
33
|
+
:creation_time => Time.new.to_s,
|
34
|
+
:uuid => 1234,
|
35
|
+
:aliases => ['alias_1', 'alias_2'],
|
36
|
+
:server_identity => 'mock_server_identity',
|
37
|
+
:links => mock_response_links(mock_app_links('mock_domain_0','mock_app_0')),
|
38
|
+
}]
|
39
|
+
}.to_json,
|
40
|
+
:status => 200
|
41
|
+
})
|
42
|
+
stub_api_request(:any, app_0_links['THREAD_DUMP']['relative']).with(:body => {:event => 'thread-dump'}, :headers => {'Accept-Encoding'=>'gzip, deflate', 'Content-Length'=>'17', 'Content-Type'=>'application/x-www-form-urlencoded'}).
|
43
|
+
to_return({ :body => {
|
44
|
+
:type => 'application',
|
45
|
+
:data =>
|
46
|
+
{ :domain_id => 'mock_domain_1',
|
47
|
+
:name => 'mock_app_0',
|
48
|
+
:creation_time => Time.new.to_s,
|
49
|
+
:uuid => 1234,
|
50
|
+
:aliases => ['alias_1', 'alias_2'],
|
51
|
+
:server_identity => 'mock_server_identity',
|
52
|
+
:links => mock_response_links(mock_app_links('mock_domain_1','mock_app_0')),
|
53
|
+
},
|
54
|
+
:messages => [{:text => 'Application test thread dump complete.: Success'}]
|
55
|
+
}.to_json,
|
56
|
+
:status => 200
|
57
|
+
})
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'help' do
|
61
|
+
let(:arguments) { ['threaddump', '--help'] }
|
62
|
+
|
63
|
+
context 'help is run' do
|
64
|
+
it "should display help" do
|
65
|
+
expect { run }.should exit_with_code(0)
|
66
|
+
end
|
67
|
+
it('should output usage') { run_output.should match("Usage: rhc threaddump") }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'threaddump' do
|
72
|
+
let(:arguments) { ['threaddump', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password', 'mock_app_0'] }
|
73
|
+
context 'with no issues' do
|
74
|
+
it { expect { run }.should exit_with_code(0) }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
describe 'threaddump no args' do
|
78
|
+
let(:arguments) { ['threaddump', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
|
79
|
+
context 'args not supplied' do
|
80
|
+
it { expect { run }.should exit_with_code(1) }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/spec/rhc/config_spec.rb
CHANGED
@@ -8,10 +8,10 @@ describe RHC::Config do
|
|
8
8
|
ENV['http_proxy'] = nil
|
9
9
|
mock_terminal
|
10
10
|
FakeFS.activate!
|
11
|
+
FakeFS::FileSystem.clear
|
11
12
|
end
|
12
13
|
|
13
14
|
after(:all) do
|
14
|
-
FakeFS::FileSystem.clear
|
15
15
|
FakeFS.deactivate!
|
16
16
|
end
|
17
17
|
|
@@ -254,22 +254,48 @@ describe RHC::Config do
|
|
254
254
|
end
|
255
255
|
end
|
256
256
|
|
257
|
-
context "
|
257
|
+
context "Proxy ENV variable parsing" do
|
258
|
+
before do
|
259
|
+
RHC::Config.initialize
|
260
|
+
['http_proxy','HTTP_PROXY'].each do |var|
|
261
|
+
ENV[var] = nil
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
258
265
|
it "should return a direct http connection" do
|
259
|
-
|
260
|
-
proxy.should == Net::HTTP
|
266
|
+
RHC::Config.using_proxy?.should_not == true
|
261
267
|
end
|
262
268
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
269
|
+
['http_proxy','HTTP_PROXY'].each do |var|
|
270
|
+
it "should retrun a proxy http connection for #{var}" do
|
271
|
+
ENV[var] = "fakeproxy.foo:8080"
|
272
|
+
# returns a generic class so we check to make sure it is not a
|
273
|
+
# Net::HTTP class and rely on simplecov to make sure the proxy
|
274
|
+
# code path was run
|
275
|
+
RHC::Config.using_proxy?.should == true
|
276
|
+
end
|
271
277
|
end
|
272
278
|
|
279
|
+
context "it should have the correct values" do
|
280
|
+
let(:vars){ RHC::Config.proxy_vars }
|
281
|
+
before do
|
282
|
+
ENV['http_proxy'] = "my_user:my_pass@fakeproxy.foo:8080"
|
283
|
+
end
|
284
|
+
|
285
|
+
{
|
286
|
+
:user => 'my_user',
|
287
|
+
:pass => 'my_pass',
|
288
|
+
:address => 'fakeproxy.foo',
|
289
|
+
:port => 8080
|
290
|
+
}.each do |var,expected|
|
291
|
+
it "for #{var}" do
|
292
|
+
vars[var].should == expected
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
context "Configuration file parsing" do
|
273
299
|
it "should exit if config file can't be read" do
|
274
300
|
ConfigHelper.write_out_config(ConfigHelper.global_config_path,
|
275
301
|
"global.openshift.redhat.com",
|
@@ -325,6 +351,6 @@ class ConfigHelper
|
|
325
351
|
f.write("libra_server = #{server}\n") unless server.nil?
|
326
352
|
f.write("default_rhlogin = #{login}\n\n") unless login.nil?
|
327
353
|
other.each { |key, value| f.write("#{key}=#{value}\n") }
|
354
|
+
end
|
328
355
|
end
|
329
356
|
end
|
330
|
-
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rhc/commands/base'
|
3
|
+
require 'rhc/exceptions'
|
4
|
+
|
5
|
+
describe RHC::Commands::Base do
|
6
|
+
context 'when statically defined with context' do
|
7
|
+
subject do
|
8
|
+
Kernel.module_eval do
|
9
|
+
class Static < RHC::Commands::Base
|
10
|
+
suppress_wizard
|
11
|
+
|
12
|
+
def one_context
|
13
|
+
1
|
14
|
+
end
|
15
|
+
|
16
|
+
def nil_context
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
|
20
|
+
option ["--context-opt opt1"], "Test context option", :context => :one_context
|
21
|
+
summary "Test command execute with one_context"
|
22
|
+
def execute_with_one_context; return options.context_opt; end
|
23
|
+
|
24
|
+
option ["--context-opt opt1"], "Test context option", :context => :nil_context, :required => true
|
25
|
+
summary "Test command nil_context"
|
26
|
+
def execute_with_nil_context; return options.context_opt; end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
Static
|
30
|
+
end
|
31
|
+
|
32
|
+
let(:instance) { subject.new }
|
33
|
+
|
34
|
+
context 'and when execute_with_one_context is called' do
|
35
|
+
it { expects_running('static', 'execute-with-one-context').should call(:one_context).on(instance).with(no_args) }
|
36
|
+
it { expects_running('static', 'execute-with-one-context').should exit_with_code(1) }
|
37
|
+
it { expects_running('static', 'execute-with-one-context', '--context-opt', 'opt').should call(:execute_with_one_context).on(instance).with(no_args) }
|
38
|
+
it { expects_running('static', 'execute-with-one-context', '--context-opt', 'opt').should exit_with_code('opt') }
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'and when execute_with_nil_context is called' do
|
42
|
+
it { expects_running('static', 'execute-with-nil-context').should call(:nil_context).on(instance).with(no_args) }
|
43
|
+
it { expects_running('static', 'execute-with-nil-context', '--trace').should raise_error(ArgumentError) }
|
44
|
+
it { expects_running('static', 'execute-with-nil-context', '--context-opt', 'opt', '--trace').should call(:execute_with_nil_context).on(instance).with(no_args) }
|
45
|
+
it { expects_running('static', 'execute-with-nil-context', '--context-opt', 'opt', '--trace').should exit_with_code('opt') }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
|
data/spec/rhc/helpers_spec.rb
CHANGED
@@ -4,13 +4,14 @@ require 'rhc/ssh_key_helpers'
|
|
4
4
|
require 'rhc/core_ext'
|
5
5
|
require 'highline/import'
|
6
6
|
require 'rhc/config'
|
7
|
+
require 'rhc/helpers'
|
7
8
|
require 'date'
|
8
9
|
|
9
10
|
describe RHC::Helpers do
|
10
11
|
before(:each) do
|
11
12
|
mock_terminal
|
12
13
|
RHC::Config.set_defaults
|
13
|
-
@tests = HelperTests.new
|
14
|
+
@tests = HelperTests.new
|
14
15
|
end
|
15
16
|
|
16
17
|
subject do
|
@@ -47,6 +48,12 @@ describe RHC::Helpers do
|
|
47
48
|
end.should == ['10 2','3 40']
|
48
49
|
end
|
49
50
|
|
51
|
+
it("should generate table rows"){ subject.send(:make_table, [1,2]).should == [1,2] }
|
52
|
+
it("should generate a table"){ subject.send(:make_table, 1).should == [1] }
|
53
|
+
it("should output a table") do
|
54
|
+
subject.send(:display_no_info, 'test').should == ['This test has no information to show']
|
55
|
+
end
|
56
|
+
|
50
57
|
it "should parse an RFC3339 date" do
|
51
58
|
d = subject.datetime_rfc3339('2012-06-24T20:48:20-04:00')
|
52
59
|
d.day.should == 24
|
@@ -139,18 +146,12 @@ describe RHC::Helpers do
|
|
139
146
|
end
|
140
147
|
|
141
148
|
context "SSH Key Helpers" do
|
142
|
-
before do
|
143
|
-
FakeFS.activate!
|
144
|
-
end
|
145
|
-
|
146
149
|
it "should generate an ssh key then return nil when it tries to create another" do
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
FakeFS::FileSystem.clear
|
153
|
-
FakeFS.deactivate!
|
150
|
+
FakeFS do
|
151
|
+
FakeFS::FileSystem.clear
|
152
|
+
@tests.generate_ssh_key_ruby.should match("\.ssh/id_rsa\.pub")
|
153
|
+
@tests.generate_ssh_key_ruby == nil
|
154
|
+
end
|
154
155
|
end
|
155
156
|
end
|
156
157
|
|
@@ -254,3 +255,42 @@ describe OpenURI do
|
|
254
255
|
specify('https to http') { OpenURI.redirectable?(URI.parse('https://foo.com'), URI.parse('http://foo.com')).should be_false }
|
255
256
|
end
|
256
257
|
end
|
258
|
+
|
259
|
+
describe HighLine do
|
260
|
+
it "should wrap the terminal" do
|
261
|
+
$terminal.wrap_at = 10
|
262
|
+
say "Lorem ipsum dolor sit amet"
|
263
|
+
output = $terminal.read
|
264
|
+
output.should match "Lorem\nipsum\ndolor sit\namet"
|
265
|
+
end
|
266
|
+
it "should wrap the terminal" do
|
267
|
+
$terminal.wrap_at = 16
|
268
|
+
say "Lorem ipsum dolor sit amet"
|
269
|
+
output = $terminal.read
|
270
|
+
output.should match "Lorem ipsum\ndolor sit amet"
|
271
|
+
end
|
272
|
+
it "should not wrap the terminal" do
|
273
|
+
$terminal.wrap_at = 50
|
274
|
+
say "Lorem ipsum dolor sit amet"
|
275
|
+
output = $terminal.read
|
276
|
+
output.should match "Lorem ipsum dolor sit amet"
|
277
|
+
end
|
278
|
+
it "should wrap the terminal when using color codes" do
|
279
|
+
$terminal.wrap_at = 10
|
280
|
+
say $terminal.color("Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet", :red)
|
281
|
+
output = $terminal.read
|
282
|
+
output.should match "Lorem\nipsum\ndolor sit\namet Lorem\nipsum\ndolor sit\namet"
|
283
|
+
end
|
284
|
+
it "should wrap the terminal with other escape characters" do
|
285
|
+
$terminal.wrap_at = 10
|
286
|
+
say "Lorem ipsum dolor sit am\eet"
|
287
|
+
output = $terminal.read
|
288
|
+
output.should match "Lorem\nipsum\ndolor sit\nam\eet"
|
289
|
+
end
|
290
|
+
it "should wrap the terminal when words are smaller than wrap length" do
|
291
|
+
$terminal.wrap_at = 3
|
292
|
+
say "Antidisestablishmentarianism"
|
293
|
+
output = $terminal.read
|
294
|
+
output.should match "Ant\nidi\nses\ntab\nlis\nhme\nnta\nria\nnis\nm"
|
295
|
+
end
|
296
|
+
end
|
@@ -30,7 +30,7 @@ module RHC
|
|
30
30
|
it "returns an application object" do
|
31
31
|
app = app_obj
|
32
32
|
app.should be_an_instance_of RHC::Rest::Application
|
33
|
-
app.
|
33
|
+
app.send(:links).length.should equal(app_links.length)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -43,7 +43,7 @@ module RHC
|
|
43
43
|
app = app_obj
|
44
44
|
cart = app.add_cartridge('mock_cart_0')
|
45
45
|
cart.should be_an_instance_of RHC::Rest::Cartridge
|
46
|
-
cart.
|
46
|
+
cart.name.should == 'mock_cart_0'
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -59,7 +59,7 @@ module RHC
|
|
59
59
|
carts.length.should equal(2)
|
60
60
|
(0..1).each do |idx|
|
61
61
|
carts[idx].should be_an_instance_of RHC::Rest::Cartridge
|
62
|
-
carts[idx].
|
62
|
+
carts[idx].name.should == "mock_cart_#{idx}"
|
63
63
|
end
|
64
64
|
end
|
65
65
|
it "returns an empty list if the current app has no cartridges" do
|
@@ -70,6 +70,19 @@ module RHC
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
+
context "#gear_groups" do
|
74
|
+
before(:each) do
|
75
|
+
stub_api_request(:any, app_links['GET_GEAR_GROUPS']['relative']).
|
76
|
+
to_return(mock_gear_groups_response())
|
77
|
+
end
|
78
|
+
it "returns a list of all gear groups the current application" do
|
79
|
+
app = app_obj
|
80
|
+
gear_groups = app.gear_groups
|
81
|
+
gear_groups.length.should equal(1)
|
82
|
+
gear_groups[0].should be_an_instance_of RHC::Rest::GearGroup
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
73
86
|
# These application control tests are subtle; the key lies in making sure the
|
74
87
|
# webmock specifies the expected body that is sent in the request.
|
75
88
|
# This is currently of the form "event=foo"
|
@@ -14,8 +14,8 @@ class MockClient < RHC::Rest::Client
|
|
14
14
|
def logger
|
15
15
|
Logger.new((@output = StringIO.new))
|
16
16
|
end
|
17
|
-
def
|
18
|
-
@
|
17
|
+
def use_debug
|
18
|
+
@debug = true
|
19
19
|
end
|
20
20
|
def logged
|
21
21
|
@output.string
|
@@ -28,13 +28,14 @@ module RHC
|
|
28
28
|
let(:client_links) { mock_response_links(mock_client_links) }
|
29
29
|
let(:domain_0_links) { mock_response_links(mock_domain_links('mock_domain_0')) }
|
30
30
|
let(:domain_1_links) { mock_response_links(mock_domain_links('mock_domain_1')) }
|
31
|
+
let(:app_0_links) { mock_response_links(mock_app_links('mock_domain_0', 'mock_app')) }
|
31
32
|
let(:user_links) { mock_response_links(mock_user_links) }
|
32
33
|
let(:key_links) { mock_response_links(mock_key_links) }
|
33
34
|
|
34
35
|
context "#new" do
|
35
36
|
before do
|
36
37
|
stub_api_request(:get, '').
|
37
|
-
to_return({ :body => { :data => client_links }.to_json,
|
38
|
+
to_return({ :body => { :data => client_links, :supported_api_versions => [1.0, 1.1] }.to_json,
|
38
39
|
:status => 200
|
39
40
|
})
|
40
41
|
stub_api_request(:get, 'api_error').
|
@@ -47,7 +48,7 @@ module RHC
|
|
47
48
|
credentials = Base64.strict_encode64(mock_user + ":" + mock_pass)
|
48
49
|
client = RHC::Rest::Client.new(mock_href, mock_user, mock_pass)
|
49
50
|
@@headers['Authorization'].should == "Basic #{credentials}"
|
50
|
-
client.
|
51
|
+
client.send(:links).should == client_links
|
51
52
|
end
|
52
53
|
it "does not add newlines to username and password > 60 characters" do
|
53
54
|
username = "a" * 45
|
@@ -60,14 +61,68 @@ module RHC
|
|
60
61
|
end
|
61
62
|
it "raises a generic error for any other error condition" do
|
62
63
|
lambda{ RHC::Rest::Client.new(mock_href('other_error'), mock_user, mock_pass) }.
|
63
|
-
should raise_error("
|
64
|
+
should raise_error("Failed to access resource: Other Error")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#new" do
|
69
|
+
context "when server supports API versions [1.0, 1.1]" do
|
70
|
+
before :each do
|
71
|
+
stub_api_request(:get, '').
|
72
|
+
to_return({ :body => { :data => client_links, :supported_api_versions => [1.0, 1.1] }.to_json,
|
73
|
+
:status => 200
|
74
|
+
})
|
75
|
+
stub_api_request(:get, 'api_error').
|
76
|
+
to_raise(RestClient::ExceptionWithResponse.new('API Error'))
|
77
|
+
stub_api_request(:get, 'other_error').
|
78
|
+
to_raise(Exception.new('Other Error'))
|
79
|
+
end
|
80
|
+
|
81
|
+
context "when client is instantiated with [1.0, 1.1] as the preferred API versions" do
|
82
|
+
before :each do
|
83
|
+
@client = RHC::Rest::Client.new(mock_href, mock_user, mock_pass, false, [1.0, 1.1])
|
84
|
+
end
|
85
|
+
it "settles on 1.1 as the API version" do
|
86
|
+
@client.api_version_negotiated.should == 1.1
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context "when client is instantiated with [1.1, 1.0] as the preferred API versions" do
|
91
|
+
before :each do
|
92
|
+
@client = RHC::Rest::Client.new(mock_href, mock_user, mock_pass, false, [1.1, 1.0])
|
93
|
+
end
|
94
|
+
it "settles on 1.0 as the API version" do
|
95
|
+
@client.api_version_negotiated.should == 1.0
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "when client is instantiated with [1.2, 1.3] as the preferred API versions" do
|
100
|
+
before :each do
|
101
|
+
@client = RHC::Rest::Client.new(mock_href, mock_user, mock_pass, false, [1.2, 1.3])
|
102
|
+
end
|
103
|
+
it "fails to negotiate an agreeable API version" do
|
104
|
+
@client.api_version_negotiated.should be_nil
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context "when client is instantiated with [1.1, 1.0, 1.3] as the preferred API versions" do
|
109
|
+
before :each do
|
110
|
+
@client = RHC::Rest::Client.new(mock_href, mock_user, mock_pass, false, [1.1, 1.0, 1.3])
|
111
|
+
end
|
112
|
+
it "settles on 1.0 as the API version" do
|
113
|
+
@client.api_version_negotiated.should == 1.0
|
114
|
+
end
|
115
|
+
end
|
64
116
|
end
|
65
117
|
end
|
66
118
|
|
67
119
|
context "with an instantiated client " do
|
68
120
|
before(:each) do
|
69
121
|
stub_api_request(:get, '').
|
70
|
-
to_return({ :body => {
|
122
|
+
to_return({ :body => {
|
123
|
+
:data => client_links,
|
124
|
+
:supported_api_versions => [1.0, 1.1]
|
125
|
+
}.to_json,
|
71
126
|
:status => 200
|
72
127
|
})
|
73
128
|
@client = RHC::Rest::Client.new(mock_href, mock_user, mock_pass)
|
@@ -78,6 +133,7 @@ module RHC
|
|
78
133
|
stub_api_request(:any, client_links['ADD_DOMAIN']['relative']).
|
79
134
|
to_return({ :body => {
|
80
135
|
:type => 'domain',
|
136
|
+
:supported_api_versions => [1.0, 1.1],
|
81
137
|
:data => {
|
82
138
|
:id => 'mock_domain',
|
83
139
|
:links => mock_response_links(mock_domain_links('mock_domain')),
|
@@ -88,9 +144,9 @@ module RHC
|
|
88
144
|
end
|
89
145
|
it "returns a domain object" do
|
90
146
|
domain = @client.add_domain('mock_domain')
|
91
|
-
domain.class.should
|
92
|
-
domain.
|
93
|
-
domain.
|
147
|
+
domain.class.should == RHC::Rest::Domain
|
148
|
+
domain.id.should == 'mock_domain'
|
149
|
+
domain.send(:links).should ==
|
94
150
|
mock_response_links(mock_domain_links('mock_domain'))
|
95
151
|
end
|
96
152
|
end
|
@@ -122,8 +178,8 @@ module RHC
|
|
122
178
|
domains.length.should equal(2)
|
123
179
|
(0..1).each do |idx|
|
124
180
|
domains[idx].class.should == RHC::Rest::Domain
|
125
|
-
domains[idx].
|
126
|
-
domains[idx].
|
181
|
+
domains[idx].id.should == "mock_domain_#{idx}"
|
182
|
+
domains[idx].send(:links).should ==
|
127
183
|
mock_response_links(mock_domain_links("mock_domain_#{idx}"))
|
128
184
|
end
|
129
185
|
end
|
@@ -214,9 +270,9 @@ module RHC
|
|
214
270
|
domain.applications.each do |app|
|
215
271
|
match = domain.find_application(app.name)
|
216
272
|
match.class.should == RHC::Rest::Application
|
217
|
-
match.
|
218
|
-
match.
|
219
|
-
match.
|
273
|
+
match.name.should == 'mock_app'
|
274
|
+
match.domain_id.should == "#{domain.id}"
|
275
|
+
match.send(:links).should ==
|
220
276
|
mock_response_links(mock_app_links("#{domain.id}",'mock_app'))
|
221
277
|
end
|
222
278
|
end
|
@@ -254,9 +310,9 @@ module RHC
|
|
254
310
|
carts.length.should equal(2)
|
255
311
|
(0..1).each do |idx|
|
256
312
|
carts[idx].class.should == RHC::Rest::Cartridge
|
257
|
-
carts[idx].
|
258
|
-
carts[idx].
|
259
|
-
carts[idx].
|
313
|
+
carts[idx].name.should == "mock_cart_#{idx}"
|
314
|
+
carts[idx].type.should == "mock_cart_#{idx}_type"
|
315
|
+
carts[idx].send(:links).should ==
|
260
316
|
mock_response_links(mock_cart_links("mock_cart_#{idx}"))
|
261
317
|
end
|
262
318
|
end
|
@@ -295,9 +351,9 @@ module RHC
|
|
295
351
|
matches = @client.find_cartridges('mock_cart_0')
|
296
352
|
matches.length.should equal(1)
|
297
353
|
matches[0].class.should == RHC::Rest::Cartridge
|
298
|
-
matches[0].
|
299
|
-
matches[0].
|
300
|
-
matches[0].
|
354
|
+
matches[0].name.should == 'mock_cart_0'
|
355
|
+
matches[0].type.should == 'mock_cart_0_type'
|
356
|
+
matches[0].send(:links).should ==
|
301
357
|
mock_response_links(mock_cart_links('mock_cart_0'))
|
302
358
|
end
|
303
359
|
it "returns an empty list when no matching cartridges can be found" do
|
@@ -326,8 +382,8 @@ module RHC
|
|
326
382
|
it "returns the user object associated with this client connection" do
|
327
383
|
user = @client.user
|
328
384
|
user.class.should == RHC::Rest::User
|
329
|
-
user.
|
330
|
-
user.
|
385
|
+
user.login.should == mock_user
|
386
|
+
user.send(:links).should == mock_response_links(mock_user_links)
|
331
387
|
end
|
332
388
|
end
|
333
389
|
|
@@ -366,10 +422,10 @@ module RHC
|
|
366
422
|
expect { key = @client.find_key('mock_key_0') }.should_not raise_error
|
367
423
|
|
368
424
|
key.class.should == RHC::Rest::Key
|
369
|
-
key.
|
370
|
-
key.
|
371
|
-
key.
|
372
|
-
key.
|
425
|
+
key.name.should == 'mock_key_0'
|
426
|
+
key.type.should == 'mock_key_0_type'
|
427
|
+
key.content.should == '123456789:0'
|
428
|
+
key.send(:links).should ==
|
373
429
|
mock_response_links(mock_key_links('mock_key_0'))
|
374
430
|
end
|
375
431
|
it "raise an error when no matching keys can be found" do
|
@@ -380,25 +436,28 @@ module RHC
|
|
380
436
|
shared_examples_for "a logout method" do
|
381
437
|
before(:each) do
|
382
438
|
stub_api_request(:get, '').
|
383
|
-
to_return({ :body => { :data => client_links }.to_json,
|
439
|
+
to_return({ :body => { :data => client_links, :supported_api_versions => [1.0, 1.1] }.to_json,
|
384
440
|
:status => 200
|
385
441
|
})
|
386
|
-
@client = MockClient.new(mock_href, mock_user, mock_pass)
|
387
442
|
end
|
388
443
|
context "debug mode is on" do
|
389
444
|
it "writes a message to the logger" do
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
445
|
+
capture do
|
446
|
+
@client = MockClient.new(mock_href, mock_user, mock_pass, true)
|
447
|
+
@client.send logout_method.to_sym
|
448
|
+
$stderr.rewind
|
449
|
+
$stderr.read.should =~ /Logout\/Close client$/
|
450
|
+
end
|
394
451
|
end
|
395
452
|
end
|
396
453
|
context "debug mode is off" do
|
397
454
|
it "does nothing" do
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
455
|
+
capture do
|
456
|
+
@client = MockClient.new(mock_href, mock_user, mock_pass, false)
|
457
|
+
@client.send logout_method.to_sym
|
458
|
+
$stderr.rewind
|
459
|
+
$stderr.read.should == ''
|
460
|
+
end
|
402
461
|
end
|
403
462
|
end
|
404
463
|
end
|
@@ -461,6 +520,55 @@ module RHC
|
|
461
520
|
it_should_behave_like "a logout method"
|
462
521
|
end
|
463
522
|
end
|
523
|
+
|
524
|
+
context "when server supports API versions 1.0 and 1.1" do
|
525
|
+
before :each do
|
526
|
+
stub_api_request(:get, '').
|
527
|
+
to_return({ :body => {
|
528
|
+
:data => client_links,
|
529
|
+
:supported_api_versions => [1.0, 1.1]
|
530
|
+
}.to_json,
|
531
|
+
:status => 200
|
532
|
+
})
|
533
|
+
end
|
534
|
+
|
535
|
+
context "when client supports API version 1.1" do
|
536
|
+
before :each do
|
537
|
+
@client = RHC::Rest::Client.new(mock_href, mock_user, mock_pass, false, [1.1])
|
538
|
+
end
|
539
|
+
|
540
|
+
describe "#api_version_negotiated" do
|
541
|
+
it "returns 1.1" do
|
542
|
+
@client.api_version_negotiated.to_s.should == '1.1'
|
543
|
+
end
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
context "when client supports only API version 1.2" do
|
548
|
+
before :each do
|
549
|
+
@client = RHC::Rest::Client.new(mock_href, mock_user, mock_pass, false, [1.2])
|
550
|
+
end
|
551
|
+
|
552
|
+
describe "#api_version_negotiated" do
|
553
|
+
it 'returns nil' do
|
554
|
+
@client.api_version_negotiated.should be_nil
|
555
|
+
end
|
556
|
+
end
|
557
|
+
end
|
558
|
+
|
559
|
+
context "when client supports only API version 0.9" do
|
560
|
+
describe "#new" do
|
561
|
+
it "warns user that it is outdated" do
|
562
|
+
capture do
|
563
|
+
@client = RHC::Rest::Client.new(mock_href, mock_user, mock_pass, false, [0.9])
|
564
|
+
@output.rewind
|
565
|
+
@output.read.should =~ /client version may be outdated/
|
566
|
+
end
|
567
|
+
end
|
568
|
+
end
|
569
|
+
end
|
570
|
+
end
|
571
|
+
|
464
572
|
end
|
465
573
|
end
|
466
574
|
end
|
data/spec/rhc/rest_spec.rb
CHANGED
@@ -55,7 +55,7 @@ module RHC
|
|
55
55
|
:links => { :foo => 'bar' }
|
56
56
|
}}
|
57
57
|
it "deserializes to an application" do
|
58
|
-
json_response = { :type => 'application', :data => object }.to_json
|
58
|
+
json_response = { :type => 'application', :data => object, :messages => [{'text' => 'test message'}]}.to_json
|
59
59
|
app_obj = RHC::Rest::Application.new(object)
|
60
60
|
subject.parse_response(json_response).should have_same_attributes_as(app_obj)
|
61
61
|
end
|