rubyrep 1.2.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +18 -0
  5. data/Gemfile.lock +84 -0
  6. data/History.txt +6 -0
  7. data/README.txt +1 -1
  8. data/Rakefile +6 -27
  9. data/bin/rubyrep +1 -1
  10. data/config/mysql_config.rb +2 -2
  11. data/config/postgres_config.rb +5 -3
  12. data/lib/rubyrep/command_runner.rb +1 -1
  13. data/lib/rubyrep/connection_extenders/connection_extenders.rb +30 -44
  14. data/lib/rubyrep/connection_extenders/mysql_extender.rb +23 -1
  15. data/lib/rubyrep/connection_extenders/postgresql_extender.rb +31 -168
  16. data/lib/rubyrep/generate_runner.rb +1 -1
  17. data/lib/rubyrep/logged_change.rb +1 -1
  18. data/lib/rubyrep/proxy_connection.rb +22 -12
  19. data/lib/rubyrep/replication_difference.rb +1 -1
  20. data/lib/rubyrep/replication_extenders/mysql_replication.rb +1 -1
  21. data/lib/rubyrep/replication_helper.rb +1 -1
  22. data/lib/rubyrep/replication_runner.rb +10 -0
  23. data/lib/rubyrep/scan_report_printers/scan_detail_reporter.rb +1 -1
  24. data/lib/rubyrep/table_spec_resolver.rb +1 -1
  25. data/lib/rubyrep/type_casting_cursor.rb +8 -4
  26. data/lib/rubyrep/version.rb +1 -7
  27. data/lib/rubyrep.rb +4 -3
  28. data/rubyrep +4 -0
  29. data/rubyrep.bat +5 -0
  30. data/rubyrep.gemspec +29 -0
  31. data/sims/performance/big_rep_spec.rb +34 -17
  32. data/sims/performance/performance.rake +11 -31
  33. data/tasks/database.rake +14 -14
  34. data/tasks/java.rake +18 -5
  35. data/tasks/rspec.rake +14 -34
  36. data/tasks/stats.rake +1 -16
  37. metadata +99 -162
  38. data/.gemtest +0 -0
  39. data/config/requirements.rb +0 -32
  40. data/lib/rubyrep/connection_extenders/jdbc_extender.rb +0 -65
  41. data/spec/base_runner_spec.rb +0 -218
  42. data/spec/buffered_committer_spec.rb +0 -274
  43. data/spec/command_runner_spec.rb +0 -145
  44. data/spec/committers_spec.rb +0 -178
  45. data/spec/configuration_spec.rb +0 -203
  46. data/spec/connection_extender_interface_spec.rb +0 -141
  47. data/spec/connection_extenders_registration_spec.rb +0 -164
  48. data/spec/database_proxy_spec.rb +0 -48
  49. data/spec/database_rake_spec.rb +0 -40
  50. data/spec/db_specific_connection_extenders_spec.rb +0 -34
  51. data/spec/db_specific_replication_extenders_spec.rb +0 -38
  52. data/spec/direct_table_scan_spec.rb +0 -61
  53. data/spec/dolphins.jpg +0 -0
  54. data/spec/generate_runner_spec.rb +0 -84
  55. data/spec/initializer_spec.rb +0 -46
  56. data/spec/log_helper_spec.rb +0 -39
  57. data/spec/logged_change_loader_spec.rb +0 -68
  58. data/spec/logged_change_spec.rb +0 -470
  59. data/spec/noisy_connection_spec.rb +0 -78
  60. data/spec/postgresql_replication_spec.rb +0 -48
  61. data/spec/postgresql_schema_support_spec.rb +0 -212
  62. data/spec/postgresql_support_spec.rb +0 -63
  63. data/spec/progress_bar_spec.rb +0 -77
  64. data/spec/proxied_table_scan_spec.rb +0 -151
  65. data/spec/proxy_block_cursor_spec.rb +0 -197
  66. data/spec/proxy_connection_spec.rb +0 -423
  67. data/spec/proxy_cursor_spec.rb +0 -56
  68. data/spec/proxy_row_cursor_spec.rb +0 -66
  69. data/spec/proxy_runner_spec.rb +0 -70
  70. data/spec/replication_difference_spec.rb +0 -161
  71. data/spec/replication_extender_interface_spec.rb +0 -367
  72. data/spec/replication_extenders_spec.rb +0 -32
  73. data/spec/replication_helper_spec.rb +0 -178
  74. data/spec/replication_initializer_spec.rb +0 -509
  75. data/spec/replication_run_spec.rb +0 -443
  76. data/spec/replication_runner_spec.rb +0 -254
  77. data/spec/replicators_spec.rb +0 -36
  78. data/spec/rubyrep_spec.rb +0 -8
  79. data/spec/scan_detail_reporter_spec.rb +0 -119
  80. data/spec/scan_progress_printers_spec.rb +0 -68
  81. data/spec/scan_report_printers_spec.rb +0 -67
  82. data/spec/scan_runner_spec.rb +0 -50
  83. data/spec/scan_summary_reporter_spec.rb +0 -61
  84. data/spec/session_spec.rb +0 -253
  85. data/spec/spec.opts +0 -1
  86. data/spec/spec_helper.rb +0 -305
  87. data/spec/strange_name_support_spec.rb +0 -135
  88. data/spec/sync_helper_spec.rb +0 -169
  89. data/spec/sync_runner_spec.rb +0 -78
  90. data/spec/syncers_spec.rb +0 -171
  91. data/spec/table_scan_helper_spec.rb +0 -36
  92. data/spec/table_scan_spec.rb +0 -49
  93. data/spec/table_sorter_spec.rb +0 -30
  94. data/spec/table_spec_resolver_spec.rb +0 -111
  95. data/spec/table_sync_spec.rb +0 -140
  96. data/spec/task_sweeper_spec.rb +0 -47
  97. data/spec/trigger_mode_switcher_spec.rb +0 -83
  98. data/spec/two_way_replicator_spec.rb +0 -721
  99. data/spec/two_way_syncer_spec.rb +0 -256
  100. data/spec/type_casting_cursor_spec.rb +0 -50
  101. data/spec/uninstall_runner_spec.rb +0 -93
  102. data/tasks/rubyrep.tailor +0 -18
  103. data/tasks/website.rake +0 -19
