Skip to content

Commit

Permalink
CI: Add scripts to run samples automatically
Browse files Browse the repository at this point in the history
The scripts are a mix of bash and a bit of GNU expect for flexibility,
as each sample needs to be tested in slightly different ways.

Each sample must have a test.sh script in its folder so that the CI
detects it and runs it. They are executed by run_sample.sh script,
created using run_test.sh as an example.

This commit adds several samples to the CI, but not all of them:

- The ml folder samples, for example, take far too long to be part of a
  regular CI run, and need caching of docker images, which is a task on
  its own.

- The openmp and nodejs samples seem to be broken.
  • Loading branch information
AntonioND committed Sep 23, 2020
1 parent d0bb924 commit f8f09a3
Show file tree
Hide file tree
Showing 27 changed files with 406 additions and 34 deletions.
1 change: 1 addition & 0 deletions .azure-pipelines/scripts/install_prerequisites.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ sudo apt-get install -y \
autopoint pkgconf autoconf libtool libcurl4-openssl-dev libprotobuf-dev libprotobuf-c-dev protobuf-compiler protobuf-c-compiler libssl-dev \
ninja-build ansible "linux-headers-$(uname -r)" \
python3 python3-setuptools python3-pip unzip dkms debhelper apt-utils pax-utils openjdk-8-jdk-headless \
redis-tools \
expect \
gdb \
shellcheck clang-format
Expand Down
86 changes: 86 additions & 0 deletions .azure-pipelines/scripts/run_sample.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/bin/bash

if [ -z "$SGXLKL_ROOT" ]; then
echo "ERROR: 'SGXLKL_ROOT' is undefined. Please export SGXLKL_ROOT=<SGX-LKL-OE> source code repository"
exit 1
fi
if [ -z "$SGXLKL_BUILD_MODE" ]; then
echo "ERROR: 'SGXLKL_BUILD_MODE' is undefined. Please export SGXLKL_BUILD_MODE=<mode>"
exit 1
fi

#shellcheck source=.azure-pipelines/scripts/junit_utils.sh
. "$SGXLKL_ROOT/.azure-pipelines/scripts/junit_utils.sh"
#shellcheck source=.azure-pipelines/scripts/test_utils.sh
. "$SGXLKL_ROOT/.azure-pipelines/scripts/test_utils.sh"

# Initialize the variables and test case [mandatory].
sample_mode=$1 # clean, init or run
run_mode=$2 # run-hw or run-sw

if [[ "$sample_mode" == "clean" ]]; then
./test.sh clean
exit $?
fi

samples_dir=$SGXLKL_ROOT/samples
sample_name="$(realpath --relative-to="$samples_dir" "$(pwd)")"
sample_name="${sample_name//\//-}"
sample_name+="-($SGXLKL_BUILD_MODE)-($run_mode)-($SGXLKL_ETHREADS-ethreads)"
sample_class=$(realpath --relative-to="$samples_dir" "$(pwd)/..")
test_suite="sgx-lkl-oe"

if [[ -z $sample_name || -z $sample_class || -z $sample_mode ]]; then
echo -e "\n ERROR: sample_name sample_class or sample_mode not passed \n"
exit 1
fi

if [[ "$sample_mode" == "init" ]]; then
InitializeTestCase "$sample_name" "$sample_class" "$test_suite" "$run_mode"
fi

# Get the timeout from the test module
DEFAULT_TIMEOUT=300
if ! timeout=$(./test.sh gettimeout 2> /dev/null); then
timeout=$DEFAULT_TIMEOUT
fi
echo "Execution timeout: $timeout"

case "$run_mode" in
"run-hw")
echo "Will run samples for run-hw"
;;
"run-sw")
echo "Will run samples for run-sw"
;;
*)
echo "Invalid run_mode parameter: $run_mode. Valid options: run-hw/run-sw"
exit 1;
;;
esac

if [[ $sample_mode == "init" ]]; then
timeout --kill-after=$((timeout + 60)) $timeout ./test.sh init
script_exit=$?
elif [[ $sample_mode == "run" ]]; then
timeout --kill-after=$((timeout + 60)) $timeout ./test.sh run "$run_mode"
script_exit=$?
else
echo "Invalid sample_mode parameter: $sample_mode. Valid options: clean/init/run/gettimeout"
exit 1
fi

