bump runc@b263a43430ac6996a4302b891688544225197294

Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
Antonio Murdaca 2017-02-06 21:16:36 +01:00
parent 73a0881dbb
commit c258a2d8f0
No known key found for this signature in database
GPG key ID: B2BEAD150DE936B9
386 changed files with 9394 additions and 39467 deletions

View file

@ -0,0 +1,83 @@
# runc Integration Tests
Integration tests provide end-to-end testing of runc.
Note that integration tests do **not** replace unit tests.
As a rule of thumb, code should be tested thoroughly with unit tests.
Integration tests on the other hand are meant to test a specific feature end
to end.
Integration tests are written in *bash* using the
[bats](https://github.com/sstephenson/bats) framework.
## Running integration tests
The easiest way to run integration tests is with Docker:
```
$ make integration
```
Alternatively, you can run integration tests directly on your host through make:
```
$ sudo make localintegration
```
Or you can just run them directly using bats
```
$ sudo bats tests/integration
```
To run a single test bucket:
```
$ make integration TESTFLAGS="/checkpoint.bats"
```
To run them on your host, you will need to setup a development environment plus
[bats](https://github.com/sstephenson/bats#installing-bats-from-source)
For example:
```
$ cd ~/go/src/github.com
$ git clone https://github.com/sstephenson/bats.git
$ cd bats
$ ./install.sh /usr/local
```
> **Note**: There are known issues running the integration tests using
> **devicemapper** as a storage driver, make sure that your docker daemon
> is using **aufs** if you want to successfully run the integration tests.
## Writing integration tests
[helper functions]
(https://github.com/opencontainers/runc/blob/master/test/integration/helpers.bash)
are provided in order to facilitate writing tests.
```sh
#!/usr/bin/env bats
# This will load the helpers.
load helpers
# setup is called at the beginning of every test.
function setup() {
# see functions teardown_hello and setup_hello in helpers.bash, used to
# create a pristine environment for running your tests
teardown_hello
setup_hello
}
# teardown is called at the end of every test.
function teardown() {
teardown_hello
}
@test "this is a simple test" {
runc run containerid
# "The runc macro" automatically populates $status, $output and $lines.
# Please refer to bats documentation to find out more.
[ "$status" -eq 0 ]
# check expected output
[[ "${output}" == *"Hello"* ]]
}
```

View file

@ -0,0 +1,78 @@
#!/usr/bin/env bats
load helpers
TEST_CGROUP_NAME="runc-cgroups-integration-test"
CGROUP_MEMORY="${CGROUP_MEMORY_BASE_PATH}/${TEST_CGROUP_NAME}"
function teardown() {
rm -f $BATS_TMPDIR/runc-update-integration-test.json
teardown_running_container test_cgroups_kmem
teardown_busybox
}
function setup() {
teardown
setup_busybox
}
function check_cgroup_value() {
cgroup=$1
source=$2
expected=$3
current=$(cat $cgroup/$source)
echo $cgroup/$source
echo "current" $current "!?" "$expected"
[ "$current" -eq "$expected" ]
}
@test "runc update --kernel-memory (initialized)" {
requires cgroups_kmem
# Add cgroup path
sed -i 's/\("linux": {\)/\1\n "cgroupsPath": "\/runc-cgroups-integration-test",/' ${BUSYBOX_BUNDLE}/config.json
# Set some initial known values
DATA=$(cat <<-EOF
"memory": {
"kernel": 16777216
},
EOF
)
DATA=$(echo ${DATA} | sed 's/\n/\\n/g')
sed -i "s/\(\"resources\": {\)/\1\n${DATA}/" ${BUSYBOX_BUNDLE}/config.json
# run a detached busybox to work with
runc run -d --console-socket $CONSOLE_SOCKET test_cgroups_kmem
[ "$status" -eq 0 ]
wait_for_container 15 1 test_cgroups_kmem
# update kernel memory limit
runc update test_cgroups_kmem --kernel-memory 50331648
[ "$status" -eq 0 ]
# check the value
check_cgroup_value $CGROUP_MEMORY "memory.kmem.limit_in_bytes" 50331648
}
@test "runc update --kernel-memory (uninitialized)" {
requires cgroups_kmem
# Add cgroup path
sed -i 's/\("linux": {\)/\1\n "cgroupsPath": "\/runc-cgroups-integration-test",/' ${BUSYBOX_BUNDLE}/config.json
# run a detached busybox to work with
runc run -d --console-socket $CONSOLE_SOCKET test_cgroups_kmem
[ "$status" -eq 0 ]
wait_for_container 15 1 test_cgroups_kmem
# update kernel memory limit
runc update test_cgroups_kmem --kernel-memory 50331648
# Since kernel 4.6, we can update kernel memory without initialization
# because it's accounted by default.
if [ "$KERNEL_MAJOR" -lt 4 ] || [ "$KERNEL_MAJOR" -eq 4 -a "$KERNEL_MINOR" -le 5 ]; then
[ ! "$status" -eq 0 ]
else
[ "$status" -eq 0 ]
check_cgroup_value $CGROUP_MEMORY "memory.kmem.limit_in_bytes" 50331648
fi
}

View file

@ -0,0 +1,59 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_busybox
setup_busybox
}
function teardown() {
teardown_busybox
}
@test "checkpoint and restore" {
requires criu
# criu does not work with external terminals so..
# setting terminal and root:readonly: to false
sed -i 's;"terminal": true;"terminal": false;' config.json
sed -i 's;"readonly": true;"readonly": false;' config.json
sed -i 's/"sh"/"sh","-c","while :; do date; sleep 1; done"/' config.json
(
# run busybox (not detached)
runc run test_busybox
[ "$status" -eq 0 ]
) &
# check state
wait_for_container 15 1 test_busybox
runc state test_busybox
[ "$status" -eq 0 ]
[[ "${output}" == *"running"* ]]
# checkpoint the running container
runc --criu "$CRIU" checkpoint test_busybox
# if you are having problems getting criu to work uncomment the following dump:
#cat /run/opencontainer/containers/test_busybox/criu.work/dump.log
[ "$status" -eq 0 ]
# after checkpoint busybox is no longer running
runc state test_busybox
[ "$status" -ne 0 ]
# restore from checkpoint
(
runc --criu "$CRIU" restore test_busybox
[ "$status" -eq 0 ]
) &
# check state
wait_for_container 15 1 test_busybox
# busybox should be back up and running
runc state test_busybox
[ "$status" -eq 0 ]
[[ "${output}" == *"running"* ]]
}

View file

@ -0,0 +1,89 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_busybox
setup_busybox
}
function teardown() {
teardown_busybox
}
@test "runc create" {
runc create --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
testcontainer test_busybox created
# start the command
runc start test_busybox
[ "$status" -eq 0 ]
testcontainer test_busybox running
}
@test "runc create exec" {
runc create --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
testcontainer test_busybox created
runc exec test_busybox true
[ "$status" -eq 0 ]
testcontainer test_busybox created
# start the command
runc start test_busybox
[ "$status" -eq 0 ]
testcontainer test_busybox running
}
@test "runc create --pid-file" {
runc create --pid-file pid.txt --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
testcontainer test_busybox created
# check pid.txt was generated
[ -e pid.txt ]
run cat pid.txt
[ "$status" -eq 0 ]
[[ ${lines[0]} == $(__runc state test_busybox | jq '.pid') ]]
# start the command
runc start test_busybox
[ "$status" -eq 0 ]
testcontainer test_busybox running
}
@test "runc create --pid-file with new CWD" {
# create pid_file directory as the CWD
run mkdir pid_file
[ "$status" -eq 0 ]
run cd pid_file
[ "$status" -eq 0 ]
runc create --pid-file pid.txt -b $BUSYBOX_BUNDLE --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
testcontainer test_busybox created
# check pid.txt was generated
[ -e pid.txt ]
run cat pid.txt
[ "$status" -eq 0 ]
[[ ${lines[0]} == $(__runc state test_busybox | jq '.pid') ]]
# start the command
runc start test_busybox
[ "$status" -eq 0 ]
testcontainer test_busybox running
}

View file

@ -0,0 +1,70 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_hello
setup_hello
}
function teardown() {
teardown_hello
}
@test "global --debug" {
# run hello-world
runc --debug run test_hello
echo "${output}"
[ "$status" -eq 0 ]
}
@test "global --debug to --log" {
# run hello-world
runc --log log.out --debug run test_hello
[ "$status" -eq 0 ]
# check output does not include debug info
[[ "${output}" != *"level=debug"* ]]
# check log.out was generated
[ -e log.out ]
# check expected debug output was sent to log.out
run cat log.out
[ "$status" -eq 0 ]
[[ "${output}" == *"level=debug"* ]]
}
@test "global --debug to --log --log-format 'text'" {
# run hello-world
runc --log log.out --log-format "text" --debug run test_hello
[ "$status" -eq 0 ]
# check output does not include debug info
[[ "${output}" != *"level=debug"* ]]
# check log.out was generated
[ -e log.out ]
# check expected debug output was sent to log.out
run cat log.out
[ "$status" -eq 0 ]
[[ "${output}" == *"level=debug"* ]]
}
@test "global --debug to --log --log-format 'json'" {
# run hello-world
runc --log log.out --log-format "json" --debug run test_hello
[ "$status" -eq 0 ]
# check output does not include debug info
[[ "${output}" != *"level=debug"* ]]
# check log.out was generated
[ -e log.out ]
# check expected debug output was sent to log.out
run cat log.out
[ "$status" -eq 0 ]
[[ "${output}" == *'"level":"debug"'* ]]
}

