Skip to content

Commit

Permalink
tests: add rootless integration tests
Browse files Browse the repository at this point in the history
This adds targets for rootless integration tests, as well as all of the
required setup in order to get the tests to run. This includes quite a
few changes, because of a lot of assumptions about things running as
root within the bats scripts (which is not true when setting up rootless
containers).

Signed-off-by: Aleksa Sarai <asarai@suse.de>
  • Loading branch information
cyphar committed Mar 23, 2017
1 parent 2ce3357 commit ba38383
Show file tree
Hide file tree
Showing 14 changed files with 117 additions and 24 deletions.
7 changes: 7 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ RUN echo 'deb http://httpredir.debian.org/debian jessie-backports main' > /etc/a
RUN apt-get update && apt-get install -y \
build-essential \
curl \
sudo \
gawk \
iptables \
jq \
Expand All @@ -22,6 +23,12 @@ RUN apt-get update && apt-get install -y \
--no-install-recommends \
&& apt-get clean

# Add a dummy user for the rootless integration tests. While runC does
# not require an entry in /etc/passwd to operate, one of the tests uses
# `git clone` -- and `git clone` does not allow you to clone a
# repository if the current uid does not have an entry in /etc/passwd.
RUN useradd -u1000 -m -d/home/rootless -s/bin/bash rootless

# install bats
RUN cd /tmp \
&& git clone https://github.com/sstephenson/bats.git \
Expand Down
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ runcimage:
docker build -t $(RUNC_IMAGE) .

test:
make unittest integration
make unittest integration rootlessintegration

localtest:
make localunittest localintegration
make localunittest localintegration localrootlessintegration

unittest: runcimage
docker run -e TESTFLAGS -t --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) $(RUNC_IMAGE) make localunittest
Expand All @@ -96,6 +96,13 @@ integration: runcimage
localintegration: all
bats -t tests/integration${TESTFLAGS}

rootlessintegration: runcimage
docker run -e TESTFLAGS -t --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) --cap-drop=ALL -u rootless $(RUNC_IMAGE) make localintegration

# FIXME: This should not be separate from rootlessintegration's method of running.
localrootlessintegration: all
sudo -u rootless -H PATH="${PATH}" bats -t tests/integration${TESTFLAGS}

shell: all
docker run -e TESTFLAGS -ti --privileged --rm -v $(CURDIR):/go/src/$(PROJECT) $(RUNC_IMAGE) bash

Expand Down
5 changes: 3 additions & 2 deletions tests/integration/checkpoint.bats
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ function teardown() {
[[ "${output}" == *"running"* ]]
}

