Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CI: Add scripts to run samples automatically #829

Merged
merged 4 commits into from
Sep 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
28 changes: 7 additions & 21 deletions samples/basic/helloworld/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,25 +1,11 @@
FROM alpine:3.8
FROM alpine:3.6 AS builder

ARG UID
ARG GID
RUN apk add --no-cache gcc musl-dev

USER root
ADD *.c /
RUN gcc -g -o helloworld helloworld.c

# Build packages: build-base gcc wget git curl
FROM alpine:3.6

RUN apk add --no-cache bash shadow sudo && \
addgroup -S alpine; \
adduser -S -G alpine -s /bin/bash user; \
echo "user ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/user && \
chmod 0440 /etc/sudoers.d/user

WORKDIR /app
RUN chown user:alpine /app
USER user

#ENV PS1="\[\033[31;40;1m\][\u@\h]\[\033[32;40;1m\] \W\[\033[33;40;1m\]>\[\033[0m\]"

COPY --chown=user:alpine app/ .

# Start from a Bash prompt
CMD ["/bin/bash"]
COPY --from=builder helloworld .
ADD app /app
66 changes: 25 additions & 41 deletions samples/basic/helloworld/Makefile
Original file line number Diff line number Diff line change
@@ -1,57 +1,41 @@
include ../../../tests/common.mk

APP_ROOT=app
PROG=${APP_ROOT}/helloworld
PROG_NONPIE=${APP_ROOT}/helloworld-nonpie
PROG_C=helloworld.c
PROG=helloworld
PROG_SRC=$(PROG).c
IMAGE_SIZE=5M

DISK_IMAGE=sgxlkl-helloworld.img
IMAGE_SIZE=100M
EXECUTION_TIMEOUT=60

SGXLKL_ROOT=../../..
SGXLKL_ENV=SGXLKL_VERBOSE=1 SGXLKL_KERNEL_VERBOSE=1
SGXLKL_HW_PARAMS=--hw-debug
SGXLKL_SW_PARAMS=--sw-debug

MUSL_CC=${SGXLKL_ROOT}/build/host-musl/bin/musl-gcc

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

ifeq ($(SGXLKL_VERBOSE),)
SGXLKL_ENV=\
SGXLKL_VERBOSE=1 SGXLKL_KERNEL_VERBOSE=0 SGXLKL_TRACE_SIGNAL=0\
SGXLKL_TRACE_HOST_SYSCALL=0 SGXLKL_TRACE_LKL_SYSCALL=0 SGXLKL_TRACE_MMAP=0
else
SGXLKL_ENV=
endif

SGXLKL_DISK_TOOL=${SGXLKL_ROOT}/tools/sgx-lkl-disk
SGXLKL_GDB=${SGXLKL_ROOT}/tools/gdb/sgx-lkl-gdb
SGXLKL_ROOTFS=sgx-lkl-rootfs.img

.DELETE_ON_ERROR:
.PHONY: all clean

all: $(DISK_IMAGE)
$(SGXLKL_ROOTFS): $(PROG_SRC)
${SGXLKL_DISK_TOOL} create --size=${IMAGE_SIZE} --docker=./Dockerfile ${SGXLKL_ROOTFS}

clean:
rm -f $(DISK_IMAGE) $(PROG) $(PROG_NONPIE)

$(PROG): $(PROG_C)
${MUSL_CC} -fPIE -pie -o $@ $(PROG_C)
gettimeout:
@echo ${EXECUTION_TIMEOUT}

# non-PIE executable are currently unsupported by SGX-LKL-OE
$(PROG_NONPIE): $(PROG_C)
${MUSL_CC} -fno-pie -no-pie -o $@ $(PROG_C)
run: run-hw run-sw

$(DISK_IMAGE): $(PROG) $(PROG_NONPIE)
${SGXLKL_DISK_TOOL} create --size=${IMAGE_SIZE} --copy=./${APP_ROOT}/ ${DISK_IMAGE}
run-gdb: run-hw-gdb

run: run-hw
run-hw: ${SGXLKL_ROOTFS}
$(SGXLKL_ENV) $(SGXLKL_STARTER) $(SGXLKL_HW_PARAMS) --enclave-config enclave_config.json $(SGXLKL_ROOTFS) $(PROG)

run-hw: $(DISK_IMAGE)
${SGXLKL_ENV} ${SGXLKL_STARTER} --hw-debug --enclave-config enclave_config.json $(DISK_IMAGE)
run-sw: ${SGXLKL_ROOTFS}
$(SGXLKL_ENV) $(SGXLKL_STARTER) $(SGXLKL_SW_PARAMS) --enclave-config enclave_config.json $(SGXLKL_ROOTFS) $(PROG)

run-hw-gdb: $(DISK_IMAGE)
${SGXLKL_ENV} ${SGXLKL_GDB} --args ${SGXLKL_STARTER} --hw-debug --enclave-config enclave_config.json $(DISK_IMAGE)
run-hw-gdb: ${SGXLKL_ROOTFS}
$(SGXLKL_ENV) $(SGXLKL_GDB) --args $(SGXLKL_STARTER) $(SGXLKL_HW_PARAMS) --enclave-config enclave_config.json $(SGXLKL_ROOTFS) $(PROG)

run-sw: $(DISK_IMAGE)
${SGXLKL_ENV} ${SGXLKL_STARTER} --sw-debug --enclave-config enclave_config.json $(DISK_IMAGE)
run-sw-gdb: ${SGXLKL_ROOTFS}
$(SGXLKL_ENV) $(SGXLKL_GDB) --args $(SGXLKL_STARTER) $(SGXLKL_SW_PARAMS) --enclave-config enclave_config.json $(SGXLKL_ROOTFS) $(PROG)

run-sw-gdb: $(DISK_IMAGE)
${SGXLKL_ENV} ${SGXLKL_GDB} --args ${SGXLKL_STARTER} --sw-debug --enclave-config enclave_config.json $(DISK_IMAGE)
clean:
rm -f $(SGXLKL_ROOTFS) $(PROG)
3 changes: 2 additions & 1 deletion samples/basic/helloworld/helloworld.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ int main(int argc, char** argv)
{
fprintf(
stderr, "Could not open file %s: %s\n", HW_FILE, strerror(errno));
fprintf(stderr, "TEST_FAILED");
exit(1);
}

Expand All @@ -28,8 +29,8 @@ int main(int argc, char** argv)
"Could not read first line of file %s: %s\n",
HW_FILE,
strerror(errno));
fprintf(stderr, "TEST_FAILED");
exit(1);
}

return 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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is 1 second and it is too short to be default value. May be 60 seconds is better.

Copy link
Contributor Author

@AntonioND AntonioND Sep 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this means "default". This is how it works in the case of the Makefiles of the tests. If there is no target called gettimeout, make will return 1. If the target is there, it prints the timeout length.

Take a look at tests/ltp/batch.mk, target gettimeout, for example.

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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are already exported in Makefile. Do we need to export again? Also SGXLKL_SETUP_TOOL exists in common.sh and not in common.mk just FYI

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some samples need this in the bash script because not all of the commands are run in the Makefile. For example, SGXLKL_SETUP_TOOL is needed in containers/redis/test.sh. A couple of them are needed in languages/python/test.sh.

I only added SGXLKL_SETUP_TOOL to the bash script because it's not needed in the Makefiles.

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
Loading