View file

@ -0,0 +1,109 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_busybox
setup_busybox
}
function teardown() {
teardown_busybox
}
@test "runc delete" {
# 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
# 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 ]
}
@test "runc delete --force" {
# 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
# force delete test_busybox
runc delete --force test_busybox
runc state test_busybox
[ "$status" -ne 0 ]
}
@test "run delete with multi-containers" {
# create busybox1 detached
runc create --console-socket $CONSOLE_SOCKET test_busybox1
[ "$status" -eq 0 ]
testcontainer test_busybox1 created
# run busybox2 detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox2
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox2
testcontainer test_busybox2 running
# delete both test_busybox1 and test_busybox2 container
runc delete test_busybox1 test_busybox2
runc state test_busybox1
[ "$status" -ne 0 ]
runc state test_busybox2
[ "$status" -eq 0 ]
runc kill test_busybox2 KILL
# wait for busybox2 to be in the destroyed state
retry 10 1 eval "__runc state test_busybox2 | grep -q 'stopped'"
# delete test_busybox2
runc delete test_busybox2
runc state test_busybox2
[ "$status" -ne 0 ]
}
@test "run delete --force with multi-containers" {
# create busybox1 detached
runc create --console-socket $CONSOLE_SOCKET test_busybox1
[ "$status" -eq 0 ]
testcontainer test_busybox1 created
# run busybox2 detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox2
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox2
testcontainer test_busybox2 running
# delete both test_busybox1 and test_busybox2 container
runc delete --force test_busybox1 test_busybox2
runc state test_busybox1
[ "$status" -ne 0 ]
runc state test_busybox2
[ "$status" -ne 0 ]
}

View file

@ -0,0 +1,109 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_busybox
setup_busybox
}
function teardown() {
teardown_busybox
}
@test "events --stats" {
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
# check state
wait_for_container 15 1 test_busybox
# generate stats
runc events --stats test_busybox
[ "$status" -eq 0 ]
[[ "${lines[0]}" == [\{]"\"type\""[:]"\"stats\""[,]"\"id\""[:]"\"test_busybox\""[,]* ]]
[[ "${lines[0]}" == *"data"* ]]
}
@test "events --interval default " {
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
# check state
wait_for_container 15 1 test_busybox
# spawn two sub processes (shells)
# the first sub process is an event logger that sends stats events to events.log
# the second sub process waits for an event that incudes test_busybox then
# kills the test_busybox container which causes the event logger to exit
(__runc events test_busybox > events.log) &
(
retry 10 1 eval "grep -q 'test_busybox' events.log"
teardown_running_container test_busybox
) &
wait # wait for the above sub shells to finish
[ -e events.log ]
run cat events.log
[ "$status" -eq 0 ]
[[ "${lines[0]}" == [\{]"\"type\""[:]"\"stats\""[,]"\"id\""[:]"\"test_busybox\""[,]* ]]
[[ "${lines[0]}" == *"data"* ]]
}
@test "events --interval 1s " {
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
# check state
wait_for_container 15 1 test_busybox
# spawn two sub processes (shells)
# the first sub process is an event logger that sends stats events to events.log once a second
# the second sub process tries 3 times for an event that incudes test_busybox
# pausing 1s between each attempt then kills the test_busybox container which
# causes the event logger to exit
(__runc events --interval 1s test_busybox > events.log) &
(
retry 3 1 eval "grep -q 'test_busybox' events.log"
teardown_running_container test_busybox
) &
wait # wait for the above sub shells to finish
[ -e events.log ]
run eval "grep -q 'test_busybox' events.log"
[ "$status" -eq 0 ]
}
@test "events --interval 100ms " {
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
# check state
wait_for_container 15 1 test_busybox
#prove there is no carry over of events.log from a prior test
[ ! -e events.log ]
# spawn two sub processes (shells)
# the first sub process is an event logger that sends stats events to events.log once every 100ms
# the second sub process tries 3 times for an event that incudes test_busybox
# pausing 100s between each attempt then kills the test_busybox container which
# causes the event logger to exit
(__runc events --interval 100ms test_busybox > events.log) &
(
retry 3 0.100 eval "grep -q 'test_busybox' events.log"
teardown_running_container test_busybox
) &
wait # wait for the above sub shells to finish
[ -e events.log ]
run eval "grep -q 'test_busybox' events.log"
[ "$status" -eq 0 ]
}

View file

@ -0,0 +1,125 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_busybox
setup_busybox
}
function teardown() {
teardown_busybox
}
@test "runc exec" {
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox
runc exec test_busybox echo Hello from exec
[ "$status" -eq 0 ]
echo text echoed = "'""${output}""'"
[[ "${output}" == *"Hello from exec"* ]]
}
@test "runc exec --pid-file" {
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox
runc exec --pid-file pid.txt test_busybox echo Hello from exec
[ "$status" -eq 0 ]
echo text echoed = "'""${output}""'"
[[ "${output}" == *"Hello from exec"* ]]
# check pid.txt was generated
[ -e pid.txt ]
run cat pid.txt
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ [0-9]+ ]]
[[ ${lines[0]} != $(__runc state test_busybox | jq '.pid') ]]
}
@test "runc exec --pid-file with new CWD" {
# create pid_file directory as the CWD
run mkdir pid_file
[ "$status" -eq 0 ]
run cd pid_file
[ "$status" -eq 0 ]
# run busybox detached
runc run -d -b $BUSYBOX_BUNDLE --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox
runc exec --pid-file pid.txt test_busybox echo Hello from exec
[ "$status" -eq 0 ]
echo text echoed = "'""${output}""'"
[[ "${output}" == *"Hello from exec"* ]]
# check pid.txt was generated
[ -e pid.txt ]
run cat pid.txt
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ [0-9]+ ]]
[[ ${lines[0]} != $(__runc state test_busybox | jq '.pid') ]]
}
@test "runc exec ls -la" {
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox
runc exec test_busybox ls -la
[ "$status" -eq 0 ]
[[ ${lines[0]} == *"total"* ]]
[[ ${lines[1]} == *"."* ]]
[[ ${lines[2]} == *".."* ]]
}
@test "runc exec ls -la with --cwd" {
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox
runc exec --cwd /bin test_busybox pwd
[ "$status" -eq 0 ]
[[ ${output} == "/bin" ]]
}
@test "runc exec --env" {
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox
runc exec --env RUNC_EXEC_TEST=true test_busybox env
[ "$status" -eq 0 ]
[[ ${output} == *"RUNC_EXEC_TEST=true"* ]]
}
@test "runc exec --user" {
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox
runc exec --user 1000:1000 test_busybox id
[ "$status" -eq 0 ]
[[ ${output} == "uid=1000 gid=1000" ]]
}

