Skip to content

Commit

Permalink
Parallelise test
Browse files Browse the repository at this point in the history
Runs the test suite split across nodes.
We introduce a script `test_splitter` to handle splitting up the
test suite based on the number of nodes.
I don't know of a good way to avoid having to perform the set up on each
node but as the bulk of the run time is spent on the tests this is a
worthwhile trade off IMO.
  • Loading branch information
rjlynch committed Apr 22, 2024
1 parent 3c75bfd commit 37feca2
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
19 changes: 16 additions & 3 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ name: CI
on: push
jobs:
test_and_lint:
strategy:
fail-fast: false
matrix:
ci_node_total: [8]
ci_node_index: [0, 1, 2, 3, 4, 5, 6, 7]
runs-on: ubuntu-latest
services:
postgres:
Expand All @@ -18,6 +23,8 @@ jobs:
DFE_TEACHERS_PAYMENT_SERVICE_DATABASE_USERNAME: postgres
DFE_TEACHERS_PAYMENT_SERVICE_DATABASE_PASSWORD: password
DFE_TEACHERS_PAYMENT_SERVICE_DATABASE_HOST: localhost
CI_NODE_TOTAL: ${{ matrix.ci_node_total }}
CI_NODE_INDEX: ${{ matrix.ci_node_index }}
steps:
- name: Checkout code
uses: actions/checkout@v4
Expand All @@ -26,7 +33,7 @@ jobs:
- name: Setup yarn
run: npm install -g yarn
- name: Install Node packages
run: yarn install # TODO RL: cache yarn
run: yarn install
- name: Install Ruby
uses: ruby/setup-ruby@v1
with:
Expand All @@ -42,5 +49,11 @@ jobs:
run: bin/rails standard
- name: Prepare DB
run: bin/rails db:schema:load
- name: Run test
run: bundle exec rspec
- name: Run unit tests
env:
SPEC_TYPE: unit
run: bundle exec rspec $(bin/test_splitter)
- name: Run feature tests
env:
SPEC_TYPE: feature
run: bundle exec rspec $(bin/test_splitter)
26 changes: 26 additions & 0 deletions bin/test_splitter
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env ruby

# Use on ci to split tests by file type and split them across ci nodes

all_specs = Dir["spec/**/*_spec.rb"]

case ENV["SPEC_TYPE"]
when "unit"
specs = all_specs.reject { |path| /\Aspec\/features\//.match? path }
when "feature"
specs = all_specs.select { |path| /\Aspec\/features\//.match? path }
else
specs = all_specs
end

number_of_ci_nodes = ENV.fetch("CI_NODE_TOTAL").to_i

this_ci_node = ENV.fetch("CI_NODE_INDEX").to_i

number_of_slices = (specs.size / number_of_ci_nodes.to_f).ceil

specs_split_across_nodes = specs.each_slice(number_of_slices).to_a

specs_to_run_on_this_node = specs_split_across_nodes[this_ci_node]

print specs_to_run_on_this_node.join(" ")

0 comments on commit 37feca2

Please sign in to comment.