right_agent 0.6.6 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/lib/right_agent/agent.rb +26 -25
  2. data/lib/right_agent/agent_config.rb +28 -2
  3. data/lib/right_agent/command/command_constants.rb +2 -2
  4. data/lib/right_agent/core_payload_types/executable_bundle.rb +3 -21
  5. data/lib/right_agent/core_payload_types/login_user.rb +19 -4
  6. data/lib/right_agent/core_payload_types/recipe_instantiation.rb +7 -1
  7. data/lib/right_agent/core_payload_types/right_script_instantiation.rb +7 -1
  8. data/lib/right_agent/dispatcher.rb +6 -19
  9. data/lib/right_agent/idempotent_request.rb +72 -17
  10. data/lib/right_agent/monkey_patches/ruby_patch.rb +0 -1
  11. data/lib/right_agent/monkey_patches.rb +0 -1
  12. data/lib/right_agent/operation_result.rb +27 -4
  13. data/lib/right_agent/packets.rb +47 -23
  14. data/lib/right_agent/platform/darwin.rb +33 -2
  15. data/lib/right_agent/platform/linux.rb +98 -2
  16. data/lib/right_agent/platform/windows.rb +41 -6
  17. data/lib/right_agent/platform.rb +11 -2
  18. data/lib/right_agent/scripts/agent_controller.rb +2 -1
  19. data/lib/right_agent/scripts/agent_deployer.rb +2 -2
  20. data/lib/right_agent/scripts/stats_manager.rb +7 -3
  21. data/lib/right_agent/sender.rb +45 -28
  22. data/lib/right_agent.rb +2 -5
  23. data/right_agent.gemspec +5 -3
  24. data/spec/agent_config_spec.rb +1 -1
  25. data/spec/agent_spec.rb +26 -20
  26. data/spec/core_payload_types/login_user_spec.rb +7 -3
  27. data/spec/idempotent_request_spec.rb +218 -48
  28. data/spec/operation_result_spec.rb +19 -0
  29. data/spec/packets_spec.rb +42 -1
  30. data/spec/platform/darwin.rb +11 -0
  31. data/spec/platform/linux.rb +23 -0
  32. data/spec/platform/linux_volume_manager_spec.rb +43 -43
  33. data/spec/platform/platform_spec.rb +35 -32
  34. data/spec/platform/windows.rb +11 -0
  35. data/spec/sender_spec.rb +21 -25
  36. metadata +47 -40
  37. data/lib/right_agent/broker_client.rb +0 -686
  38. data/lib/right_agent/ha_broker_client.rb +0 -1327
  39. data/lib/right_agent/monkey_patches/amqp_patch.rb +0 -274
  40. data/lib/right_agent/monkey_patches/ruby_patch/string_patch.rb +0 -107
  41. data/lib/right_agent/stats_helper.rb +0 -745
  42. data/spec/broker_client_spec.rb +0 -962
  43. data/spec/ha_broker_client_spec.rb +0 -1695
  44. data/spec/monkey_patches/amqp_patch_spec.rb +0 -100
  45. data/spec/monkey_patches/string_patch_spec.rb +0 -99
  46. data/spec/stats_helper_spec.rb +0 -686
@@ -44,11 +44,13 @@ describe RightScale::IdempotentRequest do
44
44
  end
45
45
 
46
46
  context ':targets option' do
47
- context 'when :targets=>nil' do
47
+
48
+ context 'when :targets => nil' do
48
49
  it 'should send target-less requests' do
49
50
  request = RightScale::IdempotentRequest.new('type', 'payload')
50
51
  flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
51
52
  and_yield(RightScale::OperationResult.non_delivery('test')).once
53
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_TIMEOUT, Proc).once
52
54
  flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_RETRY_DELAY, Proc).once
53
55
  request.run
54
56
  end
@@ -56,9 +58,10 @@ describe RightScale::IdempotentRequest do
56
58
 
57
59
  context 'when one target is specified' do
58
60
  it 'should send a targeted request' do
59
- request = RightScale::IdempotentRequest.new('type', 'payload', :targets=>[1])
61
+ request = RightScale::IdempotentRequest.new('type', 'payload', :targets => [1])
60
62
  flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', 1, Proc).
61
63
  and_yield(RightScale::OperationResult.non_delivery('test')).once
64
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_TIMEOUT, Proc).once
62
65
  flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_RETRY_DELAY, Proc).once
63
66
  request.run