View file

@ -0,0 +1,86 @@
#!/usr/bin/env bats
load helpers
@test "runc -h" {
runc -h
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ NAME:+ ]]
[[ ${lines[1]} =~ runc\ '-'\ Open\ Container\ Initiative\ runtime+ ]]
runc --help
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ NAME:+ ]]
[[ ${lines[1]} =~ runc\ '-'\ Open\ Container\ Initiative\ runtime+ ]]
}
@test "runc command -h" {
runc checkpoint -h
[ "$status" -eq 0 ]
[[ ${lines[1]} =~ runc\ checkpoint+ ]]
runc delete -h
[ "$status" -eq 0 ]
[[ ${lines[1]} =~ runc\ delete+ ]]
runc events -h
[ "$status" -eq 0 ]
[[ ${lines[1]} =~ runc\ events+ ]]
runc exec -h
[ "$status" -eq 0 ]
[[ ${lines[1]} =~ runc\ exec+ ]]
runc kill -h
[ "$status" -eq 0 ]
[[ ${lines[1]} =~ runc\ kill+ ]]
runc list -h
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ NAME:+ ]]
[[ ${lines[1]} =~ runc\ list+ ]]
runc list --help
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ NAME:+ ]]
[[ ${lines[1]} =~ runc\ list+ ]]
runc pause -h
[ "$status" -eq 0 ]
[[ ${lines[1]} =~ runc\ pause+ ]]
runc restore -h
[ "$status" -eq 0 ]
[[ ${lines[1]} =~ runc\ restore+ ]]
runc resume -h
[ "$status" -eq 0 ]
[[ ${lines[1]} =~ runc\ resume+ ]]
runc spec -h
[ "$status" -eq 0 ]
[[ ${lines[1]} =~ runc\ spec+ ]]
runc start -h
[ "$status" -eq 0 ]
[[ ${lines[1]} =~ runc\ start+ ]]
runc run -h
[ "$status" -eq 0 ]
[[ ${lines[1]} =~ runc\ run+ ]]
runc state -h
[ "$status" -eq 0 ]
[[ ${lines[1]} =~ runc\ state+ ]]
runc update -h
[ "$status" -eq 0 ]
[[ ${lines[1]} =~ runc\ update+ ]]
}
@test "runc foo -h" {
runc foo -h
[ "$status" -ne 0 ]
[[ "${output}" == *"No help topic for 'foo'"* ]]
}

View file

