lhm-shopify 3.5.4 → 4.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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +6 -6
  3. data/Appraisals +8 -13
  4. data/CHANGELOG.md +13 -0
  5. data/Gemfile.lock +22 -20
  6. data/README.md +14 -7
  7. data/dev.yml +12 -8
  8. data/docker-compose.yml +2 -0
  9. data/gemfiles/activerecord_6.0.gemfile +1 -1
  10. data/gemfiles/activerecord_6.0.gemfile.lock +25 -21
  11. data/gemfiles/activerecord_6.1.gemfile.lock +17 -13
  12. data/gemfiles/{activerecord_7.0.0.alpha2.gemfile → activerecord_7.0.gemfile} +1 -1
  13. data/gemfiles/{activerecord_7.0.0.alpha2.gemfile.lock → activerecord_7.0.gemfile.lock} +23 -19
  14. data/gemfiles/{activerecord_5.2.gemfile → activerecord_7.1.0.beta1.gemfile} +1 -3
  15. data/gemfiles/activerecord_7.1.0.beta1.gemfile.lock +81 -0
  16. data/lhm.gemspec +1 -1
  17. data/lib/lhm/sql_helper.rb +1 -1
  18. data/lib/lhm/sql_retry.rb +37 -47
  19. data/lib/lhm/throttler/replica_lag.rb +162 -0
  20. data/lib/lhm/throttler/slave_lag.rb +5 -155
  21. data/lib/lhm/throttler/threads_running.rb +3 -1
  22. data/lib/lhm/throttler.rb +7 -3
  23. data/lib/lhm/version.rb +1 -1
  24. data/spec/.lhm.example +1 -1
  25. data/spec/README.md +8 -9
  26. data/spec/integration/atomic_switcher_spec.rb +2 -2
  27. data/spec/integration/chunk_insert_spec.rb +2 -2
  28. data/spec/integration/chunker_spec.rb +33 -38
  29. data/spec/integration/database.yml +1 -1
  30. data/spec/integration/entangler_spec.rb +4 -4
  31. data/spec/integration/integration_helper.rb +12 -12
  32. data/spec/integration/lhm_spec.rb +41 -32
  33. data/spec/integration/locked_switcher_spec.rb +2 -2
  34. data/spec/integration/sql_retry/retry_with_proxysql_spec.rb +6 -5
  35. data/spec/integration/toxiproxy_helper.rb +1 -1
  36. data/spec/test_helper.rb +3 -0
  37. data/spec/unit/printer_spec.rb +2 -6
  38. data/spec/unit/sql_helper_spec.rb +2 -2
  39. data/spec/unit/throttler/{slave_lag_spec.rb → replica_lag_spec.rb} +79 -79
  40. data/spec/unit/throttler/threads_running_spec.rb +18 -0
  41. data/spec/unit/throttler_spec.rb +8 -8
  42. metadata +10 -9
  43. data/gemfiles/activerecord_5.2.gemfile.lock +0 -65
@@ -28,7 +28,7 @@ describe Lhm::Chunker do
28
28
 
29
29
  Lhm::Chunker.new(@migration, connection, {throttler: throttler, printer: printer} ).run
30
30
 
31
- slave do
31
+ replica do
32
32
  value(count_all(@destination.name)).must_equal(1)
33
33
  end
34
34
 
@@ -41,7 +41,7 @@ describe Lhm::Chunker do
41
41
 
42
42
  Lhm::Chunker.new(@migration, connection, {throttler: throttler, printer: printer} ).run
43
43
 
44
- slave do
44
+ replica do
45
45
  value(count_all(@destination.name)).must_equal(2)
46
46
  end
47
47
  end
@@ -57,7 +57,7 @@ describe Lhm::Chunker do
57
57
 
58
58
  Lhm::Chunker.new(migration, connection, {throttler: throttler, printer: printer} ).run
59
59
 
60
- slave do
60
+ replica do
61
61
  value(count_all(destination.name)).must_equal(2)
62
62
  end
63
63
  end