64
67
  end
@@ -66,71 +69,238 @@ describe RightScale::IdempotentRequest do
66
69
 
67
70
  context 'when many targets are specified' do
68
71
  it 'should choose a random target' do
69
- request = RightScale::IdempotentRequest.new('type', 'payload', :targets=>[1, 2, 3])
72
+ request = RightScale::IdempotentRequest.new('type', 'payload', :targets => [1, 2, 3])
70
73
  flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).and_return do |type, payload, tgt, block|
71
74
  type.should == 'type'
72
75
  payload.should == 'payload'
73
- [1,2,3].should include(tgt)
76
+ [1, 2, 3].should include(tgt)
74
77
  block.call(RightScale::OperationResult.non_delivery('test'))
75
78
  end
79
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_TIMEOUT, Proc).once
76
80
  flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_RETRY_DELAY, Proc).once
77
81
  request.run
78
82
  end
79
83
  end
80
- end
81
84
 
82
- it 'should retry non-delivery responses' do
83
- request = RightScale::IdempotentRequest.new('type', 'payload')
84
- flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
85
- and_yield(RightScale::OperationResult.non_delivery('test')).once
86
- flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_RETRY_DELAY, Proc).once
87
- request.run
88
85
  end
89
86
 
90
- it 'should retry retry responses' do
91
- request = RightScale::IdempotentRequest.new('type', 'payload')
92
- flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
93
- and_yield(RightScale::OperationResult.retry('test')).once
94
- flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_RETRY_DELAY, Proc).once
95
- request.run
96
- end
87
+ context ':retry_on_error option' do
97
88
 
98
- it 'should fail in case of error responses by default' do
99
- request = RightScale::IdempotentRequest.new('type', 'payload')
100
- flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
101
- and_yield(RightScale::OperationResult.error('test')).once
102
- flexmock(request).should_receive(:fail).once
103
- request.run
104
- end
89
+ context 'when not specified' do
90
+ it 'should fail if receives error response' do
91
+ request = RightScale::IdempotentRequest.new('type', 'payload')
92
+ flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
93
+ and_yield(RightScale::OperationResult.error('test')).once
94
+ flexmock(request).should_receive(:fail).once
95
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_TIMEOUT, Proc).once
96
+ request.run
97
+ end
98
+ end
99
+
100
+ context 'when specified as true' do
101
+ it 'should retry if receives error response' do
102
+ request = RightScale::IdempotentRequest.new('type', 'payload', :retry_on_error => true)
103
+ flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
104
+ and_yield(RightScale::OperationResult.error('test')).once
105
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_RETRY_DELAY, Proc).once
106
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_TIMEOUT, Proc).once
107
+ request.run
108
+ end
109
+
110
+ it 'should ignore duplicate responses' do
111
+ request = RightScale::IdempotentRequest.new('type', 'payload', :retry_on_error => true)
112
+ flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).and_return do |t, p, tgt, b|
113
+ 5.times { b.call(RightScale::OperationResult.success('test')) }
114
+ end
115
+ flexmock(request).should_receive(:fail).never
116
+ flexmock(request).should_receive(:succeed).once
117
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_RETRY_DELAY, Proc).never
118
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_TIMEOUT, Proc).once
119
+ request.run
120
+ end
121
+
122
+ it 'should never retry after cancel response' do
123
+ request = RightScale::IdempotentRequest.new('type', 'payload', :retry_on_error => true)
124
+ flexmock(RightScale::Log).should_receive(:info).with("Request type canceled (enough already)").once
125
+ flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
126
+ and_yield(RightScale::OperationResult.cancel('enough already')).once
127
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_RETRY_DELAY, Proc).never
128
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_TIMEOUT, Proc).once
129
+ request.run
130
+ end
131
+ end
105
132
 
106
- it 'should retry error responses when told to' do
107
- request = RightScale::IdempotentRequest.new('type', 'payload', :retry_on_error => true)
108
- flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
109
- and_yield(RightScale::OperationResult.error('test')).once
110
- flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_RETRY_DELAY, Proc).once
111
- request.run
112
133
  end
113
134
 
