forked from harvard-acc/smaug
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use CircleCI for continuous integration testing.
The CircleCI configuration includes build, unit testing and storing of test results in JUnit reports, and downloading a recently built gem5-aladdin binary so that we can run gem5 simulations in the future as part of the CI flow. TESTED=verified CircleCI pipeline passes.
- Loading branch information
Showing
6 changed files
with
194 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
version: 2.1 | ||
jobs: | ||
build: | ||
docker: | ||
- image: xyzsam/smaug:latest | ||
environment: | ||
SMAUG_HOME: /root/project | ||
steps: | ||
- checkout | ||
- run: | ||
name: Checkout dependencies | ||
command: git submodule update --init --recursive | ||
- run: | ||
name: Build | ||
command: | | ||
make all -j2 | ||
make test -j2 | ||
- run: | ||
name: Run unit tests | ||
environment: | ||
JUNIT_REPORT_DIR: ~/smaug-junit-report-dir | ||
command: | | ||
export PYTHONPATH=$SMAUG_HOME:$PYTHONPATH | ||
make test-run-junit | ||
- run: | ||
name: Download latest gem5-aladdin binary | ||
command: | ||
python .circleci/download_artifacts.py --api_token=${GEM5_ALADDIN_BUILD_ARTIFACT_TOKEN} --project=gem5-aladdin --artifact_name=gem5.opt --user=${USER} --download_loc=/tmp --filter=${BUILD_ARTIFACT_FILTER} --branch=${BUILD_ARTIFACT_BRANCH} | ||
- store_test_results: | ||
path: ~/smaug-junit-report-dir |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
"""Downloads build artifacts via the CircleCI API.""" | ||
|
||
import argparse | ||
import os | ||
import json | ||
import six | ||
import subprocess | ||
import sys | ||
|
||
def query_artifacts(api_token, user, project, branch, filter): | ||
"""Queries CircleCI for a list of build artifacts. | ||
All parameters are strings. The returned value is a JSON object with the | ||
following attributes: | ||
"path": Path to the artifact in the project, relative to the working | ||
directory. | ||
"pretty_path": Same as path. | ||
"node_index": Ignored. | ||
"url": The URL at which the artifact is located. | ||
""" | ||
url = "https://circleci.com/api/v1.1/project/github/%(user)s/%(project)s/latest/artifacts?branch=%(branch)s&filter=%(filter)s" % { | ||
"user": user, | ||
"project": project, | ||
"branch": branch, | ||
"filter": filter, | ||
} | ||
args = ["curl", "-H'Circle-Token: %s'" % api_token, url] | ||
print(" ".join(args)) | ||
proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | ||
stdout, stderr = proc.communicate() | ||
print("Stdout: %s", stdout) | ||
print("Stderr: %s", stderr) | ||
if proc.returncode != 0: | ||
raise OSError("artifact lookup failed") | ||
artifacts = json.loads(stdout) | ||
return artifacts | ||
|
||
|
||
def download_artifacts(artifacts, artifact_name, download_loc): | ||
"""Downloads matching artifacts to the desired location. | ||
artifacts: List of artifacts from the CircleCI API. | ||
artifact_name: The basename of the artifacts to download. | ||
download_loc: The directory where the objects will be downloaded to. | ||
""" | ||
for artifact in artifacts: | ||
if os.path.basename(artifact["path"]) == artifact_name: | ||
proc = subprocess.Popen(["wget", "-P", download_loc, artifact["url"]]) | ||
stdout, stderr = proc.communicate() | ||
if stdout is not None: | ||
print(six.ensure_str(stdout)) | ||
if stderr is not None: | ||
print(six.ensure_str(stderr)) | ||
if proc.returncode != 0: | ||
raise OSError("failed to download artifact") | ||
|
||
|
||
def main(): | ||
parser = argparse.ArgumentParser( | ||
"Download CircleCI artifacts for SMAUG dependencies") | ||
parser.add_argument("--artifact_name", type=str, required=True, | ||
help="Base filename of the object to download.") | ||
parser.add_argument("--download_loc", type=str, required=True, | ||
help="Directory to store the downloaded artifact.") | ||
parser.add_argument("--api_token", type=str, required=True, | ||
help="Secret API token for access to CircleCI APIs.") | ||
parser.add_argument("--project", type=str, required=True, | ||
help="Name of the project to download from") | ||
parser.add_argument("--user", type=str, default="harvard-acc", | ||
help="CircleCI username.") | ||
parser.add_argument("--branch", type=str, default="master", | ||
help="Branch from which the artifact was built.") | ||
parser.add_argument("--filter", type=str, default="successful", | ||
help="Filter on which builds to return.") | ||
args = parser.parse_args() | ||
artifacts = query_artifacts(args.api_token, | ||
args.user, | ||
args.project, | ||
args.branch, | ||
args.filter) | ||
if "message" in artifacts: | ||
print("Artifact query failed:", artifacts["message"]) | ||
sys.exit(1) | ||
download_artifacts(artifacts, args.artifact_name, args.download_loc) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#!/bin/bash | ||
# Runs C++ Catch2 tests with Junit reports. | ||
# Usage: | ||
# ./run_cpp_tests.sh report_dir test0 test1 test2... | ||
|
||
REPORT_DIR=$1 | ||
TESTS=${@:2} # All remaining arguments | ||
HAS_ERROR=0 | ||
|
||
mkdir -p ${REPORT_DIR} | ||
for t in $TESTS; do | ||
printf "Running test ($t)" | ||
JUNIT_XML=$(basename $t).xml | ||
./$t -r junit -o ${REPORT_DIR}/${JUNIT_XML} | ||
RET_VAL=$(echo $?) | ||
if [ $RET_VAL -ne 0 ]; then | ||
echo "... failed" | ||
HAS_ERROR=1 | ||
else | ||
echo " ... ok" | ||
fi | ||
done | ||
|
||
if [ $HAS_ERROR -ne 0 ]; then | ||
exit 1 | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#!/bin/bash | ||
# Runs Python tests without JUnit reports. | ||
# Usage: | ||
# ./run_py_tests.sh report_dir test0 test1 test2... | ||
# | ||
# No reports are currently generated but this is planned. | ||
|
||
REPORT_DIR=$1 | ||
TESTS=${@:2} | ||
HAS_ERROR=0 | ||
|
||
mkdir -p ${REPORT_DIR} | ||
for t in $TESTS; do | ||
printf "Running test ($t)" | ||
JUNIT_XML=$(basename $t).xml | ||
./$t > tmpout 2>&1 | ||
RET_VAL=$(echo $?) | ||
if [ $RET_VAL -ne 0 ]; then | ||
echo "... failed" | ||
cat tmpout | ||
HAS_ERROR=1 | ||
else | ||
echo " ... ok" | ||
fi | ||
done | ||
rm -f tmpout | ||
|
||
if [ $HAS_ERROR -ne 0 ]; then | ||
exit 1 | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters