ibm_db 5.6.1-arm64-darwin-24

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.
Files changed (753) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +299 -0
  3. data/LICENSE +55 -0
  4. data/MANIFEST +14 -0
  5. data/ParameterizedQueries README +39 -0
  6. data/README +210 -0
  7. data/ext/Makefile +270 -0
  8. data/ext/Makefile.nt32 +181 -0
  9. data/ext/Makefile.nt32.191 +212 -0
  10. data/ext/extconf.rb +320 -0
  11. data/ext/gil_release_version.h +3 -0
  12. data/ext/ibm_db.bundle +0 -0
  13. data/ext/ibm_db.c +11865 -0
  14. data/ext/ibm_db.o +0 -0
  15. data/ext/mkmf.log +98 -0
  16. data/ext/ruby_ibm_db.h +241 -0
  17. data/ext/ruby_ibm_db_cli.c +867 -0
  18. data/ext/ruby_ibm_db_cli.h +508 -0
  19. data/ext/ruby_ibm_db_cli.o +0 -0
  20. data/ext/unicode_support_version.h +3 -0
  21. data/init.rb +42 -0
  22. data/lib/IBM_DB.rb +27 -0
  23. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +4407 -0
  24. data/lib/active_record/connection_adapters/ibm_db_pstmt.rb +1965 -0
  25. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +5 -0
  26. data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -0
  27. data/lib/ibm_db.bundle +0 -0
  28. data/test/active_record/connection_adapters/fake_adapter.rb +52 -0
  29. data/test/activejob/destroy_association_async_test.rb +305 -0
  30. data/test/activejob/destroy_async_job_not_present_test.rb +31 -0
  31. data/test/activejob/helper.rb +15 -0
  32. data/test/assets/example.log +1 -0
  33. data/test/assets/flowers.jpg +0 -0
  34. data/test/assets/schema_dump_5_1.yml +345 -0
  35. data/test/assets/test.txt +1 -0
  36. data/test/cases/adapter_prevent_writes_test.rb +334 -0
  37. data/test/cases/adapter_test.rb +565 -0
  38. data/test/cases/adapters/mysql2/active_schema_test.rb +203 -0
  39. data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
  40. data/test/cases/adapters/mysql2/bind_parameter_test.rb +52 -0
  41. data/test/cases/adapters/mysql2/boolean_test.rb +102 -0
  42. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +65 -0
  43. data/test/cases/adapters/mysql2/charset_collation_test.rb +57 -0
  44. data/test/cases/adapters/mysql2/connection_test.rb +208 -0
  45. data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
  46. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +49 -0
  47. data/test/cases/adapters/mysql2/enum_test.rb +47 -0
  48. data/test/cases/adapters/mysql2/explain_test.rb +23 -0
  49. data/test/cases/adapters/mysql2/json_test.rb +24 -0
  50. data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
  51. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +238 -0
  52. data/test/cases/adapters/mysql2/nested_deadlock_test.rb +75 -0
  53. data/test/cases/adapters/mysql2/optimizer_hints_test.rb +69 -0
  54. data/test/cases/adapters/mysql2/reserved_word_test.rb +152 -0
  55. data/test/cases/adapters/mysql2/schema_migrations_test.rb +64 -0
  56. data/test/cases/adapters/mysql2/schema_test.rb +128 -0
  57. data/test/cases/adapters/mysql2/set_test.rb +32 -0
  58. data/test/cases/adapters/mysql2/sp_test.rb +38 -0
  59. data/test/cases/adapters/mysql2/sql_types_test.rb +16 -0
  60. data/test/cases/adapters/mysql2/table_options_test.rb +125 -0
  61. data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
  62. data/test/cases/adapters/mysql2/unsigned_type_test.rb +68 -0
  63. data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
  64. data/test/cases/adapters/postgresql/active_schema_test.rb +113 -0
  65. data/test/cases/adapters/postgresql/array_test.rb +394 -0
  66. data/test/cases/adapters/postgresql/bit_string_test.rb +84 -0
  67. data/test/cases/adapters/postgresql/bytea_test.rb +135 -0
  68. data/test/cases/adapters/postgresql/case_insensitive_test.rb +27 -0
  69. data/test/cases/adapters/postgresql/change_schema_test.rb +40 -0
  70. data/test/cases/adapters/postgresql/cidr_test.rb +27 -0
  71. data/test/cases/adapters/postgresql/citext_test.rb +78 -0
  72. data/test/cases/adapters/postgresql/collation_test.rb +55 -0
  73. data/test/cases/adapters/postgresql/composite_test.rb +134 -0
  74. data/test/cases/adapters/postgresql/connection_test.rb +245 -0
  75. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +74 -0
  76. data/test/cases/adapters/postgresql/datatype_test.rb +89 -0
  77. data/test/cases/adapters/postgresql/date_test.rb +42 -0
  78. data/test/cases/adapters/postgresql/domain_test.rb +49 -0
  79. data/test/cases/adapters/postgresql/enum_test.rb +93 -0
  80. data/test/cases/adapters/postgresql/explain_test.rb +22 -0
  81. data/test/cases/adapters/postgresql/extension_migration_test.rb +64 -0
  82. data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
  83. data/test/cases/adapters/postgresql/full_text_test.rb +46 -0
  84. data/test/cases/adapters/postgresql/geometric_test.rb +372 -0
  85. data/test/cases/adapters/postgresql/hstore_test.rb +390 -0
  86. data/test/cases/adapters/postgresql/infinity_test.rb +108 -0
  87. data/test/cases/adapters/postgresql/integer_test.rb +27 -0
  88. data/test/cases/adapters/postgresql/interval_test.rb +99 -0
  89. data/test/cases/adapters/postgresql/json_test.rb +52 -0
  90. data/test/cases/adapters/postgresql/ltree_test.rb +51 -0
  91. data/test/cases/adapters/postgresql/money_test.rb +127 -0
  92. data/test/cases/adapters/postgresql/network_test.rb +102 -0
  93. data/test/cases/adapters/postgresql/numbers_test.rb +51 -0
  94. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +71 -0
  95. data/test/cases/adapters/postgresql/partitions_test.rb +22 -0
  96. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +205 -0
  97. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +447 -0
  98. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
  99. data/test/cases/adapters/postgresql/prepared_statements_test.rb +22 -0
  100. data/test/cases/adapters/postgresql/quoting_test.rb +50 -0
  101. data/test/cases/adapters/postgresql/range_test.rb +457 -0
  102. data/test/cases/adapters/postgresql/referential_integrity_test.rb +112 -0
  103. data/test/cases/adapters/postgresql/rename_table_test.rb +35 -0
  104. data/test/cases/adapters/postgresql/schema_authorization_test.rb +110 -0
  105. data/test/cases/adapters/postgresql/schema_test.rb +713 -0
  106. data/test/cases/adapters/postgresql/serial_test.rb +156 -0
  107. data/test/cases/adapters/postgresql/statement_pool_test.rb +61 -0
  108. data/test/cases/adapters/postgresql/timestamp_test.rb +92 -0
  109. data/test/cases/adapters/postgresql/transaction_nested_test.rb +114 -0
  110. data/test/cases/adapters/postgresql/transaction_test.rb +189 -0
  111. data/test/cases/adapters/postgresql/type_lookup_test.rb +35 -0
  112. data/test/cases/adapters/postgresql/utils_test.rb +64 -0
  113. data/test/cases/adapters/postgresql/uuid_test.rb +411 -0
  114. data/test/cases/adapters/postgresql/xml_test.rb +50 -0
  115. data/test/cases/adapters/sqlite3/collation_test.rb +64 -0
  116. data/test/cases/adapters/sqlite3/copy_table_test.rb +101 -0
  117. data/test/cases/adapters/sqlite3/explain_test.rb +23 -0
  118. data/test/cases/adapters/sqlite3/json_test.rb +29 -0
  119. data/test/cases/adapters/sqlite3/quoting_test.rb +79 -0
  120. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +186 -0
  121. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +628 -0
  122. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +24 -0
  123. data/test/cases/adapters/sqlite3/statement_pool_test.rb +21 -0
  124. data/test/cases/adapters/sqlite3/transaction_test.rb +123 -0
  125. data/test/cases/aggregations_test.rb +170 -0
  126. data/test/cases/annotate_test.rb +46 -0
  127. data/test/cases/ar_schema_test.rb +213 -0
  128. data/test/cases/arel/attributes/attribute_test.rb +1145 -0
  129. data/test/cases/arel/attributes/math_test.rb +83 -0
  130. data/test/cases/arel/attributes_test.rb +27 -0
  131. data/test/cases/arel/collectors/bind_test.rb +40 -0
  132. data/test/cases/arel/collectors/composite_test.rb +47 -0
  133. data/test/cases/arel/collectors/sql_string_test.rb +41 -0
  134. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +48 -0
  135. data/test/cases/arel/crud_test.rb +65 -0
  136. data/test/cases/arel/delete_manager_test.rb +53 -0
  137. data/test/cases/arel/factory_methods_test.rb +46 -0
  138. data/test/cases/arel/helper.rb +45 -0
  139. data/test/cases/arel/insert_manager_test.rb +241 -0
  140. data/test/cases/arel/nodes/and_test.rb +30 -0
  141. data/test/cases/arel/nodes/as_test.rb +36 -0
  142. data/test/cases/arel/nodes/ascending_test.rb +46 -0
  143. data/test/cases/arel/nodes/bin_test.rb +35 -0
  144. data/test/cases/arel/nodes/binary_test.rb +29 -0
  145. data/test/cases/arel/nodes/bind_param_test.rb +22 -0
  146. data/test/cases/arel/nodes/case_test.rb +96 -0
  147. data/test/cases/arel/nodes/casted_test.rb +18 -0
  148. data/test/cases/arel/nodes/comment_test.rb +22 -0
  149. data/test/cases/arel/nodes/count_test.rb +35 -0
  150. data/test/cases/arel/nodes/delete_statement_test.rb +36 -0
  151. data/test/cases/arel/nodes/descending_test.rb +46 -0
  152. data/test/cases/arel/nodes/distinct_test.rb +21 -0
  153. data/test/cases/arel/nodes/equality_test.rb +62 -0
  154. data/test/cases/arel/nodes/extract_test.rb +43 -0
  155. data/test/cases/arel/nodes/false_test.rb +21 -0
  156. data/test/cases/arel/nodes/grouping_test.rb +26 -0
  157. data/test/cases/arel/nodes/infix_operation_test.rb +42 -0
  158. data/test/cases/arel/nodes/insert_statement_test.rb +44 -0
  159. data/test/cases/arel/nodes/named_function_test.rb +48 -0
  160. data/test/cases/arel/nodes/node_test.rb +22 -0
  161. data/test/cases/arel/nodes/not_test.rb +31 -0
  162. data/test/cases/arel/nodes/or_test.rb +36 -0
  163. data/test/cases/arel/nodes/over_test.rb +69 -0
  164. data/test/cases/arel/nodes/select_core_test.rb +79 -0
  165. data/test/cases/arel/nodes/select_statement_test.rb +51 -0
  166. data/test/cases/arel/nodes/sql_literal_test.rb +75 -0
  167. data/test/cases/arel/nodes/sum_test.rb +35 -0
  168. data/test/cases/arel/nodes/table_alias_test.rb +29 -0
  169. data/test/cases/arel/nodes/true_test.rb +21 -0
  170. data/test/cases/arel/nodes/unary_operation_test.rb +41 -0
  171. data/test/cases/arel/nodes/update_statement_test.rb +60 -0
  172. data/test/cases/arel/nodes/window_test.rb +81 -0
  173. data/test/cases/arel/nodes_test.rb +34 -0
  174. data/test/cases/arel/select_manager_test.rb +1238 -0
  175. data/test/cases/arel/support/fake_record.rb +135 -0
  176. data/test/cases/arel/table_test.rb +216 -0
  177. data/test/cases/arel/update_manager_test.rb +126 -0
  178. data/test/cases/arel/visitors/dispatch_contamination_test.rb +78 -0
  179. data/test/cases/arel/visitors/dot_test.rb +90 -0
  180. data/test/cases/arel/visitors/mysql_test.rb +157 -0
  181. data/test/cases/arel/visitors/postgres_test.rb +366 -0
  182. data/test/cases/arel/visitors/sqlite_test.rb +75 -0
  183. data/test/cases/arel/visitors/to_sql_test.rb +750 -0
  184. data/test/cases/associations/association_scope_test.rb +16 -0
  185. data/test/cases/associations/belongs_to_associations_test.rb +1493 -0
  186. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +43 -0
  187. data/test/cases/associations/callbacks_test.rb +208 -0
  188. data/test/cases/associations/cascaded_eager_loading_test.rb +245 -0
  189. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +156 -0
  190. data/test/cases/associations/eager_load_nested_include_test.rb +127 -0
  191. data/test/cases/associations/eager_singularization_test.rb +148 -0
  192. data/test/cases/associations/eager_test.rb +1658 -0
  193. data/test/cases/associations/extension_test.rb +93 -0
  194. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +1025 -0
  195. data/test/cases/associations/has_many_associations_test.rb +3074 -0
  196. data/test/cases/associations/has_many_through_associations_test.rb +1580 -0
  197. data/test/cases/associations/has_one_associations_test.rb +872 -0
  198. data/test/cases/associations/has_one_through_associations_test.rb +429 -0
  199. data/test/cases/associations/inner_join_association_test.rb +215 -0
  200. data/test/cases/associations/inverse_associations_test.rb +941 -0
  201. data/test/cases/associations/join_model_test.rb +787 -0
  202. data/test/cases/associations/left_outer_join_association_test.rb +123 -0
  203. data/test/cases/associations/nested_through_associations_test.rb +636 -0
  204. data/test/cases/associations/required_test.rb +127 -0
  205. data/test/cases/associations_test.rb +516 -0
  206. data/test/cases/attribute_decorators_test.rb +126 -0
  207. data/test/cases/attribute_methods/read_test.rb +60 -0
  208. data/test/cases/attribute_methods_test.rb +1124 -0
  209. data/test/cases/attribute_set_test.rb +270 -0
  210. data/test/cases/attribute_test.rb +246 -0
  211. data/test/cases/attributes_test.rb +371 -0
  212. data/test/cases/autosave_association_test.rb +1953 -0
  213. data/test/cases/base_prevent_writes_test.rb +229 -0
  214. data/test/cases/base_test.rb +1770 -0
  215. data/test/cases/batches_test.rb +695 -0
  216. data/test/cases/binary_test.rb +39 -0
  217. data/test/cases/bind_parameter_test.rb +283 -0
  218. data/test/cases/boolean_test.rb +52 -0
  219. data/test/cases/cache_key_test.rb +131 -0
  220. data/test/cases/calculations_test.rb +1361 -0
  221. data/test/cases/callbacks_test.rb +503 -0
  222. data/test/cases/clone_test.rb +45 -0
  223. data/test/cases/coders/json_test.rb +17 -0
  224. data/test/cases/coders/yaml_column_test.rb +66 -0
  225. data/test/cases/collection_cache_key_test.rb +272 -0
  226. data/test/cases/column_alias_test.rb +19 -0
  227. data/test/cases/column_definition_test.rb +34 -0
  228. data/test/cases/comment_test.rb +204 -0
  229. data/test/cases/connection_adapters/adapter_leasing_test.rb +60 -0
  230. data/test/cases/connection_adapters/connection_handler_test.rb +467 -0
  231. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +400 -0
  232. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +103 -0
  233. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +499 -0
  234. data/test/cases/connection_adapters/connection_specification_test.rb +12 -0
  235. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +457 -0
  236. data/test/cases/connection_adapters/legacy_connection_handlers_multi_db_test.rb +486 -0
  237. data/test/cases/connection_adapters/legacy_connection_handlers_sharding_db_test.rb +586 -0
  238. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +436 -0
  239. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +81 -0
  240. data/test/cases/connection_adapters/quoting_test.rb +13 -0
  241. data/test/cases/connection_adapters/schema_cache_test.rb +294 -0
  242. data/test/cases/connection_adapters/type_lookup_test.rb +119 -0
  243. data/test/cases/connection_management_test.rb +114 -0
  244. data/test/cases/connection_pool_test.rb +754 -0
  245. data/test/cases/connection_specification/resolver_test.rb +131 -0
  246. data/test/cases/core_test.rb +136 -0
  247. data/test/cases/counter_cache_test.rb +368 -0
  248. data/test/cases/custom_locking_test.rb +19 -0
  249. data/test/cases/database_configurations/hash_config_test.rb +74 -0
  250. data/test/cases/database_configurations/resolver_test.rb +150 -0
  251. data/test/cases/database_configurations_test.rb +145 -0
  252. data/test/cases/database_selector_test.rb +296 -0
  253. data/test/cases/database_statements_test.rb +36 -0
  254. data/test/cases/date_test.rb +36 -0
  255. data/test/cases/date_time_precision_test.rb +129 -0
  256. data/test/cases/date_time_test.rb +76 -0
  257. data/test/cases/defaults_test.rb +254 -0
  258. data/test/cases/delegated_type_test.rb +57 -0
  259. data/test/cases/dirty_test.rb +959 -0
  260. data/test/cases/disconnected_test.rb +30 -0
  261. data/test/cases/dup_test.rb +184 -0
  262. data/test/cases/enum_test.rb +823 -0
  263. data/test/cases/errors_test.rb +16 -0
  264. data/test/cases/explain_subscriber_test.rb +66 -0
  265. data/test/cases/explain_test.rb +79 -0
  266. data/test/cases/filter_attributes_test.rb +153 -0
  267. data/test/cases/finder_respond_to_test.rb +60 -0
  268. data/test/cases/finder_test.rb +1676 -0
  269. data/test/cases/fixture_set/file_test.rb +152 -0
  270. data/test/cases/fixtures_test.rb +1645 -0
  271. data/test/cases/forbidden_attributes_protection_test.rb +130 -0
  272. data/test/cases/habtm_destroy_order_test.rb +61 -0
  273. data/test/cases/helper.rb +233 -0
  274. data/test/cases/hot_compatibility_test.rb +143 -0
  275. data/test/cases/i18n_test.rb +46 -0
  276. data/test/cases/inheritance_test.rb +671 -0
  277. data/test/cases/insert_all_test.rb +489 -0
  278. data/test/cases/instrumentation_test.rb +101 -0
  279. data/test/cases/integration_test.rb +243 -0
  280. data/test/cases/invalid_connection_test.rb +26 -0
  281. data/test/cases/invertible_migration_test.rb +527 -0
  282. data/test/cases/json_attribute_test.rb +35 -0
  283. data/test/cases/json_serialization_test.rb +310 -0
  284. data/test/cases/json_shared_test_cases.rb +290 -0
  285. data/test/cases/locking_test.rb +787 -0
  286. data/test/cases/log_subscriber_test.rb +267 -0
  287. data/test/cases/marshal_serialization_test.rb +39 -0
  288. data/test/cases/migration/change_schema_test.rb +504 -0
  289. data/test/cases/migration/change_table_test.rb +364 -0
  290. data/test/cases/migration/check_constraint_test.rb +162 -0
  291. data/test/cases/migration/column_attributes_test.rb +186 -0
  292. data/test/cases/migration/column_positioning_test.rb +68 -0
  293. data/test/cases/migration/columns_test.rb +326 -0
  294. data/test/cases/migration/command_recorder_test.rb +437 -0
  295. data/test/cases/migration/compatibility_test.rb +673 -0
  296. data/test/cases/migration/create_join_table_test.rb +167 -0
  297. data/test/cases/migration/foreign_key_test.rb +581 -0
  298. data/test/cases/migration/helper.rb +40 -0
  299. data/test/cases/migration/index_test.rb +267 -0
  300. data/test/cases/migration/logger_test.rb +39 -0
  301. data/test/cases/migration/pending_migrations_test.rb +106 -0
  302. data/test/cases/migration/references_foreign_key_test.rb +235 -0
  303. data/test/cases/migration/references_index_test.rb +120 -0
  304. data/test/cases/migration/references_statements_test.rb +137 -0
  305. data/test/cases/migration/rename_table_test.rb +116 -0
  306. data/test/cases/migration_test.rb +1525 -0
  307. data/test/cases/migrator_test.rb +527 -0
  308. data/test/cases/mixin_test.rb +64 -0
  309. data/test/cases/modules_test.rb +174 -0
  310. data/test/cases/multi_db_migrator_test.rb +223 -0
  311. data/test/cases/multiparameter_attributes_test.rb +399 -0
  312. data/test/cases/multiple_db_test.rb +116 -0
  313. data/test/cases/nested_attributes_test.rb +1119 -0
  314. data/test/cases/nested_attributes_with_callbacks_test.rb +146 -0
  315. data/test/cases/null_relation_test.rb +84 -0
  316. data/test/cases/numeric_data_test.rb +93 -0
  317. data/test/cases/persistence_test.rb +1093 -0
  318. data/test/cases/pooled_connections_test.rb +73 -0
  319. data/test/cases/prepared_statement_status_test.rb +48 -0
  320. data/test/cases/primary_keys_test.rb +482 -0
  321. data/test/cases/query_cache_test.rb +915 -0
  322. data/test/cases/quoting_test.rb +303 -0
  323. data/test/cases/readonly_test.rb +120 -0
  324. data/test/cases/reaper_test.rb +199 -0
  325. data/test/cases/reflection_test.rb +520 -0
  326. data/test/cases/relation/delegation_test.rb +76 -0
  327. data/test/cases/relation/delete_all_test.rb +117 -0
  328. data/test/cases/relation/merging_test.rb +434 -0
  329. data/test/cases/relation/mutation_test.rb +145 -0
  330. data/test/cases/relation/or_test.rb +192 -0
  331. data/test/cases/relation/predicate_builder_test.rb +31 -0
  332. data/test/cases/relation/record_fetch_warning_test.rb +42 -0
  333. data/test/cases/relation/select_test.rb +67 -0
  334. data/test/cases/relation/update_all_test.rb +317 -0
  335. data/test/cases/relation/where_chain_test.rb +141 -0
  336. data/test/cases/relation/where_clause_test.rb +257 -0
  337. data/test/cases/relation/where_test.rb +429 -0
  338. data/test/cases/relation_test.rb +482 -0
  339. data/test/cases/relations_test.rb +2251 -0
  340. data/test/cases/reload_models_test.rb +26 -0
  341. data/test/cases/reserved_word_test.rb +141 -0
  342. data/test/cases/result_test.rb +141 -0
  343. data/test/cases/sanitize_test.rb +192 -0
  344. data/test/cases/schema_dumper_test.rb +550 -0
  345. data/test/cases/schema_loading_test.rb +53 -0
  346. data/test/cases/scoping/default_scoping_test.rb +569 -0
  347. data/test/cases/scoping/named_scoping_test.rb +649 -0
  348. data/test/cases/scoping/relation_scoping_test.rb +522 -0
  349. data/test/cases/secure_token_test.rb +47 -0
  350. data/test/cases/serialization_test.rb +106 -0
  351. data/test/cases/serialized_attribute_test.rb +455 -0
  352. data/test/cases/signed_id_test.rb +168 -0
  353. data/test/cases/statement_cache_test.rb +153 -0
  354. data/test/cases/statement_invalid_test.rb +42 -0
  355. data/test/cases/store_test.rb +320 -0
  356. data/test/cases/strict_loading_test.rb +473 -0
  357. data/test/cases/suppressor_test.rb +77 -0
  358. data/test/cases/tasks/database_tasks_test.rb +1526 -0
  359. data/test/cases/tasks/mysql_rake_test.rb +417 -0
  360. data/test/cases/tasks/postgresql_rake_test.rb +534 -0
  361. data/test/cases/tasks/sqlite_rake_test.rb +267 -0
  362. data/test/cases/test_case.rb +142 -0
  363. data/test/cases/test_databases_test.rb +79 -0
  364. data/test/cases/test_fixtures_test.rb +96 -0
  365. data/test/cases/time_precision_test.rb +125 -0
  366. data/test/cases/timestamp_test.rb +504 -0
  367. data/test/cases/touch_later_test.rb +123 -0
  368. data/test/cases/transaction_callbacks_test.rb +772 -0
  369. data/test/cases/transaction_isolation_test.rb +106 -0
  370. data/test/cases/transactions_test.rb +1285 -0
  371. data/test/cases/type/adapter_specific_registry_test.rb +145 -0
  372. data/test/cases/type/date_time_test.rb +16 -0
  373. data/test/cases/type/integer_test.rb +29 -0
  374. data/test/cases/type/string_test.rb +24 -0
  375. data/test/cases/type/time_test.rb +28 -0
  376. data/test/cases/type/type_map_test.rb +178 -0
  377. data/test/cases/type/unsigned_integer_test.rb +19 -0
  378. data/test/cases/type_test.rb +41 -0
  379. data/test/cases/types_test.rb +26 -0
  380. data/test/cases/unconnected_test.rb +46 -0
  381. data/test/cases/unsafe_raw_sql_test.rb +274 -0
  382. data/test/cases/validations/absence_validation_test.rb +75 -0
  383. data/test/cases/validations/association_validation_test.rb +99 -0
  384. data/test/cases/validations/i18n_generate_message_validation_test.rb +102 -0
  385. data/test/cases/validations/i18n_validation_test.rb +87 -0
  386. data/test/cases/validations/length_validation_test.rb +80 -0
  387. data/test/cases/validations/numericality_validation_test.rb +181 -0
  388. data/test/cases/validations/presence_validation_test.rb +105 -0
  389. data/test/cases/validations/uniqueness_validation_test.rb +618 -0
  390. data/test/cases/validations_repair_helper.rb +21 -0
  391. data/test/cases/validations_test.rb +229 -0
  392. data/test/cases/view_test.rb +222 -0
  393. data/test/cases/yaml_serialization_test.rb +166 -0
  394. data/test/config.example.yml +97 -0
  395. data/test/config.rb +7 -0
  396. data/test/config.yml +220 -0
  397. data/test/connections/native_ibm_db/connection.rb +44 -0
  398. data/test/fixtures/accounts.yml +29 -0
  399. data/test/fixtures/admin/accounts.yml +2 -0
  400. data/test/fixtures/admin/randomly_named_a9.yml +7 -0
  401. data/test/fixtures/admin/randomly_named_b0.yml +7 -0
  402. data/test/fixtures/admin/users.yml +10 -0
  403. data/test/fixtures/all/admin +1 -0
  404. data/test/fixtures/all/developers.yml +0 -0
  405. data/test/fixtures/all/namespaced/accounts.yml +2 -0
  406. data/test/fixtures/all/people.yml +0 -0
  407. data/test/fixtures/all/tasks.yml +0 -0
  408. data/test/fixtures/author_addresses.yml +11 -0
  409. data/test/fixtures/author_favorites.yml +4 -0
  410. data/test/fixtures/authors.yml +17 -0
  411. data/test/fixtures/bad_posts.yml +9 -0
  412. data/test/fixtures/binaries.yml +137 -0
  413. data/test/fixtures/books.yml +38 -0
  414. data/test/fixtures/bulbs.yml +5 -0
  415. data/test/fixtures/cars.yml +9 -0
  416. data/test/fixtures/categories/special_categories.yml +9 -0
  417. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
  418. data/test/fixtures/categories.yml +19 -0
  419. data/test/fixtures/categories_ordered.yml +7 -0
  420. data/test/fixtures/categories_posts.yml +34 -0
  421. data/test/fixtures/categorizations.yml +23 -0
  422. data/test/fixtures/citations.yml +5 -0
  423. data/test/fixtures/clubs.yml +8 -0
  424. data/test/fixtures/collections.yml +3 -0
  425. data/test/fixtures/colleges.yml +3 -0
  426. data/test/fixtures/comments.yml +72 -0
  427. data/test/fixtures/companies.yml +72 -0
  428. data/test/fixtures/computers.yml +12 -0
  429. data/test/fixtures/content.yml +3 -0
  430. data/test/fixtures/content_positions.yml +3 -0
  431. data/test/fixtures/courses.yml +8 -0
  432. data/test/fixtures/customers.yml +35 -0
  433. data/test/fixtures/dashboards.yml +6 -0
  434. data/test/fixtures/dead_parrots.yml +5 -0
  435. data/test/fixtures/developers.yml +22 -0
  436. data/test/fixtures/developers_projects.yml +17 -0
  437. data/test/fixtures/dog_lovers.yml +7 -0
  438. data/test/fixtures/dogs.yml +4 -0
  439. data/test/fixtures/doubloons.yml +3 -0
  440. data/test/fixtures/edges.yml +5 -0
  441. data/test/fixtures/entrants.yml +14 -0
  442. data/test/fixtures/essays.yml +16 -0
  443. data/test/fixtures/faces.yml +11 -0
  444. data/test/fixtures/fk_test_has_fk.yml +3 -0
  445. data/test/fixtures/fk_test_has_pk.yml +2 -0
  446. data/test/fixtures/friendships.yml +4 -0
  447. data/test/fixtures/funny_jokes.yml +10 -0
  448. data/test/fixtures/humans.yml +5 -0
  449. data/test/fixtures/interests.yml +33 -0
  450. data/test/fixtures/items.yml +3 -0
  451. data/test/fixtures/jobs.yml +7 -0
  452. data/test/fixtures/legacy_things.yml +3 -0
  453. data/test/fixtures/live_parrots.yml +4 -0
  454. data/test/fixtures/mateys.yml +4 -0
  455. data/test/fixtures/member_details.yml +8 -0
  456. data/test/fixtures/member_types.yml +6 -0
  457. data/test/fixtures/members.yml +11 -0
  458. data/test/fixtures/memberships.yml +41 -0
  459. data/test/fixtures/men.yml +5 -0
  460. data/test/fixtures/minimalistics.yml +5 -0
  461. data/test/fixtures/minivans.yml +5 -0
  462. data/test/fixtures/mixed_case_monkeys.yml +6 -0
  463. data/test/fixtures/mixins.yml +29 -0
  464. data/test/fixtures/movies.yml +7 -0
  465. data/test/fixtures/naked/yml/accounts.yml +1 -0
  466. data/test/fixtures/naked/yml/companies.yml +1 -0
  467. data/test/fixtures/naked/yml/courses.yml +1 -0
  468. data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
  469. data/test/fixtures/naked/yml/parrots.yml +3 -0
  470. data/test/fixtures/naked/yml/trees.yml +3 -0
  471. data/test/fixtures/nodes.yml +29 -0
  472. data/test/fixtures/organizations.yml +5 -0
  473. data/test/fixtures/other_books.yml +26 -0
  474. data/test/fixtures/other_comments.yml +6 -0
  475. data/test/fixtures/other_dogs.yml +2 -0
  476. data/test/fixtures/other_posts.yml +8 -0
  477. data/test/fixtures/other_topics.yml +42 -0
  478. data/test/fixtures/owners.yml +9 -0
  479. data/test/fixtures/parrots.yml +33 -0
  480. data/test/fixtures/parrots_pirates.yml +7 -0
  481. data/test/fixtures/people.yml +24 -0
  482. data/test/fixtures/peoples_treasures.yml +3 -0
  483. data/test/fixtures/pets.yml +19 -0
  484. data/test/fixtures/pirates.yml +15 -0
  485. data/test/fixtures/posts.yml +88 -0
  486. data/test/fixtures/price_estimates.yml +16 -0
  487. data/test/fixtures/products.yml +4 -0
  488. data/test/fixtures/projects.yml +7 -0
  489. data/test/fixtures/randomly_named_a9.yml +7 -0
  490. data/test/fixtures/ratings.yml +14 -0
  491. data/test/fixtures/readers.yml +17 -0
  492. data/test/fixtures/references.yml +17 -0
  493. data/test/fixtures/reserved_words/distinct.yml +5 -0
  494. data/test/fixtures/reserved_words/distinct_select.yml +11 -0
  495. data/test/fixtures/reserved_words/group.yml +14 -0
  496. data/test/fixtures/reserved_words/select.yml +8 -0
  497. data/test/fixtures/reserved_words/values.yml +7 -0
  498. data/test/fixtures/ships.yml +6 -0
  499. data/test/fixtures/speedometers.yml +8 -0
  500. data/test/fixtures/sponsors.yml +15 -0
  501. data/test/fixtures/strict_zines.yml +2 -0
  502. data/test/fixtures/string_key_objects.yml +7 -0
  503. data/test/fixtures/subscribers.yml +11 -0
  504. data/test/fixtures/subscriptions.yml +12 -0
  505. data/test/fixtures/taggings.yml +78 -0
  506. data/test/fixtures/tags.yml +11 -0
  507. data/test/fixtures/tasks.yml +7 -0
  508. data/test/fixtures/teapots.yml +3 -0
  509. data/test/fixtures/to_be_linked/accounts.yml +2 -0
  510. data/test/fixtures/to_be_linked/users.yml +10 -0
  511. data/test/fixtures/topics.yml +49 -0
  512. data/test/fixtures/toys.yml +14 -0
  513. data/test/fixtures/traffic_lights.yml +10 -0
  514. data/test/fixtures/treasures.yml +10 -0
  515. data/test/fixtures/trees.yml +3 -0
  516. data/test/fixtures/uuid_children.yml +3 -0
  517. data/test/fixtures/uuid_parents.yml +2 -0
  518. data/test/fixtures/variants.yml +4 -0
  519. data/test/fixtures/vegetables.yml +20 -0
  520. data/test/fixtures/vertices.yml +4 -0
  521. data/test/fixtures/warehouse-things.yml +3 -0
  522. data/test/fixtures/warehouse_things.yml +3 -0
  523. data/test/fixtures/zines.yml +5 -0
  524. data/test/ibm_db_test.rb +25 -0
  525. data/test/migrations/10_urban/9_add_expressions.rb +13 -0
  526. data/test/migrations/decimal/1_give_me_big_numbers.rb +17 -0
  527. data/test/migrations/magic/1_currencies_have_symbols.rb +13 -0
  528. data/test/migrations/missing/1000_people_have_middle_names.rb +11 -0
  529. data/test/migrations/missing/1_people_have_last_names.rb +11 -0
  530. data/test/migrations/missing/3_we_need_reminders.rb +14 -0
  531. data/test/migrations/missing/4_innocent_jointable.rb +14 -0
  532. data/test/migrations/rename/1_we_need_things.rb +13 -0
  533. data/test/migrations/rename/2_rename_things.rb +11 -0
  534. data/test/migrations/to_copy/1_people_have_hobbies.rb +11 -0
  535. data/test/migrations/to_copy/2_people_have_descriptions.rb +11 -0
  536. data/test/migrations/to_copy2/1_create_articles.rb +9 -0
  537. data/test/migrations/to_copy2/2_create_comments.rb +9 -0
  538. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +11 -0
  539. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +11 -0
  540. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +11 -0
  541. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +9 -0
  542. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +9 -0
  543. data/test/migrations/valid/1_valid_people_have_last_names.rb +11 -0
  544. data/test/migrations/valid/2_we_need_reminders.rb +14 -0
  545. data/test/migrations/valid/3_innocent_jointable.rb +14 -0
  546. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +11 -0
  547. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +14 -0
  548. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +14 -0
  549. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +11 -0
  550. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +14 -0
  551. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +14 -0
  552. data/test/migrations/version_check/20131219224947_migration_version_check.rb +10 -0
  553. data/test/models/account.rb +46 -0
  554. data/test/models/admin/account.rb +5 -0
  555. data/test/models/admin/randomly_named_c1.rb +9 -0
  556. data/test/models/admin/user.rb +48 -0
  557. data/test/models/admin.rb +7 -0
  558. data/test/models/aircraft.rb +7 -0
  559. data/test/models/arunit2_model.rb +5 -0
  560. data/test/models/author.rb +260 -0
  561. data/test/models/auto_id.rb +6 -0
  562. data/test/models/autoloadable/extra_firm.rb +4 -0
  563. data/test/models/binary.rb +4 -0
  564. data/test/models/binary_field.rb +6 -0
  565. data/test/models/bird.rb +24 -0
  566. data/test/models/book.rb +33 -0
  567. data/test/models/book_destroy_async.rb +24 -0
  568. data/test/models/boolean.rb +7 -0
  569. data/test/models/bulb.rb +61 -0
  570. data/test/models/cake_designer.rb +5 -0
  571. data/test/models/car.rb +36 -0
  572. data/test/models/carrier.rb +4 -0
  573. data/test/models/cart.rb +5 -0
  574. data/test/models/cat.rb +12 -0
  575. data/test/models/categorization.rb +21 -0
  576. data/test/models/category.rb +47 -0
  577. data/test/models/chef.rb +10 -0
  578. data/test/models/citation.rb +7 -0
  579. data/test/models/club.rb +28 -0
  580. data/test/models/college.rb +12 -0
  581. data/test/models/column.rb +5 -0
  582. data/test/models/column_name.rb +5 -0
  583. data/test/models/comment.rb +98 -0
  584. data/test/models/company.rb +226 -0
  585. data/test/models/company_in_module.rb +99 -0
  586. data/test/models/computer.rb +5 -0
  587. data/test/models/contact.rb +43 -0
  588. data/test/models/content.rb +42 -0
  589. data/test/models/contract.rb +38 -0
  590. data/test/models/country.rb +5 -0
  591. data/test/models/course.rb +8 -0
  592. data/test/models/customer.rb +85 -0
  593. data/test/models/customer_carrier.rb +16 -0
  594. data/test/models/dashboard.rb +5 -0
  595. data/test/models/default.rb +4 -0
  596. data/test/models/department.rb +6 -0
  597. data/test/models/destroy_async_parent.rb +15 -0
  598. data/test/models/destroy_async_parent_soft_delete.rb +20 -0
  599. data/test/models/developer.rb +341 -0
  600. data/test/models/dl_keyed_belongs_to.rb +13 -0
  601. data/test/models/dl_keyed_belongs_to_soft_delete.rb +19 -0
  602. data/test/models/dl_keyed_has_many.rb +5 -0
  603. data/test/models/dl_keyed_has_many_through.rb +5 -0
  604. data/test/models/dl_keyed_has_one.rb +5 -0
  605. data/test/models/dl_keyed_join.rb +10 -0
  606. data/test/models/dog.rb +7 -0
  607. data/test/models/dog_lover.rb +7 -0
  608. data/test/models/doubloon.rb +14 -0
  609. data/test/models/drink_designer.rb +20 -0
  610. data/test/models/edge.rb +7 -0
  611. data/test/models/electron.rb +7 -0
  612. data/test/models/engine.rb +5 -0
  613. data/test/models/entrant.rb +5 -0
  614. data/test/models/entry.rb +5 -0
  615. data/test/models/essay.rb +8 -0
  616. data/test/models/essay_destroy_async.rb +12 -0
  617. data/test/models/event.rb +5 -0
  618. data/test/models/eye.rb +39 -0
  619. data/test/models/face.rb +17 -0
  620. data/test/models/family.rb +6 -0
  621. data/test/models/family_tree.rb +6 -0
  622. data/test/models/friendship.rb +8 -0
  623. data/test/models/frog.rb +8 -0
  624. data/test/models/guid.rb +4 -0
  625. data/test/models/guitar.rb +6 -0
  626. data/test/models/hotel.rb +13 -0
  627. data/test/models/human.rb +39 -0
  628. data/test/models/image.rb +5 -0
  629. data/test/models/interest.rb +16 -0
  630. data/test/models/invoice.rb +6 -0
  631. data/test/models/item.rb +9 -0
  632. data/test/models/job.rb +9 -0
  633. data/test/models/joke.rb +9 -0
  634. data/test/models/keyboard.rb +5 -0
  635. data/test/models/legacy_thing.rb +5 -0
  636. data/test/models/lesson.rb +13 -0
  637. data/test/models/line_item.rb +5 -0
  638. data/test/models/liquid.rb +6 -0
  639. data/test/models/man.rb +11 -0
  640. data/test/models/matey.rb +6 -0
  641. data/test/models/measurement.rb +4 -0
  642. data/test/models/member.rb +45 -0
  643. data/test/models/member_detail.rb +11 -0
  644. data/test/models/member_type.rb +5 -0
  645. data/test/models/membership.rb +38 -0
  646. data/test/models/mentor.rb +5 -0
  647. data/test/models/message.rb +5 -0
  648. data/test/models/minimalistic.rb +4 -0
  649. data/test/models/minivan.rb +10 -0
  650. data/test/models/mixed_case_monkey.rb +5 -0
  651. data/test/models/mocktail_designer.rb +2 -0
  652. data/test/models/molecule.rb +8 -0
  653. data/test/models/mouse.rb +6 -0
  654. data/test/models/movie.rb +7 -0
  655. data/test/models/node.rb +7 -0
  656. data/test/models/non_primary_key.rb +4 -0
  657. data/test/models/notification.rb +5 -0
  658. data/test/models/numeric_data.rb +12 -0
  659. data/test/models/order.rb +6 -0
  660. data/test/models/organization.rb +16 -0
  661. data/test/models/other_dog.rb +7 -0
  662. data/test/models/owner.rb +39 -0
  663. data/test/models/parrot.rb +36 -0
  664. data/test/models/person.rb +147 -0
  665. data/test/models/personal_legacy_thing.rb +6 -0
  666. data/test/models/pet.rb +20 -0
  667. data/test/models/pet_treasure.rb +8 -0
  668. data/test/models/pirate.rb +116 -0
  669. data/test/models/possession.rb +5 -0
  670. data/test/models/post.rb +371 -0
  671. data/test/models/price_estimate.rb +14 -0
  672. data/test/models/professor.rb +7 -0
  673. data/test/models/project.rb +42 -0
  674. data/test/models/publisher/article.rb +6 -0
  675. data/test/models/publisher/magazine.rb +5 -0
  676. data/test/models/publisher.rb +4 -0
  677. data/test/models/randomly_named_c1.rb +5 -0
  678. data/test/models/rating.rb +8 -0
  679. data/test/models/reader.rb +25 -0
  680. data/test/models/recipe.rb +5 -0
  681. data/test/models/record.rb +4 -0
  682. data/test/models/reference.rb +25 -0
  683. data/test/models/reply.rb +79 -0
  684. data/test/models/room.rb +6 -0
  685. data/test/models/section.rb +6 -0
  686. data/test/models/seminar.rb +6 -0
  687. data/test/models/session.rb +6 -0
  688. data/test/models/ship.rb +42 -0
  689. data/test/models/ship_part.rb +10 -0
  690. data/test/models/shop.rb +19 -0
  691. data/test/models/shop_account.rb +8 -0
  692. data/test/models/speedometer.rb +8 -0
  693. data/test/models/sponsor.rb +10 -0
  694. data/test/models/squeak.rb +6 -0
  695. data/test/models/strict_zine.rb +7 -0
  696. data/test/models/string_key_object.rb +5 -0
  697. data/test/models/student.rb +6 -0
  698. data/test/models/subject.rb +16 -0
  699. data/test/models/subscriber.rb +10 -0
  700. data/test/models/subscription.rb +8 -0
  701. data/test/models/tag.rb +16 -0
  702. data/test/models/tagging.rb +20 -0
  703. data/test/models/task.rb +7 -0
  704. data/test/models/topic.rb +153 -0
  705. data/test/models/toy.rb +10 -0
  706. data/test/models/traffic_light.rb +6 -0
  707. data/test/models/treasure.rb +16 -0
  708. data/test/models/treaty.rb +5 -0
  709. data/test/models/tree.rb +5 -0
  710. data/test/models/tuning_peg.rb +6 -0
  711. data/test/models/tyre.rb +13 -0
  712. data/test/models/user.rb +22 -0
  713. data/test/models/uuid_child.rb +5 -0
  714. data/test/models/uuid_item.rb +8 -0
  715. data/test/models/uuid_parent.rb +5 -0
  716. data/test/models/vegetables.rb +33 -0
  717. data/test/models/vehicle.rb +7 -0
  718. data/test/models/vertex.rb +11 -0
  719. data/test/models/warehouse_thing.rb +7 -0
  720. data/test/models/wheel.rb +5 -0
  721. data/test/models/without_table.rb +5 -0
  722. data/test/models/zine.rb +5 -0
  723. data/test/schema/i5/ibm_db_specific_schema.rb +137 -0
  724. data/test/schema/ids/ibm_db_specific_schema.rb +140 -0
  725. data/test/schema/luw/ibm_db_specific_schema.rb +137 -0
  726. data/test/schema/mysql2_specific_schema.rb +82 -0
  727. data/test/schema/oracle_specific_schema.rb +38 -0
  728. data/test/schema/postgresql_specific_schema.rb +125 -0
  729. data/test/schema/schema.rb +1237 -0
  730. data/test/schema/schema.rb.original +1057 -0
  731. data/test/schema/sqlite_specific_schema.rb +11 -0
  732. data/test/schema/zOS/ibm_db_specific_schema.rb +208 -0
  733. data/test/support/config.rb +43 -0
  734. data/test/support/connection.rb +29 -0
  735. data/test/support/connection_helper.rb +16 -0
  736. data/test/support/ddl_helper.rb +10 -0
  737. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic.dump +0 -0
  738. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic_associations.dump +0 -0
  739. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic.dump +0 -0
  740. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic_associations.dump +0 -0
  741. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic.dump +0 -0
  742. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic_associations.dump +0 -0
  743. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic.dump +0 -0
  744. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic_associations.dump +0 -0
  745. data/test/support/marshal_compatibility_fixtures/legacy_6_0_record_mysql.dump +0 -0
  746. data/test/support/marshal_compatibility_fixtures/legacy_relation.dump +0 -0
  747. data/test/support/schema_dumping_helper.rb +22 -0
  748. data/test/support/stubs/strong_parameters.rb +40 -0
  749. data/test/support/yaml_compatibility_fixtures/rails_4_1.yml +22 -0
  750. data/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml +182 -0
  751. data/test/support/yaml_compatibility_fixtures/rails_v1_mysql.yml +206 -0
  752. data/test/support/yaml_compatibility_fixtures/rails_v2.yml +55 -0
  753. metadata +876 -0