@@ -127,7 +127,7 @@ describe Lhm::Chunker do
127
127
 
128
128
  Lhm::Chunker.new(@migration, connection, {throttler: throttler, printer: printer} ).run
129
129
 
130
- slave do
130
+ replica do
131
131
  value(count_all(@destination.name)).must_equal(0)
132
132
  end
133
133
 
@@ -136,20 +136,17 @@ describe Lhm::Chunker do
136
136
  it 'should copy 23 rows from origin to destination in one shot, regardless of the value of the id' do
137
137
  23.times { |n| execute("insert into origin set id = '#{ n * n + 23 }'") }
138
138
 
139
- printer = MiniTest::Mock.new
140
- printer.expect(:notify, :return_value, [Integer, Integer])
141
- printer.expect(:end, :return_value, [])
139
+ printer = mock("printer")
140
+ printer.expects(:notify).with(kind_of(Integer), kind_of(Integer))
141
+ printer.expects(:end)
142
142
 
143
143
  Lhm::Chunker.new(
144
144
  @migration, connection, { throttler: throttler, printer: printer }
145
145
  ).run
146
146
 
147
- slave do
147
+ replica do
148
148
  value(count_all(@destination.name)).must_equal(23)
149
149
  end
150
-
151
- printer.verify
152
-
153
150
  end
154
151
 
155
152
  it 'should copy all the records of a table, even if the last chunk starts with the last record of it.' do
@@ -160,42 +157,40 @@ describe Lhm::Chunker do
160
157
  @migration, connection, { throttler: Lhm::Throttler::Time.new(stride: 10), printer: printer }
161
158
  ).run
162
159
 
163
- slave do
160
+ replica do
164
161
  value(count_all(@destination.name)).must_equal(11)
165
162
  end
166
163
 
167
164
  end
168
165
 
169
- it 'should copy 23 rows from origin to destination in one shot with slave lag based throttler, regardless of the value of the id' do
166
+ it 'should copy 23 rows from origin to destination in one shot with replica lag based throttler, regardless of the value of the id' do
170
167
  23.times { |n| execute("insert into origin set id = '#{ 100000 + n * n + 23 }'") }
171
168
 
172
- printer = MiniTest::Mock.new
173
- printer.expect(:notify, :return_value, [Integer, Integer])
174
- printer.expect(:end, :return_value, [])
169
+ printer = mock("printer")
170
+ printer.expects(:notify).with(kind_of(Integer), kind_of(Integer))
171
+ printer.expects(:end)
175
172
 
176
- Lhm::Throttler::Slave.any_instance.stubs(:slave_hosts).returns(['127.0.0.1'])
177
- Lhm::Throttler::SlaveLag.any_instance.stubs(:master_slave_hosts).returns(['127.0.0.1'])
173
+ Lhm::Throttler::Replica.any_instance.stubs(:replica_hosts).returns(['127.0.0.1'])
174
+ Lhm::Throttler::ReplicaLag.any_instance.stubs(:master_replica_hosts).returns(['127.0.0.1'])
178
175
 
179
176
  Lhm::Chunker.new(
180
- @migration, connection, { throttler: Lhm::Throttler::SlaveLag.new(stride: 100), printer: printer }
177
+ @migration, connection, { throttler: Lhm::Throttler::ReplicaLag.new(stride: 100), printer: printer }
181
178
  ).run
182
179
 
183
- slave do
180
+ replica do
184
181
  value(count_all(@destination.name)).must_equal(23)
185
182
  end
186
-
187
- printer.verify
188
183
  end
189
184
 
190
- it 'should throttle work stride based on slave lag' do
185
+ it 'should throttle work stride based on replica lag' do
191
186
  15.times { |n| execute("insert into origin set id = '#{ (n * n) + 1 }'") }
192
187
 
193
188
  printer = mock()
194
189
  printer.expects(:notify).with(instance_of(Integer), instance_of(Integer)).twice
195
190
  printer.expects(:end)
196
191
 
