Skip to content

Commit 88058ef

Browse files
authored
Merge pull request #6512 from fdefelici/chore/remove-contrib-mutation-testing
chore: remove contrib mutation testing
2 parents 25f8617 + 7ad4042 commit 88058ef

File tree

3 files changed

+0
-331
lines changed

3 files changed

+0
-331
lines changed

contrib/tools/local-mutation-testing.sh

Lines changed: 0 additions & 87 deletions
This file was deleted.

docs/ci-workflow.md

Lines changed: 0 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ All releases are built via a Github Actions workflow named [`CI`](../.github/wor
55
- Verifying code is formatted correctly
66
- Integration tests
77
- Unit tests
8-
- [Mutation tests](https://en.wikipedia.org/wiki/Mutation_testing)
98
- Creating releases
109
- Building binary archives and calculating checksums
1110
- Publishing Docker images
@@ -128,100 +127,3 @@ check-tests:
128127
jobs: ${{ toJson(needs) }}
129128
summary_print: "true"
130129
```
131-
132-
## Mutation Testing
133-
134-
When a new Pull Request (PR) is submitted, this feature evaluates the quality of the tests added or modified in the PR.
135-
It checks the new and altered functions through mutation testing.
136-
Mutation testing involves making small changes (mutations) to the code to check if the tests can detect these changes.
137-
138-
The mutations are run with or without a [Github Actions matrix](https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs).
139-
The matrix is used when there is a large number of mutations to run ([check doc specific cases](https://github.com/stacks-network/actions/blob/main/stacks-core/mutation-testing/check-packages-and-shards/README.md#outputs)).
140-
We utilize a matrix strategy with shards to enable parallel execution in GitHub Actions.
141-
This approach allows for the concurrent execution of multiple jobs across various runners.
142-
The total workload is divided across all shards, effectively reducing the overall duration of a workflow because the time taken is approximately the total time divided by the number of shards (+ initial build & test time).
143-
This is particularly advantageous for large packages that have significant build and test times, as it enhances efficiency and speeds up the process.
144-
145-
Since mutation testing is directly correlated to the written tests, there are slower packages (due to the quantity or time it takes to run the tests) like `stackslib` or `stacks-node`.
146-
These mutations are run separately from the others, with one or more parallel jobs, depending on the amount of mutations found.
147-
148-
Once all the jobs have finished testing mutants, the last job collects all the tested mutations from the previous jobs, combines them and outputs them to the `Summary` section of the workflow, at the bottom of the page.
149-
There, you can find all mutants on categories, with links to the function they tested, and a short description on how to fix the issue.
150-
The PR should only be approved/merged after all the mutants tested are in the `Caught` category.
151-
152-
### Time required to run the workflow based on mutants outcome and packages' size
153-
154-
- Small packages typically completed in under 30 minutes, aided by the use of shards.
155-
- Large packages like stackslib and stacks-node initially required about 20-25 minutes for build and test processes.
156-
- Each "missed" and "caught" mutant took approximately 15 minutes. Using shards, this meant about 50-55 minutes for processing around 32 mutants (10-16 functions modified). Every additional 8 mutants added another 15 minutes to the runtime.
157-
- "Unviable" mutants, which are functions lacking a Default implementation for their returned struct type, took less than a minute each.
158-
- "Timeout" mutants typically required more time. However, these should be marked to be skipped (by adding a skip flag to their header) since they indicate functions unable to proceed in their test workflow with mutated values, as opposed to the original implementations.
159-
160-
File:
161-
162-
- [PR Differences Mutants](../.github/workflows/pr-differences-mutants.yml)
163-
164-
### Mutant Outcomes
165-
166-
- caught — A test failed with this mutant applied.
167-
This is a good sign about test coverage.
168-
169-
- missed — No test failed with this mutation applied, which seems to indicate a gap in test coverage.
170-
Or, it may be that the mutant is undistinguishable from the correct code.
171-
In any case, you may wish to add a better test.
172-
173-
- unviable — The attempted mutation doesn't compile.
174-
This is inconclusive about test coverage, since the function's return structure may not implement `Default::default()` (one of the mutations applied), hence causing the compile to fail.
175-
It is recommended to add `Default` implementation for the return structures of these functions, only mark that the function should be skipped as a last resort.
176-
177-
- timeout — The mutation caused the test suite to run for a long time, until it was eventually killed.
178-
You might want to investigate the cause and only mark the function to be skipped if necessary.
179-
180-
### Skipping Mutations
181-
182-
Some functions may be inherently hard to cover with tests, for example if:
183-
184-
- Generated mutants cause tests to hang.
185-
- You've chosen to test the functionality by human inspection or some higher-level integration tests.
186-
- The function has side effects or performance characteristics that are hard to test.
187-
- You've decided that the function is not important to test.
188-
189-
To mark functions as skipped, so they are not mutated:
190-
191-
- Add a Cargo dependency of the [mutants](https://crates.io/crates/mutants) crate, version `0.0.3` or later (this must be a regular `dependency`, not a `dev-dependency`, because the annotation will be on non-test code) and mark functions with `#[mutants::skip]`, or
192-
193-
- You can avoid adding the dependency by using the slightly longer `#[cfg_attr(test, mutants::skip)]`.
194-
195-
### Example
196-
197-
```rust
198-
use std::time::{Duration, Instant};
199-
200-
/// Returns true if the program should stop
201-
#[cfg_attr(test, mutants::skip)] // Returning false would cause a hang
202-
fn should_stop() -> bool {
203-
true
204-
}
205-
206-
pub fn controlled_loop() {
207-
let start = Instant::now();
208-
for i in 0.. {
209-
println!("{}", i);
210-
if should_stop() {
211-
break;
212-
}
213-
if start.elapsed() > Duration::from_secs(60 * 5) {
214-
panic!("timed out");
215-
}
216-
}
217-
}
218-
219-
mod test {
220-
#[test]
221-
fn controlled_loop_terminates() {
222-
super::controlled_loop()
223-
}
224-
}
225-
```
226-
227-
---

docs/mutation-testing.md

Lines changed: 0 additions & 146 deletions
This file was deleted.

0 commit comments

Comments
 (0)