@ -0,0 +1,233 @@
#!/bin/bash
# Root directory of integration tests.
INTEGRATION_ROOT=$(dirname "$(readlink -f "$BASH_SOURCE")")
RUNC="${INTEGRATION_ROOT}/../../runc"
RECVTTY="${INTEGRATION_ROOT}/../../contrib/cmd/recvtty/recvtty"
GOPATH="${INTEGRATION_ROOT}/../../../.."
# Test data path.
TESTDATA="${INTEGRATION_ROOT}/testdata"
# Busybox image
BUSYBOX_IMAGE="$BATS_TMPDIR/busybox.tar"
BUSYBOX_BUNDLE="$BATS_TMPDIR/busyboxtest"
# hello-world in tar format
HELLO_IMAGE="$TESTDATA/hello-world.tar"
HELLO_BUNDLE="$BATS_TMPDIR/hello-world"
# CRIU PATH
CRIU="$(which criu)"
# Kernel version
KERNEL_VERSION="$(uname -r)"
KERNEL_MAJOR="${KERNEL_VERSION%%.*}"
KERNEL_MINOR="${KERNEL_VERSION#$KERNEL_MAJOR.}"
KERNEL_MINOR="${KERNEL_MINOR%%.*}"
# Root state path.
ROOT="$BATS_TMPDIR/runc"
# Path to console socket.
CONSOLE_SOCKET="$BATS_TMPDIR/console.sock"
# Cgroup mount
CGROUP_MEMORY_BASE_PATH=$(grep "cgroup" /proc/self/mountinfo | gawk 'toupper($NF) ~ /\<MEMORY\>/ { print $5; exit }')
CGROUP_CPU_BASE_PATH=$(grep "cgroup" /proc/self/mountinfo | gawk 'toupper($NF) ~ /\<CPU\>/ { print $5; exit }')
# CONFIG_MEMCG_KMEM support
KMEM="${CGROUP_MEMORY_BASE_PATH}/memory.kmem.limit_in_bytes"
RT_PERIOD="${CGROUP_CPU_BASE_PATH}/cpu.rt_period_us"
# Wrapper for runc.
function runc() {
run __runc "$@"
# Some debug information to make life easier. bats will only print it if the
# test failed, in which case the output is useful.
echo "runc $@ (status=$status):" >&2
echo "$output" >&2
}
# Raw wrapper for runc.
function __runc() {
"$RUNC" --root "$ROOT" "$@"
}
# Fails the current test, providing the error given.
function fail() {
echo "$@" >&2
exit 1
}
# Allows a test to specify what things it requires. If the environment can't
# support it, the test is skipped with a message.
function requires() {
for var in "$@"; do
case $var in
criu)
if [ ! -e "$CRIU" ]; then
skip "Test requires ${var}."
fi
;;
cgroups_kmem)
if [ ! -e "$KMEM" ]; then
skip "Test requires ${var}."
fi
;;
cgroups_rt)
if [ ! -e "$RT_PERIOD" ]; then
skip "Test requires ${var}."
fi
;;
*)
fail "BUG: Invalid requires ${var}."
;;
esac
done
}
# Retry a command $1 times until it succeeds. Wait $2 seconds between retries.
function retry() {
local attempts=$1
shift
local delay=$1
shift
local i
for ((i = 0; i < attempts; i++)); do
run "$@"
if [[ "$status" -eq 0 ]]; then
return 0
fi
sleep $delay
done
echo "Command \"$@\" failed $attempts times. Output: $output"
false
}
# retry until the given container has state
function wait_for_container() {
local attempts=$1
local delay=$2
local cid=$3
local i
for ((i = 0; i < attempts; i++)); do
runc state $cid
if [[ "$status" -eq 0 ]]; then
return 0
fi
sleep $delay
done
echo "runc state failed to return state $statecheck $attempts times. Output: $output"
false
}
# retry until the given container has state
function wait_for_container_inroot() {
local attempts=$1
local delay=$2
local cid=$3
local i
for ((i = 0; i < attempts; i++)); do
ROOT=$4 runc state $cid
if [[ "$status" -eq 0 ]]; then
return 0
fi
sleep $delay
done
echo "runc state failed to return state $statecheck $attempts times. Output: $output"
false
}
function testcontainer() {
# test state of container
runc state $1
[ "$status" -eq 0 ]
[[ "${output}" == *"$2"* ]]
}
function setup_recvtty() {
# We need to start recvtty in the background, so we double fork in the shell.
("$RECVTTY" --pid-file "$BATS_TMPDIR/recvtty.pid" --mode null "$CONSOLE_SOCKET" &) &
}
function teardown_recvtty() {
# When we kill recvtty, the container will also be killed.
if [ -f "$BATS_TMPDIR/recvtty.pid" ]; then
kill -9 $(cat "$BATS_TMPDIR/recvtty.pid")
fi
# Clean up the files that might be left over.
rm -f "$BATS_TMPDIR/recvtty.pid"
rm -f "$CONSOLE_SOCKET"
}
function setup_busybox() {
setup_recvtty
run mkdir "$BUSYBOX_BUNDLE"
run mkdir "$BUSYBOX_BUNDLE"/rootfs
if [ -e "/testdata/busybox.tar" ]; then
BUSYBOX_IMAGE="/testdata/busybox.tar"
fi
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"
cd "$BUSYBOX_BUNDLE"
runc spec
}
function setup_hello() {
setup_recvtty
run mkdir "$HELLO_BUNDLE"
run mkdir "$HELLO_BUNDLE"/rootfs
tar -C "$HELLO_BUNDLE"/rootfs -xf "$HELLO_IMAGE"
cd "$HELLO_BUNDLE"
runc spec
sed -i 's;"sh";"/hello";' config.json
}
function teardown_running_container() {
runc list
# $1 should be a container name such as "test_busybox"
# here we detect "test_busybox "(with one extra blank) to avoid conflict prefix
# e.g. "test_busybox" and "test_busybox_update"
if [[ "${output}" == *"$1 "* ]]; then
runc kill $1 KILL
retry 10 1 eval "__runc state '$1' | grep -q 'stopped'"
runc delete $1
fi
}
function teardown_running_container_inroot() {
ROOT=$2 runc list
# $1 should be a container name such as "test_busybox"
# here we detect "test_busybox "(with one extra blank) to avoid conflict prefix
# e.g. "test_busybox" and "test_busybox_update"
if [[ "${output}" == *"$1 "* ]]; then
ROOT=$2 runc kill $1 KILL
retry 10 1 eval "ROOT='$2' __runc state '$1' | grep -q 'stopped'"
ROOT=$2 runc delete $1
fi
}
function teardown_busybox() {
cd "$INTEGRATION_ROOT"
teardown_recvtty
teardown_running_container test_busybox
run rm -f -r "$BUSYBOX_BUNDLE"
}
function teardown_hello() {
cd "$INTEGRATION_ROOT"
teardown_recvtty
teardown_running_container test_hello
run rm -f -r "$HELLO_BUNDLE"
}

View file

@ -0,0 +1,33 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_busybox
setup_busybox
}
function teardown() {
teardown_busybox
}
@test "kill detached busybox" {
# 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 ]
retry 10 1 eval "__runc state test_busybox | grep -q 'stopped'"
runc delete test_busybox
[ "$status" -eq 0 ]
}

View file

@ -0,0 +1,59 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_running_container_inroot test_box1 $HELLO_BUNDLE
teardown_running_container_inroot test_box2 $HELLO_BUNDLE
teardown_running_container_inroot test_box3 $HELLO_BUNDLE
teardown_busybox
setup_busybox
}
function teardown() {
teardown_running_container_inroot test_box1 $HELLO_BUNDLE
teardown_running_container_inroot test_box2 $HELLO_BUNDLE
teardown_running_container_inroot test_box3 $HELLO_BUNDLE
teardown_busybox
}
@test "list" {
# run a few busyboxes detached
ROOT=$HELLO_BUNDLE runc run -d --console-socket $CONSOLE_SOCKET test_box1
[ "$status" -eq 0 ]
wait_for_container_inroot 15 1 test_box1 $HELLO_BUNDLE
ROOT=$HELLO_BUNDLE runc run -d --console-socket $CONSOLE_SOCKET test_box2
[ "$status" -eq 0 ]
wait_for_container_inroot 15 1 test_box2 $HELLO_BUNDLE
ROOT=$HELLO_BUNDLE runc run -d --console-socket $CONSOLE_SOCKET test_box3
[ "$status" -eq 0 ]
wait_for_container_inroot 15 1 test_box3 $HELLO_BUNDLE
ROOT=$HELLO_BUNDLE runc list
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ ID\ +PID\ +STATUS\ +BUNDLE\ +CREATED+ ]]
[[ "${lines[1]}" == *"test_box1"*[0-9]*"running"*$BUSYBOX_BUNDLE*[0-9]* ]]
[[ "${lines[2]}" == *"test_box2"*[0-9]*"running"*$BUSYBOX_BUNDLE*[0-9]* ]]
[[ "${lines[3]}" == *"test_box3"*[0-9]*"running"*$BUSYBOX_BUNDLE*[0-9]* ]]
ROOT=$HELLO_BUNDLE runc list -q
[ "$status" -eq 0 ]
[[ "${lines[0]}" == "test_box1" ]]
[[ "${lines[1]}" == "test_box2" ]]
[[ "${lines[2]}" == "test_box3" ]]
ROOT=$HELLO_BUNDLE runc list --format table
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ ID\ +PID\ +STATUS\ +BUNDLE\ +CREATED+ ]]
[[ "${lines[1]}" == *"test_box1"*[0-9]*"running"*$BUSYBOX_BUNDLE*[0-9]* ]]
[[ "${lines[2]}" == *"test_box2"*[0-9]*"running"*$BUSYBOX_BUNDLE*[0-9]* ]]
[[ "${lines[3]}" == *"test_box3"*[0-9]*"running"*$BUSYBOX_BUNDLE*[0-9]* ]]
ROOT=$HELLO_BUNDLE runc list --format json
[ "$status" -eq 0 ]
[[ "${lines[0]}" == [\[][\{]"\"ociVersion\""[:]"\""*[0-9][\.]*[0-9][\.]*[0-9]*"\""[,]"\"id\""[:]"\"test_box1\""[,]"\"pid\""[:]*[0-9][,]"\"status\""[:]*"\"running\""[,]"\"bundle\""[:]*$BUSYBOX_BUNDLE*[,]"\"rootfs\""[:]"\""*"\""[,]"\"created\""[:]*[0-9]*[\}]* ]]
[[ "${lines[0]}" == *[,][\{]"\"ociVersion\""[:]"\""*[0-9][\.]*[0-9][\.]*[0-9]*"\""[,]"\"id\""[:]"\"test_box2\""[,]"\"pid\""[:]*[0-9][,]"\"status\""[:]*"\"running\""[,]"\"bundle\""[:]*$BUSYBOX_BUNDLE*[,]"\"rootfs\""[:]"\""*"\""[,]"\"created\""[:]*[0-9]*[\}]* ]]
[[ "${lines[0]}" == *[,][\{]"\"ociVersion\""[:]"\""*[0-9][\.]*[0-9][\.]*[0-9]*"\""[,]"\"id\""[:]"\"test_box3\""[,]"\"pid\""[:]*[0-9][,]"\"status\""[:]*"\"running\""[,]"\"bundle\""[:]*$BUSYBOX_BUNDLE*[,]"\"rootfs\""[:]"\""*"\""[,]"\"created\""[:]*[0-9]*[\}][\]] ]]
}

