ibm_db 3.0.5-x86-mingw32 → 5.0.5-x86-mingw32
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 +5 -5
- data/CHANGES +4 -0
- data/LICENSE +1 -1
- data/ParameterizedQueries README +6 -6
- data/README +38 -55
- data/ext/Makefile +269 -0
- data/ext/extconf.rb +34 -3
- data/ext/gil_release_version +3 -0
- data/ext/ibm_db-i386-mingw32.def +2 -0
- data/ext/ibm_db.c +100 -108
- data/ext/ibm_db.o +0 -0
- data/ext/ibm_db.so +0 -0
- data/ext/mkmf.log +110 -0
- data/ext/ruby_ibm_db_cli.o +0 -0
- data/ext/unicode_support_version +3 -0
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +923 -527
- data/lib/active_record/connection_adapters/ibmdb_adapter.rb +4 -1
- data/lib/mswin32/ibm_db.rb +7 -39
- data/lib/mswin32/rb2x/i386/ibm_db.so +0 -0
- data/test/active_record/connection_adapters/fake_adapter.rb +8 -5
- data/test/cases/adapter_test.rb +133 -58
- data/test/cases/adapters/mysql2/active_schema_test.rb +193 -0
- data/test/cases/adapters/mysql2/bind_parameter_test.rb +50 -0
- data/test/cases/adapters/mysql2/boolean_test.rb +100 -0
- data/test/cases/adapters/mysql2/case_sensitivity_test.rb +63 -0
- data/test/cases/adapters/mysql2/charset_collation_test.rb +54 -0
- data/test/cases/adapters/mysql2/connection_test.rb +210 -0
- data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +45 -0
- data/test/cases/adapters/mysql2/enum_test.rb +26 -0
- data/test/cases/adapters/mysql2/explain_test.rb +21 -0
- data/test/cases/adapters/mysql2/json_test.rb +195 -0
- data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +83 -0
- data/test/cases/adapters/mysql2/reserved_word_test.rb +152 -0
- data/test/cases/adapters/mysql2/schema_migrations_test.rb +59 -0
- data/test/cases/adapters/mysql2/schema_test.rb +126 -0
- data/test/cases/adapters/mysql2/sp_test.rb +36 -0
- data/test/cases/adapters/mysql2/sql_types_test.rb +14 -0
- data/test/cases/adapters/mysql2/table_options_test.rb +42 -0
- data/test/cases/adapters/mysql2/unsigned_type_test.rb +66 -0
- data/test/cases/adapters/postgresql/active_schema_test.rb +98 -0
- data/test/cases/adapters/postgresql/array_test.rb +339 -0
- data/test/cases/adapters/postgresql/bit_string_test.rb +82 -0
- data/test/cases/adapters/postgresql/bytea_test.rb +134 -0
- data/test/cases/adapters/postgresql/case_insensitive_test.rb +26 -0
- data/test/cases/adapters/postgresql/change_schema_test.rb +38 -0
- data/test/cases/adapters/postgresql/cidr_test.rb +25 -0
- data/test/cases/adapters/postgresql/citext_test.rb +78 -0
- data/test/cases/adapters/postgresql/collation_test.rb +53 -0
- data/test/cases/adapters/postgresql/composite_test.rb +132 -0
- data/test/cases/adapters/postgresql/connection_test.rb +257 -0
- data/test/cases/adapters/postgresql/datatype_test.rb +92 -0
- data/test/cases/adapters/postgresql/domain_test.rb +47 -0
- data/test/cases/adapters/postgresql/enum_test.rb +91 -0
- data/test/cases/adapters/postgresql/explain_test.rb +20 -0
- data/test/cases/adapters/postgresql/extension_migration_test.rb +63 -0
- data/test/cases/adapters/postgresql/full_text_test.rb +44 -0
- data/test/cases/adapters/postgresql/geometric_test.rb +378 -0
- data/test/cases/adapters/postgresql/hstore_test.rb +382 -0
- data/test/cases/adapters/postgresql/infinity_test.rb +69 -0
- data/test/cases/adapters/postgresql/integer_test.rb +25 -0
- data/test/cases/adapters/postgresql/json_test.rb +237 -0
- data/test/cases/adapters/postgresql/ltree_test.rb +53 -0
- data/test/cases/adapters/postgresql/money_test.rb +96 -0
- data/test/cases/adapters/postgresql/network_test.rb +94 -0
- data/test/cases/adapters/postgresql/numbers_test.rb +49 -0
- data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +405 -0
- data/test/cases/adapters/postgresql/prepared_statements_test.rb +22 -0
- data/test/cases/adapters/postgresql/quoting_test.rb +44 -0
- data/test/cases/adapters/postgresql/range_test.rb +343 -0
- data/test/cases/adapters/postgresql/referential_integrity_test.rb +111 -0
- data/test/cases/adapters/postgresql/rename_table_test.rb +34 -0
- data/test/cases/adapters/postgresql/schema_authorization_test.rb +119 -0
- data/test/cases/adapters/postgresql/schema_test.rb +597 -0
- data/test/cases/adapters/postgresql/serial_test.rb +154 -0
- data/test/cases/adapters/postgresql/statement_pool_test.rb +41 -0
- data/test/cases/adapters/postgresql/timestamp_test.rb +90 -0
- data/test/cases/adapters/postgresql/type_lookup_test.rb +33 -0
- data/test/cases/adapters/postgresql/utils_test.rb +62 -0
- data/test/cases/adapters/postgresql/uuid_test.rb +294 -0
- data/test/cases/adapters/postgresql/xml_test.rb +54 -0
- data/test/cases/adapters/sqlite3/collation_test.rb +53 -0
- data/test/cases/adapters/sqlite3/copy_table_test.rb +98 -0
- data/test/cases/adapters/sqlite3/explain_test.rb +21 -0
- data/test/cases/adapters/sqlite3/quoting_test.rb +101 -0
- data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +441 -0
- data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +24 -0
- data/test/cases/adapters/sqlite3/statement_pool_test.rb +20 -0
- data/test/cases/aggregations_test.rb +11 -1
- data/test/cases/ar_schema_test.rb +35 -50
- data/test/cases/associations/association_scope_test.rb +1 -6
- data/test/cases/associations/belongs_to_associations_test.rb +122 -10
- data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +41 -0
- data/test/cases/associations/callbacks_test.rb +5 -7
- data/test/cases/associations/cascaded_eager_loading_test.rb +1 -1
- data/test/cases/associations/eager_load_nested_include_test.rb +1 -3
- data/test/cases/associations/eager_test.rb +158 -73
- data/test/cases/associations/extension_test.rb +7 -2
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +64 -32
- data/test/cases/associations/has_many_associations_test.rb +362 -43
- data/test/cases/associations/has_many_through_associations_test.rb +108 -41
- data/test/cases/associations/has_one_associations_test.rb +105 -8
- data/test/cases/associations/has_one_through_associations_test.rb +6 -3
- data/test/cases/associations/inner_join_association_test.rb +3 -3
- data/test/cases/associations/inverse_associations_test.rb +38 -11
- data/test/cases/associations/join_model_test.rb +59 -36
- data/test/cases/associations/left_outer_join_association_test.rb +88 -0
- data/test/cases/associations/nested_through_associations_test.rb +2 -2
- data/test/cases/associations/required_test.rb +25 -5
- data/test/cases/associations_test.rb +39 -34
- data/test/cases/attribute_decorators_test.rb +9 -8
- data/test/cases/attribute_methods/read_test.rb +5 -5
- data/test/cases/attribute_methods_test.rb +97 -40
- data/test/cases/attribute_set_test.rb +64 -4
- data/test/cases/attribute_test.rb +84 -18
- data/test/cases/attributes_test.rb +151 -34
- data/test/cases/autosave_association_test.rb +149 -36
- data/test/cases/base_test.rb +290 -241
- data/test/cases/batches_test.rb +299 -22
- data/test/cases/binary_test.rb +2 -10
- data/test/cases/bind_parameter_test.rb +76 -66
- data/test/cases/cache_key_test.rb +26 -0
- data/test/cases/calculations_test.rb +167 -15
- data/test/cases/callbacks_test.rb +161 -68
- data/test/cases/coders/json_test.rb +15 -0
- data/test/cases/collection_cache_key_test.rb +115 -0
- data/test/cases/column_definition_test.rb +26 -57
- data/test/cases/comment_test.rb +145 -0
- data/test/cases/connection_adapters/adapter_leasing_test.rb +5 -3
- data/test/cases/connection_adapters/connection_handler_test.rb +128 -21
- data/test/cases/connection_adapters/connection_specification_test.rb +1 -1
- data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +0 -38
- data/test/cases/connection_adapters/mysql_type_lookup_test.rb +5 -1
- data/test/cases/connection_adapters/schema_cache_test.rb +8 -3
- data/test/cases/connection_adapters/type_lookup_test.rb +15 -7
- data/test/cases/connection_management_test.rb +46 -56
- data/test/cases/connection_pool_test.rb +195 -20
- data/test/cases/connection_specification/resolver_test.rb +15 -0
- data/test/cases/counter_cache_test.rb +10 -5
- data/test/cases/custom_locking_test.rb +1 -1
- data/test/cases/database_statements_test.rb +18 -3
- data/test/cases/{invalid_date_test.rb → date_test.rb} +13 -1
- data/test/cases/date_time_precision_test.rb +107 -0
- data/test/cases/defaults_test.rb +85 -89
- data/test/cases/dirty_test.rb +30 -52
- data/test/cases/disconnected_test.rb +4 -2
- data/test/cases/enum_test.rb +178 -24
- data/test/cases/errors_test.rb +16 -0
- data/test/cases/explain_test.rb +32 -21
- data/test/cases/finder_test.rb +273 -148
- data/test/cases/fixture_set/file_test.rb +18 -0
- data/test/cases/fixtures_test.rb +112 -32
- data/test/cases/forbidden_attributes_protection_test.rb +69 -3
- data/test/cases/helper.rb +10 -16
- data/test/cases/hot_compatibility_test.rb +89 -1
- data/test/cases/inheritance_test.rb +284 -53
- data/test/cases/integration_test.rb +23 -7
- data/test/cases/invalid_connection_test.rb +4 -2
- data/test/cases/invertible_migration_test.rb +124 -32
- data/test/cases/json_serialization_test.rb +11 -2
- data/test/cases/locking_test.rb +22 -6
- data/test/cases/log_subscriber_test.rb +106 -17
- data/test/cases/migration/change_schema_test.rb +60 -114
- data/test/cases/migration/change_table_test.rb +34 -2
- data/test/cases/migration/column_attributes_test.rb +7 -23
- data/test/cases/migration/column_positioning_test.rb +8 -8
- data/test/cases/migration/columns_test.rb +17 -11
- data/test/cases/migration/command_recorder_test.rb +47 -2
- data/test/cases/migration/compatibility_test.rb +118 -0
- data/test/cases/migration/create_join_table_test.rb +21 -12
- data/test/cases/migration/foreign_key_test.rb +52 -18
- data/test/cases/migration/index_test.rb +14 -12
- data/test/cases/migration/logger_test.rb +1 -1
- data/test/cases/migration/pending_migrations_test.rb +0 -1
- data/test/cases/migration/references_foreign_key_test.rb +59 -7
- data/test/cases/migration/references_index_test.rb +4 -4
- data/test/cases/migration/references_statements_test.rb +26 -6
- data/test/cases/migration/rename_table_test.rb +25 -25
- data/test/cases/migration_test.rb +279 -81
- data/test/cases/migrator_test.rb +91 -8
- data/test/cases/mixin_test.rb +0 -2
- data/test/cases/modules_test.rb +3 -4
- data/test/cases/multiparameter_attributes_test.rb +24 -2
- data/test/cases/multiple_db_test.rb +11 -4
- data/test/cases/nested_attributes_test.rb +61 -33
- data/test/cases/persistence_test.rb +102 -10
- data/test/cases/pooled_connections_test.rb +3 -3
- data/test/cases/primary_keys_test.rb +170 -31
- data/test/cases/query_cache_test.rb +216 -96
- data/test/cases/quoting_test.rb +65 -19
- data/test/cases/readonly_test.rb +2 -1
- data/test/cases/reflection_test.rb +68 -22
- data/test/cases/relation/delegation_test.rb +3 -8
- data/test/cases/relation/merging_test.rb +10 -14
- data/test/cases/relation/mutation_test.rb +42 -24
- data/test/cases/relation/or_test.rb +92 -0
- data/test/cases/relation/predicate_builder_test.rb +4 -2
- data/test/cases/relation/record_fetch_warning_test.rb +40 -0
- data/test/cases/relation/where_chain_test.rb +23 -99
- data/test/cases/relation/where_clause_test.rb +182 -0
- data/test/cases/relation/where_test.rb +45 -23
- data/test/cases/relation_test.rb +67 -58
- data/test/cases/relations_test.rb +249 -38
- data/test/cases/result_test.rb +10 -0
- data/test/cases/sanitize_test.rb +108 -15
- data/test/cases/schema_dumper_test.rb +119 -125
- data/test/cases/schema_loading_test.rb +52 -0
- data/test/cases/scoping/default_scoping_test.rb +113 -39
- data/test/cases/scoping/named_scoping_test.rb +46 -9
- data/test/cases/scoping/relation_scoping_test.rb +47 -4
- data/test/cases/secure_token_test.rb +32 -0
- data/test/cases/serialization_test.rb +1 -1
- data/test/cases/serialized_attribute_test.rb +93 -6
- data/test/cases/statement_cache_test.rb +38 -0
- data/test/cases/store_test.rb +2 -1
- data/test/cases/suppressor_test.rb +63 -0
- data/test/cases/tasks/database_tasks_test.rb +73 -9
- data/test/cases/tasks/mysql_rake_test.rb +139 -118
- data/test/cases/tasks/postgresql_rake_test.rb +60 -6
- data/test/cases/tasks/sqlite_rake_test.rb +30 -3
- data/test/cases/test_case.rb +28 -20
- data/test/cases/test_fixtures_test.rb +36 -0
- data/test/cases/time_precision_test.rb +103 -0
- data/test/cases/timestamp_test.rb +44 -10
- data/test/cases/touch_later_test.rb +121 -0
- data/test/cases/transaction_callbacks_test.rb +128 -62
- data/test/cases/transaction_isolation_test.rb +2 -2
- data/test/cases/transactions_test.rb +61 -43
- data/test/cases/type/adapter_specific_registry_test.rb +133 -0
- data/test/cases/type/date_time_test.rb +14 -0
- data/test/cases/type/integer_test.rb +2 -96
- data/test/cases/type/string_test.rb +0 -14
- data/test/cases/type_test.rb +39 -0
- data/test/cases/types_test.rb +1 -118
- data/test/cases/unconnected_test.rb +1 -1
- data/test/cases/validations/absence_validation_test.rb +73 -0
- data/test/cases/validations/association_validation_test.rb +13 -2
- data/test/cases/validations/i18n_validation_test.rb +6 -10
- data/test/cases/validations/length_validation_test.rb +62 -30
- data/test/cases/validations/presence_validation_test.rb +36 -1
- data/test/cases/validations/uniqueness_validation_test.rb +128 -37
- data/test/cases/validations_repair_helper.rb +2 -6
- data/test/cases/validations_test.rb +36 -7
- data/test/cases/view_test.rb +102 -5
- data/test/cases/yaml_serialization_test.rb +21 -26
- data/test/config.example.yml +97 -0
- data/test/fixtures/bad_posts.yml +9 -0
- data/test/fixtures/books.yml +20 -0
- data/test/fixtures/content.yml +3 -0
- data/test/fixtures/content_positions.yml +3 -0
- data/test/fixtures/dead_parrots.yml +5 -0
- data/test/fixtures/live_parrots.yml +4 -0
- data/test/fixtures/naked/yml/parrots.yml +2 -0
- data/test/fixtures/naked/yml/trees.yml +3 -0
- data/test/fixtures/nodes.yml +29 -0
- data/test/fixtures/other_comments.yml +6 -0
- data/test/fixtures/other_dogs.yml +2 -0
- data/test/fixtures/other_posts.yml +7 -0
- data/test/fixtures/price_estimates.yml +10 -1
- data/test/fixtures/trees.yml +3 -0
- data/test/migrations/10_urban/9_add_expressions.rb +1 -1
- data/test/migrations/decimal/1_give_me_big_numbers.rb +1 -1
- data/test/migrations/magic/1_currencies_have_symbols.rb +1 -1
- data/test/migrations/missing/1000_people_have_middle_names.rb +2 -2
- data/test/migrations/missing/1_people_have_last_names.rb +2 -2
- data/test/migrations/missing/3_we_need_reminders.rb +2 -2
- data/test/migrations/missing/4_innocent_jointable.rb +2 -2
- data/test/migrations/rename/1_we_need_things.rb +2 -2
- data/test/migrations/rename/2_rename_things.rb +2 -2
- data/test/migrations/to_copy/1_people_have_hobbies.rb +1 -1
- data/test/migrations/to_copy/2_people_have_descriptions.rb +1 -1
- data/test/migrations/to_copy2/1_create_articles.rb +1 -1
- data/test/migrations/to_copy2/2_create_comments.rb +1 -1
- data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +1 -1
- data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +1 -1
- data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +1 -1
- data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +1 -1
- data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +1 -1
- data/test/migrations/valid/1_valid_people_have_last_names.rb +1 -1
- data/test/migrations/valid/2_we_need_reminders.rb +2 -2
- data/test/migrations/valid/3_innocent_jointable.rb +2 -2
- data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +1 -1
- data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -2
- data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +2 -2
- data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +1 -1
- data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +1 -1
- data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +1 -1
- data/test/migrations/version_check/20131219224947_migration_version_check.rb +1 -1
- data/test/models/admin/randomly_named_c1.rb +6 -2
- data/test/models/aircraft.rb +1 -0
- data/test/models/author.rb +4 -7
- data/test/models/bird.rb +1 -1
- data/test/models/book.rb +5 -0
- data/test/models/bulb.rb +2 -1
- data/test/models/car.rb +3 -0
- data/test/models/cat.rb +10 -0
- data/test/models/chef.rb +1 -0
- data/test/models/club.rb +2 -0
- data/test/models/comment.rb +17 -5
- data/test/models/company.rb +4 -2
- data/test/models/company_in_module.rb +1 -1
- data/test/models/contact.rb +1 -1
- data/test/models/content.rb +40 -0
- data/test/models/customer.rb +8 -2
- data/test/models/developer.rb +19 -0
- data/test/models/face.rb +1 -1
- data/test/models/guitar.rb +4 -0
- data/test/models/hotel.rb +2 -0
- data/test/models/member.rb +1 -0
- data/test/models/member_detail.rb +4 -3
- data/test/models/mentor.rb +3 -0
- data/test/models/mocktail_designer.rb +2 -0
- data/test/models/node.rb +5 -0
- data/test/models/non_primary_key.rb +2 -0
- data/test/models/notification.rb +3 -0
- data/test/models/other_dog.rb +5 -0
- data/test/models/owner.rb +4 -1
- data/test/models/parrot.rb +6 -7
- data/test/models/person.rb +0 -1
- data/test/models/pet.rb +3 -0
- data/test/models/pet_treasure.rb +6 -0
- data/test/models/pirate.rb +3 -3
- data/test/models/post.rb +18 -9
- data/test/models/project.rb +9 -0
- data/test/models/randomly_named_c1.rb +1 -1
- data/test/models/recipe.rb +3 -0
- data/test/models/ship.rb +8 -2
- data/test/models/tag.rb +6 -0
- data/test/models/topic.rb +2 -8
- data/test/models/tree.rb +3 -0
- data/test/models/tuning_peg.rb +4 -0
- data/test/models/user.rb +14 -0
- data/test/models/uuid_item.rb +6 -0
- data/test/schema/mysql2_specific_schema.rb +33 -23
- data/test/schema/oracle_specific_schema.rb +1 -4
- data/test/schema/postgresql_specific_schema.rb +36 -124
- data/test/schema/schema.rb +170 -65
- data/test/schema/schema.rb.original +1057 -0
- data/test/schema/sqlite_specific_schema.rb +1 -5
- data/test/support/connection.rb +1 -0
- data/test/support/schema_dumping_helper.rb +1 -1
- data/test/support/yaml_compatibility_fixtures/rails_4_1.yml +22 -0
- data/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml +182 -0
- metadata +146 -30
- data/lib/mswin32/rb19x/ibm_db.so +0 -0
- data/lib/mswin32/rb21x/i386/ibm_db.so +0 -0
- data/lib/mswin32/rb22x/i386/ibm_db.so +0 -0
- data/lib/mswin32/rb23x/i386/ibm_db.so +0 -0
- data/test/cases/associations/deprecated_counter_cache_on_has_many_through_test.rb +0 -26
- data/test/cases/attribute_methods/serialization_test.rb +0 -29
- data/test/cases/migration/change_schema_test - Copy.rb +0 -448
- data/test/cases/migration/foreign_key_test - Changed.rb +0 -325
- data/test/cases/migration/table_and_index_test.rb +0 -24
- data/test/cases/relation/where_test2.rb +0 -36
- data/test/cases/type/decimal_test.rb +0 -56
- data/test/cases/type/unsigned_integer_test.rb +0 -18
- data/test/cases/xml_serialization_test.rb +0 -457
- data/test/fixtures/naked/csv/accounts.csv +0 -1
- data/test/schema/mysql_specific_schema.rb +0 -70
@@ -4,7 +4,7 @@ module ActiveRecord
|
|
4
4
|
module ConnectionAdapters
|
5
5
|
class ConnectionSpecificationTest < ActiveRecord::TestCase
|
6
6
|
def test_dup_deep_copy_config
|
7
|
-
spec = ConnectionSpecification.new({ :a => :b }, "bar")
|
7
|
+
spec = ConnectionSpecification.new("primary", { :a => :b }, "bar")
|
8
8
|
assert_not_equal(spec.config.object_id, spec.dup.config.object_id)
|
9
9
|
end
|
10
10
|
end
|
@@ -51,34 +51,6 @@ module ActiveRecord
|
|
51
51
|
assert_equal expected, actual
|
52
52
|
end
|
53
53
|
|
54
|
-
def test_resolver_with_database_uri_and_and_current_env_string_key
|
55
|
-
ENV['DATABASE_URL'] = "postgres://localhost/foo"
|
56
|
-
config = { "default_env" => { "adapter" => "not_postgres", "database" => "not_foo" } }
|
57
|
-
actual = assert_deprecated { resolve_spec("default_env", config) }
|
58
|
-
expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
|
59
|
-
assert_equal expected, actual
|
60
|
-
end
|
61
|
-
|
62
|
-
def test_resolver_with_database_uri_and_and_current_env_string_key_and_rails_env
|
63
|
-
ENV['DATABASE_URL'] = "postgres://localhost/foo"
|
64
|
-
ENV['RAILS_ENV'] = "foo"
|
65
|
-
|
66
|
-
config = { "not_production" => {"adapter" => "not_postgres", "database" => "not_foo" } }
|
67
|
-
actual = assert_deprecated { resolve_spec("foo", config) }
|
68
|
-
expected = { "adapter" => "postgresql", "database" => "foo", "host" => "localhost" }
|
69
|
-
assert_equal expected, actual
|
70
|
-
end
|
71
|
-
|
72
|
-
def test_resolver_with_database_uri_and_and_current_env_string_key_and_rack_env
|
73
|
-
ENV['DATABASE_URL'] = "postgres://localhost/foo"
|
74
|
-
ENV['RACK_ENV'] = "foo"
|
75
|
-
|
76
|
-
config = { "not_production" => {"adapter" => "not_postgres", "database" => "not_foo" } }
|
77
|
-
actual = assert_deprecated { resolve_spec("foo", config) }
|
78
|
-
expected = { "adapter" => "postgresql", "database" => "foo", "host" => "localhost" }
|
79
|
-
assert_equal expected, actual
|
80
|
-
end
|
81
|
-
|
82
54
|
def test_resolver_with_database_uri_and_known_key
|
83
55
|
ENV['DATABASE_URL'] = "postgres://localhost/foo"
|
84
56
|
config = { "production" => { "adapter" => "not_postgres", "database" => "not_foo", "host" => "localhost" } }
|
@@ -95,16 +67,6 @@ module ActiveRecord
|
|
95
67
|
end
|
96
68
|
end
|
97
69
|
|
98
|
-
def test_resolver_with_database_uri_and_unknown_string_key
|
99
|
-
ENV['DATABASE_URL'] = "postgres://localhost/foo"
|
100
|
-
config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
|
101
|
-
assert_deprecated do
|
102
|
-
assert_raises AdapterNotSpecified do
|
103
|
-
resolve_spec("production", config)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
70
|
def test_resolver_with_database_uri_and_supplied_url
|
109
71
|
ENV['DATABASE_URL'] = "not-postgres://not-localhost/not_foo"
|
110
72
|
config = { "production" => { "adapter" => "also_not_postgres", "database" => "also_not_foo" } }
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require "cases/helper"
|
2
2
|
|
3
|
-
if current_adapter?(:
|
3
|
+
if current_adapter?(:Mysql2Adapter)
|
4
4
|
module ActiveRecord
|
5
5
|
module ConnectionAdapters
|
6
6
|
class MysqlTypeLookupTest < ActiveRecord::TestCase
|
@@ -22,6 +22,10 @@ module ActiveRecord
|
|
22
22
|
assert_lookup_type :string, "SET('one', 'two', 'three')"
|
23
23
|
end
|
24
24
|
|
25
|
+
def test_set_type_with_value_matching_other_type
|
26
|
+
assert_lookup_type :string, "SET('unicode', '8bit', 'none', 'time')"
|
27
|
+
end
|
28
|
+
|
25
29
|
def test_enum_type_with_value_matching_other_type
|
26
30
|
assert_lookup_type :string, "ENUM('unicode', '8bit', 'none')"
|
27
31
|
end
|
@@ -29,7 +29,7 @@ module ActiveRecord
|
|
29
29
|
def test_clearing
|
30
30
|
@cache.columns('posts')
|
31
31
|
@cache.columns_hash('posts')
|
32
|
-
@cache.
|
32
|
+
@cache.data_sources('posts')
|
33
33
|
@cache.primary_keys('posts')
|
34
34
|
|
35
35
|
@cache.clear!
|
@@ -40,17 +40,22 @@ module ActiveRecord
|
|
40
40
|
def test_dump_and_load
|
41
41
|
@cache.columns('posts')
|
42
42
|
@cache.columns_hash('posts')
|
43
|
-
@cache.
|
43
|
+
@cache.data_sources('posts')
|
44
44
|
@cache.primary_keys('posts')
|
45
45
|
|
46
46
|
@cache = Marshal.load(Marshal.dump(@cache))
|
47
47
|
|
48
48
|
assert_equal 11, @cache.columns('posts').size
|
49
49
|
assert_equal 11, @cache.columns_hash('posts').size
|
50
|
-
assert @cache.
|
50
|
+
assert @cache.data_sources('posts')
|
51
51
|
assert_equal 'id', @cache.primary_keys('posts')
|
52
52
|
end
|
53
53
|
|
54
|
+
def test_table_methods_deprecation
|
55
|
+
assert_deprecated { assert @cache.table_exists?('posts') }
|
56
|
+
assert_deprecated { assert @cache.tables('posts') }
|
57
|
+
assert_deprecated { @cache.clear_table_cache!('posts') }
|
58
|
+
end
|
54
59
|
end
|
55
60
|
end
|
56
61
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require "cases/helper"
|
2
2
|
|
3
|
-
unless current_adapter?(:PostgreSQLAdapter) # PostgreSQL does not use type
|
3
|
+
unless current_adapter?(:PostgreSQLAdapter) # PostgreSQL does not use type strings for lookup
|
4
4
|
module ActiveRecord
|
5
5
|
module ConnectionAdapters
|
6
6
|
class TypeLookupTest < ActiveRecord::TestCase
|
@@ -89,12 +89,20 @@ module ActiveRecord
|
|
89
89
|
end
|
90
90
|
|
91
91
|
def test_decimal_without_scale
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
92
|
+
if current_adapter?(:OracleAdapter)
|
93
|
+
{
|
94
|
+
decimal: %w{decimal(2) decimal(2,0) numeric(2) numeric(2,0)},
|
95
|
+
integer: %w{number(2) number(2,0)}
|
96
|
+
}
|
97
|
+
else
|
98
|
+
{ decimal: %w{decimal(2) decimal(2,0) numeric(2) numeric(2,0) number(2) number(2,0)} }
|
99
|
+
end.each do |expected_type, types|
|
100
|
+
types.each do |type|
|
101
|
+
cast_type = @connection.type_map.lookup(type)
|
102
|
+
|
103
|
+
assert_equal expected_type, cast_type.type
|
104
|
+
assert_equal 2, cast_type.cast(2.1)
|
105
|
+
end
|
98
106
|
end
|
99
107
|
end
|
100
108
|
|
@@ -4,6 +4,8 @@ require "rack"
|
|
4
4
|
module ActiveRecord
|
5
5
|
module ConnectionAdapters
|
6
6
|
class ConnectionManagementTest < ActiveRecord::TestCase
|
7
|
+
self.use_transactional_tests = false
|
8
|
+
|
7
9
|
class App
|
8
10
|
attr_reader :calls
|
9
11
|
def initialize
|
@@ -19,48 +21,20 @@ module ActiveRecord
|
|
19
21
|
def setup
|
20
22
|
@env = {}
|
21
23
|
@app = App.new
|
22
|
-
@management =
|
24
|
+
@management = middleware(@app)
|
23
25
|
|
24
26
|
# make sure we have an active connection
|
25
27
|
assert ActiveRecord::Base.connection
|
26
28
|
assert ActiveRecord::Base.connection_handler.active_connections?
|
27
29
|
end
|
28
30
|
|
29
|
-
if Process.respond_to?(:fork)
|
30
|
-
def test_connection_pool_per_pid
|
31
|
-
object_id = ActiveRecord::Base.connection.object_id
|
32
|
-
|
33
|
-
rd, wr = IO.pipe
|
34
|
-
rd.binmode
|
35
|
-
wr.binmode
|
36
|
-
|
37
|
-
pid = fork {
|
38
|
-
rd.close
|
39
|
-
wr.write Marshal.dump ActiveRecord::Base.connection.object_id
|
40
|
-
wr.close
|
41
|
-
exit!
|
42
|
-
}
|
43
|
-
|
44
|
-
wr.close
|
45
|
-
|
46
|
-
Process.waitpid pid
|
47
|
-
assert_not_equal object_id, Marshal.load(rd.read)
|
48
|
-
rd.close
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
31
|
def test_app_delegation
|
53
|
-
manager =
|
32
|
+
manager = middleware(@app)
|
54
33
|
|
55
34
|
manager.call @env
|
56
35
|
assert_equal [@env], @app.calls
|
57
36
|
end
|
58
37
|
|
59
|
-
def test_connections_are_active_after_call
|
60
|
-
@management.call(@env)
|
61
|
-
assert ActiveRecord::Base.connection_handler.active_connections?
|
62
|
-
end
|
63
|
-
|
64
38
|
def test_body_responds_to_each
|
65
39
|
_, _, body = @management.call(@env)
|
66
40
|
bits = []
|
@@ -74,49 +48,65 @@ module ActiveRecord
|
|
74
48
|
assert !ActiveRecord::Base.connection_handler.active_connections?
|
75
49
|
end
|
76
50
|
|
77
|
-
def
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
51
|
+
def test_active_connections_are_not_cleared_on_body_close_during_transaction
|
52
|
+
ActiveRecord::Base.transaction do
|
53
|
+
_, _, body = @management.call(@env)
|
54
|
+
body.close
|
55
|
+
assert ActiveRecord::Base.connection_handler.active_connections?
|
56
|
+
end
|
82
57
|
end
|
83
58
|
|
84
59
|
def test_connections_closed_if_exception
|
85
60
|
app = Class.new(App) { def call(env); raise NotImplementedError; end }.new
|
86
|
-
explosive =
|
61
|
+
explosive = middleware(app)
|
87
62
|
assert_raises(NotImplementedError) { explosive.call(@env) }
|
88
63
|
assert !ActiveRecord::Base.connection_handler.active_connections?
|
89
64
|
end
|
90
65
|
|
91
|
-
def
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
def test_connections_closed_if_exception_and_explicitly_not_test
|
100
|
-
@env['rack.test'] = false
|
101
|
-
app = Class.new(App) { def call(env); raise NotImplementedError; end }.new
|
102
|
-
explosive = ConnectionManagement.new(app)
|
103
|
-
assert_raises(NotImplementedError) { explosive.call(@env) }
|
104
|
-
assert !ActiveRecord::Base.connection_handler.active_connections?
|
66
|
+
def test_connections_not_closed_if_exception_inside_transaction
|
67
|
+
ActiveRecord::Base.transaction do
|
68
|
+
app = Class.new(App) { def call(env); raise RuntimeError; end }.new
|
69
|
+
explosive = middleware(app)
|
70
|
+
assert_raises(RuntimeError) { explosive.call(@env) }
|
71
|
+
assert ActiveRecord::Base.connection_handler.active_connections?
|
72
|
+
end
|
105
73
|
end
|
106
74
|
|
107
75
|
test "doesn't clear active connections when running in a test case" do
|
108
|
-
|
109
|
-
|
110
|
-
|
76
|
+
executor.wrap do
|
77
|
+
@management.call(@env)
|
78
|
+
assert ActiveRecord::Base.connection_handler.active_connections?
|
79
|
+
end
|
111
80
|
end
|
112
81
|
|
113
|
-
test "proxy is polite to
|
82
|
+
test "proxy is polite to its body and responds to it" do
|
114
83
|
body = Class.new(String) { def to_path; "/path"; end }.new
|
115
84
|
app = lambda { |_| [200, {}, body] }
|
116
|
-
response_body =
|
85
|
+
response_body = middleware(app).call(@env)[2]
|
117
86
|
assert response_body.respond_to?(:to_path)
|
118
|
-
assert_equal
|
87
|
+
assert_equal "/path", response_body.to_path
|
88
|
+
end
|
89
|
+
|
90
|
+
test "doesn't mutate the original response" do
|
91
|
+
original_response = [200, {}, 'hi']
|
92
|
+
app = lambda { |_| original_response }
|
93
|
+
middleware(app).call(@env)[2]
|
94
|
+
assert_equal 'hi', original_response.last
|
119
95
|
end
|
96
|
+
|
97
|
+
private
|
98
|
+
def executor
|
99
|
+
@executor ||= Class.new(ActiveSupport::Executor).tap do |exe|
|
100
|
+
ActiveRecord::QueryCache.install_executor_hooks(exe)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def middleware(app)
|
105
|
+
lambda do |env|
|
106
|
+
a, b, c = executor.wrap { app.call(env) }
|
107
|
+
[a, b, Rack::BodyProxy.new(c) { }]
|
108
|
+
end
|
109
|
+
end
|
120
110
|
end
|
121
111
|
end
|
122
112
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require "cases/helper"
|
2
|
-
require '
|
2
|
+
require 'concurrent/atomic/count_down_latch'
|
3
3
|
|
4
4
|
module ActiveRecord
|
5
5
|
module ConnectionAdapters
|
@@ -100,7 +100,7 @@ module ActiveRecord
|
|
100
100
|
t = Thread.new { @pool.checkout }
|
101
101
|
|
102
102
|
# make sure our thread is in the timeout section
|
103
|
-
Thread.pass until
|
103
|
+
Thread.pass until @pool.num_waiting_in_queue == 1
|
104
104
|
|
105
105
|
connection = cs.first
|
106
106
|
connection.close
|
@@ -112,7 +112,7 @@ module ActiveRecord
|
|
112
112
|
t = Thread.new { @pool.checkout }
|
113
113
|
|
114
114
|
# make sure our thread is in the timeout section
|
115
|
-
Thread.pass until
|
115
|
+
Thread.pass until @pool.num_waiting_in_queue == 1
|
116
116
|
|
117
117
|
connection = cs.first
|
118
118
|
@pool.remove connection
|
@@ -133,15 +133,15 @@ module ActiveRecord
|
|
133
133
|
end
|
134
134
|
|
135
135
|
def test_reap_inactive
|
136
|
-
ready =
|
136
|
+
ready = Concurrent::CountDownLatch.new
|
137
137
|
@pool.checkout
|
138
138
|
child = Thread.new do
|
139
139
|
@pool.checkout
|
140
140
|
@pool.checkout
|
141
|
-
ready.
|
141
|
+
ready.count_down
|
142
142
|
Thread.stop
|
143
143
|
end
|
144
|
-
ready.
|
144
|
+
ready.wait
|
145
145
|
|
146
146
|
assert_equal 3, active_connections(@pool).size
|
147
147
|
|
@@ -151,7 +151,7 @@ module ActiveRecord
|
|
151
151
|
|
152
152
|
assert_equal 1, active_connections(@pool).size
|
153
153
|
ensure
|
154
|
-
@pool.connections.each
|
154
|
+
@pool.connections.each { |conn| conn.close if conn.in_use? }
|
155
155
|
end
|
156
156
|
|
157
157
|
def test_remove_connection
|
@@ -184,14 +184,14 @@ module ActiveRecord
|
|
184
184
|
|
185
185
|
def test_checkout_behaviour
|
186
186
|
pool = ConnectionPool.new ActiveRecord::Base.connection_pool.spec
|
187
|
-
|
188
|
-
assert_not_nil
|
187
|
+
main_connection = pool.connection
|
188
|
+
assert_not_nil main_connection
|
189
189
|
threads = []
|
190
190
|
4.times do |i|
|
191
191
|
threads << Thread.new(i) do
|
192
|
-
|
193
|
-
assert_not_nil
|
194
|
-
|
192
|
+
thread_connection = pool.connection
|
193
|
+
assert_not_nil thread_connection
|
194
|
+
thread_connection.close
|
195
195
|
end
|
196
196
|
end
|
197
197
|
|
@@ -204,13 +204,13 @@ module ActiveRecord
|
|
204
204
|
end
|
205
205
|
|
206
206
|
# The connection pool is "fair" if threads waiting for
|
207
|
-
# connections receive them the order in which they began
|
207
|
+
# connections receive them in the order in which they began
|
208
208
|
# waiting. This ensures that we don't timeout one HTTP request
|
209
209
|
# even while well under capacity in a multi-threaded environment
|
210
210
|
# such as a Java servlet container.
|
211
211
|
#
|
212
212
|
# We don't need strict fairness: if two connections become
|
213
|
-
# available at the same time, it's fine
|
213
|
+
# available at the same time, it's fine if two threads that were
|
214
214
|
# waiting acquire the connections out of order.
|
215
215
|
#
|
216
216
|
# Thus this test prepares waiting threads and then trickles in
|
@@ -234,7 +234,7 @@ module ActiveRecord
|
|
234
234
|
mutex.synchronize { errors << e }
|
235
235
|
end
|
236
236
|
}
|
237
|
-
Thread.pass until
|
237
|
+
Thread.pass until @pool.num_waiting_in_queue == i
|
238
238
|
t
|
239
239
|
end
|
240
240
|
|
@@ -271,7 +271,7 @@ module ActiveRecord
|
|
271
271
|
mutex.synchronize { errors << e }
|
272
272
|
end
|
273
273
|
}
|
274
|
-
Thread.pass until
|
274
|
+
Thread.pass until @pool.num_waiting_in_queue == i
|
275
275
|
t
|
276
276
|
end
|
277
277
|
|
@@ -335,11 +335,186 @@ module ActiveRecord
|
|
335
335
|
# is called with an anonymous class
|
336
336
|
def test_anonymous_class_exception
|
337
337
|
anonymous = Class.new(ActiveRecord::Base)
|
338
|
-
handler = ActiveRecord::Base.connection_handler
|
339
338
|
|
340
|
-
assert_raises(RuntimeError)
|
341
|
-
|
342
|
-
|
339
|
+
assert_raises(RuntimeError) do
|
340
|
+
anonymous.establish_connection
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
def test_pool_sets_connection_schema_cache
|
345
|
+
connection = pool.checkout
|
346
|
+
schema_cache = SchemaCache.new connection
|
347
|
+
schema_cache.add(:posts)
|
348
|
+
pool.schema_cache = schema_cache
|
349
|
+
|
350
|
+
pool.with_connection do |conn|
|
351
|
+
assert_not_same pool.schema_cache, conn.schema_cache
|
352
|
+
assert_equal pool.schema_cache.size, conn.schema_cache.size
|
353
|
+
assert_same pool.schema_cache.columns(:posts), conn.schema_cache.columns(:posts)
|
354
|
+
end
|
355
|
+
|
356
|
+
pool.checkin connection
|
357
|
+
end
|
358
|
+
|
359
|
+
def test_concurrent_connection_establishment
|
360
|
+
assert_operator @pool.connections.size, :<=, 1
|
361
|
+
|
362
|
+
all_threads_in_new_connection = Concurrent::CountDownLatch.new(@pool.size - @pool.connections.size)
|
363
|
+
all_go = Concurrent::CountDownLatch.new
|
364
|
+
|
365
|
+
@pool.singleton_class.class_eval do
|
366
|
+
define_method(:new_connection) do
|
367
|
+
all_threads_in_new_connection.count_down
|
368
|
+
all_go.wait
|
369
|
+
super()
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
connecting_threads = []
|
374
|
+
@pool.size.times do
|
375
|
+
connecting_threads << Thread.new { @pool.checkout }
|
376
|
+
end
|
377
|
+
|
378
|
+
begin
|
379
|
+
Timeout.timeout(5) do
|
380
|
+
# the kernel of the whole test is here, everything else is just scaffolding,
|
381
|
+
# this latch will not be released unless conn. pool allows for concurrent
|
382
|
+
# connection creation
|
383
|
+
all_threads_in_new_connection.wait
|
384
|
+
end
|
385
|
+
rescue Timeout::Error
|
386
|
+
flunk 'pool unable to establish connections concurrently or implementation has ' <<
|
387
|
+
'changed, this test then needs to patch a different :new_connection method'
|
388
|
+
ensure
|
389
|
+
# clean up the threads
|
390
|
+
all_go.count_down
|
391
|
+
connecting_threads.map(&:join)
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
def test_non_bang_disconnect_and_clear_reloadable_connections_throw_exception_if_threads_dont_return_their_conns
|
396
|
+
@pool.checkout_timeout = 0.001 # no need to delay test suite by waiting the whole full default timeout
|
397
|
+
[:disconnect, :clear_reloadable_connections].each do |group_action_method|
|
398
|
+
@pool.with_connection do |connection|
|
399
|
+
assert_raises(ExclusiveConnectionTimeoutError) do
|
400
|
+
Thread.new { @pool.send(group_action_method) }.join
|
401
|
+
end
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
def test_disconnect_and_clear_reloadable_connections_attempt_to_wait_for_threads_to_return_their_conns
|
407
|
+
[:disconnect, :disconnect!, :clear_reloadable_connections, :clear_reloadable_connections!].each do |group_action_method|
|
408
|
+
begin
|
409
|
+
thread = timed_join_result = nil
|
410
|
+
@pool.with_connection do |connection|
|
411
|
+
thread = Thread.new { @pool.send(group_action_method) }
|
412
|
+
|
413
|
+
# give the other `thread` some time to get stuck in `group_action_method`
|
414
|
+
timed_join_result = thread.join(0.3)
|
415
|
+
# thread.join # => `nil` means the other thread hasn't finished running and is still waiting for us to
|
416
|
+
# release our connection
|
417
|
+
assert_nil timed_join_result
|
418
|
+
|
419
|
+
# assert that since this is within default timeout our connection hasn't been forcefully taken away from us
|
420
|
+
assert @pool.active_connection?
|
421
|
+
end
|
422
|
+
ensure
|
423
|
+
thread.join if thread && !timed_join_result # clean up the other thread
|
424
|
+
end
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
def test_bang_versions_of_disconnect_and_clear_reloadable_connections_if_unable_to_aquire_all_connections_proceed_anyway
|
429
|
+
@pool.checkout_timeout = 0.001 # no need to delay test suite by waiting the whole full default timeout
|
430
|
+
[:disconnect!, :clear_reloadable_connections!].each do |group_action_method|
|
431
|
+
@pool.with_connection do |connection|
|
432
|
+
Thread.new { @pool.send(group_action_method) }.join
|
433
|
+
# assert connection has been forcefully taken away from us
|
434
|
+
assert_not @pool.active_connection?
|
435
|
+
|
436
|
+
# make a new connection for with_connection to clean up
|
437
|
+
@pool.connection
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
def test_disconnect_and_clear_reloadable_connections_are_able_to_preempt_other_waiting_threads
|
443
|
+
with_single_connection_pool do |pool|
|
444
|
+
[:disconnect, :disconnect!, :clear_reloadable_connections, :clear_reloadable_connections!].each do |group_action_method|
|
445
|
+
conn = pool.connection # drain the only available connection
|
446
|
+
second_thread_done = Concurrent::CountDownLatch.new
|
447
|
+
|
448
|
+
# create a first_thread and let it get into the FIFO queue first
|
449
|
+
first_thread = Thread.new do
|
450
|
+
pool.with_connection { second_thread_done.wait }
|
451
|
+
end
|
452
|
+
|
453
|
+
# wait for first_thread to get in queue
|
454
|
+
Thread.pass until pool.num_waiting_in_queue == 1
|
455
|
+
|
456
|
+
# create a different, later thread, that will attempt to do a "group action",
|
457
|
+
# but because of the group action semantics it should be able to preempt the
|
458
|
+
# first_thread when a connection is made available
|
459
|
+
second_thread = Thread.new do
|
460
|
+
pool.send(group_action_method)
|
461
|
+
second_thread_done.count_down
|
462
|
+
end
|
463
|
+
|
464
|
+
# wait for second_thread to get in queue
|
465
|
+
Thread.pass until pool.num_waiting_in_queue == 2
|
466
|
+
|
467
|
+
# return the only available connection
|
468
|
+
pool.checkin(conn)
|
469
|
+
|
470
|
+
# if the second_thread is not able to preempt the first_thread,
|
471
|
+
# they will temporarily (until either of them timeouts with ConnectionTimeoutError)
|
472
|
+
# deadlock and a join(2) timeout will be reached
|
473
|
+
failed = true unless second_thread.join(2)
|
474
|
+
|
475
|
+
#--- post test clean up start
|
476
|
+
second_thread_done.count_down if failed
|
477
|
+
|
478
|
+
first_thread.join
|
479
|
+
second_thread.join
|
480
|
+
#--- post test clean up end
|
481
|
+
|
482
|
+
flunk "#{group_action_method} is not able to preempt other waiting threads" if failed
|
483
|
+
end
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
def test_clear_reloadable_connections_creates_new_connections_for_waiting_threads_if_necessary
|
488
|
+
with_single_connection_pool do |pool|
|
489
|
+
conn = pool.connection # drain the only available connection
|
490
|
+
def conn.requires_reloading? # make sure it gets removed from the pool by clear_reloadable_connections
|
491
|
+
true
|
492
|
+
end
|
493
|
+
|
494
|
+
stuck_thread = Thread.new do
|
495
|
+
pool.with_connection {}
|
496
|
+
end
|
497
|
+
|
498
|
+
# wait for stuck_thread to get in queue
|
499
|
+
Thread.pass until pool.num_waiting_in_queue == 1
|
500
|
+
|
501
|
+
pool.clear_reloadable_connections
|
502
|
+
|
503
|
+
unless stuck_thread.join(2)
|
504
|
+
flunk 'clear_reloadable_connections must not let other connection waiting threads get stuck in queue'
|
505
|
+
end
|
506
|
+
|
507
|
+
assert_equal 0, pool.num_waiting_in_queue
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
511
|
+
private
|
512
|
+
def with_single_connection_pool
|
513
|
+
one_conn_spec = ActiveRecord::Base.connection_pool.spec.dup
|
514
|
+
one_conn_spec.config[:pool] = 1 # this is safe to do, because .dupped ConnectionSpecification also auto-dups its config
|
515
|
+
yield(pool = ConnectionPool.new(one_conn_spec))
|
516
|
+
ensure
|
517
|
+
pool.disconnect! if pool
|
343
518
|
end
|
344
519
|
end
|
345
520
|
end
|