114
- it 'should ignore responses that arrive post-cancel' do
115
- request = RightScale::IdempotentRequest.new('type', 'payload')
116
- flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
117
- and_yield(RightScale::OperationResult.success('test')).once
118
- flexmock(request).should_receive(:fail).once
119
- flexmock(request).should_receive(:succeed).never
120
- flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_RETRY_DELAY, Proc).never
121
- request.cancel('test')
122
- request.run
135
+ context ':retry_delay options' do
136
+
137
+ context 'when using default settings' do
138
+ it 'should retry non-delivery responses' do
139
+ request = RightScale::IdempotentRequest.new('type', 'payload')
140
+ flexmock(RightScale::Log).should_receive(:info).with(/Retrying in 5 seconds/).once
141
+ flexmock(RightScale::Log).should_receive(:info).with("Request non-delivery (test) for type").once
142
+ flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
143
+ and_yield(RightScale::OperationResult.non_delivery('test')).once
144
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_RETRY_DELAY, Proc).once
145
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_TIMEOUT, Proc).once
146
+ request.run
147
+ end
148
+
149
+ it 'should retry retry responses' do
150
+ request = RightScale::IdempotentRequest.new('type', 'payload')
151
+ flexmock(RightScale::Log).should_receive(:info).with(/Retrying in 5 seconds/).once
152
+ flexmock(RightScale::Log).should_receive(:info).with("Request type failed (test) and should be retried").once
153
+ flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
154
+ and_yield(RightScale::OperationResult.retry('test')).once
155
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_RETRY_DELAY, Proc).once
156
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_TIMEOUT, Proc).once
157
+ request.run
158
+ end
159
+
160
+ it 'should log default retry reason if none given' do
161
+ request = RightScale::IdempotentRequest.new('type', 'payload')
162
+ flexmock(RightScale::Log).should_receive(:info).with(/Retrying in 5 seconds/).once
163
+ flexmock(RightScale::Log).should_receive(:info).with("Request type failed (RightScale not ready) and should be retried").once
164
+ flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
165
+ and_yield(RightScale::OperationResult.retry).once
166
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_RETRY_DELAY, Proc).once
167
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_TIMEOUT, Proc).once
168
+ request.run
169
+ end
170
+
171
+ it 'should ignore responses that arrive post-cancel' do
172
+ request = RightScale::IdempotentRequest.new('type', 'payload')
173
+ flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
174
+ and_yield(RightScale::OperationResult.success('test')).once
175
+ flexmock(request).should_receive(:fail).once
176
+ flexmock(request).should_receive(:succeed).never
177
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_RETRY_DELAY, Proc).never
178
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_TIMEOUT, Proc).once
179
+ request.cancel('test')
180
+ request.run
181
+ end
182
+
183
+ it 'should never retry after cancel response' do
184
+ request = RightScale::IdempotentRequest.new('type', 'payload')
185
+ flexmock(RightScale::Log).should_receive(:info).with("Request type canceled (enough already)").once
186
+ flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
187
+ and_yield(RightScale::OperationResult.cancel('enough already')).once
188
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_RETRY_DELAY, Proc).never
189
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_TIMEOUT, Proc).once
190
+ request.run
191
+ end
192
+ end
193
+
194
+ context 'when a :retry_delay is specified' do
195
+ it 'should control the initial retry delay' do
196
+ retry_delay = 10
197
+ request = RightScale::IdempotentRequest.new('type', 'payload', :retry_delay => retry_delay)
198
+ flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
199
+ and_yield(RightScale::OperationResult.retry('test')).once
200
+ flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).once
201
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_TIMEOUT, Proc).once
202
+ flexmock(EM).should_receive(:next_tick).never
203
+ request.run
204
+ end
205
+
206
+ it 'should treat -1 as meaning no delay' do
207
+ retry_delay = -1
208
+ request = RightScale::IdempotentRequest.new('type', 'payload', :retry_delay => retry_delay)
209
+ flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
210
+ and_yield(RightScale::OperationResult.retry('test')).once
211
+ flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).never
212
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_TIMEOUT, Proc).once
213
+ flexmock(EM).should_receive(:next_tick).once
214
+ request.run
215
+ end
216
+ end
217
+
218
+ context 'when a :retry_delay_count is specified' do
219
+ it 'should limit the number of retries using the :retry_delay value' do
220
+ retry_delay = 10
221
+ retry_delay_count = 1
222
+ backoff_factor = RightScale::IdempotentRequest::RETRY_BACKOFF_FACTOR
223
+ request = RightScale::IdempotentRequest.new('type', 'payload', :retry_delay => retry_delay,
224
+ :retry_delay_count => retry_delay_count)
225
+ flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
226
+ and_yield(RightScale::OperationResult.retry('test')).twice
227
+ flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).and_yield.once
228
+ flexmock(EM).should_receive(:add_timer).with(retry_delay * backoff_factor, Proc).once
229
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_TIMEOUT, Proc).once
230
+ flexmock(EM).should_receive(:next_tick).never
231
+ request.run
232
+ end
233
+
234
+ it 'should backoff as delay time increases' do
235
+ retry_delay = 10
236
+ retry_delay_count = 2
237
+ max_retry_delay = 30
238
+ backoff_factor = RightScale::IdempotentRequest::RETRY_BACKOFF_FACTOR
239
+ request = RightScale::IdempotentRequest.new('type', 'payload', :retry_delay => retry_delay,
240
+ :retry_delay_count => retry_delay_count,
241
+ :max_retry_delay => max_retry_delay)
242
+ flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
243
+ and_yield(RightScale::OperationResult.retry('test')).times(4)
244
+ flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).and_yield.twice
245
+ flexmock(EM).should_receive(:add_timer).with(retry_delay * backoff_factor, Proc).and_yield.once
246
+ flexmock(EM).should_receive(:add_timer).with(max_retry_delay, Proc).once
247
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_TIMEOUT, Proc).once
248
+ flexmock(EM).should_receive(:next_tick).never
249
+ request.run
250
+ request.instance_variable_get(:@retry_delay_count).should == retry_delay_count / 2
251
+ end
252
+ end
253
+
254
+ context 'when a :max_retry_delay is specified' do
255
+ it 'should limit the retry delay total backoff' do
256
+ retry_delay = 10
257
+ retry_delay_count = 1
258
+ max_retry_delay = 30
259
+ backoff_factor = RightScale::IdempotentRequest::RETRY_BACKOFF_FACTOR
260
+ request = RightScale::IdempotentRequest.new('type', 'payload', :retry_delay => retry_delay,
261
+ :retry_delay_count => retry_delay_count,
262
+ :max_retry_delay => max_retry_delay)
263
+ flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).
264
+ and_yield(RightScale::OperationResult.retry('test')).times(3)
265
+ flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).and_yield.once
266
+ flexmock(EM).should_receive(:add_timer).with(retry_delay * backoff_factor, Proc).and_yield.once
267
+ flexmock(EM).should_receive(:add_timer).with(max_retry_delay, Proc).once
268
+ flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_TIMEOUT, Proc).once
269
+ flexmock(EM).should_receive(:next_tick).never
270
+ request.run
271
+ end
272
+ end
273
+
123
274
  end
