From 22b4d37480ff93719acd196b0e41469c87805846 Mon Sep 17 00:00:00 2001 From: Shinichi Maeshima Date: Mon, 22 Jun 2026 19:00:14 +0900 Subject: [PATCH] Fix flaky tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Fix an order-dependent PostgreSQL test failure caused by the `upsert_all` test leaving the `users` primary key sequence out of sync. ## Details The `upsert_all with different value formats works correctly` test inserts rows with explicit primary keys: ```ruby { id: 1, ... } { id: 2, ... } { id: 3, ... } ``` On PostgreSQL, inserting or upserting rows with explicit IDs does not advance the table’s primary key sequence. As a result, later tests that create `User` records without specifying an ID can receive an already-used ID from the sequence, causing errors like: ```text PG::UniqueViolation: duplicate key value violates unique constraint "users_pkey" ``` This failure depends on randomized test order. In the failing CI run, the `upsert_all` test ran before tests that performed normal `User.create!` / `save!` calls. ## Fix Wrap the `upsert_all` test in an `ensure` block and reset the primary key sequence afterward when the adapter supports it: ```ruby User.connection.reset_pk_sequence!(User.table_name) if User.connection.respond_to?(:reset_pk_sequence!) ``` Using `ensure` makes sure the sequence is reset even if the test fails partway through, preventing this test from leaking database state into later tests. ## Verification Reproduced with PostgreSQL using the CI seed: ``` POSTGRES_USER=postgres \ POSTGRES_PASSWORD=postgres \ DB=postgresql \ bundle exec ruby -w -Ilib:test test/activerecord_test.rb --seed 40802 ``` result example ``` 1) Error: ActiveRecordTest#test_0028_stores multiple value passed passed to new: ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "users_pkey" DETAIL: Key (id)=(2) already exists. # … snip … 2) Error: ActiveRecordTest#test_0044_does not change by the practical same value: ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "users_pkey" DETAIL: Key (id)=(3) already exists. # … snip … ``` --- test/activerecord_test.rb | 46 +++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/test/activerecord_test.rb b/test/activerecord_test.rb index 5fdc213..a1d6f5d 100644 --- a/test/activerecord_test.rb +++ b/test/activerecord_test.rb @@ -834,26 +834,30 @@ class AdminUser < User it 'upsert_all with different value formats works correctly' do User.delete_all - User.upsert_all([ - { id: 1, sex: :male, status: 1 }, - { id: 2, sex: 'female', status: :blocked } - ]) - - User.upsert_all([ - { id: 1, sex: 'male', status: :active }, - { id: 3, sex: :female, status: 2 } - ]) - - users = User.order(:id).to_a - expect(users.size).must_equal 3 - - expect(users[0].sex).must_equal 'male' - expect(users[0].status).must_equal 'active' - - expect(users[1].sex).must_equal 'female' - expect(users[1].status).must_equal 'blocked' - - expect(users[2].sex).must_equal 'female' - expect(users[2].status).must_equal 'blocked' + begin + User.upsert_all([ + { id: 1, sex: :male, status: 1 }, + { id: 2, sex: 'female', status: :blocked } + ]) + + User.upsert_all([ + { id: 1, sex: 'male', status: :active }, + { id: 3, sex: :female, status: 2 } + ]) + + users = User.order(:id).to_a + expect(users.size).must_equal 3 + + expect(users[0].sex).must_equal 'male' + expect(users[0].status).must_equal 'active' + + expect(users[1].sex).must_equal 'female' + expect(users[1].status).must_equal 'blocked' + + expect(users[2].sex).must_equal 'female' + expect(users[2].status).must_equal 'blocked' + ensure + User.connection.reset_pk_sequence!(User.table_name) if User.connection.respond_to?(:reset_pk_sequence!) + end end end