197
- throttler = Lhm::Throttler::SlaveLag.new(stride: 10, allowed_lag: 0)
198
- def throttler.max_current_slave_lag
192
+ throttler = Lhm::Throttler::ReplicaLag.new(stride: 10, allowed_lag: 0)
193
+ def throttler.max_current_replica_lag
199
194
  1
200
195
  end
201
196
 
@@ -203,14 +198,14 @@ describe Lhm::Chunker do
203
198
  @migration, connection, { throttler: throttler, printer: printer }
204
199
  ).run
205
200
 
206
- assert_equal(Lhm::Throttler::SlaveLag::INITIAL_TIMEOUT * 2 * 2, throttler.timeout_seconds)
201
+ assert_equal(Lhm::Throttler::ReplicaLag::INITIAL_TIMEOUT * 2 * 2, throttler.timeout_seconds)
207
202
 
208
- slave do
203
+ replica do
209
204
  value(count_all(@destination.name)).must_equal(15)
210
205
  end
211
206
  end
212
207
 
213
- it 'should detect a single slave with no lag in the default configuration' do
208
+ it 'should detect a single replica with no lag in the default configuration' do
214
209
  15.times { |n| execute("insert into origin set id = '#{ (n * n) + 1 }'") }
215
210
 
216
211
  printer = mock()
@@ -218,15 +213,15 @@ describe Lhm::Chunker do
218
213
  printer.expects(:verify)
219
214
  printer.expects(:end)
220
215
 
221
- Lhm::Throttler::Slave.any_instance.stubs(:slave_hosts).returns(['127.0.0.1'])
222
- Lhm::Throttler::SlaveLag.any_instance.stubs(:master_slave_hosts).returns(['127.0.0.1'])
216
+ Lhm::Throttler::Replica.any_instance.stubs(:replica_hosts).returns(['127.0.0.1'])
217
+ Lhm::Throttler::ReplicaLag.any_instance.stubs(:master_replica_hosts).returns(['127.0.0.1'])
223
218
 
224
- throttler = Lhm::Throttler::SlaveLag.new(stride: 10, allowed_lag: 0)
219
+ throttler = Lhm::Throttler::ReplicaLag.new(stride: 10, allowed_lag: 0)
225
220
 
226
- if master_slave_mode?
227
- def throttler.slave_connection(slave)
221
+ if master_replica_mode?
222
+ def throttler.replica_connection(replica)
228
223
  config = ActiveRecord::Base.connection_pool.db_config.configuration_hash.dup
229
- config[:host] = slave
224
+ config[:host] = replica
230
225
  config[:port] = 33007
231
226
  ActiveRecord::Base.send('mysql2_connection', config)
232
227
  end
@@ -236,10 +231,10 @@ describe Lhm::Chunker do
236
231
  @migration, connection, { throttler: throttler, printer: printer }
237
232
  ).run
238
233
 
239
- assert_equal(Lhm::Throttler::SlaveLag::INITIAL_TIMEOUT, throttler.timeout_seconds)
240
- assert_equal(0, throttler.send(:max_current_slave_lag))
234
+ assert_equal(Lhm::Throttler::ReplicaLag::INITIAL_TIMEOUT, throttler.timeout_seconds)
235
+ assert_equal(0, throttler.send(:max_current_replica_lag))
241
236
 
242
- slave do
237
+ replica do
243
238
  value(count_all(@destination.name)).must_equal(15)
244
239
  end
245
240
 
@@ -261,7 +256,7 @@ describe Lhm::Chunker do
261
256
 
262
257
  assert_match "Verification failed, aborting early", exception.message
263
258
 
264
- slave do
259
+ replica do
265
260
  value(count_all(@destination.name)).must_equal(0)
266
261
  end
267
262
  end
@@ -3,7 +3,7 @@ master:
3
3
  user: root
4
4
  password: password
5
5
  port: 33006
6
- slave:
6
+ replica:
7
7
  host: mysql-2
8
8
  user: root
9
9
  password: password
