Skip to content

Commit

Permalink
Split test and coverage metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
JonJagger committed Nov 6, 2024
1 parent f4b1bbe commit e90c04a
Show file tree
Hide file tree
Showing 17 changed files with 290 additions and 179 deletions.
58 changes: 43 additions & 15 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,15 @@ jobs:
run:
make test_server

- name: Get unit test coverage
id: coverage
- name: Check test metrics
id: test_metrics
run:
make coverage_server
make metrics_test_server

- name: Check coverage metrics
id: coverage_metrics
run:
make metrics_coverage_server

- name: Setup Kosli CLI
if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }}
Expand All @@ -241,16 +246,25 @@ jobs:
--name=saver.unit-test
--results-dir=./reports/server/junit

- name: Attest coverage evidence to Kosli
- name: Attest test metrics to Kosli
if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }}
env:
KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.artifact_digest }}
run: |
KOSLI_COMPLIANT=$([ "${{ steps.test_metrics.outcome }}" == 'success' ] && echo true || echo false)
kosli attest generic \
--name=saver.unit-test-metrics \
--user-data="./reports/server/test_metrics.json"
- name: Attest coverage metrics to Kosli
if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }}
env:
KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.artifact_digest }}
run: |
KOSLI_COMPLIANT=$([ "${{ steps.coverage.outcome }}" == 'success' ] && echo true || echo false)
KOSLI_COMPLIANT=$([ "${{ steps.coverage_metrics.outcome }}" == 'success' ] && echo true || echo false)
kosli attest generic \
--description="unit-test branch-coverage and metrics" \
--name=saver.unit-test-branch-coverage \
--user-data="./reports/server/coverage_metrics.json"
--name=saver.unit-test-coverage-metrics \
--user-data="./reports/server/coverage_metrics.json"
integration-tests:
Expand All @@ -275,10 +289,15 @@ jobs:
run:
make image_client test_client

- name: Get integration test coverage
id: coverage
- name: Check test metrics
id: test_metrics
run:
make coverage_client
make metrics_test_client

- name: Check coverage metrics
id: coverage_metrics
run:
make metrics_coverage_client

- name: Setup Kosli CLI
if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }}
Expand All @@ -295,15 +314,24 @@ jobs:
--name=saver.integration-test
--results-dir=./reports/client/junit

- name: Attest coverage evidence to Kosli
- name: Attest test metrics to Kosli
if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }}
env:
KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.artifact_digest }}
run: |
KOSLI_COMPLIANT=$([ "${{ steps.test_metrics.outcome }}" == 'success' ] && echo true || echo false)
kosli attest generic \
--name=saver.integration-test-metrics \
--user-data="./reports/client/test_metrics.json"
- name: Attest coverage metrics to Kosli
if: ${{ github.ref == 'refs/heads/main' && (success() || failure()) }}
env:
KOSLI_FINGERPRINT: ${{ needs.build-image.outputs.artifact_digest }}
run: |
KOSLI_COMPLIANT=$([ "${{ steps.coverage.outcome }}" == 'success' ] && echo true || echo false)
KOSLI_COMPLIANT=$([ "${{ steps.coverage_metrics.outcome }}" == 'success' ] && echo true || echo false)
kosli attest generic \
--description="integration-test branch-coverage and metrics" \
--name=saver.integration-test-branch-coverage \
--name=saver.integration-test-coverage-metrics \
--user-data="./reports/client/coverage_metrics.json"
Expand Down
8 changes: 6 additions & 2 deletions .kosli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ trail:
type: snyk
- name: unit-test
type: junit
- name: unit-test-branch-coverage
- name: unit-test-metrics
type: generic
- name: unit-test-coverage-metrics
type: generic
- name: integration-test
type: junit
- name: integration-test-branch-coverage
- name: integration-test-metrics
type: generic
- name: integration-coverage-metrics
type: generic

18 changes: 12 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@

all_server: image_server test_server coverage_server
all_server: image_server test_server metrics_test_server metrics_coverage_server

image_server:
@${PWD}/bin/build_image.sh server

test_server:
@${PWD}/bin/run_tests.sh server

coverage_server:
@${PWD}/bin/check_coverage.sh server
metrics_test_server:
@${PWD}/bin/check_test_metrics.sh server

metrics_coverage_server:
@${PWD}/bin/check_coverage_metrics.sh server