@test "checkpoint(pre-dump) and restore" {
requires criu
@test "checkpoint --pre-dump and restore" {
# XXX: currently criu require root containers.
requires criu root

# criu does not work with external terminals so..
# setting terminal and root:readonly: to false
Expand Down
2 changes: 2 additions & 0 deletions tests/integration/delete.bats
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ function teardown() {
testcontainer test_busybox running

runc kill test_busybox KILL
[ "$status" -eq 0 ]
# wait for busybox to be in the destroyed state
retry 10 1 eval "__runc state test_busybox | grep -q 'stopped'"

# delete test_busybox
runc delete test_busybox
[ "$status" -eq 0 ]

runc state test_busybox
[ "$status" -ne 0 ]
Expand Down
12 changes: 12 additions & 0 deletions tests/integration/events.bats
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ function teardown() {
}

@test "events --stats" {
# XXX: currently cgroups require root containers.
requires root

# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
Expand All @@ -27,6 +30,9 @@ function teardown() {
}

@test "events --interval default " {
# XXX: currently cgroups require root containers.
requires root

# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
Expand Down Expand Up @@ -54,6 +60,9 @@ function teardown() {
}

@test "events --interval 1s " {
# XXX: currently cgroups require root containers.
requires root

# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
Expand All @@ -80,6 +89,9 @@ function teardown() {
}

@test "events --interval 100ms " {
# XXX: currently cgroups require root containers.
requires root

# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
Expand Down
3 changes: 3 additions & 0 deletions tests/integration/exec.bats
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ function teardown() {
}

@test "runc exec --user" {
# --user can't work in rootless containers
requires root

# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
Expand Down
1 change: 1 addition & 0 deletions tests/integration/help.bats
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ load helpers
[ "$status" -eq 0 ]
[[ ${lines[1]} =~ runc\ resume+ ]]

# We don't use runc_spec here, because we're just testing the help page.
runc spec -h
[ "$status" -eq 0 ]
[[ ${lines[1]} =~ runc\ spec+ ]]
Expand Down
23 changes: 17 additions & 6 deletions tests/integration/helpers.bash
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
INTEGRATION_ROOT=$(dirname "$(readlink -f "$BASH_SOURCE")")
RUNC="${INTEGRATION_ROOT}/../../runc"
RECVTTY="${INTEGRATION_ROOT}/../../contrib/cmd/recvtty/recvtty"
GOPATH="${INTEGRATION_ROOT}/../../../.."
GOPATH="$(mktemp -d --tmpdir runc-integration-gopath.XXXXXX)"

# Test data path.
TESTDATA="${INTEGRATION_ROOT}/testdata"
Expand All @@ -27,7 +27,7 @@ KERNEL_MINOR="${KERNEL_VERSION#$KERNEL_MAJOR.}"
KERNEL_MINOR="${KERNEL_MINOR%%.*}"

# Root state path.
ROOT="$BATS_TMPDIR/runc"
ROOT=$(mktemp -d "$BATS_TMPDIR/runc.XXXXXX")

# Path to console socket.
CONSOLE_SOCKET="$BATS_TMPDIR/console.sock"
Expand Down Expand Up @@ -58,6 +58,17 @@ function __runc() {
"$RUNC" --root "$ROOT" "$@"
}

# Wrapper for runc spec.
function runc_spec() {
local args=""

if [ "$ROOTLESS" -ne 0 ]; then
args+="--rootless"
fi

runc spec $args "$@"
}

# Fails the current test, providing the error given.
function fail() {
echo "$@" >&2
Expand Down Expand Up @@ -187,18 +198,18 @@ function setup_busybox() {
if [ ! -e $BUSYBOX_IMAGE ]; then
curl -o $BUSYBOX_IMAGE -sSL 'https://github.com/docker-library/busybox/raw/a0558a9006ce0dd6f6ec5d56cfd3f32ebeeb815f/glibc/busybox.tar.xz'
fi
tar -C "$BUSYBOX_BUNDLE"/rootfs -xf "$BUSYBOX_IMAGE"
tar --exclude './dev/*' -C "$BUSYBOX_BUNDLE"/rootfs -xf "$BUSYBOX_IMAGE"
cd "$BUSYBOX_BUNDLE"
runc spec
runc_spec
}

function setup_hello() {
setup_recvtty
run mkdir "$HELLO_BUNDLE"
run mkdir "$HELLO_BUNDLE"/rootfs
tar -C "$HELLO_BUNDLE"/rootfs -xf "$HELLO_IMAGE"
tar --exclude './dev/*' -C "$HELLO_BUNDLE"/rootfs -xf "$HELLO_IMAGE"
cd "$HELLO_BUNDLE"
runc spec
runc_spec
sed -i 's;"sh";"/hello";' config.json
}

Expand Down
11 changes: 10 additions & 1 deletion tests/integration/ps.bats
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ function teardown() {
}

@test "ps" {
# ps is not supported, it requires cgroups
requires root

# start busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
Expand All @@ -24,10 +27,13 @@ function teardown() {
runc ps test_busybox
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ UID\ +PID\ +PPID\ +C\ +STIME\ +TTY\ +TIME\ +CMD+ ]]
[[ "${lines[1]}" == *"root"*[0-9]* ]]
[[ "${lines[1]}" == *"$(id -un 2>/dev/null)"*[0-9]* ]]
}

@test "ps -f json" {
# ps is not supported, it requires cgroups
requires root

# start busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
Expand All @@ -43,6 +49,9 @@ function teardown() {
}

@test "ps -e -x" {
# ps is not supported, it requires cgroups
requires root

# start busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/spec.bats
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function teardown() {
[ ! -e config.json ]

# test generation of spec does not return an error
runc spec
runc_spec
[ "$status" -eq 0 ]

# test generation of spec created our config.json (spec)
Expand All @@ -51,7 +51,7 @@ function teardown() {
[ ! -e "$HELLO_BUNDLE"/config.json ]

# test generation of spec does not return an error
runc spec --bundle "$HELLO_BUNDLE"
runc_spec --bundle "$HELLO_BUNDLE"
[ "$status" -eq 0 ]

# test generation of spec created our config.json (spec)
Expand Down
3 changes: 3 additions & 0 deletions tests/integration/start_detached.bats
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ function teardown() {
}

@test "runc run detached ({u,g}id != 0)" {
# cannot start containers as another user in rootless setup
requires root

# replace "uid": 0 with "uid": 1000
# and do a similar thing for gid.
sed -i 's;"uid": 0;"uid": 1000;g' config.json
Expand Down
3 changes: 3 additions & 0 deletions tests/integration/start_hello.bats
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ function teardown() {
}

@test "runc run ({u,g}id != 0)" {
# cannot start containers as another user in rootless setup
requires root

# replace "uid": 0 with "uid": 1000
# and do a similar thing for gid.
sed -i 's;"uid": 0;"uid": 1000;g' config.json
Expand Down
42 changes: 31 additions & 11 deletions tests/integration/state.bats
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,37 @@ function teardown() {
teardown_busybox
}

@test "state" {
@test "state (kill + delete)" {
runc state test_busybox
[ "$status" -ne 0 ]

# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]

# check state
wait_for_container 15 1 test_busybox

testcontainer test_busybox running

runc kill test_busybox KILL
[ "$status" -eq 0 ]

# wait for busybox to be in the destroyed state
retry 10 1 eval "__runc state test_busybox | grep -q 'stopped'"

# delete test_busybox
runc delete test_busybox
[ "$status" -eq 0 ]

runc state test_busybox
[ "$status" -ne 0 ]
}

@test "state (pause + resume)" {
# XXX: pause and resume require cgroups.
requires root

runc state test_busybox
[ "$status" -ne 0 ]

Expand All @@ -37,14 +67,4 @@ function teardown() {

# test state of busybox is back to running
testcontainer test_busybox running

runc kill test_busybox KILL
# wait for busybox to be in the destroyed state
retry 10 1 eval "__runc state test_busybox | grep -q 'stopped'"

# delete test_busybox
runc delete test_busybox

runc state test_busybox
[ "$status" -ne 0 ]
}
14 changes: 14 additions & 0 deletions tests/integration/tty.bats
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ function teardown() {
}

@test "runc run [tty owner]" {
# tty chmod is not doable in rootless containers.
# TODO: this can be made as a change to the gid test.
requires root

# Replace sh script with stat.
sed -i 's/"sh"/"sh", "-c", "stat -c %u:%g $(tty) | tr : \\\\\\\\n"/' config.json

Expand All @@ -36,6 +40,9 @@ function teardown() {
}

@test "runc run [tty owner] ({u,g}id != 0)" {
# tty chmod is not doable in rootless containers.
requires root

# replace "uid": 0 with "uid": 1000
# and do a similar thing for gid.
sed -i 's;"uid": 0;"uid": 1000;g' config.json
Expand Down Expand Up @@ -72,6 +79,10 @@ function teardown() {
}

@test "runc exec [tty owner]" {
# tty chmod is not doable in rootless containers.
# TODO: this can be made as a change to the gid test.
requires root

# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
Expand All @@ -90,6 +101,9 @@ function teardown() {
}

@test "runc exec [tty owner] ({u,g}id != 0)" {
# tty chmod is not doable in rootless containers.
requires root

# replace "uid": 0 with "uid": 1000
# and do a similar thing for gid.
sed -i 's;"uid": 0;"uid": 1000;g' config.json
Expand Down

0 comments on commit ba38383

Please sign in to comment.