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.
- 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
|