Skip to content

Commit 5172160

Browse files
committed
Attempt to run mutation tests in parallel for the most time-consuming context.
1 parent ca6e770 commit 5172160

File tree

4 files changed

+69
-5
lines changed

4 files changed

+69
-5
lines changed

.github/workflows/pricing.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,30 @@ jobs:
3636
continue-on-error: true
3737

3838
mutate:
39+
needs: test
3940
runs-on: ubuntu-24.04
4041
strategy:
4142
fail-fast: false
43+
matrix:
44+
total_nodes: [2]
45+
node_index: [0, 1]
4246
env:
4347
WORKING_DIRECTORY: ecommerce/pricing
4448
steps:
4549
- uses: actions/checkout@v3
50+
4651
- uses: ruby/setup-ruby@v1
4752
with:
4853
ruby-version: ruby-3.3.7
4954
bundler-cache: true
5055
working-directory: ${{ env.WORKING_DIRECTORY }}
56+
5157
- run: make mutate
58+
env:
59+
MUTANT_NODE_INDEX: ${{ matrix.node_index }}
60+
MUTANT_TOTAL_NODES: ${{ matrix.total_nodes }}
5261
working-directory: ${{ env.WORKING_DIRECTORY }}
62+
5363
- uses: 8398a7/action-slack@v3
5464
with:
5565
status: custom
@@ -58,7 +68,7 @@ jobs:
5868
{
5969
attachments: [{
6070
color: '${{ job.status }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning',
61-
text: `${process.env.AS_WORKFLOW}/${process.env.AS_JOB} ${{ job.status }} in ${process.env.AS_TOOK}\n${process.env.AS_COMMIT} in ${process.env.AS_REF}`,
71+
text: `Workflow: ${process.env.AS_WORKFLOW}\nJob: ${process.env.AS_JOB} (Node ${{ matrix.node_index }}/${{ matrix.total_nodes }})\nStatus: ${{ job.status }} in ${process.env.AS_TOOK}\nCommit: ${process.env.AS_COMMIT} on ${process.env.AS_REF} by ${process.env.AS_AUTHOR}`,
6272
}]
6373
}
6474
env:

.github/workflows/rails_application.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,13 @@ jobs:
4848
continue-on-error: true
4949

5050
mutate:
51+
needs: test
5152
runs-on: ubuntu-24.04
5253
strategy:
5354
fail-fast: false
55+
matrix:
56+
total_nodes: [2]
57+
node_index: [0, 1]
5458
env:
5559
WORKING_DIRECTORY: rails_application
5660
services:
@@ -64,16 +68,23 @@ jobs:
6468
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
6569
steps:
6670
- uses: actions/checkout@v3
71+
6772
- uses: ruby/setup-ruby@v1
6873
with:
6974
ruby-version: ruby-3.3.7
7075
bundler-cache: true
7176
working-directory: ${{ env.WORKING_DIRECTORY }}
77+
7278
- name: Assets Precompile
7379
working-directory: ${{ env.WORKING_DIRECTORY }}
7480
run: bundle exec rails tailwindcss:build
81+
7582
- run: make mutate
83+
env:
84+
MUTANT_NODE_INDEX: ${{ matrix.node_index }}
85+
MUTANT_TOTAL_NODES: ${{ matrix.total_nodes }}
7686
working-directory: ${{ env.WORKING_DIRECTORY }}
87+
7788
- uses: 8398a7/action-slack@v3
7889
with:
7990
status: custom
@@ -82,7 +93,7 @@ jobs:
8293
{
8394
attachments: [{
8495
color: '${{ job.status }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning',
85-
text: `${process.env.AS_WORKFLOW}/${process.env.AS_JOB} ${{ job.status }} in ${process.env.AS_TOOK}\n${process.env.AS_COMMIT} in ${process.env.AS_REF}`,
96+
text: `Workflow: ${process.env.AS_WORKFLOW}\nJob: ${process.env.AS_JOB} (Node ${{ matrix.node_index }}/${{ matrix.total_nodes }})\nStatus: ${{ job.status }} in ${process.env.AS_TOOK}\nCommit: ${process.env.AS_COMMIT} on ${process.env.AS_REF} by ${process.env.AS_AUTHOR}`,
8697
}]
8798
}
8899
env:

