diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f04e4033..6f5e33ad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,3 +42,11 @@ jobs: run: docker build -t tpm-provider e2e_tests/provider_cfg/tpm - name: Run the container to execute the test script run: docker run -v $(pwd):/tmp/parsec -w /tmp/parsec tpm-provider /tmp/parsec/ci.sh tpm + + installation-tests: + name: Installation tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Build and run the container + run: e2e_tests/installation_tests/run-installation-tests.sh diff --git a/e2e_tests/installation_tests/Dockerfile b/e2e_tests/installation_tests/Dockerfile new file mode 100644 index 00000000..22964814 --- /dev/null +++ b/e2e_tests/installation_tests/Dockerfile @@ -0,0 +1,38 @@ +FROM ubuntu:18.04 + +ENV container docker + +RUN apt-get update +RUN apt-get install -y git make gcc python3 python curl wget cmake \ + automake autoconf libtool pkg-config libssl-dev \ + # These libraries are needed for bindgen as it uses + # libclang.so + clang libclang-dev libc6-dev-i386 +RUN apt-get install -y systemd systemd-sysv +RUN apt-get clean + +RUN useradd -m parsec +RUN groupadd parsec-clients +RUN usermod -a -G parsec-clients parsec + +USER parsec +WORKDIR /home/parsec + +# Install Rust toolchain. +RUN curl https://sh.rustup.rs -sSf | bash -s -- -y +ENV PATH "/home/parsec/.cargo/bin:$PATH" + +# Install Parsec. +RUN cargo install parsec-service --features mbed-crypto-provider +RUN git clone https://github.com/parallaxsecond/parsec.git +RUN cp parsec/config.toml config.toml + +# Install the systemd unit files. +RUN mkdir -p .config/systemd/user +RUN cp parsec/systemd-daemon/parsec.service .config/systemd/user/parsec.service + +USER root +WORKDIR /root +COPY context/run-tests.sh ./ +VOLUME [ "/sys/fs/cgroup" ] +CMD [ "/lib/systemd/systemd" ] diff --git a/e2e_tests/installation_tests/context/run-tests.sh b/e2e_tests/installation_tests/context/run-tests.sh new file mode 100755 index 00000000..39404cab --- /dev/null +++ b/e2e_tests/installation_tests/context/run-tests.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +set -euo pipefail +IFS=$'\n\t' + +function test_ping_parsec() { + # Creates a new test user, adds them to the parsec-clients group, and + # checks that the Parsec service can be pinged. + + useradd -m test-user-1 + usermod -a -G parsec-clients test-user-1 + + su test-user-1 <<' EOSU' + set -eu + cd ${HOME} + curl https://sh.rustup.rs -sSf | bash -s -- -y + export PATH="${HOME}/.cargo/bin:$PATH" + + git clone https://github.com/parallaxsecond/parsec-tool.git + cd parsec-tool + cargo build + + set +e + cargo run -- ping + + # This test passes if the above command pinged the Parsec service + # successfully. + [ $? -eq 0 ] + EOSU +} + +function test_ping_parsec_not_in_group() { + # Creates a new test user, and tries to ping the Parsec service. This + # should fail, since the user is not in the appropriate group. + + useradd -m test-user-2 + + su test-user-2 <<' EOSU' + set -eu + cd ${HOME} + curl https://sh.rustup.rs -sSf | bash -s -- -y + export PATH="${HOME}/.cargo/bin:$PATH" + + git clone https://github.com/parallaxsecond/parsec-tool.git + cd parsec-tool + cargo build + + set +e + cargo run -- ping + + # This test passes if the above command failed to ping the Parsec service. + [ $? -ne 0 ] + EOSU +} + +function install_parsec() { + mkdir /tmp/parsec + chown parsec:parsec-clients /tmp/parsec + chown -R parsec:parsec /home/parsec + chmod 750 /tmp/parsec + + # Configure and start the Parsec service as user `parsec`. + su parsec << ' EOSU' + set -eu + export PATH="${HOME}/.cargo/bin:$PATH" + cargo install --path ${HOME}/parsec --features 'mbed-crypto-provider' + mkdir -p ${HOME}/.config/systemd/user + cp ${HOME}/parsec/systemd-daemon/parsec.service \ + ${HOME}/.config/systemd/user/parsec.service + + systemctl --user daemon-reload + systemctl --user start parsec + EOSU +} + +function main() { + install_parsec + + # Register tests. + declare -a TESTS + TESTS[1]="test_ping_parsec" + TESTS[2]="test_ping_parsec_not_in_group" + + # Run tests. + NUM_FAILED=0 + for i in "${!TESTS[@]}"; do + TEST_NAME="${TESTS[$i]}" + echo "=== RUNNING TEST ${TEST_NAME} ===" + if ${TESTS[$i]}; then + echo "${TEST_NAME} passed." + else + echo "${TEST_NAME} failed!" + NUM_FAILED=$((NUM_FAILED + 1)) + fi + echo "" # spacing + done + + if [[ ${NUM_FAILED} -eq 0 ]]; then + echo "All tests passed!" + else + echo "${NUM_FAILED} test(s) failed!" + fi + + return ${NUM_FAILED} +} + +main "${@}" || exit 1 diff --git a/e2e_tests/installation_tests/run-installation-tests.sh b/e2e_tests/installation_tests/run-installation-tests.sh new file mode 100755 index 00000000..44668901 --- /dev/null +++ b/e2e_tests/installation_tests/run-installation-tests.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +set -euo pipefail +IFS=$'\n\t' + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +DOCKER_IMAGE_DIR="$SCRIPT_DIR" +DOCKER_IMAGE_NAME="parsec" + +docker build -t ${DOCKER_IMAGE_NAME} ${DOCKER_IMAGE_DIR} +DOCKER_CONTAINER_ID=$(docker run -d \ + --rm \ + --tmpfs /run \ + --tmpfs /run/lock \ + --tmpfs /tmp:exec \ + -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ + -v $(git rev-parse --show-toplevel):/home/parsec/parsec \ + ${DOCKER_IMAGE_NAME}) + +# Give the systemd daemon some time to spin up. +sleep 3 + +echo "Running tests inside container..." +docker exec ${DOCKER_CONTAINER_ID} /root/run-tests.sh +TEST_STATUS=$? + +echo "Testing complete, stopping container." +docker stop ${DOCKER_CONTAINER_ID} + +exit ${TEST_STATUS}