Run specs in randomized order#284
Merged
yahonda merged 6 commits intorsim:masterfrom May 6, 2026
Merged
Conversation
Configure RSpec to randomize example order and seed Ruby's RNG from config.seed so any non-RSpec randomness is reproducible from the printed seed. Remove the unused RSpec 1.x-era spec/spec.opts (not loaded by RSpec::Core::RakeTask, and its --loadby mtime --reverse ordering would conflict with random order). Update the CONTRIBUTING.md banner example to match RSpec's actual start-of-run output. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The "Numeric" shared examples have three tests that share a single package variable (numeric_var): one reads the default value, two others assign a value via the setter. When examples run in defined order the default-value test runs first and observes the initial default, but in any other order it observes the previously-assigned value because Oracle keeps package variable state at session scope across tests. CREATE OR REPLACE PACKAGE alone does not clear that session state when the spec is unchanged, so call DBMS_SESSION.RESET_PACKAGE in before(:each) to force re-initialization to defaults before every example. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The :column => nil select example mutated the last entry of the @Employees array, which is built once in before(:all) and shared with every other example in the View describe. When the example ran before any of the "should insert many records ..." examples, the later tests compared their actual results against an @Employees array whose last element had been overwritten with employee_id+1 and hire_date: nil, producing spurious failures. Build the modified employee with merge so the underlying @Employees array stays untouched. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The ActiveRecord connection describe block bound the global plsql schema to ActiveRecord via plsql.activerecord_class= in before(:each) but never reset it. Because oci_connection.ora_date_to_ruby_date consults plsql.default_timezone (a singleton on the global plsql schema), and that accessor returns ActiveRecord.default_timezone when an AR class is bound, every subsequent test that read DATE values back through any OCI connection saw UTC values instead of the local-time defaults. The connection-level "should parse PL/SQL procedure call ... and get bind parameter value" example then asserted equality between a local Time and the UTC round-trip and failed. Reset plsql.activerecord_class to nil in after(:all) so other describe blocks observe a fresh, non-AR-bound plsql singleton. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The "using Oracle 9.2" nested describe inside "Function with table indexed by binary integer parameter" called plsql.connect! in its before(:all) before checking the database version and skipping on 18c or higher. That call replaced the outer describe's connection with a fresh session; when skip fired the nested after(:all) was suppressed, but the outer after(:all) still ran on the new session. Its drop_session_ruby_temporary_tables therefore filtered by the new session_id and never touched the outer session's ruby_<outer_sid>_<package_id>_* tables, while the outer session itself was now leaked. Once that orphan session held its temporary tables in use, any later attempt to drop_all_ruby_temporary_tables hit ORA-14452. Drop the redundant plsql.connect! and check the version using the outer describe's existing connection. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Named Schema describe ended its after(:all) with plsql.connection.logoff, which closes the underlying connection but leaves plsql.connection pointing at the now-closed wrapper. Any later example that attempted plsql.logoff if plsql.connection (for example the after(:each) in "Connection with connect!") then followed the stale reference into rollback on a dead OCI8 handle and raised "OCI8 was already closed". Surfaced under random order when "Named Schema" ran before "Connection with connect!" — the "should not connect with wrong port number" example never replaced the stale connection (its connect! is meant to fail), so its after(:each) was the one that hit the dead handle. Use plsql.logoff so the schema's setter clears @connection to nil. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
CONTRIBUTING.mdalready documents that specs run in randomized order with a reproducible seed, but the configuration to make that true was missing — RSpec ran in:definedorder. This PR enables random ordering and fixes the four order-dependent specs that the change surfaces, so the suite is stable under randomization.The five commits are intentionally split for review:
Run specs in randomized order — set
config.order = :randomandKernel.srand config.seedinspec/spec_helper.rb; remove the unused RSpec 1.x-eraspec/spec.opts(its--loadby mtime --reversedirectly contradicts random order); align the CONTRIBUTING.md banner example with RSpec's actual start-of-run output.Reset package state between Numeric variable examples — the "Numeric" shared examples in
variable_spec.rbsharednumeric_varacross three examples; with random order the default-value check could observe a previously-assigned value. AddedDBMS_SESSION.RESET_PACKAGEinbefore(:each)so every example re-initializes to defaults.Avoid mutating shared @Employees in view spec — the
:column => nil conditionexample inview_spec.rbmutated@employees.lastin place, leaving the array — built once inbefore(:all)— corrupted for any subsequent example. Switched tomergeso the shared array stays intact.Reset plsql.activerecord_class after ActiveRecord connection examples —
schema_spec.rb's ActiveRecord describe bound the global plsql singleton to AR viabefore(:each)but never reset it. Becauseoci_connection.ora_date_to_ruby_dateconsultsplsql.default_timezone(a singleton) and that accessor returnsActiveRecord.default_timezone(:utcin modern Rails) when an AR class is bound, every later test reading DATE values back through any OCI connection saw UTC. Addedafter(:all) { plsql.activerecord_class = nil }.Avoid orphaning the outer session in the Oracle 9.2 nested describe — the nested "using Oracle 9.2" describe in
procedure_spec.rbcalledplsql.connect!again in itsbefore(:all)before the version-skip check. That replaced the outer describe's connection with a fresh session; whenskipfired the nestedafter(:all)was suppressed, but the outerafter(:all)still ran on the new session — itsdrop_session_ruby_temporary_tablesfiltered by the newsession_idand never touched the outer session'sruby_<outer_sid>_<package_id>_*tables, while the outer session itself was leaked. Once that orphan held its temporary tables in use, any laterdrop_all_ruby_temporary_tableshit ORA-14452. Dropped the redundantplsql.connect!; the version check now uses the outer describe's existing connection.Test plan