ecommerce/pricing/Makefile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,25 @@ install:
44
test:
55
@bundle exec ruby -e "require \"rake/rake_test_loader\"" test/*_test.rb
66

7+
MUTANT_TARGET_DIRS := lib
8+
79
mutate:
10+
ifeq ($(origin MUTANT_NODE_INDEX), environment)
11+
@echo "Running mutation tests in parallel (Node $(MUTANT_NODE_INDEX)/$(MUTANT_TOTAL_NODES)) for pricing, using .mutant.yml"
12+
@find $(MUTANT_TARGET_DIRS) -path ./vendor -prune -o -name '*.rb' -print | sed 's|^\./||' > .all_files.tmp
13+
@awk "NR % $(MUTANT_TOTAL_NODES) == $(MUTANT_NODE_INDEX)" .all_files.tmp > .node_files.tmp
14+
@SUBJECT_NAMES_CMD="cat .node_files.tmp | perl -pe 's|^lib/||; s|\\.rb$$||; s|/|::|g; s/\\b(\\w)/ucfirst(\$1)/ge'"
15+
@SUBJECT_ARGS=$$($$SUBJECT_NAMES_CMD | tr '\\n' ' '); \
16+
if [ -z "$$SUBJECT_ARGS" ]; then \
17+
echo "No subjects derived for this node. Skipping."; \
18+
else \
19+
echo "Attempting to run mutant --fail-fast for derived subjects: $$SUBJECT_ARGS"; \
20+
RAILS_ENV=test bundle exec mutant --fail-fast run $$SUBJECT_ARGS; \
21+
fi
22+
@rm -f .all_files.tmp .node_files.tmp
23+
else
24+
@echo "Running mutation tests locally (using .mutant.yml)"
825
@RAILS_ENV=test bundle exec mutant run
26+
endif
927

1028
.PHONY: install test mutate

rails_application/Makefile

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1+
MUTANT_TARGET_DIRS := app lib
2+
13
install: ## Installs dependencies, runs migrations, creates db & seeds if necessary
24
@bin/setup
35
@env RAILS_ENV=test bin/rails db:create
46

57
dev:
68
@$(MAKE) -j 10 web css
79

8-
mutate: ## Run mutation tests
9-
@env RAILS_ENV=test bundle exec mutant run
10-
1110
test: ## Run unit tests
1211
@bin/rails tailwindcss:build
1312
@echo "Running unit tests"
@@ -16,6 +15,32 @@ test: ## Run unit tests
1615
help:
1716
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
1817

18+
mutate: ## Run mutation tests
19+
ifeq ($(origin MUTANT_NODE_INDEX), environment)
20+
@echo "Running mutation tests in parallel (Node $(MUTANT_NODE_INDEX)/$(MUTANT_TOTAL_NODES)) for rails_application"
21+
@find $(MUTANT_TARGET_DIRS) -name '*.rb' \
22+
-not -path '*/test/*' \
23+
-not -path '*/spec/*' \
24+
-not -path 'config/*' \
25+
-not -path '*/initializers/*' \
26+
-not -path 'db/*' \
27+
-not -path 'vendor/*' \
28+
-print > .all_files.tmp
29+
@awk "NR % $(MUTANT_TOTAL_NODES) == $(MUTANT_NODE_INDEX)" .all_files.tmp > .node_files.tmp
30+
@SUBJECT_NAMES_CMD="cat .node_files.tmp | perl -pe 's|^(app|lib)/||; s|\\.rb$$||; s|/|::|g; s/\\b(\\w)/ucfirst(\$1)/ge'"
31+
@SUBJECT_ARGS=$$($$SUBJECT_NAMES_CMD | tr '\\n' ' '); \
32+
if [ -z "$$SUBJECT_ARGS" ]; then \
33+
echo "No subjects derived for this node. Skipping."; \
34+
else \
35+
echo "Attempting to run mutant --fail-fast for derived subjects: $$SUBJECT_ARGS"; \
36+
RAILS_ENV=test bundle exec mutant --fail-fast run $$SUBJECT_ARGS; \
37+
fi
38+
@rm -f .all_files.tmp .node_files.tmp
39+
else
40+
@echo "Running mutation tests locally for rails_application (mutant discovers subjects)"
41+
@RAILS_ENV=test bundle exec mutant run
42+
endif
43+
1944
.PHONY: help test db
2045
.DEFAULT_GOAL := help
2146

0 commit comments

Comments
 (0)