@@ -0,0 +1,754 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "concurrent/atomic/count_down_latch"
5
+
6
+ module ActiveRecord
7
+ module ConnectionAdapters
8
+ class ConnectionPoolTest < ActiveRecord::TestCase
9
+ attr_reader :pool
10
+
11
+ def setup
12
+ super
13
+
14
+ # Keep a duplicate pool so we do not bother others
15
+ @db_config = ActiveRecord::Base.connection_pool.db_config
16
+ @pool_config = ActiveRecord::ConnectionAdapters::PoolConfig.new(ActiveRecord::Base, @db_config)
17
+ @pool = ConnectionPool.new(@pool_config)
18
+
19
+ if in_memory_db?
20
+ # Separate connections to an in-memory database create an entirely new database,
21
+ # with an empty schema etc, so we just stub out this schema on the fly.
22
+ @pool.with_connection do |connection|
23
+ connection.create_table :posts do |t|
24
+ t.integer :cololumn
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ teardown do
31
+ @pool.disconnect!
32
+ end
33
+
34
+ def active_connections(pool)
35
+ pool.connections.find_all(&:in_use?)
36
+ end
37
+
38
+ def test_checkout_after_close
39
+ connection = pool.connection
40
+ assert_predicate connection, :in_use?
41
+
42
+ connection.close
43
+ assert_not_predicate connection, :in_use?
44
+
45
+ assert_predicate pool.connection, :in_use?
46
+ end
47
+
48
+ def test_released_connection_moves_between_threads
49
+ thread_conn = nil
50
+
51
+ Thread.new {
52
+ pool.with_connection do |conn|
53
+ thread_conn = conn
54
+ end
55
+ }.join
56
+
57
+ assert thread_conn
58
+
59
+ Thread.new {
60
+ pool.with_connection do |conn|
61
+ assert_equal thread_conn, conn
62
+ end
63
+ }.join
64
+ end
65
+
66
+ def test_with_connection
67
+ assert_equal 0, active_connections(pool).size
68
+
69
+ main_thread = pool.connection
70
+ assert_equal 1, active_connections(pool).size
71
+
72
+ Thread.new {
73
+ pool.with_connection do |conn|
74
+ assert conn
75
+ assert_equal 2, active_connections(pool).size
76
+ end
77
+ assert_equal 1, active_connections(pool).size
78
+ }.join
79
+
80
+ main_thread.close
81
+ assert_equal 0, active_connections(pool).size
82
+ end
83
+
84
+ def test_active_connection_in_use
85
+ assert_not_predicate pool, :active_connection?
86
+ main_thread = pool.connection
87
+
88
+ assert_predicate pool, :active_connection?
89
+
90
+ main_thread.close
91
+
92
+ assert_not_predicate pool, :active_connection?
93
+ end
94
+
95
+ def test_full_pool_exception
96
+ @pool.checkout_timeout = 0.001 # no need to delay test suite by waiting the whole full default timeout
97
+ @pool.size.times { assert @pool.checkout }
98
+
99
+ assert_raises(ConnectionTimeoutError) do
100
+ @pool.checkout
101
+ end
102
+ end
103
+
104
+ def test_full_pool_blocks
105
+ cs = @pool.size.times.map { @pool.checkout }
106
+ t = Thread.new { @pool.checkout }
107
+
108
+ # make sure our thread is in the timeout section
109
+ Thread.pass until @pool.num_waiting_in_queue == 1
110
+
111
+ connection = cs.first
112
+ connection.close
113
+ assert_equal connection, t.join.value
114
+ end
115
+
116
+ def test_full_pool_blocking_shares_load_interlock
117
+ @pool.instance_variable_set(:@size, 1)
118
+
119
+ load_interlock_latch = Concurrent::CountDownLatch.new
120
+ connection_latch = Concurrent::CountDownLatch.new
121
+
122
+ able_to_get_connection = false
123
+ able_to_load = false
124
+
125
+ thread_with_load_interlock = Thread.new do
126
+ ActiveSupport::Dependencies.interlock.running do
127
+ load_interlock_latch.count_down
128
+ connection_latch.wait
129
+
130
+ @pool.with_connection do
131
+ able_to_get_connection = true
132
+ end
133
+ end
134
+ end
135
+
136
+ thread_with_last_connection = Thread.new do
137
+ @pool.with_connection do
138
+ connection_latch.count_down
139
+ load_interlock_latch.wait
140
+
141
+ ActiveSupport::Dependencies.interlock.loading do
142
+ able_to_load = true
143
+ end
144
+ end
145
+ end
146
+
147
+ thread_with_load_interlock.join
148
+ thread_with_last_connection.join
149
+
150
+ assert able_to_get_connection
151
+ assert able_to_load
152
+ end
153
+
154
+ def test_removing_releases_latch
155
+ cs = @pool.size.times.map { @pool.checkout }
156
+ t = Thread.new { @pool.checkout }
157
+
158
+ # make sure our thread is in the timeout section
159
+ Thread.pass until @pool.num_waiting_in_queue == 1
160
+
161
+ connection = cs.first
162
+ @pool.remove connection
163
+ assert_respond_to t.join.value, :execute
164
+ connection.close
165
+ end
166
+
167
+ def test_reap_and_active
168
+ @pool.checkout
169
+ @pool.checkout
170
+ @pool.checkout
171
+
172
+ connections = @pool.connections.dup
173
+
174
+ @pool.reap
175
+
176
+ assert_equal connections.length, @pool.connections.length
177
+ end
178
+
179
+ def test_reap_inactive
180
+ ready = Concurrent::CountDownLatch.new
181
+ @pool.checkout
182
+ child = Thread.new do
183
+ @pool.checkout
184
+ @pool.checkout
185
+ ready.count_down
186
+ Thread.stop
187
+ end
188
+ ready.wait
189
+
190
+ assert_equal 3, active_connections(@pool).size
191
+
192
+ child.terminate
193
+ child.join
194
+ @pool.reap
195
+
196
+ assert_equal 1, active_connections(@pool).size
197
+ ensure
198
+ @pool.connections.each { |conn| conn.close if conn.in_use? }
199
+ end
200
+
201
+ def test_idle_timeout_configuration
202
+ @pool.disconnect!
203
+
204
+ config = @db_config.configuration_hash.merge(idle_timeout: "0.02")
205
+ db_config = ActiveRecord::DatabaseConfigurations::HashConfig.new(@db_config.env_name, @db_config.name, config)
206
+
207
+ pool_config = ActiveRecord::ConnectionAdapters::PoolConfig.new(ActiveRecord::Base, db_config)
208
+ @pool = ConnectionPool.new(pool_config)
209
+ idle_conn = @pool.checkout
210
+ @pool.checkin(idle_conn)
211
+
212
+ idle_conn.instance_variable_set(
213
+ :@idle_since,
214
+ Concurrent.monotonic_time - 0.01
215
+ )
216
+
217
+ @pool.flush
218
+ assert_equal 1, @pool.connections.length
219
+
220
+ idle_conn.instance_variable_set(
221
+ :@idle_since,
222
+ Concurrent.monotonic_time - 0.02
223
+ )
224
+
225
+ @pool.flush
226
+ assert_equal 0, @pool.connections.length
227
+ end
228
+
229
+ def test_disable_flush
230
+ @pool.disconnect!
231
+
232
+ config = @db_config.configuration_hash.merge(idle_timeout: -5)
233
+ db_config = ActiveRecord::DatabaseConfigurations::HashConfig.new(@db_config.env_name, @db_config.name, config)
234
+ pool_config = ActiveRecord::ConnectionAdapters::PoolConfig.new(ActiveRecord::Base, db_config)
235
+ @pool = ConnectionPool.new(pool_config)
236
+ idle_conn = @pool.checkout
237
+ @pool.checkin(idle_conn)
238
+
239
+ idle_conn.instance_variable_set(
240
+ :@idle_since,
241
+ Concurrent.monotonic_time - 1
242
+ )
243
+
244
+ @pool.flush
245
+ assert_equal 1, @pool.connections.length
246
+ end
247
+
248
+ def test_flush
249
+ idle_conn = @pool.checkout
250
+ recent_conn = @pool.checkout
251
+ active_conn = @pool.checkout
252
+
253
+ @pool.checkin idle_conn
254
+ @pool.checkin recent_conn
255
+
256
+ assert_equal 3, @pool.connections.length
257
+
258
+ idle_conn.instance_variable_set(
259
+ :@idle_since,
260
+ Concurrent.monotonic_time - 1000
261
+ )
262
+
263
+ @pool.flush(30)
264
+
265
+ assert_equal 2, @pool.connections.length
266
+
267
+ assert_equal [recent_conn, active_conn].sort_by(&:__id__), @pool.connections.sort_by(&:__id__)
268
+ ensure
269
+ @pool.checkin active_conn
270
+ end
271
+
272
+ def test_flush_bang
273
+ idle_conn = @pool.checkout
274
+ recent_conn = @pool.checkout
275
+ active_conn = @pool.checkout
276
+ _dead_conn = Thread.new { @pool.checkout }.join
277
+
278
+ @pool.checkin idle_conn
279
+ @pool.checkin recent_conn
280
+
281
+ assert_equal 4, @pool.connections.length
282
+
283
+ def idle_conn.seconds_idle
284
+ 1000
285
+ end
286
+
287
+ @pool.flush!
288
+
289
+ assert_equal 1, @pool.connections.length
290
+
291
+ assert_equal [active_conn].sort_by(&:__id__), @pool.connections.sort_by(&:__id__)
292
+ ensure
293
+ @pool.checkin active_conn
294
+ end
295
+
296
+ def test_remove_connection
297
+ conn = @pool.checkout
298
+ assert_predicate conn, :in_use?
299
+
300
+ length = @pool.connections.length
301
+ @pool.remove conn
302
+ assert_predicate conn, :in_use?
303
+ assert_equal(length - 1, @pool.connections.length)
304
+ ensure
305
+ conn.close
306
+ end
307
+
308
+ def test_remove_connection_for_thread
309
+ conn = @pool.connection
310
+ @pool.remove conn
311
+ assert_not_equal(conn, @pool.connection)
312
+ ensure
313
+ conn.close if conn
314
+ end
315
+
316
+ def test_active_connection?
317
+ assert_not_predicate @pool, :active_connection?
318
+ assert @pool.connection
319
+ assert_predicate @pool, :active_connection?
320
+ @pool.release_connection
321
+ assert_not_predicate @pool, :active_connection?
322
+ end
323
+
324
+ def test_checkout_behaviour
325
+ pool = ConnectionPool.new(@pool_config)
326
+ main_connection = pool.connection
327
+ assert_not_nil main_connection
328
+ threads = []
329
+ 4.times do |i|
330
+ threads << Thread.new(i) do
331
+ thread_connection = pool.connection
332
+ assert_not_nil thread_connection
333
+ thread_connection.close
334
+ end
335
+ end
336
+
337
+ threads.each(&:join)
338
+
339
+ Thread.new do
340
+ assert pool.connection
341
+ pool.connection.close
342
+ end.join
343
+ end
344
+
345
+ def test_checkout_order_is_lifo
346
+ conn1 = @pool.checkout
347
+ conn2 = @pool.checkout
348
+ @pool.checkin conn1
349
+ @pool.checkin conn2
350
+ assert_equal [conn2, conn1], 2.times.map { @pool.checkout }
351
+ end
352
+
353
+ # The connection pool is "fair" if threads waiting for
354
+ # connections receive them in the order in which they began
355
+ # waiting. This ensures that we don't timeout one HTTP request
356
+ # even while well under capacity in a multi-threaded environment
357
+ # such as a Java servlet container.
358
+ #
359
+ # We don't need strict fairness: if two connections become
360
+ # available at the same time, it's fine if two threads that were
361
+ # waiting acquire the connections out of order.
362
+ #
363
+ # Thus this test prepares waiting threads and then trickles in
364
+ # available connections slowly, ensuring the wakeup order is
365
+ # correct in this case.
366
+ def test_checkout_fairness
367
+ @pool.instance_variable_set(:@size, 10)
368
+ expected = (1..@pool.size).to_a.freeze
369
+ # check out all connections so our threads start out waiting
370
+ conns = expected.map { @pool.checkout }
371
+ mutex = Mutex.new
372
+ order = []
373
+ errors = []
374
+
375
+ threads = expected.map do |i|
376
+ t = Thread.new {
377
+ begin
378
+ @pool.checkout # never checked back in
379
+ mutex.synchronize { order << i }
380
+ rescue => e
381
+ mutex.synchronize { errors << e }
382
+ end
383
+ }
384
+ Thread.pass until @pool.num_waiting_in_queue == i
385
+ t
386
+ end
387
+
388
+ # this should wake up the waiting threads one by one in order
389
+ conns.each { |conn| @pool.checkin(conn); sleep 0.1 }
390
+
391
+ threads.each(&:join)
392
+
393
+ raise errors.first if errors.any?
394
+
395
+ assert_equal(expected, order)
396
+ end
397
+
398
+ # As mentioned in #test_checkout_fairness, we don't care about
399
+ # strict fairness. This test creates two groups of threads:
400
+ # group1 whose members all start waiting before any thread in
401
+ # group2. Enough connections are checked in to wakeup all
402
+ # group1 threads, and the fact that only group1 and no group2
403
+ # threads acquired a connection is enforced.
404
+ def test_checkout_fairness_by_group
405
+ @pool.instance_variable_set(:@size, 10)
406
+ # take all the connections
407
+ conns = (1..10).map { @pool.checkout }
408
+ mutex = Mutex.new
409
+ successes = [] # threads that successfully got a connection
410
+ errors = []
411
+
412
+ make_thread = proc do |i|
413
+ t = Thread.new {
414
+ begin
415
+ @pool.checkout # never checked back in
416
+ mutex.synchronize { successes << i }
417
+ rescue => e
418
+ mutex.synchronize { errors << e }
419
+ end
420
+ }
421
+ Thread.pass until @pool.num_waiting_in_queue == i
422
+ t
423
+ end
424
+
425
+ # all group1 threads start waiting before any in group2
426
+ group1 = (1..5).map(&make_thread)
427
+ group2 = (6..10).map(&make_thread)
428
+
429
+ # checkin n connections back to the pool
430
+ checkin = proc do |n|
431
+ n.times do
432
+ c = conns.pop
433
+ @pool.checkin(c)
434
+ end
435
+ end
436
+
437
+ checkin.call(group1.size) # should wake up all group1
438
+
439
+ loop do
440
+ sleep 0.1
441
+ break if mutex.synchronize { (successes.size + errors.size) == group1.size }
442
+ end
443
+
444
+ winners = mutex.synchronize { successes.dup }
445
+ checkin.call(group2.size) # should wake up everyone remaining
446
+
447
+ group1.each(&:join)
448
+ group2.each(&:join)
449
+
450
+ assert_equal((1..group1.size).to_a, winners.sort)
451
+
452
+ if errors.any?
453
+ raise errors.first
454
+ end
455
+ end
456
+
457
+ def test_automatic_reconnect_restores_after_disconnect
458
+ pool = ConnectionPool.new(@pool_config)
459
+ assert pool.automatic_reconnect
460
+ assert pool.connection
461
+
462
+ pool.disconnect!
463
+ assert pool.connection
464
+ end
465
+
466
+ def test_automatic_reconnect_can_be_disabled
467
+ pool = ConnectionPool.new(@pool_config)
468
+ pool.disconnect!
469
+ pool.automatic_reconnect = false
470
+
471
+ assert_raises(ConnectionNotEstablished) do
472
+ pool.connection
473
+ end
474
+
475
+ assert_raises(ConnectionNotEstablished) do
476
+ pool.with_connection
477
+ end
478
+ end
479
+
480
+ def test_pool_sets_connection_visitor
481
+ assert @pool.connection.visitor.is_a?(Arel::Visitors::ToSql)
482
+ end
483
+
484
+ # make sure exceptions are thrown when establish_connection
485
+ # is called with an anonymous class
486
+ def test_anonymous_class_exception
487
+ anonymous = Class.new(ActiveRecord::Base)
488
+
489
+ assert_raises(RuntimeError) do
490
+ anonymous.establish_connection
491
+ end
492
+ end
493
+
494
+ class ConnectionTestModel < ActiveRecord::Base
495
+ self.abstract_class = true
496
+ end
497
+
498
+ def test_connection_notification_is_called
499
+ payloads = []
500
+ subscription = ActiveSupport::Notifications.subscribe("!connection.active_record") do |name, started, finished, unique_id, payload|
501
+ payloads << payload
502
+ end
503
+ ConnectionTestModel.establish_connection :arunit
504
+
505
+ assert_equal [:config, :shard, :spec_name], payloads[0].keys.sort
506
+ assert_equal "ActiveRecord::ConnectionAdapters::ConnectionPoolTest::ConnectionTestModel", payloads[0][:spec_name]
507
+ assert_equal ActiveRecord::Base.default_shard, payloads[0][:shard]
508
+ ensure
509
+ ActiveSupport::Notifications.unsubscribe(subscription) if subscription
510
+ end
511
+
512
+ def test_connection_notification_is_called_for_shard
513
+ payloads = []
514
+ subscription = ActiveSupport::Notifications.subscribe("!connection.active_record") do |name, started, finished, unique_id, payload|
515
+ payloads << payload
516
+ end
517
+ ConnectionTestModel.connects_to shards: { shard_two: { writing: :arunit } }
518
+
519
+ assert_equal [:config, :shard, :spec_name], payloads[0].keys.sort
520
+ assert_equal "ActiveRecord::ConnectionAdapters::ConnectionPoolTest::ConnectionTestModel", payloads[0][:spec_name]
521
+ assert_equal :shard_two, payloads[0][:shard]
522
+ ensure
523
+ ActiveSupport::Notifications.unsubscribe(subscription) if subscription
524
+ end
525
+
526
+ def test_pool_sets_connection_schema_cache
527
+ connection = pool.checkout
528
+ schema_cache = SchemaCache.new connection
529
+ schema_cache.add(:posts)
530
+ pool.schema_cache = schema_cache
531
+
532
+ pool.with_connection do |conn|
533
+ assert_equal pool.schema_cache.size, conn.schema_cache.size
534
+ assert_same pool.schema_cache.columns(:posts), conn.schema_cache.columns(:posts)
535
+ end
536
+
537
+ pool.checkin connection
538
+ end
539
+
540
+ def test_concurrent_connection_establishment
541
+ assert_operator @pool.connections.size, :<=, 1
542
+
543
+ all_threads_in_new_connection = Concurrent::CountDownLatch.new(@pool.size - @pool.connections.size)
544
+ all_go = Concurrent::CountDownLatch.new
545
+
546
+ @pool.singleton_class.class_eval do
547
+ define_method(:new_connection) do
548
+ all_threads_in_new_connection.count_down
549
+ all_go.wait
550
+ super()
551
+ end
552
+ end
553
+
554
+ connecting_threads = []
555
+ @pool.size.times do
556
+ connecting_threads << Thread.new { @pool.checkout }
557
+ end
558
+
559
+ begin
560
+ Timeout.timeout(5) do
561
+ # the kernel of the whole test is here, everything else is just scaffolding,
562
+ # this latch will not be released unless conn. pool allows for concurrent
563
+ # connection creation
564
+ all_threads_in_new_connection.wait
565
+ end
566
+ rescue Timeout::Error
567
+ flunk "pool unable to establish connections concurrently or implementation has " \
568
+ "changed, this test then needs to patch a different :new_connection method"
569
+ ensure
570
+ # clean up the threads
571
+ all_go.count_down
572
+ connecting_threads.map(&:join)
573
+ end
574
+ end
575
+
576
+ def test_non_bang_disconnect_and_clear_reloadable_connections_throw_exception_if_threads_dont_return_their_conns
577
+ Thread.report_on_exception, original_report_on_exception = false, Thread.report_on_exception
578
+ @pool.checkout_timeout = 0.001 # no need to delay test suite by waiting the whole full default timeout
579
+ [:disconnect, :clear_reloadable_connections].each do |group_action_method|
580
+ @pool.with_connection do |connection|
581
+ assert_raises(ExclusiveConnectionTimeoutError) do
582
+ Thread.new { @pool.public_send(group_action_method) }.join
583
+ end
584
+ end
585
+ end
586
+ ensure
587
+ Thread.report_on_exception = original_report_on_exception
588
+ end
589
+
590
+ def test_disconnect_and_clear_reloadable_connections_attempt_to_wait_for_threads_to_return_their_conns
591
+ [:disconnect, :disconnect!, :clear_reloadable_connections, :clear_reloadable_connections!].each do |group_action_method|
592
+ thread = timed_join_result = nil
593
+ @pool.with_connection do |connection|
594
+ thread = Thread.new { @pool.send(group_action_method) }
595
+
596
+ # give the other `thread` some time to get stuck in `group_action_method`
597
+ timed_join_result = thread.join(0.3)
598
+ # thread.join # => `nil` means the other thread hasn't finished running and is still waiting for us to
599
+ # release our connection
600
+ assert_nil timed_join_result
601
+
602
+ # assert that since this is within default timeout our connection hasn't been forcefully taken away from us
603
+ assert_predicate @pool, :active_connection?
604
+ end
605
+ ensure
606
+ thread.join if thread && !timed_join_result # clean up the other thread
607
+ end
608
+ end
609
+
610
+ def test_bang_versions_of_disconnect_and_clear_reloadable_connections_if_unable_to_acquire_all_connections_proceed_anyway
611
+ @pool.checkout_timeout = 0.001 # no need to delay test suite by waiting the whole full default timeout
612
+ [:disconnect!, :clear_reloadable_connections!].each do |group_action_method|
613
+ @pool.with_connection do |connection|
614
+ Thread.new { @pool.send(group_action_method) }.join
615
+ # assert connection has been forcefully taken away from us
616
+ assert_not_predicate @pool, :active_connection?
617
+
618
+ # make a new connection for with_connection to clean up
619
+ @pool.connection
620
+ end
621
+ end
622
+ end
623
+
624
+ def test_disconnect_and_clear_reloadable_connections_are_able_to_preempt_other_waiting_threads
625
+ with_single_connection_pool do |pool|
626
+ [:disconnect, :disconnect!, :clear_reloadable_connections, :clear_reloadable_connections!].each do |group_action_method|
627
+ conn = pool.connection # drain the only available connection
628
+ second_thread_done = Concurrent::Event.new
629
+
630
+ begin
631
+ # create a first_thread and let it get into the FIFO queue first
632
+ first_thread = Thread.new do
633
+ pool.with_connection { second_thread_done.wait }
634
+ end
635
+
636
+ # wait for first_thread to get in queue
637
+ Thread.pass until pool.num_waiting_in_queue == 1
638
+
639
+ # create a different, later thread, that will attempt to do a "group action",
640
+ # but because of the group action semantics it should be able to preempt the
641
+ # first_thread when a connection is made available
642
+ second_thread = Thread.new do
643
+ pool.send(group_action_method)
644
+ second_thread_done.set
645
+ end
646
+
647
+ # wait for second_thread to get in queue
648
+ Thread.pass until pool.num_waiting_in_queue == 2
649
+
650
+ # return the only available connection
651
+ pool.checkin(conn)
652
+
653
+ # if the second_thread is not able to preempt the first_thread,
654
+ # they will temporarily (until either of them timeouts with ConnectionTimeoutError)
655
+ # deadlock and a join(2) timeout will be reached
656
+ assert second_thread.join(2), "#{group_action_method} is not able to preempt other waiting threads"
657
+
658
+ ensure
659
+ # post test clean up
660
+ failed = !second_thread_done.set?
661
+
662
+ if failed
663
+ second_thread_done.set
664
+
665
+ first_thread.join(2)
666
+ second_thread.join(2)
667
+ end
668
+
669
+ first_thread.join(10) || raise("first_thread got stuck")
670
+ second_thread.join(10) || raise("second_thread got stuck")
671
+ end
672
+ end
673
+ end
674
+ end
675
+
676
+ def test_clear_reloadable_connections_creates_new_connections_for_waiting_threads_if_necessary
677
+ with_single_connection_pool do |pool|
678
+ conn = pool.connection # drain the only available connection
679
+ def conn.requires_reloading? # make sure it gets removed from the pool by clear_reloadable_connections
680
+ true
681
+ end
682
+
683
+ stuck_thread = Thread.new do
684
+ pool.with_connection { }
685
+ end
686
+
687
+ # wait for stuck_thread to get in queue
688
+ Thread.pass until pool.num_waiting_in_queue == 1
689
+
690
+ pool.clear_reloadable_connections
691
+
692
+ unless stuck_thread.join(2)
693
+ flunk "clear_reloadable_connections must not let other connection waiting threads get stuck in queue"
694
+ end
695
+
696
+ assert_equal 0, pool.num_waiting_in_queue
697
+ end
698
+ end
699
+
700
+ def test_connection_pool_stat
701
+ with_single_connection_pool do |pool|
702
+ pool.with_connection do |connection|
703
+ stats = pool.stat
704
+ assert_equal({ size: 1, connections: 1, busy: 1, dead: 0, idle: 0, waiting: 0, checkout_timeout: 5 }, stats)
705
+ end
706
+
707
+ stats = pool.stat
708
+ assert_equal({ size: 1, connections: 1, busy: 0, dead: 0, idle: 1, waiting: 0, checkout_timeout: 5 }, stats)
709
+
710
+ Thread.new do
711
+ pool.checkout
712
+ Thread.current.kill
713
+ end.join
714
+
715
+ stats = pool.stat
716
+ assert_equal({ size: 1, connections: 1, busy: 0, dead: 1, idle: 0, waiting: 0, checkout_timeout: 5 }, stats)
717
+ end
718
+ end
719
+
720
+ def test_public_connections_access_threadsafe
721
+ _conn1 = @pool.checkout
722
+ conn2 = @pool.checkout
723
+
724
+ connections = @pool.connections
725
+ found_conn = nil
726
+
727
+ # Without assuming too much about implementation
728
+ # details make sure that a concurrent change to
729
+ # the pool is thread-safe.
730
+ connections.each_index do |idx|
731
+ if connections[idx] == conn2
732
+ Thread.new do
733
+ @pool.remove(conn2)
734
+ end.join
735
+ end
736
+ found_conn = connections[idx]
737
+ end
738
+
739
+ assert_not_nil found_conn
740
+ end
741
+
742
+ private
743
+ def with_single_connection_pool
744
+ config = @db_config.configuration_hash.merge(pool: 1)
745
+ db_config = ActiveRecord::DatabaseConfigurations::HashConfig.new("arunit", "primary", config)
746
+ pool_config = ActiveRecord::ConnectionAdapters::PoolConfig.new(ActiveRecord::Base, db_config)
747
+
748
+ yield(pool = ConnectionPool.new(pool_config))
749
+ ensure
750
+ pool.disconnect! if pool
751
+ end
752
+ end
753
+ end
754
+ end