switchman 1.2.10 → 1.2.11
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/app/models/switchman/shard.rb +2 -2
- data/lib/switchman/active_record/connection_handler.rb +18 -9
- data/lib/switchman/active_record/connection_pool.rb +3 -0
- data/lib/switchman/active_record/query_cache.rb +6 -1
- data/lib/switchman/active_record/query_methods.rb +1 -1
- data/lib/switchman/connection_pool_proxy.rb +1 -1
- data/lib/switchman/r_spec_helper.rb +73 -61
- data/lib/switchman/test_helper.rb +8 -2
- data/lib/switchman/version.rb +1 -1
- data/lib/tasks/switchman.rake +5 -0
- data/spec/dummy/config/database.yml +2 -4
- data/spec/dummy/config/environments/development.rb +0 -4
- data/spec/dummy/config/environments/test.rb +1 -1
- data/spec/dummy/db/schema.rb +12 -12
- data/spec/dummy/db/shard_120.sqlite3 +0 -0
- data/spec/dummy/db/shard_156.sqlite3 +0 -0
- data/spec/dummy/db/shard_193.sqlite3 +0 -0
- data/spec/dummy/db/shard_23.sqlite3 +0 -0
- data/spec/dummy/db/shard_234.sqlite3 +0 -0
- data/spec/dummy/db/shard_257.sqlite3 +0 -0
- data/spec/dummy/db/shard_277.sqlite3 +0 -0
- data/spec/dummy/db/shard_311.sqlite3 +0 -0
- data/spec/dummy/db/shard_324.sqlite3 +0 -0
- data/spec/dummy/db/shard_342.sqlite3 +0 -0
- data/spec/dummy/db/shard_375.sqlite3 +0 -0
- data/spec/dummy/db/shard_389.sqlite3 +0 -0
- data/spec/dummy/db/shard_428.sqlite3 +0 -0
- data/spec/dummy/db/shard_452.sqlite3 +0 -0
- data/spec/dummy/db/shard_462.sqlite3 +0 -0
- data/spec/dummy/db/shard_483.sqlite3 +0 -0
- data/spec/dummy/db/shard_508.sqlite3 +0 -0
- data/spec/dummy/db/shard_531.sqlite3 +0 -0
- data/spec/dummy/db/shard_554.sqlite3 +0 -0
- data/spec/dummy/db/shard_577.sqlite3 +0 -0
- data/spec/dummy/db/shard_58.sqlite3 +0 -0
- data/spec/dummy/db/shard_600.sqlite3 +0 -0
- data/spec/dummy/db/shard_623.sqlite3 +0 -0
- data/spec/dummy/db/shard_646.sqlite3 +0 -0
- data/spec/dummy/db/shard_668.sqlite3 +0 -0
- data/spec/dummy/db/shard_680.sqlite3 +0 -0
- data/spec/dummy/db/shard_708.sqlite3 +0 -0
- data/spec/dummy/db/shard_735.sqlite3 +0 -0
- data/spec/dummy/db/shard_753.sqlite3 +0 -0
- data/spec/dummy/db/shard_76.sqlite3 +0 -0
- data/spec/dummy/db/shard_802.sqlite3 +0 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +7 -0
- data/spec/dummy/log/test.log +106293 -0
- data/spec/dummy/tmp/cache/313/970/shard%2F30 +1 -0
- data/spec/dummy/tmp/cache/316/980/shard%2F15 +1 -0
- data/spec/dummy/tmp/cache/317/9D0/shard%2F52 +1 -0
- data/spec/dummy/tmp/cache/31C/A40/shard%2F75 +1 -0
- data/spec/dummy/tmp/cache/345/E00/shard%2F500 +1 -0
- data/spec/dummy/tmp/cache/346/DF0/shard%2F321 +1 -0
- data/spec/dummy/tmp/cache/349/DE0/shard%2F126 +1 -0
- data/spec/dummy/tmp/cache/349/E10/shard%2F153 +0 -0
- data/spec/dummy/tmp/cache/349/E20/shard%2F243 +1 -0
- data/spec/dummy/tmp/cache/34A/E20/shard%2F154 +0 -0
- data/spec/dummy/tmp/cache/34A/E40/shard%2F172 +1 -0
- data/spec/dummy/tmp/cache/34A/E70/shard%2F523 +1 -0
- data/spec/dummy/tmp/cache/34A/EB0/shard%2F721 +1 -0
- data/spec/dummy/tmp/cache/34A/EC0/shard%2F730 +1 -0
- data/spec/dummy/tmp/cache/34B/E40/shard%2F245 +0 -0
- data/spec/dummy/tmp/cache/34B/E60/shard%2F425 +1 -0
- data/spec/dummy/tmp/cache/34B/EC0/shard%2F722 +1 -0
- data/spec/dummy/tmp/cache/34C/E50/shard%2F246 +0 -0
- data/spec/dummy/tmp/cache/34C/E80/shard%2F273 +1 -0
- data/spec/dummy/tmp/cache/34C/E90/shard%2F363 +0 -0
- data/spec/dummy/tmp/cache/34C/E90/shard%2F444 +1 -0
- data/spec/dummy/tmp/cache/34C/EA0/shard%2F615 +1 -0
- data/spec/dummy/tmp/cache/34C/F00/shard%2F750 +1 -0
- data/spec/dummy/tmp/cache/34D/E80/shard%2F265 +1 -0
- data/spec/dummy/tmp/cache/34D/ED0/shard%2F391 +1 -0
- data/spec/dummy/tmp/cache/34D/EE0/shard%2F724 +1 -0
- data/spec/dummy/tmp/cache/34E/ED0/shard%2F383 +1 -0
- data/spec/dummy/tmp/cache/34E/EF0/shard%2F725 +1 -0
- data/spec/dummy/tmp/cache/34E/F00/shard%2F653 +1 -0
- data/spec/dummy/tmp/cache/34F/EE0/shard%2F546 +1 -0
- data/spec/dummy/tmp/cache/34F/F00/shard%2F807 +1 -0
- data/spec/dummy/tmp/cache/34F/F30/shard%2F672 +1 -0
- data/spec/dummy/tmp/cache/350/EA0/shard%2F178 +1 -0
- data/spec/dummy/tmp/cache/350/EB0/shard%2F349 +1 -0
- data/spec/dummy/tmp/cache/350/F00/shard%2F718 +0 -0
- data/spec/dummy/tmp/cache/350/F40/shard%2F592 +1 -0
- data/spec/dummy/tmp/cache/351/F00/shard%2F386 +0 -0
- data/spec/dummy/tmp/cache/351/F10/shard%2F638 +1 -0
- data/spec/dummy/tmp/cache/351/F10/shard%2F719 +0 -0
- data/spec/dummy/tmp/cache/352/F10/shard%2F387 +0 -0
- data/spec/dummy/tmp/cache/352/F10/shard%2F468 +1 -0
- data/spec/dummy/tmp/cache/352/F30/shard%2F729 +1 -0
- data/spec/dummy/tmp/cache/353/F10/shard%2F298 +1 -0
- data/spec/dummy/tmp/cache/353/F50/shard%2F739 +1 -0
- data/spec/dummy/tmp/cache/354/F50/shard%2F569 +1 -0
- data/spec/dummy/tmp/cache/354/F80/shard%2F677 +1 -0
- data/spec/dummy/tmp/cache/354/F90/shard%2F767 +1 -0
- data/spec/dummy/tmp/cache/358/FE0/shard%2F699 +1 -0
- data/spec/dummy/tmp/cache/3A5/EA0/shard%2F10004 +1 -0
- data/spec/dummy/tmp/cache/3A6/F40/shard%2F10410 +1 -0
- data/spec/dummy/tmp/cache/3A7/F30/shard%2F10231 +1 -0
- data/spec/dummy/tmp/cache/3A8/F90/shard%2F10520 +1 -0
- data/spec/dummy/tmp/cache/3A9/F40/shard%2F10062 +1 -0
- data/spec/dummy/tmp/cache/3A9/F80/shard%2F10341 +1 -0
- data/spec/dummy/tmp/cache/3AA/F10/shard%2F10027 +1 -0
- data/spec/dummy/tmp/cache/3AA/F10/shard%2F10108 +1 -0
- data/spec/dummy/tmp/cache/3AA/FB0/shard%2F10441 +1 -0
- data/spec/dummy/tmp/cache/3AA/FC0/shard%2F10612 +1 -0
- data/spec/dummy/tmp/cache/3AB/010/shard%2F10730 +1 -0
- data/spec/dummy/tmp/cache/3AB/F70/shard%2F10154 +1 -0
- data/spec/dummy/tmp/cache/3AC/020/shard%2F10650 +1 -0
- data/spec/dummy/tmp/cache/3AC/FC0/shard%2F10272 +1 -0
- data/spec/dummy/tmp/cache/3AD/000/shard%2F10543 +1 -0
- data/spec/dummy/tmp/cache/3AD/F50/shard%2F10039 +1 -0
- data/spec/dummy/tmp/cache/3AD/F90/shard%2F10318 +1 -0
- data/spec/dummy/tmp/cache/3AD/FA0/shard%2F10246 +1 -0
- data/spec/dummy/tmp/cache/3AE/060/shard%2F10751 +1 -0
- data/spec/dummy/tmp/cache/3AE/FF0/shard%2F10364 +1 -0
- data/spec/dummy/tmp/cache/3AF/030/shard%2F10635 +1 -0
- data/spec/dummy/tmp/cache/3B0/FE0/shard%2F10177 +1 -0
- data/spec/dummy/tmp/cache/3B1/030/shard%2F10295 +1 -0
- data/spec/dummy/tmp/cache/3B1/040/shard%2F10466 +1 -0
- data/spec/dummy/tmp/cache/3B1/090/shard%2F10673 +1 -0
- data/spec/dummy/tmp/cache/3B2/070/shard%2F10566 +1 -0
- data/spec/dummy/tmp/cache/3B3/060/shard%2F10387 +1 -0
- data/spec/dummy/tmp/cache/3B5/0B0/shard%2F10497 +1 -0
- data/spec/dummy/tmp/cache/3B6/100/shard%2F10696 +1 -0
- data/spec/dummy/tmp/cache/3B7/0E0/shard%2F10589 +1 -0
- data/spec/dummy/tmp/cache/3BA/160/shard%2F10799 +1 -0
- data/spec/lib/action_controller/caching_spec.rb +4 -4
- data/spec/lib/active_record/abstract_adapter_spec.rb +1 -1
- data/spec/lib/active_record/association_spec.rb +83 -67
- data/spec/lib/active_record/attribute_methods_spec.rb +29 -29
- data/spec/lib/active_record/base_spec.rb +20 -20
- data/spec/lib/active_record/calculations_spec.rb +79 -59
- data/spec/lib/active_record/connection_handler_spec.rb +14 -14
- data/spec/lib/active_record/connection_pool_spec.rb +7 -7
- data/spec/lib/active_record/finder_methods_spec.rb +8 -8
- data/spec/lib/active_record/query_cache_spec.rb +38 -38
- data/spec/lib/active_record/query_methods_spec.rb +45 -45
- data/spec/lib/active_record/relation_spec.rb +8 -8
- data/spec/lib/active_record/spawn_methods_spec.rb +11 -11
- data/spec/lib/connection_pool_proxy_spec.rb +2 -2
- data/spec/lib/database_server_spec.rb +37 -37
- data/spec/lib/default_shard_spec.rb +3 -3
- data/spec/lib/r_spec_helper_spec.rb +33 -7
- data/spec/lib/rails_spec.rb +5 -5
- data/spec/lib/shackles_spec.rb +35 -35
- data/spec/models/shard_spec.rb +104 -104
- data/spec/spec_helper.rb +1 -1
- metadata +254 -29
|
@@ -12,25 +12,25 @@ module Switchman
|
|
|
12
12
|
|
|
13
13
|
describe "#exec_queries" do
|
|
14
14
|
it "should activate the correct shard for the query" do
|
|
15
|
-
User.shard(@shard1).where(:id => @user2.local_id).first.
|
|
15
|
+
expect(User.shard(@shard1).where(:id => @user2.local_id).first).to eq @user2
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
it "should activate multiple shards if necessary" do
|
|
19
|
-
User.where(:id => [@user1.id, @user2.id]).sort_by(&:id).
|
|
19
|
+
expect(User.where(:id => [@user1.id, @user2.id]).sort_by(&:id)).to eq [@user1, @user2].sort_by(&:id)
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
describe "#update_all" do
|
|
24
24
|
it "should activate the correct shard for the query" do
|
|
25
25
|
User.shard(@shard1).where(:id => @user2.local_id).update_all(:name => 'a')
|
|
26
|
-
@user1.reload.name.
|
|
27
|
-
@user2.reload.name.
|
|
26
|
+
expect(@user1.reload.name).to eq 'user1'
|
|
27
|
+
expect(@user2.reload.name).to eq 'a'
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
it "should activate multiple shards if necessary" do
|
|
31
31
|
User.where(:id => [@user1.id, @user2.id]).update_all(:name => 'a')
|
|
32
|
-
@user1.reload.name.
|
|
33
|
-
@user2.reload.name.
|
|
32
|
+
expect(@user1.reload.name).to eq 'a'
|
|
33
|
+
expect(@user2.reload.name).to eq 'a'
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
|
|
@@ -38,8 +38,8 @@ module Switchman
|
|
|
38
38
|
it "should infer the scope's shard" do
|
|
39
39
|
scope = @shard1.activate { User.where(id: 1) }
|
|
40
40
|
u = scope.new
|
|
41
|
-
u.shard.
|
|
42
|
-
u.local_id.
|
|
41
|
+
expect(u.shard).to eq @shard1
|
|
42
|
+
expect(u.local_id).to eq 1
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
end
|
|
@@ -8,35 +8,35 @@ module Switchman
|
|
|
8
8
|
describe "#merge" do
|
|
9
9
|
it "should merge shard_value for multiple explicits" do
|
|
10
10
|
result = User.shard([@shard1, @shard2]).merge(User.shard([Shard.default, @shard1]))
|
|
11
|
-
result.shard_value.
|
|
12
|
-
result.shard_source_value.
|
|
11
|
+
expect(result.shard_value).to eq @shard1
|
|
12
|
+
expect(result.shard_source_value).to eq :explicit
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
it "should merge shard_value relations for multiple explicits" do
|
|
16
16
|
result = User.shard(Shard.where("id IN (?)", [@shard1, @shard2])).merge(User.shard(Shard.where(id: [Shard.default, @shard1])))
|
|
17
|
-
(::ActiveRecord::Relation === result.shard_value).
|
|
18
|
-
result.shard_value.to_a.
|
|
19
|
-
result.shard_source_value.
|
|
17
|
+
expect(::ActiveRecord::Relation === result.shard_value).to eq true
|
|
18
|
+
expect(result.shard_value.to_a).to eq [@shard1]
|
|
19
|
+
expect(result.shard_source_value).to eq :explicit
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
it "should ignore implicit shard value lhs" do
|
|
23
23
|
scope = ::Rails.version < '4' ? User.scoped : User.all
|
|
24
24
|
result = scope.merge(User.shard(@shard1))
|
|
25
|
-
result.shard_value.
|
|
26
|
-
result.shard_source_value.
|
|
25
|
+
expect(result.shard_value).to eq @shard1
|
|
26
|
+
expect(result.shard_source_value).to eq :explicit
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
it "should ignore implicit shard value rhs" do
|
|
30
30
|
result = User.shard(@shard1).merge(::Rails.version < '4' ? User.scoped : User.all)
|
|
31
|
-
result.shard_value.
|
|
32
|
-
result.shard_source_value.
|
|
31
|
+
expect(result.shard_value).to eq @shard1
|
|
32
|
+
expect(result.shard_source_value).to eq :explicit
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
it "should take lhs shard_value for double implicit" do
|
|
36
36
|
scope1 = @shard2.activate { ::Rails.version < '4' ? User.scoped : User.all }
|
|
37
37
|
result = scope1.merge(::Rails.version < '4' ? User.scoped : User.all)
|
|
38
|
-
result.shard_value.
|
|
39
|
-
result.shard_source_value.
|
|
38
|
+
expect(result.shard_value).to eq @shard2
|
|
39
|
+
expect(result.shard_source_value).to eq :implicit
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
end
|
|
@@ -8,8 +8,8 @@ module Switchman
|
|
|
8
8
|
@db = DatabaseServer.create(:config => { :adapter => 'sqlite3', :database => ':memory:' })
|
|
9
9
|
@sqlite_shard1 = @db.shards.create!
|
|
10
10
|
@sqlite_shard2 = @db.shards.create!
|
|
11
|
-
::ActiveRecord::Base.connection.
|
|
12
|
-
@sqlite_shard1.activate { ::ActiveRecord::Base.connection }.
|
|
11
|
+
expect(::ActiveRecord::Base.connection).not_to eq @sqlite_shard2.activate { ::ActiveRecord::Base.connection }
|
|
12
|
+
expect(@sqlite_shard1.activate { ::ActiveRecord::Base.connection }).not_to eq @sqlite_shard2.activate { ::ActiveRecord::Base.connection }
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
it "should forward clear_idle_connections! to each of its pools" do
|
|
@@ -5,37 +5,37 @@ module Switchman
|
|
|
5
5
|
describe "shareable?" do
|
|
6
6
|
it "should be false for sqlite" do
|
|
7
7
|
db = DatabaseServer.new(config: { adapter: 'sqlite3', database: '%{shard_name}' })
|
|
8
|
-
db.shareable
|
|
8
|
+
expect(db.shareable?).to eq false
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
it "should be true for mysql" do
|
|
12
12
|
db = DatabaseServer.new(config: { adapter: 'mysql' })
|
|
13
|
-
db.shareable
|
|
13
|
+
expect(db.shareable?).to eq true
|
|
14
14
|
|
|
15
15
|
db = DatabaseServer.new(config: { adapter: 'mysql2' })
|
|
16
|
-
db.shareable
|
|
16
|
+
expect(db.shareable?).to eq true
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
it "should be true for postgres with a non-variable username" do
|
|
20
20
|
db = DatabaseServer.new(config: { adapter: 'postgresql' })
|
|
21
|
-
db.shareable
|
|
21
|
+
expect(db.shareable?).to eq true
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
it "should be false for postgres with variable username" do
|
|
25
25
|
db = DatabaseServer.new(config: { adapter: 'postgresql', username: '%{schema_search_path}' })
|
|
26
|
-
db.shareable
|
|
26
|
+
expect(db.shareable?).to eq false
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
it "should depend on the database environment" do
|
|
30
30
|
db = DatabaseServer.new(config: { adapter: 'postgresql', username: '%{schema_search_path}', deploy: { username: 'deploy' }})
|
|
31
|
-
db.shareable
|
|
32
|
-
::Shackles.activate(:deploy) { db.shareable? }.
|
|
31
|
+
expect(db.shareable?).to eq false
|
|
32
|
+
expect(::Shackles.activate(:deploy) { db.shareable? }).to eq true
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
it "should handle string keys" do
|
|
36
36
|
db = DatabaseServer.new(config: { adapter: 'postgresql', username: '%{schema_search_path}', deploy: { 'username' => 'deploy' }})
|
|
37
|
-
db.shareable
|
|
38
|
-
::Shackles.activate(:deploy) { db.shareable? }.
|
|
37
|
+
expect(db.shareable?).to eq false
|
|
38
|
+
expect(::Shackles.activate(:deploy) { db.shareable? }).to eq true
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
|
|
@@ -50,19 +50,19 @@ module Switchman
|
|
|
50
50
|
adapter = ::ActiveRecord::Base.connection.adapter_name
|
|
51
51
|
def create_shard(server)
|
|
52
52
|
new_shard = server.create_new_shard
|
|
53
|
-
new_shard.
|
|
54
|
-
new_shard.name.
|
|
53
|
+
expect(new_shard).not_to be_new_record
|
|
54
|
+
expect(new_shard.name).to match /shard_#{new_shard.id}/
|
|
55
55
|
# They should share a connection pool
|
|
56
56
|
if server == Shard.default.database_server
|
|
57
|
-
User.connection_pool.current_pool.
|
|
58
|
-
User.connection_pool.current_pool.
|
|
57
|
+
expect(User.connection_pool.current_pool).to eq new_shard.activate { User.connection_pool.current_pool }
|
|
58
|
+
expect(User.connection_pool.current_pool).to eq Shard.connection_pool.current_pool
|
|
59
59
|
else
|
|
60
|
-
User.connection_pool.current_pool.
|
|
60
|
+
expect(User.connection_pool.current_pool).not_to eq new_shard.activate { User.connection_pool.current_pool }
|
|
61
61
|
end
|
|
62
62
|
# The tables should be created, ready to use
|
|
63
63
|
new_shard.activate {
|
|
64
64
|
a = User.create!
|
|
65
|
-
a.
|
|
65
|
+
expect(a).not_to be_new_record
|
|
66
66
|
}
|
|
67
67
|
ensure
|
|
68
68
|
if new_shard
|
|
@@ -90,7 +90,7 @@ module Switchman
|
|
|
90
90
|
|
|
91
91
|
it "should be able to create a new shard from a db server that doesn't have any shards" do
|
|
92
92
|
# otherwise it's a repeat of the sqlite spec above
|
|
93
|
-
|
|
93
|
+
skip 'A "real" database"' unless %w{MySQL Mysql2 PostgreSQL}.include?(adapter)
|
|
94
94
|
|
|
95
95
|
# So, it's really the same server, but we want separate connections
|
|
96
96
|
db = DatabaseServer.create(:config => Shard.default.database_server.config)
|
|
@@ -105,7 +105,7 @@ module Switchman
|
|
|
105
105
|
it "should use the connection's db name as temp db name" do
|
|
106
106
|
db = DatabaseServer.new(config: { adapter: 'postgresql' })
|
|
107
107
|
Shard.expects(:create!).with(:name => Shard.default.name, :database_server => db).raises(MyException.new)
|
|
108
|
-
|
|
108
|
+
expect { db.create_new_shard }.to raise_error(MyException)
|
|
109
109
|
end
|
|
110
110
|
end
|
|
111
111
|
|
|
@@ -115,38 +115,38 @@ module Switchman
|
|
|
115
115
|
slave: [nil, { database: 'slave' }],
|
|
116
116
|
deploy: { username: 'deploy' }}
|
|
117
117
|
ds = DatabaseServer.new(config: base_config)
|
|
118
|
-
ds.config.
|
|
119
|
-
ds.config(:slave).
|
|
118
|
+
expect(ds.config).to eq base_config
|
|
119
|
+
expect(ds.config(:slave)).to eq [{ database: 'db', deploy: base_config[:deploy] },
|
|
120
120
|
{ database: 'slave', deploy: base_config[:deploy] }]
|
|
121
|
-
ds.config(:deploy).
|
|
121
|
+
expect(ds.config(:deploy)).to eq({ database: 'db', username: 'deploy', slave: base_config[:slave], deploy: base_config[:deploy] })
|
|
122
122
|
end
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
describe "#shackles_environment" do
|
|
126
126
|
it "should inherit from Shackles.environment" do
|
|
127
127
|
ds = DatabaseServer.new
|
|
128
|
-
ds.shackles_environment.
|
|
128
|
+
expect(ds.shackles_environment).to eq :master
|
|
129
129
|
::Shackles.activate(:slave) do
|
|
130
|
-
ds.shackles_environment.
|
|
130
|
+
expect(ds.shackles_environment).to eq :slave
|
|
131
131
|
end
|
|
132
132
|
end
|
|
133
133
|
|
|
134
134
|
it "should override Shackles.environment when explicitly set" do
|
|
135
135
|
ds = DatabaseServer.new
|
|
136
136
|
ds.shackle!
|
|
137
|
-
ds.shackles_environment.
|
|
137
|
+
expect(ds.shackles_environment).to eq :slave
|
|
138
138
|
ds.unshackle do
|
|
139
|
-
ds.shackles_environment.
|
|
139
|
+
expect(ds.shackles_environment).to eq :master
|
|
140
140
|
end
|
|
141
|
-
ds.shackles_environment.
|
|
141
|
+
expect(ds.shackles_environment).to eq :slave
|
|
142
142
|
::Shackles.activate(:slave) do
|
|
143
|
-
ds.shackles_environment.
|
|
143
|
+
expect(ds.shackles_environment).to eq :slave
|
|
144
144
|
ds.unshackle do
|
|
145
|
-
ds.shackles_environment.
|
|
145
|
+
expect(ds.shackles_environment).to eq :slave
|
|
146
146
|
end
|
|
147
|
-
ds.shackles_environment.
|
|
147
|
+
expect(ds.shackles_environment).to eq :slave
|
|
148
148
|
end
|
|
149
|
-
ds.shackles_environment.
|
|
149
|
+
expect(ds.shackles_environment).to eq :slave
|
|
150
150
|
end
|
|
151
151
|
end
|
|
152
152
|
|
|
@@ -164,12 +164,12 @@ module Switchman
|
|
|
164
164
|
end
|
|
165
165
|
|
|
166
166
|
it "should prefer the cache specific to the database" do
|
|
167
|
-
@db.cache_store.object_id.
|
|
167
|
+
expect(@db.cache_store.object_id).to eq @db_store.object_id
|
|
168
168
|
end
|
|
169
169
|
|
|
170
170
|
it "should fallback to Rails.cache_without_sharding if no specific cache" do
|
|
171
171
|
Switchman.config[:cache_map].delete(@db.id)
|
|
172
|
-
@db.cache_store.object_id.
|
|
172
|
+
expect(@db.cache_store.object_id).to eq @default_store.object_id
|
|
173
173
|
end
|
|
174
174
|
end
|
|
175
175
|
|
|
@@ -200,20 +200,20 @@ module Switchman
|
|
|
200
200
|
end
|
|
201
201
|
|
|
202
202
|
it "should return the default server if that's the only one around" do
|
|
203
|
-
DatabaseServer.server_for_new_shard.
|
|
203
|
+
expect(DatabaseServer.server_for_new_shard).to eq @db1
|
|
204
204
|
end
|
|
205
205
|
|
|
206
206
|
it "should return on open server" do
|
|
207
207
|
@db1.config[:open] = true
|
|
208
|
-
DatabaseServer.server_for_new_shard.
|
|
208
|
+
expect(DatabaseServer.server_for_new_shard).to eq @db1
|
|
209
209
|
end
|
|
210
210
|
|
|
211
211
|
it "should return another server if it's the only one open" do
|
|
212
212
|
@db2 = DatabaseServer.create(:config => { :open => true})
|
|
213
|
-
4.times { DatabaseServer.server_for_new_shard.
|
|
213
|
+
4.times { expect(DatabaseServer.server_for_new_shard).to eq @db2 }
|
|
214
214
|
@db2.config.delete(:open)
|
|
215
215
|
@db1.config[:open] = true
|
|
216
|
-
4.times { DatabaseServer.server_for_new_shard.
|
|
216
|
+
4.times { expect(DatabaseServer.server_for_new_shard).to eq @db1 }
|
|
217
217
|
end
|
|
218
218
|
|
|
219
219
|
it "should return multiple open servers" do
|
|
@@ -223,8 +223,8 @@ module Switchman
|
|
|
223
223
|
20.times do
|
|
224
224
|
dbs << DatabaseServer.server_for_new_shard
|
|
225
225
|
end
|
|
226
|
-
dbs.
|
|
227
|
-
dbs.
|
|
226
|
+
expect(dbs).to include(@db1)
|
|
227
|
+
expect(dbs).to include(@db2)
|
|
228
228
|
end
|
|
229
229
|
end
|
|
230
230
|
end
|
|
@@ -6,13 +6,13 @@ module Switchman
|
|
|
6
6
|
include RSpecHelper
|
|
7
7
|
|
|
8
8
|
it "should be equivalent to a real default shard" do
|
|
9
|
-
Shard.default.
|
|
10
|
-
DefaultShard.send(:new).
|
|
9
|
+
expect(Shard.default).to be_is_a(Shard)
|
|
10
|
+
expect(DefaultShard.send(:new)).to eq Shard.default
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
it "all defaultshards should be equivalent to each other" do
|
|
15
|
-
DefaultShard.send(:new).
|
|
15
|
+
expect(DefaultShard.send(:new)).to eq DefaultShard.send(:new)
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
end
|
|
@@ -2,20 +2,46 @@ require "spec_helper"
|
|
|
2
2
|
|
|
3
3
|
module Switchman
|
|
4
4
|
describe RSpecHelper do
|
|
5
|
+
context "unsharded" do
|
|
6
|
+
it "doesn't make shards accessible" do
|
|
7
|
+
# by virtue of including RSpecHelper somewhere, test shards will
|
|
8
|
+
# always already be set up by this point (though not accessible),
|
|
9
|
+
# but only if we are running a sharding spec
|
|
10
|
+
expect(Shard.count).to eq 0
|
|
11
|
+
expect(Shard.default).to be_a(DefaultShard)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "doesn't set up sharding at all if no sharded specs are run" do
|
|
15
|
+
run_groups = RSpec.world.filtered_examples.select{ |k, v| v.present? }.map(&:first)
|
|
16
|
+
pending "run without other sharding specs" if run_groups.any?{ |group| RSpecHelper.included_in?(group) }
|
|
17
|
+
|
|
18
|
+
expect(RSpecHelper.class_variable_defined?(:@@default_shard)).to eq false
|
|
19
|
+
expect(RSpecHelper.class_variable_get(:@@shard1)).to be_nil
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "sets up sharding but hides it if other sharding specs are run" do
|
|
23
|
+
run_groups = RSpec.world.filtered_examples.select{ |k, v| v.present? }.map(&:first)
|
|
24
|
+
pending "run alongside sharding specs" unless run_groups.any?{ |group| RSpecHelper.included_in?(group) }
|
|
25
|
+
|
|
26
|
+
expect(RSpecHelper.class_variable_get(:@@default_shard)).to be_a(Shard)
|
|
27
|
+
expect(RSpecHelper.class_variable_get(:@@shard1)).to be_a(Shard)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
5
31
|
context "sharding" do
|
|
6
32
|
# strategically place these before we include the module
|
|
7
33
|
before(:all) do
|
|
8
|
-
Shard.default.
|
|
34
|
+
expect(Shard.default).to be_a(DefaultShard)
|
|
9
35
|
end
|
|
10
36
|
|
|
11
37
|
after(:all) do
|
|
12
|
-
Shard.default.
|
|
38
|
+
expect(Shard.default).to be_a(DefaultShard)
|
|
13
39
|
end
|
|
14
40
|
|
|
15
41
|
include RSpecHelper
|
|
16
42
|
|
|
17
43
|
it "should make the default shard a real shard" do
|
|
18
|
-
Shard.default.
|
|
44
|
+
expect(Shard.default).to be_a(Shard)
|
|
19
45
|
end
|
|
20
46
|
end
|
|
21
47
|
|
|
@@ -54,18 +80,18 @@ module Switchman
|
|
|
54
80
|
|
|
55
81
|
it "should support nested transactions" do
|
|
56
82
|
@shard2.activate do |shard|
|
|
57
|
-
User.count.
|
|
83
|
+
expect(User.count).to eq 1 # we get the user from the before :all
|
|
58
84
|
User.create! # should only last for the duration of this spec
|
|
59
85
|
conn = ::ActiveRecord::Base.connection
|
|
60
|
-
conn.open_transactions.
|
|
86
|
+
expect(conn.open_transactions).to eql 2
|
|
61
87
|
end
|
|
62
88
|
end
|
|
63
89
|
|
|
64
90
|
prepend_after :all do
|
|
65
91
|
@shard2.activate do
|
|
66
|
-
User.count.
|
|
92
|
+
expect(User.count).to eq 1
|
|
67
93
|
conn = ::ActiveRecord::Base.connection
|
|
68
|
-
conn.open_transactions.
|
|
94
|
+
expect(conn.open_transactions).to eql 1 # RSpecHelper shouldn't have rolled back the before :all one above
|
|
69
95
|
rollback_transaction(::ActiveRecord::Base.connection)
|
|
70
96
|
end
|
|
71
97
|
end
|
data/spec/lib/rails_spec.rb
CHANGED
|
@@ -9,19 +9,19 @@ module Switchman
|
|
|
9
9
|
s1 = db.shards.create!
|
|
10
10
|
s2 = db.shards.create!
|
|
11
11
|
|
|
12
|
-
s1.activate { ::Rails.cache }.
|
|
12
|
+
expect(s1.activate { ::Rails.cache }).to eq s2.activate { ::Rails.cache }
|
|
13
13
|
|
|
14
14
|
from_1 = s1.activate { ::Rails.cache.fetch('key') { 1 } }
|
|
15
|
-
from_1.
|
|
15
|
+
expect(from_1).to eq 1
|
|
16
16
|
from_2 = s2.activate do
|
|
17
17
|
::Rails.cache.fetch('key') { 2 }
|
|
18
18
|
end
|
|
19
|
-
from_2.
|
|
19
|
+
expect(from_2).to eq 2
|
|
20
20
|
|
|
21
21
|
from_1 = s1.activate { ::Rails.cache.fetch('key') }
|
|
22
|
-
from_1.
|
|
22
|
+
expect(from_1).to eq 1
|
|
23
23
|
from_2 = s2.activate { ::Rails.cache.fetch('key') }
|
|
24
|
-
from_2.
|
|
24
|
+
expect(from_2).to eq 2
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
it "should not be assignable" do
|
data/spec/lib/shackles_spec.rb
CHANGED
|
@@ -18,7 +18,7 @@ module Switchman
|
|
|
18
18
|
@current_pool = ::Shackles.activate(:slave) { ::ActiveRecord::Base.connection_pool.current_pool }
|
|
19
19
|
end
|
|
20
20
|
::Shackles.activate(:slave) do
|
|
21
|
-
::ActiveRecord::Base.connection_pool.default_pool.
|
|
21
|
+
expect(::ActiveRecord::Base.connection_pool.default_pool).not_to eq @current_pool
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
@@ -30,9 +30,9 @@ module Switchman
|
|
|
30
30
|
models = ::ActiveRecord::Base.connection_handler.send(:class_to_pool)
|
|
31
31
|
pools = {}
|
|
32
32
|
models.each_pair { |k, v| pools[k] = v.current_pool }
|
|
33
|
-
default_pools.keys.sort.
|
|
33
|
+
expect(default_pools.keys.sort).to eq pools.keys.sort
|
|
34
34
|
default_pools.keys.each do |model|
|
|
35
|
-
default_pools[model].
|
|
35
|
+
expect(default_pools[model]).not_to eq pools[model]
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
end
|
|
@@ -47,7 +47,7 @@ module Switchman
|
|
|
47
47
|
s = ds.shards.create!
|
|
48
48
|
s.activate do
|
|
49
49
|
User.connection
|
|
50
|
-
User.connection_pool.spec.config[:host].
|
|
50
|
+
expect(User.connection_pool.spec.config[:host]).not_to eq 'some.postgres.server'
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
@@ -55,8 +55,8 @@ module Switchman
|
|
|
55
55
|
begin
|
|
56
56
|
Shard.default.database_server.shackle!
|
|
57
57
|
@shard2.activate do
|
|
58
|
-
Shard.default.database_server.shackles_environment.
|
|
59
|
-
::Shackles.environment.
|
|
58
|
+
expect(Shard.default.database_server.shackles_environment).to eq :slave
|
|
59
|
+
expect(::Shackles.environment).to eq :master
|
|
60
60
|
|
|
61
61
|
Shard.default.database_server.expects(:unshackle).once
|
|
62
62
|
User.shard(Shard.default).update_all(updated_at: nil)
|
|
@@ -69,13 +69,13 @@ module Switchman
|
|
|
69
69
|
it "should deshackle for FOR UPDATE queries" do
|
|
70
70
|
begin
|
|
71
71
|
Shard.default.database_server.shackle!
|
|
72
|
-
Shard.default.database_server.shackles_environment.
|
|
72
|
+
expect(Shard.default.database_server.shackles_environment).to eq :slave
|
|
73
73
|
|
|
74
74
|
u = User.create!
|
|
75
75
|
Shard.default.database_server.expects(:unshackle).once.returns([])
|
|
76
76
|
User.lock.first
|
|
77
77
|
Shard.default.database_server.expects(:unshackle).once.returns([])
|
|
78
|
-
|
|
78
|
+
expect { u.lock! }.to raise_error(::ActiveRecord::RecordNotFound)
|
|
79
79
|
ensure
|
|
80
80
|
Shard.default.database_server.unshackle!
|
|
81
81
|
end
|
|
@@ -90,7 +90,7 @@ module Switchman
|
|
|
90
90
|
::Rails.env.stubs(:test?).returns(false)
|
|
91
91
|
s = ds.shards.create!
|
|
92
92
|
s.activate do
|
|
93
|
-
User.connection_pool.spec.config[:host].
|
|
93
|
+
expect(User.connection_pool.spec.config[:host]).to eq 'notshackled'
|
|
94
94
|
end
|
|
95
95
|
ensure
|
|
96
96
|
Shard.default.database_server.unshackle!
|
|
@@ -102,44 +102,44 @@ module Switchman
|
|
|
102
102
|
|
|
103
103
|
it "should really disconnect all envs" do
|
|
104
104
|
::ActiveRecord::Base.connection
|
|
105
|
-
::ActiveRecord::Base.connection_pool.
|
|
105
|
+
expect(::ActiveRecord::Base.connection_pool).to be_connected
|
|
106
106
|
@shard1.activate do
|
|
107
107
|
::ActiveRecord::Base.connection
|
|
108
|
-
::ActiveRecord::Base.connection_pool.
|
|
108
|
+
expect(::ActiveRecord::Base.connection_pool).to be_connected
|
|
109
109
|
end
|
|
110
110
|
@shard2.activate do
|
|
111
111
|
::ActiveRecord::Base.connection
|
|
112
|
-
::ActiveRecord::Base.connection_pool.
|
|
112
|
+
expect(::ActiveRecord::Base.connection_pool).to be_connected
|
|
113
113
|
end
|
|
114
114
|
|
|
115
115
|
::Shackles.activate(:slave) do
|
|
116
116
|
::ActiveRecord::Base.connection
|
|
117
|
-
::ActiveRecord::Base.connection_pool.
|
|
117
|
+
expect(::ActiveRecord::Base.connection_pool).to be_connected
|
|
118
118
|
@shard1.activate do
|
|
119
119
|
::ActiveRecord::Base.connection
|
|
120
|
-
::ActiveRecord::Base.connection_pool.
|
|
120
|
+
expect(::ActiveRecord::Base.connection_pool).to be_connected
|
|
121
121
|
end
|
|
122
122
|
@shard2.activate do
|
|
123
123
|
::ActiveRecord::Base.connection
|
|
124
|
-
::ActiveRecord::Base.connection_pool.
|
|
124
|
+
expect(::ActiveRecord::Base.connection_pool).to be_connected
|
|
125
125
|
end
|
|
126
126
|
end
|
|
127
127
|
|
|
128
128
|
::ActiveRecord::Base.clear_all_connections!
|
|
129
|
-
::ActiveRecord::Base.connection_pool.
|
|
129
|
+
expect(::ActiveRecord::Base.connection_pool).not_to be_connected
|
|
130
130
|
@shard1.activate do
|
|
131
|
-
::ActiveRecord::Base.connection_pool.
|
|
131
|
+
expect(::ActiveRecord::Base.connection_pool).not_to be_connected
|
|
132
132
|
end
|
|
133
133
|
@shard2.activate do
|
|
134
|
-
::ActiveRecord::Base.connection_pool.
|
|
134
|
+
expect(::ActiveRecord::Base.connection_pool).not_to be_connected
|
|
135
135
|
end
|
|
136
136
|
::Shackles.activate(:slave) do
|
|
137
|
-
::ActiveRecord::Base.connection_pool.
|
|
137
|
+
expect(::ActiveRecord::Base.connection_pool).not_to be_connected
|
|
138
138
|
@shard1.activate do
|
|
139
|
-
::ActiveRecord::Base.connection_pool.
|
|
139
|
+
expect(::ActiveRecord::Base.connection_pool).not_to be_connected
|
|
140
140
|
end
|
|
141
141
|
@shard2.activate do
|
|
142
|
-
::ActiveRecord::Base.connection_pool.
|
|
142
|
+
expect(::ActiveRecord::Base.connection_pool).not_to be_connected
|
|
143
143
|
end
|
|
144
144
|
end
|
|
145
145
|
end
|
|
@@ -150,53 +150,53 @@ module Switchman
|
|
|
150
150
|
|
|
151
151
|
it "should really return active connections to the pool in all envs" do
|
|
152
152
|
::ActiveRecord::Base.connection
|
|
153
|
-
actual_connection_count.
|
|
153
|
+
expect(actual_connection_count).not_to eq 0
|
|
154
154
|
@shard1.activate do
|
|
155
155
|
::ActiveRecord::Base.connection
|
|
156
|
-
actual_connection_count.
|
|
156
|
+
expect(actual_connection_count).not_to eq 0
|
|
157
157
|
end
|
|
158
158
|
@shard2.activate do
|
|
159
159
|
::ActiveRecord::Base.connection
|
|
160
|
-
actual_connection_count.
|
|
160
|
+
expect(actual_connection_count).not_to eq 0
|
|
161
161
|
end
|
|
162
162
|
|
|
163
163
|
::Shackles.activate(:slave) do
|
|
164
164
|
::ActiveRecord::Base.connection
|
|
165
|
-
actual_connection_count.
|
|
165
|
+
expect(actual_connection_count).not_to eq 0
|
|
166
166
|
@shard1.activate do
|
|
167
167
|
::ActiveRecord::Base.connection
|
|
168
|
-
actual_connection_count.
|
|
168
|
+
expect(actual_connection_count).not_to eq 0
|
|
169
169
|
end
|
|
170
170
|
@shard2.activate do
|
|
171
171
|
::ActiveRecord::Base.connection
|
|
172
|
-
actual_connection_count.
|
|
172
|
+
expect(actual_connection_count).not_to eq 0
|
|
173
173
|
end
|
|
174
174
|
end
|
|
175
175
|
|
|
176
176
|
::ActiveRecord::Base.clear_active_connections!
|
|
177
|
-
actual_connection_count.
|
|
177
|
+
expect(actual_connection_count).to eq 0
|
|
178
178
|
@shard1.activate do
|
|
179
|
-
actual_connection_count.
|
|
179
|
+
expect(actual_connection_count).to eq 0
|
|
180
180
|
end
|
|
181
181
|
@shard2.activate do
|
|
182
|
-
actual_connection_count.
|
|
182
|
+
expect(actual_connection_count).to eq 0
|
|
183
183
|
end
|
|
184
184
|
::Shackles.activate(:slave) do
|
|
185
|
-
actual_connection_count.
|
|
185
|
+
expect(actual_connection_count).to eq 0
|
|
186
186
|
@shard1.activate do
|
|
187
|
-
actual_connection_count.
|
|
187
|
+
expect(actual_connection_count).to eq 0
|
|
188
188
|
end
|
|
189
189
|
@shard2.activate do
|
|
190
|
-
actual_connection_count.
|
|
190
|
+
expect(actual_connection_count).to eq 0
|
|
191
191
|
end
|
|
192
192
|
end
|
|
193
193
|
end
|
|
194
194
|
|
|
195
195
|
it "should not establish connections when switching environments" do
|
|
196
196
|
::ActiveRecord::Base.clear_all_connections!
|
|
197
|
-
::ActiveRecord::Base.connection_pool.
|
|
197
|
+
expect(::ActiveRecord::Base.connection_pool).not_to be_connected
|
|
198
198
|
::Shackles.activate(:slave) {}
|
|
199
|
-
::ActiveRecord::Base.connection_pool.
|
|
199
|
+
expect(::ActiveRecord::Base.connection_pool).not_to be_connected
|
|
200
200
|
end
|
|
201
201
|
end
|
|
202
202
|
end
|