Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/mutation testing #8

Merged
merged 32 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
227c667
feat: add ci workflows
ASuciuX Dec 10, 2023
33a3cbb
feat: upload artifact to fetch data easily & rename cache to mutants-…
ASuciuX Dec 10, 2023
ed270a1
feat: docs readme mutations
ASuciuX Dec 11, 2023
f47472d
feat: add retry to cache/artifact save in case of failure
ASuciuX Dec 12, 2023
9c2ab75
fix: regex matching for mutants v12.3
ASuciuX Dec 12, 2023
bb9d337
feat: remove logger files, only keep filter-pr ones
ASuciuX Dec 16, 2023
8b2b43d
feat: update readme to exclude logger paths
ASuciuX Dec 16, 2023
f765dac
feat: update actions checkout branch to point at the base branch of t…
ASuciuX Dec 18, 2023
1f1679e
feat: add env vars and test-threads for `cargo test`
ASuciuX Dec 28, 2023
07c7d28
modularize mutants' runs for different package size cases
ASuciuX Jan 7, 2024
e7b4a75
feat: rename from `filter-pr` to `pr-differences`
ASuciuX Jan 8, 2024
9617c14
Merge pull request #4 from ASuciuX/test/mutants-filter-pr
wileyj Jan 8, 2024
b773b0f
feat: shorter step names, check files and commands before using them
ASuciuX Jan 9, 2024
34438d1
feat: move the packages checking and output steps to composite
ASuciuX Jan 10, 2024
8508292
feat: update output structure
ASuciuX Jan 10, 2024
105384e
feat: debug prints
ASuciuX Jan 10, 2024
18bc826
feat: change 'echo' to 'cat'
ASuciuX Jan 10, 2024
3b5a1b7
feat: check if file is empty, not the other way around
ASuciuX Jan 10, 2024
f4bde14
feat: update actions version, add comments, check files before access…
ASuciuX Jan 11, 2024
6ee34a9
feat: fix indentation
ASuciuX Jan 11, 2024
c422ffb
feat: remove a check - perhaps it takes longer to move back
ASuciuX Jan 11, 2024
f8097b3
feat: add moving of the temp file to input file
ASuciuX Jan 11, 2024
d72903a
feat: move the temp file to input file in script
ASuciuX Jan 11, 2024
946ec2f
feat: fix typo in 'case'
ASuciuX Jan 11, 2024
427290c
feat: remove unnecessary check
ASuciuX Jan 11, 2024
75a257c
feat: change artifact download version back to v3
ASuciuX Jan 11, 2024
121448d
Merge branch 'feat/mutation-testing' into test/move-shell-to-composite
ASuciuX Jan 11, 2024
babc08d
Merge pull request #7 from ASuciuX/test/move-shell-to-composite
ASuciuX Jan 11, 2024
86d2d9f
feat: add file names to prints for easier debugging
ASuciuX Jan 11, 2024
d322c16
feat: add `id` key to all steps
ASuciuX Jan 12, 2024
85ebbb8
feat: mutants - file and exit code handling, readme structure
ASuciuX Jan 15, 2024
c7574a1
feat: move `mutation-testing` folder to `stacks-core` folder
ASuciuX Jan 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions stacks-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ Folder of composite actions for the [stacks blockchain](https://github.com/stack
- [cache](./cache) - Various cache operations
- [testenv](./testenv) - Configures a workflow with a testing environment
- [run-tests](./run-tests) - Run tests with [nextest](https://nexte.st)
- [mutation-testing](./mutation-testing) - Run mutation testing
5 changes: 5 additions & 0 deletions stacks-core/mutation-testing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Mutation Testing actions

> - [Check Packages and Shards action](./check-packages-and-shards/README.md)
> - [Output PR Mutants action](./output-pr-mutants/README.md)
> - [PR Differences action](./pr-differences/README.md)
28 changes: 28 additions & 0 deletions stacks-core/mutation-testing/check-packages-and-shards/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Check Packages and Shards action

Checks whether to run mutants on big ([stackslib](https://github.com/stacks-network/stacks-core/tree/develop/stackslib)/[stacks-node](https://github.com/stacks-network/stacks-core/tree/develop/testnet/stacks-node)) or small packages (all others), and whether to run them using strategy matrix or not.

## Documentation

### Outputs
| Output | Description |
| ------------------------------- | ----------------------------------------------------- |
| `run_big_packages` | True if there are mutants on `stackslib` or `stacks-node` packages, false otherwise.
| `big_packages_with_shards` | True if there are more than 15 mutants on big packages.
| `run_small_packages` | True if there are mutants on small packages, false otherwise.
| `small_packages_with_shards` | True if there are more than 79 (119 if `big_packages_with_shards` is true) mutants on small packages.

## Usage

```yaml
name: Action
on: pull-request
jobs:
check-packages-and-shards:
name: Check Packages and Shards
runs-on: ubuntu-latest
steps:
- name: Check Packages and Shards
id: check_packages_and_shards
uses: stacks-network/actions/stacks-core/mutation-testing/check-packages-and-shards@main
```
168 changes: 168 additions & 0 deletions stacks-core/mutation-testing/check-packages-and-shards/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
name: Check Packages and Shards
description: "Checks which types of packages are contained in the diffs and how many mutants there are"
branding:
icon: "check"
color: "gray-dark"

outputs:
run_big_packages:
description: "True if there are packages on `stackslib` or `stacks-node`."
value: ${{ steps.check_packages_and_shards.outputs.run_big_packages }}
big_packages_with_shards:
description: "True if there are more than 16 mutants on `stackslib` and `stacks-node`."
value: ${{ steps.check_packages_and_shards.outputs.big_packages_with_shards }}
run_small_packages:
description: "True if there are packages on other packages than `stackslib` or `stacks-node`."
value: ${{ steps.check_packages_and_shards.outputs.run_small_packages }}
small_packages_with_shards:
description: "True if there are more than 79 (119 if `big_packages_with_shards` is true) mutants on small packages."
value: ${{ steps.check_packages_and_shards.outputs.small_packages_with_shards }}

runs:
using: "composite"

steps:
- name: Checkout stacks-core repo
id: checkout_stacks_core
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
fetch-depth: 0

- uses: taiki-e/install-action@ac89944b5b150d78567ab6c02badfbe48b0b55aa # v2.20.16
id: install_cargo_mutants
name: Install cargo-mutants
with:
tool: [email protected] # v23.12.2

- name: Relative diff
id: relative_diff
shell: bash
run: |
git diff origin/${{ github.base_ref }}.. > git.diff

- name: Update git diff
id: update_git_diff
shell: bash
run: |
input_file="git.diff"
temp_file="temp_diff_file.diff"

# Check if the commands exist on the host
for cmd in tac awk sed; do
command -v "${cmd}" > /dev/null 2>&1 || { echo "Missing command: ${cmd}" && exit 1; }
done

# Check that the file exists before performing actions on it
if [ ! -s "$input_file" ]; then
echo "Diff file (git.diff) is missing or empty!"
exit 1
fi

# Reverse the file, remove 4 lines after '+++ /dev/null', then reverse it back (editors can't go backwards - to remove lines above)
tac "$input_file" > "$temp_file" && mv "$temp_file" "$input_file"
sed '/+++ \/dev\/null/{n;N;N;N;d;}' "$input_file" > "$temp_file" && mv "$temp_file" "$input_file"
tac "$input_file" > "$temp_file" && mv "$temp_file" "$input_file"

# Remove the lines between '+++ /dev/null' (included) and 'diff --git a/'
awk '
BEGIN { in_block=0 }
/\+\+\+ \/dev\/null/ { in_block=1; next }
in_block && /diff --git a\// { in_block=0; print; next }
!in_block
' "$input_file" > "$temp_file"

# Check that the file exists before performing actions on it
if [ -s "$temp_file" ]; then
mv "$temp_file" "$input_file"
exit 0
fi

echo "Temp diff file (temp_diff_file.diff) is missing or empty!"
exit 1

- name: Split diffs
id: split_diffs_by_packages
shell: bash
run: |
# Check that the file exists before performing actions on it
if [ ! -s git.diff ]; then
echo "Diff file (git.diff) is missing or empty!"
exit 1
fi

# Make a file containing all the mutants for the differences in the PR and a folder to split them into big and small packages
cargo mutants --in-diff git.diff --list > all_mutants.txt
if [ $? -ne 0 ]; then
echo "Error retrieving the list of mutants!"
exit $?
fi

mkdir -p mutants_by_packages

# Check that the file exists before performing actions on it
if [ ! -s all_mutants.txt ]; then
echo "The file containing mutants (all_mutants.txt) is missing or empty!"
exit 1
fi

# Split the differences from git into 2 parts, big packages ('stacks-node' and 'stackslib') and small packages (all others) and put them into separate files
while IFS= read -r line; do
package=$(echo "$line" | cut -d'/' -f1)
case $package in
"testnet" | "stackslib")
echo "$line" >> "mutants_by_packages/big_packages.txt"
;;
*)
echo "$line" >> "mutants_by_packages/small_packages.txt"
;;
esac
done < all_mutants.txt

exit 0

- name: Check packages and shards
id: check_packages_and_shards
shell: bash
run: |
number_of_big_mutants=0
number_of_small_mutants=0

# If big_packages file exists, count how many mutants there are
if [[ -s mutants_by_packages/big_packages.txt ]]; then
number_of_big_mutants=$(cat mutants_by_packages/big_packages.txt | awk 'END { print NR }' | tr -d '[:space:]')
fi

# If small_packages file exists, count how many mutants there are
if [[ -s mutants_by_packages/small_packages.txt ]]; then
number_of_small_mutants=$(cat mutants_by_packages/small_packages.txt | awk 'END { print NR }' | tr -d '[:space:]')
fi

# Set the mutants limit for when to run with shards on the small packages
# If there are mutants from big packages, check whether to run with or without shards, otherwise there's nothing to run
if [[ $number_of_big_mutants -gt 15 ]]; then
small_packages_shard_limit=119
echo "run_big_packages=true" >> "$GITHUB_OUTPUT"
echo "big_packages_with_shards=true" >> "$GITHUB_OUTPUT"
else
small_packages_shard_limit=79
if [[ $number_of_big_mutants -ne 0 ]]; then
echo "run_big_packages=true" >> "$GITHUB_OUTPUT"
echo "big_packages_with_shards=false" >> "$GITHUB_OUTPUT"
else
echo "run_big_packages=false" >> "$GITHUB_OUTPUT"
fi
fi

# If there are mutants from small packages, check whether to run with or without shards, otherwise there's nothing to run
if [[ $number_of_small_mutants -ne 0 ]]; then
echo "run_small_packages=true" >> "$GITHUB_OUTPUT"
if [[ $number_of_small_mutants -gt $small_packages_shard_limit ]]; then
echo "small_packages_with_shards=true" >> "$GITHUB_OUTPUT"
else
echo "small_packages_with_shards=false" >> "$GITHUB_OUTPUT"
fi
else
echo "run_small_packages=false" >> "$GITHUB_OUTPUT"
fi

exit 0
34 changes: 34 additions & 0 deletions stacks-core/mutation-testing/output-pr-mutants/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Output PR Mutants action

Write the mutants tested in the previous jobs of the same workflow to github step summary.

## Documentation

### Inputs

| Input | Description | Required | Default |
| ------------------------------- | ----------------------------------------------------- | ------------------------- | ------------------------- |
| `big_packages` | True if there were big packages running | true | |
| `shards_for_big_packages` | True if the big packages were running using matrix | true | |
| `small_packages` | True if there were small packages running | true | |
| `shards_for_small_packages` | True if the small packages were running using matrix | true | |

## Usage

```yaml
name: Action
on: push
jobs:
check-packages-and-shards:
name: Output Mutants
runs-on: ubuntu-latest
steps:
- name: Output Mutants
id: output_pr_mutants
uses: stacks-network/actions/stacks-core/mutation-testing/output-pr-mutants@main
with:
big_packages: "true"
shards_for_big_packages: "false"
small_packages: "true"
shards_for_small_packages: "true"
```
Loading