Skip to content

Commit

Permalink
test: generate checkpoint image files for tests
Browse files Browse the repository at this point in the history
Previously, tests were run against a stats-dump file available in the
test directory. Now that we require other checkpoint files to test the
functionality added through CRIT, a proper checkpoint is generated with
CRIU and used.

Signed-off-by: Prajwal S N <[email protected]>
  • Loading branch information
snprajwal committed Jun 10, 2023
1 parent 0405c79 commit 19ae4f8
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 49 deletions.
9 changes: 7 additions & 2 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ jobs:
# needed for codecov
fetch-depth: 0
- name: Install tools
run: sudo apt-get install -qqy bats
run: |
sudo apt-get install -qqy bats
# Add PPA for CRIU
sudo add-apt-repository ppa:criu/ppa
sudo apt-get update
sudo apt-get install -qqy criu
- name: Run make coverage
run: make coverage
run: sudo -E make coverage
- name: Run make codecov
run: make codecov
9 changes: 5 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@ jobs:
runs-on: ubuntu-latest
container:
image: registry.fedoraproject.org/fedora:latest
options: --privileged
steps:
- uses: actions/checkout@v3
- name: Install tools
run: sudo dnf -y install ShellCheck bats golang
run: sudo dnf -y install ShellCheck bats golang criu
- name: Run make shellcheck
run: make shellcheck
- name: Run make all
run: make all
- name: Run make test
run: make test
run: sudo -E make test
- name: Run make test-junit
run: make test-junit
run: sudo -E make test-junit
- name: Upload Test Results
# To display test results from forked repositories they need to
# be uploaded and then analyzed.
Expand All @@ -27,7 +28,7 @@ jobs:
with:
name: test-results
retention-days: 1
path: junit.xml
path: test/junit.xml
- name: Run make install/uninstall
run: test/uninstall.sh

Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ checkpointctl
checkpointctl.coverage
.coverage
junit.xml
test/piggie/piggie
test/test-imgs
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,14 @@ shellcheck:
lint: golang-lint shellcheck

