right_infrastructure_agent 1.1.2
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.
- checksums.yaml +7 -0
- data/LICENSE +10 -0
- data/README.rdoc +65 -0
- data/Rakefile +86 -0
- data/lib/right_infrastructure_agent.rb +26 -0
- data/lib/right_infrastructure_agent/command_constants.rb +34 -0
- data/lib/right_infrastructure_agent/global_object_replicator_sink.rb +337 -0
- data/lib/right_infrastructure_agent/global_object_replicator_source.rb +117 -0
- data/lib/right_infrastructure_agent/infrastructure_auth_client.rb +88 -0
- data/lib/right_infrastructure_agent/infrastructure_helpers.rb +85 -0
- data/lib/right_infrastructure_agent/login_policy_factory.rb +137 -0
- data/lib/right_infrastructure_agent/models_helper.rb +483 -0
- data/lib/right_infrastructure_agent/rainbows_agent_controller.rb +192 -0
- data/lib/right_infrastructure_agent/scripts/infrastructure_agent_deployer.rb +278 -0
- data/right_infrastructure_agent.gemspec +54 -0
- data/spec/global_object_replicator_sink_spec.rb +305 -0
- data/spec/global_object_replicator_source_spec.rb +113 -0
- data/spec/infrastructure_auth_client_spec.rb +140 -0
- data/spec/infrastructure_helpers_spec.rb +80 -0
- data/spec/login_policy_factory_spec.rb +279 -0
- data/spec/models_helper_spec.rb +546 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +85 -0
- metadata +116 -0
@@ -0,0 +1,546 @@
|
|
1
|
+
# Copyright (c) 2009-2011 RightScale, Inc, All Rights Reserved Worldwide.
|
2
|
+
#
|
3
|
+
# THIS PROGRAM IS CONFIDENTIAL AND PROPRIETARY TO RIGHTSCALE
|
4
|
+
# AND CONSTITUTES A VALUABLE TRADE SECRET. Any unauthorized use,
|
5
|
+
# reproduction, modification, or disclosure of this program is
|
6
|
+
# strictly prohibited. Any use of this program by an authorized
|
7
|
+
# licensee is strictly subject to the terms and conditions,
|
8
|
+
# including confidentiality obligations, set forth in the applicable
|
9
|
+
# License Agreement between RightScale.com, Inc. and
|
10
|
+
# the licensee.
|
11
|
+
|
12
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
13
|
+
|
14
|
+
describe RightScale::ModelsHelper do
|
15
|
+
|
16
|
+
include RightScale::ModelsHelper
|
17
|
+
|
18
|
+
class Account; end
|
19
|
+
class AuditEntry; end
|
20
|
+
class InstanceApiToken; end
|
21
|
+
class Permission; end
|
22
|
+
class Repository; end
|
23
|
+
class RightScript; end
|
24
|
+
class Setting; end
|
25
|
+
class ServerTemplateChefRecipe; end
|
26
|
+
class User; end
|
27
|
+
class UserCredential; end
|
28
|
+
|
29
|
+
before(:each) do
|
30
|
+
flexmock(RightScale::Log).should_receive(:info).never.by_default
|
31
|
+
flexmock(RightScale::Log).should_receive(:warning).never.by_default
|
32
|
+
flexmock(RightScale::Log).should_receive(:error).never.by_default
|
33
|
+
@audit_formatter = flexmock(RightScale::AuditFormatter)
|
34
|
+
@audit_formatter.should_receive(:error).never.by_default
|
35
|
+
@audit = flexmock("audit")
|
36
|
+
@audit.should_receive(:append).never.by_default
|
37
|
+
@last_error = nil
|
38
|
+
end
|
39
|
+
|
40
|
+
context :query do
|
41
|
+
it 'should run query, yielding to block and returning result from query block' do
|
42
|
+
called = 0
|
43
|
+
result = query("query database") { called += 1 }
|
44
|
+
called.should == 1
|
45
|
+
result.should == 1
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should catch and log exception and return nil by default' do
|
49
|
+
flexmock(RightScale::Log).should_receive(:error).with("Failed to query database", NoMethodError, :trace).once
|
50
|
+
called = 0
|
51
|
+
result = query("query database") do
|
52
|
+
called += 1
|
53
|
+
nil + "string"
|
54
|
+
end
|
55
|
+
called.should == 1
|
56
|
+
result.should == nil
|
57
|
+
error = /Failed to query database \(NoMethodError.*undefined method.*models_helper_spec.*\)$/
|
58
|
+
(@last_error.should =~ error).should be_true
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should audit exception if audit enabled' do
|
62
|
+
error = /Failed to query database \(NoMethodError.*undefined method.*models_helper_spec.*\)$/
|
63
|
+
@audit_formatter.should_receive(:error).with(error).once
|
64
|
+
@audit.should_receive(:append).once
|
65
|
+
flexmock(RightScale::Log).should_receive(:error).once
|
66
|
+
called = 0
|
67
|
+
result = query("query database", :audit => @audit) do
|
68
|
+
called += 1
|
69
|
+
nil + "string"
|
70
|
+
end
|
71
|
+
called.should == 1
|
72
|
+
result.should == nil
|
73
|
+
(@last_error.should =~ error).should be_true
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should return nil if catch RecordNotFound exception and not log error' do
|
77
|
+
called = 0
|
78
|
+
result = query("query database") do
|
79
|
+
called += 1
|
80
|
+
raise ActiveRecord::RecordNotFound.new("Missing")
|
81
|
+
end
|
82
|
+
called.should == 1
|
83
|
+
result.should == nil
|
84
|
+
@last_error.should be_nil
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should raise RetryableError if exceed retries, :retryable_error enabled, and error retryable' do
|
88
|
+
flexmock(RightScale::Log).should_receive(:info).with("Retrying query...").times(3)
|
89
|
+
flexmock(RightScale::Log).should_receive(:warning).with("Aborting query after 3 failed retries").once
|
90
|
+
flexmock(RightScale::Log).should_receive(:error).with("Failed running MySQL query",
|
91
|
+
ActiveRecord::StatementInvalid, :trace).times(3)
|
92
|
+
flexmock(RightScale::Log).should_receive(:error).with("Failed to query database but retryable",
|
93
|
+
RightScale::Exceptions::RetryableError, :trace).once
|
94
|
+
lambda do
|
95
|
+
query("query database", :retryable_error => true) do
|
96
|
+
raise ActiveRecord::StatementInvalid.new("Deadlock found")
|
97
|
+
end
|
98
|
+
end.should raise_error(RightScale::Exceptions::RetryableError)
|
99
|
+
error = /Failed to query database but retryable \(RightScale::Exceptions::RetryableError: RightScale database temporarily unavailable in .*models_helper.*\)$/
|
100
|
+
(@last_error.should =~ error).should be_true
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should not raise RetryableError if exceed retries, :retryable_error enabled, but error not retryable' do
|
104
|
+
flexmock(RightScale::Log).should_receive(:info).with("Retrying query...").times(3)
|
105
|
+
flexmock(RightScale::Log).should_receive(:warning).with("Aborting query after 3 failed retries").once
|
106
|
+
flexmock(RightScale::Log).should_receive(:error).with("Failed running MySQL query",
|
107
|
+
ActiveRecord::StatementInvalid, :trace).times(3)
|
108
|
+
flexmock(RightScale::Log).should_receive(:error).with("Failed to query database",
|
109
|
+
ActiveRecord::StatementInvalid, :trace).once
|
110
|
+
query("query database", :retryable_error => true) do
|
111
|
+
raise ActiveRecord::StatementInvalid.new("Invalid query")
|
112
|
+
end
|
113
|
+
error = /Failed to query database \(ActiveRecord::StatementInvalid.*Invalid query in .*models_helper_spec.*\)$/
|
114
|
+
(@last_error.should =~ error).should be_true
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context :run_query do
|
119
|
+
it 'should return result of executed block' do
|
120
|
+
run_query { "result" }.should == "result"
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'should treat RecordNotFound as nil result and not raise error' do
|
124
|
+
run_query { raise ActiveRecord::RecordNotFound }.should be_nil
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should retry if exception is retryable' do
|
128
|
+
flexmock(RightScale::Log).should_receive(:info).with("Retrying query...").once
|
129
|
+
flexmock(RightScale::Log).should_receive(:error).with("Failed running MySQL query",
|
130
|
+
ActiveRecord::StatementInvalid, :trace).once
|
131
|
+
called = 0
|
132
|
+
result = run_query do
|
133
|
+
called += 1
|
134
|
+
raise ActiveRecord::StatementInvalid.new("Invalid query") if called == 1
|
135
|
+
"result"
|
136
|
+
end
|
137
|
+
called.should == 2
|
138
|
+
result.should == "result"
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should raise exception if not retryable' do
|
142
|
+
flexmock(RightScale::Log).should_receive(:info).with("Retrying query...").never
|
143
|
+
lambda do
|
144
|
+
run_query do
|
145
|
+
raise ArgumentError
|
146
|
+
end
|
147
|
+
end.should raise_error(ArgumentError)
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'should retry at most 3 times' do
|
151
|
+
flexmock(RightScale::Log).should_receive(:info).with("Retrying query...").times(3)
|
152
|
+
flexmock(RightScale::Log).should_receive(:warning).with("Aborting query after 3 failed retries").once
|
153
|
+
flexmock(RightScale::Log).should_receive(:error).with("Failed running MySQL query",
|
154
|
+
ActiveRecord::StatementInvalid, :trace).times(3)
|
155
|
+
called = 0
|
156
|
+
lambda do
|
157
|
+
run_query do
|
158
|
+
called += 1
|
159
|
+
raise ActiveRecord::StatementInvalid.new("Invalid query")
|
160
|
+
end
|
161
|
+
end.should raise_error(ActiveRecord::StatementInvalid)
|
162
|
+
called.should == 4
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should raise RetryableError if exceed retries, :retryable_error enabled, and error retryable' do
|
166
|
+
flexmock(RightScale::Log).should_receive(:info).with("Retrying query...").times(3)
|
167
|
+
flexmock(RightScale::Log).should_receive(:warning).with("Aborting query after 3 failed retries").once
|
168
|
+
flexmock(RightScale::Log).should_receive(:error).with("Failed running MySQL query",
|
169
|
+
ActiveRecord::StatementInvalid, :trace).times(3)
|
170
|
+
called = 0
|
171
|
+
lambda do
|
172
|
+
run_query(:retryable_error => true) do
|
173
|
+
called += 1
|
174
|
+
raise ActiveRecord::StatementInvalid.new("Deadlock found")
|
175
|
+
end
|
176
|
+
end.should raise_error(RightScale::Exceptions::RetryableError, RightScale::ModelsHelper::DEFAULT_RETRY_MESSAGE)
|
177
|
+
called.should == 4
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'should raise RetryableError with account unavailable message if wrong shard error' do
|
181
|
+
flexmock(RightScale::Log).should_receive(:info).with("Retrying query...").times(3)
|
182
|
+
flexmock(RightScale::Log).should_receive(:warning).with("Aborting query after 3 failed retries").once
|
183
|
+
flexmock(RightScale::Log).should_receive(:error).with("Failed running MySQL query",
|
184
|
+
ActiveRecord::StatementInvalid, :trace).times(3)
|
185
|
+
called = 0
|
186
|
+
lambda do
|
187
|
+
run_query(:retryable_error => true) do
|
188
|
+
called += 1
|
189
|
+
raise ActiveRecord::StatementInvalid.new(RightScale::ModelsHelper::WRONG_SHARD_ERROR)
|
190
|
+
end
|
191
|
+
end.should raise_error(RightScale::Exceptions::RetryableError, RightScale::ModelsHelper::WRONG_SHARD_RETRY_MESSAGE)
|
192
|
+
called.should == 4
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'should not raise RetryableError if exceed retries, :retryable_error enabled, but error not retryable' do
|
196
|
+
flexmock(RightScale::Log).should_receive(:info).with("Retrying query...").times(3)
|
197
|
+
flexmock(RightScale::Log).should_receive(:warning).with("Aborting query after 3 failed retries").once
|
198
|
+
flexmock(RightScale::Log).should_receive(:error).with("Failed running MySQL query",
|
199
|
+
ActiveRecord::StatementInvalid, :trace).times(3)
|
200
|
+
called = 0
|
201
|
+
lambda do
|
202
|
+
run_query(:retryable_error => true) do
|
203
|
+
called += 1
|
204
|
+
raise ActiveRecord::StatementInvalid.new("Invalid query")
|
205
|
+
end
|
206
|
+
end.should raise_error(ActiveRecord::StatementInvalid)
|
207
|
+
called.should == 4
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
context :is_retryable_error? do
|
212
|
+
it 'should be permissive of any MysqlError or ActiveRecord::ActiveRecordError for local test' do
|
213
|
+
is_retryable_error?(ArgumentError.new("anything"), local = true).should be_false
|
214
|
+
is_retryable_error?(MysqlError.new("anything"), local = true).should be_true
|
215
|
+
is_retryable_error?(MysqlError.new("has gone away"), local = true).should be_true
|
216
|
+
is_retryable_error?(ActiveRecord::StatementInvalid.new("anything"), local = true).should be_true
|
217
|
+
is_retryable_error?(ActiveRecord::StatementInvalid.new("Deadlock found"), local = true).should be_true
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'should use selected ActiveRecord::ActiveRecordError retryable errors to restrict for external test' do
|
221
|
+
is_retryable_error?(ArgumentError.new("anything")).should be_false
|
222
|
+
is_retryable_error?(MysqlError.new("anything")).should be_false
|
223
|
+
is_retryable_error?(MysqlError.new("has gone away")).should be_true
|
224
|
+
is_retryable_error?(ActiveRecord::StatementInvalid.new("anything")).should be_false
|
225
|
+
is_retryable_error?(ActiveRecord::StatementInvalid.new("Deadlock found")).should be_true
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
context :retrieve_or_create_audit do
|
230
|
+
it 'should retrieve audit when id specified' do
|
231
|
+
flexmock(self).should_receive(:audit_entry).with(123, :audit_id => 123).and_return("audit")
|
232
|
+
flexmock(AuditEntry).should_receive(:create!).never
|
233
|
+
retrieve_or_create_audit("instance", "summary", "detail", "account", "user", :audit_id => 123).should == "audit"
|
234
|
+
end
|
235
|
+
|
236
|
+
it 'should create audit when agent identity specified instead of id' do
|
237
|
+
flexmock(self).should_receive(:audit_entry).with(1, :audit_id => 123).never
|
238
|
+
flexmock(AuditEntry).should_receive(:create!).with({:auditee => "instance", :summary => "summary", :detail => "detail",
|
239
|
+
:account => "account", :user => "user"}).and_return("audit").once
|
240
|
+
retrieve_or_create_audit("instance", "summary", "detail", "account", "user", :agent_identity => "111").should == "audit"
|
241
|
+
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'should raise exception if neiher audit id or agent identity specified' do
|
245
|
+
lambda do
|
246
|
+
retrieve_or_create_audit("instance", "summary", "detail", "account", "user")
|
247
|
+
end.should raise_error(ArgumentError)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
context :retrieve_or_default_user do
|
252
|
+
before(:each) do
|
253
|
+
@user = flexmock("user", :id= => 0, :id => 123)
|
254
|
+
@account = flexmock("account", :users => [@user])
|
255
|
+
@instance = flexmock("instance", :account => @account)
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'should return default user if not user id supplied' do
|
259
|
+
flexmock(User).should_receive(:new).with(:email => "alerter@rightscale.com").and_return(@user).once
|
260
|
+
retrieve_or_default_user(@instance).should == @user
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'should retrieve user if user id supplied' do
|
264
|
+
flexmock(User).should_receive(:new).never
|
265
|
+
result = retrieve_or_default_user(@instance, :user_id => 123).should == @user
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'should return error result if no user found' do
|
269
|
+
retrieve_or_default_user(@instance, :user_id => 124).should be_nil
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
context :retrieve do
|
274
|
+
it 'should yield and return result from block' do
|
275
|
+
called = 0
|
276
|
+
result = retrieve("something") { called += 1 }
|
277
|
+
called.should == 1
|
278
|
+
result.should == 1
|
279
|
+
@last_error.should be_nil
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'should detect not found but not log warning nor audit by default' do
|
283
|
+
called = 0
|
284
|
+
result = retrieve("something") { called += 1; nil }
|
285
|
+
called.should == 1
|
286
|
+
result.should == nil
|
287
|
+
@last_error.should == "Could not find something"
|
288
|
+
end
|
289
|
+
|
290
|
+
it 'should detect not found and log warning if log enabled' do
|
291
|
+
flexmock(RightScale::Log).should_receive(:warning).with(/Could not find something/).once
|
292
|
+
called = 0
|
293
|
+
result = retrieve("something", :log => true) { called += 1; nil }
|
294
|
+
called.should == 1
|
295
|
+
result.should == nil
|
296
|
+
@last_error.should == "Could not find something"
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'should detect not found and audit if audit enabled' do
|
300
|
+
@audit_formatter.should_receive(:error).with("Could not find something").once
|
301
|
+
@audit.should_receive(:append).once
|
302
|
+
called = 0
|
303
|
+
result = retrieve("something", :audit => @audit) { called += 1; nil }
|
304
|
+
called.should == 1
|
305
|
+
result.should == nil
|
306
|
+
@last_error.should == "Could not find something"
|
307
|
+
end
|
308
|
+
|
309
|
+
it 'should catch and log exception and return nil by default' do
|
310
|
+
flexmock(RightScale::Log).should_receive(:error).with("Failed to retrieve something", NoMethodError, :trace).once
|
311
|
+
called = 0
|
312
|
+
result = retrieve("something") do
|
313
|
+
called += 1
|
314
|
+
nil + "string"
|
315
|
+
end
|
316
|
+
called.should == 1
|
317
|
+
result.should == nil
|
318
|
+
error = /Failed to retrieve something \(NoMethodError.*undefined method.*models_helper_spec.*\)$/
|
319
|
+
(@last_error.should =~ error).should be_true
|
320
|
+
end
|
321
|
+
|
322
|
+
it 'should audit exception if audit enabled' do
|
323
|
+
error = /Failed to retrieve something \(NoMethodError.*undefined method.*models_helper_spec.*\)$/
|
324
|
+
@audit_formatter.should_receive(:error).with(error).once
|
325
|
+
@audit.should_receive(:append).once
|
326
|
+
flexmock(RightScale::Log).should_receive(:error).once
|
327
|
+
called = 0
|
328
|
+
result = retrieve("something", :audit => @audit) do
|
329
|
+
called += 1
|
330
|
+
nil + "string"
|
331
|
+
end
|
332
|
+
called.should == 1
|
333
|
+
result.should == nil
|
334
|
+
(@last_error.should =~ error).should be_true
|
335
|
+
end
|
336
|
+
|
337
|
+
it 'should not log or audit an error from a previous retrieval' do
|
338
|
+
called = 0
|
339
|
+
result = retrieve("something") { called += 1; nil }
|
340
|
+
called.should == 1
|
341
|
+
result.should == nil
|
342
|
+
@last_error.should == "Could not find something"
|
343
|
+
result = retrieve("something else", :audit => true, :log => true) { called += 1 }
|
344
|
+
called.should == 2
|
345
|
+
@last_error.should be_nil
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
context :instance_token do
|
350
|
+
it 'should retrieve InstanceApiToken using id' do
|
351
|
+
flexmock(InstanceApiToken).should_receive(:find).with(123).and_return("instance_api_token").once
|
352
|
+
instance_token(123).should == "instance_api_token"
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
context :instance do
|
357
|
+
before(:each) do
|
358
|
+
@token_id = 123
|
359
|
+
@account = flexmock("account")
|
360
|
+
@account.should_receive(:disabled_in_every_shard?).and_return(false).by_default
|
361
|
+
@instance = flexmock("instance", :account => @account)
|
362
|
+
@instance_api_token = flexmock("instance_api_token")
|
363
|
+
@instance_api_token.should_receive(:instance).and_return(@instance)
|
364
|
+
flexmock(InstanceApiToken).should_receive(:find).with(@token_id).and_return(@instance_api_token).once
|
365
|
+
end
|
366
|
+
|
367
|
+
it 'should retrieve Instance using id' do
|
368
|
+
instance(@token_id).should == @instance
|
369
|
+
end
|
370
|
+
|
371
|
+
it 'should raise RetryableError if shard is disabled for account' do
|
372
|
+
@account.should_receive(:disabled_in_every_shard?).and_return(true)
|
373
|
+
lambda do
|
374
|
+
instance(@token_id)
|
375
|
+
end.should raise_error(RightScale::Exceptions::RetryableError)
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
context :instance_from_token_id do
|
380
|
+
before(:each) do
|
381
|
+
@token_id = 123
|
382
|
+
@account = flexmock("account")
|
383
|
+
@account.should_receive(:disabled_in_every_shard?).and_return(false).by_default
|
384
|
+
@instance = flexmock("instance", :account => @account)
|
385
|
+
@instance_api_token = flexmock("instance_api_token")
|
386
|
+
@instance_api_token.should_receive(:instance).and_return(@instance).by_default
|
387
|
+
flexmock(InstanceApiToken).should_receive(:find).with(@token_id).and_return(@instance_api_token).by_default
|
388
|
+
end
|
389
|
+
|
390
|
+
it 'should retrieve Instance using token_id' do
|
391
|
+
instance_from_token_id(@token_id).should == @instance
|
392
|
+
end
|
393
|
+
|
394
|
+
it 'should cache tokens and use to reload instance' do
|
395
|
+
@instance.should_receive(:reload).and_return(@instance).once
|
396
|
+
instance_from_token_id(@token_id).should == @instance
|
397
|
+
@tokens[@token_id].should == @instance
|
398
|
+
instance_from_token_id(@token_id).should == @instance
|
399
|
+
end
|
400
|
+
|
401
|
+
it 'should raise exception if InstanceApiToken not found' do
|
402
|
+
flexmock(InstanceApiToken).should_receive(:find).with(@token_id).and_return(nil)
|
403
|
+
lambda do
|
404
|
+
instance_from_token_id(@token_id).should == @instance
|
405
|
+
end.should raise_error(RightScale::Exceptions::Application)
|
406
|
+
end
|
407
|
+
|
408
|
+
it 'should raise exception if Instance not found' do
|
409
|
+
@instance_api_token.should_receive(:instance).and_return(nil)
|
410
|
+
lambda do
|
411
|
+
instance_from_token_id(@token_id).should == @instance
|
412
|
+
end.should raise_error(RightScale::Exceptions::Application)
|
413
|
+
end
|
414
|
+
|
415
|
+
it 'should raise RetryableError if shard is disabled for account' do
|
416
|
+
@account.should_receive(:disabled_in_every_shard?).and_return(true)
|
417
|
+
lambda do
|
418
|
+
instance_from_token_id(@token_id)
|
419
|
+
end.should raise_error(RightScale::Exceptions::RetryableError)
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
context :instance_from_agent_id do
|
424
|
+
before(:each) do
|
425
|
+
@token_id = 123
|
426
|
+
@agent_id = "rs-instance-1111-#{@token_id}"
|
427
|
+
@account = flexmock("account")
|
428
|
+
@account.should_receive(:disabled_in_every_shard?).and_return(false).by_default
|
429
|
+
@instance = flexmock("instance", :account => @account)
|
430
|
+
@instance_api_token = flexmock("instance_api_token")
|
431
|
+
@instance_api_token.should_receive(:instance).and_return(@instance).by_default
|
432
|
+
flexmock(InstanceApiToken).should_receive(:find).with(@token_id).and_return(@instance_api_token).by_default
|
433
|
+
end
|
434
|
+
|
435
|
+
it 'should retrieve Instance using agent identity' do
|
436
|
+
instance_from_agent_id(@agent_id).should == @instance
|
437
|
+
end
|
438
|
+
|
439
|
+
it 'should raise error if agent identity invalid' do
|
440
|
+
lambda do
|
441
|
+
instance_from_agent_id("rs-instance-1111")
|
442
|
+
end.should raise_error(ArgumentError)
|
443
|
+
end
|
444
|
+
|
445
|
+
it 'should raise RetryableError if shard is disabled for account' do
|
446
|
+
@account.should_receive(:disabled_in_every_shard?).and_return(true)
|
447
|
+
lambda do
|
448
|
+
instance_from_agent_id(@agent_id)
|
449
|
+
end.should raise_error(RightScale::Exceptions::RetryableError)
|
450
|
+
end
|
451
|
+
end
|
452
|
+
|
453
|
+
context :account do
|
454
|
+
it 'should retrieve Account using id' do
|
455
|
+
flexmock(Account).should_receive(:find).with(123).and_return("account").once
|
456
|
+
account(123).should == "account"
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
context :audit_entry do
|
461
|
+
it 'should retrieve AuditEntry using id' do
|
462
|
+
flexmock(AuditEntry).should_receive(:find).with(123).and_return("audit_entry").once
|
463
|
+
audit_entry(123).should == "audit_entry"
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
context :right_script do
|
468
|
+
it 'should retrieve RightScript using id' do
|
469
|
+
flexmock(RightScript).should_receive(:find).with(123).and_return("right_script").once
|
470
|
+
right_script(123).should == "right_script"
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
context :right_script_from_name do
|
475
|
+
it 'should retrieve RightScript using name' do
|
476
|
+
right_scripts = flexmock("right_scripts")
|
477
|
+
right_scripts.should_receive(:find_by_name).with("name").and_return("script")
|
478
|
+
server_template = flexmock("server_template", :right_scripts => right_scripts)
|
479
|
+
instance = flexmock("instance", :server_template => server_template)
|
480
|
+
right_script_from_name("name", instance).should == "script"
|
481
|
+
end
|
482
|
+
|
483
|
+
it 'should not retrieve RightScript if instance has no server template' do
|
484
|
+
instance = flexmock("instance", :server_template => nil)
|
485
|
+
right_script_from_name("name", instance).should be_nil
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
context :recipe do
|
490
|
+
it 'should retrieve ServerTemplateChefRecipe using id' do
|
491
|
+
flexmock(ServerTemplateChefRecipe).should_receive(:find).with(123).and_return("recipe").once
|
492
|
+
recipe(123).should == "recipe"
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
context :recipe_from_name do
|
497
|
+
it 'should retrieve ServerTemplateChefRecipe using name' do
|
498
|
+
server_template_chef_recipes = flexmock("server_template_chef_recipes")
|
499
|
+
server_template_chef_recipes.should_receive(:find_by_recipe).with("name").and_return("recipe")
|
500
|
+
server_template = flexmock("server_template", :server_template_chef_recipes => server_template_chef_recipes)
|
501
|
+
instance = flexmock("instance", :server_template => server_template)
|
502
|
+
recipe_from_name("name", instance).should == "recipe"
|
503
|
+
end
|
504
|
+
|
505
|
+
it 'should not retrieve ServerTemplateChefRecipe if instance has no server template' do
|
506
|
+
instance = flexmock("instance", :server_template => nil)
|
507
|
+
recipe_from_name("name", instance).should be_nil
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
511
|
+
context :permission do
|
512
|
+
it 'should retrieve Permission using id' do
|
513
|
+
flexmock(Permission).should_receive(:find).with(123).and_return("permission").once
|
514
|
+
permission(123).should == "permission"
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
context :user_credential do
|
519
|
+
it 'should retrieve UserCredential using id' do
|
520
|
+
flexmock(UserCredential).should_receive(:find).with(123).and_return("user_credential").once
|
521
|
+
user_credential(123).should == "user_credential"
|
522
|
+
end
|
523
|
+
end
|
524
|
+
|
525
|
+
context :user_credential_from_fingerprint do
|
526
|
+
it 'should retrieve UserCredential using fingerprint' do
|
527
|
+
flexmock(UserCredential).should_receive(:find_by_public_value_fingerprint).with("123").and_return("user_credential").once
|
528
|
+
user_credential_from_fingerprint("123").should == "user_credential"
|
529
|
+
end
|
530
|
+
end
|
531
|
+
|
532
|
+
context :setting do
|
533
|
+
it 'should retrieve Setting using id' do
|
534
|
+
flexmock(Setting).should_receive(:find).with(123).and_return("setting").once
|
535
|
+
setting(123).should == "setting"
|
536
|
+
end
|
537
|
+
end
|
538
|
+
|
539
|
+
context :repositories do
|
540
|
+
it 'should retrieve all Repository objects' do
|
541
|
+
flexmock(Repository).should_receive(:find).with(:all).and_return("repositories").once
|
542
|
+
repositories.should == "repositories"
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
end
|