Skip to content

Commit

Permalink
scripts/run_tests.sh: Extract reusable functionality
Browse files Browse the repository at this point in the history
The scripts/lib_tests.sh file provides functionality that can be reused
in other tests running scripts as well.

Signed-off-by: Costin Lupu <[email protected]>
  • Loading branch information
clupuishere committed Jan 19, 2024
1 parent 3c7f1e0 commit cef6afe
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 113 deletions.
159 changes: 159 additions & 0 deletions scripts/lib_tests.sh
Original file line number Diff line number Diff line change
@@ -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
}

134 changes: 21 additions & 113 deletions scripts/run_tests.sh
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit cef6afe

Please sign in to comment.