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,212 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper.rb'
2
-
3
- include RR
4
-
5
- require File.dirname(__FILE__) + "/../config/test_config.rb"
6
-
7
- describe "PostgreSQL schema support" do
8
- before(:each) do
9
- config = deep_copy(standard_config)
10
- config.options[:rep_prefix] = 'rx'
11
- config.left[:schema_search_path] = 'rr'
12
- config.right[:schema_search_path] = 'rr'
13
- Initializer.configuration = config
14
- end
15
-
16
- after(:each) do
17
- end
18
-
19
- if Initializer.configuration.left[:adapter] == 'postgresql'
20
- it "tables should show the tables from the schema and no others" do
21
- session = Session.new
22
- session.left.tables.include?('rr_simple').should be_true
23
- session.left.tables.include?('scanner_records').should be_false
24
- end
25
-
26
- it "tables should not show the tables from other schemas" do
27
- session = Session.new standard_config
28
- session.left.tables.include?('scanner_records').should be_true
29
- session.left.tables.include?('rr_simple').should be_false
30
- end
31
-
32
- it "primary_key_names should work" do
33
- session = Session.new
34
- session.left.primary_key_names('rr_simple').should == ['id']
35
- end
36
-
37
- it "primary_key_names should pick the table in the target schema" do
38
- session = Session.new
39
- session.left.primary_key_names('rr_duplicate').should == ['id']
40
- end
41
-
42
- it "column_names should work" do
43
- session = Session.new
44
- session.left.column_names('rr_simple').should == ['id', 'name']
45
- end
46
-
47
- it "column_names should pick the table in the target schema" do
48
- session = Session.new
49
- session.left.column_names('rr_duplicate').should == ['id', 'name']
50
- end
51
-
52
- it "referenced_tables should work" do
53
- session = Session.new
54
- session.left.referenced_tables(['rr_referencing']).should == {
55
- 'rr_referencing' => ['rr_referenced']
56
- }
57
- end
58
-
59
- it "table_select_query should work" do
60
- session = Session.new
61
- session.left.table_select_query('rr_simple').
62
- should == 'select "id", "name" from "rr_simple" order by "id"'
63
- end
64
-
65
- it "TypeCastingCursor should work" do
66
- session = Session.new
67
- org_cursor = session.left.select_cursor(
68
- :query => "select id, name from rr_simple where id = 1",
69
- :type_cast => false
70
- )
71
- cursor = TypeCastingCursor.new session.left, 'rr_simple', org_cursor
72
-
73
- row = cursor.next_row
74
-
75
- row.should == {
76
- 'id' => 1,
77
- 'name' => 'bla'
78
- }
79
- end
80
-
81
- it "sequence_values should pick the table in the target schema" do
82
- session = Session.new
83
- session.left.sequence_values('rx', 'rr_duplicate').keys.should == ["rr_duplicate_id_seq"]
84
- end
85
-
86
- it "clear_sequence_setup should pick the table in the target schema" do
87
- session = nil
88
- begin
89
- session = Session.new
90
- initializer = ReplicationInitializer.new(session)
91
- session.left.begin_db_transaction
92
- session.right.begin_db_transaction
93
- table_pair = {:left => 'rr_duplicate', :right => 'rr_duplicate'}
94
- initializer.ensure_sequence_setup table_pair, 5, 2, 1
95
- id1, id2 = get_example_sequence_values(session, 'rr_duplicate')
96
- (id2 - id1).should == 5
97
- (id1 % 5).should == 2
98
-
99
- initializer.clear_sequence_setup :left, 'rr_duplicate'
100
- id1, id2 = get_example_sequence_values(session, 'rr_duplicate')
101
- (id2 - id1).should == 1
102
- ensure
103
- [:left, :right].each do |database|
104
- initializer.clear_sequence_setup database, 'rr_duplicate' rescue nil if session
105
- session.send(database).execute "delete from rr_duplicate" rescue nil if session
106
- session.send(database).rollback_db_transaction rescue nil if session
107
- end
108
- end
109
-
110
- end
111
-
112
- it "sequence setup should work" do
113
- session = nil
114
- begin
115
- session = Session.new
116
- initializer = ReplicationInitializer.new(session)
117
- session.left.begin_db_transaction
118
- session.right.begin_db_transaction
119
- table_pair = {:left => 'rr_sequence_test', :right => 'rr_sequence_test'}
120
- initializer.ensure_sequence_setup table_pair, 5, 2, 1
121
- id1, id2 = get_example_sequence_values(session, 'rr_sequence_test')
122
- (id2 - id1).should == 5
123
- (id1 % 5).should == 2
124
- ensure
125
- [:left, :right].each do |database|
126
- initializer.clear_sequence_setup database, 'rr_sequence_test' rescue nil if session
127
- session.send(database).execute "delete from rr_sequence_test" rescue nil if session
128
- session.send(database).rollback_db_transaction rescue nil if session
129
- end
130
- end
131
- end
132
-
133
- it "clear_sequence_setup should work" do
134
- session = nil
135
- begin
136
- session = Session.new
137
- initializer = ReplicationInitializer.new(session)
138
- session.left.begin_db_transaction
139
- session.right.begin_db_transaction
140
- table_pair = {:left => 'rr_sequence_test', :right => 'rr_sequence_test'}
141
- initializer.ensure_sequence_setup table_pair, 5, 2, 2
142
- initializer.clear_sequence_setup :left, 'rr_sequence_test'
143
- id1, id2 = get_example_sequence_values(session, 'rr_sequence_test')
144
- (id2 - id1).should == 1
145
- ensure
146
- [:left, :right].each do |database|
147
- initializer.clear_sequence_setup database, 'rr_sequence_test' if session
148
- session.send(database).execute "delete from rr_sequence_test" if session
149
- session.send(database).rollback_db_transaction if session
150
- end
151
- end
152
- end
153
-
154
- it "initializer should create tables in target schema" do
155
- session = nil
156
- begin
157
- config = deep_copy(Initializer.configuration)
158
- config.options[:rep_prefix] = 'ry'
159
- session = Session.new config
160
- session.left.begin_db_transaction
161
-
162
- initializer = ReplicationInitializer.new(session)
163
- initializer.create_change_log(:left)
164
-
165
- # no exception ==> means table was created in target schema
166
- session.left.select_one("select id from rr.ry_pending_changes")
167
- ensure
168
- session.left.rollback_db_transaction if session
169
- end
170
- end
171
-
172
- it "create_trigger, trigger_exists? and drop_trigger should work" do
173
- session = nil
174
- begin
175
- session = Session.new
176
- initializer = ReplicationInitializer.new(session)
177
- session.left.begin_db_transaction
178
-
179
- initializer.create_trigger :left, 'rr_trigger_test'
180
- initializer.trigger_exists?(:left, 'rr_trigger_test').
181
- should be_true
182
-
183
- # Verify that the trigger can find the pending_changes table even if
184
- # current search_path does not include it.
185
- session.left.execute "set search_path = 'public'"
186
- session.left.execute <<-EOF
187
- insert into rr.rr_trigger_test(first_id, second_id) values(10, 11)
188
- EOF
189
- session.left.execute "set search_path = 'rr'"
190
- session.left.select_one("select change_key from rx_pending_changes")['change_key'].
191
- should == "first_id|10|second_id|11"
192
-
193
- initializer.drop_trigger(:left, 'rr_trigger_test')
194
- initializer.trigger_exists?(:left, 'rr_trigger_test').
195
- should be_false
196
- ensure
197
- session.left.rollback_db_transaction if session
198
- end
199
- end
200
-
201
- it "should work with complex search paths" do
202
- config = deep_copy(standard_config)
203
- config.left[:schema_search_path] = 'public,rr'
204
- config.right[:schema_search_path] = 'public,rr'
205
- session = Session.new(config)
206
-
207
- tables = session.left.tables
208
- tables.include?('rr_simple').should be_true
209
- tables.include?('scanner_records').should be_true
210
- end
211
- end
212
- end
@@ -1,63 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper.rb'
2
-
3
- include RR
4
-
5
- require File.dirname(__FILE__) + "/../config/test_config.rb"
6
-
7
- describe "PostgreSQL support" do
8
- before(:each) do
9
- Initializer.configuration = standard_config
10
- end
11
-
12
- after(:each) do
13
- end
14
-
15
- if Initializer.configuration.left[:adapter] == 'postgresql'
16
-
17
- it "should read & write microsecond times" do
18
- session = nil
19
- begin
20
- session = Session.new
21
- session.left.begin_db_transaction
22
- session.left.insert_record('extender_type_check',
23
- {'id' => 2, 'timestamp' => Time.local(2009, "feb", 16, 20, 48, 1, 543)}
24
- )
25
-
26
- org_cursor = session.left.select_cursor(
27
- :query => "select id, timestamp from extender_type_check where id = 2",
28
- :type_cast => false
29
- )
30
- cursor = TypeCastingCursor.new session.left, 'extender_type_check', org_cursor
31
-
32
- row = cursor.next_row
33
- row['timestamp'].usec.should == 543
34
- cursor.clear
35
- ensure
36
- session.left.rollback_db_transaction if session
37
- end
38
- end
39
-
40
- it "should not round microsecond times to incorrect value" do
41
- session = nil
42
- begin
43
- session = Session.new
44
- session.left.begin_db_transaction
45
- session.left.insert_record('extender_type_check',
46
- {'id' => 2, 'timestamp' => Time.local(2009, "feb", 16, 13, 37, 11, 126291)}
47
- )
48
-
49
- org_cursor = session.left.select_cursor(
50
- :query => "select id, timestamp from extender_type_check where id = 2",
51
- :type_cast => false
52
- )
53
- cursor = TypeCastingCursor.new session.left, 'extender_type_check', org_cursor
54
-
55
- row = cursor.next_row
56
- row['timestamp'].usec.should == 126291
57
- cursor.clear
58
- ensure
59
- session.left.rollback_db_transaction if session
60
- end
61
- end
62
- end
63
- end
@@ -1,77 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper.rb'
2
-
3
- include RR
4
- include ScanProgressPrinters
5
-
6
- describe ProgressBar do
7
- before(:each) do
8
- @org_stdout = $stdout
9
- $stdout = StringIO.new
10
- @old_arg = ProgressBar.arg
11
- end
12
-
13
- after(:each) do
14
- ProgressBar.arg = @old_arg
15
- $stdout = @org_stdout
16
- end
17
-
18
- it "arg should store the command line argument and max_markers return the correct marker number" do
19
- ProgressBar.arg = nil
20
- ProgressBar.new(100, Session.new(standard_config), 'bla', 'blub').max_markers.should == ProgressBar::MAX_MARKERS
21
- ProgressBar.arg = "2"
22
- ProgressBar.new(100, Session.new(standard_config), 'bla', 'blub').max_markers.should == 2
23
- end
24
-
25
- it "step should use ANSI codes if options :use_ansi is set" do
26
- session = Session.new(deep_copy(standard_config))
27
- session.configuration.options[:use_ansi] = true
28
- bar = ProgressBar.new(10, session, 'bla', 'blub')
29
- bar.step 1
30
- bar.step 1
31
- $stdout.string.should =~ Regexp.new(Regexp.escape("\e[1"))
32
- end
33
-
34
- it "step should not use ANSI codes if options :use_ansi is not true" do
35
- session = Session.new(deep_copy(standard_config))
36
- session.configuration.options[:use_ansi] = false
37
- bar = ProgressBar.new(10, session, 'bla', 'blub')
38
- bar.step 1
39
- bar.step 1
40
- $stdout.string.should_not =~ Regexp.new(Regexp.escape("\e[1"))
41
- end
42
-
43
- it "should register itself with ScanRunner" do
44
- RR::ScanProgressPrinters.printers[:progress_bar][:printer_class].
45
- should == ProgressBar
46
- end
47
-
48
- it "step should print the correct progress" do
49
- bar = ProgressBar.new(1000, Session.new(standard_config), 'bla', 'blub')
50
- bar.step 200
51
- bar.step 300
52
- $stdout.string.count('.').should == ProgressBar::MAX_MARKERS / 2
53
- bar.step 500
54
- $stdout.string.count('.').should == ProgressBar::MAX_MARKERS
55
- end
56
-
57
- it "step should work around weird floating point rounding issues" do
58
- bar = ProgressBar.new(56, Session.new(standard_config), 'bla', 'blub')
59
- (1..56).each {bar.step 1}
60
- $stdout.string.count('.').should == ProgressBar::MAX_MARKERS
61
- end
62
-
63
- it "if max_steps is 0, any step call should go to 100% progress" do
64
- config = deep_copy(standard_config)
65
- config.options[:use_ansi] = true
66
- bar = ProgressBar.new(0, Session.new(config), 'bla', 'blub')
67
- bar.step
68
- $stdout.string.count('.').should == ProgressBar::MAX_MARKERS
69
- $stdout.string.should =~ /100%/
70
-
71
- # Ensure we don't go over 100%
72
- $stdout = StringIO.new
73
- bar.step
74
- $stdout.string.should == ''
75
- end
76
-
77
- end
@@ -1,151 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper.rb'
2
-
3
- include RR
4
-
5
- describe ProxiedTableScan do
6
- before(:each) do
7
- Initializer.configuration = deep_copy(proxied_config)
8
-
9
- # Small block size necessary to exercize all code paths in ProxiedTableScan
10
- # even when only using tables with very small number of records.
11
- Initializer.configuration.options[:proxy_block_size] = 2
12
-
13
- ensure_proxy
14
- end
15
-
16
- it "initialize should raise exception if session is not proxied" do
17
- session = Session.new standard_config
18
- lambda { ProxiedTableScan.new session, 'dummy_table' } \
19
- .should raise_error(RuntimeError, /only works with proxied sessions/)
20
- end
21
-
22
- it "initialize should cache the primary keys" do
23
- session = Session.new
24
- scan = ProxiedTableScan.new session, 'scanner_records'
25
- scan.primary_key_names.should == ['id']
26
- end
27
-
28
- it "initialize should raise exception if table doesn't have primary keys" do
29
- session = Session.new
30
- lambda {ProxiedTableScan.new session, 'extender_without_key'} \
31
- .should raise_error(RuntimeError, /.*extender_without_key.*primary key/)
32
- end
33
-
34
- it "block_size should return the :proxy_block_size value of the session options" do
35
- ProxiedTableScan.new(Session.new, 'scanner_records').block_size \
36
- .should == 2
37
- end
38
-
39
- it "block_size should return the matching table specific option if available" do
40
- config = Initializer.configuration
41
- old_table_specific_options = config.tables_with_options
42
- begin
43
- config.options = {:proxy_block_size => 2}
44
- config.include_tables 'scanner_records', {:proxy_block_size => 3}
45
- ProxiedTableScan.new(Session.new(config), 'scanner_records').block_size \
46
- .should == 3
47
- ensure
48
- config.instance_eval {@tables_with_options = old_table_specific_options}
49
- end
50
- end
51
-
52
- # Creates, prepares and returns a +ProxyBlockCursor+ for the given database
53
- # +connection+ and +table+.
54
- # Sets the ProxyBlockCursor#max_row_cache_size as per method parameter.
55
- def get_block_cursor(connection, table, max_row_cache_size = 1000000)
56
- cursor = ProxyBlockCursor.new connection, table
57
- cursor.max_row_cache_size = max_row_cache_size
58
- cursor.prepare_fetch
59
- cursor.checksum :proxy_block_size => 1000
60
- cursor
61
- end
62
-
63
- it "compare_blocks should compare all the records in the range" do
64
- session = Session.new
65
-
66
- left_cursor = get_block_cursor session.left, 'scanner_records'
67
- right_cursor = get_block_cursor session.right, 'scanner_records'
68
-
69
- scan = ProxiedTableScan.new session, 'scanner_records'
70
- diff = []
71
- scan.compare_blocks(left_cursor, right_cursor) do |type, row|
72
- diff.push [type, row]
73
- end
74
- # in this scenario the right table has the 'highest' data,
75
- # so 'right-sided' data are already implicitely tested here
76
- diff.should == [
77
- [:conflict, [
78
- {'id' => 2, 'name' => 'Bob - left database version'},
79
- {'id' => 2, 'name' => 'Bob - right database version'}]],
80
- [:left, {'id' => 3, 'name' => 'Charlie - exists in left database only'}],
81
- [:right, {'id' => 4, 'name' => 'Dave - exists in right database only'}],
82
- [:left, {'id' => 5, 'name' => 'Eve - exists in left database only'}],
83
- [:right, {'id' => 6, 'name' => 'Fred - exists in right database only'}]
84
- ]
85
- end
86
-
87
- it "compare_blocks should destroy the created cursors" do
88
- session = Session.new
89
-
90
- left_cursor = get_block_cursor session.left, 'scanner_records', 0
91
- right_cursor = get_block_cursor session.right, 'scanner_records', 0
92
-
93
- scan = ProxiedTableScan.new session, 'scanner_records'
94
- scan.compare_blocks(left_cursor, right_cursor) { |type, row| }
95
-
96
- session.left.cursors.should == {}
97
- session.right.cursors.should == {}
98
- end
99
-
100
- it "run should only call compare single rows if there are different block checksums" do
101
- config = deep_copy(proxied_config)
102
- config.right = config.left
103
- session = Session.new config
104
- scan = ProxiedTableScan.new session, 'scanner_records'
105
- scan.should_not_receive(:compare_blocks)
106
- diff = []
107
- scan.run do |type, row|
108
- diff.push [type,row]
109
- end
110
- diff.should == []
111
- end
112
-
113
- it "run should compare all the records in the table" do
114
- session = Session.new
115
- scan = ProxiedTableScan.new session, 'scanner_records'
116
- diff = []
117
- scan.run do |type, row|
118
- diff.push [type, row]
119
- end
120
- # in this scenario the right table has the 'highest' data,
121
- # so 'right-sided' data are already implicitely tested here
122
- diff.should == [
123
- [:conflict, [
124
- {'id' => 2, 'name' => 'Bob - left database version'},
125
- {'id' => 2, 'name' => 'Bob - right database version'}]],
126
- [:left, {'id' => 3, 'name' => 'Charlie - exists in left database only'}],
127
- [:right, {'id' => 4, 'name' => 'Dave - exists in right database only'}],
128
- [:left, {'id' => 5, 'name' => 'Eve - exists in left database only'}],
129
- [:right, {'id' => 6, 'name' => 'Fred - exists in right database only'}]
130
- ]
131
- end
132
-
133
- it "run should update the progress" do
134
- session = Session.new
135
- scan = ProxiedTableScan.new session, 'scanner_records'
136
- number_steps = 0
137
- scan.should_receive(:update_progress).any_number_of_times do |steps|
138
- number_steps += steps
139
- end
140
- scan.run {|_, _|}
141
- number_steps.should == 8
142
- end
143
-
144
- it "run should update the progress even if there are no records" do
145
- # it should do that to ensure the progress bar is printed
146
- scan = ProxiedTableScan.new Session.new, 'extender_no_record'
147
- scan.should_receive(:update_progress).at_least(:once)
148
- scan.run {|_, _|}
149
- end
150
- end
151
-
@@ -1,197 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper.rb'
2
-
3
- include RR
4
-
5
- describe ProxyBlockCursor do
6
- before(:each) do
7
- @session = create_mock_proxy_connection 'dummy_table', ['dummy_id']
8
- @cursor = ProxyBlockCursor.new @session, 'dummy_table'
9
- end
10
-
11
- it "initialize should super to ProxyCursor" do
12
- @cursor.table.should == 'dummy_table'
13
- end
14
-
15
- it "next? should return true if there is an already loaded unprocessed row" do
16
- @cursor.last_row = :dummy_row
17
- @cursor.next?.should be_true
18
- end
19
-
20
- it "next? should return true if the database cursor has more rows" do
21
- table_cursor = mock("DBCursor")
22
- table_cursor.should_receive(:next?).and_return(true)
23
- @cursor.cursor = table_cursor
24
-
25
- @cursor.next?.should be_true
26
- end
27
-
28
- it "next? should return false if there are no loaded or unloaded unprocessed rows" do
29
- table_cursor = mock("DBCursor")
30
- table_cursor.should_receive(:next?).and_return(false)
31
- @cursor.cursor = table_cursor
32
-
33
- @cursor.next?.should be_false
34
- end
35
-
36
- it "next_row should return last loaded unprocessed row or nil if there is none" do
37
- @cursor.last_row = :dummy_row
38
-
39
- @cursor.next_row.should == :dummy_row
40
- @cursor.last_row.should be_nil
41
- end
42
-
43
- it "next_row should return next row in database if there is no loaded unprocessed row available" do
44
- table_cursor = mock("DBCursor")
45
- table_cursor.should_receive(:next_row).and_return(:dummy_row)
46
- @cursor.cursor = table_cursor
47
-
48
- @cursor.next_row.should == :dummy_row
49
- end
50
-
51
- it "reset_checksum should create a new empty SHA1 digest" do
52
- @cursor.digest = :dummy_digest
53
- @cursor.reset_checksum
54
- @cursor.digest.should be_an_instance_of(Digest::SHA1)
55
- end
56
-
57
- it "reset_checksum should reset block variables" do
58
- @cursor.reset_checksum
59
- @cursor.row_checksums.should == []
60
- @cursor.current_row_cache_size.should == 0
61
- @cursor.row_cache.should == {}
62
-
63
- end
64
-
65
- it "update_checksum should update the existing digests" do
66
- dummy_row1 = {'dummy_id' => 'dummy_value1'}
67
- dummy_row2 = {'dummy_id' => 'dummy_value2'}
68
-
69
- @cursor.reset_checksum
70
- @cursor.update_checksum dummy_row1
71
- @cursor.update_checksum dummy_row2
72
-
73
- @cursor.current_checksum.should == Digest::SHA1.hexdigest(Marshal.dump(dummy_row1) + Marshal.dump(dummy_row2))
74
- @cursor.row_checksums.should == [
75
- {:row_keys => dummy_row1, :checksum => Digest::SHA1.hexdigest(Marshal.dump(dummy_row1))},
76
- {:row_keys => dummy_row2, :checksum => Digest::SHA1.hexdigest(Marshal.dump(dummy_row2))},
77
- ]
78
-
79
- @cursor.row_cache.should == {
80
- Digest::SHA1.hexdigest(Marshal.dump(dummy_row1)) => Marshal.dump(dummy_row1),
81
- Digest::SHA1.hexdigest(Marshal.dump(dummy_row2)) => Marshal.dump(dummy_row2)
82
- }
83
- end
84
-
85
- it "retrieve_row_cache should retrieve the specified elements" do
86
- @cursor.row_cache = {'dummy_checksum' => 'bla'}
87
- @cursor.retrieve_row_cache(['non_cached_row_checksum', 'dummy_checksum']).should ==
88
- {'dummy_checksum' => 'bla'}
89
- end
90
-
91
- it "current_checksum should return the current checksum" do
92
- digest = mock("Digest")
93
- digest.should_receive(:hexdigest).and_return(:dummy_checksum)
94
- @cursor.digest = digest
95
-
96
- @cursor.current_checksum.should == :dummy_checksum
97
- end
98
-
99
- it "checksum should reset the current digest" do
100
- @cursor.reset_checksum # need to call it now so that for the call to checksum it can be mocked
101
- @cursor.should_receive(:reset_checksum)
102
- @cursor.should_receive(:next?).and_return(false)
103
- @cursor.checksum :proxy_block_size => 1
104
- end
105
-
106
- it "checksum should complain if neither :proxy_block_size nor :max_row are provided" do
107
- lambda {@cursor.checksum}.should raise_error(
108
- RuntimeError, 'options must include either :proxy_block_size or :max_row')
109
- end
110
-
111
- it "checksum should verify options" do
112
- lambda {@cursor.checksum}.should raise_error(
113
- RuntimeError, 'options must include either :proxy_block_size or :max_row')
114
- lambda {@cursor.checksum(:proxy_block_size => 0)}.should raise_error(
115
- RuntimeError, ':proxy_block_size must be greater than 0')
116
- end
117
-
118
- it "checksum should read maximum :proxy_block_size rows" do
119
- session = ProxyConnection.new proxied_config.left
120
-
121
- cursor = ProxyBlockCursor.new session, 'scanner_records'
122
- cursor.prepare_fetch
123
-
124
- last_row, = cursor.checksum :proxy_block_size => 2
125
- last_row.should == {'id' => 2}
126
-
127
- last_row, = cursor.checksum :proxy_block_size => 1000
128
- last_row.should == {'id' => 5}
129
- end
130
-
131
- it "checksum should read up to the specified :max_row" do
132
- session = ProxyConnection.new proxied_config.left
133
-
134
- cursor = ProxyBlockCursor.new session, 'scanner_records'
135
- cursor.prepare_fetch
136
-
137
- last_row, = cursor.checksum :max_row => {'id' => 2}
138
- last_row.should == {'id' => 2}
139
- last_row, = cursor.checksum :max_row => {'id' => 1000}
140
- last_row.should == {'id' => 5}
141
- end
142
-
143
- it "checksum called with :proxy_block_size should return the correct checksum" do
144
- session = ProxyConnection.new proxied_config.left
145
-
146
- cursor = ProxyBlockCursor.new session, 'scanner_records'
147
- cursor.prepare_fetch
148
-
149
- last_row , checksum = cursor.checksum :proxy_block_size => 2
150
-
151
- expected_checksum = Digest::SHA1.hexdigest(
152
- Marshal.dump('id' => 1, 'name' => 'Alice - exists in both databases') +
153
- Marshal.dump('id' => 2, 'name' => 'Bob - left database version')
154
- )
155
-
156
- checksum.should == expected_checksum
157
- end
158
-
159
- it "checksum called with :max_row should return the correct checksum" do
160
- session = ProxyConnection.new proxied_config.left
161
-
162
- cursor = ProxyBlockCursor.new session, 'scanner_records'
163
- cursor.prepare_fetch
164
-
165
- last_row , checksum = cursor.checksum :max_row => {'id' => 2}
166
-
167
- expected_checksum = Digest::SHA1.hexdigest(
168
- Marshal.dump('id' => 1, 'name' => 'Alice - exists in both databases') +
169
- Marshal.dump('id' => 2, 'name' => 'Bob - left database version')
170
- )
171
-
172
- checksum.should == expected_checksum
173
- end
174
-
175
- it "checksum called with :proxy_block_size should return the correct row count" do
176
- session = ProxyConnection.new proxied_config.left
177
-
178
- cursor = ProxyBlockCursor.new session, 'scanner_records'
179
- cursor.prepare_fetch
180
-
181
- _ , _, row_count = cursor.checksum :proxy_block_size => 2
182
-
183
- row_count.should == 2
184
- end
185
-
186
- it "checksum called with :max_row should return the correct row count" do
187
- session = ProxyConnection.new proxied_config.left
188
-
189
- cursor = ProxyBlockCursor.new session, 'scanner_records'
190
- cursor.prepare_fetch
191
-
192
- _ , _, row_count = cursor.checksum :max_row => {'id' => 2}
193
-
194
- row_count.should == 2
195
- end
196
-
197
- end