test: $(NAME)
bats test/*bats
make -C test

test-junit: $(NAME)
bats -F junit test/*bats > junit.xml
make -C test test-junit clean

coverage: check-go-version $(NAME).coverage
mkdir -p $(COVERAGE_PATH)
COVERAGE_PATH=$(COVERAGE_PATH) COVERAGE=1 bats test/*bats
COVERAGE_PATH=$(COVERAGE_PATH) COVERAGE=1 make -C test
# Print coverage from this run
$(GO) tool covdata percent -i=${COVERAGE_PATH}
$(GO) tool covdata textfmt -i=${COVERAGE_PATH} -o ${COVERAGE_PATH}/coverage.out
Expand Down
26 changes: 26 additions & 0 deletions test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
CRIU ?= criu
CC ?= gcc

all: test clean

test: test-imgs
@echo "Running BATS tests..."
bats checkpointctl.bats

test-junit: test-imgs
@echo "Running BATS tests with JUnit results..."
bats -F junit checkpointctl.bats > junit.xml

test-imgs: piggie/piggie
$(eval PID := $(shell piggie/piggie))
mkdir -p $@
$(CRIU) dump -v4 -o dump.log -D $@ -t $(PID)

piggie/piggie: piggie/piggie.c
$(CC) $^ -o $@

clean:
@echo "Cleaning up test files..."
@rm -rf test-imgs piggie/piggie

.PHONY: all test test-junit clean
81 changes: 41 additions & 40 deletions test/checkpointctl.bats
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
if [ -n "$COVERAGE" ]; then
export GOCOVERDIR="${COVERAGE_PATH}"
CHECKPOINTCTL="./checkpointctl.coverage"
CHECKPOINTCTL="../checkpointctl.coverage"
else
CHECKPOINTCTL="./checkpointctl"
CHECKPOINTCTL="../checkpointctl"
fi

TEST_TMP_DIR1=""
TEST_TMP_DIR2=""

Expand Down Expand Up @@ -57,7 +58,7 @@ function teardown() {
}

@test "Run checkpointctl show with tar file with valid config.dump and no spec.dump" {
cp test/config.dump "$TEST_TMP_DIR1"
cp data/config.dump "$TEST_TMP_DIR1"
mkdir "$TEST_TMP_DIR1"/checkpoint
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl show "$TEST_TMP_DIR2"/test.tar
Expand All @@ -66,7 +67,7 @@ function teardown() {
}

@test "Run checkpointctl show with tar file with valid config.dump and empty spec.dump" {
cp test/config.dump "$TEST_TMP_DIR1"
cp data/config.dump "$TEST_TMP_DIR1"
mkdir "$TEST_TMP_DIR1"/checkpoint
touch "$TEST_TMP_DIR1"/spec.dump
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
Expand All @@ -76,17 +77,17 @@ function teardown() {
}

@test "Run checkpointctl show with tar file with valid config.dump and valid spec.dump and no checkpoint directory" {
cp test/config.dump "$TEST_TMP_DIR1"
cp test/spec.dump "$TEST_TMP_DIR1"
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump "$TEST_TMP_DIR1"
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl show "$TEST_TMP_DIR2"/test.tar
[ "$status" -eq 1 ]
[[ ${lines[0]} == *"Error: checkpoint directory is missing in the archive file"* ]]
}

@test "Run checkpointctl show with tar file with valid config.dump and valid spec.dump and checkpoint directory" {
cp test/config.dump "$TEST_TMP_DIR1"
cp test/spec.dump "$TEST_TMP_DIR1"
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump "$TEST_TMP_DIR1"
mkdir "$TEST_TMP_DIR1"/checkpoint
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl show "$TEST_TMP_DIR2"/test.tar
Expand All @@ -95,7 +96,7 @@ function teardown() {
}

@test "Run checkpointctl show with tar file from containerd with valid config.dump and valid spec.dump and checkpoint directory" {
cp test/config.dump "$TEST_TMP_DIR1"
cp data/config.dump "$TEST_TMP_DIR1"
mkdir "$TEST_TMP_DIR1"/checkpoint
echo "{}" > "$TEST_TMP_DIR1"/status
echo "{}" > "$TEST_TMP_DIR1"/spec.dump
Expand All @@ -106,8 +107,8 @@ function teardown() {
}

@test "Run checkpointctl show with tar file and --stats and missing stats-dump" {
cp test/config.dump "$TEST_TMP_DIR1"
cp test/spec.dump "$TEST_TMP_DIR1"
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump "$TEST_TMP_DIR1"
mkdir "$TEST_TMP_DIR1"/checkpoint
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl show "$TEST_TMP_DIR2"/test.tar --stats
Expand All @@ -116,9 +117,9 @@ function teardown() {
}

@test "Run checkpointctl show with tar file and --stats and invalid stats-dump" {
cp test/config.dump "$TEST_TMP_DIR1"
cp test/spec.dump "$TEST_TMP_DIR1"
cp test/spec.dump "$TEST_TMP_DIR1"/stats-dump
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump "$TEST_TMP_DIR1"
cp data/spec.dump "$TEST_TMP_DIR1"/stats-dump
mkdir "$TEST_TMP_DIR1"/checkpoint
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl show "$TEST_TMP_DIR2"/test.tar --stats
Expand All @@ -127,21 +128,21 @@ function teardown() {
}

@test "Run checkpointctl show with tar file and --stats and valid stats-dump" {
cp test/config.dump "$TEST_TMP_DIR1"
cp test/spec.dump "$TEST_TMP_DIR1"
cp test/stats-dump "$TEST_TMP_DIR1"
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump "$TEST_TMP_DIR1"
cp test-imgs/stats-dump "$TEST_TMP_DIR1"
mkdir "$TEST_TMP_DIR1"/checkpoint
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl show "$TEST_TMP_DIR2"/test.tar --stats
[ "$status" -eq 0 ]
[[ ${lines[6]} == *"CRIU dump statistics"* ]]
[[ ${lines[8]} == *"MEMWRITE TIME"* ]]
[[ ${lines[10]} == *"446571 us"* ]]
[[ ${lines[10]} =~ [1-9]+" us" ]]
}

@test "Run checkpointctl show with tar file and --mounts and valid spec.dump" {
cp test/config.dump "$TEST_TMP_DIR1"
cp test/spec.dump "$TEST_TMP_DIR1"
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump "$TEST_TMP_DIR1"
mkdir "$TEST_TMP_DIR1"/checkpoint
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl show "$TEST_TMP_DIR2"/test.tar --mounts
Expand All @@ -152,8 +153,8 @@ function teardown() {
}

@test "Run checkpointctl show with tar file and --mounts and --full-paths and valid spec.dump" {
cp test/config.dump "$TEST_TMP_DIR1"
cp test/spec.dump "$TEST_TMP_DIR1"
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump "$TEST_TMP_DIR1"
mkdir "$TEST_TMP_DIR1"/checkpoint
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl show "$TEST_TMP_DIR2"/test.tar --mounts --full-paths
Expand All @@ -164,9 +165,9 @@ function teardown() {
}

@test "Run checkpointctl show with tar file and --all and valid spec.dump and valid stats-dump" {
cp test/config.dump "$TEST_TMP_DIR1"
cp test/spec.dump "$TEST_TMP_DIR1"
cp test/stats-dump "$TEST_TMP_DIR1"
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump "$TEST_TMP_DIR1"
cp test-imgs/stats-dump "$TEST_TMP_DIR1"
mkdir "$TEST_TMP_DIR1"/checkpoint
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl show "$TEST_TMP_DIR2"/test.tar --all
Expand All @@ -177,12 +178,12 @@ function teardown() {
[[ ${lines[11]} == *"/etc/hostname"* ]]
[[ ${lines[13]} == *"CRIU dump statistics"* ]]
[[ ${lines[15]} == *"MEMWRITE TIME"* ]]
[[ ${lines[17]} == *"446571 us"* ]]
[[ ${lines[17]} =~ [1-9]+" us" ]]
}

@test "Run checkpointctl show with tar file and missing --mounts/--all and --full-paths" {
cp test/config.dump "$TEST_TMP_DIR1"
cp test/spec.dump "$TEST_TMP_DIR1"
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump "$TEST_TMP_DIR1"
mkdir "$TEST_TMP_DIR1"/checkpoint
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl show "$TEST_TMP_DIR2"/test.tar --full-paths
Expand All @@ -191,17 +192,17 @@ function teardown() {
}

@test "Run checkpointctl show with tar file with valid config.dump and valid spec.dump (CRI-O) and no checkpoint directory" {
cp test/config.dump "$TEST_TMP_DIR1"
cp test/spec.dump.cri-o "$TEST_TMP_DIR1"/spec.dump
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump.cri-o "$TEST_TMP_DIR1"/spec.dump
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl show "$TEST_TMP_DIR2"/test.tar
[ "$status" -eq 1 ]
[[ ${lines[0]} == *"Error: checkpoint directory is missing in the archive file"* ]]
}

@test "Run checkpointctl show with tar file with valid config.dump and valid spec.dump (CRI-O) and checkpoint directory" {
cp test/config.dump "$TEST_TMP_DIR1"
cp test/spec.dump.cri-o "$TEST_TMP_DIR1"/spec.dump
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump.cri-o "$TEST_TMP_DIR1"/spec.dump
mkdir "$TEST_TMP_DIR1"/checkpoint
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl show "$TEST_TMP_DIR2"/test.tar
Expand All @@ -210,8 +211,8 @@ function teardown() {
}

@test "Run checkpointctl show with tar file compressed" {
cp test/config.dump "$TEST_TMP_DIR1"
cp test/spec.dump "$TEST_TMP_DIR1"
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump "$TEST_TMP_DIR1"
mkdir "$TEST_TMP_DIR1"/checkpoint
( cd "$TEST_TMP_DIR1" && tar czf "$TEST_TMP_DIR2"/test.tar.gz . )
checkpointctl show "$TEST_TMP_DIR2"/test.tar.gz
Expand All @@ -220,8 +221,8 @@ function teardown() {
}

@test "Run checkpointctl show with tar file corrupted" {
cp test/config.dump "$TEST_TMP_DIR1"
cp test/spec.dump "$TEST_TMP_DIR1"
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump "$TEST_TMP_DIR1"
mkdir "$TEST_TMP_DIR1"/checkpoint
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
dd if=/dev/urandom of="$TEST_TMP_DIR2"/test.tar bs=1 count=10 seek=2 conv=notrunc
Expand All @@ -231,8 +232,8 @@ function teardown() {
}

@test "Run checkpointctl show with tar file compressed and corrupted" {
cp test/config.dump "$TEST_TMP_DIR1"
cp test/spec.dump "$TEST_TMP_DIR1"
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump "$TEST_TMP_DIR1"
mkdir "$TEST_TMP_DIR1"/checkpoint
( cd "$TEST_TMP_DIR1" && tar czf "$TEST_TMP_DIR2"/test.tar.gz . )
dd if=/dev/urandom of="$TEST_TMP_DIR2"/test.tar.gz bs=1 count=10 seek=2 conv=notrunc
Expand All @@ -242,8 +243,8 @@ function teardown() {
}

@test "Run checkpointctl show with tar file and rootfs-diff tar file" {
cp test/config.dump "$TEST_TMP_DIR1"
cp test/spec.dump "$TEST_TMP_DIR1"
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump "$TEST_TMP_DIR1"
mkdir "$TEST_TMP_DIR1"/checkpoint
echo 1 > "$TEST_TMP_DIR1"/test.pid
tar -cf "$TEST_TMP_DIR1"/rootfs-diff.tar -C "$TEST_TMP_DIR1" test.pid
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
61 changes: 61 additions & 0 deletions test/piggie/piggie.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sched.h>

#define STKS (4*4096)

#ifndef CLONE_NEWPID
#define CLONE_NEWPID 0x20000000
#endif

static int do_test(void *logf)
{
int fd, i = 0;

setsid();

close(0);
close(1);
close(2);

fd = open("/dev/null", O_RDONLY);
if (fd != 0) {
dup2(fd, 0);
close(fd);
}

fd = open(logf, O_WRONLY | O_TRUNC | O_CREAT, 0600);
dup2(fd, 1);
dup2(fd, 2);
if (fd != 1 && fd != 2)
close(fd);

while (1) {
sleep(1);
printf("%d\n", i++);
fflush(stdout);
}

return 0;
}

int main(int argc, char **argv)
{
int pid;
void *stk;

stk = mmap(NULL, STKS, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON | MAP_GROWSDOWN, 0, 0);
pid = clone(do_test, stk + STKS, SIGCHLD | CLONE_NEWPID, argv[1]);
if (pid < 0) {
fprintf(stderr, "clone() failed: %m\n");
return 1;
}
printf("%d\n", pid);

return 0;
}
Binary file removed test/stats-dump
Binary file not shown.

0 comments on commit 19ae4f8

Please sign in to comment.