active_record_shards 2.7.3 → 2.7.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -39,21 +39,32 @@ module ActiveRecord
39
39
 
40
40
  # list of pending migrations is any migrations that haven't run on all shards.
41
41
  def pending_migrations
42
- migration_counts = Hash.new(0)
43
- ActiveRecord::Base.on_shard(nil) do
44
- migrated.each { |v| migration_counts[v] += 1 }
45
- end
42
+ pending, missing = self.class.shard_status(migrations.map(&:version))
43
+ pending = pending.values.flatten
44
+ migrations.select { |m| pending.include?(m.version) }
45
+ end
46
46
 
47
- shard_count = 1
48
- ActiveRecord::Base.on_all_shards do
49
- migrated.each { |v| migration_counts[v] += 1 }
50
- shard_count += 1
51
- end
47
+ # public
48
+ # list of pending and missing versions per shard
49
+ # [{1 => [1234567]}, {1 => [2345678]}]
50
+ def self.shard_status(versions)
51
+ pending = {}
52
+ missing = {}
53
+
54
+ collect = lambda do |shard|
55
+ migrated = get_all_versions
52
56
 
53
- migrations.select do |m|
54
- count = migration_counts[m.version]
55
- count.nil? || count < shard_count
57
+ p = versions - migrated
58
+ pending[shard] = p if p.any?
59
+
60
+ m = migrated - versions
61
+ missing[shard] = m if m.any?
56
62
  end
63
+
64
+ ActiveRecord::Base.on_shard(nil) { collect.call(nil) }
65
+ ActiveRecord::Base.on_all_shards { |shard| collect.call(shard) }
66
+
67
+ return pending, missing
57
68
  end
58
69
  end
59
70
  end
@@ -32,8 +32,7 @@ module ActiveRecordShards
32
32
  end
33
33
 
34
34
  module InstanceMethods
35
- def after_initialize_with_slave
36
- after_initialize_without_slave if respond_to?(:after_initialize_without_slave)
35
+ def initialize_shard_and_slave
37
36
  @from_slave = !!self.class.current_shard_selection.options[:slave]
38
37
  @from_shard = self.class.current_shard_selection.options[:shard]
39
38
  end
@@ -49,16 +48,11 @@ module ActiveRecordShards
49
48
 
50
49
  def self.extended(base)
51
50
  base.send(:include, InstanceMethods)
52
-
53
- if ActiveRecord::VERSION::MAJOR >= 3
54
- base.after_initialize :after_initialize_with_slave
55
- else
56
- if base.method_defined?(:after_initialize)
57
- base.alias_method_chain :after_initialize, :slave
58
- else
59
- base.send(:alias_method, :after_initialize, :after_initialize_with_slave)
60
- end
51
+ if ActiveRecord::VERSION::MAJOR == 2 && !base.method_defined?(:after_initialize)
52
+ # trick rails 2 into running callbacks
53
+ base.send(:define_method, :after_initialize){}
61
54
  end
55
+ base.after_initialize :initialize_shard_and_slave
62
56
  end
63
57
  end
64
58
  end
@@ -1,14 +1,14 @@
1
1
  require_relative 'helper'
2
2
 
3
- class ConfigurationParserTest < ActiveSupport::TestCase
4
- context "exploding the database.yml" do
5
- setup do
3
+ describe ActiveRecordShards::ConfigurationParser do
4
+ describe "exploding the database.yml" do
5
+ before do
6
6
  @exploded_conf = ActiveRecordShards::ConfigurationParser.explode(YAML::load(IO.read(File.dirname(__FILE__) + '/database_parse_test.yml')))
7
7
  end
8
8
 
9
- context "main slave" do
10
- setup { @conf = @exploded_conf['test_slave'] }
11
- should "be exploded" do
9
+ describe "main slave" do
10
+ before { @conf = @exploded_conf['test_slave'] }
11
+ it "be exploded" do
12
12
  @conf["shard_names"] = @conf["shard_names"].to_set
