rubyrep 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. data/History.txt +4 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +137 -0
  4. data/README.txt +37 -0
  5. data/Rakefile +30 -0
  6. data/bin/rubyrep +8 -0
  7. data/config/hoe.rb +72 -0
  8. data/config/mysql_config.rb +25 -0
  9. data/config/postgres_config.rb +21 -0
  10. data/config/proxied_test_config.rb +14 -0
  11. data/config/redmine_config.rb +17 -0
  12. data/config/rep_config.rb +20 -0
  13. data/config/requirements.rb +32 -0
  14. data/config/test_config.rb +20 -0
  15. data/lib/rubyrep/base_runner.rb +195 -0
  16. data/lib/rubyrep/command_runner.rb +144 -0
  17. data/lib/rubyrep/committers/buffered_committer.rb +140 -0
  18. data/lib/rubyrep/committers/committers.rb +146 -0
  19. data/lib/rubyrep/configuration.rb +240 -0
  20. data/lib/rubyrep/connection_extenders/connection_extenders.rb +133 -0
  21. data/lib/rubyrep/connection_extenders/jdbc_extender.rb +284 -0
  22. data/lib/rubyrep/connection_extenders/mysql_extender.rb +168 -0
  23. data/lib/rubyrep/connection_extenders/postgresql_extender.rb +261 -0
  24. data/lib/rubyrep/database_proxy.rb +52 -0
  25. data/lib/rubyrep/direct_table_scan.rb +75 -0
  26. data/lib/rubyrep/generate_runner.rb +105 -0
  27. data/lib/rubyrep/initializer.rb +39 -0
  28. data/lib/rubyrep/logged_change.rb +326 -0
  29. data/lib/rubyrep/proxied_table_scan.rb +171 -0
  30. data/lib/rubyrep/proxy_block_cursor.rb +145 -0
  31. data/lib/rubyrep/proxy_connection.rb +318 -0
  32. data/lib/rubyrep/proxy_cursor.rb +44 -0
  33. data/lib/rubyrep/proxy_row_cursor.rb +43 -0
  34. data/lib/rubyrep/proxy_runner.rb +89 -0
  35. data/lib/rubyrep/replication_difference.rb +91 -0
  36. data/lib/rubyrep/replication_extenders/mysql_replication.rb +271 -0
  37. data/lib/rubyrep/replication_extenders/postgresql_replication.rb +204 -0
  38. data/lib/rubyrep/replication_extenders/replication_extenders.rb +26 -0
  39. data/lib/rubyrep/replication_helper.rb +104 -0
  40. data/lib/rubyrep/replication_initializer.rb +307 -0
  41. data/lib/rubyrep/replication_run.rb +48 -0
  42. data/lib/rubyrep/replication_runner.rb +138 -0
  43. data/lib/rubyrep/replicators/replicators.rb +37 -0
  44. data/lib/rubyrep/replicators/two_way_replicator.rb +334 -0
  45. data/lib/rubyrep/scan_progress_printers/progress_bar.rb +65 -0
  46. data/lib/rubyrep/scan_progress_printers/scan_progress_printers.rb +65 -0
  47. data/lib/rubyrep/scan_report_printers/scan_detail_reporter.rb +111 -0
  48. data/lib/rubyrep/scan_report_printers/scan_report_printers.rb +67 -0
  49. data/lib/rubyrep/scan_report_printers/scan_summary_reporter.rb +75 -0
  50. data/lib/rubyrep/scan_runner.rb +25 -0
  51. data/lib/rubyrep/session.rb +177 -0
  52. data/lib/rubyrep/sync_helper.rb +111 -0
  53. data/lib/rubyrep/sync_runner.rb +31 -0
  54. data/lib/rubyrep/syncers/syncers.rb +112 -0
  55. data/lib/rubyrep/syncers/two_way_syncer.rb +174 -0
  56. data/lib/rubyrep/table_scan.rb +54 -0
  57. data/lib/rubyrep/table_scan_helper.rb +38 -0
  58. data/lib/rubyrep/table_sorter.rb +70 -0
  59. data/lib/rubyrep/table_spec_resolver.rb +136 -0
  60. data/lib/rubyrep/table_sync.rb +68 -0
  61. data/lib/rubyrep/trigger_mode_switcher.rb +63 -0
  62. data/lib/rubyrep/type_casting_cursor.rb +31 -0
  63. data/lib/rubyrep/uninstall_runner.rb +92 -0
  64. data/lib/rubyrep/version.rb +9 -0
  65. data/lib/rubyrep.rb +68 -0
  66. data/script/destroy +14 -0
  67. data/script/generate +14 -0
  68. data/script/txt2html +74 -0
  69. data/setup.rb +1585 -0
  70. data/sims/performance/big_rep_spec.rb +100 -0
  71. data/sims/performance/big_scan_spec.rb +57 -0
  72. data/sims/performance/big_sync_spec.rb +141 -0
  73. data/sims/performance/performance.rake +228 -0
  74. data/sims/sim_helper.rb +24 -0
  75. data/spec/base_runner_spec.rb +218 -0
  76. data/spec/buffered_committer_spec.rb +271 -0
  77. data/spec/command_runner_spec.rb +145 -0
  78. data/spec/committers_spec.rb +174 -0
  79. data/spec/configuration_spec.rb +198 -0
  80. data/spec/connection_extender_interface_spec.rb +138 -0
  81. data/spec/connection_extenders_registration_spec.rb +129 -0
  82. data/spec/database_proxy_spec.rb +48 -0
  83. data/spec/database_rake_spec.rb +40 -0
  84. data/spec/db_specific_connection_extenders_spec.rb +34 -0
  85. data/spec/db_specific_replication_extenders_spec.rb +38 -0
  86. data/spec/direct_table_scan_spec.rb +61 -0
  87. data/spec/generate_runner_spec.rb +84 -0
  88. data/spec/initializer_spec.rb +46 -0
  89. data/spec/logged_change_spec.rb +480 -0
  90. data/spec/postgresql_replication_spec.rb +48 -0
  91. data/spec/postgresql_support_spec.rb +57 -0
  92. data/spec/progress_bar_spec.rb +77 -0
  93. data/spec/proxied_table_scan_spec.rb +151 -0
  94. data/spec/proxy_block_cursor_spec.rb +197 -0
  95. data/spec/proxy_connection_spec.rb +399 -0
  96. data/spec/proxy_cursor_spec.rb +56 -0
  97. data/spec/proxy_row_cursor_spec.rb +66 -0
  98. data/spec/proxy_runner_spec.rb +70 -0
  99. data/spec/replication_difference_spec.rb +160 -0
  100. data/spec/replication_extender_interface_spec.rb +365 -0
  101. data/spec/replication_extenders_spec.rb +32 -0
  102. data/spec/replication_helper_spec.rb +121 -0
  103. data/spec/replication_initializer_spec.rb +477 -0
  104. data/spec/replication_run_spec.rb +166 -0
  105. data/spec/replication_runner_spec.rb +213 -0
  106. data/spec/replicators_spec.rb +31 -0
  107. data/spec/rubyrep_spec.rb +8 -0
  108. data/spec/scan_detail_reporter_spec.rb +119 -0
  109. data/spec/scan_progress_printers_spec.rb +68 -0
  110. data/spec/scan_report_printers_spec.rb +67 -0
  111. data/spec/scan_runner_spec.rb +50 -0
  112. data/spec/scan_summary_reporter_spec.rb +61 -0
  113. data/spec/session_spec.rb +212 -0
  114. data/spec/spec.opts +1 -0
  115. data/spec/spec_helper.rb +295 -0
  116. data/spec/sync_helper_spec.rb +157 -0
  117. data/spec/sync_runner_spec.rb +78 -0
  118. data/spec/syncers_spec.rb +171 -0
  119. data/spec/table_scan_helper_spec.rb +29 -0
  120. data/spec/table_scan_spec.rb +49 -0
  121. data/spec/table_sorter_spec.rb +31 -0
  122. data/spec/table_spec_resolver_spec.rb +102 -0
  123. data/spec/table_sync_spec.rb +84 -0
  124. data/spec/trigger_mode_switcher_spec.rb +83 -0
  125. data/spec/two_way_replicator_spec.rb +551 -0
  126. data/spec/two_way_syncer_spec.rb +256 -0
  127. data/spec/type_casting_cursor_spec.rb +50 -0
  128. data/spec/uninstall_runner_spec.rb +86 -0
  129. data/tasks/database.rake +439 -0
  130. data/tasks/deployment.rake +29 -0
  131. data/tasks/environment.rake +9 -0
  132. data/tasks/java.rake +37 -0
  133. data/tasks/redmine_test.rake +47 -0
  134. data/tasks/rspec.rake +68 -0
  135. data/tasks/rubyrep.tailor +18 -0
  136. data/tasks/stats.rake +19 -0
  137. data/tasks/task_helper.rb +20 -0
  138. data.tar.gz.sig +0 -0
  139. metadata +243 -0
  140. metadata.gz.sig +0 -0