124
275
 
125
- it 'should ignore duplicate responses' do
126
- request = RightScale::IdempotentRequest.new('type', 'payload', :retry_on_error => true)
127
- flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).and_return do |t, p, tgt, b|
128
- 5.times { b.call(RightScale::OperationResult.success('test')) }
276
+ context ':timeout option' do
277
+ context 'when disable timeout' do
278
+ it 'should not timeout' do
279
+ request = RightScale::IdempotentRequest.new('type', 'payload', :timeout => -1)
280
+ flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).once
281
+ flexmock(EM).should_receive(:add_timer).never
282
+ request.run
283
+ end
284
+ end
285
+
286
+ context 'when a timeout is specified' do
287
+ it 'should time the response' do
288
+ timeout = 10
289
+ request = RightScale::IdempotentRequest.new('type', 'payload', :timeout => timeout)
290
+ flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).once
291
+ flexmock(EM).should_receive(:add_timer).with(timeout, Proc).once
292
+ request.run
293
+ end
294
+
295
+ it 'should log a message when timeout' do
296
+ timeout = 10
297
+ request = RightScale::IdempotentRequest.new('type', 'payload', :timeout => timeout)
298
+ flexmock(RightScale::Log).should_receive(:info).with("Request type timed out after 10 seconds").once
299
+ flexmock(RightScale::Sender.instance).should_receive(:send_retryable_request).with('type', 'payload', nil, Proc).once
300
+ flexmock(EM).should_receive(:add_timer).with(timeout, Proc).and_yield.once
301
+ request.run
302
+ end
129
303
  end
130
- flexmock(request).should_receive(:fail).never
131
- flexmock(request).should_receive(:succeed).once
132
- flexmock(EM).should_receive(:add_timer).with(RightScale::IdempotentRequest::DEFAULT_RETRY_DELAY, nil, Proc).never
133
- request.run
134
304
  end