all_client: image_client test_client coverage_client

all_client: image_client test_client metrics_test_client metrics_coverage_client

image_client:
@${PWD}/bin/build_image.sh client

test_client:
@${PWD}/bin/run_tests.sh client

coverage_client:
@${PWD}/bin/check_coverage.sh client
metrics_test_client:
@${PWD}/bin/check_test_metrics.sh client

metrics_coverage_client:
@${PWD}/bin/check_coverage_metrics.sh client


rubocop-lint:
Expand Down
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,25 @@ There are two sets of tests:
- client: these run from outside the saver container, making api calls only

```bash
# To build the images
# Build the images
$ make {image_server|image_client}

# To run all tests
# Run all tests
$ make {test_server|test_client}

# To run only specific tests
# Run only specific tests
$ ./bin/run_tests.sh {-h|--help}
$ ./bin/run_tests.sh server Ks366

# To check coverage metrics
$ make {coverage_server|coverage_client}
# Check test metrics
$ make {metrics_test_server|metrics_test_client}

# Check coverage metrics
$ make {metrics_coverage_server|metrics_coverage_client}
```

# API

## Group

* [POST group_create(manifest)](docs/api.md#post-group_createmanifest)
Expand Down Expand Up @@ -61,5 +65,6 @@ $ make {coverage_server|coverage_client}
- [GET ready?](docs/api.md#get-ready)
- [GET sha](docs/api.md#get-sha)

## Screenshots

![cyber-dojo.org home page](https://github.com/cyber-dojo/cyber-dojo/blob/master/shared/home_page_snapshot.png)
20 changes: 8 additions & 12 deletions bin/check_coverage.sh → bin/check_coverage_metrics.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ show_help()
Use: ${MY_NAME} {server|client}
Check test coverage (and other metrics) for tests run from inside the client or server container only
Check test coverage metrics for tests run from inside the client or server container only
EOF
}
Expand Down Expand Up @@ -49,30 +49,26 @@ check_coverage()
local -r HOST_REPORTS_DIR="${ROOT_DIR}/reports/${TYPE}" # where report json files have been written to
local -r CONTAINER_TMP_DIR=/tmp

exit_non_zero_unless_file_exists "${HOST_REPORTS_DIR}/${TEST_LOG}"
exit_non_zero_unless_file_exists "${HOST_REPORTS_DIR}/test_metrics.json"
exit_non_zero_unless_file_exists "${HOST_REPORTS_DIR}/coverage_metrics.json"
exit_non_zero_unless_file_exists "${HOST_TEST_DIR}/config/check_test_metrics.rb"
exit_non_zero_unless_file_exists "${HOST_TEST_DIR}/config/check_metrics.rb" # evaluator
exit_non_zero_unless_file_exists "${HOST_REPORTS_DIR}/coverage_metrics.json" # data from test run
exit_non_zero_unless_file_exists "${HOST_TEST_DIR}/config/coverage_metrics_limits.rb" # metric limits

set +e
docker run \
--read-only \
--rm \
--entrypoint="" \
--env COVERAGE_ROOT="${CONTAINER_TMP_DIR}" \
--env COVERAGE_CODE_TAB_NAME=app \
--env COVERAGE_TEST_TAB_NAME=test \
--volume ${HOST_REPORTS_DIR}/test_metrics.json:${CONTAINER_TMP_DIR}/test_metrics.json:ro \
--volume ${HOST_TEST_DIR}/config/check_metrics.rb:${CONTAINER_TMP_DIR}/check_metrics.rb:ro \
--volume ${HOST_REPORTS_DIR}/coverage_metrics.json:${CONTAINER_TMP_DIR}/coverage_metrics.json:ro \
--volume ${HOST_TEST_DIR}/config/check_test_metrics.rb:${CONTAINER_TMP_DIR}/check_test_metrics.rb:ro \
--volume ${HOST_TEST_DIR}/config/coverage_metrics_limits.rb:${CONTAINER_TMP_DIR}/coverage_metrics_limits.rb:ro \
"${CYBER_DOJO_SAVER_IMAGE}:${CYBER_DOJO_SAVER_TAG}" \
sh -c "ruby ${CONTAINER_TMP_DIR}/check_test_metrics.rb" \
sh -c "ruby ${CONTAINER_TMP_DIR}/check_metrics.rb ${CONTAINER_TMP_DIR}/coverage_metrics.json coverage_metrics_limits" \
| tee -a "${HOST_REPORTS_DIR}/${TEST_LOG}"

local -r STATUS=${PIPESTATUS[0]}
set -e

echo "${TYPE} coverage status == ${STATUS}"
echo "${TYPE} coverage metrics status == ${STATUS}"
echo
return "${STATUS}"
}
Expand Down
76 changes: 76 additions & 0 deletions bin/check_test_metrics.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env bash
set -Eeu

export ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

source "${ROOT_DIR}/bin/lib.sh"

show_help()
{
local -r MY_NAME=$(basename "${BASH_SOURCE[0]}")
cat <<- EOF
Use: ${MY_NAME} {server|client}
Check test metrics for tests run from inside the client or server container only
EOF
}

check_args()
{
case "${1:-}" in
'-h' | '--help')
show_help
exit 0
;;
'server' | 'client')
;;
'')
show_help
stderr "no argument - must be 'client' or 'server'"
exit 42
;;
*)
show_help
stderr "argument is '${1:-}' - must be 'client' or 'server'"
exit 42
esac
}