View file

@ -0,0 +1,63 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_busybox
setup_busybox
# Create fake rootfs.
mkdir rootfs/testdir
echo "Forbidden information!" > rootfs/testfile
# add extra masked paths
sed -i 's;"maskedPaths": \[;"maskedPaths": \["/testdir","/testfile",;g' config.json
}
function teardown() {
teardown_busybox
}
@test "mask paths [file]" {
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox
runc exec test_busybox cat /testfile
[ "$status" -eq 0 ]
[[ "${output}" == "" ]]
runc exec test_busybox rm -f /testfile
[ "$status" -eq 1 ]
[[ "${output}" == *"Read-only file system"* ]]
runc exec test_busybox umount /testfile
[ "$status" -eq 1 ]
[[ "${output}" == *"Operation not permitted"* ]]
}
@test "mask paths [directory]" {
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox
runc exec test_busybox ls /testdir
[ "$status" -eq 0 ]
[[ "${output}" == "" ]]
runc exec test_busybox touch /testdir/foo
[ "$status" -eq 1 ]
[[ "${output}" == *"Read-only file system"* ]]
runc exec test_busybox rm -rf /testdir
[ "$status" -eq 1 ]
[[ "${output}" == *"Read-only file system"* ]]
runc exec test_busybox umount /testdir
[ "$status" -eq 1 ]
[[ "${output}" == *"Operation not permitted"* ]]
}

View file

@ -0,0 +1,112 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_busybox
setup_busybox
}
function teardown() {
teardown_busybox
}
@test "runc pause and resume" {
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox
# pause busybox
runc pause test_busybox
[ "$status" -eq 0 ]
# test state of busybox is paused
testcontainer test_busybox paused
# resume busybox
runc resume test_busybox
[ "$status" -eq 0 ]
# test state of busybox is back to running
testcontainer test_busybox running
}
@test "runc pause and resume with multi-container" {
# run test_busybox1 detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox1
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox1
# run test_busybox2 detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox2
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox2
# pause test_busybox1 and test_busybox2
runc pause test_busybox1 test_busybox2
[ "$status" -eq 0 ]
# test state of test_busybox1 and test_busybox2 is paused
testcontainer test_busybox1 paused
testcontainer test_busybox2 paused
# resume test_busybox1 and test_busybox2
runc resume test_busybox1 test_busybox2
[ "$status" -eq 0 ]
# test state of two containers is back to running
testcontainer test_busybox1 running
testcontainer test_busybox2 running
# delete test_busybox1 and test_busybox2
runc delete --force test_busybox1 test_busybox2
runc state test_busybox1
[ "$status" -ne 0 ]
runc state test_busybox2
[ "$status" -ne 0 ]
}
@test "runc pause and resume with nonexist container" {
# run test_busybox1 detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox1
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox1
# run test_busybox2 detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox2
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox2
# pause test_busybox1, test_busybox2 and nonexistent container
runc pause test_busybox1 test_busybox2 nonexistent
[ "$status" -ne 0 ]
# test state of test_busybox1 and test_busybox2 is paused
testcontainer test_busybox1 paused
testcontainer test_busybox2 paused
# resume test_busybox1, test_busybox2 and nonexistent container
runc resume test_busybox1 test_busybox2 nonexistent
[ "$status" -ne 0 ]
# test state of two containers is back to running
testcontainer test_busybox1 running
testcontainer test_busybox2 running
# delete test_busybox1 and test_busybox2
runc delete --force test_busybox1 test_busybox2
runc state test_busybox1
[ "$status" -ne 0 ]
runc state test_busybox2
[ "$status" -ne 0 ]
}

View file

@ -0,0 +1,59 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_busybox
setup_busybox
}
function teardown() {
teardown_busybox
}
@test "ps" {
# start 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 ps test_busybox
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ UID\ +PID\ +PPID\ +C\ +STIME\ +TTY\ +TIME\ +CMD+ ]]
[[ "${lines[1]}" == *"root"*[0-9]* ]]
}
@test "ps -f json" {
# start 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 ps -f json test_busybox
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ [0-9]+ ]]
}
@test "ps -e -x" {
# start 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 ps test_busybox -e -x
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ \ +PID\ +TTY\ +STAT\ +TIME\ +COMMAND+ ]]
[[ "${lines[1]}" =~ [0-9]+ ]]
}

View file

