@@ -271,6 +271,8 @@ def start_beef_server
271271 # Generate a token for the server to respond with
272272 BeEF ::Core ::Crypto ::api_token
273273
274+ disconnect_all_active_record!
275+
274276 # Initiate server start-up
275277 BeEF ::API ::Registrar . instance . fire ( BeEF ::API ::Server , 'pre_http_start' , http_hook_server )
276278 pid = fork do
@@ -322,4 +324,60 @@ def stop_beef_server(pid)
322324 pid = nil
323325 end
324326
327+ end
328+
329+ # -------------------------------------------------------------------
330+ # ActiveRecord connection snapshot/restore helpers (test isolation)
331+ # Some specs disconnect ActiveRecord (fork safety), destroying the SQLite in-memory DB.
332+ # These helpers restore it for later specs.
333+ # -------------------------------------------------------------------
334+ module SpecActiveRecordConnection
335+ module_function
336+
337+ def snapshot
338+ # Capture the current AR connection configuration hash if possible.
339+ if ActiveRecord ::Base . respond_to? ( :connection_db_config ) && ActiveRecord ::Base . connection_db_config
340+ ActiveRecord ::Base . connection_db_config . configuration_hash
341+ else
342+ ActiveRecord ::Base . connection_config
343+ end
344+ rescue StandardError
345+ nil
346+ end
347+
348+ def restore! ( config_hash )
349+ # Ensure we don't leave AR disconnected for subsequent specs.
350+ begin
351+ handler = ActiveRecord ::Base . connection_handler
352+ if handler . respond_to? ( :connection_pool_list )
353+ handler . connection_pool_list . each { |pool | pool . disconnect! }
354+ elsif handler . respond_to? ( :connection_pools )
355+ handler . connection_pools . each_value { |pool | pool . disconnect! }
356+ else
357+ ActiveRecord ::Base . connection_pool . disconnect!
358+ end
359+ rescue StandardError
360+ # ignore
361+ end
362+
363+ if config_hash
364+ OTR ::ActiveRecord . configure_from_hash! ( config_hash )
365+ else
366+ # Fallback to suite default
367+ OTR ::ActiveRecord . configure_from_hash! ( adapter : 'sqlite3' , database : ':memory:' )
368+ end
369+
370+ if Gem . loaded_specs [ 'otr-activerecord' ] . version > Gem ::Version . create ( '1.4.2' )
371+ OTR ::ActiveRecord . establish_connection!
372+ end
373+ ActiveRecord ::Schema . verbose = false
374+
375+ # Run migrations if the restored DB is empty/outdated
376+ ActiveRecord ::Migration . verbose = false
377+ ActiveRecord ::Migrator . migrations_paths = [ File . join ( 'core' , 'main' , 'ar-migrations' ) ]
378+ context = ActiveRecord ::MigrationContext . new ( ActiveRecord ::Migrator . migrations_paths )
379+ if context . needs_migration?
380+ ActiveRecord ::Migrator . new ( :up , context . migrations , context . schema_migration , context . internal_metadata ) . migrate
381+ end
382+ end
325383end
0 commit comments