135
305
 
136
306
  end
@@ -140,6 +140,13 @@ describe RightScale::OperationResult do
140
140
  result.non_delivery?.should be_true
141
141
  result.content.should == "Non-delivery"
142
142
  end
143
+
144
+ it "should store cancel content value and respond to cancel query" do
145
+ result = RightScale::OperationResult.cancel("Cancel")
146
+ result.kind_of?(RightScale::OperationResult).should be_true
147
+ result.cancel?.should be_true
148
+ result.content.should == "Cancel"
149
+ end
143
150
  end
144
151
 
145
152
  describe "when converting result to string" do
@@ -160,12 +167,24 @@ describe RightScale::OperationResult do
160
167
  result.status.should == "error"
161
168
  end
162
169
 
170
+ it "should display retry reason" do
171
+ result = RightScale::OperationResult.retry("because")
172
+ result.to_s.should == "retry (because)"
173
+ result.status.should == "retry"
174
+ end
175
+
163
176
  it "should display non-delivery reason" do
164
177
  result = RightScale::OperationResult.non_delivery(RightScale::OperationResult::TTL_EXPIRATION)
165
178
  result.to_s.should == "non-delivery (TTL expiration)"
166
179
  result.status.should == "non-delivery"
167
180
  end
168
181
 
182
+ it "should display cancel reason" do
183
+ result = RightScale::OperationResult.cancel("enough already")
184
+ result.to_s.should == "cancel (enough already)"
185
+ result.status.should == "cancel"
186
+ end
187
+
169
188
  end
170
189
 
171
190
  end
data/spec/packets_spec.rb CHANGED
@@ -65,7 +65,7 @@ describe "Packet: Base class" do
65
65
  packet.to_s(filter = nil, version = :send_version).should == "[test_packet v5]"
66
66
  end
67
67
 
68
- it "should convert to string including duration if filtered and size is also known" do
68
+ it "should convert to string including duration if filtered and size known" do
69
69
  packet = TestPacket.new(1, 0.042122, 323)
70
70
  packet.to_s(filter = nil).should == "[test_packet] (323 bytes, 0.042 sec)"
71
71
  packet.to_s(filter = []).should == "[test_packet] (323 bytes)"
@@ -74,6 +74,17 @@ describe "Packet: Base class" do
74
74
  packet.to_s(filter = [:duration]).should == "[test_packet]"
75
75
  end
76
76
 
77
+ it "should convert to string including local duration if filtered and size known" do
78
+ flexmock(Time).should_receive(:now).and_return(Time.at(1000000), Time.at(1000000.012))
79
+ packet = TestPacket.new(1, nil, 323)
80
+ packet.received_at = Time.now.to_f
81
+ packet.to_s(filter = nil).should == "[test_packet] (323 bytes, 0.012 sec)"
82
+ packet.to_s(filter = []).should == "[test_packet] (323 bytes)"
83
+ packet.to_s(filter = [:local_duration]).should == "[test_packet] (323 bytes, 0.012 sec)"
84
+ packet = TestPacket.new(1)
85
+ packet.to_s(filter = [:local_duration]).should == "[test_packet]"
86
+ end
87
+
77
88
  it "should convert floating point values to decimal digit string with at least two digit precision" do
78
89
  packet = TestPacket.new(1)
79
90
  packet.enough_precision(100.5).should == "101"
@@ -125,6 +136,12 @@ describe "Packet: Base class" do
125
136
  packet.to_msgpack.should_not =~ /cls_attr/
126
137
  end
127
138
 
139
+ it "should not dump excluded instance variables" do
140
+ packet = TestPacket.new(382)
141
+ packet.received_at = Time.now.to_f
142
+ packet.to_msgpack.should_not =~ /received_at/
143
+ end
144
+
128
145
  it "should remove '@' from instance variables" do
129
146
  packet = TestPacket.new(2)
130
147
  packet.to_msgpack.should_not =~ /@attr1/
@@ -157,6 +174,12 @@ describe "Packet: Base class" do
157
174
  packet.to_json.should_not =~ /cls_attr/
158
175
  end
159
176
 
177
+ it "should not dump excluded instance variables" do
178
+ packet = TestPacket.new(382)
179
+ packet.received_at = Time.now.to_f
180
+ packet.to_json.should_not =~ /received_at/
181
+ end
182
+
160
183
  it "should remove '@' from instance variables" do