@ -0,0 +1,54 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_running_container_inroot test_dotbox $HELLO_BUNDLE
teardown_busybox
setup_busybox
}
function teardown() {
teardown_running_container_inroot test_dotbox $HELLO_BUNDLE
teardown_busybox
}
@test "global --root" {
# run busybox detached using $HELLO_BUNDLE for state
ROOT=$HELLO_BUNDLE runc run -d --console-socket $CONSOLE_SOCKET test_dotbox
[ "$status" -eq 0 ]
# run busybox detached in default root
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
# check state of the busyboxes are only in their respective root path
wait_for_container 15 1 test_busybox
wait_for_container_inroot 15 1 test_dotbox $HELLO_BUNDLE
runc state test_busybox
[ "$status" -eq 0 ]
[[ "${output}" == *"running"* ]]
ROOT=$HELLO_BUNDLE runc state test_dotbox
[ "$status" -eq 0 ]
[[ "${output}" == *"running"* ]]
ROOT=$HELLO_BUNDLE runc state test_busybox
[ "$status" -ne 0 ]
runc state test_dotbox
[ "$status" -ne 0 ]
runc kill test_busybox KILL
[ "$status" -eq 0 ]
retry 10 1 eval "__runc state test_busybox | grep -q 'stopped'"
runc delete test_busybox
[ "$status" -eq 0 ]
ROOT=$HELLO_BUNDLE runc kill test_dotbox KILL
[ "$status" -eq 0 ]
retry 10 1 eval "ROOT='$HELLO_BUNDLE' __runc state test_dotbox | grep -q 'stopped'"
ROOT=$HELLO_BUNDLE runc delete test_dotbox
[ "$status" -eq 0 ]
}

View file

@ -0,0 +1,95 @@
#!/usr/bin/env bats
load helpers
function setup() {
# initial cleanup in case a prior test exited and did not cleanup
cd "$INTEGRATION_ROOT"
run rm -f -r "$HELLO_BUNDLE"
# setup hello-world for spec generation testing
run mkdir "$HELLO_BUNDLE"
run mkdir "$HELLO_BUNDLE"/rootfs
run tar -C "$HELLO_BUNDLE"/rootfs -xf "$HELLO_IMAGE"
}
function teardown() {
cd "$INTEGRATION_ROOT"
run rm -f -r "$HELLO_BUNDLE"
}
@test "spec generation cwd" {
cd "$HELLO_BUNDLE"
# note this test runs from the bundle not the integration root
# test that config.json does not exist after the above partial setup
[ ! -e config.json ]
# test generation of spec does not return an error
runc spec
[ "$status" -eq 0 ]
# test generation of spec created our config.json (spec)
[ -e config.json ]
# test existence of required args parameter in the generated config.json
run bash -c "grep -A2 'args' config.json | grep 'sh'"
[[ "${output}" == *"sh"* ]]
# change the default args parameter from sh to hello
sed -i 's;"sh";"/hello";' config.json
# ensure the generated spec works by running hello-world
runc run test_hello
[ "$status" -eq 0 ]
}
@test "spec generation --bundle" {
# note this test runs from the integration root not the bundle
# test that config.json does not exist after the above partial setup
[ ! -e "$HELLO_BUNDLE"/config.json ]
# test generation of spec does not return an error
runc spec --bundle "$HELLO_BUNDLE"
[ "$status" -eq 0 ]
# test generation of spec created our config.json (spec)
[ -e "$HELLO_BUNDLE"/config.json ]
# change the default args parameter from sh to hello
sed -i 's;"sh";"/hello";' "$HELLO_BUNDLE"/config.json
# ensure the generated spec works by running hello-world
runc run --bundle "$HELLO_BUNDLE" test_hello
[ "$status" -eq 0 ]
}
@test "spec validator" {
TESTDIR=$(pwd)
cd "$HELLO_BUNDLE"
run git clone https://github.com/opencontainers/runtime-spec.git src/runtime-spec
[ "$status" -eq 0 ]
SPEC_COMMIT=$(grep runtime-spec ${TESTDIR}/../../Godeps/Godeps.json -A 4 | grep Rev | cut -d":" -f 2 | tr -d ' "')
(
cd src/runtime-spec &&
run git reset --hard "${SPEC_COMMIT}"
)
[ "$status" -eq 0 ]
[ -e src/runtime-spec/schema/config-schema.json ]
run bash -c "GOPATH='$GOPATH' go get github.com/xeipuuv/gojsonschema"
[ "$status" -eq 0 ]
GOPATH="$GOPATH" go build src/runtime-spec/schema/validate.go
[ -e ./validate ]
runc spec
[ -e config.json ]
run ./validate src/runtime-spec/schema/config-schema.json config.json
[ "$status" -eq 0 ]
[[ "${lines[0]}" == *"The document is valid"* ]]
}

View file

@ -0,0 +1,41 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_busybox
setup_busybox
}
function teardown() {
teardown_busybox
}
@test "runc start" {
runc create --console-socket $CONSOLE_SOCKET test_busybox1
[ "$status" -eq 0 ]
testcontainer test_busybox1 created
runc create --console-socket $CONSOLE_SOCKET test_busybox2
[ "$status" -eq 0 ]
testcontainer test_busybox2 created
# start container test_busybox1 and test_busybox2
runc start test_busybox1 test_busybox2
[ "$status" -eq 0 ]
testcontainer test_busybox1 running
testcontainer test_busybox2 running
# delete test_busybox1 and test_busybox2
runc delete --force test_busybox1 test_busybox2
runc state test_busybox1
[ "$status" -ne 0 ]
runc state test_busybox2
[ "$status" -ne 0 ]
}

View file

@ -0,0 +1,81 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_busybox
setup_busybox
}
function teardown() {
teardown_busybox
}
@test "runc run detached" {
# 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
}
@test "runc run detached ({u,g}id != 0)" {
# replace "uid": 0 with "uid": 1000
# and do a similar thing for gid.
sed -i 's;"uid": 0;"uid": 1000;g' config.json
sed -i 's;"gid": 0;"gid": 100;g' config.json
# 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
}
@test "runc run detached --pid-file" {
# run busybox detached
runc run --pid-file pid.txt -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
# check state
wait_for_container 15 1 test_busybox
testcontainer test_busybox running
# check pid.txt was generated
[ -e pid.txt ]
run cat pid.txt
[ "$status" -eq 0 ]
[[ ${lines[0]} == $(__runc state test_busybox | jq '.pid') ]]
}
@test "runc run detached --pid-file with new CWD" {
# create pid_file directory as the CWD
run mkdir pid_file
[ "$status" -eq 0 ]
run cd pid_file
[ "$status" -eq 0 ]
# run busybox detached
runc run --pid-file pid.txt -d -b $BUSYBOX_BUNDLE --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
# check state
wait_for_container 15 1 test_busybox
testcontainer test_busybox running
# check pid.txt was generated
[ -e pid.txt ]
run cat pid.txt
[ "$status" -eq 0 ]
[[ ${lines[0]} == $(__runc state test_busybox | jq '.pid') ]]
}

View file

@ -0,0 +1,61 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_hello
setup_hello
}
function teardown() {
teardown_hello
}
@test "runc run" {
# run hello-world
runc run test_hello
[ "$status" -eq 0 ]
# check expected output
[[ "${output}" == *"Hello"* ]]
}
@test "runc run ({u,g}id != 0)" {
# replace "uid": 0 with "uid": 1000
# and do a similar thing for gid.
sed -i 's;"uid": 0;"uid": 1000;g' config.json
sed -i 's;"gid": 0;"gid": 100;g' config.json
# run hello-world
runc run test_hello
[ "$status" -eq 0 ]
# check expected output
[[ "${output}" == *"Hello"* ]]
}
@test "runc run with rootfs set to ." {
cp config.json rootfs/.
rm config.json
cd rootfs
sed -i 's;"rootfs";".";' config.json
# run hello-world
runc run test_hello
[ "$status" -eq 0 ]
[[ "${output}" == *"Hello"* ]]
}
@test "runc run --pid-file" {
# run hello-world
runc run --pid-file pid.txt test_hello
[ "$status" -eq 0 ]
[[ "${output}" == *"Hello"* ]]
# check pid.txt was generated
[ -e pid.txt ]
run cat pid.txt
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ [0-9]+ ]]
}

