diff --git a/api/web/start.py b/api/web/start.py index 235afe4d3..6691dc3ff 100644 --- a/api/web/start.py +++ b/api/web/start.py @@ -1,4 +1,3 @@ -import atexit import json import os import sys @@ -9,17 +8,20 @@ # Start coverage before local module loading so their def and imports are counted # http://coverage.readthedocs.io/en/coverage-4.2/faq.html if os.environ.get("SCITRAN_RUNTIME_COVERAGE") == "true": # pragma: no cover - oh, the irony - def save_coverage(cov): - print("Saving coverage") - cov.stop() - cov.save() + import coverage + cov = coverage.coverage(source=["api"], data_suffix="integration-tests") + + class CoverageSaveHandler(webapp2.RequestHandler): + def save_coverage(self): + print("Saving coverage") + cov.stop() + cov.save() def start_coverage(): - import coverage print("Enabling code coverage") - cov = coverage.coverage(source=["api"], data_suffix="integration-tests") cov.start() - atexit.register(save_coverage, cov) + from ..api import endpoints, route # pylint: disable=redefined-outer-name + endpoints.append(route('/api/save-coverage', CoverageSaveHandler, h='save_coverage', m=['POST'])) start_coverage() diff --git a/tests/bin/run-tests-docker.sh b/tests/bin/run-tests-docker.sh index 8aa0fa1f3..61543102d 100755 --- a/tests/bin/run-tests-docker.sh +++ b/tests/bin/run-tests-docker.sh @@ -87,8 +87,7 @@ main() { --env SCITRAN_PERSISTENT_DB_LOG_URI=mongodb://core-test-service:27017/logs \ --env SCITRAN_SITE_API_URL=http://core-test-service/api \ scitran/core:testing \ - /src/core/tests/bin/run-tests-ubuntu.sh \ - $TEST_ARGS + tests/bin/run-tests-ubuntu.sh $TEST_ARGS } @@ -99,15 +98,23 @@ clean_up() { log "INFO: Test return code = $TEST_RESULT_CODE" if [ "${TEST_RESULT_CODE}" = "0" ]; then # Copy unit test coverage - docker cp core-test-runner:/src/core/.coverage .coverage.unit-tests - - # Gracefully stop API then copy integration test coverage - # TODO added exec to dev+mongo.sh and tried (TERM|KILL|INT|QUIT) signals to no avail - # Somehow api.web.start/save_coverage() (atexit) is NOT triggered - # docker kill --signal=SIGTERM core-test-service - # docker cp core-test-service:/src/core/.coverage.integration-tests ./ - - # TODO report/combine/htmlize coverage using a test container + docker cp core-test-runner:/src/core/.coverage .coverage.unit-tests 2>/dev/null + + # Save integration test coverage + docker exec core-test-service python -c 'import requests; requests.post("http://localhost/api/save-coverage")' + docker cp core-test-service:/src/core/.coverage.integration-tests ./ 2>/dev/null + + # Combine unit/integ coverage and report/grenerate html + docker run --rm \ + --name core-test-coverage \ + --volume $(pwd):/src/core \ + scitran/core:testing \ + sh -c ' + rm .coverage; + coverage combine; + coverage report --skip-covered --show-missing; + coverage html; + ' else log "INFO: Printing container logs..." docker logs core-test-service @@ -115,8 +122,8 @@ clean_up() { fi # Spin down dependencies - docker rm -f -v core-test-runner - docker rm -f -v core-test-service + docker rm --force --volumes core-test-runner + docker rm --force --volumes core-test-service docker network rm core-test exit $TEST_RESULT_CODE }