sequel 4.22.0 → 4.23.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +22 -0
- data/README.rdoc +6 -0
- data/Rakefile +59 -81
- data/doc/migration.rdoc +2 -0
- data/doc/release_notes/4.23.0.txt +65 -0
- data/doc/sharding.rdoc +16 -14
- data/doc/testing.rdoc +61 -77
- data/lib/sequel/adapters/jdbc.rb +1 -0
- data/lib/sequel/adapters/mock.rb +0 -1
- data/lib/sequel/adapters/postgres.rb +1 -0
- data/lib/sequel/adapters/postgresql.rb +1 -0
- data/lib/sequel/adapters/shared/postgres.rb +3 -3
- data/lib/sequel/connection_pool/sharded_threaded.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +9 -1
- data/lib/sequel/database/connecting.rb +1 -1
- data/lib/sequel/database/transactions.rb +2 -1
- data/lib/sequel/dataset/prepared_statements.rb +1 -1
- data/lib/sequel/extensions/constraint_validations.rb +12 -12
- data/lib/sequel/extensions/date_arithmetic.rb +0 -4
- data/lib/sequel/extensions/pagination.rb +14 -2
- data/lib/sequel/extensions/pg_enum.rb +2 -2
- data/lib/sequel/extensions/pg_hstore.rb +1 -1
- data/lib/sequel/extensions/pg_json_ops.rb +2 -2
- data/lib/sequel/plugins/csv_serializer.rb +2 -0
- data/lib/sequel/plugins/delay_add_association.rb +50 -0
- data/lib/sequel/plugins/list.rb +2 -2
- data/lib/sequel/plugins/nested_attributes.rb +8 -28
- data/lib/sequel/plugins/update_refresh.rb +50 -0
- data/lib/sequel/plugins/validate_associated.rb +55 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +29 -29
- data/spec/adapters/firebird_spec.rb +97 -103
- data/spec/adapters/informix_spec.rb +25 -25
- data/spec/adapters/mssql_spec.rb +156 -172
- data/spec/adapters/mysql_spec.rb +334 -359
- data/spec/adapters/oracle_spec.rb +67 -69
- data/spec/adapters/postgres_spec.rb +1298 -1249
- data/spec/adapters/spec_helper.rb +2 -35
- data/spec/adapters/sqlanywhere_spec.rb +39 -39
- data/spec/adapters/sqlite_spec.rb +203 -200
- data/spec/bin_spec.rb +57 -59
- data/spec/core/connection_pool_spec.rb +402 -401
- data/spec/core/database_spec.rb +953 -944
- data/spec/core/dataset_spec.rb +2178 -2168
- data/spec/core/deprecated_spec.rb +19 -19
- data/spec/core/expression_filters_spec.rb +415 -415
- data/spec/core/mock_adapter_spec.rb +212 -212
- data/spec/core/object_graph_spec.rb +73 -73
- data/spec/core/placeholder_literalizer_spec.rb +71 -71
- data/spec/core/schema_generator_spec.rb +44 -44
- data/spec/core/schema_spec.rb +470 -472
- data/spec/core/spec_helper.rb +5 -20
- data/spec/core/version_spec.rb +2 -2
- data/spec/core_extensions_spec.rb +320 -320
- data/spec/extensions/accessed_columns_spec.rb +12 -12
- data/spec/extensions/active_model_spec.rb +3 -3
- data/spec/extensions/after_initialize_spec.rb +2 -2
- data/spec/extensions/arbitrary_servers_spec.rb +23 -23
- data/spec/extensions/association_dependencies_spec.rb +34 -34
- data/spec/extensions/association_pks_spec.rb +98 -98
- data/spec/extensions/association_proxies_spec.rb +33 -33
- data/spec/extensions/auto_validations_spec.rb +46 -46
- data/spec/extensions/blacklist_security_spec.rb +19 -18
- data/spec/extensions/blank_spec.rb +36 -36
- data/spec/extensions/boolean_readers_spec.rb +36 -36
- data/spec/extensions/caching_spec.rb +82 -82
- data/spec/extensions/class_table_inheritance_spec.rb +72 -72
- data/spec/extensions/column_conflicts_spec.rb +19 -14
- data/spec/extensions/column_select_spec.rb +19 -19
- data/spec/extensions/columns_introspection_spec.rb +43 -43
- data/spec/extensions/composition_spec.rb +64 -64
- data/spec/extensions/connection_validator_spec.rb +92 -90
- data/spec/extensions/constraint_validations_plugin_spec.rb +92 -92
- data/spec/extensions/constraint_validations_spec.rb +80 -80
- data/spec/extensions/core_refinements_spec.rb +220 -220
- data/spec/extensions/csv_serializer_spec.rb +44 -44
- data/spec/extensions/current_datetime_timestamp_spec.rb +8 -8
- data/spec/extensions/dataset_associations_spec.rb +65 -65
- data/spec/extensions/dataset_source_alias_spec.rb +16 -16
- data/spec/extensions/date_arithmetic_spec.rb +51 -58
- data/spec/extensions/defaults_setter_spec.rb +19 -19
- data/spec/extensions/delay_add_association_spec.rb +52 -0
- data/spec/extensions/dirty_spec.rb +51 -51
- data/spec/extensions/eager_each_spec.rb +8 -8
- data/spec/extensions/empty_array_ignore_nulls_spec.rb +10 -10
- data/spec/extensions/error_splitter_spec.rb +2 -2
- data/spec/extensions/error_sql_spec.rb +4 -4
- data/spec/extensions/eval_inspect_spec.rb +3 -3
- data/spec/extensions/filter_having_spec.rb +8 -8
- data/spec/extensions/force_encoding_spec.rb +30 -30
- data/spec/extensions/from_block_spec.rb +7 -7
- data/spec/extensions/graph_each_spec.rb +19 -19
- data/spec/extensions/hash_aliases_spec.rb +5 -5
- data/spec/extensions/hook_class_methods_spec.rb +100 -100
- data/spec/extensions/inflector_spec.rb +54 -54
- data/spec/extensions/input_transformer_spec.rb +10 -10
- data/spec/extensions/insert_returning_select_spec.rb +8 -8
- data/spec/extensions/instance_filters_spec.rb +26 -26
- data/spec/extensions/instance_hooks_spec.rb +85 -85
- data/spec/extensions/json_serializer_spec.rb +68 -68
- data/spec/extensions/lazy_attributes_spec.rb +49 -49
- data/spec/extensions/list_spec.rb +77 -75
- data/spec/extensions/looser_typecasting_spec.rb +16 -16
- data/spec/extensions/many_through_many_spec.rb +627 -627
- data/spec/extensions/meta_def_spec.rb +7 -7
- data/spec/extensions/migration_spec.rb +217 -217
- data/spec/extensions/modification_detection_spec.rb +20 -20
- data/spec/extensions/mssql_optimistic_locking_spec.rb +21 -21
- data/spec/extensions/named_timezones_spec.rb +18 -18
- data/spec/extensions/nested_attributes_spec.rb +107 -107
- data/spec/extensions/null_dataset_spec.rb +24 -24
- data/spec/extensions/optimistic_locking_spec.rb +21 -21
- data/spec/extensions/pagination_spec.rb +52 -52
- data/spec/extensions/pg_array_associations_spec.rb +273 -273
- data/spec/extensions/pg_array_ops_spec.rb +52 -52
- data/spec/extensions/pg_array_spec.rb +152 -152
- data/spec/extensions/pg_enum_spec.rb +13 -13
- data/spec/extensions/pg_hstore_ops_spec.rb +63 -63
- data/spec/extensions/pg_hstore_spec.rb +84 -84
- data/spec/extensions/pg_inet_spec.rb +15 -15
- data/spec/extensions/pg_interval_spec.rb +29 -29
- data/spec/extensions/pg_json_ops_spec.rb +86 -84
- data/spec/extensions/pg_json_spec.rb +104 -104
- data/spec/extensions/pg_loose_count_spec.rb +6 -6
- data/spec/extensions/pg_range_ops_spec.rb +24 -24
- data/spec/extensions/pg_range_spec.rb +143 -143
- data/spec/extensions/pg_row_ops_spec.rb +14 -14
- data/spec/extensions/pg_row_plugin_spec.rb +12 -12
- data/spec/extensions/pg_row_spec.rb +118 -118
- data/spec/extensions/pg_static_cache_updater_spec.rb +28 -28
- data/spec/extensions/pg_typecast_on_load_spec.rb +21 -21
- data/spec/extensions/prepared_statements_associations_spec.rb +42 -42
- data/spec/extensions/prepared_statements_safe_spec.rb +18 -18
- data/spec/extensions/prepared_statements_spec.rb +28 -28
- data/spec/extensions/prepared_statements_with_pk_spec.rb +11 -11
- data/spec/extensions/pretty_table_spec.rb +16 -16
- data/spec/extensions/query_literals_spec.rb +37 -37
- data/spec/extensions/query_spec.rb +32 -32
- data/spec/extensions/rcte_tree_spec.rb +141 -141
- data/spec/extensions/round_timestamps_spec.rb +21 -21
- data/spec/extensions/schema_caching_spec.rb +8 -8
- data/spec/extensions/schema_dumper_spec.rb +78 -78
- data/spec/extensions/schema_spec.rb +31 -27
- data/spec/extensions/scissors_spec.rb +3 -3
- data/spec/extensions/select_remove_spec.rb +14 -14
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +28 -28
- data/spec/extensions/serialization_modification_detection_spec.rb +33 -33
- data/spec/extensions/serialization_spec.rb +79 -78
- data/spec/extensions/server_block_spec.rb +17 -17
- data/spec/extensions/set_overrides_spec.rb +30 -30
- data/spec/extensions/sharding_spec.rb +65 -65
- data/spec/extensions/shared_caching_spec.rb +29 -29
- data/spec/extensions/single_table_inheritance_spec.rb +79 -79
- data/spec/extensions/skip_create_refresh_spec.rb +3 -3
- data/spec/extensions/spec_helper.rb +4 -29
- data/spec/extensions/split_array_nil_spec.rb +9 -9
- data/spec/extensions/split_values_spec.rb +7 -7
- data/spec/extensions/sql_expr_spec.rb +32 -32
- data/spec/extensions/static_cache_spec.rb +123 -123
- data/spec/extensions/string_date_time_spec.rb +34 -34
- data/spec/extensions/string_stripper_spec.rb +15 -15
- data/spec/extensions/subclasses_spec.rb +31 -31
- data/spec/extensions/table_select_spec.rb +15 -15
- data/spec/extensions/tactical_eager_loading_spec.rb +23 -23
- data/spec/extensions/thread_local_timezones_spec.rb +13 -13
- data/spec/extensions/timestamps_spec.rb +40 -40
- data/spec/extensions/to_dot_spec.rb +34 -34
- data/spec/extensions/touch_spec.rb +52 -52
- data/spec/extensions/tree_spec.rb +72 -72
- data/spec/extensions/typecast_on_load_spec.rb +25 -25
- data/spec/extensions/unlimited_update_spec.rb +2 -2
- data/spec/extensions/update_or_create_spec.rb +36 -36
- data/spec/extensions/update_primary_key_spec.rb +35 -35
- data/spec/extensions/update_refresh_spec.rb +41 -0
- data/spec/extensions/validate_associated_spec.rb +52 -0
- data/spec/extensions/validation_class_methods_spec.rb +314 -317
- data/spec/extensions/validation_helpers_spec.rb +195 -195
- data/spec/extensions/xml_serializer_spec.rb +48 -48
- data/spec/guards_helper.rb +55 -0
- data/spec/integration/associations_test.rb +1089 -1088
- data/spec/integration/database_test.rb +29 -29
- data/spec/integration/dataset_test.rb +661 -661
- data/spec/integration/eager_loader_test.rb +147 -147
- data/spec/integration/migrator_test.rb +122 -122
- data/spec/integration/model_test.rb +70 -70
- data/spec/integration/plugin_test.rb +682 -640
- data/spec/integration/prepared_statement_test.rb +172 -172
- data/spec/integration/schema_test.rb +245 -245
- data/spec/integration/spec_helper.rb +1 -64
- data/spec/integration/timezone_test.rb +17 -17
- data/spec/integration/transaction_test.rb +87 -87
- data/spec/integration/type_test.rb +33 -33
- data/spec/model/association_reflection_spec.rb +130 -121
- data/spec/model/associations_spec.rb +1112 -1113
- data/spec/model/base_spec.rb +197 -196
- data/spec/model/class_dataset_methods_spec.rb +118 -118
- data/spec/model/dataset_methods_spec.rb +49 -49
- data/spec/model/eager_loading_spec.rb +705 -702
- data/spec/model/hooks_spec.rb +169 -168
- data/spec/model/inflector_spec.rb +5 -5
- data/spec/model/model_spec.rb +287 -297
- data/spec/model/plugins_spec.rb +47 -47
- data/spec/model/record_spec.rb +534 -535
- data/spec/model/spec_helper.rb +3 -21
- data/spec/model/validations_spec.rb +72 -70
- data/spec/spec_config.rb +8 -0
- metadata +41 -9
- data/lib/sequel/adapters/fdbsql.rb +0 -286
- data/lib/sequel/adapters/jdbc/fdbsql.rb +0 -66
- data/lib/sequel/adapters/openbase.rb +0 -54
- data/lib/sequel/adapters/shared/fdbsql.rb +0 -550
- data/spec/adapters/fdbsql_spec.rb +0 -429
- data/spec/rspec_helper.rb +0 -22
data/spec/bin_spec.rb
CHANGED
@@ -26,7 +26,7 @@ DB2 = Sequel.connect("#{CONN_PREFIX}#{BIN_SPEC_DB2}")
|
|
26
26
|
File.delete(BIN_SPEC_DB) if File.file?(BIN_SPEC_DB)
|
27
27
|
File.delete(BIN_SPEC_DB2) if File.file?(BIN_SPEC_DB2)
|
28
28
|
|
29
|
-
require
|
29
|
+
require 'minitest/autorun'
|
30
30
|
|
31
31
|
describe "bin/sequel" do
|
32
32
|
def bin(opts={})
|
@@ -41,22 +41,20 @@ describe "bin/sequel" do
|
|
41
41
|
File.delete(BIN_SPEC_DB) if File.file?(BIN_SPEC_DB)
|
42
42
|
File.delete(BIN_SPEC_DB2) if File.file?(BIN_SPEC_DB2)
|
43
43
|
File.delete(TMP_FILE) if File.file?(TMP_FILE)
|
44
|
-
end
|
45
|
-
after(:all) do
|
46
44
|
File.delete(OUTPUT) if File.file?(OUTPUT)
|
47
45
|
end
|
48
46
|
|
49
47
|
it "-h should print the help" do
|
50
48
|
help = bin(:args=>"-h", :no_conn=>true)
|
51
|
-
help.
|
52
|
-
help.
|
49
|
+
help.must_match(/\ASequel: The Database Toolkit for Ruby/)
|
50
|
+
help.must_match(/^Usage: sequel /)
|
53
51
|
end
|
54
52
|
|
55
53
|
it "-c should run code" do
|
56
|
-
bin(:args=>'-c "print DB.tables.inspect"').
|
54
|
+
bin(:args=>'-c "print DB.tables.inspect"').must_equal '[]'
|
57
55
|
DB.create_table(:a){Integer :a}
|
58
|
-
bin(:args=>'-c "print DB.tables.inspect"').
|
59
|
-
bin(:args=>'-v -c "print DB.tables.inspect"').
|
56
|
+
bin(:args=>'-c "print DB.tables.inspect"').must_equal '[:a]'
|
57
|
+
bin(:args=>'-v -c "print DB.tables.inspect"').strip.must_equal "sequel #{Sequel.version}\n[:a]"
|
60
58
|
end
|
61
59
|
|
62
60
|
it "-C should copy databases" do
|
@@ -70,7 +68,7 @@ describe "bin/sequel" do
|
|
70
68
|
end
|
71
69
|
DB[:a].insert(1, 'foo')
|
72
70
|
DB[:b].insert(1)
|
73
|
-
bin(:args=>'-C', :post=>"#{CONN_PREFIX}#{BIN_SPEC_DB2}").
|
71
|
+
bin(:args=>'-C', :post=>"#{CONN_PREFIX}#{BIN_SPEC_DB2}").must_match Regexp.new(<<END)
|
74
72
|
Databases connections successful
|
75
73
|
Migrations dumped successfully
|
76
74
|
Tables created
|
@@ -86,15 +84,15 @@ Begin adding foreign key constraints
|
|
86
84
|
Finished adding foreign key constraints
|
87
85
|
Database copy finished in \\d\\.\\d+ seconds
|
88
86
|
END
|
89
|
-
DB2.tables.sort_by{|t| t.to_s}.
|
90
|
-
DB[:a].all.
|
91
|
-
DB[:b].all.
|
92
|
-
DB2.schema(:a).map{|col, sch| [col, *sch.values_at(:allow_null, :default, :primary_key, :db_type, :type, :ruby_default)]}.
|
93
|
-
DB2.schema(:b).map{|col, sch| [col, *sch.values_at(:allow_null, :default, :primary_key, :db_type, :type, :ruby_default)]}.
|
94
|
-
DB2.indexes(:a).
|
95
|
-
DB2.indexes(:b).
|
96
|
-
DB2.foreign_key_list(:a).
|
97
|
-
DB2.foreign_key_list(:b).
|
87
|
+
DB2.tables.sort_by{|t| t.to_s}.must_equal [:a, :b]
|
88
|
+
DB[:a].all.must_equal [{:a=>1, :name=>'foo'}]
|
89
|
+
DB[:b].all.must_equal [{:a=>1}]
|
90
|
+
DB2.schema(:a).map{|col, sch| [col, *sch.values_at(:allow_null, :default, :primary_key, :db_type, :type, :ruby_default)]}.must_equal [[:a, false, nil, true, "integer", :integer, nil], [:name, true, nil, false, "varchar(255)", :string, nil]]
|
91
|
+
DB2.schema(:b).map{|col, sch| [col, *sch.values_at(:allow_null, :default, :primary_key, :db_type, :type, :ruby_default)]}.must_equal [[:a, true, nil, false, "integer", :integer, nil]]
|
92
|
+
DB2.indexes(:a).must_equal({})
|
93
|
+
DB2.indexes(:b).must_equal(:b_a_index=>{:unique=>false, :columns=>[:a]})
|
94
|
+
DB2.foreign_key_list(:a).must_equal []
|
95
|
+
DB2.foreign_key_list(:b).must_equal [{:columns=>[:a], :table=>:a, :key=>nil, :on_update=>:no_action, :on_delete=>:no_action}]
|
98
96
|
end
|
99
97
|
|
100
98
|
it "-d and -D should dump generic and specific migrations" do
|
@@ -106,7 +104,7 @@ END
|
|
106
104
|
foreign_key :a, :a
|
107
105
|
index :a
|
108
106
|
end
|
109
|
-
bin(:args=>'-d').
|
107
|
+
bin(:args=>'-d').must_equal <<END
|
110
108
|
Sequel.migration do
|
111
109
|
change do
|
112
110
|
create_table(:a) do
|
@@ -122,7 +120,7 @@ Sequel.migration do
|
|
122
120
|
end
|
123
121
|
end
|
124
122
|
END
|
125
|
-
bin(:args=>'-D').
|
123
|
+
bin(:args=>'-D').must_equal <<END
|
126
124
|
Sequel.migration do
|
127
125
|
change do
|
128
126
|
create_table(:a) do
|
@@ -141,79 +139,79 @@ END
|
|
141
139
|
end
|
142
140
|
|
143
141
|
it "-E should echo SQL statements to stdout" do
|
144
|
-
bin(:args=>'-E -c DB.tables').
|
142
|
+
bin(:args=>'-E -c DB.tables').must_match %r{SELECT \* FROM `sqlite_master` WHERE \(type = 'table' AND NOT name = 'sqlite_sequence'\)\n}
|
145
143
|
end
|
146
144
|
|
147
145
|
it "-I should include directory in load path" do
|
148
|
-
bin(:args=>'-Ifoo -c "p 1 if $:.include?(\'foo\')"').
|
146
|
+
bin(:args=>'-Ifoo -c "p 1 if $:.include?(\'foo\')"').must_equal "1\n"
|
149
147
|
end
|
150
148
|
|
151
149
|
it "-l should log SQL statements to file" do
|
152
|
-
bin(:args=>"-l #{TMP_FILE} -c DB.tables").
|
153
|
-
File.read(TMP_FILE).
|
150
|
+
bin(:args=>"-l #{TMP_FILE} -c DB.tables").must_equal ''
|
151
|
+
File.read(TMP_FILE).must_match %r{SELECT \* FROM `sqlite_master` WHERE \(type = 'table' AND NOT name = 'sqlite_sequence'\)\n}
|
154
152
|
end
|
155
153
|
|
156
154
|
it "-L should load all *.rb files in given directory" do
|
157
|
-
bin(:args=>'-L ./lib/sequel/connection_pool -c "p [Sequel::SingleConnectionPool, Sequel::ThreadedConnectionPool, Sequel::ShardedSingleConnectionPool, Sequel::ShardedThreadedConnectionPool].length"').
|
155
|
+
bin(:args=>'-L ./lib/sequel/connection_pool -c "p [Sequel::SingleConnectionPool, Sequel::ThreadedConnectionPool, Sequel::ShardedSingleConnectionPool, Sequel::ShardedThreadedConnectionPool].length"').must_equal "4\n"
|
158
156
|
end
|
159
157
|
|
160
158
|
it "-m should migrate database up" do
|
161
|
-
bin(:args=>"-m spec/files/integer_migrations").
|
162
|
-
DB.tables.sort_by{|t| t.to_s}.
|
159
|
+
bin(:args=>"-m spec/files/integer_migrations").must_equal ''
|
160
|
+
DB.tables.sort_by{|t| t.to_s}.must_equal [:schema_info, :sm1111, :sm2222, :sm3333]
|
163
161
|
end
|
164
162
|
|
165
163
|
it "-M should specify version to migrate to" do
|
166
|
-
bin(:args=>"-m spec/files/integer_migrations -M 2").
|
167
|
-
DB.tables.sort_by{|t| t.to_s}.
|
164
|
+
bin(:args=>"-m spec/files/integer_migrations -M 2").must_equal ''
|
165
|
+
DB.tables.sort_by{|t| t.to_s}.must_equal [:schema_info, :sm1111, :sm2222]
|
168
166
|
end
|
169
167
|
|
170
168
|
it "-N should not test for a valid connection" do
|
171
|
-
bin(:no_conn=>true, :args=>"-c '' -N #{CONN_PREFIX}spec/nonexistent/foo").
|
172
|
-
bin(:no_conn=>true, :args=>"-c '' #{CONN_PREFIX}spec/nonexistent/foo", :stderr=>true).
|
169
|
+
bin(:no_conn=>true, :args=>"-c '' -N #{CONN_PREFIX}spec/nonexistent/foo").must_equal ''
|
170
|
+
bin(:no_conn=>true, :args=>"-c '' #{CONN_PREFIX}spec/nonexistent/foo", :stderr=>true).must_match(/\AError: Sequel::DatabaseConnectionError: /)
|
173
171
|
end
|
174
172
|
|
175
173
|
it "-r should require a given library" do
|
176
|
-
bin(:args=>'-rsequel/extensions/sql_expr -c "print DB.literal(1.sql_expr)"').
|
174
|
+
bin(:args=>'-rsequel/extensions/sql_expr -c "print DB.literal(1.sql_expr)"').must_equal "1"
|
177
175
|
end
|
178
176
|
|
179
177
|
it "-S should dump the schema cache" do
|
180
|
-
bin(:args=>"-S #{TMP_FILE}").
|
181
|
-
Marshal.load(File.read(TMP_FILE)).
|
178
|
+
bin(:args=>"-S #{TMP_FILE}").must_equal ''
|
179
|
+
Marshal.load(File.read(TMP_FILE)).must_equal({})
|
182
180
|
DB.create_table(:a){Integer :a}
|
183
|
-
bin(:args=>"-S #{TMP_FILE}").
|
184
|
-
Marshal.load(File.read(TMP_FILE)).
|
181
|
+
bin(:args=>"-S #{TMP_FILE}").must_equal ''
|
182
|
+
Marshal.load(File.read(TMP_FILE)).must_equal("`a`"=>[[:a, {:type=>:integer, :db_type=>"integer", :ruby_default=>nil, :allow_null=>true, :default=>nil, :primary_key=>false}]])
|
185
183
|
end
|
186
184
|
|
187
185
|
it "-t should output full backtraces on error" do
|
188
|
-
bin(:args=>'-c "lambda{lambda{lambda{raise \'foo\'}.call}.call}.call"', :stderr=>true).count("\n").
|
189
|
-
bin(:args=>'-t -c "lambda{lambda{lambda{raise \'foo\'}.call}.call}.call"', :stderr=>true).count("\n").
|
186
|
+
bin(:args=>'-c "lambda{lambda{lambda{raise \'foo\'}.call}.call}.call"', :stderr=>true).count("\n").must_be :<, 3
|
187
|
+
bin(:args=>'-t -c "lambda{lambda{lambda{raise \'foo\'}.call}.call}.call"', :stderr=>true).count("\n").must_be :>, 3
|
190
188
|
end
|
191
189
|
|
192
190
|
it "-v should output the Sequel version and exit if database is not given" do
|
193
|
-
bin(:args=>"-v", :no_conn=>true).
|
191
|
+
bin(:args=>"-v", :no_conn=>true).strip.must_equal "sequel #{Sequel.version}"
|
194
192
|
end
|
195
193
|
|
196
194
|
it "should error if using -M without -m" do
|
197
|
-
bin(:args=>'-M 2', :stderr=>true).
|
195
|
+
bin(:args=>'-M 2', :stderr=>true).must_equal "Error: Must specify -m if using -M\n"
|
198
196
|
end
|
199
197
|
|
200
198
|
it "should error if using mutually exclusive options together" do
|
201
|
-
bin(:args=>'-c foo -d', :stderr=>true).
|
202
|
-
bin(:args=>'-D -d', :stderr=>true).
|
203
|
-
bin(:args=>'-m foo -d', :stderr=>true).
|
204
|
-
bin(:args=>'-S foo -d', :stderr=>true).
|
205
|
-
bin(:args=>'-S foo -C', :stderr=>true).
|
199
|
+
bin(:args=>'-c foo -d', :stderr=>true).must_equal "Error: Cannot specify -c and -d together\n"
|
200
|
+
bin(:args=>'-D -d', :stderr=>true).must_equal "Error: Cannot specify -D and -d together\n"
|
201
|
+
bin(:args=>'-m foo -d', :stderr=>true).must_equal "Error: Cannot specify -m and -d together\n"
|
202
|
+
bin(:args=>'-S foo -d', :stderr=>true).must_equal "Error: Cannot specify -S and -d together\n"
|
203
|
+
bin(:args=>'-S foo -C', :stderr=>true).must_equal "Error: Cannot specify -S and -C together\n"
|
206
204
|
end
|
207
205
|
|
208
206
|
it "should use a mock database if no database is given" do
|
209
|
-
bin(:args=>'-c "print DB.adapter_scheme"', :no_conn=>true).
|
207
|
+
bin(:args=>'-c "print DB.adapter_scheme"', :no_conn=>true).must_equal "mock"
|
210
208
|
end
|
211
209
|
|
212
210
|
it "should work with a yaml config file" do
|
213
211
|
File.open(TMP_FILE, 'wb'){|f| f.write(YAML.dump(CONN_HASH))}
|
214
|
-
bin(:args=>"-c \"print DB.tables.inspect\" #{TMP_FILE}", :no_conn=>true).
|
212
|
+
bin(:args=>"-c \"print DB.tables.inspect\" #{TMP_FILE}", :no_conn=>true).must_equal "[]"
|
215
213
|
DB.create_table(:a){Integer :a}
|
216
|
-
bin(:args=>"-c \"print DB.tables.inspect\" #{TMP_FILE}", :no_conn=>true).
|
214
|
+
bin(:args=>"-c \"print DB.tables.inspect\" #{TMP_FILE}", :no_conn=>true).must_equal "[:a]"
|
217
215
|
end
|
218
216
|
|
219
217
|
it "should work with a yaml config file with string keys" do
|
@@ -221,36 +219,36 @@ END
|
|
221
219
|
CONN_HASH.each{|k,v| h[k.to_s] = v}
|
222
220
|
File.open(TMP_FILE, 'wb'){|f| f.write(YAML.dump(h))}
|
223
221
|
DB.create_table(:a){Integer :a}
|
224
|
-
bin(:args=>"-c \"print DB.tables.inspect\" #{TMP_FILE}", :no_conn=>true).
|
222
|
+
bin(:args=>"-c \"print DB.tables.inspect\" #{TMP_FILE}", :no_conn=>true).must_equal "[:a]"
|
225
223
|
end
|
226
224
|
|
227
225
|
it "should work with a yaml config file with environments" do
|
228
226
|
File.open(TMP_FILE, 'wb'){|f| f.write(YAML.dump(:development=>CONN_HASH))}
|
229
|
-
bin(:args=>"-c \"print DB.tables.inspect\" #{TMP_FILE}", :no_conn=>true).
|
227
|
+
bin(:args=>"-c \"print DB.tables.inspect\" #{TMP_FILE}", :no_conn=>true).must_equal "[]"
|
230
228
|
DB.create_table(:a){Integer :a}
|
231
|
-
bin(:args=>"-c \"print DB.tables.inspect\" #{TMP_FILE}", :no_conn=>true).
|
229
|
+
bin(:args=>"-c \"print DB.tables.inspect\" #{TMP_FILE}", :no_conn=>true).must_equal "[:a]"
|
232
230
|
end
|
233
231
|
|
234
232
|
it "-e should set environment for yaml config file" do
|
235
233
|
File.open(TMP_FILE, 'wb'){|f| f.write(YAML.dump(:foo=>CONN_HASH))}
|
236
|
-
bin(:args=>"-c \"print DB.tables.inspect\" -e foo #{TMP_FILE}", :no_conn=>true).
|
234
|
+
bin(:args=>"-c \"print DB.tables.inspect\" -e foo #{TMP_FILE}", :no_conn=>true).must_equal "[]"
|
237
235
|
DB.create_table(:a){Integer :a}
|
238
|
-
bin(:args=>"-c \"print DB.tables.inspect\" -e foo #{TMP_FILE}", :no_conn=>true).
|
236
|
+
bin(:args=>"-c \"print DB.tables.inspect\" -e foo #{TMP_FILE}", :no_conn=>true).must_equal "[:a]"
|
239
237
|
File.open(TMP_FILE, 'wb'){|f| f.write(YAML.dump('foo'=>CONN_HASH))}
|
240
|
-
bin(:args=>"-c \"print DB.tables.inspect\" -e foo #{TMP_FILE}", :no_conn=>true).
|
238
|
+
bin(:args=>"-c \"print DB.tables.inspect\" -e foo #{TMP_FILE}", :no_conn=>true).must_equal "[:a]"
|
241
239
|
end
|
242
240
|
|
243
241
|
it "should run code in given filenames" do
|
244
242
|
File.open(TMP_FILE, 'wb'){|f| f.write('print DB.tables.inspect')}
|
245
|
-
bin(:post=>TMP_FILE).
|
243
|
+
bin(:post=>TMP_FILE).must_equal '[]'
|
246
244
|
DB.create_table(:a){Integer :a}
|
247
|
-
bin(:post=>TMP_FILE).
|
248
|
-
bin(:post=>TMP_FILE, :args=>'-v').
|
245
|
+
bin(:post=>TMP_FILE).must_equal '[:a]'
|
246
|
+
bin(:post=>TMP_FILE, :args=>'-v').strip.must_equal "sequel #{Sequel.version}\n[:a]"
|
249
247
|
end
|
250
248
|
|
251
249
|
it "should run code provided on stdin" do
|
252
|
-
bin(:pre=>'echo print DB.tables.inspect | ').
|
250
|
+
bin(:pre=>'echo print DB.tables.inspect | ').must_equal '[]'
|
253
251
|
DB.create_table(:a){Integer :a}
|
254
|
-
bin(:pre=>'echo print DB.tables.inspect | ').
|
252
|
+
bin(:pre=>'echo print DB.tables.inspect | ').must_equal '[:a]'
|
255
253
|
end
|
256
254
|
end
|
@@ -15,32 +15,32 @@ describe "An empty ConnectionPool" do
|
|
15
15
|
@cpool = Sequel::ConnectionPool.get_pool(mock_db.call, CONNECTION_POOL_DEFAULTS)
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
|
-
@cpool.available_connections.
|
18
|
+
it "should have no available connections" do
|
19
|
+
@cpool.available_connections.must_equal []
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
|
-
@cpool.allocated.
|
22
|
+
it "should have no allocated connections" do
|
23
|
+
@cpool.allocated.must_equal({})
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
|
-
@cpool.created_count.
|
26
|
+
it "should have a created_count of zero" do
|
27
|
+
@cpool.created_count.must_equal 0
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
31
|
describe "ConnectionPool options" do
|
32
|
-
|
32
|
+
it "should support string option values" do
|
33
33
|
cpool = Sequel::ConnectionPool.get_pool(mock_db.call, {:max_connections=>'5', :pool_timeout=>'3', :pool_sleep_time=>'0.01'})
|
34
|
-
cpool.max_size.
|
35
|
-
cpool.instance_variable_get(:@timeout).
|
36
|
-
cpool.instance_variable_get(:@sleep_time).
|
34
|
+
cpool.max_size.must_equal 5
|
35
|
+
cpool.instance_variable_get(:@timeout).must_equal 3
|
36
|
+
cpool.instance_variable_get(:@sleep_time).must_equal 0.01 unless cpool.class::USE_WAITER
|
37
37
|
end
|
38
38
|
|
39
|
-
|
40
|
-
lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>0)}.
|
41
|
-
lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>-10)}.
|
42
|
-
lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>'-10')}.
|
43
|
-
lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>'0')}.
|
39
|
+
it "should raise an error unless size is positive" do
|
40
|
+
lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>0)}.must_raise(Sequel::Error)
|
41
|
+
lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>-10)}.must_raise(Sequel::Error)
|
42
|
+
lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>'-10')}.must_raise(Sequel::Error)
|
43
|
+
lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>'0')}.must_raise(Sequel::Error)
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -51,86 +51,86 @@ describe "A connection pool handling connections" do
|
|
51
51
|
@cpool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| msp.call}){:got_connection}, CONNECTION_POOL_DEFAULTS.merge(:max_connections=>@max_size))
|
52
52
|
end
|
53
53
|
|
54
|
-
|
54
|
+
it "#hold should increment #created_count" do
|
55
55
|
@cpool.hold do
|
56
|
-
@cpool.created_count.
|
57
|
-
@cpool.hold {@cpool.hold {@cpool.created_count.
|
58
|
-
Thread.new{@cpool.hold {@cpool.created_count.
|
56
|
+
@cpool.created_count.must_equal 1
|
57
|
+
@cpool.hold {@cpool.hold {@cpool.created_count.must_equal 1}}
|
58
|
+
Thread.new{@cpool.hold {_(@cpool.created_count).must_equal 2}}.join
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
|
62
|
+
it "#hold should add the connection to the #allocated array" do
|
63
63
|
@cpool.hold do
|
64
|
-
@cpool.allocated.size.
|
64
|
+
@cpool.allocated.size.must_equal 1
|
65
65
|
|
66
|
-
@cpool.allocated.
|
66
|
+
@cpool.allocated.must_equal(Thread.current=>:got_connection)
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
-
|
71
|
-
@cpool.hold {|conn| conn.
|
70
|
+
it "#hold should yield a new connection" do
|
71
|
+
@cpool.hold {|conn| conn.must_equal :got_connection}
|
72
72
|
end
|
73
73
|
|
74
|
-
|
74
|
+
it "a connection should be de-allocated after it has been used in #hold" do
|
75
75
|
@cpool.hold {}
|
76
|
-
@cpool.allocated.size.
|
76
|
+
@cpool.allocated.size.must_equal 0
|
77
77
|
end
|
78
78
|
|
79
|
-
|
80
|
-
@cpool.hold {:block_return}.
|
79
|
+
it "#hold should return the value of its block" do
|
80
|
+
@cpool.hold {:block_return}.must_equal :block_return
|
81
81
|
end
|
82
82
|
|
83
83
|
if RUBY_VERSION < '1.9.0' and !defined?(RUBY_ENGINE)
|
84
|
-
|
84
|
+
it "#hold should remove dead threads from the pool if it reaches its max_size" do
|
85
85
|
Thread.new{@cpool.hold{Thread.current.exit!}}.join
|
86
|
-
@cpool.allocated.keys.map{|t| t.alive?}.
|
86
|
+
@cpool.allocated.keys.map{|t| t.alive?}.must_equal [false]
|
87
87
|
|
88
88
|
Thread.new{@cpool.hold{Thread.current.exit!}}.join
|
89
|
-
@cpool.allocated.keys.map{|t| t.alive?}.
|
89
|
+
@cpool.allocated.keys.map{|t| t.alive?}.must_equal [false, false]
|
90
90
|
|
91
91
|
Thread.new{@cpool.hold{}}.join
|
92
|
-
@cpool.allocated.
|
92
|
+
@cpool.allocated.must_equal({})
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
|
96
|
+
it "#make_new should not make more than max_size connections" do
|
97
97
|
q = Queue.new
|
98
98
|
50.times{Thread.new{@cpool.hold{q.pop}}}
|
99
99
|
50.times{q.push nil}
|
100
|
-
@cpool.created_count.
|
100
|
+
@cpool.created_count.must_be :<=, @max_size
|
101
101
|
end
|
102
102
|
|
103
|
-
|
104
|
-
@max_size.
|
105
|
-
proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.
|
106
|
-
@max_size.
|
103
|
+
it "database's disconnect connection method should be called when a disconnect is detected" do
|
104
|
+
@max_size.must_equal 2
|
105
|
+
proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
|
106
|
+
@max_size.must_equal 3
|
107
107
|
end
|
108
108
|
|
109
|
-
|
110
|
-
@cpool.created_count.
|
109
|
+
it "#hold should remove the connection if a DatabaseDisconnectError is raised" do
|
110
|
+
@cpool.created_count.must_equal 0
|
111
111
|
q, q1 = Queue.new, Queue.new
|
112
112
|
@cpool.hold{Thread.new{@cpool.hold{q1.pop; q.push nil}; q1.pop; q.push nil}; q1.push nil; q.pop; q1.push nil; q.pop}
|
113
|
-
@cpool.created_count.
|
114
|
-
proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.
|
115
|
-
@cpool.created_count.
|
116
|
-
proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.
|
117
|
-
@cpool.created_count.
|
118
|
-
proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.
|
119
|
-
@cpool.created_count.
|
113
|
+
@cpool.created_count.must_equal 2
|
114
|
+
proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
|
115
|
+
@cpool.created_count.must_equal 1
|
116
|
+
proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
|
117
|
+
@cpool.created_count.must_equal 0
|
118
|
+
proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
|
119
|
+
@cpool.created_count.must_equal 0
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
123
|
describe "A connection pool handling connection errors" do
|
124
|
-
|
124
|
+
it "#hold should raise a Sequel::DatabaseConnectionError if an exception is raised by the connection_proc" do
|
125
125
|
cpool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS){raise Interrupt}
|
126
|
-
proc{cpool.hold{:block_return}}.
|
127
|
-
cpool.created_count.
|
126
|
+
proc{cpool.hold{:block_return}}.must_raise(Sequel::DatabaseConnectionError)
|
127
|
+
cpool.created_count.must_equal 0
|
128
128
|
end
|
129
129
|
|
130
|
-
|
130
|
+
it "#hold should raise a Sequel::DatabaseConnectionError if nil is returned by the connection_proc" do
|
131
131
|
cpool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS){nil}
|
132
|
-
proc{cpool.hold{:block_return}}.
|
133
|
-
cpool.created_count.
|
132
|
+
proc{cpool.hold{:block_return}}.must_raise(Sequel::DatabaseConnectionError)
|
133
|
+
cpool.created_count.must_equal 0
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
@@ -144,24 +144,24 @@ describe "ConnectionPool#hold" do
|
|
144
144
|
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{c.new}, CONNECTION_POOL_DEFAULTS)
|
145
145
|
end
|
146
146
|
|
147
|
-
|
147
|
+
it "shoulda use the database's connect method to get new connections" do
|
148
148
|
res = nil
|
149
149
|
@pool.hold {|c| res = c}
|
150
|
-
res.
|
151
|
-
res.value.
|
150
|
+
res.must_be_kind_of(@c)
|
151
|
+
res.value.must_equal 1
|
152
152
|
@pool.hold {|c| res = c}
|
153
|
-
res.
|
154
|
-
res.value.
|
153
|
+
res.must_be_kind_of(@c)
|
154
|
+
res.value.must_equal 1 # the connection maker is invoked only once
|
155
155
|
end
|
156
156
|
|
157
|
-
|
157
|
+
it "should be re-entrant by the same thread" do
|
158
158
|
cc = nil
|
159
159
|
@pool.hold {|c| @pool.hold {|c1| @pool.hold {|c2| cc = c2}}}
|
160
|
-
cc.
|
160
|
+
cc.must_be_kind_of(@c)
|
161
161
|
end
|
162
162
|
|
163
|
-
|
164
|
-
proc {@pool.hold {|c| c.foobar}}.
|
163
|
+
it "should catch exceptions and reraise them" do
|
164
|
+
proc {@pool.hold {|c| c.foobar}}.must_raise(NoMethodError)
|
165
165
|
end
|
166
166
|
end
|
167
167
|
|
@@ -172,51 +172,51 @@ describe "A connection pool with a max size of 1" do
|
|
172
172
|
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{icp.call; 'herro'}, CONNECTION_POOL_DEFAULTS.merge(:max_connections=>1))
|
173
173
|
end
|
174
174
|
|
175
|
-
|
175
|
+
it "should let only one thread access the connection at any time" do
|
176
176
|
cc,c1, c2 = nil
|
177
177
|
q, q1 = Queue.new, Queue.new
|
178
178
|
|
179
179
|
t1 = Thread.new {@pool.hold {|c| cc = c; c1 = c.dup; q1.push nil; q.pop}}
|
180
180
|
q1.pop
|
181
|
-
cc.
|
182
|
-
c1.
|
181
|
+
cc.must_equal 'herro'
|
182
|
+
c1.must_equal 'herro'
|
183
183
|
|
184
184
|
t2 = Thread.new {@pool.hold {|c| c2 = c.dup; q1.push nil; q.pop;}}
|
185
185
|
|
186
186
|
# connection held by t1
|
187
|
-
t1.
|
188
|
-
t2.
|
187
|
+
t1.must_be :alive?
|
188
|
+
t2.must_be :alive?
|
189
189
|
|
190
|
-
cc.
|
191
|
-
c1.
|
192
|
-
c2.
|
190
|
+
cc.must_equal 'herro'
|
191
|
+
c1.must_equal 'herro'
|
192
|
+
c2.must_equal nil
|
193
193
|
|
194
|
-
@pool.available_connections.
|
195
|
-
@pool.allocated.
|
194
|
+
@pool.available_connections.must_be :empty?
|
195
|
+
@pool.allocated.must_equal(t1=>cc)
|
196
196
|
|
197
197
|
cc.gsub!('rr', 'll')
|
198
198
|
q.push nil
|
199
199
|
q1.pop
|
200
200
|
|
201
201
|
t1.join
|
202
|
-
t2.
|
202
|
+
t2.must_be :alive?
|
203
203
|
|
204
|
-
c2.
|
204
|
+
c2.must_equal 'hello'
|
205
205
|
|
206
|
-
@pool.available_connections.
|
207
|
-
@pool.allocated.
|
206
|
+
@pool.available_connections.must_be :empty?
|
207
|
+
@pool.allocated.must_equal(t2=>cc)
|
208
208
|
|
209
209
|
#connection released
|
210
210
|
q.push nil
|
211
211
|
t2.join
|
212
212
|
|
213
|
-
@invoked_count.
|
214
|
-
@pool.size.
|
215
|
-
@pool.available_connections.
|
216
|
-
@pool.allocated.
|
213
|
+
@invoked_count.must_equal 1
|
214
|
+
@pool.size.must_equal 1
|
215
|
+
@pool.available_connections.must_equal [cc]
|
216
|
+
@pool.allocated.must_be :empty?
|
217
217
|
end
|
218
218
|
|
219
|
-
|
219
|
+
it "should let the same thread reenter #hold" do
|
220
220
|
c1, c2, c3 = nil
|
221
221
|
@pool.hold do |c|
|
222
222
|
c1 = c
|
@@ -227,19 +227,19 @@ describe "A connection pool with a max size of 1" do
|
|
227
227
|
end
|
228
228
|
end
|
229
229
|
end
|
230
|
-
c1.
|
231
|
-
c2.
|
232
|
-
c3.
|
230
|
+
c1.must_equal 'herro'
|
231
|
+
c2.must_equal 'herro'
|
232
|
+
c3.must_equal 'herro'
|
233
233
|
|
234
|
-
@invoked_count.
|
235
|
-
@pool.size.
|
236
|
-
@pool.available_connections.size.
|
237
|
-
@pool.allocated.
|
234
|
+
@invoked_count.must_equal 1
|
235
|
+
@pool.size.must_equal 1
|
236
|
+
@pool.available_connections.size.must_equal 1
|
237
|
+
@pool.allocated.must_be :empty?
|
238
238
|
end
|
239
239
|
end
|
240
240
|
|
241
|
-
|
242
|
-
|
241
|
+
ThreadedConnectionPoolSpecs = shared_description do
|
242
|
+
it "should not have all_connections yield connections allocated to other threads" do
|
243
243
|
pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>2, :pool_timeout=>0))
|
244
244
|
q, q1 = Queue.new, Queue.new
|
245
245
|
t = Thread.new do
|
@@ -250,13 +250,13 @@ shared_examples_for "A threaded connection pool" do
|
|
250
250
|
end
|
251
251
|
pool.hold do |c1|
|
252
252
|
q1.pop
|
253
|
-
pool.all_connections{|c| c.
|
253
|
+
pool.all_connections{|c| c.must_equal c1}
|
254
254
|
q.push nil
|
255
255
|
end
|
256
256
|
t.join
|
257
257
|
end
|
258
258
|
|
259
|
-
|
259
|
+
it "should wait until a connection is available if all are checked out" do
|
260
260
|
pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>1, :pool_timeout=>0.1, :pool_sleep_time=>0))
|
261
261
|
q, q1 = Queue.new, Queue.new
|
262
262
|
t = Thread.new do
|
@@ -267,12 +267,12 @@ shared_examples_for "A threaded connection pool" do
|
|
267
267
|
end
|
268
268
|
end
|
269
269
|
q1.pop
|
270
|
-
proc{pool.hold{}}.
|
270
|
+
proc{pool.hold{}}.must_raise(Sequel::PoolTimeout)
|
271
271
|
q.push nil
|
272
272
|
t.join
|
273
273
|
end
|
274
274
|
|
275
|
-
|
275
|
+
it "should not have all_connections yield all available connections" do
|
276
276
|
pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>2, :pool_timeout=>0))
|
277
277
|
q, q1 = Queue.new, Queue.new
|
278
278
|
b = []
|
@@ -291,128 +291,128 @@ shared_examples_for "A threaded connection pool" do
|
|
291
291
|
t.join
|
292
292
|
a = []
|
293
293
|
pool.all_connections{|c| a << c}
|
294
|
-
a.sort.
|
294
|
+
a.sort.must_equal b.sort
|
295
295
|
end
|
296
296
|
|
297
|
-
|
297
|
+
it "should raise a PoolTimeout error if a connection couldn't be acquired before timeout" do
|
298
298
|
q, q1 = Queue.new, Queue.new
|
299
299
|
pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>1, :pool_timeout=>0))
|
300
300
|
t = Thread.new{pool.hold{|c| q1.push nil; q.pop}}
|
301
301
|
q1.pop
|
302
|
-
proc{pool.hold{|c|}}.
|
302
|
+
proc{pool.hold{|c|}}.must_raise(Sequel::PoolTimeout)
|
303
303
|
q.push nil
|
304
304
|
t.join
|
305
305
|
end
|
306
306
|
|
307
307
|
it "should not add a disconnected connection back to the pool if the disconnection_proc raises an error" do
|
308
308
|
pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| raise Sequel::Error}, &@icpp), @cp_opts.merge(:max_connections=>1, :pool_timeout=>0))
|
309
|
-
proc{pool.hold{raise Sequel::DatabaseDisconnectError}}.
|
310
|
-
pool.available_connections.length.
|
309
|
+
proc{pool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::Error)
|
310
|
+
pool.available_connections.length.must_equal 0
|
311
311
|
end
|
312
312
|
|
313
|
-
|
313
|
+
it "should let five threads simultaneously access separate connections" do
|
314
314
|
cc = {}
|
315
315
|
threads = []
|
316
316
|
q, q1, q2 = Queue.new, Queue.new, Queue.new
|
317
317
|
|
318
318
|
5.times{|i| threads << Thread.new{@pool.hold{|c| q.pop; cc[i] = c; q1.push nil; q2.pop}}; q.push nil; q1.pop}
|
319
|
-
threads.each {|t| t.
|
320
|
-
cc.size.
|
321
|
-
@invoked_count.
|
322
|
-
@pool.size.
|
323
|
-
@pool.available_connections.
|
319
|
+
threads.each {|t| t.must_be :alive?}
|
320
|
+
cc.size.must_equal 5
|
321
|
+
@invoked_count.must_equal 5
|
322
|
+
@pool.size.must_equal 5
|
323
|
+
@pool.available_connections.must_be :empty?
|
324
324
|
|
325
325
|
h = {}
|
326
326
|
i = 0
|
327
327
|
threads.each{|t| h[t] = (i+=1)}
|
328
|
-
@pool.allocated.
|
329
|
-
@pool.available_connections.
|
328
|
+
@pool.allocated.must_equal h
|
329
|
+
@pool.available_connections.must_equal []
|
330
330
|
5.times{q2.push nil}
|
331
331
|
threads.each{|t| t.join}
|
332
332
|
|
333
|
-
@pool.available_connections.size.
|
334
|
-
@pool.allocated.
|
333
|
+
@pool.available_connections.size.must_equal 5
|
334
|
+
@pool.allocated.must_be :empty?
|
335
335
|
end
|
336
336
|
|
337
|
-
|
337
|
+
it "should block threads until a connection becomes available" do
|
338
338
|
cc = {}
|
339
339
|
threads = []
|
340
340
|
q, q1 = Queue.new, Queue.new
|
341
341
|
|
342
342
|
5.times{|i| threads << Thread.new{@pool.hold{|c| cc[i] = c; q1.push nil; q.pop}}}
|
343
343
|
5.times{q1.pop}
|
344
|
-
threads.each {|t| t.
|
345
|
-
@pool.available_connections.
|
344
|
+
threads.each {|t| t.must_be :alive?}
|
345
|
+
@pool.available_connections.must_be :empty?
|
346
346
|
|
347
347
|
3.times {|i| threads << Thread.new {@pool.hold {|c| cc[i + 5] = c; q1.push nil}}}
|
348
348
|
|
349
|
-
threads[5].
|
350
|
-
threads[6].
|
351
|
-
threads[7].
|
352
|
-
cc.size.
|
353
|
-
cc[5].
|
354
|
-
cc[6].
|
355
|
-
cc[7].
|
349
|
+
threads[5].must_be :alive?
|
350
|
+
threads[6].must_be :alive?
|
351
|
+
threads[7].must_be :alive?
|
352
|
+
cc.size.must_equal 5
|
353
|
+
cc[5].must_equal nil
|
354
|
+
cc[6].must_equal nil
|
355
|
+
cc[7].must_equal nil
|
356
356
|
|
357
357
|
5.times{q.push nil}
|
358
358
|
5.times{|i| threads[i].join}
|
359
359
|
3.times{q1.pop}
|
360
360
|
3.times{|i| threads[i+5].join}
|
361
361
|
|
362
|
-
threads.each {|t| t.
|
362
|
+
threads.each {|t| t.wont_be :alive?}
|
363
363
|
|
364
|
-
@pool.size.
|
365
|
-
@invoked_count.
|
366
|
-
@pool.available_connections.size.
|
367
|
-
@pool.allocated.
|
364
|
+
@pool.size.must_equal 5
|
365
|
+
@invoked_count.must_equal 5
|
366
|
+
@pool.available_connections.size.must_equal 5
|
367
|
+
@pool.allocated.must_be :empty?
|
368
368
|
end
|
369
369
|
|
370
|
-
|
370
|
+
it "should store connections in a stack if :connection_handling=>:stack" do
|
371
371
|
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:connection_handling=>:stack))
|
372
372
|
c2 = nil
|
373
373
|
c = @pool.hold{|cc| Thread.new{@pool.hold{|cc2| c2 = cc2}}.join; cc}
|
374
|
-
@pool.size.
|
375
|
-
@pool.hold{|cc| cc.
|
376
|
-
@pool.hold{|cc| cc.
|
374
|
+
@pool.size.must_equal 2
|
375
|
+
@pool.hold{|cc| cc.must_equal c}
|
376
|
+
@pool.hold{|cc| cc.must_equal c}
|
377
377
|
@pool.hold do |cc|
|
378
|
-
cc.
|
379
|
-
Thread.new{@pool.hold{|cc2| cc2.
|
378
|
+
cc.must_equal c
|
379
|
+
Thread.new{@pool.hold{|cc2| cc2.must_equal c2}}
|
380
380
|
end
|
381
381
|
end
|
382
382
|
|
383
|
-
|
383
|
+
it "should store connections in a queue if :connection_handling=>:queue" do
|
384
384
|
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:connection_handling=>:queue))
|
385
385
|
c2 = nil
|
386
386
|
c = @pool.hold{|cc| Thread.new{@pool.hold{|cc2| c2 = cc2}}.join; cc}
|
387
|
-
@pool.size.
|
388
|
-
@pool.hold{|cc| cc.
|
389
|
-
@pool.hold{|cc| cc.
|
387
|
+
@pool.size.must_equal 2
|
388
|
+
@pool.hold{|cc| cc.must_equal c2}
|
389
|
+
@pool.hold{|cc| cc.must_equal c}
|
390
390
|
@pool.hold do |cc|
|
391
|
-
cc.
|
392
|
-
Thread.new{@pool.hold{|cc2| cc2.
|
391
|
+
cc.must_equal c2
|
392
|
+
Thread.new{@pool.hold{|cc2| cc2.must_equal c}}
|
393
393
|
end
|
394
394
|
end
|
395
395
|
|
396
|
-
|
396
|
+
it "should not store connections if :connection_handling=>:disconnect" do
|
397
397
|
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:connection_handling=>:disconnect))
|
398
398
|
d = []
|
399
399
|
meta_def(@pool.db, :disconnect_connection){|c| d << c}
|
400
400
|
@pool.hold do |cc|
|
401
|
-
cc.
|
402
|
-
Thread.new{@pool.hold{|cc2| cc2.
|
403
|
-
d.
|
404
|
-
@pool.hold{|cc3| cc3.
|
401
|
+
cc.must_equal 1
|
402
|
+
Thread.new{@pool.hold{|cc2| _(cc2).must_equal 2}}.join
|
403
|
+
d.must_equal [2]
|
404
|
+
@pool.hold{|cc3| cc3.must_equal 1}
|
405
405
|
end
|
406
|
-
@pool.size.
|
407
|
-
d.
|
406
|
+
@pool.size.must_equal 0
|
407
|
+
d.must_equal [2, 1]
|
408
408
|
|
409
|
-
@pool.hold{|cc| cc.
|
410
|
-
@pool.size.
|
411
|
-
d.
|
409
|
+
@pool.hold{|cc| cc.must_equal 3}
|
410
|
+
@pool.size.must_equal 0
|
411
|
+
d.must_equal [2, 1, 3]
|
412
412
|
|
413
|
-
@pool.hold{|cc| cc.
|
414
|
-
@pool.size.
|
415
|
-
d.
|
413
|
+
@pool.hold{|cc| cc.must_equal 4}
|
414
|
+
@pool.size.must_equal 0
|
415
|
+
d.must_equal [2, 1, 3, 4]
|
416
416
|
end
|
417
417
|
end
|
418
418
|
|
@@ -424,7 +424,7 @@ describe "Threaded Unsharded Connection Pool" do
|
|
424
424
|
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts)
|
425
425
|
end
|
426
426
|
|
427
|
-
|
427
|
+
include ThreadedConnectionPoolSpecs
|
428
428
|
end
|
429
429
|
|
430
430
|
describe "Threaded Sharded Connection Pool" do
|
@@ -435,7 +435,7 @@ describe "Threaded Sharded Connection Pool" do
|
|
435
435
|
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts)
|
436
436
|
end
|
437
437
|
|
438
|
-
|
438
|
+
include ThreadedConnectionPoolSpecs
|
439
439
|
end
|
440
440
|
|
441
441
|
describe "ConnectionPool#disconnect" do
|
@@ -451,34 +451,34 @@ describe "ConnectionPool#disconnect" do
|
|
451
451
|
threads.each {|t| t.join}
|
452
452
|
end
|
453
453
|
|
454
|
-
|
455
|
-
@pool.size.
|
456
|
-
@pool.available_connections.size.
|
457
|
-
@pool.available_connections.each {|c| c[:id].
|
454
|
+
it "should invoke the given block for each available connection" do
|
455
|
+
@pool.size.must_equal 5
|
456
|
+
@pool.available_connections.size.must_equal 5
|
457
|
+
@pool.available_connections.each {|c| c[:id].wont_equal nil}
|
458
458
|
conns = []
|
459
459
|
meta_def(@pool.db, :disconnect_connection){|c| conns << c}
|
460
460
|
@pool.disconnect
|
461
|
-
conns.size.
|
461
|
+
conns.size.must_equal 5
|
462
462
|
end
|
463
463
|
|
464
|
-
|
465
|
-
@pool.size.
|
464
|
+
it "should remove all available connections" do
|
465
|
+
@pool.size.must_equal 5
|
466
466
|
@pool.disconnect
|
467
|
-
@pool.size.
|
467
|
+
@pool.size.must_equal 0
|
468
468
|
end
|
469
469
|
|
470
|
-
|
471
|
-
@pool.size.
|
470
|
+
it "should disconnect connections in use as soon as they are no longer in use" do
|
471
|
+
@pool.size.must_equal 5
|
472
472
|
@pool.hold do |conn|
|
473
|
-
@pool.available_connections.size.
|
474
|
-
@pool.available_connections.each {|c| c.
|
473
|
+
@pool.available_connections.size.must_equal 4
|
474
|
+
@pool.available_connections.each {|c| c.wont_be_same_as(conn)}
|
475
475
|
conns = []
|
476
476
|
meta_def(@pool.db, :disconnect_connection){|c| conns << c}
|
477
477
|
@pool.disconnect
|
478
|
-
conns.size.
|
479
|
-
@pool.size.
|
478
|
+
conns.size.must_equal 4
|
479
|
+
@pool.size.must_equal 1
|
480
480
|
end
|
481
|
-
@pool.size.
|
481
|
+
@pool.size.must_equal 0
|
482
482
|
end
|
483
483
|
end
|
484
484
|
|
@@ -488,187 +488,187 @@ describe "A connection pool with multiple servers" do
|
|
488
488
|
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{|server| "#{server}#{ic[server] += 1}"}, CONNECTION_POOL_DEFAULTS.merge(:servers=>{:read_only=>{}}))
|
489
489
|
end
|
490
490
|
|
491
|
-
|
491
|
+
it "should support preconnect method that immediately creates the maximum number of connections" do
|
492
492
|
@pool.send(:preconnect)
|
493
493
|
i = 0
|
494
494
|
@pool.all_connections{|c1| i+=1}
|
495
|
-
i.
|
495
|
+
i.must_equal @pool.max_size * 2
|
496
496
|
end
|
497
497
|
|
498
|
-
|
498
|
+
it "#all_connections should return connections for all servers" do
|
499
499
|
@pool.hold{}
|
500
|
-
@pool.all_connections{|c1| c1.
|
500
|
+
@pool.all_connections{|c1| c1.must_equal "default1"}
|
501
501
|
a = []
|
502
502
|
@pool.hold(:read_only) do |c|
|
503
503
|
@pool.all_connections{|c1| a << c1}
|
504
504
|
end
|
505
|
-
a.sort_by{|c| c.to_s}.
|
505
|
+
a.sort_by{|c| c.to_s}.must_equal ["default1", "read_only1"]
|
506
506
|
end
|
507
507
|
|
508
|
-
|
509
|
-
@pool.servers.sort_by{|s| s.to_s}.
|
508
|
+
it "#servers should return symbols for all servers" do
|
509
|
+
@pool.servers.sort_by{|s| s.to_s}.must_equal [:default, :read_only]
|
510
510
|
end
|
511
511
|
|
512
|
-
|
513
|
-
@pool.size.
|
512
|
+
it "should use the :default server by default" do
|
513
|
+
@pool.size.must_equal 0
|
514
514
|
@pool.hold do |c|
|
515
|
-
c.
|
516
|
-
@pool.allocated.
|
515
|
+
c.must_equal "default1"
|
516
|
+
@pool.allocated.must_equal(Thread.current=>"default1")
|
517
517
|
end
|
518
|
-
@pool.available_connections.
|
519
|
-
@pool.size.
|
520
|
-
@invoked_counts.
|
518
|
+
@pool.available_connections.must_equal ["default1"]
|
519
|
+
@pool.size.must_equal 1
|
520
|
+
@invoked_counts.must_equal(:default=>1)
|
521
521
|
end
|
522
522
|
|
523
|
-
|
523
|
+
it "should use the :default server an invalid server is used" do
|
524
524
|
@pool.hold do |c1|
|
525
|
-
c1.
|
525
|
+
c1.must_equal "default1"
|
526
526
|
@pool.hold(:blah) do |c2|
|
527
|
-
c2.
|
527
|
+
c2.must_equal c1
|
528
528
|
@pool.hold(:blah2) do |c3|
|
529
|
-
c2.
|
529
|
+
c2.must_equal c3
|
530
530
|
end
|
531
531
|
end
|
532
532
|
end
|
533
533
|
end
|
534
534
|
|
535
|
-
|
535
|
+
it "should support a :servers_hash option used for converting the server argument" do
|
536
536
|
ic = @invoked_counts
|
537
537
|
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{|server| "#{server}#{ic[server] += 1}"}, CONNECTION_POOL_DEFAULTS.merge(:servers_hash=>Hash.new(:read_only), :servers=>{:read_only=>{}}))
|
538
538
|
@pool.hold(:blah) do |c1|
|
539
|
-
c1.
|
539
|
+
c1.must_equal "read_only1"
|
540
540
|
@pool.hold(:blah) do |c2|
|
541
|
-
c2.
|
541
|
+
c2.must_equal c1
|
542
542
|
@pool.hold(:blah2) do |c3|
|
543
|
-
c2.
|
543
|
+
c2.must_equal c3
|
544
544
|
end
|
545
545
|
end
|
546
546
|
end
|
547
547
|
|
548
548
|
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{|server| "#{server}#{ic[server] += 1}"}, CONNECTION_POOL_DEFAULTS.merge(:servers_hash=>Hash.new{|h,k| raise Sequel::Error}, :servers=>{:read_only=>{}}))
|
549
|
-
proc{@pool.hold(:blah){|c1|}}.
|
549
|
+
proc{@pool.hold(:blah){|c1|}}.must_raise(Sequel::Error)
|
550
550
|
end
|
551
551
|
|
552
|
-
|
553
|
-
@pool.size(:read_only).
|
552
|
+
it "should use the requested server if server is given" do
|
553
|
+
@pool.size(:read_only).must_equal 0
|
554
554
|
@pool.hold(:read_only) do |c|
|
555
|
-
c.
|
556
|
-
@pool.allocated(:read_only).
|
555
|
+
c.must_equal "read_only1"
|
556
|
+
@pool.allocated(:read_only).must_equal(Thread.current=>"read_only1")
|
557
557
|
end
|
558
|
-
@pool.available_connections(:read_only).
|
559
|
-
@pool.size(:read_only).
|
560
|
-
@invoked_counts.
|
558
|
+
@pool.available_connections(:read_only).must_equal ["read_only1"]
|
559
|
+
@pool.size(:read_only).must_equal 1
|
560
|
+
@invoked_counts.must_equal(:read_only=>1)
|
561
561
|
end
|
562
562
|
|
563
|
-
|
563
|
+
it "#hold should only yield connections for the server requested" do
|
564
564
|
@pool.hold(:read_only) do |c|
|
565
|
-
c.
|
566
|
-
@pool.allocated(:read_only).
|
565
|
+
c.must_equal "read_only1"
|
566
|
+
@pool.allocated(:read_only).must_equal(Thread.current=>"read_only1")
|
567
567
|
@pool.hold do |d|
|
568
|
-
d.
|
568
|
+
d.must_equal "default1"
|
569
569
|
@pool.hold do |e|
|
570
|
-
e.
|
571
|
-
@pool.hold(:read_only){|b| b.
|
570
|
+
e.must_equal d
|
571
|
+
@pool.hold(:read_only){|b| b.must_equal c}
|
572
572
|
end
|
573
|
-
@pool.allocated.
|
573
|
+
@pool.allocated.must_equal(Thread.current=>"default1")
|
574
574
|
end
|
575
575
|
end
|
576
|
-
@invoked_counts.
|
576
|
+
@invoked_counts.must_equal(:read_only=>1, :default=>1)
|
577
577
|
end
|
578
578
|
|
579
|
-
|
579
|
+
it "#disconnect should disconnect from all servers" do
|
580
580
|
@pool.hold(:read_only){}
|
581
581
|
@pool.hold{}
|
582
582
|
conns = []
|
583
|
-
@pool.size.
|
584
|
-
@pool.size(:read_only).
|
583
|
+
@pool.size.must_equal 1
|
584
|
+
@pool.size(:read_only).must_equal 1
|
585
585
|
meta_def(@pool.db, :disconnect_connection){|c| conns << c}
|
586
586
|
@pool.disconnect
|
587
|
-
conns.sort.
|
588
|
-
@pool.size.
|
589
|
-
@pool.size(:read_only).
|
590
|
-
@pool.hold(:read_only){|c| c.
|
591
|
-
@pool.hold{|c| c.
|
587
|
+
conns.sort.must_equal %w'default1 read_only1'
|
588
|
+
@pool.size.must_equal 0
|
589
|
+
@pool.size(:read_only).must_equal 0
|
590
|
+
@pool.hold(:read_only){|c| c.must_equal 'read_only2'}
|
591
|
+
@pool.hold{|c| c.must_equal 'default2'}
|
592
592
|
end
|
593
593
|
|
594
|
-
|
594
|
+
it "#add_servers should add new servers to the pool" do
|
595
595
|
pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :servers=>{:server1=>{}})
|
596
596
|
|
597
597
|
pool.hold{}
|
598
598
|
pool.hold(:server2){}
|
599
599
|
pool.hold(:server3){}
|
600
600
|
pool.hold(:server1) do
|
601
|
-
pool.allocated.length.
|
602
|
-
pool.allocated(:server1).length.
|
603
|
-
pool.allocated(:server2).
|
604
|
-
pool.allocated(:server3).
|
605
|
-
pool.available_connections.length.
|
606
|
-
pool.available_connections(:server1).length.
|
607
|
-
pool.available_connections(:server2).
|
608
|
-
pool.available_connections(:server3).
|
601
|
+
pool.allocated.length.must_equal 0
|
602
|
+
pool.allocated(:server1).length.must_equal 1
|
603
|
+
pool.allocated(:server2).must_equal nil
|
604
|
+
pool.allocated(:server3).must_equal nil
|
605
|
+
pool.available_connections.length.must_equal 1
|
606
|
+
pool.available_connections(:server1).length.must_equal 0
|
607
|
+
pool.available_connections(:server2).must_equal nil
|
608
|
+
pool.available_connections(:server3).must_equal nil
|
609
609
|
|
610
610
|
pool.add_servers([:server2, :server3])
|
611
611
|
pool.hold(:server2){}
|
612
612
|
pool.hold(:server3) do
|
613
|
-
pool.allocated.length.
|
614
|
-
pool.allocated(:server1).length.
|
615
|
-
pool.allocated(:server2).length.
|
616
|
-
pool.allocated(:server3).length.
|
617
|
-
pool.available_connections.length.
|
618
|
-
pool.available_connections(:server1).length.
|
619
|
-
pool.available_connections(:server2).length.
|
620
|
-
pool.available_connections(:server3).length.
|
613
|
+
pool.allocated.length.must_equal 0
|
614
|
+
pool.allocated(:server1).length.must_equal 1
|
615
|
+
pool.allocated(:server2).length.must_equal 0
|
616
|
+
pool.allocated(:server3).length.must_equal 1
|
617
|
+
pool.available_connections.length.must_equal 1
|
618
|
+
pool.available_connections(:server1).length.must_equal 0
|
619
|
+
pool.available_connections(:server2).length.must_equal 1
|
620
|
+
pool.available_connections(:server3).length.must_equal 0
|
621
621
|
end
|
622
622
|
end
|
623
623
|
end
|
624
624
|
|
625
|
-
|
625
|
+
it "#add_servers should ignore existing keys" do
|
626
626
|
pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :servers=>{:server1=>{}})
|
627
627
|
|
628
|
-
pool.allocated.length.
|
629
|
-
pool.allocated(:server1).length.
|
630
|
-
pool.available_connections.length.
|
631
|
-
pool.available_connections(:server1).length.
|
628
|
+
pool.allocated.length.must_equal 0
|
629
|
+
pool.allocated(:server1).length.must_equal 0
|
630
|
+
pool.available_connections.length.must_equal 0
|
631
|
+
pool.available_connections(:server1).length.must_equal 0
|
632
632
|
pool.hold do |c1|
|
633
|
-
c1.
|
634
|
-
pool.allocated.length.
|
635
|
-
pool.allocated(:server1).length.
|
636
|
-
pool.available_connections.length.
|
637
|
-
pool.available_connections(:server1).length.
|
633
|
+
c1.must_equal :default
|
634
|
+
pool.allocated.length.must_equal 1
|
635
|
+
pool.allocated(:server1).length.must_equal 0
|
636
|
+
pool.available_connections.length.must_equal 0
|
637
|
+
pool.available_connections(:server1).length.must_equal 0
|
638
638
|
pool.hold(:server1) do |c2|
|
639
|
-
c2.
|
640
|
-
pool.allocated.length.
|
641
|
-
pool.allocated(:server1).length.
|
642
|
-
pool.available_connections.length.
|
643
|
-
pool.available_connections(:server1).length.
|
639
|
+
c2.must_equal :server1
|
640
|
+
pool.allocated.length.must_equal 1
|
641
|
+
pool.allocated(:server1).length.must_equal 1
|
642
|
+
pool.available_connections.length.must_equal 0
|
643
|
+
pool.available_connections(:server1).length.must_equal 0
|
644
644
|
pool.add_servers([:default, :server1])
|
645
|
-
pool.allocated.length.
|
646
|
-
pool.allocated(:server1).length.
|
647
|
-
pool.available_connections.length.
|
648
|
-
pool.available_connections(:server1).length.
|
645
|
+
pool.allocated.length.must_equal 1
|
646
|
+
pool.allocated(:server1).length.must_equal 1
|
647
|
+
pool.available_connections.length.must_equal 0
|
648
|
+
pool.available_connections(:server1).length.must_equal 0
|
649
649
|
end
|
650
|
-
pool.allocated.length.
|
651
|
-
pool.allocated(:server1).length.
|
652
|
-
pool.available_connections.length.
|
653
|
-
pool.available_connections(:server1).length.
|
650
|
+
pool.allocated.length.must_equal 1
|
651
|
+
pool.allocated(:server1).length.must_equal 0
|
652
|
+
pool.available_connections.length.must_equal 0
|
653
|
+
pool.available_connections(:server1).length.must_equal 1
|
654
654
|
pool.add_servers([:default, :server1])
|
655
|
-
pool.allocated.length.
|
656
|
-
pool.allocated(:server1).length.
|
657
|
-
pool.available_connections.length.
|
658
|
-
pool.available_connections(:server1).length.
|
655
|
+
pool.allocated.length.must_equal 1
|
656
|
+
pool.allocated(:server1).length.must_equal 0
|
657
|
+
pool.available_connections.length.must_equal 0
|
658
|
+
pool.available_connections(:server1).length.must_equal 1
|
659
659
|
end
|
660
|
-
pool.allocated.length.
|
661
|
-
pool.allocated(:server1).length.
|
662
|
-
pool.available_connections.length.
|
663
|
-
pool.available_connections(:server1).length.
|
660
|
+
pool.allocated.length.must_equal 0
|
661
|
+
pool.allocated(:server1).length.must_equal 0
|
662
|
+
pool.available_connections.length.must_equal 1
|
663
|
+
pool.available_connections(:server1).length.must_equal 1
|
664
664
|
pool.add_servers([:default, :server1])
|
665
|
-
pool.allocated.length.
|
666
|
-
pool.allocated(:server1).length.
|
667
|
-
pool.available_connections.length.
|
668
|
-
pool.available_connections(:server1).length.
|
665
|
+
pool.allocated.length.must_equal 0
|
666
|
+
pool.allocated(:server1).length.must_equal 0
|
667
|
+
pool.available_connections.length.must_equal 1
|
668
|
+
pool.available_connections(:server1).length.must_equal 1
|
669
669
|
end
|
670
670
|
|
671
|
-
|
671
|
+
it "#remove_servers should disconnect available connections immediately" do
|
672
672
|
pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :max_connections=>5, :servers=>{:server1=>{}})
|
673
673
|
threads = []
|
674
674
|
q, q1 = Queue.new, Queue.new
|
@@ -677,57 +677,57 @@ describe "A connection pool with multiple servers" do
|
|
677
677
|
5.times{q.push nil}
|
678
678
|
threads.each {|t| t.join}
|
679
679
|
|
680
|
-
pool.size(:server1).
|
680
|
+
pool.size(:server1).must_equal 5
|
681
681
|
pool.remove_servers([:server1])
|
682
|
-
pool.size(:server1).
|
682
|
+
pool.size(:server1).must_equal 0
|
683
683
|
end
|
684
684
|
|
685
|
-
|
685
|
+
it "#remove_servers should disconnect connections in use as soon as they are returned to the pool" do
|
686
686
|
dc = []
|
687
687
|
pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| dc << c}){|c| c}, :servers=>{:server1=>{}})
|
688
688
|
c1 = nil
|
689
689
|
pool.hold(:server1) do |c|
|
690
|
-
pool.size(:server1).
|
691
|
-
dc.
|
690
|
+
pool.size(:server1).must_equal 1
|
691
|
+
dc.must_equal []
|
692
692
|
pool.remove_servers([:server1])
|
693
|
-
pool.size(:server1).
|
694
|
-
dc.
|
693
|
+
pool.size(:server1).must_equal 0
|
694
|
+
dc.must_equal []
|
695
695
|
c1 = c
|
696
696
|
end
|
697
|
-
pool.size(:server1).
|
698
|
-
dc.
|
697
|
+
pool.size(:server1).must_equal 0
|
698
|
+
dc.must_equal [c1]
|
699
699
|
end
|
700
700
|
|
701
|
-
|
701
|
+
it "#remove_servers should remove server related data structures immediately" do
|
702
702
|
pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :servers=>{:server1=>{}})
|
703
|
-
pool.available_connections(:server1).
|
704
|
-
pool.allocated(:server1).
|
703
|
+
pool.available_connections(:server1).must_equal []
|
704
|
+
pool.allocated(:server1).must_equal({})
|
705
705
|
pool.remove_servers([:server1])
|
706
|
-
pool.available_connections(:server1).
|
707
|
-
pool.allocated(:server1).
|
706
|
+
pool.available_connections(:server1).must_equal nil
|
707
|
+
pool.allocated(:server1).must_equal nil
|
708
708
|
end
|
709
709
|
|
710
|
-
|
710
|
+
it "#remove_servers should not allow the removal of the default server" do
|
711
711
|
pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :servers=>{:server1=>{}})
|
712
|
-
|
713
|
-
proc{pool.remove_servers([:default])}.
|
712
|
+
pool.remove_servers([:server1])
|
713
|
+
proc{pool.remove_servers([:default])}.must_raise(Sequel::Error)
|
714
714
|
end
|
715
715
|
|
716
|
-
|
716
|
+
it "#remove_servers should ignore servers that have already been removed" do
|
717
717
|
dc = []
|
718
718
|
pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| dc << c}){|c| c}, :servers=>{:server1=>{}})
|
719
719
|
c1 = nil
|
720
720
|
pool.hold(:server1) do |c|
|
721
|
-
pool.size(:server1).
|
722
|
-
dc.
|
721
|
+
pool.size(:server1).must_equal 1
|
722
|
+
dc.must_equal []
|
723
723
|
pool.remove_servers([:server1])
|
724
724
|
pool.remove_servers([:server1])
|
725
|
-
pool.size(:server1).
|
726
|
-
dc.
|
725
|
+
pool.size(:server1).must_equal 0
|
726
|
+
dc.must_equal []
|
727
727
|
c1 = c
|
728
728
|
end
|
729
|
-
pool.size(:server1).
|
730
|
-
dc.
|
729
|
+
pool.size(:server1).must_equal 0
|
730
|
+
dc.must_equal [c1]
|
731
731
|
end
|
732
732
|
end
|
733
733
|
|
@@ -738,20 +738,20 @@ describe "SingleConnectionPool" do
|
|
738
738
|
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{1234}, ST_CONNECTION_POOL_DEFAULTS)
|
739
739
|
end
|
740
740
|
|
741
|
-
|
741
|
+
it "should provide a #hold method" do
|
742
742
|
conn = nil
|
743
743
|
@pool.hold{|c| conn = c}
|
744
|
-
conn.
|
744
|
+
conn.must_equal 1234
|
745
745
|
end
|
746
746
|
|
747
|
-
|
747
|
+
it "should provide a #disconnect method" do
|
748
748
|
conn = nil
|
749
749
|
x = nil
|
750
750
|
pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| conn = c}){1234}, ST_CONNECTION_POOL_DEFAULTS)
|
751
751
|
pool.hold{|c| x = c}
|
752
|
-
x.
|
752
|
+
x.must_equal 1234
|
753
753
|
pool.disconnect
|
754
|
-
conn.
|
754
|
+
conn.must_equal 1234
|
755
755
|
end
|
756
756
|
end
|
757
757
|
|
@@ -762,242 +762,242 @@ describe "A single threaded pool with multiple servers" do
|
|
762
762
|
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| msp.call}){|c| c}, ST_CONNECTION_POOL_DEFAULTS.merge(:servers=>{:read_only=>{}}))
|
763
763
|
end
|
764
764
|
|
765
|
-
|
765
|
+
it "should support preconnect method that immediately creates the maximum number of connections" do
|
766
766
|
@pool.send(:preconnect)
|
767
767
|
i = 0
|
768
768
|
@pool.all_connections{|c1| i+=1}
|
769
|
-
i.
|
769
|
+
i.must_equal 2
|
770
770
|
end
|
771
771
|
|
772
|
-
|
772
|
+
it "#all_connections should return connections for all servers" do
|
773
773
|
@pool.hold{}
|
774
|
-
@pool.all_connections{|c1| c1.
|
774
|
+
@pool.all_connections{|c1| c1.must_equal :default}
|
775
775
|
a = []
|
776
776
|
@pool.hold(:read_only) do
|
777
777
|
@pool.all_connections{|c1| a << c1}
|
778
778
|
end
|
779
|
-
a.sort_by{|c| c.to_s}.
|
779
|
+
a.sort_by{|c| c.to_s}.must_equal [:default, :read_only]
|
780
780
|
end
|
781
781
|
|
782
|
-
|
783
|
-
@pool.servers.sort_by{|s| s.to_s}.
|
782
|
+
it "#servers should return symbols for all servers" do
|
783
|
+
@pool.servers.sort_by{|s| s.to_s}.must_equal [:default, :read_only]
|
784
784
|
end
|
785
785
|
|
786
|
-
|
787
|
-
@pool.hold(:blah){|c| c.
|
786
|
+
it "#add_servers should add new servers to the pool" do
|
787
|
+
@pool.hold(:blah){|c| c.must_equal :default}
|
788
788
|
@pool.add_servers([:blah])
|
789
|
-
@pool.hold(:blah){|c| c.
|
789
|
+
@pool.hold(:blah){|c| c.must_equal :blah}
|
790
790
|
end
|
791
791
|
|
792
|
-
|
793
|
-
@pool.hold{|c| c.
|
794
|
-
@pool.hold(:read_only){|c| c.
|
792
|
+
it "#add_servers should ignore keys already existing" do
|
793
|
+
@pool.hold{|c| c.must_equal :default}
|
794
|
+
@pool.hold(:read_only){|c| c.must_equal :read_only}
|
795
795
|
@pool.add_servers([:default, :read_only])
|
796
|
-
@pool.conn.
|
797
|
-
@pool.conn(:read_only).
|
796
|
+
@pool.conn.must_equal :default
|
797
|
+
@pool.conn(:read_only).must_equal :read_only
|
798
798
|
end
|
799
799
|
|
800
|
-
|
801
|
-
@pool.hold(:read_only){|c| c.
|
800
|
+
it "#remove_servers should remove servers from the pool" do
|
801
|
+
@pool.hold(:read_only){|c| c.must_equal :read_only}
|
802
802
|
@pool.remove_servers([:read_only])
|
803
|
-
@pool.hold(:read_only){|c| c.
|
803
|
+
@pool.hold(:read_only){|c| c.must_equal :default}
|
804
804
|
end
|
805
805
|
|
806
|
-
|
807
|
-
proc{@pool.remove_servers([:default])}.
|
806
|
+
it "#remove_servers should not allow the removal of the default server" do
|
807
|
+
proc{@pool.remove_servers([:default])}.must_raise(Sequel::Error)
|
808
808
|
end
|
809
809
|
|
810
|
-
|
811
|
-
@pool.hold(:read_only){|c| c.
|
812
|
-
@pool.conn(:read_only).
|
810
|
+
it "#remove_servers should disconnect connection immediately" do
|
811
|
+
@pool.hold(:read_only){|c| c.must_equal :read_only}
|
812
|
+
@pool.conn(:read_only).must_equal :read_only
|
813
813
|
@pool.remove_servers([:read_only])
|
814
|
-
@pool.conn(:read_only).
|
814
|
+
@pool.conn(:read_only).must_equal nil
|
815
815
|
@pool.hold{}
|
816
|
-
@pool.conn(:read_only).
|
816
|
+
@pool.conn(:read_only).must_equal :default
|
817
817
|
end
|
818
818
|
|
819
|
-
|
820
|
-
|
819
|
+
it "#remove_servers should ignore keys that do not exist" do
|
820
|
+
@pool.remove_servers([:blah])
|
821
821
|
end
|
822
822
|
|
823
|
-
|
824
|
-
@pool.hold{|c| c.
|
825
|
-
@pool.conn.
|
823
|
+
it "should use the :default server by default" do
|
824
|
+
@pool.hold{|c| c.must_equal :default}
|
825
|
+
@pool.conn.must_equal :default
|
826
826
|
end
|
827
827
|
|
828
|
-
|
828
|
+
it "should use the :default server an invalid server is used" do
|
829
829
|
@pool.hold do |c1|
|
830
|
-
c1.
|
830
|
+
c1.must_equal :default
|
831
831
|
@pool.hold(:blah) do |c2|
|
832
|
-
c2.
|
832
|
+
c2.must_equal c1
|
833
833
|
@pool.hold(:blah2) do |c3|
|
834
|
-
c2.
|
834
|
+
c2.must_equal c3
|
835
835
|
end
|
836
836
|
end
|
837
837
|
end
|
838
838
|
end
|
839
839
|
|
840
|
-
|
841
|
-
@pool.hold(:read_only){|c| c.
|
842
|
-
@pool.conn(:read_only).
|
840
|
+
it "should use the requested server if server is given" do
|
841
|
+
@pool.hold(:read_only){|c| c.must_equal :read_only}
|
842
|
+
@pool.conn(:read_only).must_equal :read_only
|
843
843
|
end
|
844
844
|
|
845
|
-
|
845
|
+
it "#hold should only yield connections for the server requested" do
|
846
846
|
@pool.hold(:read_only) do |c|
|
847
|
-
c.
|
847
|
+
c.must_equal :read_only
|
848
848
|
@pool.hold do |d|
|
849
|
-
d.
|
849
|
+
d.must_equal :default
|
850
850
|
@pool.hold do |e|
|
851
|
-
e.
|
852
|
-
@pool.hold(:read_only){|b| b.
|
851
|
+
e.must_equal d
|
852
|
+
@pool.hold(:read_only){|b| b.must_equal c}
|
853
853
|
end
|
854
854
|
end
|
855
855
|
end
|
856
|
-
@pool.conn.
|
857
|
-
@pool.conn(:read_only).
|
856
|
+
@pool.conn.must_equal :default
|
857
|
+
@pool.conn(:read_only).must_equal :read_only
|
858
858
|
end
|
859
859
|
|
860
|
-
|
860
|
+
it "#disconnect should disconnect from all servers" do
|
861
861
|
@pool.hold(:read_only){}
|
862
862
|
@pool.hold{}
|
863
|
-
@pool.conn.
|
864
|
-
@pool.conn(:read_only).
|
863
|
+
@pool.conn.must_equal :default
|
864
|
+
@pool.conn(:read_only).must_equal :read_only
|
865
865
|
@pool.disconnect
|
866
|
-
@max_size.
|
867
|
-
@pool.conn.
|
868
|
-
@pool.conn(:read_only).
|
866
|
+
@max_size.must_equal 4
|
867
|
+
@pool.conn.must_equal nil
|
868
|
+
@pool.conn(:read_only).must_equal nil
|
869
869
|
end
|
870
870
|
|
871
|
-
|
872
|
-
@max_size.
|
873
|
-
proc{@pool.hold{raise Sequel::DatabaseDisconnectError}}.
|
874
|
-
@max_size.
|
871
|
+
it ":disconnection_proc option should set the disconnection proc to use" do
|
872
|
+
@max_size.must_equal 2
|
873
|
+
proc{@pool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
|
874
|
+
@max_size.must_equal 3
|
875
875
|
end
|
876
876
|
|
877
|
-
|
878
|
-
@pool.instance_variable_get(:@conns).length.
|
877
|
+
it "#hold should remove the connection if a DatabaseDisconnectError is raised" do
|
878
|
+
@pool.instance_variable_get(:@conns).length.must_equal 0
|
879
879
|
@pool.hold{}
|
880
|
-
@pool.instance_variable_get(:@conns).length.
|
881
|
-
proc{@pool.hold{raise Sequel::DatabaseDisconnectError}}.
|
882
|
-
@pool.instance_variable_get(:@conns).length.
|
880
|
+
@pool.instance_variable_get(:@conns).length.must_equal 1
|
881
|
+
proc{@pool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
|
882
|
+
@pool.instance_variable_get(:@conns).length.must_equal 0
|
883
883
|
end
|
884
884
|
end
|
885
885
|
|
886
|
-
|
887
|
-
|
888
|
-
@class.new(mock_db.call{123}, {}).pool_type.
|
886
|
+
AllConnectionPoolClassesSpecs = shared_description do
|
887
|
+
it "should have pool_type return a symbol" do
|
888
|
+
@class.new(mock_db.call{123}, {}).pool_type.must_be_kind_of(Symbol)
|
889
889
|
end
|
890
890
|
|
891
|
-
|
891
|
+
it "should have all_connections yield current and available connections" do
|
892
892
|
p = @class.new(mock_db.call{123}, {})
|
893
|
-
p.hold{|c| p.all_connections{|c1| c.
|
893
|
+
p.hold{|c| p.all_connections{|c1| c.must_equal c1}}
|
894
894
|
end
|
895
895
|
|
896
|
-
|
896
|
+
it "should have a size method that gives the current size of the pool" do
|
897
897
|
p = @class.new(mock_db.call{123}, {})
|
898
|
-
p.size.
|
898
|
+
p.size.must_equal 0
|
899
899
|
p.hold{}
|
900
|
-
p.size.
|
900
|
+
p.size.must_equal 1
|
901
901
|
end
|
902
902
|
|
903
|
-
|
904
|
-
@class.new(mock_db.call{123}, {}).max_size.
|
903
|
+
it "should have a max_size method that gives the maximum size of the pool" do
|
904
|
+
@class.new(mock_db.call{123}, {}).max_size.must_be :>=, 1
|
905
905
|
end
|
906
906
|
|
907
|
-
|
907
|
+
it "should support preconnect method that immediately creates the maximum number of connections" do
|
908
908
|
p = @class.new(mock_db.call{123}, {})
|
909
909
|
p.send(:preconnect)
|
910
910
|
i = 0
|
911
911
|
p.all_connections{|c1| i+=1}
|
912
|
-
i.
|
912
|
+
i.must_equal p.max_size
|
913
913
|
end
|
914
914
|
|
915
|
-
|
915
|
+
it "should be able to modify after_connect proc after the pool is created" do
|
916
916
|
a = []
|
917
917
|
p = @class.new(mock_db.call{123}, {})
|
918
918
|
p.after_connect = pr = proc{|c| a << c}
|
919
|
-
p.after_connect.
|
920
|
-
a.
|
919
|
+
p.after_connect.must_equal pr
|
920
|
+
a.must_equal []
|
921
921
|
p.hold{}
|
922
|
-
a.
|
922
|
+
a.must_equal [123]
|
923
923
|
end
|
924
924
|
|
925
|
-
|
925
|
+
it "should not raise an error when disconnecting twice" do
|
926
926
|
c = @class.new(mock_db.call{123}, {})
|
927
|
-
|
928
|
-
|
927
|
+
c.disconnect
|
928
|
+
c.disconnect
|
929
929
|
end
|
930
930
|
|
931
|
-
|
931
|
+
it "should yield a connection created by the initialize block to hold" do
|
932
932
|
x = nil
|
933
933
|
@class.new(mock_db.call{123}, {}).hold{|c| x = c}
|
934
|
-
x.
|
934
|
+
x.must_equal 123
|
935
935
|
end
|
936
936
|
|
937
|
-
|
937
|
+
it "should have the initialize block accept a shard/server argument" do
|
938
938
|
x = nil
|
939
939
|
@class.new(mock_db.call{|c| [c, c]}, {}).hold{|c| x = c}
|
940
|
-
x.
|
940
|
+
x.must_equal [:default, :default]
|
941
941
|
end
|
942
942
|
|
943
|
-
|
943
|
+
it "should have respect an :after_connect proc that is called with each newly created connection" do
|
944
944
|
x = nil
|
945
945
|
@class.new(mock_db.call{123}, :after_connect=>proc{|c| x = [c, c]}).hold{}
|
946
|
-
x.
|
946
|
+
x.must_equal [123, 123]
|
947
947
|
@class.new(mock_db.call{123}, :after_connect=>lambda{|c| x = [c, c]}).hold{}
|
948
|
-
x.
|
948
|
+
x.must_equal [123, 123]
|
949
949
|
@class.new(mock_db.call{123}, :after_connect=>proc{|c, s| x = [c, s]}).hold{}
|
950
|
-
x.
|
950
|
+
x.must_equal [123, :default]
|
951
951
|
@class.new(mock_db.call{123}, :after_connect=>lambda{|c, s| x = [c, s]}).hold{}
|
952
|
-
x.
|
952
|
+
x.must_equal [123, :default]
|
953
953
|
end
|
954
954
|
|
955
|
-
|
956
|
-
proc{@class.new(mock_db.call{|c| raise Exception}, {}).hold{}}.
|
955
|
+
it "should raise a DatabaseConnectionError if the connection raises an exception" do
|
956
|
+
proc{@class.new(mock_db.call{|c| raise Exception}, {}).hold{}}.must_raise(Sequel::DatabaseConnectionError)
|
957
957
|
end
|
958
958
|
|
959
|
-
|
960
|
-
proc{@class.new(mock_db.call{}, {}).hold{}}.
|
959
|
+
it "should raise a DatabaseConnectionError if the initialize block returns nil" do
|
960
|
+
proc{@class.new(mock_db.call{}, {}).hold{}}.must_raise(Sequel::DatabaseConnectionError)
|
961
961
|
end
|
962
962
|
|
963
|
-
|
963
|
+
it "should call the disconnection_proc option if the hold block raises a DatabaseDisconnectError" do
|
964
964
|
x = nil
|
965
|
-
proc{@class.new(mock_db.call(proc{|c| x = c}){123}).hold{raise Sequel::DatabaseDisconnectError}}.
|
966
|
-
x.
|
965
|
+
proc{@class.new(mock_db.call(proc{|c| x = c}){123}).hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
|
966
|
+
x.must_equal 123
|
967
967
|
end
|
968
968
|
|
969
|
-
|
969
|
+
it "should have a disconnect method that disconnects the connection" do
|
970
970
|
x = nil
|
971
971
|
c = @class.new(mock_db.call(proc{|c1| x = c1}){123})
|
972
972
|
c.hold{}
|
973
|
-
x.
|
973
|
+
x.must_equal nil
|
974
974
|
c.disconnect
|
975
|
-
x.
|
975
|
+
x.must_equal 123
|
976
976
|
end
|
977
977
|
|
978
|
-
|
978
|
+
it "should have a reentrent hold method" do
|
979
979
|
o = Object.new
|
980
980
|
c = @class.new(mock_db.call{o}, {})
|
981
981
|
c.hold do |x|
|
982
|
-
x.
|
982
|
+
x.must_equal o
|
983
983
|
c.hold do |x1|
|
984
|
-
x1.
|
984
|
+
x1.must_equal o
|
985
985
|
c.hold do |x2|
|
986
|
-
x2.
|
986
|
+
x2.must_equal o
|
987
987
|
end
|
988
988
|
end
|
989
989
|
end
|
990
990
|
end
|
991
991
|
|
992
|
-
|
993
|
-
@class.new(mock_db.call{123}, {}).servers.
|
992
|
+
it "should have a servers method that returns an array of shard/server symbols" do
|
993
|
+
@class.new(mock_db.call{123}, {}).servers.must_equal [:default]
|
994
994
|
end
|
995
995
|
|
996
|
-
|
996
|
+
it "should have a servers method that returns an array of shard/server symbols" do
|
997
997
|
c = @class.new(mock_db.call{123}, {})
|
998
|
-
c.size.
|
998
|
+
c.size.must_equal 0
|
999
999
|
c.hold{}
|
1000
|
-
c.size.
|
1000
|
+
c.size.must_equal 1
|
1001
1001
|
end
|
1002
1002
|
end
|
1003
1003
|
|
@@ -1010,6 +1010,7 @@ Sequel::ConnectionPool::CONNECTION_POOL_MAP.keys.each do |k, v|
|
|
1010
1010
|
before do
|
1011
1011
|
@class = Sequel::ConnectionPool.send(:connection_pool_class, opts)
|
1012
1012
|
end
|
1013
|
-
|
1013
|
+
|
1014
|
+
include AllConnectionPoolClassesSpecs
|
1014
1015
|
end
|
1015
1016
|
end
|