@@ -27,7 +27,7 @@ describe Lhm::Entangler do
27
27
  execute("insert into origin (common) values ('inserted')")
28
28
  end
29
29
 
30
- slave do
30
+ replica do
31
31
  value(count(:destination, 'common', 'inserted')).must_equal(1)
32
32
  end
33
33
  end
@@ -39,7 +39,7 @@ describe Lhm::Entangler do
39
39
  execute("delete from origin where common = 'inserted'")
40
40
  end
41
41
 
42
- slave do
42
+ replica do
43
43
  value(count(:destination, 'common', 'inserted')).must_equal(0)
44
44
  end
45
45
  end
@@ -50,7 +50,7 @@ describe Lhm::Entangler do
50
50
  execute("update origin set common = 'updated'")
51
51
  end
52
52
 
53
- slave do
53
+ replica do
54
54
  value(count(:destination, 'common', 'updated')).must_equal(1)
55
55
  end
56
56
  end
@@ -60,7 +60,7 @@ describe Lhm::Entangler do
60
60
 
61
61
  execute("insert into origin (common) values ('inserted')")
62
62
 
63
- slave do
63
+ replica do
64
64
  value(count(:destination, 'common', 'inserted')).must_equal(0)
65
65
  end
66
66
  end
@@ -53,12 +53,12 @@ module IntegrationHelper
53
53
  )
54
54
  end
55
55
 
56
- def connect_slave!
56
+ def connect_replica!
57
57
  connect!(
58
58
  '127.0.0.1',
59
- $db_config['slave']['port'],
60
- $db_config['slave']['user'],
61
- $db_config['slave']['password'],
59
+ $db_config['replica']['port'],
60
+ $db_config['replica']['user'],
61
+ $db_config['replica']['password'],
62
62
  )
63
63
  end
64
64
 
@@ -113,12 +113,12 @@ module IntegrationHelper
113
113
  end
114
114
  end
115
115
 
116
- def slave(&block)
117
- if master_slave_mode?
118
- connect_slave!
116
+ def replica(&block)
117
+ if master_replica_mode?
118
+ connect_replica!
119
119
 
120
- # need to wait for the slave to catch up. a better method would be to
121
- # check the master binlog position and wait for the slave to catch up
120
+ # need to wait for the replica to catch up. a better method would be to
121
+ # check the master binlog position and wait for the replica to catch up
122
122
  # to that position.
123
123
  sleep 1
124
124
  else
@@ -127,7 +127,7 @@ module IntegrationHelper
127
127
 
128
128
  yield block
129
129
 
130
- if master_slave_mode?
130
+ if master_replica_mode?
131
131
  connect_master!
132
132
  end
133
133
  end
@@ -215,8 +215,8 @@ module IntegrationHelper
215
215
  # Environment
216
216
  #
217
217
 
218
- def master_slave_mode?
219
- !!ENV['MASTER_SLAVE']
218
+ def master_replica_mode?
219
+ !!ENV['MASTER_REPLICA']
220
220
  end
221
221
 
222
222
  #
@@ -17,7 +17,7 @@ describe Lhm do
17
17
  t.add_column(:logins, "int(12) default '0'")
18
18
  end
19
19
 
