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

Measure coverage for integration tests in CI #1893

Merged
merged 49 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
99de732
Add a build step that builds with HPC enabled
Jul 12, 2023
8e59c10
Enable HPC via environmental variable
Jul 12, 2023
f8c4c20
Add missing `hpc` config on old LTS build
Jul 12, 2023
afb2f7e
Consistent order
Jul 12, 2023
fc0fcf7
Upload hpc artifacts
Jul 12, 2023
aac344c
Fix typo
Jul 12, 2023
25742ac
Force Windows 9.2.7 cache rebuild
Jul 12, 2023
481bb13
" -> '
Jul 12, 2023
740486a
Fix typo in artifact upload conditionals
Jul 13, 2023
9a8e287
Run linux intTests with HPC bins
Jul 13, 2023
1af0efa
Compute coverage from HPC files
Jul 14, 2023
ae23bdc
Fix missing '$'
Jul 14, 2023
0d7d80f
Upload .mix files as artifact
Jul 17, 2023
d3ff0a3
Generate HTML
Jul 17, 2023
0585c54
Capture autogenerated .hs files
Jul 17, 2023
89a4a19
Download hpc artifacts without creating new folder
Jul 18, 2023
aee9d31
Another stab at unpacking the HPC build files
Jul 18, 2023
ecb7f20
Cleanup some TODOs
Jul 20, 2023
41a524c
Pull coverage computation into separate script
Jul 20, 2023
356f6b3
Consistency in naming
Jul 20, 2023
0e6ce01
Merge remote-tracking branch 'origin/master' into bb/ci-coverage
Aug 10, 2023
62e831a
Upload html tagged with PR number
Aug 10, 2023
7e5ddc3
Attempt to serve with gh-pages
Aug 10, 2023
29c999f
Only upload to gh-pages if hpc is set
Aug 10, 2023
c93efc1
Set GH_TOKEN for collecting html
Aug 10, 2023
92cf702
Merge remote-tracking branch 'origin/master' into bb/ci-coverage
Aug 25, 2023
d45d96c
Generate simple HTML index for PRs
Aug 25, 2023
b4cd1a3
Initial cleanup + docs
Aug 25, 2023
3f05edf
Cleanup
Aug 25, 2023
58e4548
Only upload PR HTML
Aug 28, 2023
e7fa27a
Fix syntax error
Aug 28, 2023
63fb418
Split running tests with coverage into separate job
Sep 8, 2023
a6cba8e
Address comments in shell scripts
Sep 8, 2023
6325cc0
Add matrix to get more specific os string
Sep 8, 2023
b9400d4
Fix file permissions
Sep 8, 2023
0c07f87
Fix missing download of hpc.tar.gz
Sep 8, 2023
8519b88
Merge remote-tracking branch 'origin/master' into bb/ci-coverage
Sep 8, 2023
40166bf
Download artifact hpc.tar.gz to correct place
Sep 8, 2023
9d76d62
Remove checkout step
Sep 8, 2023
4a6a507
Bring dist/bin into hpc.tar.gz
Sep 8, 2023
e1be4bf
Remove unnecessary run-tests checks
Sep 8, 2023
2c5063c
Better documentation for `ci.yml`
Sep 8, 2023
fcf9c93
Package up necessary scripts and add gh-pages permissions
Sep 9, 2023
334ea75
Package up tests
Sep 9, 2023
f589a55
Package up supporting test files
Sep 11, 2023
8f9d070
Checkout repo
Sep 12, 2023
c36e85e
Merge remote-tracking branch 'origin/master' into bb/ci-coverage
Sep 14, 2023
2f2b267
Use solver caching
Sep 14, 2023
4ced21f
Re-enable accidentally disabled ubuntu integration tests
Sep 14, 2023
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
19 changes: 18 additions & 1 deletion .github/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ build() {
else
pkgs=(saw crux-mir-comp saw-remote-api)
fi
tee -a cabal.project.local > /dev/null < cabal.project.ci
cat cabal.project.ci >> cabal.project.local
if [[ "$ENABLE_HPC" == "true" ]]; then
cat cabal.project.ci-hpc >> cabal.project.local
fi
if ! retry cabal v2-build "$@" "${pkgs[@]}"; then
if [[ "$RUNNER_OS" == "macOS" ]]; then
echo "Working around a dylib issue on macos by removing the cache and trying again"
Expand All @@ -74,6 +77,20 @@ build() {
fi
}

# Gather and tar up all HPC coverage files
collect_hpc_files() {
local MIX_FILES=$(find dist-newstyle -name "*.mix")
local GENERATED_HS_FILES=$(find dist-newstyle/build -name "*.hs")
bboston7 marked this conversation as resolved.
Show resolved Hide resolved
tar cvf hpc.tar.gz ${MIX_FILES} ${GENERATED_HS_FILES}
}

# Download HTML coverage reports and generate an index file linking to them
collect_all_html() {
local HTML_DIR=all-html
mkdir -p ${HTML_DIR}
(cd ${HTML_DIR} && gh run download -p "coverage-html-*" && python3 ../.github/generate_index.py)
}

install_system_deps() {
(cd $BIN && curl -o bins.zip -sL "https://github.com/GaloisInc/what4-solvers/releases/download/$SOLVER_PKG_VERSION/$BUILD_TARGET_OS-bin.zip" && unzip -o bins.zip && rm bins.zip)
chmod +x $BIN/*
Expand Down
30 changes: 30 additions & 0 deletions .github/generate_index.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env python3

# This script generates an HTML index file for all coverage reports

import glob

HEADER = """
<!DOCTYPE html>
<head>
<title>SAWScript Test Coverage Results</title>
</head>
<body>
<h1>SAWScript Test Coverage Results</h1>
<p>SAWScript coverage results by pull request number:</p>
<ul>
"""

FOOTER = """
</ul>
</body>
"""

if __name__ == "__main__":
with open("index.html", "w") as f:
f.write(HEADER)
for dir in sorted(glob.glob("coverage-html-*")):
pr_num = dir[14:]
link_dest = f"{dir}/hpc_index.html"
f.write(f" <li><a href={link_dest}>{pr_num}</a></li>")
f.write(FOOTER)
117 changes: 114 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ jobs:
cabal: ["3.10.1.0"]
ghc: ["8.10.7", "9.2.7", "9.4.4"]
run-tests: [true]
hpc: [false]
include:
# We include one job from an older Ubuntu LTS release to increase our
# coverage of possible Linux configurations. Since we already run the
Expand All @@ -79,6 +80,13 @@ jobs:
ghc: "8.10.7"
cabal: "3.10.1.0"
run-tests: false
hpc: false
# Include one job with HPC enabled
- os: ubuntu-22.04
ghc: "9.4.4"
cabal: "3.10.1.0"
run-tests: true
hpc: true
outputs:
cabal-test-suites-json: ${{ steps.cabal-test-suites.outputs.targets-json }}
steps:
Expand Down Expand Up @@ -134,6 +142,9 @@ jobs:

- shell: bash
run: .github/ci.sh build
env:
ENABLE_HPC: ${{ matrix.hpc }}


- shell: bash
env:
Expand Down Expand Up @@ -182,28 +193,44 @@ jobs:
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
run: .github/ci.sh sign $NAME-with-solvers.tar.gz

bboston7 marked this conversation as resolved.
Show resolved Hide resolved
- if: matrix.ghc == '8.10.7'
- if: matrix.ghc == '8.10.7' && matrix.hpc == false
uses: actions/upload-artifact@v2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we explicitly checking matrix.hpc == false here? If the ghc version is because this is (arbitrarily) our current "distribution" version, won't this break if we then happen to choose the distribution version to be the same one we are generating coverage for? Same question goes for the next 2 steps with the same check. Either something to fix, or something that should have an explanatory comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check is here to avoid the problem you identified. If the distribution version is changed to match the HPC version, then this prevents the HPC binaries from clobbering the distribution binaries. For example, assume the distribution is changed to 9.4.4. The matrix specifies that there are two different Ubuntu builds with GHC 9.4.4. One of those builds has HPC enabled and the other has HPC disabled. This conditional ensures that it's the version with HPC disabled that gets uploaded. I'll add a comment to clarify that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a comment clarifying the matrix.hpc == false check

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if you still think there's a logic error here

with:
name: ${{ steps.config.outputs.name }} (GHC ${{ matrix.ghc }})
path: "${{ steps.config.outputs.name }}.tar.gz*"
if-no-files-found: error
retention-days: ${{ needs.config.outputs.retention-days }}

- if: matrix.ghc == '8.10.7'
- if: matrix.ghc == '8.10.7' && matrix.hpc == false
uses: actions/upload-artifact@v2
with:
name: ${{ steps.config.outputs.name }}-with-solvers (GHC ${{ matrix.ghc }})
path: "${{ steps.config.outputs.name }}-with-solvers.tar.gz*"
if-no-files-found: error
retention-days: ${{ needs.config.outputs.retention-days }}

- if: matrix.ghc == '8.10.7' && matrix.run-tests
- if: matrix.ghc == '8.10.7' && matrix.run-tests && matrix.hpc == false
uses: actions/upload-artifact@v2
with:
path: dist/bin
name: ${{ runner.os }}-bins

- if: matrix.run-tests && matrix.hpc == true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here (and in the next two steps), why are we concerned with matrix.run_tests?

In fact, for this entire job, it's not clear to me what matrix.run_tests is intended to solve, and why we need it at all in this job. Any ideas?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like matrix.run_tests exists to avoid uploading build artifacts from the ubuntu-20.04 build because none of the testing runs use that version of Ubuntu. Does that sound right to you?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That being said, run_tests is implicitly true for the HPC builds so I removed it from the HPC related steps.

uses: actions/upload-artifact@v2
with:
path: dist/bin
name: ${{ runner.os }}-with-hpc-bins
bboston7 marked this conversation as resolved.
Show resolved Hide resolved

- if: matrix.run-tests && matrix.hpc == true
shell: bash
run: .github/ci.sh collect_hpc_files
bboston7 marked this conversation as resolved.
Show resolved Hide resolved

- if: matrix.run-tests && matrix.hpc == true
uses: actions/upload-artifact@v2
with:
path: hpc.tar.gz
name: ${{ runner.os }}-hpc.tar.gz

- uses: actions/cache/save@v3
name: Save cabal store cache
if: always()
Expand Down Expand Up @@ -360,6 +387,9 @@ jobs:

cabal-test:
runs-on: ${{ matrix.os }}
permissions:
pages: write
id-token: write
needs: [build]
strategy:
fail-fast: false
Expand All @@ -382,6 +412,9 @@ jobs:
- suite: integration_tests
os: windows-2019
continue-on-error: false
- suite: integration_tests
os: ubuntu-22.04
continue-on-error: false
steps:
- uses: actions/checkout@v2
with:
Expand Down Expand Up @@ -428,6 +461,84 @@ jobs:
export PATH="$PWD/bin:$PWD/dist/bin:$PATH"
dist-tests/${{ matrix.suite }}

coverage:
bboston7 marked this conversation as resolved.
Show resolved Hide resolved
name: "Run integration tests with coverage reporting"
needs: build
runs-on: ${{ matrix.os }}
if: github.event_name == 'pull_request'
strategy:
matrix:
os: [ubuntu-22.04]
steps:
- uses: actions/checkout@v2
bboston7 marked this conversation as resolved.
Show resolved Hide resolved
with:
submodules: true

- shell: bash
run: .github/ci.sh install_system_deps
env:
BUILD_TARGET_OS: ${{ matrix.os }}

- uses: actions/download-artifact@v2
with:
name: "${{ runner.os }}-with-hpc-bins"
path: dist/bin

- uses: actions/download-artifact@v2
with:
name: "${{ runner.os }}-hpc.tar.gz"
path: dist/bin

- uses: actions/download-artifact@v2
with:
name: dist-tests-${{ matrix.os }}
path: dist-tests

- name: Update permissions
shell: bash
run: |
chmod +x dist/bin/*
chmod +x bin/*
chmod +x dist-tests/*

- uses: actions/setup-java@v1
with:
java-version: "8"
java-package: jdk
architecture: x64

- name: Run integration tests
shell: bash
run: |
export PATH="$PWD/bin:$PWD/dist/bin:$PATH"
dist-tests/integration_tests

- name: Compute coverage
shell: bash
run: |
tar xvf hpc.tar.gz
./compute-coverage.sh

- uses: actions/upload-artifact@v2
with:
path: hpc-html
name: coverage-html-${{ github.event.number }}

- name: Gather HPC coverage files
shell: bash
run: .github/ci.sh collect_all_html
env:
GH_TOKEN: ${{ github.token }}

- name: Upload pages artifact
uses: actions/upload-pages-artifact@v1
with:
path: all-html

- name: Deploy to github pages
id: deployment
uses: actions/deploy-pages@v2

build-push-image:
runs-on: ubuntu-22.04
needs: [config]
Expand Down
3 changes: 3 additions & 0 deletions cabal.project.ci-hpc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- concatenated with cabal.project when run in the CI HPC build
package saw-script
coverage: true
26 changes: 26 additions & 0 deletions compute-coverage.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -Eeuxo pipefail

# This script generates an HTML coverage report for any tests run within the
# saw-script repo. It uses HPC, which is a tool in the standard GHC
# distribution. Follow these steps to use this script:
# 1. Build with coverage enabled. One way to do this is to add "coverage: true"
# to the saw-script package in cabal.project.
# 2. Run whatever tests you want. It is important that you use the saw binary
# built in step (1), and that your current working directory be somewhere at
# or underneath this top level-directory.
# 3. Run this script in the top-level directory (where this script is found).
# 4. You'll find the HPC HTML report in the "hpc-html" directory beneath the
# directory containing this script.

# Combine .tix files
SUM_TIX="all.tix"
hpc sum --output=$SUM_TIX --union --exclude=Main --exclude=GitRev $(find . -name "*.tix")

# Generate report
HPC_ROOT=$(find dist-newstyle -name "hpc")
HPC_ARGS=""
for dir in ${HPC_ROOT}/vanilla/mix/*; do
HPC_ARGS="${HPC_ARGS} --hpcdir=${dir}"
done
hpc markup --destdir=hpc-html ${HPC_ARGS} ${SUM_TIX}
32 changes: 0 additions & 32 deletions coverage.sh

This file was deleted.