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
data/spec/spec_helper.rb DELETED
@@ -1,305 +0,0 @@
1
- begin
2
- require 'spec'
3
- rescue LoadError
4
- require 'rubygems'
5
- gem 'rspec'
6
- require 'spec'
7
- end
8
-
9
- require 'drb'
10
- require 'digest/sha1'
11
-
12
- $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "..", "lib")
13
- $LOAD_PATH.unshift File.dirname(__FILE__)
14
-
15
- require 'rubyrep'
16
- require 'connection_extender_interface_spec'
17
-
18
- unless self.class.const_defined?('STRANGE_TABLE')
19
- if ENV['RR_TEST_DB'] == 'postgres' || ENV['RR_TEST_DB'] == nil
20
- STRANGE_TABLE = 'table_with.stränge Name山'
21
- else
22
- STRANGE_TABLE = 'table_with_stränge Name山'
23
- end
24
- STRANGE_COLUMN = 'stränge. Column山'
25
- end
26
-
27
- class Module
28
- # Used to verify that an instance of the class / module receives a call of the
29
- # specified method.
30
- # This is for cases where a method call has to be mocked of an object that is
31
- # not yet created.
32
- # (Couldn't find out how to do that using existing rspec mocking features.)
33
- def any_instance_should_receive(method, &blck)
34
- tmp_method = "original_before_mocking_#{method}".to_sym
35
- logger_key = "#{self.name}_#{method}"
36
- $mock_method_marker ||= {}
37
- $mock_method_marker[logger_key] = Spec::Mocks::Mock.new("#{name} Instance")
38
- $mock_method_marker[logger_key].should_receive(method).at_least(:once)
39
- self.send :alias_method, tmp_method, method
40
- self.class_eval "def #{method}(*args); $mock_method_marker['#{logger_key}'].#{method}; end"
41
- blck.call
42
- ensure
43
- $mock_method_marker.delete logger_key
44
- self.send :alias_method, method, tmp_method rescue nil
45
- end
46
-
47
- # Used to verify that an instance of the class / module does not receive a
48
- # call of the specified method.
49
- # This is for cases where a method call has to be mocked of an object that is
50
- # not yet created.
51
- # (Couldn't find out how to do that using existing rspec mocking features.)
52
- def any_instance_should_not_receive(method, &blck)
53
- tmp_method = "original_before_mocking_#{method}".to_sym
54
- logger_key = "#{self.name}_#{method}"
55
- $mock_method_marker ||= {}
56
- $mock_method_marker[logger_key] = Spec::Mocks::Mock.new("#{name} Instance")
57
- $mock_method_marker[logger_key].should_not_receive(method)
58
- self.send :alias_method, tmp_method, method
59
- self.class_eval "def #{method}(*args); $mock_method_marker['#{logger_key}'].#{method}; end"
60
- blck.call
61
- ensure
62
- $mock_method_marker.delete logger_key
63
- self.send :alias_method, method, tmp_method rescue nil
64
- end
65
- end
66
-
67
- class RR::Session
68
- # To keep rspec output of failed tests managable
69
- def inspect; 'session'; end
70
- end
71
-
72
- class ActiveRecord::Base
73
- class << self
74
- # Hack:
75
- # The default inspect method (as per activerecord version 2.2.2) tries to
76
- # send commands to the database.
77
- # This leads to rcov failing.
78
- # As workaround this is disabling the attempts to connect to the database.
79
- def inspect
80
- super
81
- end
82
- end
83
- end
84
-
85
- # If number_of_calls is :once, mock ActiveRecord for 1 call.
86
- # If number_of_calls is :twice, mock ActiveRecord for 2 calls.
87
- def mock_active_record(number_of_calls)
88
- ConnectionExtenders::DummyActiveRecord.should_receive(:establish_connection).send(number_of_calls) \
89
- .and_return {|config| $used_config = config}
90
-
91
- dummy_connection = Object.new
92
- # We have a spec testing behaviour for non-existing extenders.
93
- # So extend might not be called in all cases
94
- dummy_connection.stub!(:extend)
95
- dummy_connection.stub!(:tables).and_return([])
96
- dummy_connection.stub!(:initialize_search_path)
97
- dummy_connection.stub!(:select_one).and_return({'x' => '2'})
98
-
99
- ConnectionExtenders::DummyActiveRecord.should_receive(:connection).send(number_of_calls) \
100
- .and_return {dummy_connection}
101
- end
102
-
103
- # Creates a mock ProxyConnection with the given
104
- # * mock_table: name of the mock table
105
- # * primary_key_names: array of mock primary column names
106
- # * column_names: array of mock column names, if nil: doesn't mock this function
107
- def create_mock_proxy_connection(mock_table, primary_key_names, column_names = nil)
108
- session = mock("ProxyConnection")
109
- if primary_key_names
110
- session.should_receive(:primary_key_names) \
111
- .with(mock_table) \
112
- .and_return(primary_key_names)
113
- end
114
- if column_names
115
- session.should_receive(:column_names) \
116
- .with(mock_table) \
117
- .and_return(column_names)
118
- end
119
- session.should_receive(:quote_value) \
120
- .any_number_of_times \
121
- .with(an_instance_of(String), an_instance_of(String), anything) \
122
- .and_return { |table, column, value| value}
123
-
124
- session.should_receive(:connection) \
125
- .any_number_of_times \
126
- .and_return {dummy_connection}
127
-
128
- session.should_receive(:quote_column_name) \
129
- .any_number_of_times \
130
- .with(an_instance_of(String)) \
131
- .and_return { |column_name| "'#{column_name}'" }
132
-
133
- session.should_receive(:quote_table_name) \
134
- .any_number_of_times \
135
- .with(an_instance_of(String)) \
136
- .and_return { |table_name| "'#{table_name}'" }
137
-
138
- session
139
- end
140
-
141
- # Turns an SQL query into a regular expression:
142
- # * Handles quotes (differing depending on DBMS).
143
- # * Handles round brackets (escaping with backslash to make them literals).
144
- # * Removes line breaks and double spaces
145
- # (allowing use of intendation and line continuation)
146
- # Returns the regular expression created from the provided +sql+ string.
147
- def sql_to_regexp(sql)
148
- Regexp.new(sql.strip.squeeze(" ") \
149
- .gsub("(", "\\(").gsub(")", "\\)") \
150
- .gsub("'", 'E?.') \
151
- .gsub('"', 'E?.'))
152
- end
153
-
154
- # Returns a deep copy of the provided object. Works also for Proc objects or
155
- # objects referencing Proc objects.
156
- def deep_copy(object)
157
- Proc.send :define_method, :_dump, lambda { |depth|
158
- @@proc_store ||= {}
159
- @@proc_key ||= "000000000"
160
- @@proc_key.succ!
161
- @@proc_store[@@proc_key] = self
162
- @@proc_key
163
- }
164
- Proc.class.send :define_method, :_load, lambda { |key|
165
- proc = @@proc_store[key]
166
- @@proc_store.delete key
167
- proc
168
- }
169
-
170
- Marshal.restore(Marshal.dump(object))
171
- ensure
172
- Proc.send :remove_method, :_dump if Proc.method_defined? :_dump
173
- Proc.class.send :remove_method, :_load if Proc.class.method_defined? :_load
174
- end
175
-
176
- # Allows the temporary faking of RUBY_PLATFORM to the given value
177
- # Needs to be called with a block. While the block is executed, RUBY_PLATFORM
178
- # is set to the given fake value
179
- def fake_ruby_platform(fake_ruby_platform)
180
- old_ruby_platform = RUBY_PLATFORM
181
- old_verbose, $VERBOSE = $VERBOSE, nil
182
- Object.const_set 'RUBY_PLATFORM', fake_ruby_platform
183
- $VERBOSE = old_verbose
184
- yield
185
- ensure
186
- $VERBOSE = nil
187
- Object.const_set 'RUBY_PLATFORM', old_ruby_platform
188
- $VERBOSE = old_verbose
189
- end
190
-
191
- # Reads the database configuration from the config folder for the specified config key
192
- # E.g. if config is :postgres, tries to read the config from 'postgres_config.rb'
193
- def read_config(config)
194
- $config_cache ||= {}
195
- cache_key = "#{config.to_s}_#{ENV['RR_TEST_DB']}"
196
- unless $config_cache[cache_key]
197
- # load the proxied config but ensure that the original configuration is restored
198
- old_config = RR::Initializer.configuration
199
- RR::Initializer.reset
200
- begin
201
- load File.dirname(__FILE__) + "/../config/#{config}_config.rb"
202
- $config_cache[cache_key] = RR::Initializer.configuration
203
- ensure
204
- RR::Initializer.configuration = old_config
205
- end
206
- end
207
- $config_cache[cache_key]
208
- end
209
-
210
- # Removes all cached database configurations
211
- def clear_config_cache
212
- $config_cache = {}
213
- end
214
-
215
- # Retrieves the proxied database config as specified in config/proxied_test_config.rb
216
- def proxied_config
217
- read_config :proxied_test
218
- end
219
-
220
- # Retrieves the standard (non-proxied) database config as specified in config/test_config.rb
221
- def standard_config
222
- read_config :test
223
- end
224
-
225
- # Inserts two records into 'sequence_test' and returns the generated id values
226
- # * session: the active Session
227
- # * table: name of the table which is to be tested
228
- def get_example_sequence_values(session, table = 'sequence_test')
229
- session.left.insert_record table, { 'name' => 'bla' }
230
- id1 = session.left.select_one("select max(id) as id from #{table}")['id'].to_i
231
- session.left.insert_record table, { 'name' => 'blub' }
232
- id2 = session.left.select_one("select max(id) as id from #{table}")['id'].to_i
233
- return id1, id2
234
- end
235
-
236
- # If true, start proxy as external process (more realistic test but also slower).
237
- # Otherwise start in the current process as thread.
238
- $start_proxy_as_external_process ||= false
239
-
240
- # Starts a proxy under the given host and post
241
- def start_proxy(host, port)
242
- if $start_proxy_as_external_process
243
- bin_path = File.join(File.dirname(__FILE__), "..", "bin", "rubyrep")
244
- ruby = RUBY_PLATFORM =~ /java/ ? 'jruby' : 'ruby'
245
- cmd = "#{ruby} #{bin_path} proxy -h #{host} -p #{port}"
246
- Thread.new {system cmd}
247
- else
248
- url = "druby://#{host}:#{port}"
249
- DRb.start_service(url, DatabaseProxy.new)
250
- end
251
- end
252
-
253
- # Set to true if the proxy as per SPEC_PROXY_CONFIG is running
254
- $proxy_confirmed_running = false
255
-
256
- # Starts a proxy as per left proxy settings defined in config/proxied_test_config.rb.
257
- # Only starts the proxy though if none is running yet at the according host / port.
258
- # If it starts a proxy child process, it also prepares automatic termination
259
- # after the spec run is finished.
260
- def ensure_proxy
261
- # only execute the network verification once per spec run
262
- unless $proxy_confirmed_running
263
- drb_url = "druby://#{proxied_config.left[:proxy_host]}:#{proxied_config.left[:proxy_port]}"
264
- # try to connect to the proxy
265
- begin
266
- proxy = DRbObject.new nil, drb_url
267
- proxy.ping
268
- $proxy_confirmed_running = true
269
- rescue DRb::DRbConnError => e
270
- # Proxy not yet running ==> start it
271
- start_proxy proxied_config.left[:proxy_host], proxied_config.left[:proxy_port]
272
-
273
- maximum_startup_time = 5 # maximum time in seconds for the proxy to start
274
- waiting_time = 0.1 # time to wait between connection attempts
275
-
276
- time = 0.0
277
- ping_response = ''
278
- # wait for the proxy to start up and become operational
279
- while ping_response != 'pong' and time < maximum_startup_time
280
- begin
281
- proxy = DRbObject.new nil, drb_url
282
- ping_response = proxy.ping
283
- break
284
- rescue DRb::DRbConnError => e
285
- # do nothing (just try again)
286
- end
287
- sleep waiting_time
288
- time += waiting_time
289
- end
290
- if ping_response == 'pong'
291
- #puts "Proxy started (took #{time} seconds)"
292
- # Ensure that the started proxy is terminated with the completion of the spec run.
293
- at_exit do
294
- proxy = DRbObject.new nil, drb_url
295
- proxy.terminate! rescue DRb::DRbConnError
296
- end if $start_proxy_as_external_process
297
- else
298
- raise "Could not start proxy"
299
- end
300
- end
301
-
302
- # if we got till here, then a proxy is running or was successfully started
303
- $proxy_confirmed_running = true
304
- end
305
- end
@@ -1,135 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper.rb'
2
-
3
- include RR
4
-
5
- describe "Unusual table and column name support" do
6
- before(:each) do
7
- Initializer.configuration = standard_config
8
- end
9
-
10
- it "should be able to insert, update and delete records" do
11
- session = Session.new
12
- session.left.begin_db_transaction
13
- begin
14
- select_row = Proc.new {
15
- session.left.
16
- select_one(
17
- "select #{session.left.quote_column_name(STRANGE_COLUMN)}
18
- from #{session.left.quote_table_name(STRANGE_TABLE)}")
19
- }
20
-
21
- session.left.insert_record STRANGE_TABLE, 'id' => 1, STRANGE_COLUMN => 'bla'
22
- select_row.call[STRANGE_COLUMN].should == 'bla'
23
-
24
- session.left.update_record STRANGE_TABLE, 'id' => 1, STRANGE_COLUMN => 'blub'
25
- select_row.call[STRANGE_COLUMN].should == 'blub'
26
-
27
- session.left.delete_record STRANGE_TABLE, 'id' => 1
28
- select_row.call.should be_nil
29
- ensure
30
- session.left.rollback_db_transaction
31
- end
32
- end
33
-
34
- it "should be able to identify primary keys" do
35
- session = Session.new
36
- session.left.primary_key_names(STRANGE_TABLE).should == ['id']
37
- end
38
-
39
- it "should be able to identify referenced tables" do
40
- session = Session.new
41
- referenced_tables = session.left.referenced_tables([STRANGE_TABLE])
42
- referenced_tables.size.should == 1
43
- referenced_tables[STRANGE_TABLE].sort.
44
- should == ["referenced_table"]
45
- end
46
-
47
- it "should support sequence operations" do
48
- session = Session.new
49
- begin
50
- left_sequence_values = session.left.sequence_values('rr', STRANGE_TABLE)
51
- right_sequence_values = session.right.sequence_values('rr', STRANGE_TABLE)
52
- session.left.update_sequences(
53
- 'rr', STRANGE_TABLE, 10, 7, left_sequence_values, right_sequence_values, 1)
54
-
55
- sequence_props = session.left.sequence_values('rr', STRANGE_TABLE).values.first
56
- sequence_props[:increment].should == 10
57
- (sequence_props[:value] % 10).should == 7
58
-
59
- session.left.clear_sequence_setup 'rr', STRANGE_TABLE
60
-
61
- session.left.sequence_values('rr', STRANGE_TABLE).values.first[:increment].should == 1
62
- ensure
63
- session.left.clear_sequence_setup 'rr', STRANGE_TABLE
64
- end
65
- end
66
-
67
- it "should support trigger operations for strange tables" do
68
- trigger_name = 'rr_' + STRANGE_TABLE
69
- session = Session.new
70
- begin
71
- session.left.replication_trigger_exists?(trigger_name, STRANGE_TABLE).should be_false
72
- session.left.create_replication_trigger({
73
- :trigger_name => trigger_name,
74
- :table => STRANGE_TABLE,
75
- :keys => ['id'],
76
- :log_table => 'rr_pending_changes',
77
- :activity_table => 'rr_running_flags',
78
- :key_sep => '|',
79
- :exclude_rr_activity => true
80
- })
81
- session.left.replication_trigger_exists?(trigger_name, STRANGE_TABLE).should be_true
82
- session.left.insert_record STRANGE_TABLE, {
83
- 'id' => 11,
84
- STRANGE_COLUMN => 'blub'
85
- }
86
- log_record = session.left.select_one(
87
- "select * from rr_pending_changes where change_table = '#{STRANGE_TABLE}'")
88
- log_record['change_key'].should == 'id|11'
89
- log_record['change_type'].should == 'I'
90
-
91
- session.left.drop_replication_trigger trigger_name, STRANGE_TABLE
92
- session.left.replication_trigger_exists?(trigger_name, STRANGE_TABLE).should be_false
93
- ensure
94
- if session.left.replication_trigger_exists?(trigger_name, STRANGE_TABLE)
95
- session.left.drop_replication_trigger trigger_name, STRANGE_TABLE
96
- end
97
- session.left.execute "delete from #{session.left.quote_table_name(STRANGE_TABLE)}"
98
- session.left.execute "delete from rr_pending_changes"
99
- end
100
- end
101
-
102
- it "should support trigger operations for table with strange primary keys" do
103
- trigger_name = 'rr_table_with_strange_key'
104
- session = Session.new
105
- begin
106
- session.left.replication_trigger_exists?(trigger_name, :table_with_strange_key).should be_false
107
- session.left.create_replication_trigger({
108
- :trigger_name => trigger_name,
109
- :table => :table_with_strange_key,
110
- :keys => [STRANGE_COLUMN],
111
- :log_table => 'rr_pending_changes',
112
- :activity_table => 'rr_running_flags',
113
- :key_sep => '|',
114
- :exclude_rr_activity => true
115
- })
116
- session.left.replication_trigger_exists?(trigger_name, :table_with_strange_key).should be_true
117
- session.left.insert_record 'table_with_strange_key', {
118
- STRANGE_COLUMN => '11'
119
- }
120
- log_record = session.left.select_one(
121
- "select * from rr_pending_changes where change_table = 'table_with_strange_key'")
122
- log_record['change_key'].should == "#{STRANGE_COLUMN}|11"
123
- log_record['change_type'].should == 'I'
124
-
125
- session.left.drop_replication_trigger trigger_name, :table_with_strange_key
126
- session.left.replication_trigger_exists?(trigger_name, :table_with_strange_key).should be_false
127
- ensure
128
- if session.left.replication_trigger_exists?(trigger_name, :table_with_strange_key)
129
- session.left.drop_replication_trigger trigger_name, :table_with_strange_key
130
- end
131
- session.left.execute "delete from #{session.left.quote_table_name(:table_with_strange_key)}"
132
- session.left.execute "delete from rr_pending_changes"
133
- end
134
- end
135
- end
@@ -1,169 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper.rb'
2
-
3
- include RR
4
-
5
- describe SyncHelper do
6
- before(:each) do
7
- Initializer.configuration = standard_config
8
- end
9
-
10
- it "initialize should initialize the correct committer" do
11
- sync = TableSync.new(Session.new, 'scanner_records')
12
- helper = SyncHelper.new(sync)
13
- c = helper.instance_eval {committer}
14
- c.should be_an_instance_of(Committers::DefaultCommitter)
15
- c.session.should == helper.session
16
- end
17
-
18
- it "session should return the session" do
19
- sync = TableSync.new(Session.new, 'scanner_records')
20
- helper = SyncHelper.new(sync)
21
- helper.session.should == sync.session
22
- end
23
-
24
- it "extract_key should extract the primary key column_name => value pairs" do
25
- sync = TableSync.new(Session.new, 'extender_combined_key')
26
- helper = SyncHelper.new(sync)
27
- helper.extract_key('first_id' => 1, 'second_id' => 2, 'name' => 'bla').
28
- should == {'first_id' => 1, 'second_id' => 2}
29
- end
30
-
31
- it "ensure_event_log should ask the replication_initializer to ensure the event log" do
32
- sync = TableSync.new(Session.new, 'scanner_records')
33
- helper = SyncHelper.new(sync)
34
- ReplicationInitializer.any_instance_should_receive(:ensure_event_log) do
35
- helper.ensure_event_log
36
- end
37
- end
38
-
39
- it "log_sync_outcome should log the replication outcome correctly" do
40
- session = Session.new
41
- session.left.begin_db_transaction
42
- begin
43
- sync = TableSync.new(Session.new, 'scanner_records')
44
- helper = SyncHelper.new(sync)
45
-
46
- # Verify that the log information are made fitting
47
- helper.should_receive(:fit_description_columns).
48
- with('my_outcome', 'my_long_description').
49
- and_return(['my_outcomeX', 'my_long_descriptionY'])
50
-
51
- helper.log_sync_outcome(
52
- {'bla' => 'blub', 'id' => 1},
53
- 'my_sync_type',
54
- 'my_outcome',
55
- 'my_long_description'
56
- )
57
-
58
- row = session.left.select_one("select * from rr_logged_events order by id desc")
59
- row['activity'].should == 'sync'
60
- row['change_table'].should == 'scanner_records'
61
- row['diff_type'].should == 'my_sync_type'
62
- row['change_key'].should == '1'
63
- row['left_change_type'].should be_nil
64
- row['right_change_type'].should be_nil
65
- row['description'].should == 'my_outcomeX'
66
- row['long_description'].should == 'my_long_descriptionY'
67
- Time.parse(row['event_time']).should >= 10.seconds.ago
68
- row['diff_dump'].should == nil
69
- ensure
70
- session.left.rollback_db_transaction if session
71
- end
72
- end
73
-
74
- it "log_sync_outcome should log events for combined primary key tables correctly" do
75
- session = Session.new
76
- session.left.begin_db_transaction
77
- begin
78
- sync = TableSync.new(Session.new, 'extender_combined_key')
79
- helper = SyncHelper.new(sync)
80
-
81
- helper.log_sync_outcome(
82
- {'bla' => 'blub', 'first_id' => 1, 'second_id' => 2},
83
- 'my_sync_type',
84
- 'my_outcome',
85
- 'my_long_description'
86
- )
87
-
88
- row = session.left.select_one("select * from rr_logged_events order by id desc")
89
- row['change_key'].should == '"first_id"=>"1", "second_id"=>"2"'
90
- ensure
91
- session.left.rollback_db_transaction if session
92
- end
93
- end
94
-
95
- it "left_table and right_table should return the correct table names" do
96
- sync = TableSync.new(Session.new, 'scanner_records')
97
- helper = SyncHelper.new(sync)
98
- helper.left_table.should == 'scanner_records'
99
- helper.right_table.should == 'scanner_records'
100
-
101
- sync = TableSync.new(Session.new, 'scanner_records', 'right_table')
102
- helper = SyncHelper.new(sync)
103
- helper.left_table.should == 'scanner_records'
104
- helper.right_table.should == 'right_table'
105
- end
106
-
107
- it "tables should return the correct table name hash" do
108
- sync = TableSync.new(Session.new, 'scanner_records', 'right_table')
109
- helper = SyncHelper.new(sync)
110
- helper.tables.should == {:left => 'scanner_records', :right => 'right_table'}
111
- end
112
-
113
- it "table_sync should return the current table sync instance" do
114
- sync = TableSync.new(Session.new, 'scanner_records')
115
- helper = SyncHelper.new(sync)
116
- helper.table_sync.should == sync
117
- end
118
-
119
- it "sync_options should return the correct sync options" do
120
- sync = TableSync.new(Session.new, 'scanner_records')
121
- helper = SyncHelper.new(sync)
122
- helper.sync_options.should == sync.sync_options
123
- end
124
-
125
- it "insert_record should insert the given record" do
126
- sync = TableSync.new(Session.new, 'scanner_records')
127
- helper = SyncHelper.new(sync)
128
- c = helper.instance_eval {committer}
129
- c.should_receive(:insert_record).with(:right, 'scanner_records', :dummy_record)
130
- helper.insert_record :right, 'scanner_records', :dummy_record
131
- end
132
-
133
- it "update_record should update the given record" do
134
- sync = TableSync.new(Session.new, 'scanner_records')
135
- helper = SyncHelper.new(sync)
136
- c = helper.instance_eval {committer}
137
- c.should_receive(:update_record).with(:right, 'scanner_records', :dummy_record, nil)
138
- helper.update_record :right, 'scaner_records', :dummy_record
139
- end
140
-
141
- it "update_record should update the given record with the provided old key" do
142
- sync = TableSync.new(Session.new, 'scanner_records')
143
- helper = SyncHelper.new(sync)
144
- c = helper.instance_eval {committer}
145
- c.should_receive(:update_record).with(:right, 'scanner_records', :dummy_record, :old_key)
146
- helper.update_record :right, 'scanner_records', :dummy_record, :old_key
147
- end
148
-
149
- it "delete_record should delete the given record" do
150
- sync = TableSync.new(Session.new, 'scanner_records')
151
- helper = SyncHelper.new(sync)
152
- c = helper.instance_eval {committer}
153
- c.should_receive(:delete_record).with(:right, 'scanner_records', :dummy_record)
154
- helper.delete_record :right, 'scanner_records', :dummy_record
155
- end
156
-
157
- it "finalize should be delegated to the committer" do
158
- sync = TableSync.new(Session.new, 'scanner_records')
159
- helper = SyncHelper.new(sync)
160
-
161
- # finalize itself should not lead to creation of committer
162
- helper.finalize
163
- helper.instance_eval {@committer}.should be_nil
164
-
165
- c = helper.instance_eval {committer}
166
- c.should_receive(:finalize).with(false)
167
- helper.finalize(false)
168
- end
169
- end
@@ -1,78 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper.rb'
2
-
3
- include RR
4
-
5
- describe SyncRunner do
6
- before(:each) do
7
- end
8
-
9
- it "should register itself with CommandRunner" do
10
- CommandRunner.commands['sync'][:command].should == SyncRunner
11
- CommandRunner.commands['sync'][:description].should be_an_instance_of(String)
12
- end
13
-
14
- it "prepare_table_pairs should sort the tables" do
15
- session = Session.new standard_config
16
- session.should_receive(:sort_table_pairs).
17
- with(:dummy_table_pairs).
18
- and_return(:sorted_dummy_table_pairs)
19
-
20
- sync_runner = SyncRunner.new
21
- sync_runner.stub!(:session).and_return(session)
22
-
23
- sync_runner.prepare_table_pairs(:dummy_table_pairs).should == :sorted_dummy_table_pairs
24
- end
25
-
26
- it "execute should sync the specified tables" do
27
- org_stdout = $stdout
28
- session = nil
29
-
30
- # This is necessary to avoid the cached RubyRep configurations from getting
31
- # overwritten by the sync run
32
- old_config, Initializer.configuration = Initializer.configuration, Configuration.new
33
-
34
- session = Session.new(standard_config)
35
- session.left.begin_db_transaction
36
- session.right.begin_db_transaction
37
-
38
- $stdout = StringIO.new
39
- begin
40
- sync_runner = SyncRunner.new
41
- sync_runner.options = {
42
- :config_file => "#{File.dirname(__FILE__)}/../config/test_config.rb",
43
- :table_specs => ["scanner_records"]
44
- }
45
-
46
- sync_runner.execute
47
-
48
- $stdout.string.should =~
49
- /scanner_records .* 5\n/
50
-
51
- left_records = session.left.connection.select_all("select * from scanner_records order by id")
52
- right_records = session.right.connection.select_all("select * from scanner_records order by id")
53
- left_records.should == right_records
54
- ensure
55
- $stdout = org_stdout
56
- Initializer.configuration = old_config if old_config
57
- if session
58
- session.left.rollback_db_transaction
59
- session.right.rollback_db_transaction
60
- end
61
- end
62
- end
63
-
64
- it "create_processor should create the TableSync instance" do
65
- TableSync.should_receive(:new).
66
- with(:dummy_session, "left_table", "right_table").
67
- and_return(:dummy_table_sync)
68
- sync_runner = SyncRunner.new
69
- sync_runner.should_receive(:session).and_return(:dummy_session)
70
- sync_runner.create_processor("left_table", "right_table").
71
- should == :dummy_table_sync
72
- end
73
-
74
- it "summary_description should return a description" do
75
- SyncRunner.new.summary_description.should be_an_instance_of(String)
76
- end
77
-
78
- end