if [[ "$script_exit" == "124" ]]; then
echo "$run_mode: TIMED OUT after $timeout secs"
elif [[ "$script_exit" != "0" ]]; then
echo "$run_mode: FAILED WITH EXIT CODE: $script_exit"
fi

if [[ $sample_mode == "init" ]]; then
echo "Sample initialization completed with EXIT CODE $script_exit"
return $script_exit
fi

echo "Sample run completed with EXIT CODE $script_exit"

exit $script_exit
2 changes: 1 addition & 1 deletion .azure-pipelines/scripts/run_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fi
. "$SGXLKL_ROOT/.azure-pipelines/scripts/test_utils.sh"

# Initialize the variables and test case [mandatory].
test_mode=$1 # init or run
test_mode=$1 # clean, init or run
run_mode=$2 # run-hw or run-sw

# make clean
Expand Down
7 changes: 7 additions & 0 deletions .azure-pipelines/scripts/test_runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ disabled_tests_file="$SGXLKL_ROOT/.azure-pipelines/other/disabled_tests.txt"
nightly_tests_file="$SGXLKL_ROOT/.azure-pipelines/other/nightly_run_only_tests.txt"
# test which needs not to be executed as part of CI e.g (test_name1\|test_name2...)
test_exception_list="ltp"
sample_exception_list="openmp\|nodejs"

failure_identifiers_file="$SGXLKL_ROOT/.azure-pipelines/other/failure_identifiers.txt"
IFS=$'\n'
Expand All @@ -191,6 +192,12 @@ if [[ $1 == "ltp1" ]]; then
elif [[ $1 == "ltp2" ]]; then
file_list=("tests/ltp/ltp-batch2/Makefile")
test_group_name="ltp-batch2"
elif [[ $1 == "samples" ]]; then
test_folder_name="samples"
test_folder_identifier="test.sh"
test_runner_script="$SGXLKL_ROOT/.azure-pipelines/scripts/run_sample.sh"
file_list=( $(find $test_folder_name -name $test_folder_identifier | grep -v "$sample_exception_list") )
test_group_name="samples"
elif [[ $1 == "core" ]]; then
file_list=( $(find $test_folder_name -name $test_folder_identifier | grep -v "$test_exception_list") )
test_group_name="core"
Expand Down
1 change: 1 addition & 0 deletions .azure-pipelines/template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ parameters:
- core
- ltp1
- ltp2
- samples
- name: 'ethreads'
type: object
default:
Expand Down
13 changes: 13 additions & 0 deletions samples/basic/attack/plain-docker.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/expect -f

set timeout -1

spawn docker run --rm attackme /read_secret
set dockerID $spawn_id
expect -i $dockerID "Ready to be attacked..."

spawn ./read_memory.sh read_secret Secret42!
set readID $spawn_id
expect -i $readID "Match found."

send -i $dockerID -- "\r"
2 changes: 1 addition & 1 deletion samples/basic/attack/read_memory.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ sudo chown "$(id -u -n):$(id -g -n)" "$mem_file"

echo "Searching memory for string \"${search_string}\" in \"${mem_file}\"..."

if (strings "${mem_file}" | grep -i "${search_string}"); then
if grep -Fxq "${search_string}" "${mem_file}"; then
echo Match found.
else
echo No match found.
Expand Down
21 changes: 21 additions & 0 deletions samples/basic/attack/sgx.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/expect -f

set SGXLKL_STARTER "$env(SGXLKL_STARTER)"
set SGXLKL_DISK_TOOL "$env(SGXLKL_DISK_TOOL)"

set timeout -1

spawn "$SGXLKL_DISK_TOOL" create --force --docker=attackme --size 5M --encrypt --key-file rootfs.img
expect "Succesfully created rootfs.img"
expect eof

set env(SGXLKL_HD_KEY) rootfs.img.key
spawn "$SGXLKL_STARTER" --hw-debug rootfs.img /read_secret
set oeID $spawn_id
expect -i $oeID "Ready to be attacked..."

