From cef6afe3aca644def6d8e9a270cf6ae72e62617f Mon Sep 17 00:00:00 2001 From: Costin Lupu Date: Mon, 15 Jan 2024 14:19:27 +0100 Subject: [PATCH] scripts/run_tests.sh: Extract reusable functionality The scripts/lib_tests.sh file provides functionality that can be reused in other tests running scripts as well. Signed-off-by: Costin Lupu --- scripts/lib_tests.sh | 159 +++++++++++++++++++++++++++++++++++++++++++ scripts/run_tests.sh | 134 ++++++------------------------------ 2 files changed, 180 insertions(+), 113 deletions(-) create mode 100755 scripts/lib_tests.sh diff --git a/scripts/lib_tests.sh b/scripts/lib_tests.sh new file mode 100755 index 00000000..d8235de0 --- /dev/null +++ b/scripts/lib_tests.sh @@ -0,0 +1,159 @@ +#!/bin/bash -x +# +# Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +# +TEST_SUITES_FAILED=0 +TEST_SUITES_TOTAL=0 + +SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +export NITRO_CLI_BLOBS="$SCRIPTDIR/../blobs" +export NITRO_CLI_ARTIFACTS="$SCRIPTDIR/../build" + +ARCH="$(uname -m)" +AWS_ACCOUNT_ID=667861386598 + +test_start() { + TEST_SUITES_TOTAL=$((TEST_SUITES_TOTAL + 1)) +} + +# Indicate that the test suite has failed +register_test_fail() { + TEST_SUITES_FAILED=$((TEST_SUITES_FAILED + 1)) +} + +# Force the test suite to end in failure +test_failed() { + register_test_fail + clean_up_and_exit +} + +# Clean up and exit with the current test suite's status +clean_up_and_exit() { + driver_unload nitro_enclaves || register_test_fail + + make clean + + enclaves_images_clean + + exit $TEST_SUITES_FAILED +} + +driver_is_not_loaded() { + local driver_name="$1" + [ "$(lsmod | grep -cw $driver_name)" -eq 0 ] +} + +driver_unload() { + local driver_name="$1" + driver_is_not_loaded $driver_name || rmmod $driver_name +} + +ne_driver_is_not_loaded() { + driver_is_not_loaded nitro_enclaves +} + +# Remove the Nitro Enclaves driver +ne_driver_remove() { + ne_driver_is_not_loaded || rmmod nitro_enclaves +} + +# Configure and insert the Nitro Enclaves driver +ne_driver_configure() { + if ne_driver_is_not_loaded; then + # Preallocate 2046 Mb, that should be enough for all the tests. We explicitly + # pick this value to have both 1 GB and 2 MB pages if the system allows it. + source build/install/etc/profile.d/nitro-cli-env.sh + ./build/install/etc/profile.d/nitro-cli-config -m 2046 -t 2 + fi +} + +build_and_install() { + # First run the instalation test, before we change the environement + pytest-3 tests/integration/test_installation.py + + # Clean up build artifacts + make clean + + # Setup the environment with everything needed to run the integration tests + make command-executer + make nitro-tests + make nitro_enclaves + make nitro-cli + make vsock-proxy + make install +} + +prepare_env() { + # Ensure the Nitro Enclaves driver is inserted + ne_driver_configure + + # Load vsock_loopback module for connection_test test of vsock-proxy + if driver_is_not_loaded vsock_loopback; then + modprobe vsock_loopback || echo "Module vsock_loopback not available." + fi + + # Create directories for enclave process sockets and logs + mkdir -p /run/nitro_enclaves + mkdir -p /var/log/nitro_enclaves +} + +IMAGES_DIR="test_images" +EXAMPLES_DIR="examples/$ARCH" +HELLO_ENTRYPOINT_DIR="$EXAMPLES_DIR/hello-entrypoint" +HELLO_ENTRYPOINT_URI="hello-entrypoint-usage" + +# Build EIFS for testing +enclaves_images_build() { + mkdir -p "$IMAGES_DIR" + + # (1) Simple EIF + nitro-cli build-enclave \ + --docker-uri public.ecr.aws/aws-nitro-enclaves/hello:v1 \ + --output-file "$IMAGES_DIR"/hello.eif + + # Generate signing certificate + openssl ecparam -name secp384r1 -genkey -out "$IMAGES_DIR"/key.pem + openssl req -new -key "$IMAGES_DIR"/key.pem -sha384 -nodes \ + -subj "/CN=AWS/C=US/ST=WA/L=Seattle/O=Amazon/OU=AWS" -out "$IMAGES_DIR"/csr.pem + openssl x509 -req -days 20 -in "$IMAGES_DIR"/csr.pem -out "$IMAGES_DIR"/cert.pem \ + -sha384 -signkey "$IMAGES_DIR"/key.pem + + # (2) Signed EIF + nitro-cli build-enclave \ + --docker-uri public.ecr.aws/aws-nitro-enclaves/hello:v1 \ + --output-file "$IMAGES_DIR"/hello-signed.eif \ + --private-key "$IMAGES_DIR"/key.pem \ + --signing-certificate "$IMAGES_DIR"/cert.pem + + # (3) Build enclave image using Docker ENTRYPOINT instruction + mkdir -p "$HELLO_ENTRYPOINT_DIR" + cp -r "$EXAMPLES_DIR"/hello/* "$HELLO_ENTRYPOINT_DIR" + + sed -i 's/CMD/ENTRYPOINT/g' "$HELLO_ENTRYPOINT_DIR/Dockerfile" + + nitro-cli build-enclave \ + --docker-dir "$HELLO_ENTRYPOINT_DIR" \ + --docker-uri $HELLO_ENTRYPOINT_URI \ + --output-file "$IMAGES_DIR"/$HELLO_ENTRYPOINT_URI.eif +} + +enclaves_images_clean() { + rm -rf "$IMAGES_DIR" + + # Cleanup pulled images during testing + docker rmi public.ecr.aws/aws-nitro-enclaves/hello:v1 2> /dev/null || true + docker rmi hello-world:latest 2> /dev/null || true + + rm -rf "$HELLO_ENTRYPOINT_DIR" + docker rmi $HELLO_ENTRYPOINT_URI:latest 2> /dev/null || true +} + +run_integration_tests() { + # Ensure the Nitro Enclaves driver is inserted for the remaining integration tests. + ne_driver_configure + + # Run integration tests except the installation test + pytest-3 tests/integration/ --ignore tests/integration/test_installation.py +} + diff --git a/scripts/run_tests.sh b/scripts/run_tests.sh index 816aab60..d7752db1 100755 --- a/scripts/run_tests.sh +++ b/scripts/run_tests.sh @@ -1,137 +1,45 @@ #!/bin/bash -x # -# Copyright 2020-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# Copyright 2020-2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 # # Script used for running all the tests we have on a EC2 instance that has # --enclave-options set to true # -TEST_SUITES_FAILED=0 -TEST_SUITES_TOTAL=0 SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -export NITRO_CLI_BLOBS="${SCRIPTDIR}/blobs" -export NITRO_CLI_ARTIFACTS="${SCRIPTDIR}/build" -ARCH="$(uname -m)" -AWS_ACCOUNT_ID=667861386598 +source "$SCRIPTDIR/lib_tests.sh" -# Indicate that the test suite has failed -function register_test_fail() { - TEST_SUITES_FAILED=$((TEST_SUITES_FAILED + 1)) -} +trap test_failed ERR -# Clean up and exit with the current test suite's status -function clean_up_and_exit() { - [ "$(lsmod | grep -cw nitro_enclaves)" -eq 0 ] || rmmod nitro_enclaves || register_test_fail - make clean - rm -rf test_images +# Build and install NE CLI +build_and_install - # Cleanup pulled images during testing - docker rmi public.ecr.aws/aws-nitro-enclaves/hello:v1 2> /dev/null || true - docker rmi hello-world:latest 2> /dev/null || true - - rm -rf examples/"${ARCH}"/hello-entrypoint - docker rmi hello-entrypoint-usage:latest 2> /dev/null || true - - exit $TEST_SUITES_FAILED -} - -# Force the test suite to end in failure -function test_failed() { - register_test_fail - clean_up_and_exit -} - -# Remove the Nitro Enclaves driver -function remove_ne_driver() { - [ "$(lsmod | grep -cw nitro_enclaves)" -eq 0 ] || rmmod nitro_enclaves || test_failed -} - -# Configure and insert the Nitro Enclaves driver -function configure_ne_driver() { - if [ "$(lsmod | grep -cw nitro_enclaves)" -eq 0 ] - then - # Preallocate 2046 Mb, that should be enough for all the tests. We explicitly - # pick this value to have both 1 GB and 2 MB pages if the system allows it. - source build/install/etc/profile.d/nitro-cli-env.sh || test_failed - ./build/install/etc/profile.d/nitro-cli-config -m 2046 -t 2 || test_failed - fi -} - -# First run the instalation test, before we change the environement -pytest-3 tests/integration/test_installation.py || test_failed - -# Clean up build artefacts -make clean - -# Setup the environement with everything needed to run the integration tests -make command-executer || test_failed -make nitro-tests || test_failed -make nitro_enclaves || test_failed -make nitro-cli || test_failed -make vsock-proxy || test_failed -make install || test_failed - -# Ensure the Nitro Enclaves driver is inserted at the beginning. -configure_ne_driver - -# Create directories for enclave process sockets and logs -mkdir -p /run/nitro_enclaves || test_failed -mkdir -p /var/log/nitro_enclaves || test_failed +# Prepare environment +prepare_env # Build EIFS for testing -mkdir -p test_images || test_failed -export HOME="/root" - -# Simple EIF -nitro-cli build-enclave --docker-uri public.ecr.aws/aws-nitro-enclaves/hello:v1 \ - --output-file test_images/hello.eif || test_failed - -# Generate signing certificate -openssl ecparam -name secp384r1 -genkey -out test_images/key.pem || test_failed -openssl req -new -key test_images/key.pem -sha384 -nodes \ - -subj "/CN=AWS/C=US/ST=WA/L=Seattle/O=Amazon/OU=AWS" -out test_images/csr.pem || test_failed -openssl x509 -req -days 20 -in test_images/csr.pem -out test_images/cert.pem \ - -sha384 -signkey test_images/key.pem || test_failed -# Signed EIF -nitro-cli build-enclave --docker-uri public.ecr.aws/aws-nitro-enclaves/hello:v1 \ - --output-file test_images/hello-signed.eif \ - --private-key test_images/key.pem --signing-certificate test_images/cert.pem || test_failed - - -# Build enclave image using Docker ENTRYPOINT instruction -mkdir -p examples/"${ARCH}"/hello-entrypoint || test_failed -cp -r examples/"${ARCH}"/hello/* examples/"${ARCH}"/hello-entrypoint || test_failed - -sed -i 's/CMD/ENTRYPOINT/g' examples/"${ARCH}"/hello-entrypoint/Dockerfile || test_failed - -nitro-cli build-enclave --docker-dir examples/"${ARCH}"/hello-entrypoint --docker-uri hello-entrypoint-usage \ - --output-file test_images/hello-entrypoint-usage.eif || test_failed - -# Load vsock_loopback module for connection_test test of vsock-proxy -if [ "$(lsmod | grep -cw vsock_loopback)" -eq 0 ]; then - modprobe vsock_loopback || echo "Module vsock_loopback not available." -fi +enclaves_images_build # Run all unit tests -while IFS= read -r test_line -do - TEST_SUITES_TOTAL=$((TEST_SUITES_TOTAL + 1)) - test_module="$(echo ${test_line} | cut -d' ' -f2)" - test_exec_name="$(basename $(echo ${test_line} | cut -d' ' -f1))" +while IFS= read -r test_line; do + test_start + test_module="$(echo $test_line | cut -d' ' -f2)" + test_exec_name="$(basename $(echo $test_line | cut -d' ' -f1))" + + echo "Test module=$test_module executable=$test_exec_name" - configure_ne_driver + ne_driver_configure timeout 7m \ - ./build/nitro_cli/"${ARCH}"-unknown-linux-musl/release/deps/"${test_exec_name}" \ - --test-threads=1 --nocapture || test_failed + ./build/nitro_cli/$ARCH-unknown-linux-musl/release/deps/$test_exec_name \ + --test-threads=1 --nocapture done < <(grep -v '^ *#' < build/test_executables.txt) -# Ensure the Nitro Enclaves driver is inserted for the remaining integration tests. -configure_ne_driver - -# Run integration tests except the instalation test -pytest-3 tests/integration/ --ignore tests/integration/test_installation.py || test_failed +# Run integration tests +run_integration_tests +# Clean-up clean_up_and_exit +