13
13
  assert_equal({
14
14
  "adapter" => "mysql",
@@ -23,10 +23,10 @@ class ConfigurationParserTest < ActiveSupport::TestCase
23
23
  end
24
24
  end
25
25
 
26
- context "shard a" do
27
- context "master" do
28
- setup { @conf = @exploded_conf['test_shard_a'] }
29
- should "be exploded" do
26
+ describe "shard a" do
27
+ describe "master" do
28
+ before { @conf = @exploded_conf['test_shard_a'] }
29
+ it "be exploded" do
30
30
  @conf["shard_names"] = @conf["shard_names"].to_set
31
31
  assert_equal({
32
32
  "adapter" => "mysql",
@@ -41,9 +41,9 @@ class ConfigurationParserTest < ActiveSupport::TestCase
41
41
  end
42
42
  end
43
43
 
44
- context "slave" do
45
- setup { @conf = @exploded_conf['test_shard_a_slave'] }
46
- should "be exploded" do
44
+ describe "slave" do
45
+ before { @conf = @exploded_conf['test_shard_a_slave'] }
46
+ it "be exploded" do
47
47
  @conf["shard_names"] = @conf["shard_names"].to_set
48
48
  assert_equal({
49
49
  "adapter" => "mysql",
@@ -59,10 +59,10 @@ class ConfigurationParserTest < ActiveSupport::TestCase
59
59
  end
60
60
  end
61
61
 
62
- context "shard b" do
63
- context "master" do
64
- setup { @conf = @exploded_conf['test_shard_b'] }
65
- should "be exploded" do
62
+ describe "shard b" do
63
+ describe "master" do
64
+ before { @conf = @exploded_conf['test_shard_b'] }
65
+ it "be exploded" do
66
66
  @conf["shard_names"] = @conf["shard_names"].to_set
67
67
  assert_equal({
68
68
  "adapter" => "mysql",
@@ -77,9 +77,9 @@ class ConfigurationParserTest < ActiveSupport::TestCase
77
77
  end
78
78
  end
79
79
 
80
- context "slave" do
81
- setup { @conf = @exploded_conf['test_shard_b_slave'] }
82
- should "be exploded" do
80
+ describe "slave" do
81
+ before { @conf = @exploded_conf['test_shard_b_slave'] }
82
+ it "be exploded" do
83
83
  @conf["shard_names"] = @conf["shard_names"].to_set
84
84
  assert_equal({
85
85
  "adapter" => "mysql",
@@ -1,8 +1,10 @@
1
1
  require_relative 'helper'
2
2
 
3
- class ConnectionSwitchingTest < ActiveSupport::TestCase
4
- context "shard switching" do
5
- should "only switch connection on sharded models" do
3
+ describe "connection switching" do
4
+ i_suck_and_my_tests_are_order_dependent!
5
+
6
+ describe "shard switching" do
7
+ it "only switch connection on sharded models" do
6
8
  assert_using_database('ars_test', Ticket)
7
9
  assert_using_database('ars_test', Account)
8
10
 
@@ -12,7 +14,7 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
12
14
  end
13
15
  end
14
16
 
15
- should "switch to shard and back" do
17
+ it "switch to shard and back" do
16
18
  assert_using_database('ars_test')
17
19
  ActiveRecord::Base.on_slave { assert_using_database('ars_test_slave') }
18
20
 
@@ -33,22 +35,22 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
33
35
  ActiveRecord::Base.on_slave { assert_using_database('ars_test_slave') }
34
36
  end
35
37
 
36
- context "on_first_shard" do
37
- should "use the first shard" do
38
+ describe "on_first_shard" do
39
+ it "use the first shard" do
38
40
  ActiveRecord::Base.on_first_shard {
39
41
  assert_using_database('ars_test_shard0')
40
42
  }
41
43
  end
42
44
  end
43
45
 
44
- context "on_all_shards" do
45
- setup do
46
+ describe "on_all_shards" do
47
+ before do
46
48
  @shard_0_master = ActiveRecord::Base.on_shard(0) {ActiveRecord::Base.connection}
47
49
  @shard_1_master = ActiveRecord::Base.on_shard(1) {ActiveRecord::Base.connection}
48
- assert_not_equal(@shard_0_master.select_value("SELECT DATABASE()"), @shard_1_master.select_value("SELECT DATABASE()"))
50
+ refute_equal(@shard_0_master.select_value("SELECT DATABASE()"), @shard_1_master.select_value("SELECT DATABASE()"))
49
51
  end
50
52
 
51
- should "execute the block on all shard masters" do
53
+ it "execute the block on all shard masters" do
52
54
  result = ActiveRecord::Base.on_all_shards do |shard|
53
55
  [ActiveRecord::Base.connection.select_value("SELECT DATABASE()"), shard]
54
56
  end
@@ -56,15 +58,15 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
56
58
  database_shards = result.map(&:last)
57
59
 
58
60
  assert_equal(2, database_names.size)
59
- assert_contains(database_names, @shard_0_master.select_value("SELECT DATABASE()"))
60
- assert_contains(database_names, @shard_1_master.select_value("SELECT DATABASE()"))
61
+ assert_includes(database_names, @shard_0_master.select_value("SELECT DATABASE()"))
62
+ assert_includes(database_names, @shard_1_master.select_value("SELECT DATABASE()"))
61
63
 
62
64
  assert_equal(2, database_shards.size)
63
- assert_contains(database_shards, "0")
64
- assert_contains(database_shards, "1")
65
+ assert_includes(database_shards, "0")
66
+ assert_includes(database_shards, "1")
65
67
  end
66
68
 
67
- should "execute the block unsharded" do
69
+ it "execute the block unsharded" do
68
70
  ActiveRecord::Base.expects(:supports_sharding?).returns false
69
71
  result = ActiveRecord::Base.on_all_shards do |shard|
70
72
  [ActiveRecord::Base.connection.select_value("SELECT DATABASE()"), shard]
@@ -74,33 +76,33 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
74
76
  end
75
77
  end
76
78
 
77
- context "default shard selection" do
78
- context "of nil" do
79
- setup do
79
+ describe "default shard selection" do
80
+ describe "of nil" do
81
+ before do
80
82
  ActiveRecord::Base.default_shard = nil
81
83
  end
82
84
 
83
- should "use unsharded db for sharded models" do
85
+ it "use unsharded db for sharded models" do
84
86
  assert_using_database('ars_test', Ticket)
85
87
  assert_using_database('ars_test', Account)
86
88
  end
87
89
  end
88
90
 
89
- context "value" do
90
- setup do
91
+ describe "value" do
92
+ before do
91
93
  ActiveRecord::Base.default_shard = 0
92
94
  end
93
95
 
94
- teardown do
96
+ after do
95
97
  ActiveRecord::Base.default_shard = nil
96
98
  end
97
99
 
98
- should "use default shard db for sharded models" do
100
+ it "use default shard db for sharded models" do
99
101
  assert_using_database('ars_test_shard0', Ticket)
100
102
  assert_using_database('ars_test', Account)
101
103
  end
102
104
 
103
- should "still be able to switch to shard nil" do
105
+ it "still be able to switch to shard nil" do
104
106
  ActiveRecord::Base.on_shard(nil) do
105
107
  assert_using_database('ars_test', Ticket)
106
108
  assert_using_database('ars_test', Account)
@@ -109,44 +111,44 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
109
111
  end
110
112
  end
111
113
 
112
- context "ActiveRecord::Base.columns" do
113
- setup do
114
+ describe "ActiveRecord::Base.columns" do
115
+ before do
114
116
  ActiveRecord::Base.default_shard = nil
115
117
  end
116
118
 
117
- context "for unsharded models" do
118
- should "use the non-sharded connection" do
119
+ describe "for unsharded models" do
120
+ it "use the non-sharded connection" do
119
121
  assert_using_database('ars_test', Account)
120
122
  Account.connection.execute("alter table accounts add column foo int")
121
123
 
122
124
  assert Account.column_names.include?('foo')
123
125
  end
124
126
 
125
- teardown do
127
+ after do
126
128
  ActiveRecord::Base.connection.execute("alter table accounts drop column foo")
127
129
  Account.reset_column_information
128
130
  end
129
131
  end
130
132
 
131
- context "for sharded models" do
132
- setup do
133
+ describe "for sharded models" do
134
+ before do
133
135
  ActiveRecord::Base.on_first_shard do
134
136
  ActiveRecord::Base.connection.execute("alter table tickets add column foo int")
135
137
  end
136
138
  end
137
139
 
138
- teardown do
140
+ after do
139
141
  ActiveRecord::Base.on_first_shard do
140
142
  ActiveRecord::Base.connection.execute("alter table tickets drop column foo")
141
143
  Ticket.reset_column_information
142
144
  end
143
145
  end
144
146
 
145
- should "get colmns from the first shard" do
147
+ it "get colmns from the first shard" do
146
148
  assert Ticket.column_names.include?('foo')
147
149
  end
148
150
 
149
- should "have correct from_shard" do
151
+ it "have correct from_shard" do
150
152
  ActiveRecord::Base.on_all_shards do |shard|
151
153
  assert_equal shard, Ticket.new.from_shard
152
154
  end
@@ -154,13 +156,13 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
154
156
  end
155
157
  end
156
158
 
157
- context "ActiveRecord::Base.table_exists?" do
158
- setup do
159
+ describe "ActiveRecord::Base.table_exists?" do
160
+ before do
159
161
  ActiveRecord::Base.default_shard = nil
160
162
  end
161
163
 
162
- context "for unsharded models" do
163
- should "use the unsharded connection" do
164
+ describe "for unsharded models" do
165
+ it "use the unsharded connection" do
164
166
  class UnshardedModel < ActiveRecord::Base
165
167
  not_sharded
166
168
  end
@@ -173,8 +175,8 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
173
175
  end
174
176
  end
175
177
 
176
- context "for sharded models" do
177
- should "try the first shard" do
178
+ describe "for sharded models" do
179
+ it "try the first shard" do
178
180
  class ShardedModel < ActiveRecord::Base
179
181
  end
180
182
 
@@ -187,31 +189,31 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
187
189
  end
188
190
  end
189
191
 
190
- context "in an unsharded environment" do
191
- setup do
192
+ describe "in an unsharded environment" do
193
+ before do
192
194
  silence_warnings { ::RAILS_ENV = 'test2' }
193
195
  ActiveRecord::Base.establish_connection(::RAILS_ENV)
194
196
  assert_using_database('ars_test2', Ticket)
195
197
  end
196
198
 
197
- teardown do
199
+ after do
198
200
  silence_warnings { ::RAILS_ENV = 'test' }
199
201
  ActiveRecord::Base.establish_connection(::RAILS_ENV)
200
202
  assert_using_database('ars_test', Ticket)
201
203
  end
202
204
 
203
205
  if ActiveRecord::VERSION::MAJOR >= 3
204
- should "be able to find by column" do
206
+ it "be able to find by column" do
205
207
  Account.where(:name => "peter").to_sql # does not blow up
206
208
  end
207
209
 
208
- should "have correct engine" do
210
+ it "have correct engine" do
209
211
  assert_equal Account, Account.arel_engine
210
212
  end
211
213
  end
212
214
 
213
- context "shard switching" do
214
- should "just stay on the main db" do
215
+ describe "shard switching" do
216
+ it "just stay on the main db" do
215
217
  assert_using_database('ars_test2', Ticket)
216
218
  assert_using_database('ars_test2', Account)
217
219
 
@@ -222,31 +224,31 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
222
224
  end
223
225
  end
224
226
 
225
- context "on_all_shards" do
226
- setup do
227
+ describe "on_all_shards" do
228
+ before do
227
229
  @database_names = []
228
230
  ActiveRecord::Base.on_all_shards do
229
231
  @database_names << ActiveRecord::Base.connection.select_value("SELECT DATABASE()")
230
232
  end
231
233
  end
232
234
 
233
- should "execute the block on all shard masters" do
235
+ it "execute the block on all shard masters" do
234
236
  @database_names
235
237
  assert_equal([ActiveRecord::Base.connection.select_value("SELECT DATABASE()")], @database_names)
236
238
  end
237
239
  end
238
240
  end
239
241
 
240
- context "slave driving" do
241
- context "without slave configuration" do
242
+ describe "slave driving" do
243
+ describe "without slave configuration" do
242
244
 
243
- setup do
245
+ before do
244
246
  ActiveRecord::Base.configurations.delete('test_slave')
245
247
  ActiveRecord::Base.connection_handler.connection_pools.clear
246
248
  ActiveRecord::Base.establish_connection('test')
247
249
  end
248
250
 
249
- should "default to the master database" do
251
+ it "default to the master database" do
250
252
  Account.create!
251
253
 
252
254
  ActiveRecord::Base.on_slave { assert_using_master_db }
@@ -254,7 +256,7 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
254
256
  Ticket.on_slave { assert_using_master_db }
255
257
  end
256
258
 
257
- should "successfully execute queries" do
259
+ it "successfully execute queries" do
258
260
  Account.create!
259
261
  assert_using_master_db
260
262
 
@@ -264,9 +266,9 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
264
266
 
265
267
  end
266
268
 
267
- context "with slave configuration" do
269
+ describe "with slave configuration" do
268
270
 
269
- should "successfully execute queries" do
271
+ it "successfully execute queries" do
270
272
  assert_using_master_db
271
273
  Account.create!
272
274
 
@@ -274,7 +276,7 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
274
276
  assert_equal(0, ActiveRecord::Base.on_slave { Account.count })
275
277
  end
276
278
 
277
- should "support global on_slave blocks" do
279
+ it "support global on_slave blocks" do
278
280
  assert_using_master_db
279
281
  assert_using_master_db
280
282
 
@@ -287,7 +289,7 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
287
289
  assert_using_master_db
288
290
  end
289
291
 
290
- should "support conditional methods" do
292
+ it "support conditional methods" do
291
293
  assert_using_master_db
292
294
 
293
295
  Account.on_slave_if(true) do
@@ -309,8 +311,8 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
309
311
  end
310
312
  end
311
313
 
312
- context "a model loaded with the slave" do
313
- setup do
314
+ describe "a model loaded with the slave" do
315
+ before do
314
316
  Account.connection.execute("INSERT INTO accounts (id, name, created_at, updated_at) VALUES(1000, 'master_name', '2009-12-04 20:18:48', '2009-12-04 20:18:48')")
315
317
  assert(Account.find(1000))
316
318
  assert_equal('master_name', Account.find(1000).name)
@@ -322,23 +324,23 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
322
324
  assert_equal('slave_name', @model.name)
323
325
  end
324
326
 
325
- should "read from master on reload" do
327
+ it "read from master on reload" do
326
328
  @model.reload
327
329
  assert_equal('master_name', @model.name)
328
330
  end
329
331
 
330
- should "be marked as read only" do
332
+ it "be marked as read only" do
331
333
  assert(@model.readonly?)
332
334
  end
333
335
 
334
- should "be marked as comming from the slave" do
336
+ it "be marked as comming from the slave" do
335
337
  assert(@model.from_slave?)
336
338
  end
337
339
  end
338
340
 
339
- context "a inherited model without cached columns hash" do
341
+ describe "a inherited model without cached columns hash" do
340
342
  # before columns -> with_scope -> type-condition -> columns == loop
341
- should "not loop when on slave by default" do
343
+ it "not loop when on slave by default" do
342
344
  Person.on_slave_by_default = true
343
345
  assert User.on_slave_by_default?
344
346
  assert User.finder_needs_type_condition?
@@ -348,8 +350,8 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
348
350
  end
349
351
  end
350
352
 
351
- context "a model loaded with the master" do
352
- setup do
353
+ describe "a model loaded with the master" do
354
+ before do
353
355
  Account.connection.execute("INSERT INTO accounts (id, name, created_at, updated_at) VALUES(1000, 'master_name', '2009-12-04 20:18:48', '2009-12-04 20:18:48')")
354
356
  @model = Account.first
355
357
  assert(@model)
@@ -358,57 +360,57 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
358
360
 
359
361
  # TODO mocha raises stack level too deep on ActiveRecord 3.2+
360
362
  if ActiveRecord::VERSION::STRING < "3.2.0"
361
- should "not unnecessary call with_scope" do
363
+ it "not unnecessary call with_scope" do
362
364
  Account.expects(:with_scope).never
363
365
  Account.on_master.first
364
366
  end
365
367
  end
366
368
 
367
- should "not unset readonly" do
369
+ it "not unset readonly" do
368
370
  @model = Account.on_master.scoped(:readonly => true).first
369
371
  assert(@model.readonly?)
370
372
  end
371
373
 
372
- should "not be marked as read only" do
374
+ it "not be marked as read only" do
373
375
  assert(!@model.readonly?)
374
376
  end
375
377
 
376
- should "not be marked as comming from the slave" do
378
+ it "not be marked as comming from the slave" do
377
379
  assert(!@model.from_slave?)
378
380
  end
379
381
  end
380
382
 
381
383
  # TODO: make all this stuff rails 3 compatible.
382
- context "with finds routed to the slave by default" do
383
- setup do
384
+ describe "with finds routed to the slave by default" do
385
+ before do
384
386
  Account.on_slave_by_default = true
385
387
  Account.connection.execute("INSERT INTO accounts (id, name, created_at, updated_at) VALUES(1000, 'master_name', '2009-12-04 20:18:48', '2009-12-04 20:18:48')")
386
388
  Account.on_slave.connection.execute("INSERT INTO accounts (id, name, created_at, updated_at) VALUES(1000, 'slave_name', '2009-12-04 20:18:48', '2009-12-04 20:18:48')")
387
389
  Account.on_slave.connection.execute("INSERT INTO accounts (id, name, created_at, updated_at) VALUES(1001, 'slave_name2', '2009-12-04 20:18:48', '2009-12-04 20:18:48')")
388
390
  end
389
391
 
390
- should "find() by default on the slave" do
392
+ it "find() by default on the slave" do
391
393
  account = Account.find(1000)
392
394
  assert_equal 'slave_name', account.name
393
395
  end
394
396
 
395
- should "count() by default on the slave" do
397
+ it "count() by default on the slave" do
396
398
  count = Account.all.size
397
399
  assert_equal 2, count
398
400
  end
399
401
 
400
- should "reload() on the master" do
402
+ it "reload() on the master" do
401
403
  account = Account.find(1000)
402
404
  assert_equal 'master_name', account.reload.name
403
405
  end
404
406
 
405
- should "do exists? on the slave" do
407
+ it "do exists? on the slave" do
406
408
  if Account.respond_to?(:exists?)
407
409
  assert Account.exists?(1001)
408
410
  end
409
411
  end
410
412
 
411
- should "count associations on the slave" do
413
+ it "count associations on the slave" do
412
414
  AccountThing.on_slave_by_default = true
413
415
  Account.on_slave.connection.execute("INSERT INTO account_things (id, account_id) VALUES(123123, 1000)")
414
416
  Account.on_slave.connection.execute("INSERT INTO account_things (id, account_id) VALUES(123124, 1000)")
@@ -416,57 +418,64 @@ class ConnectionSwitchingTest < ActiveSupport::TestCase
416
418
  AccountThing.on_slave_by_default = false
417
419
  end
418
420
 
419
- should "Allow override using on_master" do
421
+ it "Allow override using on_master" do
420
422
  model = Account.on_master.find(1000)
421
423
  assert_equal "master_name", model.name
422
424
  end
423
425
 
424
- should "not override on_master with on_slave" do
426
+ it "not override on_master with on_slave" do
425
427
  model = Account.on_master { Account.on_slave.find(1000) }
426
428
  assert_equal "master_name", model.name
427
429
  end
428
430
 
429
- should "override on_slave with on_master" do
431
+ it "override on_slave with on_master" do
430
432
  model = Account.on_slave { Account.on_master.find(1000) }
431
433
  assert_equal "master_name", model.name
432
434
  end
433
435
 
434
- should "propogate the default_slave setting to inherited classes" do
436
+ it "propogate the default_slave setting to inherited classes" do
435
437
  assert AccountInherited.on_slave_by_default?
436
438
  end
437
439
 
438
- teardown do
440
+ after do
439
441
  Account.on_slave_by_default = false
440
442
  end
441
443
  end
442
444
  end
443
445
 
444
- context "slave proxy" do
445
- should "successfully execute queries" do
446
+ describe "slave proxy" do
447
+ it "successfully execute queries" do
446
448
  assert_using_master_db
447
449
  Account.create!
448
450
 
449
- assert_not_equal Account.count, Account.on_slave.count
451
+ refute_equal Account.count, Account.on_slave.count
450
452
  end
451
453
 
452
- should "work on association collections" do
453
- assert_using_master_db
454
- account = Account.create!
454
+ it "work on association collections" do
455
+ begin
456
+ assert_using_master_db
457
+ account = Account.create!
455
458
 
456
- account.tickets.create! :title => 'master ticket'
459
+ account.tickets.create! :title => 'master ticket'
457
460
 
458
- Ticket.on_slave {
459
- account.tickets.create! :title => 'slave ticket'
460
- }
461
+ Ticket.on_slave {
462
+ account.tickets.create! :title => 'slave ticket'
463
+ }
461
464
 
462
- assert_equal "master ticket", account.tickets.first.title
463
- assert_equal "slave ticket", account.tickets.on_slave.first.title
465
+ assert_equal "master ticket", account.tickets.first.title
466
+ assert_equal "slave ticket", account.tickets.on_slave.first.title
467
+ rescue Exception
468
+ retried ||= 0
469
+ retried += 1
470
+ puts "Failed in #{__LINE__}##{retried}"
471
+ retry if retried < 3
472
+ end
464
473
  end
465
474
  end
466
475
  end
467
476
 
468
- context "alternative connections" do
469
- should "not interfere with other connections" do
477
+ describe "alternative connections" do
478
+ it "not interfere with other connections" do
470
479
  assert_using_database('ars_test', Account)
471
480
  assert_using_database('ars_test', Ticket)
472
481
  assert_using_database('ars_test_alternative', Email)
data/test/helper.rb CHANGED
@@ -1,9 +1,8 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- require 'test/unit'
1
+ require 'bundler/setup'
2
+ Bundler.require
4
3
 
5
- Bundler.setup
6
- Bundler.require(:default, :development)
4
+ require 'minitest/autorun'
5
+ MiniTest::Reporters.use! MiniTest::Reporters::DefaultReporter.new
7
6
 
8
7
  if defined?(Debugger)
9
8
  ::Debugger.start
@@ -14,7 +13,6 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
13
  $LOAD_PATH.unshift(File.dirname(__FILE__))
15
14
  require 'active_record_shards'
16
15
  require 'logger'
17
- require 'shoulda'
18
16
 
19
17
  RAILS_ENV = "test"
20
18
 
@@ -34,7 +32,7 @@ init_schema
34
32
  require 'models'
35
33
 
36
34
  require 'active_support/test_case'
37
- class ActiveSupport::TestCase
35
+ class Minitest::Spec
38
36
  def clear_databases
39
37
  ActiveRecord::Base.configurations.each do |name, conf|
40
38
  ActiveRecord::Base.establish_connection(name)
@@ -43,7 +41,7 @@ class ActiveSupport::TestCase
43
41
  end
44
42
  ActiveRecord::Base.establish_connection(RAILS_ENV)
45
43
  end
46
- setup :clear_databases
44
+ before { clear_databases }
47
45
 
48
46
  def assert_using_master_db
49
47
  assert_using_database('ars_test')
@@ -10,12 +10,12 @@ class CowardlyMigration < ActiveRecord::Migration
10
10
  end
11
11
  end
12
12
 
13
- class MigratorTest < ActiveSupport::TestCase
14
- def setup
13
+ describe ActiveRecord::Migrator do
14
+ before do
15
15
  init_schema
16
16
  end
17
17
 
18
- def test_migrator
18
+ it "migrates" do
19
19
  migration_path = File.join(File.dirname(__FILE__), "/migrations")
20
20
  ActiveRecord::Migrator.migrate(migration_path)
21
21
  ActiveRecord::Base.on_all_shards do
@@ -57,7 +57,7 @@ class MigratorTest < ActiveSupport::TestCase
57
57
  end
58
58
  end
59
59
 
60
- def test_bad_migration
60
+ it "does not migrate bad migrations" do
61
61
  migration_path = File.join(File.dirname(__FILE__), "/cowardly_migration")
62
62
  exception = nil
63
63
  begin
@@ -68,7 +68,7 @@ class MigratorTest < ActiveSupport::TestCase
68
68
  assert e
69
69
  end
70
70
 
71
- def test_failing_migration
71
+ it "fails with failing migrations" do
72
72
  # like, if you have to break a migration in the middle somewhere.
73
73
  migration_path = File.join(File.dirname(__FILE__), "/failure_migration")
74
74
 
@@ -87,7 +87,22 @@ class MigratorTest < ActiveSupport::TestCase
87
87
  end
88
88
  end
89
89
 
90
+ describe "#shard_status" do
91
+ it "shows nothing if everything is ok" do
92
+ ActiveRecord::Migrator.shard_status([1]).must_equal([{}, {}])
93
+ end
94
+
95
+ it "shows missing migrations" do
96
+ ActiveRecord::Migrator.shard_status([]).must_equal([{}, {nil => [1], "0" => [1], "1" => [1]}])
97
+ end
98
+
99
+ it "shows pending migrations" do
100
+ ActiveRecord::Migrator.shard_status([1, 2]).must_equal([{nil => [2], "0" => [2], "1" => [2]}, {}])
101
+ end
102
+ end
103
+
90
104
  private
105
+
91
106
  def failure_migration_pending?(migration_path)
92
107
  ActiveRecord::Migrator.new(:up, migration_path).pending_migrations.detect { |f| f.name == "FailureMigration" }
93
108
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_shards
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.3
4
+ version: 2.7.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2013-06-06 00:00:00.000000000 Z
14
+ date: 2013-07-16 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activerecord
@@ -89,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
89
  version: '0'
90
90
  requirements: []
91
91
  rubyforge_project:
92
- rubygems_version: 1.8.21
92
+ rubygems_version: 1.8.25
93
93
  signing_key:
94
94
  specification_version: 3
95
95
  summary: Simple database switching for ActiveRecord.
@@ -106,3 +106,4 @@ test_files:
106
106
  - test/migrator_test.rb
107
107
  - test/models.rb
108
108
  - test/schema.rb
109
+ has_rdoc: