From ff6439c14b3c8f8d675ddfd2c35226333f561635 Mon Sep 17 00:00:00 2001 From: Kev Kloss Date: Tue, 30 Sep 2025 15:30:23 +0200 Subject: [PATCH 1/6] Add a test for Gitlab::Seeder.parallel_each This adds a test for the `Gitlab::Seeder.parallel_each` function, which is used by seeders to parallelize insert opertation across threads. When we added this helper function, we didn't add specs for it. This ensures that the function works as expected. --- spec/lib/gitlab/seeder_spec.rb | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/spec/lib/gitlab/seeder_spec.rb b/spec/lib/gitlab/seeder_spec.rb index d2fd8948433d78..1b8caffd9e4674 100644 --- a/spec/lib/gitlab/seeder_spec.rb +++ b/spec/lib/gitlab/seeder_spec.rb @@ -96,4 +96,36 @@ end end end + + describe '.parallel_each' do + let(:test_array) { [1, 2, 3] } + + before do + allow(Gitlab::GitalyClient).to receive(:clear_stubs!) + end + + after do + # Ensure @parallel flag is reset after each test + described_class.instance_variable_set(:@parallel, false) + end + + it 'clear Gitaly stubs and then processes the items in parallel' do + expect(Gitlab::GitalyClient).to receive(:clear_stubs!) + # we're communicating across forks + reader, writer = IO.pipe + described_class.parallel_each(test_array) { |item| writer.write(item.to_s) } + writer.close + + expect(reader.read.split('').map(&:to_i).sort).to eq(test_array) + ensure + reader.close + end + + it 'prevents nested calls by raising an error' do + described_class.parallel_each([1]) do + expect { described_class.parallel_each([2]) } + .to raise_error('Nested Gitlab::Seeder.parallel_each calls are not allowed.') + end + end + end end -- GitLab From fdc0d92bc35d84a8799ac8e63ea64745edbdcd6b Mon Sep 17 00:00:00 2001 From: Kev Kloss Date: Tue, 30 Sep 2025 15:32:45 +0200 Subject: [PATCH 2/6] Apply 1 suggestion(s) to 1 file(s) Co-authored-by: GitLab Duo --- spec/lib/gitlab/seeder_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/lib/gitlab/seeder_spec.rb b/spec/lib/gitlab/seeder_spec.rb index 1b8caffd9e4674..327997f185f564 100644 --- a/spec/lib/gitlab/seeder_spec.rb +++ b/spec/lib/gitlab/seeder_spec.rb @@ -118,8 +118,8 @@ expect(reader.read.split('').map(&:to_i).sort).to eq(test_array) ensure - reader.close - end + ensure + reader&.close it 'prevents nested calls by raising an error' do described_class.parallel_each([1]) do -- GitLab From 726f807fa05de6b69c5996a4c6cc21c2fa7980c3 Mon Sep 17 00:00:00 2001 From: Kev Kloss Date: Tue, 30 Sep 2025 15:34:23 +0200 Subject: [PATCH 3/6] Apply 1 suggestion(s) to 1 file(s) Co-authored-by: GitLab Duo --- spec/lib/gitlab/seeder_spec.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spec/lib/gitlab/seeder_spec.rb b/spec/lib/gitlab/seeder_spec.rb index 327997f185f564..62ce6e34462cf2 100644 --- a/spec/lib/gitlab/seeder_spec.rb +++ b/spec/lib/gitlab/seeder_spec.rb @@ -116,7 +116,10 @@ described_class.parallel_each(test_array) { |item| writer.write(item.to_s) } writer.close - expect(reader.read.split('').map(&:to_i).sort).to eq(test_array) + # Wait for all processes to complete and collect results + Process.waitall + results = reader.read.chars.map(&:to_i).sort + expect(results).to eq(test_array) ensure ensure reader&.close -- GitLab From 03b05a3fda340b84c9473f01c01e5276a91bbb01 Mon Sep 17 00:00:00 2001 From: Kev Kloss Date: Tue, 30 Sep 2025 15:35:20 +0200 Subject: [PATCH 4/6] Remove duplicate 'ensure' added by duo --- spec/lib/gitlab/seeder_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/lib/gitlab/seeder_spec.rb b/spec/lib/gitlab/seeder_spec.rb index 62ce6e34462cf2..306996f22bfa6d 100644 --- a/spec/lib/gitlab/seeder_spec.rb +++ b/spec/lib/gitlab/seeder_spec.rb @@ -120,9 +120,9 @@ Process.waitall results = reader.read.chars.map(&:to_i).sort expect(results).to eq(test_array) - ensure ensure reader&.close + end it 'prevents nested calls by raising an error' do described_class.parallel_each([1]) do -- GitLab From 8de9e74872663adcdf6053f2e761d33fadd72aaa Mon Sep 17 00:00:00 2001 From: Kev Kloss Date: Wed, 1 Oct 2025 10:01:43 +0200 Subject: [PATCH 5/6] Test that we run in more than one pid --- spec/lib/gitlab/seeder_spec.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/spec/lib/gitlab/seeder_spec.rb b/spec/lib/gitlab/seeder_spec.rb index 306996f22bfa6d..160ec2844eba8a 100644 --- a/spec/lib/gitlab/seeder_spec.rb +++ b/spec/lib/gitlab/seeder_spec.rb @@ -113,14 +113,22 @@ expect(Gitlab::GitalyClient).to receive(:clear_stubs!) # we're communicating across forks reader, writer = IO.pipe - described_class.parallel_each(test_array) { |item| writer.write(item.to_s) } + pid_reader, pid_writer = IO.pipe + described_class.parallel_each(test_array) do |item| + writer.write("#{item},") + pid_writer.write("#{Process.pid},") + end writer.close + pid_writer.close # Wait for all processes to complete and collect results Process.waitall - results = reader.read.chars.map(&:to_i).sort + results = reader.read.split(",").uniq.map(&:to_i).sort expect(results).to eq(test_array) + pids = pid_reader.read.split(",").uniq.reject(&:blank?) + expect(pids.size).to be > 1 ensure + pid_reader&.close reader&.close end -- GitLab From f1f5820801547a47571da6897f56b0596b62f8b0 Mon Sep 17 00:00:00 2001 From: Kev Kloss Date: Thu, 2 Oct 2025 11:12:34 +0200 Subject: [PATCH 6/6] Fix typo --- spec/lib/gitlab/seeder_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/lib/gitlab/seeder_spec.rb b/spec/lib/gitlab/seeder_spec.rb index 160ec2844eba8a..f2d60b52ff20e3 100644 --- a/spec/lib/gitlab/seeder_spec.rb +++ b/spec/lib/gitlab/seeder_spec.rb @@ -109,7 +109,7 @@ described_class.instance_variable_set(:@parallel, false) end - it 'clear Gitaly stubs and then processes the items in parallel' do + it 'clears Gitaly stubs and then processes the items in parallel' do expect(Gitlab::GitalyClient).to receive(:clear_stubs!) # we're communicating across forks reader, writer = IO.pipe -- GitLab