1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
|
require "cases/helper"
module ActiveRecord
module ConnectionAdapters
class ConnectionHandlerTest < ActiveRecord::TestCase
def setup
@handler = ConnectionHandler.new
@spec_name = "primary"
@pool = @handler.establish_connection(ActiveRecord::Base.configurations["arunit"])
end
def test_establish_connection_uses_spec_name
config = { "readonly" => { "adapter" => "sqlite3" } }
resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new(config)
spec = resolver.spec(:readonly)
@handler.establish_connection(spec.to_hash)
assert_not_nil @handler.retrieve_connection_pool("readonly")
ensure
@handler.remove_connection("readonly")
end
def test_establish_connection_using_3_levels_config
previous_env, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], "default_env"
config = {
"default_env" => {
"readonly" => { "adapter" => "sqlite3", "database" => "db/readonly.sqlite3" },
"primary" => { "adapter" => "sqlite3", "database" => "db/primary.sqlite3" }
},
"another_env" => {
"readonly" => { "adapter" => "sqlite3", "database" => "db/bad-readonly.sqlite3" },
"primary" => { "adapter" => "sqlite3", "database" => "db/bad-primary.sqlite3" }
},
"common" => { "adapter" => "sqlite3", "database" => "db/common.sqlite3" }
}
@prev_configs, ActiveRecord::Base.configurations = ActiveRecord::Base.configurations, config
@handler.establish_connection(:common)
@handler.establish_connection(:primary)
@handler.establish_connection(:readonly)
assert_not_nil pool = @handler.retrieve_connection_pool("readonly")
assert_equal "db/readonly.sqlite3", pool.spec.config[:database]
assert_not_nil pool = @handler.retrieve_connection_pool("primary")
assert_equal "db/primary.sqlite3", pool.spec.config[:database]
assert_not_nil pool = @handler.retrieve_connection_pool("common")
assert_equal "db/common.sqlite3", pool.spec.config[:database]
ensure
ActiveRecord::Base.configurations = @prev_configs
ENV["RAILS_ENV"] = previous_env
end
def test_establish_connection_using_two_level_configurations
config = { "development" => { "adapter" => "sqlite3", "database" => "db/primary.sqlite3" } }
@prev_configs, ActiveRecord::Base.configurations = ActiveRecord::Base.configurations, config
@handler.establish_connection(:development)
assert_not_nil pool = @handler.retrieve_connection_pool("development")
assert_equal "db/primary.sqlite3", pool.spec.config[:database]
ensure
ActiveRecord::Base.configurations = @prev_configs
end
def test_establish_connection_using_top_level_key_in_two_level_config
config = {
"development" => { "adapter" => "sqlite3", "database" => "db/primary.sqlite3" },
"development_readonly" => { "adapter" => "sqlite3", "database" => "db/readonly.sqlite3" }
}
@prev_configs, ActiveRecord::Base.configurations = ActiveRecord::Base.configurations, config
@handler.establish_connection(:development_readonly)
assert_not_nil pool = @handler.retrieve_connection_pool("development_readonly")
assert_equal "db/readonly.sqlite3", pool.spec.config[:database]
ensure
ActiveRecord::Base.configurations = @prev_configs
end
def test_retrieve_connection
assert @handler.retrieve_connection(@spec_name)
end
def test_active_connections?
assert !@handler.active_connections?
assert @handler.retrieve_connection(@spec_name)
assert @handler.active_connections?
@handler.clear_active_connections!
assert !@handler.active_connections?
end
def test_retrieve_connection_pool
assert_not_nil @handler.retrieve_connection_pool(@spec_name)
end
def test_retrieve_connection_pool_with_invalid_id
assert_nil @handler.retrieve_connection_pool("foo")
end
def test_connection_pools
assert_equal([@pool], @handler.connection_pools)
end
if Process.respond_to?(:fork)
def test_connection_pool_per_pid
object_id = ActiveRecord::Base.connection.object_id
rd, wr = IO.pipe
rd.binmode
wr.binmode
pid = fork {
rd.close
wr.write Marshal.dump ActiveRecord::Base.connection.object_id
wr.close
exit!
}
wr.close
Process.waitpid pid
assert_not_equal object_id, Marshal.load(rd.read)
rd.close
end
def test_retrieve_connection_pool_copies_schema_cache_from_ancestor_pool
@pool.schema_cache = @pool.connection.schema_cache
@pool.schema_cache.add("posts")
rd, wr = IO.pipe
rd.binmode
wr.binmode
pid = fork {
rd.close
pool = @handler.retrieve_connection_pool(@spec_name)
wr.write Marshal.dump pool.schema_cache.size
wr.close
exit!
}
wr.close
Process.waitpid pid
assert_equal @pool.schema_cache.size, Marshal.load(rd.read)
rd.close
end
def test_pool_from_any_process_for_uses_most_recent_spec
skip unless current_adapter?(:SQLite3Adapter)
file = Tempfile.new "lol.sqlite3"
rd, wr = IO.pipe
rd.binmode
wr.binmode
pid = fork do
ActiveRecord::Base.configurations["arunit"]["database"] = file.path
ActiveRecord::Base.establish_connection(:arunit)
pid2 = fork do
wr.write ActiveRecord::Base.connection_config[:database]
wr.close
end
Process.waitpid pid2
end
Process.waitpid pid
wr.close
assert_equal file.path, rd.read
rd.close
ensure
if file
file.close
file.unlink
end
end
def test_a_class_using_custom_pool_and_switching_back_to_primary
klass2 = Class.new(Base) { def self.name; "klass2"; end }
assert_equal klass2.connection.object_id, ActiveRecord::Base.connection.object_id
pool = klass2.establish_connection(ActiveRecord::Base.connection_pool.spec.config)
assert_equal klass2.connection.object_id, pool.connection.object_id
refute_equal klass2.connection.object_id, ActiveRecord::Base.connection.object_id
klass2.remove_connection
assert_equal klass2.connection.object_id, ActiveRecord::Base.connection.object_id
end
def test_connection_specification_name_should_fallback_to_parent
klassA = Class.new(Base)
klassB = Class.new(klassA)
assert_equal klassB.connection_specification_name, klassA.connection_specification_name
klassA.connection_specification_name = "readonly"
assert_equal "readonly", klassB.connection_specification_name
end
def test_remove_connection_should_not_remove_parent
klass2 = Class.new(Base) { def self.name; "klass2"; end }
klass2.remove_connection
refute_nil ActiveRecord::Base.connection.object_id
assert_equal klass2.connection.object_id, ActiveRecord::Base.connection.object_id
end
end
end
end
end
|