check_coverage()
{
check_args "$@"
export $(echo_versioner_env_vars)

local -r TYPE="${1}" # {server|client}
local -r TEST_LOG=test.log
local -r HOST_TEST_DIR="${ROOT_DIR}/test/${TYPE}"
local -r HOST_REPORTS_DIR="${ROOT_DIR}/reports/${TYPE}" # where report json files have been written to
local -r CONTAINER_TMP_DIR=/tmp

exit_non_zero_unless_file_exists "${HOST_TEST_DIR}/config/check_metrics.rb" # evaluator
exit_non_zero_unless_file_exists "${HOST_REPORTS_DIR}/test_metrics.json" # data from test run
exit_non_zero_unless_file_exists "${HOST_TEST_DIR}/config/test_metrics_limits.rb" # metric limits

set +e
docker run \
--read-only \
--rm \
--entrypoint="" \
--volume ${HOST_TEST_DIR}/config/check_metrics.rb:${CONTAINER_TMP_DIR}/check_metrics.rb:ro \
--volume ${HOST_REPORTS_DIR}/test_metrics.json:${CONTAINER_TMP_DIR}/test_metrics.json:ro \
--volume ${HOST_TEST_DIR}/config/test_metrics_limits.rb:${CONTAINER_TMP_DIR}/test_metrics_limits.rb:ro \
"${CYBER_DOJO_SAVER_IMAGE}:${CYBER_DOJO_SAVER_TAG}" \
sh -c "ruby ${CONTAINER_TMP_DIR}/check_metrics.rb ${CONTAINER_TMP_DIR}/test_metrics.json test_metrics_limits" \
| tee -a "${HOST_REPORTS_DIR}/${TEST_LOG}"

local -r STATUS=${PIPESTATUS[0]}
set -e

echo "${TYPE} test metrics status == ${STATUS}"
echo
return "${STATUS}"
}

check_coverage "$@"
2 changes: 1 addition & 1 deletion bin/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ run_tests_in_container()

set +e
docker exec \
--env COVERAGE_CODE_TAB_NAME=app \
--env COVERAGE_CODE_TAB_NAME=code \
--env COVERAGE_TEST_TAB_NAME=test \
--user "${USER}" \
"${CONTAINER_NAME}" \
Expand Down
35 changes: 35 additions & 0 deletions test/client/config/check_metrics.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

require 'json'

def coloured(arg)
red = 31
green = 32
colourize(arg ? green : red, arg)
end

def colourize(code, word)
"\e[#{code}m #{word} \e[0m"
end

data = JSON.parse(File.read(ARGV[0]))
require_relative ARGV[1] # metrics

results = []
metrics.each do |paths, op, limit|
if paths.nil?
puts
next
end
value = data
paths.split('.').each { |path| value = value[path] }

# puts "value=#{value}, op=#{op}, limit=#{limit}" # debug
result = eval("#{value} #{op} #{limit}")
puts '%s | %s %s %s | %s' % [
paths.rjust(35), value.to_s.rjust(5), " #{op}", limit.to_s.rjust(5), coloured(result)
]
results << result
end
puts
exit results.all?
Loading

0 comments on commit e90c04a

Please sign in to comment.