161
184
  packet = TestPacket.new(2)
162
185
  packet.to_json.should_not =~ /@attr1/
@@ -251,6 +274,15 @@ describe "Packet: Request" do
251
274
  MessagePack.load(packet.to_msgpack).send_version.should == RightScale::Packet::DEFAULT_VERSION
252
275
  JSON.load(packet.to_json).send_version.should == RightScale::Packet::DEFAULT_VERSION
253
276
  end
277
+
278
+ it "should handle either a single target or an array" do
279
+ packet = RightScale::Request.new('/some/foo', 'payload', :target => "target1")
280
+ packet.token = 123
281
+ packet.to_s([:target]).should == '[request] <> <123> /some/foo, target target1'
282
+ packet = RightScale::Request.new('/some/foo', 'payload', :target => ["target1", "target2"])
283
+ packet.token = 123
284
+ packet.to_s([:target]).should == "[request] <> <123> /some/foo, target [target1, target2]"
285
+ end
254
286
  end
255
287
 
256
288
 
@@ -331,6 +363,15 @@ describe "Packet: Push" do
331
363
  MessagePack.load(packet.to_msgpack).send_version.should == RightScale::Packet::DEFAULT_VERSION
332
364
  JSON.load(packet.to_json).send_version.should == RightScale::Packet::DEFAULT_VERSION
333
365
  end
366
+
367
+ it "should handle either a single target or an array" do
368
+ packet = RightScale::Push.new('/some/foo', 'payload', :target => "target1")
369
+ packet.token = 123
370
+ packet.to_s([:target]).should == '[push] <> <123> /some/foo, target target1'
371
+ packet = RightScale::Push.new('/some/foo', 'payload', :target => ["target1", "target2"])
372
+ packet.token = 123
373
+ packet.to_s([:target]).should == "[push] <> <123> /some/foo, target [target1, target2]"
374
+ end
334
375
  end
335
376
 
336
377
 
@@ -0,0 +1,11 @@
1
+ module RightScale
2
+ describe Platform do
3
+ subject { RightScale::Platform }
4
+
5
+ context :installer do
6
+ context :install do
7
+ specify { lambda { subject.installer.install([]) }.should raise_exception }
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+ module RightScale
2
+ describe Platform do
3
+
4
+ context :installer do
5
+ context :install do
6
+ it 'should succeed if no packages are specified' do
7
+ packages = []
8
+ RightScale::Platform.installer.install(packages).should == true
9
+ end
10
+
11
+ it 'should succeed if all packages install successfully' do
12
+ packages = ['syslog-ng']
13
+ RightScale::Platform.installer.install(packages).should == true
14
+ end
15
+
16
+ it 'should fail if one more packages are not found' do
17
+ packages = ['jdk-6u26-linux-x64']
18
+ lambda { RightScale::Platform.installer.install(packages) }.should raise_error
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -32,10 +32,10 @@ if RightScale::Platform.linux?
32
32
  context :parse_volumes do
33
33
  it 'can parse volumes from blkid output' do
34
34
  blkid_resp = <<EOF
35
- /dev/xvdh1: SEC_TYPE="msdos" LABEL="METADATA" UUID="681B-8C5D" TYPE="vfat"
36
- /dev/xvdb1: LABEL="SWAP-xvdb1" UUID="d51fcca0-6b10-4934-a572-f3898dfd8840" TYPE="swap"
37
- /dev/xvda1: UUID="f4746f9c-0557-4406-9267-5e918e87ca2e" TYPE="ext3"
38
- /dev/xvda2: UUID="14d88b9e-9fe6-4974-a8d6-180acdae4016" TYPE="ext3"
35
+ /dev/xvdh1: SEC_TYPE="msdos" LABEL="METADATA" UUID="681B-8C5D" TYPE="vfat"
36
+ /dev/xvdb1: LABEL="SWAP-xvdb1" UUID="d51fcca0-6b10-4934-a572-f3898dfd8840" TYPE="swap"
37
+ /dev/xvda1: UUID="f4746f9c-0557-4406-9267-5e918e87ca2e" TYPE="ext3"
38
+ /dev/xvda2: UUID="14d88b9e-9fe6-4974-a8d6-180acdae4016" TYPE="ext3"
39
39
  EOF
