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,54 @@
|
|
1
|
+
# -*-ruby-*-
|
2
|
+
# Copyright: Copyright (c) 2011 RightScale, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# 'Software'), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
18
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
19
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
20
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
21
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
require 'rubygems'
|
24
|
+
|
25
|
+
Gem::Specification.new do |spec|
|
26
|
+
spec.name = 'right_infrastructure_agent'
|
27
|
+
spec.version = '1.1.2'
|
28
|
+
spec.date = '2014-07-24'
|
29
|
+
spec.authors = ['Lee Kirchhoff', 'Raphael Simon']
|
30
|
+
spec.email = 'lee@rightscale.com'
|
31
|
+
spec.homepage = 'https://github.com/rightscale/right_infrastructure_agent'
|
32
|
+
spec.platform = Gem::Platform::RUBY
|
33
|
+
spec.summary = 'RightAgent extension for use by RightScale infrastructure servers'
|
34
|
+
spec.has_rdoc = true
|
35
|
+
spec.rdoc_options = ["--main", "README.rdoc", "--title", "RightInfrastructureAgent"]
|
36
|
+
spec.extra_rdoc_files = ["README.rdoc"]
|
37
|
+
spec.required_ruby_version = '>= 1.8.7'
|
38
|
+
spec.require_path = 'lib'
|
39
|
+
|
40
|
+
spec.add_dependency('right_support', '~> 2.1')
|
41
|
+
spec.add_dependency('right_amqp', '~> 0.4')
|
42
|
+
spec.add_dependency('right_agent', '~> 2.0')
|
43
|
+
|
44
|
+
spec.description = <<-EOF
|
45
|
+
RightInfrastructureAgent provides the foundation for RightScale infrastructure
|
46
|
+
servers that connect into the RightScale system via the RabbitMQ message bus.
|
47
|
+
It extends RightAgent in configuration, monitoring, and packet handling areas
|
48
|
+
as needed generically by infrastructure servers.
|
49
|
+
EOF
|
50
|
+
|
51
|
+
candidates = Dir.glob("{lib,spec}/**/*") +
|
52
|
+
["LICENSE", "README.rdoc", "Rakefile", "right_infrastructure_agent.gemspec"]
|
53
|
+
spec.files = candidates.sort
|
54
|
+
end
|
@@ -0,0 +1,305 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2011-2013 RightScale, Inc, All Rights Reserved Worldwide.
|
3
|
+
#
|
4
|
+
# THIS PROGRAM IS CONFIDENTIAL AND PROPRIETARY TO RIGHTSCALE
|
5
|
+
# AND CONSTITUTES A VALUABLE TRADE SECRET. Any unauthorized use,
|
6
|
+
# reproduction, modification, or disclosure of this program is
|
7
|
+
# strictly prohibited. Any use of this program by an authorized
|
8
|
+
# licensee is strictly subject to the terms and conditions,
|
9
|
+
# including confidentiality obligations, set forth in the applicable
|
10
|
+
# License Agreement between RightScale.com, Inc. and the licensee.
|
11
|
+
#++
|
12
|
+
|
13
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
14
|
+
|
15
|
+
describe RightScale::GlobalObjectReplicatorSink do
|
16
|
+
|
17
|
+
include FlexMock::ArgumentTypes
|
18
|
+
|
19
|
+
class SystemConfig; end
|
20
|
+
|
21
|
+
module RightSharding
|
22
|
+
module ShardHandler
|
23
|
+
def self.fetch_this_shard_id(system_config)
|
24
|
+
9
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# A pseudo HTTP controller applying GlobalObjectReplicatorSink
|
30
|
+
class GlobalObjectReplicatorSinkController
|
31
|
+
include RightScale::GlobalObjectReplicatorSink
|
32
|
+
|
33
|
+
attr_reader :logger
|
34
|
+
attr_reader :params
|
35
|
+
|
36
|
+
def initialize(params = {})
|
37
|
+
@params = params
|
38
|
+
@logger = RightScale::Log
|
39
|
+
end
|
40
|
+
|
41
|
+
def global_object_replicator_sink
|
42
|
+
"core"
|
43
|
+
end
|
44
|
+
|
45
|
+
def render(hash)
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class FakeGlobalSinkObject
|
51
|
+
|
52
|
+
attr_accessor :id, :name, :foo, :global_object_version
|
53
|
+
|
54
|
+
def initialize
|
55
|
+
@id = 71
|
56
|
+
@name = "fake"
|
57
|
+
@foo = "bar"
|
58
|
+
@global_object_version = 999
|
59
|
+
self.class.store(self)
|
60
|
+
end
|
61
|
+
|
62
|
+
def attributes
|
63
|
+
{"name" => @name, "foo" => @foo}
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.will_replicate_sink?
|
67
|
+
true
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.will_replicate_current_schema_version
|
71
|
+
3
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.calculate_global_object_checksum(checksum_type, begin_id = nil, end_id = nil)
|
75
|
+
123
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.will_replicate_initialization_chunk_size
|
79
|
+
2
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.max_id
|
83
|
+
101
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.handle_global_object_change(id, schema_version, global_object_version, attrs)
|
87
|
+
object = (@objects ||= {})[id]
|
88
|
+
raise ArgumentError("Invalid id: #{id}") unless object
|
89
|
+
raise ArgumentError("Invalid schema verson: #{schema_version}") unless schema_version == FakeGlobalSinkObject.will_replicate_current_schema_version
|
90
|
+
object.global_object_version = global_object_version
|
91
|
+
YAML.load(attrs).each { |name, value| object.instance_variable_set(eval(":@#{name}"), value) }
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.store(object)
|
95
|
+
(@objects ||= {})[object.id] = object
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.purge
|
99
|
+
@objects = nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
before(:each) do
|
104
|
+
@request_params = {}
|
105
|
+
@controller = GlobalObjectReplicatorSinkController.new(@request_params)
|
106
|
+
flexmock(@controller).should_receive(:query).and_yield.by_default
|
107
|
+
@checksum_type = "global_object_version_sum"
|
108
|
+
end
|
109
|
+
|
110
|
+
context "handle_global_object_change" do
|
111
|
+
|
112
|
+
before(:each) do
|
113
|
+
@object = FakeGlobalSinkObject.new
|
114
|
+
@updated_name = "Updated Name"
|
115
|
+
@request_params.merge!({
|
116
|
+
:source => "library",
|
117
|
+
:api_version => "1.5",
|
118
|
+
:request_token => "1234",
|
119
|
+
:class_name => FakeGlobalSinkObject.to_s,
|
120
|
+
:id => @object.id,
|
121
|
+
:schema_version => FakeGlobalSinkObject.will_replicate_current_schema_version,
|
122
|
+
:global_object_version => @object.global_object_version + 1,
|
123
|
+
:attrs => @object.attributes.merge("name" => @updated_name).to_yaml })
|
124
|
+
flexmock(RightScale::RightHttpClient).should_receive(:push).by_default
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should succeed for a valid global object" do
|
128
|
+
@controller.handle_global_object_change.should be_true
|
129
|
+
@object.name.should == @updated_name
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should ignore requests for unknown objects" do
|
133
|
+
flexmock(@controller.logger).should_receive(:warn).with(/GlobalObjectReplica: Ignoring/).once
|
134
|
+
@request_params[:class_name] = "Server"
|
135
|
+
@controller.handle_global_object_change.should be_true
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context "verify_next_replica_range" do
|
140
|
+
|
141
|
+
it "should send a request to the library_replicator" do
|
142
|
+
flexmock(EM).should_receive(:next_tick).and_yield.once
|
143
|
+
flexmock(RightScale::RightHttpClient).should_receive(:push).with("/library_replicator/verify_replica_range", hsh(:sink => "core")).once
|
144
|
+
@controller.send(:verify_next_replica_range, "library", FakeGlobalSinkObject, @checksum_type, 20, 1, 10).should be_true
|
145
|
+
end
|
146
|
+
|
147
|
+
it "logs exception if synchronize_replica_range request fails" do
|
148
|
+
flexmock(@controller.logger).should_receive(:error).with(/Failed to verify_replica_range.*failure/).once
|
149
|
+
flexmock(EM).should_receive(:next_tick).and_yield.once
|
150
|
+
flexmock(RightScale::RightHttpClient).should_receive(:push).and_raise(Exception, "failure").once
|
151
|
+
@controller.send(:verify_next_replica_range, "library", FakeGlobalSinkObject, @checksum_type, 20, 1, 10).should be_true
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context "verify_replicas" do
|
156
|
+
|
157
|
+
before(:each) do
|
158
|
+
@request_params.merge!({
|
159
|
+
:source => "library",
|
160
|
+
:api_version => "1.5",
|
161
|
+
:request_token => "1234",
|
162
|
+
:class_name => "FakeGlobalSinkObject",
|
163
|
+
:checksum_type => @checksum_type,
|
164
|
+
:checksum_value => 123 })
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should not start the synchronization process if the received sum matches the calculated" do
|
168
|
+
flexmock(@controller).should_receive(:verify_next_replica_range).never
|
169
|
+
@controller.verify_replicas.should be_true
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should start the synchronization process if the received sum does not match the calculated" do
|
173
|
+
flexmock(@controller).should_receive(:verify_next_replica_range).once
|
174
|
+
@request_params[:checksum_value] = 999
|
175
|
+
@controller.verify_replicas.should be_true
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should ignore requests for unknown objects" do
|
179
|
+
flexmock(@controller.logger).should_receive(:warn).with(/GlobalObjectReplica: Ignoring/).once
|
180
|
+
@request_params[:class_name] = "Server"
|
181
|
+
@controller.verify_replicas.should be_true
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context "synchronize_replica_range" do
|
186
|
+
|
187
|
+
before(:each) do
|
188
|
+
@request_params.merge!({
|
189
|
+
:source => "library",
|
190
|
+
:api_version => "1.5",
|
191
|
+
:request_token => "1234",
|
192
|
+
:class_name => "FakeGlobalSinkObject",
|
193
|
+
:checksum_type => @checksum_type,
|
194
|
+
:max_id_at_start => 14114,
|
195
|
+
:begin_id => 1,
|
196
|
+
:end_id => 100,
|
197
|
+
:checksum_matched => true,
|
198
|
+
:has_more => false,
|
199
|
+
:records_to_synchronize => [] })
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should update any received records" do
|
203
|
+
flexmock(FakeGlobalSinkObject).should_receive(:handle_global_object_change).with(1, 2, 3, {}).once
|
204
|
+
@request_params[:records_to_synchronize] = [{"id" => 1, "schema_version" => 2, "global_object_version" => 3, "attrs" => {}}]
|
205
|
+
@controller.synchronize_replica_range.should be_true
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should continue synchronizing if has_more is true" do
|
209
|
+
flexmock(@controller).should_receive(:verify_next_replica_range).once
|
210
|
+
@request_params[:has_more] = true
|
211
|
+
@controller.synchronize_replica_range.should be_true
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should stop synchronizing if has_more is false" do
|
215
|
+
flexmock(@replicator).should_receive(:verify_next_replica_range).never
|
216
|
+
@controller.synchronize_replica_range.should be_true
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should ignore requests for unknown objects" do
|
220
|
+
flexmock(@controller.logger).should_receive(:warn).with(/GlobalObjectReplica: Ignoring/).once
|
221
|
+
@request_params[:class_name] = "Server"
|
222
|
+
@controller.synchronize_replica_range.should be_true
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
context "calculate_next_range_for_binary_sync" do
|
227
|
+
|
228
|
+
before(:each) do
|
229
|
+
@min_size = 250
|
230
|
+
end
|
231
|
+
|
232
|
+
context "context when max_id > min_size" do
|
233
|
+
|
234
|
+
before(:each) do
|
235
|
+
@max_id = 31021
|
236
|
+
@source = "library"
|
237
|
+
end
|
238
|
+
|
239
|
+
it "should return next min_size range if top level is in sync" do
|
240
|
+
@controller.send(:calculate_next_range_for_binary_sync, @source, @max_id, @min_size, 0, @max_id, true).
|
241
|
+
should == [@max_id + 1, @max_id + @min_size]
|
242
|
+
end
|
243
|
+
|
244
|
+
it "should return next min_size range if start is past max_id" do
|
245
|
+
start_id = @max_id + 50
|
246
|
+
end_id = @max_id + 100
|
247
|
+
@controller.send(:calculate_next_range_for_binary_sync, @source, @max_id, @min_size, start_id, end_id, true).
|
248
|
+
should == [end_id + 1, end_id + @min_size]
|
249
|
+
end
|
250
|
+
|
251
|
+
it "should return the 1st level left branch if top is not in sync" do
|
252
|
+
size, center = @controller.send(:calc_size_and_center, 0, @max_id)
|
253
|
+
@controller.send(:calculate_next_range_for_binary_sync, @source, @max_id, @min_size, 0, @max_id, false).
|
254
|
+
should == [0, center]
|
255
|
+
end
|
256
|
+
|
257
|
+
it "should return the 1st level right branch if 1st level left is in sync" do
|
258
|
+
size, center = @controller.send(:calc_size_and_center, 0, @max_id)
|
259
|
+
@controller.send(:calculate_next_range_for_binary_sync, @source, @max_id, @min_size, 0, center, true).
|
260
|
+
should == [center + 1, @max_id]
|
261
|
+
end
|
262
|
+
|
263
|
+
it "should return the 2nd level left-left branch if 1st level left is not in sync" do
|
264
|
+
size, center = @controller.send(:calc_size_and_center, 0, @max_id)
|
265
|
+
size, left_center = @controller.send(:calc_size_and_center, 0, center)
|
266
|
+
@controller.send(:calculate_next_range_for_binary_sync, @source, @max_id, @min_size, 0, center, false).
|
267
|
+
should == [0, left_center]
|
268
|
+
end
|
269
|
+
|
270
|
+
it "should return the 2nd level left-right branch if 2nd left-left is in sync" do
|
271
|
+
size, center = @controller.send(:calc_size_and_center, 0, @max_id)
|
272
|
+
size, left_center = @controller.send(:calc_size_and_center, 0, center)
|
273
|
+
@controller.send(:calculate_next_range_for_binary_sync, @source, @max_id, @min_size, 0, left_center, true).
|
274
|
+
should == [left_center + 1, center]
|
275
|
+
end
|
276
|
+
|
277
|
+
it "should return the 1st level right branch if 2nd left-right is in sync" do
|
278
|
+
size, center = @controller.send(:calc_size_and_center, 0, @max_id)
|
279
|
+
size, left_center = @controller.send(:calc_size_and_center, 0, center)
|
280
|
+
@controller.send(:calculate_next_range_for_binary_sync, @source, @max_id, @min_size, left_center + 1, center, true).
|
281
|
+
should == [center + 1, @max_id]
|
282
|
+
end
|
283
|
+
|
284
|
+
it "should return the 1st level right branch if 3rd left-right-right is in sync" do
|
285
|
+
size, center = @controller.send(:calc_size_and_center, 0, @max_id)
|
286
|
+
size, left_center = @controller.send(:calc_size_and_center, 0, center)
|
287
|
+
size, left_right_center = @controller.send(:calc_size_and_center, left_center + 1, center)
|
288
|
+
@controller.send(:calculate_next_range_for_binary_sync, @source, @max_id, @min_size, left_right_center + 1, center, true).
|
289
|
+
should == [center + 1, @max_id]
|
290
|
+
end
|
291
|
+
|
292
|
+
it "should return nils if 1st level right branch is in sync" do
|
293
|
+
size, center = @controller.send(:calc_size_and_center, 0, @max_id)
|
294
|
+
@controller.send(:calculate_next_range_for_binary_sync, @source, @max_id, @min_size, center + 1, @max_id, true).
|
295
|
+
should == [@max_id + 1, @max_id + @min_size]
|
296
|
+
end
|
297
|
+
|
298
|
+
it "should return nils if 2nd level right-right branch is in sync" do
|
299
|
+
size, center = @controller.send(:calc_size_and_center, 0, @max_id)
|
300
|
+
size, right_center = @controller.send(:calc_size_and_center, center + 1, @max_id)
|
301
|
+
@controller.send(:calculate_next_range_for_binary_sync, @source, @max_id, @min_size, right_center + 1, @max_id, true).should == [@max_id + 1, @max_id + @min_size]
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2011-2013 RightScale, Inc, All Rights Reserved Worldwide.
|
3
|
+
#
|
4
|
+
# THIS PROGRAM IS CONFIDENTIAL AND PROPRIETARY TO RIGHTSCALE
|
5
|
+
# AND CONSTITUTES A VALUABLE TRADE SECRET. Any unauthorized use,
|
6
|
+
# reproduction, modification, or disclosure of this program is
|
7
|
+
# strictly prohibited. Any use of this program by an authorized
|
8
|
+
# licensee is strictly subject to the terms and conditions,
|
9
|
+
# including confidentiality obligations, set forth in the applicable
|
10
|
+
# License Agreement between RightScale.com, Inc. and the licensee.
|
11
|
+
#++
|
12
|
+
|
13
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
14
|
+
|
15
|
+
describe RightScale::GlobalObjectReplicatorSource do
|
16
|
+
|
17
|
+
include FlexMock::ArgumentTypes
|
18
|
+
|
19
|
+
# A pseudo HTTP controller applying GlobalObjectReplicatorSource
|
20
|
+
class GlobalObjectReplicatorSourceController
|
21
|
+
include RightScale::GlobalObjectReplicatorSource
|
22
|
+
|
23
|
+
attr_reader :logger
|
24
|
+
attr_reader :params
|
25
|
+
|
26
|
+
def initialize(params)
|
27
|
+
@params = params
|
28
|
+
@logger = RightScale::Log
|
29
|
+
end
|
30
|
+
|
31
|
+
def global_object_replicator_source
|
32
|
+
"library"
|
33
|
+
end
|
34
|
+
|
35
|
+
def render(hash)
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class FakeGlobalSourceObject
|
41
|
+
def self.calculate_global_object_checksum(checksum_type, schema_version, begin_id, end_id)
|
42
|
+
123
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.max_id
|
46
|
+
101
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "verify_replica_range" do
|
51
|
+
|
52
|
+
before(:each) do
|
53
|
+
@request_params = {
|
54
|
+
:sink => "core",
|
55
|
+
:class_name => "FakeGlobalSourceObject",
|
56
|
+
:schema_version => 1,
|
57
|
+
:max_id_at_start => 100,
|
58
|
+
:begin_id => 1,
|
59
|
+
:end_id => 2,
|
60
|
+
:send_records_on_checksum_mismatch => true,
|
61
|
+
:checksum_value => FakeGlobalSourceObject.calculate_global_object_checksum("x", 1, 1, 2),
|
62
|
+
:shard_id => 9}
|
63
|
+
@controller = GlobalObjectReplicatorSourceController.new(@request_params)
|
64
|
+
flexmock(@controller).should_receive(:query).and_yield.by_default
|
65
|
+
flexmock(RightScale::RightHttpClient).should_receive(:push).by_default
|
66
|
+
end
|
67
|
+
|
68
|
+
it "gets records to synchronize if the received sum does not match the calculated sum" do
|
69
|
+
flexmock(FakeGlobalSourceObject).should_receive(:get_initialization_hashes).and_return([{:a => :b}]).once
|
70
|
+
@request_params[:checksum_value] = 999
|
71
|
+
@controller.verify_replica_range.should be_true
|
72
|
+
end
|
73
|
+
|
74
|
+
it "sends synchronize_replica_range request to sink with records to synchronize" do
|
75
|
+
flexmock(EM).should_receive(:next_tick).and_yield.once
|
76
|
+
flexmock(FakeGlobalSourceObject).should_receive(:get_initialization_hashes).and_return([{:a => :b}]).once
|
77
|
+
flexmock(RightScale::RightHttpClient).should_receive(:push).with("/replicator/synchronize_replica_range",
|
78
|
+
on { |arg| arg[:records_to_synchronize] == [{:a => :b}] }, :scope => {:shard => 9}).once
|
79
|
+
@request_params[:checksum_value] = 999
|
80
|
+
@controller.verify_replica_range.should be_true
|
81
|
+
end
|
82
|
+
|
83
|
+
it "does not get records to synchronize if send_records_on_checksum_mismatch is false" do
|
84
|
+
flexmock(EM).should_receive(:next_tick).and_yield.once
|
85
|
+
flexmock(FakeGlobalSourceObject).should_receive(:get_initialization_hashes).never
|
86
|
+
flexmock(RightScale::RightHttpClient).should_receive(:push).with("/replicator/synchronize_replica_range",
|
87
|
+
on { |arg| arg[:records_to_synchronize] == [] }, :scope => {:shard => 9}).once
|
88
|
+
@request_params[:checksum_value] = 999
|
89
|
+
@request_params[:send_records_on_checksum_mismatch] = false
|
90
|
+
@controller.verify_replica_range.should be_true
|
91
|
+
end
|
92
|
+
|
93
|
+
it "does not get records to synchronize if the received checksum matches the calculated checksum" do
|
94
|
+
flexmock(EM).should_receive(:next_tick).and_yield.once
|
95
|
+
flexmock(FakeGlobalSourceObject).should_receive(:get_initialization_hashes).never
|
96
|
+
flexmock(RightScale::RightHttpClient).should_receive(:push).with("/replicator/synchronize_replica_range",
|
97
|
+
on { |arg| arg[:records_to_synchronize] == [] }, :scope => {:shard => 9}).once
|
98
|
+
@controller.verify_replica_range.should be_true
|
99
|
+
end
|
100
|
+
|
101
|
+
it "logs exception if synchronize_replica_range request fails" do
|
102
|
+
flexmock(@controller.logger).should_receive(:error).with(/Failed to synchronize_replica_range.*failure/).once
|
103
|
+
flexmock(EM).should_receive(:next_tick).and_yield.once
|
104
|
+
flexmock(RightScale::RightHttpClient).should_receive(:push).and_raise(Exception, "failure").once
|
105
|
+
@controller.verify_replica_range.should be_true
|
106
|
+
end
|
107
|
+
|
108
|
+
it "raises exception if query is unsuccessful" do
|
109
|
+
flexmock(@controller).should_receive(:query).and_return(false).once
|
110
|
+
lambda { @controller.verify_replica_range }.should raise_error(RightScale::Exceptions::QueryFailure)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|