View file

@ -0,0 +1,50 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_busybox
setup_busybox
}
function teardown() {
teardown_busybox
}
@test "state" {
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
# pause busybox
runc pause test_busybox
[ "$status" -eq 0 ]
# test state of busybox is paused
testcontainer test_busybox paused
# resume busybox
runc resume test_busybox
[ "$status" -eq 0 ]
# 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 ]
}

Binary file not shown.

View file

@ -0,0 +1,113 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_busybox
setup_busybox
}
function teardown() {
teardown_busybox
}
@test "runc run [tty ptsname]" {
# Replace sh script with readlink.
sed -i 's|"sh"|"sh", "-c", "for file in /proc/self/fd/[012]; do readlink $file; done"|' config.json
# run busybox
runc run test_busybox
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ /dev/pts/+ ]]
[[ ${lines[1]} =~ /dev/pts/+ ]]
[[ ${lines[2]} =~ /dev/pts/+ ]]
}
@test "runc run [tty owner]" {
# Replace sh script with stat.
sed -i 's/"sh"/"sh", "-c", "stat -c %u:%g $(tty) | tr : \\\\\\\\n"/' config.json
# run busybox
runc run test_busybox
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ 0 ]]
# This is set by the default config.json (it corresponds to the standard tty group).
[[ ${lines[1]} =~ 5 ]]
}
@test "runc run [tty owner] ({u,g}id != 0)" {
# replace "uid": 0 with "uid": 1000
# and do a similar thing for gid.
sed -i 's;"uid": 0;"uid": 1000;g' config.json
sed -i 's;"gid": 0;"gid": 100;g' config.json
# Replace sh script with stat.
sed -i 's/"sh"/"sh", "-c", "stat -c %u:%g $(tty) | tr : \\\\\\\\n"/' config.json
# run busybox
runc run test_busybox
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ 1000 ]]
# This is set by the default config.json (it corresponds to the standard tty group).
[[ ${lines[1]} =~ 5 ]]
}
@test "runc exec [tty ptsname]" {
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
# check state
wait_for_container 15 1 test_busybox
# make sure we're running
testcontainer test_busybox running
# run the exec
runc exec test_busybox sh -c 'for file in /proc/self/fd/[012]; do readlink $file; done'
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ /dev/pts/+ ]]
[[ ${lines[1]} =~ /dev/pts/+ ]]
[[ ${lines[2]} =~ /dev/pts/+ ]]
}
@test "runc exec [tty owner]" {
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
# check state
wait_for_container 15 1 test_busybox
# make sure we're running
testcontainer test_busybox running
# run the exec
runc exec test_busybox sh -c 'stat -c %u:%g $(tty) | tr : \\n'
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ 0 ]]
[[ ${lines[1]} =~ 5 ]]
}
@test "runc exec [tty owner] ({u,g}id != 0)" {
# replace "uid": 0 with "uid": 1000
# and do a similar thing for gid.
sed -i 's;"uid": 0;"uid": 1000;g' config.json
sed -i 's;"gid": 0;"gid": 100;g' config.json
# run busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
# check state
wait_for_container 15 1 test_busybox
# make sure we're running
testcontainer test_busybox running
# run the exec
runc exec test_busybox sh -c 'stat -c %u:%g $(tty) | tr : \\n'
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ 1000 ]]
[[ ${lines[1]} =~ 5 ]]
}

View file

