lhm-shopify 3.4.0 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/lhm/chunker.rb +16 -1
- data/lib/lhm/cleanup/current.rb +3 -2
- data/lib/lhm/entangler.rb +2 -0
- data/lib/lhm/migrator.rb +2 -0
- data/lib/lhm/printer.rb +10 -6
- data/lib/lhm/version.rb +1 -1
- data/lib/lhm.rb +8 -4
- data/spec/integration/atomic_switcher_spec.rb +5 -5
- data/spec/integration/chunk_insert_spec.rb +1 -1
- data/spec/integration/chunker_spec.rb +10 -10
- data/spec/integration/cleanup_spec.rb +49 -38
- data/spec/integration/entangler_spec.rb +4 -4
- data/spec/integration/integration_helper.rb +3 -1
- data/spec/integration/lhm_spec.rb +40 -40
- data/spec/integration/lock_wait_timeout_spec.rb +2 -2
- data/spec/integration/locked_switcher_spec.rb +4 -4
- data/spec/integration/table_spec.rb +11 -19
- data/spec/unit/atomic_switcher_spec.rb +4 -6
- data/spec/unit/entangler_spec.rb +9 -9
- data/spec/unit/intersection_spec.rb +4 -4
- data/spec/unit/lhm_spec.rb +6 -6
- data/spec/unit/locked_switcher_spec.rb +13 -18
- data/spec/unit/migrator_spec.rb +17 -19
- data/spec/unit/printer_spec.rb +14 -26
- data/spec/unit/sql_helper_spec.rb +8 -12
- data/spec/unit/table_spec.rb +5 -5
- data/spec/unit/throttler_spec.rb +12 -12
- data/spec/unit/unit_helper.rb +13 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef0c285f7d63755816429aa2795220be251c0c93c4506f8255f7e547c074d574
|
4
|
+
data.tar.gz: 5de29d0b924375634c061a459837f0ea6a12d5ccf58226032ef25f708ef15628
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d24b1d78c6fdd67129ee91a01d043ccefb1f2e8c4b8322553f1c6cbfed6237105e58eb6ddab0e143869b813682ea6b3c25e5a40e66199f76adc0cc99a97050b
|
7
|
+
data.tar.gz: 327b3a438ac2fb1b0763396094baed303a2ecb9a37558295b8b516b089bcca73534102351281883679263f7e69647d1129941df4970d3abae004faf93d91db62
|
data/CHANGELOG.md
CHANGED
data/lib/lhm/chunker.rb
CHANGED
@@ -37,6 +37,8 @@ module Lhm
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def execute
|
40
|
+
@start_time = Time.now
|
41
|
+
|
40
42
|
return if @chunk_finder.table_empty?
|
41
43
|
@next_to_insert = @start
|
42
44
|
while @next_to_insert <= @limit || (@start == @limit)
|
@@ -47,6 +49,8 @@ module Lhm
|
|
47
49
|
affected_rows = ChunkInsert.new(@migration, @connection, bottom, top, @options).insert_and_return_count_of_rows_created
|
48
50
|
expected_rows = top - bottom + 1
|
49
51
|
|
52
|
+
rate_limited_log_progress
|
53
|
+
|
50
54
|
if affected_rows < expected_rows
|
51
55
|
raise_on_non_pk_duplicate_warning
|
52
56
|
end
|
@@ -54,8 +58,10 @@ module Lhm
|
|
54
58
|
if @throttler && affected_rows > 0
|
55
59
|
@throttler.run
|
56
60
|
end
|
57
|
-
|
61
|
+
|
58
62
|
@next_to_insert = top + 1
|
63
|
+
@printer.notify(bottom, @limit)
|
64
|
+
|
59
65
|
break if @start == @limit
|
60
66
|
end
|
61
67
|
@printer.end
|
@@ -100,5 +106,14 @@ module Lhm
|
|
100
106
|
return if @chunk_finder.table_empty?
|
101
107
|
@chunk_finder.validate
|
102
108
|
end
|
109
|
+
|
110
|
+
# Only log the chunker progress every 5 minutes instead of every iteration
|
111
|
+
def rate_limited_log_progress
|
112
|
+
current_time = Time.now
|
113
|
+
if current_time - @start_time > (5 * 60)
|
114
|
+
Lhm.logger.info("Inserted #{affected_rows} rows into the destination table from #{bottom} to #{top}")
|
115
|
+
@start_time = current_time
|
116
|
+
end
|
117
|
+
end
|
103
118
|
end
|
104
119
|
end
|
data/lib/lhm/cleanup/current.rb
CHANGED
@@ -63,11 +63,12 @@ module Lhm
|
|
63
63
|
retriable_connection.execute(ddl)
|
64
64
|
end
|
65
65
|
end
|
66
|
+
Lhm.logger.info("Dropped triggers on #{@lhm_triggers_for_origin.join(', ')}")
|
67
|
+
Lhm.logger.info("Dropped tables #{@lhm_triggers_for_origin.join(', ')}")
|
66
68
|
end
|
67
69
|
|
68
70
|
def report_ddls
|
69
|
-
|
70
|
-
ddls.each { |ddl| puts ddl }
|
71
|
+
Lhm.logger.info("The following DDLs would be executed: #{ddls}")
|
71
72
|
end
|
72
73
|
end
|
73
74
|
end
|
data/lib/lhm/entangler.rb
CHANGED
@@ -94,6 +94,7 @@ module Lhm
|
|
94
94
|
retriable_connection.execute(stmt)
|
95
95
|
end
|
96
96
|
end
|
97
|
+
Lhm.logger.info("Created triggers on #{@origin.name}")
|
97
98
|
end
|
98
99
|
|
99
100
|
def after
|
@@ -102,6 +103,7 @@ module Lhm
|
|
102
103
|
retriable_connection.execute(stmt)
|
103
104
|
end
|
104
105
|
end
|
106
|
+
Lhm.logger.info("Dropped triggers on #{@origin.name}")
|
105
107
|
end
|
106
108
|
|
107
109
|
def revert
|
data/lib/lhm/migrator.rb
CHANGED
@@ -214,6 +214,8 @@ module Lhm
|
|
214
214
|
replacement = %{CREATE TABLE `#{ @origin.destination_name }`}
|
215
215
|
stmt = @origin.ddl.gsub(original, replacement)
|
216
216
|
@connection.execute(tagged(stmt))
|
217
|
+
|
218
|
+
Lhm.logger.info("Created destination table #{@origin.destination_name}")
|
217
219
|
end
|
218
220
|
|
219
221
|
def destination_read
|
data/lib/lhm/printer.rb
CHANGED
@@ -12,26 +12,30 @@ module Lhm
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
class Percentage
|
15
|
+
class Percentage
|
16
16
|
def initialize
|
17
|
-
super
|
18
17
|
@max_length = 0
|
19
18
|
end
|
20
19
|
|
21
20
|
def notify(lowest, highest)
|
22
21
|
return if !highest || highest == 0
|
22
|
+
|
23
|
+
# The argument lowest represents the next_to_insert row id, and highest represents the
|
24
|
+
# maximum id upto which chunker has to copy the data.
|
25
|
+
# If all the rows are inserted upto highest, then lowest passed here from chunker was
|
26
|
+
# highest + 1, which leads to the printer printing the progress > 100%.
|
27
|
+
return if lowest >= highest
|
28
|
+
|
23
29
|
message = "%.2f%% (#{lowest}/#{highest}) complete" % (lowest.to_f / highest * 100.0)
|
24
30
|
write(message)
|
25
31
|
end
|
26
32
|
|
27
33
|
def end
|
28
34
|
write('100% complete')
|
29
|
-
@output.write "\n"
|
30
35
|
end
|
31
36
|
|
32
37
|
def exception(e)
|
33
|
-
|
34
|
-
@output.write "\n"
|
38
|
+
Lhm.logger.error("failed: #{e}")
|
35
39
|
end
|
36
40
|
|
37
41
|
private
|
@@ -42,7 +46,7 @@ module Lhm
|
|
42
46
|
extra = 0
|
43
47
|
end
|
44
48
|
|
45
|
-
|
49
|
+
Lhm.logger.info(message)
|
46
50
|
end
|
47
51
|
end
|
48
52
|
|
data/lib/lhm/version.rb
CHANGED
data/lib/lhm.rb
CHANGED
@@ -114,17 +114,21 @@ module Lhm
|
|
114
114
|
triggers.each do |trigger|
|
115
115
|
connection.execute("drop trigger if exists #{trigger}")
|
116
116
|
end
|
117
|
+
logger.info("Dropped triggers #{triggers.join(', ')}")
|
118
|
+
|
117
119
|
tables.each do |table|
|
118
120
|
connection.execute("drop table if exists #{table}")
|
119
121
|
end
|
122
|
+
logger.info("Dropped tables #{tables.join(', ')}")
|
123
|
+
|
120
124
|
true
|
121
125
|
elsif tables.empty? && triggers.empty?
|
122
|
-
|
126
|
+
logger.info('Everything is clean. Nothing to do.')
|
123
127
|
true
|
124
128
|
else
|
125
|
-
|
126
|
-
|
127
|
-
|
129
|
+
logger.info("Would drop LHM backup tables: #{tables.join(', ')}.")
|
130
|
+
logger.info("Would drop LHM triggers: #{triggers.join(', ')}.")
|
131
|
+
logger.info('Run with Lhm.cleanup(true) to drop all LHM triggers and tables, or Lhm.cleanup_current_run(true, table_name) to clean up a specific LHM.')
|
128
132
|
false
|
129
133
|
end
|
130
134
|
end
|
@@ -58,7 +58,7 @@ describe Lhm::AtomicSwitcher do
|
|
58
58
|
switcher.send :define_singleton_method, :atomic_switch do
|
59
59
|
'SELECT * FROM nonexistent'
|
60
60
|
end
|
61
|
-
-> { switcher.run }.must_raise(ActiveRecord::StatementInvalid)
|
61
|
+
value(-> { switcher.run }).must_raise(ActiveRecord::StatementInvalid)
|
62
62
|
end
|
63
63
|
|
64
64
|
it "should raise when destination doesn't exist" do
|
@@ -75,8 +75,8 @@ describe Lhm::AtomicSwitcher do
|
|
75
75
|
switcher.run
|
76
76
|
|
77
77
|
slave do
|
78
|
-
data_source_exists?(@origin).must_equal true
|
79
|
-
table_read(@migration.archive_name).columns.keys.must_include 'origin'
|
78
|
+
value(data_source_exists?(@origin)).must_equal true
|
79
|
+
value(table_read(@migration.archive_name).columns.keys).must_include 'origin'
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
@@ -85,8 +85,8 @@ describe Lhm::AtomicSwitcher do
|
|
85
85
|
switcher.run
|
86
86
|
|
87
87
|
slave do
|
88
|
-
data_source_exists?(@destination).must_equal false
|
89
|
-
table_read(@origin.name).columns.keys.must_include 'destination'
|
88
|
+
value(data_source_exists?(@destination)).must_equal false
|
89
|
+
value(table_read(@origin.name).columns.keys).must_include 'destination'
|
90
90
|
end
|
91
91
|
end
|
92
92
|
end
|
@@ -29,7 +29,7 @@ describe Lhm::Chunker do
|
|
29
29
|
Lhm::Chunker.new(@migration, connection, {throttler: throttler, printer: printer} ).run
|
30
30
|
|
31
31
|
slave do
|
32
|
-
count_all(@destination.name).must_equal(1)
|
32
|
+
value(count_all(@destination.name)).must_equal(1)
|
33
33
|
end
|
34
34
|
|
35
35
|
end
|
@@ -42,7 +42,7 @@ describe Lhm::Chunker do
|
|
42
42
|
Lhm::Chunker.new(@migration, connection, {throttler: throttler, printer: printer} ).run
|
43
43
|
|
44
44
|
slave do
|
45
|
-
count_all(@destination.name).must_equal(2)
|
45
|
+
value(count_all(@destination.name)).must_equal(2)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -58,7 +58,7 @@ describe Lhm::Chunker do
|
|
58
58
|
Lhm::Chunker.new(migration, connection, {throttler: throttler, printer: printer} ).run
|
59
59
|
|
60
60
|
slave do
|
61
|
-
count_all(destination.name).must_equal(2)
|
61
|
+
value(count_all(destination.name)).must_equal(2)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
@@ -128,7 +128,7 @@ describe Lhm::Chunker do
|
|
128
128
|
Lhm::Chunker.new(@migration, connection, {throttler: throttler, printer: printer} ).run
|
129
129
|
|
130
130
|
slave do
|
131
|
-
count_all(@destination.name).must_equal(0)
|
131
|
+
value(count_all(@destination.name)).must_equal(0)
|
132
132
|
end
|
133
133
|
|
134
134
|
end
|
@@ -145,7 +145,7 @@ describe Lhm::Chunker do
|
|
145
145
|
).run
|
146
146
|
|
147
147
|
slave do
|
148
|
-
count_all(@destination.name).must_equal(23)
|
148
|
+
value(count_all(@destination.name)).must_equal(23)
|
149
149
|
end
|
150
150
|
|
151
151
|
printer.verify
|
@@ -161,7 +161,7 @@ describe Lhm::Chunker do
|
|
161
161
|
).run
|
162
162
|
|
163
163
|
slave do
|
164
|
-
count_all(@destination.name).must_equal(11)
|
164
|
+
value(count_all(@destination.name)).must_equal(11)
|
165
165
|
end
|
166
166
|
|
167
167
|
end
|
@@ -178,7 +178,7 @@ describe Lhm::Chunker do
|
|
178
178
|
).run
|
179
179
|
|
180
180
|
slave do
|
181
|
-
count_all(@destination.name).must_equal(23)
|
181
|
+
value(count_all(@destination.name)).must_equal(23)
|
182
182
|
end
|
183
183
|
|
184
184
|
printer.verify
|
@@ -203,7 +203,7 @@ describe Lhm::Chunker do
|
|
203
203
|
assert_equal(Lhm::Throttler::SlaveLag::INITIAL_TIMEOUT * 2 * 2, throttler.timeout_seconds)
|
204
204
|
|
205
205
|
slave do
|
206
|
-
count_all(@destination.name).must_equal(15)
|
206
|
+
value(count_all(@destination.name)).must_equal(15)
|
207
207
|
end
|
208
208
|
end
|
209
209
|
|
@@ -238,7 +238,7 @@ describe Lhm::Chunker do
|
|
238
238
|
assert_equal(0, throttler.send(:max_current_slave_lag))
|
239
239
|
|
240
240
|
slave do
|
241
|
-
count_all(@destination.name).must_equal(15)
|
241
|
+
value(count_all(@destination.name)).must_equal(15)
|
242
242
|
end
|
243
243
|
|
244
244
|
printer.verify
|
@@ -260,7 +260,7 @@ describe Lhm::Chunker do
|
|
260
260
|
assert_match "Verification failed, aborting early", exception.message
|
261
261
|
|
262
262
|
slave do
|
263
|
-
count_all(@destination.name).must_equal(0)
|
263
|
+
value(count_all(@destination.name)).must_equal(0)
|
264
264
|
end
|
265
265
|
end
|
266
266
|
end
|
@@ -31,12 +31,13 @@ describe Lhm, 'cleanup' do
|
|
31
31
|
|
32
32
|
describe 'cleanup' do
|
33
33
|
it 'should show temporary tables' do
|
34
|
-
output = capture_stdout do
|
34
|
+
output = capture_stdout do |logger|
|
35
|
+
Lhm.logger = logger
|
35
36
|
Lhm.cleanup
|
36
37
|
end
|
37
|
-
output.must_include('Would drop LHM backup tables')
|
38
|
-
output.must_match(/lhma_[0-9_]*_users/)
|
39
|
-
output.must_match(/lhma_[0-9_]*_permissions/)
|
38
|
+
value(output).must_include('Would drop LHM backup tables')
|
39
|
+
value(output).must_match(/lhma_[0-9_]*_users/)
|
40
|
+
value(output).must_match(/lhma_[0-9_]*_permissions/)
|
40
41
|
end
|
41
42
|
|
42
43
|
it 'should show temporary tables within range' do
|
@@ -48,12 +49,13 @@ describe Lhm, 'cleanup' do
|
|
48
49
|
table_name2 = Lhm::Migration.new(table2, nil, nil, {}, Time.now - 172800).archive_name
|
49
50
|
table_rename(:permissions, table_name2)
|
50
51
|
|
51
|
-
output = capture_stdout do
|
52
|
+
output = capture_stdout do |logger|
|
53
|
+
Lhm.logger = logger
|
52
54
|
Lhm.cleanup false, { :until => Time.now - 86400 }
|
53
55
|
end
|
54
|
-
output.must_include('Would drop LHM backup tables')
|
55
|
-
output.must_match(/lhma_[0-9_]*_users/)
|
56
|
-
output.must_match(/lhma_[0-9_]*_permissions/)
|
56
|
+
value(output).must_include('Would drop LHM backup tables')
|
57
|
+
value(output).must_match(/lhma_[0-9_]*_users/)
|
58
|
+
value(output).must_match(/lhma_[0-9_]*_permissions/)
|
57
59
|
end
|
58
60
|
|
59
61
|
it 'should exclude temporary tables outside range' do
|
@@ -65,30 +67,40 @@ describe Lhm, 'cleanup' do
|
|
65
67
|
table_name2 = Lhm::Migration.new(table2, nil, nil, {}, Time.now).archive_name
|
66
68
|
table_rename(:permissions, table_name2)
|
67
69
|
|
68
|
-
output = capture_stdout do
|
70
|
+
output = capture_stdout do |logger|
|
71
|
+
Lhm.logger = logger
|
69
72
|
Lhm.cleanup false, { :until => Time.now - 172800 }
|
70
73
|
end
|
71
|
-
output.must_include('Would drop LHM backup tables')
|
72
|
-
output.wont_match(/lhma_[0-9_]*_users/)
|
73
|
-
output.wont_match(/lhma_[0-9_]*_permissions/)
|
74
|
+
value(output).must_include('Would drop LHM backup tables')
|
75
|
+
value(output).wont_match(/lhma_[0-9_]*_users/)
|
76
|
+
value(output).wont_match(/lhma_[0-9_]*_permissions/)
|
74
77
|
end
|
75
78
|
|
76
79
|
it 'should show temporary triggers' do
|
77
|
-
output = capture_stdout do
|
80
|
+
output = capture_stdout do |logger|
|
81
|
+
Lhm.logger = logger
|
78
82
|
Lhm.cleanup
|
79
83
|
end
|
80
|
-
output.must_include('Would drop LHM triggers')
|
81
|
-
output.must_include('lhmt_ins_users')
|
82
|
-
output.must_include('lhmt_del_users')
|
83
|
-
output.must_include('lhmt_upd_users')
|
84
|
-
output.must_include('lhmt_ins_permissions')
|
85
|
-
output.must_include('lhmt_del_permissions')
|
86
|
-
output.must_include('lhmt_upd_permissions')
|
84
|
+
value(output).must_include('Would drop LHM triggers')
|
85
|
+
value(output).must_include('lhmt_ins_users')
|
86
|
+
value(output).must_include('lhmt_del_users')
|
87
|
+
value(output).must_include('lhmt_upd_users')
|
88
|
+
value(output).must_include('lhmt_ins_permissions')
|
89
|
+
value(output).must_include('lhmt_del_permissions')
|
90
|
+
value(output).must_include('lhmt_upd_permissions')
|
87
91
|
end
|
88
92
|
|
89
93
|
it 'should delete temporary tables' do
|
90
|
-
Lhm.cleanup(true).must_equal(true)
|
91
|
-
Lhm.cleanup.must_equal(true)
|
94
|
+
value(Lhm.cleanup(true)).must_equal(true)
|
95
|
+
value(Lhm.cleanup).must_equal(true)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'outputs deleted tables and triggers' do
|
99
|
+
output = capture_stdout do |logger|
|
100
|
+
Lhm.logger = logger
|
101
|
+
Lhm.cleanup(true)
|
102
|
+
end
|
103
|
+
value(output).must_include('Dropped triggers lhmt_ins_users, lhmt_upd_users, lhmt_del_users, lhmt_ins_permissions, lhmt_upd_permissions, lhmt_del_permissions')
|
92
104
|
end
|
93
105
|
end
|
94
106
|
|
@@ -96,27 +108,26 @@ describe Lhm, 'cleanup' do
|
|
96
108
|
it 'should show lhmn table for the specified table only' do
|
97
109
|
table_create(:permissions)
|
98
110
|
table_rename(:permissions, 'lhmn_permissions')
|
99
|
-
output = capture_stdout do
|
111
|
+
output = capture_stdout do |logger|
|
112
|
+
Lhm.logger = logger
|
100
113
|
Lhm.cleanup_current_run(false, 'permissions')
|
101
|
-
end
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
assert_match(/rename table lhmn_permissions to lhma_[0-9_]*_permissions_failed/, output[4])
|
108
|
-
assert_equal 5, output.length
|
114
|
+
end
|
115
|
+
|
116
|
+
value(output).must_include("The following DDLs would be executed:")
|
117
|
+
value(output).must_include("drop trigger if exists lhmt_ins_permissions")
|
118
|
+
value(output).must_include("drop trigger if exists lhmt_upd_permissions")
|
119
|
+
value(output).must_include("drop trigger if exists lhmt_del_permissions")
|
109
120
|
end
|
110
121
|
|
111
122
|
it 'should show temporary triggers for the specified table only' do
|
112
|
-
output = capture_stdout do
|
123
|
+
output = capture_stdout do |logger|
|
124
|
+
Lhm.logger = logger
|
113
125
|
Lhm.cleanup_current_run(false, 'permissions')
|
114
|
-
end
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
assert_equal 4, output.length
|
126
|
+
end
|
127
|
+
value(output).must_include("The following DDLs would be executed:")
|
128
|
+
value(output).must_include("drop trigger if exists lhmt_ins_permissions")
|
129
|
+
value(output).must_include("drop trigger if exists lhmt_upd_permissions")
|
130
|
+
value(output).must_include("drop trigger if exists lhmt_del_permissions")
|
120
131
|
end
|
121
132
|
|
122
133
|
it 'should delete temporary tables and triggers for the specified table only' do
|
@@ -26,7 +26,7 @@ describe Lhm::Entangler do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
slave do
|
29
|
-
count(:destination, 'common', 'inserted').must_equal(1)
|
29
|
+
value(count(:destination, 'common', 'inserted')).must_equal(1)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -38,7 +38,7 @@ describe Lhm::Entangler do
|
|
38
38
|
end
|
39
39
|
|
40
40
|
slave do
|
41
|
-
count(:destination, 'common', 'inserted').must_equal(0)
|
41
|
+
value(count(:destination, 'common', 'inserted')).must_equal(0)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -49,7 +49,7 @@ describe Lhm::Entangler do
|
|
49
49
|
end
|
50
50
|
|
51
51
|
slave do
|
52
|
-
count(:destination, 'common', 'updated').must_equal(1)
|
52
|
+
value(count(:destination, 'common', 'updated')).must_equal(1)
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -59,7 +59,7 @@ describe Lhm::Entangler do
|
|
59
59
|
execute("insert into origin (common) values ('inserted')")
|
60
60
|
|
61
61
|
slave do
|
62
|
-
count(:destination, 'common', 'inserted').must_equal(0)
|
62
|
+
value(count(:destination, 'common', 'inserted')).must_equal(0)
|
63
63
|
end
|
64
64
|
end
|
65
65
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'test_helper'
|
4
4
|
require 'yaml'
|
5
5
|
require 'active_support'
|
6
|
+
require 'logger'
|
6
7
|
|
7
8
|
begin
|
8
9
|
$db_config = YAML.load_file(File.expand_path(File.dirname(__FILE__)) + '/database.yml')
|
@@ -212,7 +213,8 @@ module IntegrationHelper
|
|
212
213
|
def capture_stdout
|
213
214
|
out = StringIO.new
|
214
215
|
$stdout = out
|
215
|
-
|
216
|
+
logger = Logger.new($stdout)
|
217
|
+
yield logger
|
216
218
|
return out.string
|
217
219
|
ensure
|
218
220
|
$stdout = ::STDOUT
|