20
- slave do
20
+ replica do
21
21
  value(table_read(:users).columns['logins']).must_equal({
22
22
  :type => 'int(12)',
23
23
  :is_nullable => 'YES',
@@ -35,7 +35,7 @@ describe Lhm do
35
35
  t.add_column(:logins, "int(12) default '0'")
36
36
  end
37
37
 
38
- slave do
38
+ replica do
39
39
  value(table_read(:custom_primary_key).columns['logins']).must_equal({
40
40
  :type => 'int(12)',
41
41
  :is_nullable => 'YES',
@@ -53,7 +53,7 @@ describe Lhm do
53
53
  t.add_column(:logins, "int(12) default '0'")
54
54
  end
55
55
 
56
- slave do
56
+ replica do
57
57
  value(table_read(:composite_primary_key).columns['logins']).must_equal({
58
58
  :type => 'int(12)',
59
59
  :is_nullable => 'YES',
@@ -82,7 +82,7 @@ describe Lhm do
82
82
  t.ddl("ALTER TABLE #{t.name} CHANGE id id bigint (20) NOT NULL AUTO_INCREMENT")
83
83
  end
84
84
 
85
- slave do
85
+ replica do
86
86
  value(connection.primary_key('users')).must_equal(['username', 'id'])
87
87
  end
88
88
  end
@@ -104,7 +104,7 @@ describe Lhm do
104
104
  describe 'when no additional data is inserted into the table' do
105
105
 
106
106
  it 'migrates the existing data' do
107
- slave do
107
+ replica do
108
108
  value(count_all(:permissions)).must_equal(11)
109
109
  end
110
110
  end
@@ -120,7 +120,7 @@ describe Lhm do
120
120
  end
121
121
 
122
122
  it 'migrates all data' do
123
- slave do
123
+ replica do
124
124
  value(count_all(:permissions)).must_equal(13)
125
125
  end
126
126
  end
@@ -132,7 +132,7 @@ describe Lhm do
132
132
  t.add_column(:logins, "INT(12) DEFAULT '0'")
133
133
  end
134
134
 
135
- slave do
135
+ replica do
136
136
  value(table_read(:users).columns['logins']).must_equal({
137
137
  :type => 'int(12)',
138
138
  :is_nullable => 'YES',
@@ -150,7 +150,7 @@ describe Lhm do
150
150
  t.add_column(:logins, "INT(12) DEFAULT '0'")
151
151
  end
152
152
 
153
- slave do
153
+ replica do
154
154
  value(count_all(:users)).must_equal(23)
155
155
  end
156
156
  end
@@ -160,7 +160,7 @@ describe Lhm do
160
160
  t.remove_column(:comment)
161
161
  end
162
162
 
163
- slave do
163
+ replica do
164
164
  assert_nil table_read(:users).columns['comment']
165
165
  end
166
166
  end
@@ -170,7 +170,7 @@ describe Lhm do
170
170
  t.add_index([:comment, :created_at])
171
171
  end
172
172
 
173
- slave do
173
+ replica do
174
174
  value(index_on_columns?(:users, [:comment, :created_at])).must_equal(true)
175
175
  end
176
176
  end
@@ -180,7 +180,7 @@ describe Lhm do
180
180
  t.add_index([:comment, :created_at], :my_index_name)
181
181
  end
182
182
 
183
- slave do
183
+ replica do
184
184
  value(index?(:users, :my_index_name)).must_equal(true)
185
185
  end
186
186
  end
@@ -190,7 +190,7 @@ describe Lhm do
190
190
  t.add_index(:group)
191
191
  end
192
192
 
193
- slave do
193
+ replica do
194
194
  value(index_on_columns?(:users, :group)).must_equal(true)
195
195
  end
196
196
  end
@@ -200,7 +200,7 @@ describe Lhm do
200
200
  t.add_unique_index(:comment)
201
201
  end
202
202
 
203
- slave do
203
+ replica do
204
204
  value(index_on_columns?(:users, :comment, :unique)).must_equal(true)
205
205
  end
206
206
  end
@@ -210,7 +210,7 @@ describe Lhm do
210
210
  t.remove_index([:username, :created_at])
211
211
  end
212
212
 
213
- slave do
213
+ replica do
214
214
  value(index_on_columns?(:users, [:username, :created_at])).must_equal(false)
215
215
  end
216
216
  end
@@ -220,7 +220,7 @@ describe Lhm do
220
220
  t.remove_index([:username, :group])
221
221
  end
222
222
 
223
- slave do
223
+ replica do
224
224
  value(index?(:users, :index_with_a_custom_name)).must_equal(false)
225
225
  end
226
226
  end
@@ -230,17 +230,27 @@ describe Lhm do
230
230
  t.remove_index(:irrelevant_column_name, :index_with_a_custom_name)
231
231
  end
232
232
 
233
- slave do
233
+ replica do
234
234
  value(index?(:users, :index_with_a_custom_name)).must_equal(false)
235
235
  end
236
236
  end
237
237
 
238
+ it 'should add an index with column sizes' do
239
+ Lhm.change_table(:users, :atomic_switch => false) do |t|
240
+ t.add_index(["username(6)", "group (10)", "comment (10)"])
241
+ end
242
+
243
+ replica do
244
+ value(index_on_columns?(:users, [:username, :group, :comment])).must_equal(true)
245
+ end
246
+ end
247
+
238
248
  it 'should apply a ddl statement' do
239
249
  Lhm.change_table(:users, :atomic_switch => false) do |t|
240
250
  t.ddl('alter table %s add column flag tinyint(1)' % t.name)
241
251
  end
242
252
 
243
- slave do
253
+ replica do
244
254
  value(table_read(:users).columns['flag']).must_equal({
245
255
  :type => 'tinyint(1)',
246
256
  :is_nullable => 'YES',
@@ -256,7 +266,7 @@ describe Lhm do
256
266
  t.change_column(:comment, "varchar(20) DEFAULT 'none' NOT NULL")
257
267
  end
258
268
 
259
- slave do
269
+ replica do
260
270
  value(table_read(:users).columns['comment']).must_equal({
261
271
  :type => 'varchar(20)',
262
272
  :is_nullable => 'NO',
@@ -274,7 +284,7 @@ describe Lhm do
274
284
  t.change_column(:id, 'int(5)')
275
285
  end
276
286
 
277
- slave do
287
+ replica do
278
288
  value(table_read(:small_table).columns['id']).must_equal({
279
289
  :type => 'int(5)',
280
290
  :is_nullable => 'NO',
@@ -293,7 +303,7 @@ describe Lhm do
293
303
  t.rename_column(:username, :login)
294
304
  end
295
305
 
296
- slave do
306
+ replica do
297
307
  table_data = table_read(:users)
298
308
  assert_nil table_data.columns['username']
299
309
  value(table_read(:users).columns['login']).must_equal({
@@ -318,7 +328,7 @@ describe Lhm do
318
328
  t.rename_column(:group, :fnord)
319
329
  end
320
330
 
321
- slave do
331
+ replica do
322
332
  table_data = table_read(:users)
323
333
  assert_nil table_data.columns['group']
324
334
  value(table_read(:users).columns['fnord']).must_equal({
@@ -345,7 +355,7 @@ describe Lhm do
345
355
  t.rename_column(:username, :user_name)
346
356
  end
347
357
 
348
- slave do
358
+ replica do
349
359
  table_data = table_read(:users)
350
360
  assert_nil table_data.columns['username']
351
361
  value(table_read(:users).columns['user_name']).must_equal({
@@ -373,7 +383,7 @@ describe Lhm do
373
383
  t.rename_column(:reference, :ref)
374
384
  end
375
385
 
376
- slave do
386
+ replica do
377
387
  table_data = table_read(:users)
378
388
  assert_nil table_data.columns['reference']
379
389
  value(table_read(:users).columns['ref']).must_equal({
@@ -400,7 +410,7 @@ describe Lhm do
400
410
  t.rename_column(:group, :fnord)
401
411
  end
402
412
 
403
- slave do
413
+ replica do
404
414
  table_data = table_read(:users)
405
415
  assert_nil table_data.columns['group']
406
416
  value(table_read(:users).columns['fnord']).must_equal({
@@ -425,7 +435,7 @@ describe Lhm do
425
435
  t.rename_column(:username, :user_name)
426
436
  end
427
437
 
428
- slave do
438
+ replica do
429
439
  table_data = table_read(:users)
430
440
  assert_nil table_data.columns['username']
431
441
  value(table_read(:users).columns['user_name']).must_equal({
@@ -452,7 +462,7 @@ describe Lhm do
452
462
  t.rename_column(:username, :user_name)
453
463
  end
454
464
 
455
- slave do
465
+ replica do
456
466
  table_data = table_read(:users)
457
467
  assert_nil table_data.columns['username']
458
468
  value(table_read(:users).columns['user_name']).must_equal({
@@ -499,7 +509,7 @@ describe Lhm do
499
509
  end
500
510
  end
501
511
 
502
- slave do
512
+ replica do
503
513
  table_data = table_read(:users)
504
514
  assert_nil table_data.columns['fnord']
505
515
  value(table_read(:users).columns['group']).must_equal({
@@ -525,7 +535,7 @@ describe Lhm do
525
535
  t.remove_index('by')
526
536
  end
527
537
 
528
- slave do
538
+ replica do
529
539
  value(table_read(:lines).columns).must_include 'by'
530
540
  value(table_read(:lines).columns).wont_include 'lines'
531
541
  value(index_on_columns?(:lines, ['between'], :unique)).must_equal true
@@ -554,7 +564,7 @@ describe Lhm do
554
564
 
555
565
  insert.join
556
566
 
557
- slave do
567
+ replica do
558
568
  value(count_all(:users)).must_equal(60)
559
569
  end
560
570
  end
@@ -577,7 +587,7 @@ describe Lhm do
577
587
 
578
588
  delete.join
579
589
 
580
- slave do
590
+ replica do
581
591
  value(count_all(:users)).must_equal(40)
582
592
  end
583
593
  end
@@ -645,13 +655,12 @@ describe Lhm do
645
655
  log_lines = @logs.string.split("\n")
646
656
 
647
657
  assert log_lines.one?{ |line| line.include?("Lost connection to MySQL, will retry to connect to same host")}
648
- assert log_lines.any?{ |line| line.include?("Lost connection to MySQL server at 'reading initial communication packet'")}
649
658
  assert log_lines.one?{ |line| line.include?("LHM successfully reconnected to initial host")}
650
659
  assert log_lines.one?{ |line| line.include?("100% complete")}
651
660
 
652
661
  Lhm::ChunkInsert.remove_all_callbacks
653
662
 
654
- slave do
663
+ replica do
655
664
  value(count_all(:users)).must_equal(100)
656
665
  end
657
666
  end
@@ -31,7 +31,7 @@ describe Lhm::LockedSwitcher do
31
31
  switcher = Lhm::LockedSwitcher.new(@migration, connection)
32
32
  switcher.run
33
33
 
34
- slave do
34
+ replica do
35
35
  value(data_source_exists?(@origin)).must_equal true
36
36
  value(table_read(@migration.archive_name).columns.keys).must_include 'origin'
37
37
  end
@@ -41,7 +41,7 @@ describe Lhm::LockedSwitcher do
41
41
  switcher = Lhm::LockedSwitcher.new(@migration, connection)
42
42
  switcher.run
43
43
 
44
- slave do
44
+ replica do
45
45
  value(data_source_exists?(@destination)).must_equal false
46
46
  value(table_read(@origin.name).columns.keys).must_include 'destination'
47
47
  end
@@ -38,7 +38,7 @@ describe Lhm::SqlRetry, "ProxiSQL tests for LHM retry" do
38
38
  end
39
39
  end
40
40
  assert_equal Lhm::Error, e.class
41
- assert_match(/LHM tried the reconnection procedure but failed. Latest error:/, e.message)
41
+ assert_match(/LHM tried the reconnection procedure but failed. Aborting/, e.message)
42
42
  end
43
43
 
44
44
  it "Will retry until connection is achieved" do
@@ -61,6 +61,7 @@ describe Lhm::SqlRetry, "ProxiSQL tests for LHM retry" do
61
61
  it "Will abort if new writer is not same host" do
62
62
  # The hostname will be constant before the blip
63
63
  Lhm::SqlRetry.any_instance.stubs(:hostname).returns("mysql-1").then.returns("mysql-2")
64
+ Lhm::SqlRetry.any_instance.stubs(:server_id).returns(1).then.returns(2)
64
65
 
65
66
  # Need new instance for stub to take into effect
66
67
  lhm_retry = Lhm::SqlRetry.new(@connection, retry_options: {},
@@ -76,12 +77,12 @@ describe Lhm::SqlRetry, "ProxiSQL tests for LHM retry" do
76
77
  end
77
78
 
78
79
  assert_equal e.class, Lhm::Error
79
- assert_match(/LHM tried the reconnection procedure but failed. Latest error: Reconnected to wrong host/, e.message)
80
+ assert_match(/LHM tried the reconnection procedure but failed. Aborting/, e.message)
80
81
 
81
82
  logs = @logger.string.split("\n")
82
83
 
83
84
  assert logs.first.include?("Lost connection to MySQL, will retry to connect to same host")
84
- assert logs.last.include?("Lost connection to MySQL server at 'reading initial communication packet")
85
+ assert logs.last.include?("Reconnected to wrong host. Started migration on: mysql-1 (server_id: 1), but reconnected to: mysql-2 (server_id: 2).")
85
86
  end
86
87
 
87
88
  it "Will abort if failover happens (mimicked with proxySQL)" do
@@ -98,11 +99,11 @@ describe Lhm::SqlRetry, "ProxiSQL tests for LHM retry" do
98
99
  end
99
100
 
100
101
  assert_equal e.class, Lhm::Error
101
- assert_match(/LHM tried the reconnection procedure but failed. Latest error: Reconnected to wrong host/, e.message)
102
+ assert_match(/LHM tried the reconnection procedure but failed. Aborting/, e.message)
102
103
 
103
104
  logs = @logger.string.split("\n")
104
105
 
105
106
  assert logs.first.include?("Lost connection to MySQL, will retry to connect to same host")
106
- assert logs.last.include?("Lost connection to MySQL server at 'reading initial communication packet")
107
+ assert logs.last.include?("Reconnected to wrong host. Started migration on: mysql-1 (server_id: 1), but reconnected to: mysql-2 (server_id: 2).")
107
108
  end
108
109
  end
@@ -7,7 +7,7 @@ module ToxiproxyHelper
7
7
  def included(base)
8
8
  Toxiproxy.reset
9
9
 
10
- # listen on localhost, but toxiproxy is in a container itself, thus the upstream uses the Docker-Compose DNS
10
+ # listen on localhost, but toxiproxy is in a container itself, thus the upstream uses the Podman-Compose DNS
11
11
  Toxiproxy.populate(
12
12
  [
13
13
  {
data/spec/test_helper.rb CHANGED
@@ -28,6 +28,9 @@ logger = Logger.new STDOUT
28
28
  logger.level = Logger::WARN
29
29
  Lhm.logger = logger
30
30
 
31
+ # Want test to be efficient without having to wait the normal value of 120s
32
+ Lhm::SqlRetry::RECONNECT_RETRY_MAX_ITERATION = 4
33
+
31
34
  def without_verbose(&block)
32
35
  old_verbose, $VERBOSE = $VERBOSE, nil
33
36
  yield
@@ -70,15 +70,11 @@ describe Lhm::Printer do
70
70
  end
71
71
 
72
72
  it 'prints the dots' do
73
- mock = MiniTest::Mock.new
74
- 10.times do
75
- mock.expect(:write, :return_value, ['.'])
76
- end
73
+ mock = mock("output")
74
+ mock.expects(:write).with('.').times(10)
77
75
 
78
76
  @printer.instance_variable_set(:@output, mock)
79
77
  10.times { @printer.notify }
80
-
81
- mock.verify
82
78
  end
83
79
 
84
80
  end
@@ -22,7 +22,7 @@ describe Lhm::SqlHelper do
22
22
  end
23
23
 
24
24
  it 'should quote column names in index specification' do
25
- value(Lhm::SqlHelper.idx_spec(['title(10)', 'album']))
26
- .must_equal('`title`(10), `album`')
25
+ value(Lhm::SqlHelper.idx_spec(['title(10)', 'name (6)', 'album']))
26
+ .must_equal('`title`(10), `name`(6), `album`')
27
27
  end
28
28
  end