@@ -0,0 +1,218 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ include RR
4
+
5
+ describe BaseRunner do
6
+ before(:each) do
7
+ end
8
+
9
+ it "process_options should make options as nil and teturn status as 1 if command line parameters are unknown" do
10
+ # also verify that an error message is printed
11
+ $stderr.should_receive(:puts).any_number_of_times
12
+ runner = BaseRunner.new
13
+ status = runner.process_options ["--nonsense"]
14
+ runner.options.should == nil
15
+ status.should == 1
16
+ end
17
+
18
+ it "process_options should make options as nil and return status as 1 if config option is not given" do
19
+ # also verify that an error message is printed
20
+ $stderr.should_receive(:puts).any_number_of_times
21
+ runner = BaseRunner.new
22
+ status = runner.process_options ["table"]
23
+ runner.options.should == nil
24
+ status.should == 1
25
+ end
26
+
27
+ it "process_options should show the summary description (if usage is printed)" do
28
+ org_stderr = $stderr
29
+ $stderr = StringIO.new
30
+ begin
31
+ base_runner = BaseRunner.new
32
+ base_runner.should_receive(:summary_description).
33
+ and_return("my_summary_description")
34
+ base_runner.process_options ["--help"]
35
+ $stderr.string.should =~ /my_summary_description/
36
+ ensure
37
+ $stderr = org_stderr
38
+ end
39
+ end
40
+
41
+ it "process_options should make options as nil and return status as 0 if command line includes '--help'" do
42
+ # also verify that the help message is printed
43
+ $stderr.should_receive(:puts)
44
+ runner = BaseRunner.new
45
+ status = runner.process_options ["--help"]
46
+ runner.options.should == nil
47
+ status.should == 0
48
+ end
49
+
50
+ it "process_options should set the correct options" do
51
+ runner = BaseRunner.new
52
+ runner.process_options ["-c", "config_path", "table_spec1", "table_spec2"]
53
+ runner.options[:config_file].should == 'config_path'
54
+ runner.options[:table_specs].should == ['table_spec1', 'table_spec2']
55
+ end
56
+
57
+ it "process_options should add runner specific options" do
58
+ BaseRunner.any_instance_should_receive(:add_specific_options) do
59
+ runner = BaseRunner.new
60
+ runner.process_options ["-c", "config_path"]
61
+ end
62
+ end
63
+
64
+ it "process_options should assign the command line specified report printer" do
65
+ org_printers = ScanReportPrinters.printers
66
+ begin
67
+ ScanReportPrinters.instance_eval { class_variable_set :@@report_printers, nil }
68
+
69
+ ScanReportPrinters.register :dummy_printer_class, "-y", "--printer_y[=arg]", "description"
70
+
71
+ runner = BaseRunner.new
72
+ runner.stub!(:session)
73
+ runner.process_options ["-c", "config_path", "--printer_y=arg_for_y", "table_spec"]
74
+ runner.report_printer_class.should == :dummy_printer_class
75
+ runner.report_printer_arg.should == 'arg_for_y'
76
+ ensure
77
+ ScanReportPrinters.instance_eval { class_variable_set :@@report_printers, org_printers }
78
+ end
79
+ end
80
+
81
+ it "process_options should assign the command line specified progress printer class" do
82
+ org_printers = ScanProgressPrinters.printers
83
+ begin
84
+ ScanProgressPrinters.instance_eval { class_variable_set :@@progress_printers, nil }
85
+
86
+ printer_y_class = mock("printer_y_class")
87
+ printer_y_class.should_receive(:arg=)
88
+
89
+ ScanProgressPrinters.register :printer_y_key, printer_y_class, "-y", "--printer_y[=arg]", "description"
90
+
91
+ runner = BaseRunner.new
92
+ runner.process_options ["-c", "config_path", "-y", "arg_for_y"]
93
+ runner.progress_printer.should == printer_y_class
94
+ ensure
95
+ ScanProgressPrinters.instance_eval { class_variable_set :@@progress_printers, org_printers }
96
+ end
97
+ end
98
+
99
+ it "add_specific_options should not do anything" do
100
+ BaseRunner.new.add_specific_options nil
101
+ end
102
+
103
+ it "create_processor should not do anything" do
104
+ BaseRunner.new.create_processor "dummy_left_table", "dummy_right_table"
105
+ end
106
+
107
+ it "prepare_table_pairs should return the provided table pairs unmodied" do
108
+ BaseRunner.new.prepare_table_pairs(:dummy_table_pairs).
109
+ should == :dummy_table_pairs
110
+ end
111
+
112
+ it "run should not start a scan if the command line is invalid" do
113
+ $stderr.should_receive(:puts).any_number_of_times
114
+ BaseRunner.any_instance_should_not_receive(:execute) {
115
+ BaseRunner.run(["--nonsense"])
116
+ }
117
+ end
118
+
119
+ it "run should start a scan if the command line is correct" do
120
+ BaseRunner.any_instance_should_receive(:execute) {
121
+ BaseRunner.run(["--config=path", "table"])
122
+ }
123
+ end
124
+
125
+ it "report_printer should create and return the printer as specified per command line options" do
126
+ printer_class = mock("printer class")
127
+ printer_class.should_receive(:new).with(:dummy_session, :dummy_arg).and_return(:dummy_printer)
128
+ runner = BaseRunner.new
129
+ runner.stub!(:session).and_return(:dummy_session)
130
+ runner.report_printer_class = printer_class
131
+ runner.report_printer_arg = :dummy_arg
132
+ runner.report_printer.should == :dummy_printer
133
+ runner.report_printer # ensure the printer object is cached
134
+ end
135
+
136
+ it "report_printer should return the ScanSummaryReporter if no other printer was chosen" do
137
+ runner = BaseRunner.new
138
+ runner.stub!(:session)
139
+ runner.report_printer.should be_an_instance_of(ScanReportPrinters::ScanSummaryReporter)
140
+ end
141
+
142
+ it "progress_printer should return the config file specified printer if none was give via command line" do
143
+ runner = BaseRunner.new
144
+ runner.options = {
145
+ :config_file => "#{File.dirname(__FILE__)}/../config/test_config.rb",
146
+ :table_specs => ["scanner_records", "extender_one_record"]
147
+ }
148
+ config_specified_printer_key = Session.new(standard_config).configuration.options[:scan_progress_printer]
149
+ config_specified_printer_class = ScanProgressPrinters.
150
+ printers[config_specified_printer_key][:printer_class]
151
+ runner.progress_printer.should == config_specified_printer_class
152
+ end
153
+
154
+ it "signal_scanning_completion should signal completion if the scan report printer supports it" do
155
+ printer = mock("printer")
156
+ printer.should_receive(:scanning_finished)
157
+ printer.should_receive(:respond_to?).with(:scanning_finished).and_return(true)
158
+ runner = BaseRunner.new
159
+ runner.stub!(:report_printer).and_return(printer)
160
+ runner.signal_scanning_completion
161
+ end
162
+
163
+ it "signal_scanning_completion should not signal completion if the scan report printer doesn't supports it" do
164
+ printer = mock("printer")
165
+ printer.should_not_receive(:scanning_finished)
166
+ printer.should_receive(:respond_to?).with(:scanning_finished).and_return(false)
167
+ runner = BaseRunner.new
168
+ runner.stub!(:report_printer).and_return(printer)
169
+ runner.signal_scanning_completion
170
+ end
171
+
172
+ it "execute should process the specified tables" do
173
+ org_stdout = $stdout
174
+ $stdout = StringIO.new
175
+ begin
176
+ runner = BaseRunner.new
177
+ runner.options = {
178
+ :config_file => "#{File.dirname(__FILE__)}/../config/test_config.rb",
179
+ :table_specs => ["scanner_records", "extender_one_record"]
180
+ }
181
+
182
+ # create and install a dummy processor
183
+ processor = mock("dummy_processor")
184
+ processor.should_receive(:run).twice.and_yield(:left, :dummy_row)
185
+
186
+ # verify that the scanner receives the progress printer
187
+ runner.stub!(:progress_printer).and_return(:dummy_printer_class)
188
+ processor.should_receive(:progress_printer=).twice.with(:dummy_printer_class)
189
+
190
+ runner.should_receive(:create_processor).twice.and_return(processor)
191
+
192
+ # verify that the scanning_completion signal is given to scan report printer
193
+ runner.should_receive :signal_scanning_completion
194
+
195
+ runner.execute
196
+
197
+ # verify that rubyrep infrastructure tables were excluded
198
+ runner.session.configuration.excluded_table_specs.include?(/^rr_.*/).should be_true
199
+
200
+ $stdout.string.should =~ /scanner_records.* 1\n/
201
+ $stdout.string.should =~ /extender_one_record.* 1\n/
202
+ ensure
203
+ $stdout = org_stdout
204
+ end
205
+ end
206
+
207
+ it "table_pairs should return the prepared table pairs" do
208
+ runner = BaseRunner.new
209
+ runner.options = {
210
+ :config_file => "#{File.dirname(__FILE__)}/../config/test_config.rb",
211
+ :table_specs => ['scanner_records']
212
+ }
213
+ runner.should_receive(:prepare_table_pairs).with([
214
+ {:left => 'scanner_records', :right => 'scanner_records'},
215
+ ]).and_return(:dummy_table_pairs)
216
+ runner.table_pairs.should == :dummy_table_pairs
217
+ end
218
+ end
@@ -0,0 +1,271 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ include RR
4
+
5
+ describe Committers::BufferedCommitter do
6
+ before(:each) do
7
+ Initializer.configuration = standard_config
8
+ end
9
+
10
+ it "should register itself" do
11
+ Committers.committers[:buffered_commit].should == Committers::BufferedCommitter
12
+ end
13
+
14
+ # Stubs out the starting of transactions in the given Session.
15
+ def stub_begin_transaction(session)
16
+ session.left.stub! :begin_db_transaction
17
+ session.right.stub! :begin_db_transaction
18
+ end
19
+
20
+ # Stubs out the executing of SQL statements for the given Session.
21
+ def stub_execute(session)
22
+ session.left.stub! :execute
23
+ session.right.stub! :execute
24
+ end
25
+
26
+ it "trigger_mode_switcher should return and if necessary create the trigger mode switcher" do
27
+ session = Session.new
28
+ stub_begin_transaction session
29
+ stub_execute session
30
+ committer = Committers::BufferedCommitter.new(session)
31
+ switcher = committer.trigger_mode_switcher
32
+ switcher.should be_an_instance_of(TriggerModeSwitcher)
33
+
34
+ committer.trigger_mode_switcher.should == switcher # ensure it is only created one
35
+ end
36
+
37
+ it "exclude_rr_activity should exclude the rubyrep activity for the specified table" do
38
+ session = Session.new
39
+ stub_begin_transaction session
40
+ stub_execute session
41
+ committer = Committers::BufferedCommitter.new(session)
42
+ committer.trigger_mode_switcher.should_receive(:exclude_rr_activity).with(:left, 'dummy_table')
43
+ committer.exclude_rr_activity :left, 'dummy_table'
44
+ end
45
+
46
+ it "activity_marker_table should return the correct table name" do
47
+ config = deep_copy(standard_config)
48
+ config.options[:rep_prefix] = 'rx'
49
+ session = Session.new config
50
+ stub_begin_transaction session
51
+ stub_execute session
52
+ committer = Committers::BufferedCommitter.new(session)
53
+ committer.activity_marker_table.should == 'rx_running_flags'
54
+ end
55
+
56
+ it "maintain_activity_status should return true if activity marker table exists" do
57
+ session = Session.new
58
+ stub_begin_transaction session
59
+ stub_execute session
60
+ committer = Committers::BufferedCommitter.new(session)
61
+ committer.maintain_activity_status?.should be_true
62
+ end
63
+
64
+ it "maintain_activity_status should return false if activity marker does not exist" do
65
+ config = deep_copy(standard_config)
66
+ config.options[:rep_prefix] = 'rx'
67
+ session = Session.new config
68
+ stub_begin_transaction session
69
+ stub_execute session
70
+ committer = Committers::BufferedCommitter.new(session)
71
+ committer.maintain_activity_status?.should be_false
72
+ end
73
+
74
+ it "commit_frequency should return the configured commit frequency" do
75
+ config = deep_copy(standard_config)
76
+ config.options[:commit_frequency] = 5
77
+ session = Session.new config
78
+ stub_begin_transaction session
79
+ stub_execute session
80
+ committer = Committers::BufferedCommitter.new(session)
81
+ committer.commit_frequency.should == 5
82
+ end
83
+
84
+ it "commit_frequency should return the the default commit frequency if nothing else is configured" do
85
+ config = deep_copy(standard_config)
86
+ config.options.delete :commit_frequency
87
+ session = Session.new config
88
+ stub_begin_transaction session
89
+ stub_execute session
90
+ committer = Committers::BufferedCommitter.new(session)
91
+ committer.commit_frequency.should == Committers::BufferedCommitter::DEFAULT_COMMIT_FREQUENCY
92
+ end
93
+
94
+ it "initialize should start transactions and setup rubyrep activity filtering" do
95
+ session = nil
96
+ begin
97
+ session = Session.new
98
+ session.left.should_receive(:begin_db_transaction)
99
+ session.right.should_receive(:begin_db_transaction)
100
+ session.left.select_one("select * from rr_running_flags").should be_nil # verify starting situation
101
+ committer = Committers::BufferedCommitter.new(session)
102
+
103
+ # rubyrep activity should be marked
104
+ session.left.select_one("select * from rr_running_flags").should_not be_nil
105
+ session.right.select_one("select * from rr_running_flags").should_not be_nil
106
+ ensure
107
+ session.left.execute "delete from rr_running_flags" if session
108
+ session.right.execute "delete from rr_running_flags" if session
109
+ end
110
+ end
111
+
112
+ it "commit_db_transactions should commit the transactions in both databases" do
113
+ session = Session.new
114
+ stub_begin_transaction session
115
+ stub_execute session
116
+ committer = Committers::BufferedCommitter.new(session)
117
+
118
+ session.left.should_receive(:commit_db_transaction)
119
+ session.right.should_receive(:commit_db_transaction)
120
+ committer.commit_db_transactions
121
+ end
122
+
123
+ it "commit_db_transactions should clear the activity marker table" do
124
+ session = Session.new
125
+ stub_begin_transaction session
126
+ session.left.stub!(:commit_db_transaction)
127
+ session.right.stub!(:commit_db_transaction)
128
+ stub_execute session
129
+ committer = Committers::BufferedCommitter.new(session)
130
+
131
+ session.left.should_receive(:execute).with("delete from rr_running_flags")
132
+ session.right.should_receive(:execute).with("delete from rr_running_flags")
133
+ committer.commit_db_transactions
134
+ end
135
+
136
+ it "commit_db_transactions should not clear the activity marker table if it doesn't exist" do
137
+ config = deep_copy(standard_config)
138
+ config.options[:rep_prefix] = 'rx'
139
+ session = Session.new config
140
+ stub_begin_transaction session
141
+ session.left.stub!(:commit_db_transaction)
142
+ session.right.stub!(:commit_db_transaction)
143
+ stub_execute session
144
+ committer = Committers::BufferedCommitter.new(session)
145
+
146
+ session.left.should_not_receive(:execute)
147
+ session.right.should_not_receive(:execute)
148
+ committer.commit_db_transactions
149
+ end
150
+
151
+ it "begin_db_transactions should begin new transactions in both databases" do
152
+ session = Session.new
153
+ stub_begin_transaction session
154
+ stub_execute session
155
+ committer = Committers::BufferedCommitter.new(session)
156
+
157
+ session.left.should_receive(:begin_db_transaction)
158
+ session.right.should_receive(:begin_db_transaction)
159
+ committer.begin_db_transactions
160
+ end
161
+
162
+ it "begin_db_transactions should insert a record into the activity marker table" do
163
+ session = Session.new
164
+ stub_begin_transaction session
165
+ stub_execute session
166
+ committer = Committers::BufferedCommitter.new(session)
167
+
168
+ session.left.should_receive(:execute).with("insert into rr_running_flags values(1)")
169
+ session.right.should_receive(:execute).with("insert into rr_running_flags values(1)")
170
+ committer.begin_db_transactions
171
+ end
172
+
173
+ it "begin_db_transactions should not clear the activity marker table if it doesn't exist" do
174
+ config = deep_copy(standard_config)
175
+ config.options[:rep_prefix] = 'rx'
176
+ session = Session.new config
177
+ stub_begin_transaction session
178
+ stub_execute session
179
+ committer = Committers::BufferedCommitter.new(session)
180
+
181
+ session.left.should_not_receive(:execute)
182
+ session.right.should_not_receive(:execute)
183
+ committer.begin_db_transactions
184
+ end
185
+
186
+ it "rollback_db_transactions should roll back the transactions in both databases" do
187
+ session = Session.new
188
+ stub_begin_transaction session
189
+ stub_execute session
190
+ committer = Committers::BufferedCommitter.new(session)
191
+
192
+ session.left.should_receive(:rollback_db_transaction)
193
+ session.right.should_receive(:rollback_db_transaction)
194
+ committer.rollback_db_transactions
195
+ end
196
+
197
+ it "commit should only commit and start new transactions if the specified number of changes have been executed" do
198
+ config = deep_copy(standard_config)
199
+ config.options[:commit_frequency] = 2
200
+ session = Session.new config
201
+ stub_begin_transaction session
202
+ stub_execute session
203
+ committer = Committers::BufferedCommitter.new(session)
204
+
205
+ committer.should_not_receive(:commit_db_transactions).twice
206
+ committer.should_not_receive(:begin_db_transactions).twice
207
+ 4.times {committer.commit}
208
+ end
209
+
210
+ it "insert_record should commit" do
211
+ session = Session.new
212
+ stub_begin_transaction session
213
+ stub_execute session
214
+ committer = Committers::BufferedCommitter.new(session)
215
+
216
+ committer.should_receive(:exclude_rr_activity).with(:right, 'right_table').ordered
217
+ session.right.should_receive(:insert_record).with('right_table', :dummy_values).ordered
218
+ committer.should_receive(:commit).ordered
219
+
220
+ committer.insert_record(:right, 'right_table', :dummy_values)
221
+ end
222
+
223
+ it "update_record should commit" do
224
+ session = Session.new
225
+ stub_begin_transaction session
226
+ stub_execute session
227
+ committer = Committers::BufferedCommitter.new(session)
228
+
229
+ committer.should_receive(:exclude_rr_activity).with(:right, 'right_table').ordered
230
+ session.right.should_receive(:update_record).with('right_table', :dummy_values, :dummy_org_key).ordered
231
+ committer.should_receive(:commit).ordered
232
+
233
+ committer.update_record(:right, 'right_table', :dummy_values, :dummy_org_key)
234
+ end
235
+
236
+ it "delete_record should commit" do
237
+ session = Session.new
238
+ stub_begin_transaction session
239
+ stub_execute session
240
+ committer = Committers::BufferedCommitter.new(session)
241
+
242
+ committer.should_receive(:exclude_rr_activity).with(:right, 'right_table').ordered
243
+ session.right.should_receive(:delete_record).with('right_table', :dummy_values).ordered
244
+ committer.should_receive(:commit).ordered
245
+
246
+ committer.delete_record(:right, 'right_table', :dummy_values)
247
+ end
248
+
249
+ it "finalize should commit the transactions if called with success = true" do
250
+ session = Session.new
251
+ stub_begin_transaction session
252
+ stub_execute session
253
+ committer = Committers::BufferedCommitter.new(session)
254
+
255
+ committer.should_receive(:commit_db_transactions)
256
+
257
+ committer.finalize true
258
+ end
259
+
260
+ it "finalize should rollbackup the transactions if called with success = false" do
261
+ session = Session.new
262
+ stub_begin_transaction session
263
+ stub_execute session
264
+ committer = Committers::BufferedCommitter.new(session)
265
+
266
+ committer.should_receive(:rollback_db_transactions)
267
+
268
+ committer.finalize false
269
+ end
270
+ end
271
+
@@ -0,0 +1,145 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ include RR
4
+
5
+ describe CommandRunner do
6
+ before(:each) do
7
+ @org_commands = CommandRunner.commands
8
+ CommandRunner.instance_variable_set :@commands, nil
9
+ end
10
+
11
+ after(:each) do
12
+ CommandRunner.instance_variable_set :@commands, @org_commands
13
+ end
14
+
15
+ it "show_version should print the version string" do
16
+ $stdout.should_receive(:puts).with(/rubyrep version ([0-9]+\.){2}[0-9]+/)
17
+ CommandRunner.show_version
18
+ end
19
+
20
+ it "register should register commands, commands should return it" do
21
+ CommandRunner.register :bla => :bla_command
22
+ CommandRunner.register :blub => :blub_command
23
+ CommandRunner.commands.should == {
24
+ :bla => :bla_command,
25
+ :blub => :blub_command
26
+ }
27
+ end
28
+
29
+ it "run should print a short help if --help is specified" do
30
+ org_stderr = $stderr
31
+ $stderr = StringIO.new
32
+ begin
33
+ CommandRunner.register 'c1' => {:description => 'desc 1'}, 'c2' => {:description => 'desc 2'}
34
+ CommandRunner.run(['--help'])
35
+ $stderr.string.should =~ /Usage/
36
+ $stderr.string.should =~ /c1.*desc 1\n/
37
+ $stderr.string.should =~ /c2.*desc 2\n/
38
+ ensure
39
+ $stderr = org_stderr
40
+ end
41
+ end
42
+
43
+ it "run should print help if no command line parameters are given" do
44
+ org_stderr = $stderr
45
+ $stderr = StringIO.new
46
+ begin
47
+ CommandRunner.run([]).should == 1
48
+ $stderr.string.should =~ /Available commands/
49
+ ensure
50
+ $stderr = org_stderr
51
+ end
52
+ end
53
+
54
+ it "run should print help if --help or help without further params is given" do
55
+ org_stderr = $stderr
56
+ $stderr = StringIO.new
57
+ begin
58
+ CommandRunner.run(['--help']).should == 0
59
+ $stderr.string.should =~ /Available commands/
60
+ $stderr = StringIO.new
61
+ CommandRunner.run(['help']).should == 0
62
+ $stderr.string.should =~ /Available commands/
63
+ ensure
64
+ $stderr = org_stderr
65
+ end
66
+ end
67
+
68
+ it "run should print version if --version is given" do
69
+ CommandRunner.should_receive(:show_version)
70
+ CommandRunner.run(['--version'])
71
+ end
72
+
73
+ it "run should call the specified command with the specified params" do
74
+ c = mock('dummy_command')
75
+ c.should_receive(:run).with(['param1', 'param2'])
76
+ CommandRunner.register 'dummy_command' => {:command => c}
77
+ CommandRunner.run(['dummy_command', 'param1', 'param2'])
78
+ end
79
+
80
+ it "run should print help if unknown command is given" do
81
+ org_stderr = $stderr
82
+ $stderr = StringIO.new
83
+ begin
84
+ CommandRunner.run('non-existing-command').should == 1
85
+ $stderr.string.should =~ /Available commands/
86
+ ensure
87
+ $stderr = org_stderr
88
+ end
89
+ end
90
+
91
+ it "run should print stacktrace if --verbose option is given" do
92
+ org_stderr = $stderr
93
+ $stderr = StringIO.new
94
+ begin
95
+ c = mock('dummy_command')
96
+ c.stub!(:run).and_return {raise 'bla'}
97
+ CommandRunner.register 'dummy_command' => {:command => c}
98
+ CommandRunner.run(['--verbose', 'dummy_command', '-c', 'non_existing_file']).should == 1
99
+ $stderr.string.should =~ /Exception caught/
100
+ $stderr.string.should =~ /command_runner.rb:[0-9]+:in /
101
+
102
+ # also verify that no stacktrace is printed if --verbose is not specified
103
+ $stderr = StringIO.new
104
+ CommandRunner.run(['dummy_command', '-c', 'non_existing_file']).should == 1
105
+ $stderr.string.should =~ /Exception caught/
106
+ $stderr.string.should_not =~ /command_runner.rb:[0-9]+:in /
107
+ ensure
108
+ $stderr = org_stderr
109
+ end
110
+ end
111
+
112
+ it "rubyrep should call CommandRunner#run" do
113
+ CommandRunner.should_receive(:run).with(ARGV).and_return(0)
114
+ Kernel.any_instance_should_receive(:exit) {
115
+ load File.dirname(__FILE__) + '/../bin/rubyrep'
116
+ }
117
+ end
118
+ end
119
+
120
+ describe HelpRunner do
121
+ it "should register itself" do
122
+ CommandRunner.commands['help'][:command].should == HelpRunner
123
+ CommandRunner.commands['help'][:description].should be_an_instance_of(String)
124
+ end
125
+
126
+ it "run should call help for the specified command" do
127
+ CommandRunner.should_receive(:run).with(['dummy_command', '--help'])
128
+ HelpRunner.run(['dummy_command'])
129
+ end
130
+
131
+ it "run should print help for itself if '--help' or 'help' is specified" do
132
+ org_stderr = $stderr
133
+ $stderr = StringIO.new
134
+ begin
135
+ HelpRunner.run(['--help'])
136
+ $stderr.string.should =~ /Shows the help for the specified command/
137
+
138
+ $stderr = StringIO.new
139
+ HelpRunner.run(['help'])
140
+ $stderr.string.should =~ /Shows the help for the specified command/
141
+ ensure
142
+ $stderr = org_stderr
143
+ end
144
+ end
145
+ end