@ -0,0 +1,243 @@
#!/usr/bin/env bats
load helpers
function teardown() {
rm -f $BATS_TMPDIR/runc-update-integration-test.json
teardown_running_container test_update
teardown_running_container test_update_rt
teardown_busybox
}
function setup() {
teardown
setup_busybox
# Add cgroup path
sed -i 's/\("linux": {\)/\1\n "cgroupsPath": "\/runc-update-integration-test",/' ${BUSYBOX_BUNDLE}/config.json
# Set some initial known values
DATA=$(cat <<EOF
"memory": {
"limit": 33554432,
"reservation": 25165824,
"kernel": 16777216,
"kernelTCP": 11534336
},
"cpu": {
"shares": 100,
"quota": 500000,
"period": 1000000,
"cpus": "0"
},
"blockio": {
"blkioWeight": 1000
},
EOF
)
DATA=$(echo ${DATA} | sed 's/\n/\\n/g')
sed -i "s/\(\"resources\": {\)/\1\n${DATA}/" ${BUSYBOX_BUNDLE}/config.json
}
function check_cgroup_value() {
cgroup=$1
source=$2
expected=$3
current=$(cat $cgroup/$source)
[ "$current" -eq "$expected" ]
}
# TODO: test rt cgroup updating
@test "update" {
requires cgroups_kmem
# run a few busyboxes detached
runc run -d --console-socket $CONSOLE_SOCKET test_update
[ "$status" -eq 0 ]
wait_for_container 15 1 test_update
# get the cgroup paths
for g in MEMORY CPUSET CPU BLKIO; do
base_path=$(grep "cgroup" /proc/self/mountinfo | gawk 'toupper($NF) ~ /\<'${g}'\>/ { print $5; exit }')
eval CGROUP_${g}="${base_path}/runc-update-integration-test"
done
# check that initial values were properly set
check_cgroup_value $CGROUP_BLKIO "blkio.weight" 1000
check_cgroup_value $CGROUP_CPU "cpu.cfs_period_us" 1000000
check_cgroup_value $CGROUP_CPU "cpu.cfs_quota_us" 500000
check_cgroup_value $CGROUP_CPU "cpu.shares" 100
check_cgroup_value $CGROUP_CPUSET "cpuset.cpus" 0
check_cgroup_value $CGROUP_MEMORY "memory.kmem.limit_in_bytes" 16777216
check_cgroup_value $CGROUP_MEMORY "memory.kmem.tcp.limit_in_bytes" 11534336
check_cgroup_value $CGROUP_MEMORY "memory.limit_in_bytes" 33554432
check_cgroup_value $CGROUP_MEMORY "memory.soft_limit_in_bytes" 25165824
# update blkio-weight
runc update test_update --blkio-weight 500
[ "$status" -eq 0 ]
check_cgroup_value $CGROUP_BLKIO "blkio.weight" 500
# update cpu-period
runc update test_update --cpu-period 900000
[ "$status" -eq 0 ]
check_cgroup_value $CGROUP_CPU "cpu.cfs_period_us" 900000
# update cpu-quota
runc update test_update --cpu-quota 600000
[ "$status" -eq 0 ]
check_cgroup_value $CGROUP_CPU "cpu.cfs_quota_us" 600000
# update cpu-shares
runc update test_update --cpu-share 200
[ "$status" -eq 0 ]
check_cgroup_value $CGROUP_CPU "cpu.shares" 200
# update cpuset if supported (i.e. we're running on a multicore cpu)
cpu_count=$(grep '^processor' /proc/cpuinfo | wc -l)
if [ $cpu_count -gt 1 ]; then
runc update test_update --cpuset-cpus "1"
[ "$status" -eq 0 ]
check_cgroup_value $CGROUP_CPUSET "cpuset.cpus" 1
fi
# update memory limit
runc update test_update --memory 67108864
[ "$status" -eq 0 ]
check_cgroup_value $CGROUP_MEMORY "memory.limit_in_bytes" 67108864
runc update test_update --memory 50M
[ "$status" -eq 0 ]
check_cgroup_value $CGROUP_MEMORY "memory.limit_in_bytes" 52428800
# update memory soft limit
runc update test_update --memory-reservation 33554432
[ "$status" -eq 0 ]
check_cgroup_value $CGROUP_MEMORY "memory.soft_limit_in_bytes" 33554432
# update memory swap (if available)
if [ -f "$CGROUP_MEMORY/memory.memsw.limit_in_bytes" ]; then
runc update test_update --memory-swap 96468992
[ "$status" -eq 0 ]
check_cgroup_value $CGROUP_MEMORY "memory.memsw.limit_in_bytes" 96468992
fi
# update kernel memory limit
runc update test_update --kernel-memory 50331648
[ "$status" -eq 0 ]
check_cgroup_value $CGROUP_MEMORY "memory.kmem.limit_in_bytes" 50331648
# update kernel memory tcp limit
runc update test_update --kernel-memory-tcp 41943040
[ "$status" -eq 0 ]
check_cgroup_value $CGROUP_MEMORY "memory.kmem.tcp.limit_in_bytes" 41943040
# Revert to the test initial value via json on stding
runc update -r - test_update <<EOF
{
"memory": {
"limit": 33554432,
"reservation": 25165824,
"kernel": 16777216,
"kernelTCP": 11534336
},
"cpu": {
"shares": 100,
"quota": 500000,
"period": 1000000,
"cpus": "0"
},
"blockIO": {
"blkioWeight": 1000
}
}
EOF
[ "$status" -eq 0 ]
check_cgroup_value $CGROUP_BLKIO "blkio.weight" 1000
check_cgroup_value $CGROUP_CPU "cpu.cfs_period_us" 1000000
check_cgroup_value $CGROUP_CPU "cpu.cfs_quota_us" 500000
check_cgroup_value $CGROUP_CPU "cpu.shares" 100
check_cgroup_value $CGROUP_CPUSET "cpuset.cpus" 0
check_cgroup_value $CGROUP_MEMORY "memory.kmem.limit_in_bytes" 16777216
check_cgroup_value $CGROUP_MEMORY "memory.kmem.tcp.limit_in_bytes" 11534336
check_cgroup_value $CGROUP_MEMORY "memory.limit_in_bytes" 33554432
check_cgroup_value $CGROUP_MEMORY "memory.soft_limit_in_bytes" 25165824
# redo all the changes at once
runc update test_update --blkio-weight 500 \
--cpu-period 900000 --cpu-quota 600000 --cpu-share 200 --memory 67108864 \
--memory-reservation 33554432 --kernel-memory 50331648 --kernel-memory-tcp 41943040
[ "$status" -eq 0 ]
check_cgroup_value $CGROUP_BLKIO "blkio.weight" 500
check_cgroup_value $CGROUP_CPU "cpu.cfs_period_us" 900000
check_cgroup_value $CGROUP_CPU "cpu.cfs_quota_us" 600000
check_cgroup_value $CGROUP_CPU "cpu.shares" 200
check_cgroup_value $CGROUP_MEMORY "memory.kmem.limit_in_bytes" 50331648
check_cgroup_value $CGROUP_MEMORY "memory.kmem.tcp.limit_in_bytes" 41943040
check_cgroup_value $CGROUP_MEMORY "memory.limit_in_bytes" 67108864
check_cgroup_value $CGROUP_MEMORY "memory.soft_limit_in_bytes" 33554432
# reset to initial test value via json file
DATA=$(cat <<"EOF"
{
"memory": {
"limit": 33554432,
"reservation": 25165824,
"kernel": 16777216,
"kernelTCP": 11534336
},
"cpu": {
"shares": 100,
"quota": 500000,
"period": 1000000,
"cpus": "0"
},
"blockIO": {
"blkioWeight": 1000
}
}
EOF
)
echo $DATA > $BATS_TMPDIR/runc-update-integration-test.json
runc update -r $BATS_TMPDIR/runc-update-integration-test.json test_update
[ "$status" -eq 0 ]
check_cgroup_value $CGROUP_BLKIO "blkio.weight" 1000
check_cgroup_value $CGROUP_CPU "cpu.cfs_period_us" 1000000
check_cgroup_value $CGROUP_CPU "cpu.cfs_quota_us" 500000
check_cgroup_value $CGROUP_CPU "cpu.shares" 100
check_cgroup_value $CGROUP_CPUSET "cpuset.cpus" 0
check_cgroup_value $CGROUP_MEMORY "memory.kmem.limit_in_bytes" 16777216
check_cgroup_value $CGROUP_MEMORY "memory.kmem.tcp.limit_in_bytes" 11534336
check_cgroup_value $CGROUP_MEMORY "memory.limit_in_bytes" 33554432
check_cgroup_value $CGROUP_MEMORY "memory.soft_limit_in_bytes" 25165824
}
@test "update rt period and runtime" {
requires cgroups_rt
# run a detached busybox
runc run -d --console-socket $CONSOLE_SOCKET test_update_rt
[ "$status" -eq 0 ]
wait_for_container 15 1 test_update_rt
# get the cgroup paths
eval CGROUP_CPU="${CGROUP_CPU_BASE_PATH}/runc-update-integration-test"
runc update -r - test_update_rt <<EOF
{
"cpu": {
"realtimePeriod": 800001,
"realtimeRuntime": 500001
}
}
EOF
check_cgroup_value $CGROUP_CPU "cpu.rt_period_us" 800001
check_cgroup_value $CGROUP_CPU "cpu.rt_runtime_us" 500001
runc update test_update_rt --cpu-rt-period 900001 --cpu-rt-runtime 600001
check_cgroup_value $CGROUP_CPU "cpu.rt_period_us" 900001
check_cgroup_value $CGROUP_CPU "cpu.rt_runtime_us" 600001
}

View file

@ -0,0 +1,11 @@
#!/usr/bin/env bats
load helpers
@test "runc version" {
runc -v
[ "$status" -eq 0 ]
[[ ${lines[0]} =~ runc\ version\ [0-9]+\.[0-9]+\.[0-9]+ ]]
[[ ${lines[1]} =~ commit:+ ]]
[[ ${lines[2]} =~ spec:\ [0-9]+\.[0-9]+\.[0-9]+ ]]
}