@@ -1,721 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper.rb'
2
-
3
- include RR
4
-
5
- describe Replicators::TwoWayReplicator do
6
- before(:each) do
7
- Initializer.configuration = deep_copy(standard_config)
8
- Initializer.configuration.options = {:replicator => :two_way}
9
- end
10
-
11
- it "should register itself" do
12
- Replicators::replicators[:two_way].should == Replicators::TwoWayReplicator
13
- end
14
-
15
- it "initialize should store the replication helper" do
16
- rep_run = ReplicationRun.new(Session.new, TaskSweeper.new(1))
17
- helper = ReplicationHelper.new(rep_run)
18
- replicator = Replicators::TwoWayReplicator.new(helper)
19
- replicator.rep_helper.should == helper
20
- end
21
-
22
- it "verify_option should raise descriptive errors" do
23
- rep_run = ReplicationRun.new(Session.new, TaskSweeper.new(1))
24
- helper = ReplicationHelper.new(rep_run)
25
- replicator = Replicators::TwoWayReplicator.new(helper)
26
- lambda {replicator.verify_option(nil, [:valid_value], :my_key, :my_value)}.
27
- should raise_error(ArgumentError, ':my_value not a valid :my_key option')
28
- lambda {replicator.verify_option(/my_spec/, [:valid_value], :my_key, :my_value)}.
29
- should raise_error(ArgumentError, '/my_spec/: :my_value not a valid :my_key option')
30
- end
31
-
32
- it "initialize should throw an error if options are invalid" do
33
- rep_run = ReplicationRun.new(Session.new, TaskSweeper.new(1))
34
- helper = ReplicationHelper.new(rep_run)
35
- base_options = {
36
- :replicator => :two_way,
37
- :left_change_handling => :ignore,
38
- :right_change_handling => :ignore,
39
- :replication_conflict_handling => :ignore,
40
- :logged_replication_events => [:ignored_conflicts]
41
- }
42
-
43
- # Verify that correct options don't raise errors.
44
- helper.stub!(:options).and_return(base_options)
45
- lambda {Replicators::TwoWayReplicator.new(helper)}.should_not raise_error
46
-
47
- # Also lambda options should not raise errors.
48
- l = lambda {}
49
- helper.stub!(:options).and_return(base_options.merge(
50
- {
51
- :left_change_handling => l,
52
- :right_change_handling => l,
53
- :repliction_conflict_handling => l
54
- })
55
- )
56
- lambda {Replicators::TwoWayReplicator.new(helper)}.should_not raise_error
57
-
58
- # Invalid options should raise errors
59
- invalid_options = [
60
- {:left_change_handling => :invalid_left_option},
61
- {:right_change_handling => :invalid_right_option},
62
- {:replication_conflict_handling => :invalid_conflict_option},
63
- {:logged_replication_events => :invalid_logging_option},
64
- ]
65
- invalid_options.each do |options|
66
- helper.session.configuration.stub!(:options).and_return(base_options.merge(options))
67
- lambda {Replicators::TwoWayReplicator.new(helper)}.should raise_error(ArgumentError)
68
- end
69
- end
70
-
71
- it "clear_conflicts should update the correct database with the correct action" do
72
- Initializer.configuration.include_tables 'left_table, right_table'
73
- session = Session.new
74
- session.left.begin_db_transaction
75
- session.right.begin_db_transaction
76
- begin
77
- rep_run = ReplicationRun.new(session, TaskSweeper.new(1))
78
- helper = ReplicationHelper.new(rep_run)
79
- replicator = Replicators::TwoWayReplicator.new(helper)
80
-
81
- loaders = LoggedChangeLoaders.new(session)
82
-
83
- left_change = LoggedChange.new loaders[:left]
84
- left_change.table = 'left_table'
85
- left_change.key = {'id' => '1'}
86
- right_change = LoggedChange.new loaders[:right]
87
- right_change.table = 'right_table'
88
- right_change.key = {'id' => '1'}
89
-
90
- diff = ReplicationDifference.new(loaders)
91
- diff.changes[:left] = left_change
92
- diff.changes[:right] = right_change
93
-
94
-
95
- # verify that an insert is dealt correctly with
96
- left_change.type = :insert
97
- right_change.type = :insert
98
-
99
- helper.should_receive(:load_record).ordered.
100
- with(:left, 'left_table', {'id' => '1'}).
101
- and_return(:dummy_values)
102
- helper.should_receive(:update_record).ordered.
103
- with(:right, 'right_table', :dummy_values, {'id' => '1'})
104
- replicator.clear_conflict :left, diff, 1
105
-
106
- # verify that an update is dealt correctly with
107
- left_change.type = :delete
108
- right_change.type = :update
109
- right_change.new_key = {'id' => '2'}
110
-
111
-
112
- helper.should_receive(:load_record).ordered.
113
- with(:right, 'right_table', {'id' => '2'}).
114
- and_return(:dummy_values)
115
- helper.should_receive(:insert_record).ordered.
116
- with(:left, 'left_table', :dummy_values)
117
- replicator.clear_conflict :right, diff, 1
118
-
119
-
120
- # verify that a delete is dealt correctly with
121
- left_change.type = :delete
122
- right_change.type = :update
123
-
124
- helper.should_receive(:delete_record).ordered.
125
- with(:right, 'right_table', {'id' => '2'})
126
- replicator.clear_conflict :left, diff, 1
127
- ensure
128
- session.left.rollback_db_transaction
129
- session.right.rollback_db_transaction
130
- end
131
- end
132
-
133
- it "log_replication_outcome should log conflicts correctly" do
134
- session = Session.new
135
- rep_run = ReplicationRun.new(session, TaskSweeper.new(1))
136
-
137
- loaders = LoggedChangeLoaders.new(session)
138
-
139
- diff = ReplicationDifference.new loaders
140
- diff.type = :conflict
141
- diff.changes[:left] = LoggedChange.new loaders[:left]
142
- diff.changes[:left].table = 'scanner_records'
143
-
144
- # should only log events if so configured
145
- helper = ReplicationHelper.new(rep_run)
146
- replicator = Replicators::TwoWayReplicator.new(helper)
147
- helper.should_not_receive(:log_replication_outcome)
148
- helper.stub!(:options_for_table).and_return({:logged_replication_events => []})
149
- replicator.log_replication_outcome :ignore, diff
150
- helper.stub!(:options_for_table).and_return({:logged_replication_events => [:ignored_conflicts]})
151
- replicator.log_replication_outcome :left, diff
152
-
153
- # should log ignored conflicts correctly
154
- helper = ReplicationHelper.new(rep_run)
155
- replicator = Replicators::TwoWayReplicator.new(helper)
156
- helper.should_receive(:log_replication_outcome).with(diff, 'ignored')
157
- helper.stub!(:options_for_table).and_return({:logged_replication_events => [:ignored_conflicts]})
158
- replicator.log_replication_outcome :ignore, diff
159
-
160
- # should log conflicts correctly
161
- helper = ReplicationHelper.new(rep_run)
162
- replicator = Replicators::TwoWayReplicator.new(helper)
163
- helper.should_receive(:log_replication_outcome).with(diff, 'left_won')
164
- helper.stub!(:options_for_table).and_return({:logged_replication_events => [:all_conflicts]})
165
- replicator.log_replication_outcome :left, diff
166
- end
167
-
168
- it "log_replication_outcome should log changes correctly" do
169
- session = Session.new
170
- rep_run = ReplicationRun.new(session, TaskSweeper.new(1))
171
-
172
- loaders = LoggedChangeLoaders.new(session)
173
-
174
- diff = ReplicationDifference.new loaders
175
- diff.type = :left
176
- diff.changes[:left] = LoggedChange.new loaders[:left]
177
- diff.changes[:left].table = 'scanner_records'
178
-
179
- # should only log events if so configured
180
- helper = ReplicationHelper.new(rep_run)
181
- replicator = Replicators::TwoWayReplicator.new(helper)
182
- helper.should_not_receive(:log_replication_outcome)
183
- helper.stub!(:options_for_table).and_return({:logged_replication_events => []})
184
- replicator.log_replication_outcome :ignore, diff
185
- helper.stub!(:options_for_table).and_return({:logged_replication_events => [:ignored_changes]})
186
- replicator.log_replication_outcome :left, diff
187
-
188
- # should log changes correctly
189
- helper = ReplicationHelper.new(rep_run)
190
- replicator = Replicators::TwoWayReplicator.new(helper)
191
- helper.should_receive(:log_replication_outcome).with(diff, 'replicated')
192
- helper.stub!(:options_for_table).and_return({:logged_replication_events => [:all_changes]})
193
- replicator.log_replication_outcome :right, diff
194
-
195
- # should log changes correctly
196
- helper = ReplicationHelper.new(rep_run)
197
- replicator = Replicators::TwoWayReplicator.new(helper)
198
- helper.should_receive(:log_replication_outcome).with(diff, 'ignored')
199
- helper.stub!(:options_for_table).and_return({:logged_replication_events => [:ignored_changes]})
200
- replicator.log_replication_outcome :ignore, diff
201
- end
202
-
203
- it "replicate_difference should not do anything if ignore option is given" do
204
- session = Session.new
205
- rep_run = ReplicationRun.new(session, TaskSweeper.new(1))
206
- helper = ReplicationHelper.new(rep_run)
207
- replicator = Replicators::TwoWayReplicator.new(helper)
208
- helper.stub!(:options_for_table).and_return(
209
- {
210
- :left_change_handling => :ignore,
211
- :right_change_handling => :ignore,
212
- :replication_conflict_handling => :ignore,
213
- :logged_replication_events => [:ignored_changes, :ignored_conflicts]
214
- }
215
- )
216
-
217
- loaders = LoggedChangeLoaders.new(session)
218
-
219
- diff = ReplicationDifference.new(loaders)
220
- diff.changes[:left] = LoggedChange.new loaders[:left]
221
- diff.changes[:left].table = 'scanner_records'
222
-
223
- # but logging should still happen
224
- replicator.should_receive(:log_replication_outcome).
225
- with(:ignore, diff).
226
- exactly(3).times
227
-
228
- helper.should_not_receive :insert_record
229
- helper.should_not_receive :update_record
230
- helper.should_not_receive :delete_record
231
-
232
- diff.type = :conflict
233
- replicator.replicate_difference diff
234
- diff.type = :left
235
- replicator.replicate_difference diff
236
- diff.type = :right
237
- replicator.replicate_difference diff
238
- end
239
-
240
- it "replicate_difference should call the provided Proc objects" do
241
- session = Session.new
242
- rep_run = ReplicationRun.new(session, TaskSweeper.new(1))
243
- helper = ReplicationHelper.new(rep_run)
244
-
245
- lambda_parameters = []
246
- l = lambda do |rep_helper, diff|
247
- lambda_parameters << [rep_helper, diff]
248
- end
249
- replicator = Replicators::TwoWayReplicator.new(helper)
250
- helper.stub!(:options_for_table).and_return(
251
- {
252
- :left_change_handling => l,
253
- :right_change_handling => l,
254
- :replication_conflict_handling => l
255
- }
256
- )
257
-
258
- loaders = LoggedChangeLoaders.new(session)
259
-
260
- change = LoggedChange.new loaders[:left]
261
- change.table = 'scanner_records'
262
-
263
- d1 = ReplicationDifference.new(loaders)
264
- d1.type = :conflict
265
- d1.changes[:left] = change
266
- replicator.replicate_difference d1
267
-
268
- d2 = ReplicationDifference.new(loaders)
269
- d2.type = :left
270
- d2.changes[:left] = change
271
- replicator.replicate_difference d2
272
-
273
- d3 = ReplicationDifference.new(loaders)
274
- d3.type = :right
275
- d3.changes[:left] = change
276
- replicator.replicate_difference d3
277
-
278
- lambda_parameters.should == [
279
- [helper, d1],
280
- [helper, d2],
281
- [helper, d3],
282
- ]
283
- end
284
-
285
- it "replicate_difference should clear conflicts as per provided options" do
286
- session = Session.new
287
- rep_run = ReplicationRun.new(session, TaskSweeper.new(1))
288
- helper = ReplicationHelper.new(rep_run)
289
-
290
- left_change = LoggedChange.new LoggedChangeLoader.new(session, :left)
291
- left_change.table = 'scanner_records'
292
- right_change = LoggedChange.new LoggedChangeLoader.new(session, :right)
293
- right_change.table = 'scanner_records'
294
- diff = ReplicationDifference.new(session)
295
- diff.type = :conflict
296
- diff.changes[:left] = left_change
297
- diff.changes[:right] = right_change
298
-
299
- replicator = Replicators::TwoWayReplicator.new(helper)
300
- helper.stub!(:options_for_table).and_return({:replication_conflict_handling => :left_wins})
301
- replicator.should_receive(:clear_conflict).with(:left, diff, 1)
302
- replicator.replicate_difference diff, 1
303
-
304
- replicator = Replicators::TwoWayReplicator.new(helper)
305
- helper.stub!(:options_for_table).and_return({:replication_conflict_handling => :right_wins})
306
- replicator.should_receive(:clear_conflict).with(:right, diff, 1)
307
- replicator.replicate_difference diff, 1
308
-
309
- replicator = Replicators::TwoWayReplicator.new(helper)
310
- helper.stub!(:options_for_table).and_return({:replication_conflict_handling => :later_wins})
311
- replicator.should_receive(:clear_conflict).with(:left, diff, 1).twice
312
- left_change.last_changed_at = 5.seconds.from_now
313
- right_change.last_changed_at = Time.now
314
- replicator.replicate_difference diff, 1
315
- left_change.last_changed_at = right_change.last_changed_at = Time.now
316
- replicator.replicate_difference diff, 1
317
- replicator.should_receive(:clear_conflict).with(:right, diff, 1)
318
- right_change.last_changed_at = 5.seconds.from_now
319
- replicator.replicate_difference diff, 1
320
-
321
- replicator = Replicators::TwoWayReplicator.new(helper)
322
- helper.stub!(:options_for_table).and_return({:replication_conflict_handling => :earlier_wins})
323
- replicator.should_receive(:clear_conflict).with(:left, diff, 1).twice
324
- left_change.last_changed_at = 5.seconds.ago
325
- right_change.last_changed_at = Time.now
326
- replicator.replicate_difference diff, 1
327
- left_change.last_changed_at = right_change.last_changed_at = Time.now
328
- replicator.replicate_difference diff, 1
329
- replicator.should_receive(:clear_conflict).with(:right, diff, 1)
330
- right_change.last_changed_at = 5.seconds.ago
331
- replicator.replicate_difference diff, 1
332
- end
333
-
334
- it "replicate_difference should replicate :left / :right changes correctly" do
335
- Initializer.configuration.include_tables 'left_table, right_table'
336
- session = Session.new
337
- session.left.begin_db_transaction
338
- session.right.begin_db_transaction
339
- begin
340
- rep_run = ReplicationRun.new(session, TaskSweeper.new(1))
341
-
342
- left_change = LoggedChange.new LoggedChangeLoader.new(session, :left)
343
- left_change.table = 'left_table'
344
- left_change.key = {'id' => '1'}
345
- right_change = LoggedChange.new LoggedChangeLoader.new(session, :right)
346
- right_change.table = 'right_table'
347
- right_change.key = {'id' => '1'}
348
-
349
- diff = ReplicationDifference.new(session)
350
-
351
- # verify insert behaviour
352
- left_change.type = :insert
353
- diff.type = :left
354
- diff.changes[:left] = left_change
355
- diff.changes[:right] = nil
356
-
357
- helper = ReplicationHelper.new(rep_run)
358
- replicator = Replicators::TwoWayReplicator.new(helper)
359
- replicator.should_receive(:log_replication_outcome).with(:left, diff)
360
- helper.should_receive(:load_record).with(:left, 'left_table', {'id' => '1'}).
361
- and_return(:dummy_values)
362
- helper.should_receive(:insert_record).with(:right, 'right_table', :dummy_values)
363
- replicator.replicate_difference diff
364
-
365
- # verify update behaviour
366
- right_change.type = :update
367
- right_change.new_key = {'id' => '2'}
368
- diff.type = :right
369
- diff.changes[:right] = right_change
370
-
371
- helper = ReplicationHelper.new(rep_run)
372
- replicator = Replicators::TwoWayReplicator.new(helper)
373
- replicator.should_receive(:log_replication_outcome).with(:right, diff)
374
- helper.should_receive(:load_record).with(:right, 'right_table', {'id' => '2'}).
375
- and_return(:dummy_values)
376
- helper.should_receive(:update_record).with(:left, 'left_table', :dummy_values, {'id' => '1'})
377
- replicator.replicate_difference diff
378
-
379
- # verify delete behaviour
380
- right_change.type = :delete
381
-
382
- helper = ReplicationHelper.new(rep_run)
383
- replicator = Replicators::TwoWayReplicator.new(helper)
384
- replicator.should_receive(:log_replication_outcome).with(:right, diff)
385
- helper.should_receive(:delete_record).with(:left, 'left_table', {'id' => '1'})
386
- replicator.replicate_difference diff
387
- ensure
388
- session.left.rollback_db_transaction
389
- session.right.rollback_db_transaction
390
- end
391
- end
392
-
393
- it "replicate_difference should handle inserts failing due duplicate records getting created after the original diff was loaded" do
394
- begin
395
- config = deep_copy(standard_config)
396
- config.options[:committer] = :never_commit
397
- config.options[:replication_conflict_handling] = :right_wins
398
-
399
- session = Session.new(config)
400
-
401
- session.left.insert_record 'extender_no_record', {
402
- 'id' => '1',
403
- 'name' => 'bla'
404
- }
405
- session.left.insert_record 'rr_pending_changes', {
406
- 'change_table' => 'extender_no_record',
407
- 'change_key' => 'id|1',
408
- 'change_type' => 'I',
409
- 'change_time' => Time.now
410
- }
411
-
412
-
413
- rep_run = ReplicationRun.new session, TaskSweeper.new(1)
414
- helper = ReplicationHelper.new(rep_run)
415
- replicator = Replicators::TwoWayReplicator.new(helper)
416
-
417
- diff = ReplicationDifference.new LoggedChangeLoaders.new(session)
418
- diff.load
419
-
420
- session.right.insert_record 'extender_no_record', {
421
- 'id' => '1',
422
- 'name' => 'blub'
423
- }
424
- session.right.insert_record 'rr_pending_changes', {
425
- 'change_table' => 'extender_no_record',
426
- 'change_key' => 'id|1',
427
- 'change_type' => 'I',
428
- 'change_time' => Time.now
429
- }
430
- replicator.replicate_difference diff, 2
431
-
432
- session.left.select_record(:table => "extender_no_record").should == {
433
- 'id' => 1,
434
- 'name' => 'blub'
435
- }
436
- ensure
437
- Committers::NeverCommitter.rollback_current_session
438
- if session
439
- session.left.execute "delete from extender_no_record"
440
- session.right.execute "delete from extender_no_record"
441
- session.left.execute "delete from rr_pending_changes"
442
- end
443
- end
444
- end
445
-
446
- it "replicate_difference should handle inserts failing due the new record being deleted after the original diff was loaded" do
447
- begin
448
- config = deep_copy(standard_config)
449
- config.options[:committer] = :never_commit
450
-
451
- session = Session.new(config)
452
-
453
- session.left.insert_record 'rr_pending_changes', {
454
- 'change_table' => 'extender_no_record',
455
- 'change_key' => 'id|1',
456
- 'change_type' => 'I',
457
- 'change_time' => Time.now
458
- }
459
-
460
- rep_run = ReplicationRun.new session, TaskSweeper.new(1)
461
- helper = ReplicationHelper.new(rep_run)
462
- replicator = Replicators::TwoWayReplicator.new(helper)
463
-
464
- diff = ReplicationDifference.new LoggedChangeLoaders.new(session)
465
- diff.load
466
-
467
- session.left.insert_record 'rr_pending_changes', {
468
- 'change_table' => 'extender_no_record',
469
- 'change_key' => 'id|1',
470
- 'change_type' => 'D',
471
- 'change_time' => Time.now
472
- }
473
- replicator.replicate_difference diff, 2
474
-
475
- # no rspec expectation: success is when we get till here without exception
476
- ensure
477
- Committers::NeverCommitter.rollback_current_session
478
- session.left.execute "delete from rr_pending_changes" if session
479
- end
480
- end
481
-
482
- it "replicate_difference should raise Exception if all replication attempts have been exceeded" do
483
- rep_run = ReplicationRun.new Session.new, TaskSweeper.new(1)
484
- helper = ReplicationHelper.new(rep_run)
485
- replicator = Replicators::TwoWayReplicator.new(helper)
486
- lambda {replicator.replicate_difference :dummy_diff, 0}.
487
- should raise_error(Exception, "max replication attempts exceeded")
488
- end
489
-
490
- it "replicate_difference should handle updates rejected by the database" do
491
- begin
492
- config = deep_copy(standard_config)
493
- config.options[:committer] = :never_commit
494
- config.options[:replication_conflict_handling] = :left_wins
495
-
496
- session = Session.new(config)
497
- session.left.execute "delete from rr_logged_events"
498
-
499
- session.left.insert_record 'rr_pending_changes', {
500
- 'change_table' => 'scanner_records',
501
- 'change_key' => 'id|1',
502
- 'change_new_key' => 'id|2',
503
- 'change_type' => 'U',
504
- 'change_time' => Time.now
505
- }
506
-
507
- rep_run = ReplicationRun.new session, TaskSweeper.new(1)
508
- helper = ReplicationHelper.new(rep_run)
509
- replicator = Replicators::TwoWayReplicator.new(helper)
510
-
511
- diff = ReplicationDifference.new LoggedChangeLoaders.new(session)
512
- diff.load
513
-
514
- lambda {replicator.replicate_difference diff, 1}.should raise_error(/duplicate/i)
515
-
516
- # Verify that the transaction has not become invalid
517
- helper.log_replication_outcome diff, "bla", "blub"
518
-
519
- row = session.left.select_one("select * from rr_logged_events")
520
- row['change_table'].should == 'scanner_records'
521
- row['change_key'].should == '1'
522
- row['description'].should == 'bla'
523
-
524
- ensure
525
- Committers::NeverCommitter.rollback_current_session
526
- if session
527
- session.left.execute "delete from rr_pending_changes"
528
- session.left.execute "delete from rr_logged_events"
529
- end
530
- end
531
- end
532
-
533
- it "replicate_difference should handle deletes rejected by the database" do
534
- begin
535
- config = deep_copy(standard_config)
536
- config.options[:committer] = :never_commit
537
- config.options[:replication_conflict_handling] = :left_wins
538
-
539
- session = Session.new(config)
540
-
541
- session.left.select_all("select * from rr_logged_events").should == []
542
-
543
- session.left.insert_record 'rr_pending_changes', {
544
- 'change_table' => 'referenced_table',
545
- 'change_key' => 'first_id|1|second_id|2',
546
- 'change_new_key' => nil,
547
- 'change_type' => 'D',
548
- 'change_time' => Time.now
549
- }
550
-
551
- rep_run = ReplicationRun.new session, TaskSweeper.new(1)
552
- helper = ReplicationHelper.new(rep_run)
553
- replicator = Replicators::TwoWayReplicator.new(helper)
554
-
555
- diff = ReplicationDifference.new LoggedChangeLoaders.new(session)
556
- diff.load
557
-
558
- lambda {replicator.replicate_difference diff, 1}.should raise_error(/referencing_table_fkey/)
559
-
560
- # Verify that the transaction has not become invalid
561
- helper.log_replication_outcome diff, "bla", "blub"
562
-
563
- row = session.left.select_one("select * from rr_logged_events")
564
- row['change_table'].should == 'referenced_table'
565
- row['change_key'].should =~ /first_id.*1.*second_id.*2/
566
- row['description'].should == 'bla'
567
-
568
- ensure
569
- Committers::NeverCommitter.rollback_current_session
570
- if session
571
- session.left.execute "delete from rr_pending_changes"
572
- session.left.execute "delete from rr_logged_events"
573
- end
574
- end
575
- end
576
-
577
- it "replicate_difference should handle deletes failing due to the target record vanishing" do
578
- begin
579
- config = deep_copy(standard_config)
580
- config.options[:committer] = :never_commit
581
- config.options[:replication_conflict_handling] = :left_wins
582
-
583
- session = Session.new(config)
584
-
585
- session.left.insert_record 'rr_pending_changes', {
586
- 'change_table' => 'scanner_records',
587
- 'change_key' => 'id|3',
588
- 'change_new_key' => nil,
589
- 'change_type' => 'D',
590
- 'change_time' => Time.now
591
- }
592
-
593
- rep_run = ReplicationRun.new session, TaskSweeper.new(1)
594
- helper = ReplicationHelper.new(rep_run)
595
- replicator = Replicators::TwoWayReplicator.new(helper)
596
-
597
- diff = ReplicationDifference.new LoggedChangeLoaders.new(session)
598
- diff.load
599
-
600
- session.right.insert_record 'rr_pending_changes', {
601
- 'change_table' => 'scanner_records',
602
- 'change_key' => 'id|3',
603
- 'change_new_key' => 'id|4',
604
- 'change_type' => 'U',
605
- 'change_time' => Time.now
606
- }
607
-
608
- replicator.replicate_difference diff, 2
609
-
610
- session.right.select_one("select * from scanner_records where id = 4").
611
- should be_nil
612
- ensure
613
- Committers::NeverCommitter.rollback_current_session
614
- if session
615
- session.left.execute "delete from rr_pending_changes"
616
- session.left.execute "delete from rr_logged_events"
617
- end
618
- end
619
- end
620
-
621
- it "replicate_difference should handle updates failing due to the source record being deleted after the original diff was loaded" do
622
- begin
623
- config = deep_copy(standard_config)
624
- config.options[:committer] = :never_commit
625
- config.options[:replication_conflict_handling] = :left_wins
626
-
627
- session = Session.new(config)
628
-
629
- session.left.insert_record 'extender_no_record', {
630
- 'id' => '2',
631
- 'name' => 'bla'
632
- }
633
- session.right.insert_record 'extender_no_record', {
634
- 'id' => '2',
635
- 'name' => 'blub'
636
- }
637
- session.left.insert_record 'rr_pending_changes', {
638
- 'change_table' => 'extender_no_record',
639
- 'change_key' => 'id|1',
640
- 'change_new_key' => 'id|2',
641
- 'change_type' => 'U',
642
- 'change_time' => Time.now
643
- }
644
-
645
- rep_run = ReplicationRun.new session, TaskSweeper.new(1)
646
- helper = ReplicationHelper.new(rep_run)
647
- replicator = Replicators::TwoWayReplicator.new(helper)
648
-
649
- diff = ReplicationDifference.new LoggedChangeLoaders.new(session)
650
- diff.load
651
-
652
- session.left.delete_record 'extender_no_record', {'id' => '2'}
653
-
654
- session.left.insert_record 'rr_pending_changes', {
655
- 'change_table' => 'extender_no_record',
656
- 'change_key' => 'id|2',
657
- 'change_type' => 'D',
658
- 'change_time' => Time.now
659
- }
660
- replicator.replicate_difference diff, 2
661
-
662
- session.right.select_one("select * from extender_no_record").should be_nil
663
- ensure
664
- Committers::NeverCommitter.rollback_current_session
665
- if session
666
- session.left.execute "delete from extender_no_record"
667
- session.right.execute "delete from extender_no_record"
668
- session.left.execute "delete from rr_pending_changes"
669
- end
670
- end
671
- end
672
-
673
- it "replicate_difference should handle updates failing due to the target record being deleted after the original diff was loaded" do
674
- begin
675
- config = deep_copy(standard_config)
676
- config.options[:committer] = :never_commit
677
- config.options[:replication_conflict_handling] = :left_wins
678
-
679
- session = Session.new(config)
680
-
681
- session.left.insert_record 'extender_no_record', {
682
- 'id' => '2',
683
- 'name' => 'bla'
684
- }
685
- session.left.insert_record 'rr_pending_changes', {
686
- 'change_table' => 'extender_no_record',
687
- 'change_key' => 'id|1',
688
- 'change_new_key' => 'id|2',
689
- 'change_type' => 'U',
690
- 'change_time' => Time.now
691
- }
692
-
693
- rep_run = ReplicationRun.new session, TaskSweeper.new(1)
694
- helper = ReplicationHelper.new(rep_run)
695
- replicator = Replicators::TwoWayReplicator.new(helper)
696
-
697
- diff = ReplicationDifference.new LoggedChangeLoaders.new(session)
698
- diff.load
699
-
700
- session.right.insert_record 'rr_pending_changes', {
701
- 'change_table' => 'extender_no_record',
702
- 'change_key' => 'id|1',
703
- 'change_type' => 'D',
704
- 'change_time' => Time.now
705
- }
706
- replicator.replicate_difference diff, 2
707
-
708
- session.right.select_record(:table => "extender_no_record").should == {
709
- 'id' => 2,
710
- 'name' => 'bla'
711
- }
712
- ensure
713
- Committers::NeverCommitter.rollback_current_session
714
- if session
715
- session.left.execute "delete from extender_no_record"
716
- session.right.execute "delete from extender_no_record"
717
- session.left.execute "delete from rr_pending_changes"
718
- end
719
- end
720
- end
721
- end