spawn ./read_memory.sh sgx-lkl-run-oe Secret42!
set readID $spawn_id
expect -i $readID "No match found."

send -i $oeID -- "\r"
27 changes: 27 additions & 0 deletions samples/basic/attack/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash

# shellcheck source=/dev/null
source "../../common.sh"

test_mode=$1
run_mode=$2

set -e

if [[ "$test_mode" == "clean" ]]; then
rm -f rootfs.img rootfs.img.docker rootfs.img.key
elif [[ "$test_mode" == "init" ]]; then
rm -f mem.dump.*
docker build -t attackme .
elif [[ "$test_mode" == "run" ]]; then
if [[ "$run_mode" == "run-sw" ]]; then
./plain-docker.exp
elif [[ "$run_mode" == "run-hw" ]]; then
./sgx.exp
fi
elif [[ "$test_mode" == "gettimeout" ]]; then
# 20 minutes
echo 1200
fi

exit 0
19 changes: 19 additions & 0 deletions samples/basic/helloworld/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash

test_mode=$1
run_mode=$2

set -e

if [[ "$test_mode" == "clean" ]]; then
make clean
elif [[ "$test_mode" == "init" ]]; then
make
elif [[ "$test_mode" == "run" ]]; then
make "$run_mode"
elif [[ "$test_mode" == "gettimeout" ]]; then
# Default
exit 1
fi

exit 0
20 changes: 20 additions & 0 deletions samples/common.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
samples_dir=$(dirname $(realpath "$BASH_SOURCE"))
SGXLKL_ROOT=$(realpath "${samples_dir}/..")

if [[ -z "${SGXLKL_PREFIX}" ]]; then
export SGXLKL_STARTER=${SGXLKL_ROOT}/build/sgx-lkl-run-oe
export SGXLKL_DISK_TOOL=${SGXLKL_ROOT}/tools/sgx-lkl-disk
export SGXLKL_DOCKER_TOOL=${SGXLKL_ROOT}/tools/sgx-lkl-docker
export SGXLKL_CFG_TOOL=${SGXLKL_ROOT}/tools/sgx-lkl-cfg
export SGXLKL_SETUP_TOOL=${SGXLKL_ROOT}/tools/sgx-lkl-setup
export SGXLKL_GDB=${SGXLKL_ROOT}/tools/gdb/sgx-lkl-gdb
export SGXLKL_JAVA_RUN=${SGXLKL_ROOT}/tools/sgx-lkl-java
else
export SGXLKL_STARTER=${SGXLKL_PREFIX}/bin/sgx-lkl-run-oe
export SGXLKL_DISK_TOOL=${SGXLKL_PREFIX}/bin/sgx-lkl-disk
export SGXLKL_DOCKER_TOOL=${SGXLKL_PREFIX}/bin/sgx-lkl-docker
export SGXLKL_CFG_TOOL=${SGXLKL_PREFIX}/bin/sgx-lkl-cfg
export SGXLKL_SETUP_TOOL=${SGXLKL_PREFIX}/bin/sgx-lkl-setup
export SGXLKL_GDB=${SGXLKL_PREFIX}/bin/sgx-lkl-gdb
export SGXLKL_JAVA_RUN=${SGXLKL_PREFIX}/bin/sgx-lkl-java
fi
18 changes: 18 additions & 0 deletions samples/containers/alpine/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

test_mode=$1

set -e

if [[ "$test_mode" == "clean" ]]; then
make clean
elif [[ "$test_mode" == "init" ]]; then
echo "Nothing to do"
elif [[ "$test_mode" == "run" ]]; then
make
elif [[ "$test_mode" == "gettimeout" ]]; then
# Default
exit 1
fi

exit 0
7 changes: 1 addition & 6 deletions samples/containers/encrypted/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

SGXLKL_ROOT=../../..
include ../../../tests/common.mk

CC_APP=/usr/bin/python3
CC_APP_CMDLINE=${CC_APP} -c 'print("Hello SGX World from Encrypted Confidential Container!")'
Expand Down Expand Up @@ -39,10 +38,6 @@ ifeq ($(SGXLKL_VERBOSE),)
SGXLKL_ENV_APP_CONFIG+=${VERBOSE_OPTS}
endif