40
40
  volume_hash_ary = [
41
41
  {:device => "/dev/xvdh1", :sec_type => "msdos", :label => "METADATA", :uuid => "681B-8C5D", :type => "vfat", :filesystem => "vfat"},
@@ -61,10 +61,10 @@ EOF
61
61
 
62
62
  it 'can filter results with only one condition' do
63
63
  blkid_resp = <<EOF
64
- /dev/xvdh1: SEC_TYPE="msdos" LABEL="METADATA" UUID="681B-8C5D" TYPE="vfat"
65
- /dev/xvdb1: LABEL="SWAP-xvdb1" UUID="d51fcca0-6b10-4934-a572-f3898dfd8840" TYPE="swap"
66
- /dev/xvda1: UUID="f4746f9c-0557-4406-9267-5e918e87ca2e" TYPE="ext3"
67
- /dev/xvda2: UUID="14d88b9e-9fe6-4974-a8d6-180acdae4016" TYPE="ext3"
64
+ /dev/xvdh1: SEC_TYPE="msdos" LABEL="METADATA" UUID="681B-8C5D" TYPE="vfat"
65
+ /dev/xvdb1: LABEL="SWAP-xvdb1" UUID="d51fcca0-6b10-4934-a572-f3898dfd8840" TYPE="swap"
66
+ /dev/xvda1: UUID="f4746f9c-0557-4406-9267-5e918e87ca2e" TYPE="ext3"
67
+ /dev/xvda2: UUID="14d88b9e-9fe6-4974-a8d6-180acdae4016" TYPE="ext3"
68
68
  EOF
69
69
  volume_hash_ary = [
70
70
  {:device => "/dev/xvdh1", :sec_type => "msdos", :label => "METADATA", :uuid => "681B-8C5D", :type => "vfat", :filesystem => "vfat"}
@@ -77,10 +77,10 @@ EOF
77
77
 
78
78
  it 'can filter results with many conditions' do
79
79
  blkid_resp = <<EOF
80
- /dev/xvdh1: SEC_TYPE="msdos" LABEL="METADATA" UUID="681B-8C5D" TYPE="vfat"
81
- /dev/xvdb1: LABEL="SWAP-xvdb1" UUID="d51fcca0-6b10-4934-a572-f3898dfd8840" TYPE="swap"
82
- /dev/xvda1: UUID="f4746f9c-0557-4406-9267-5e918e87ca2e" TYPE="ext3"
83
- /dev/xvda2: UUID="14d88b9e-9fe6-4974-a8d6-180acdae4016" TYPE="ext3"
80
+ /dev/xvdh1: SEC_TYPE="msdos" LABEL="METADATA" UUID="681B-8C5D" TYPE="vfat"
81
+ /dev/xvdb1: LABEL="SWAP-xvdb1" UUID="d51fcca0-6b10-4934-a572-f3898dfd8840" TYPE="swap"
82
+ /dev/xvda1: UUID="f4746f9c-0557-4406-9267-5e918e87ca2e" TYPE="ext3"
83
+ /dev/xvda2: UUID="14d88b9e-9fe6-4974-a8d6-180acdae4016" TYPE="ext3"
84
84
  EOF
85
85
  volume_hash_ary = [
86
86
  {:device => "/dev/xvda1", :uuid => "f4746f9c-0557-4406-9267-5e918e87ca2e", :type => "ext3", :filesystem => "ext3"},
@@ -96,8 +96,8 @@ EOF
96
96
  context :mount_volume do
97
97
  it 'mounts the specified volume if it is not already mounted' do
98
98
  mount_resp = <<EOF
99
- /dev/xvda2 on / type ext3 (rw,noatime,errors=remount-ro)
100
- proc on /proc type proc (rw,noexec,nosuid,nodev)
99
+ /dev/xvda2 on / type ext3 (rw,noatime,errors=remount-ro)
100
+ proc on /proc type proc (rw,noexec,nosuid,nodev)
101
101
  EOF
102
102
 
103
103
  mount_popen_mock = flexmock(:read => mount_resp)
@@ -109,9 +109,9 @@ EOF
109
109
 
110
110
  it 'does not attempt to re-mount the volume' do
111
111
  mount_resp = <<EOF
112
- /dev/xvda2 on / type ext3 (rw,noatime,errors=remount-ro)
113
- proc on /proc type proc (rw,noexec,nosuid,nodev)
114
- /dev/xvdh1 on /var/spool/softlayer type vfat (rw) [METADATA]
112
+ /dev/xvda2 on / type ext3 (rw,noatime,errors=remount-ro)
113
+ proc on /proc type proc (rw,noexec,nosuid,nodev)
114
+ /dev/xvdh1 on /var/spool/softlayer type vfat (rw) [METADATA]
115
115
  EOF
116
116
 
117
117
  mount_popen_mock = flexmock(:read => mount_resp)
@@ -131,19 +131,19 @@ EOF
131
131
 
132
132
  it 'raises volume error when the device is already mounted to a different mountpoint' do
133
133
  mount_resp = <<EOF
134
- /dev/xvda2 on / type ext3 (rw,noatime,errors=remount-ro)
135
- proc on /proc type proc (rw,noexec,nosuid,nodev)
136
- none on /sys type sysfs (rw,noexec,nosuid,nodev)
137
- none on /sys/kernel/debug type debugfs (rw)
138
- none on /sys/kernel/security type securityfs (rw)
139
- none on /dev type devtmpfs (rw,mode=0755)
140
- none on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
141
- none on /dev/shm type tmpfs (rw,nosuid,nodev)
142
- none on /var/run type tmpfs (rw,nosuid,mode=0755)
143
- none on /var/lock type tmpfs (rw,noexec,nosuid,nodev)
144
- none on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
145
- /dev/xvda1 on /boot type ext3 (rw,noatime)
146
- /dev/xvdh1 on /mnt type vfat (rw) [METADATA]
134
+ /dev/xvda2 on / type ext3 (rw,noatime,errors=remount-ro)
135
+ proc on /proc type proc (rw,noexec,nosuid,nodev)
136
+ none on /sys type sysfs (rw,noexec,nosuid,nodev)
137
+ none on /sys/kernel/debug type debugfs (rw)
138
+ none on /sys/kernel/security type securityfs (rw)
139
+ none on /dev type devtmpfs (rw,mode=0755)
140
+ none on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
141
+ none on /dev/shm type tmpfs (rw,nosuid,nodev)
142
+ none on /var/run type tmpfs (rw,nosuid,mode=0755)
143
+ none on /var/lock type tmpfs (rw,noexec,nosuid,nodev)
144
+ none on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
145
+ /dev/xvda1 on /boot type ext3 (rw,noatime)
146
+ /dev/xvdh1 on /mnt type vfat (rw) [METADATA]
147
147
  EOF
148
148
 
149
149
  mount_popen_mock = flexmock(:read => mount_resp)
@@ -154,19 +154,19 @@ EOF
154
154
 
155
155
  it 'raises volume error when a different device is already mounted to the specified mountpoint' do
156
156
  mount_resp = <<EOF
157
- /dev/xvda2 on / type ext3 (rw,noatime,errors=remount-ro)
158
- proc on /proc type proc (rw,noexec,nosuid,nodev)
159
- none on /sys type sysfs (rw,noexec,nosuid,nodev)
160
- none on /sys/kernel/debug type debugfs (rw)
161
- none on /sys/kernel/security type securityfs (rw)
162
- none on /dev type devtmpfs (rw,mode=0755)
163
- none on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
164
- none on /dev/shm type tmpfs (rw,nosuid,nodev)
165
- none on /var/run type tmpfs (rw,nosuid,mode=0755)
166
- none on /var/lock type tmpfs (rw,noexec,nosuid,nodev)
167
- none on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
168
- /dev/xvda1 on /boot type ext3 (rw,noatime)
169
- /dev/xvdh2 on /var/spool/softlayer type vfat (rw) [METADATA]
157
+ /dev/xvda2 on / type ext3 (rw,noatime,errors=remount-ro)
158
+ proc on /proc type proc (rw,noexec,nosuid,nodev)
159
+ none on /sys type sysfs (rw,noexec,nosuid,nodev)
160
+ none on /sys/kernel/debug type debugfs (rw)
161
+ none on /sys/kernel/security type securityfs (rw)
162
+ none on /dev type devtmpfs (rw,mode=0755)
163
+ none on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
164
+ none on /dev/shm type tmpfs (rw,nosuid,nodev)
165
+ none on /var/run type tmpfs (rw,nosuid,mode=0755)
166
+ none on /var/lock type tmpfs (rw,noexec,nosuid,nodev)
167
+ none on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
168
+ /dev/xvda1 on /boot type ext3 (rw,noatime)
169
+ /dev/xvdh2 on /var/spool/softlayer type vfat (rw) [METADATA]
170
170
  EOF
171
171
 
172
172
  mount_popen_mock = flexmock(:read => mount_resp)