SGXLKL_STARTER=$(SGXLKL_ROOT)/build/sgx-lkl-run-oe
SGXLKL_DISK_TOOL=${SGXLKL_ROOT}/tools/sgx-lkl-disk
SGXLKL_GDB=${SGXLKL_ROOT}/tools/gdb/sgx-lkl-gdb

.DELETE_ON_ERROR:
.PHONY: all clean run run-hw-verity run-sw-verity run-hw-integrity run-sw-integrity

Expand Down
21 changes: 21 additions & 0 deletions samples/containers/encrypted/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

test_mode=$1
run_mode=$2

set -e

if [[ "$test_mode" == "clean" ]]; then
make clean
elif [[ "$test_mode" == "init" ]]; then
make
elif [[ "$test_mode" == "run" ]]; then
make "$run_mode"-verity
# TODO: This doesn't work
#make "$run_mode"-integrity
elif [[ "$test_mode" == "gettimeout" ]]; then
# Default
exit 1
fi

exit 0
8 changes: 1 addition & 7 deletions samples/containers/redis/Makefile
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
include ../../../tests/common.mk

PROG=/usr/bin/redis-server

DISK_IMAGE=sgxlkl-redis.img
IMAGE_SIZE=128M

SGXLKL_ROOT=../../..

ENCLAVE_CMD=${PROG} --bind 10.0.1.1

SGXLKL_STARTER=$(SGXLKL_ROOT)/build/sgx-lkl-run-oe

SGXLKL_ENV=\
SGXLKL_TAP=sgxlkl_tap0

Expand All @@ -19,9 +16,6 @@ SGXLKL_ENV+=\
SGXLKL_TRACE_HOST_SYSCALL=0 SGXLKL_TRACE_LKL_SYSCALL=0 SGXLKL_TRACE_MMAP=0
endif

SGXLKL_DISK_TOOL=${SGXLKL_ROOT}/tools/sgx-lkl-disk
SGXLKL_GDB=${SGXLKL_ROOT}/tools/gdb/sgx-lkl-gdb

.DELETE_ON_ERROR:
.PHONY: all clean

Expand Down
11 changes: 7 additions & 4 deletions samples/containers/redis/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
Running Redis with SGX-LKL-OE
=============================

1. Ensure that you have set up netoworking and TLS support by running `tools/sgx-lkl-setup`.
1. Make sure that you have installed ``redis-cli``. In Ubuntu, the package that
contains it is called ``redis-tools``.

2. Build the Redis file sytem image:
2. Ensure that you have set up netoworking and TLS support by running `tools/sgx-lkl-setup`.

3. Build the Redis file sytem image:

```
make
```

3. Run the Redis service with:
4. Run the Redis service with:

```
make run-hw
Expand All @@ -21,7 +24,7 @@ or
make run-sw
```

4. Execute client requests against this instance:
5. Execute client requests against this instance:

```
./run-redis-client.sh
Expand Down
15 changes: 15 additions & 0 deletions samples/containers/redis/run-hw.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/expect -f

set timeout -1

spawn make run-hw
set serverID $spawn_id
expect -i $serverID "Ready to accept connections"

spawn ./run-redis-client.sh
set clientID $spawn_id
expect -i $clientID "Test succeeded"

send -i $serverID -- ""

exit 0
7 changes: 5 additions & 2 deletions samples/containers/redis/run-redis-client.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

# printf '\033]2;%s\033\\' 'Redis Client'

set -e

COUNTER=0

while :
while [ $COUNTER -lt 10 ]
do
echo $ redis-cli -h 10.0.1.1 -p 6379 set samplekey value${COUNTER}
redis-cli -h 10.0.1.1 -p 6379 set samplekey value${COUNTER}
echo $ redis-cli -h 10.0.1.1 -p 6379 get samplekey
redis-cli -h 10.0.1.1 -p 6379 get samplekey
sleep 1
let COUNTER+=1
done

echo "Sample succeeded"
Loading

0 comments on commit f8f09a3

Please sign in to comment.