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 May 30, 2023
1 parent 540772d commit 48b6c18
Show file tree
Hide file tree
Showing 12 changed files with 164 additions and 48 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ jobs:
# needed for codecov
fetch-depth: 0
- name: Install tools
run: sudo apt-get install -qqy bats
- name: Run make coverage
run: make coverage
- name: Run make codecov
run: sudo apt-get install -qqy bats criu
- name: Run tests with coverage
run: sudo -E make coverage
- name: Generate coverage report
run: make codecov
19 changes: 10 additions & 9 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,29 @@ 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
- name: Run make shellcheck
run: sudo dnf -y install ShellCheck bats golang criu
- name: Run ShellCheck
run: make shellcheck
- name: Run make all
run: make all
- name: Run make test
run: make test
- name: Run make test-junit
run: make test-junit
- name: Upload Test Results
- name: Run tests
run: sudo -E make test
- name: Run tests with JUnit results
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.
if: always()
uses: actions/upload-artifact@v3
with:
name: test-results
retention-days: 1
path: junit.xml
- name: Run make install/uninstall
path: test/junit.xml
- name: Run install/uninstall tests
run: test/uninstall.sh

event_file:
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/loop/loop
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
25 changes: 25 additions & 0 deletions test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
CRIU ?= criu

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: loop/loop
$(eval PID := $(shell loop/loop))
mkdir -p $@
$(CRIU) dump -v4 -o dump.log -D $@ -t $(PID)

loop/loop:
$(MAKE) -C loop

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

.PHONY: all test test-junit clean
80 changes: 48 additions & 32 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 @@ -56,15 +57,15 @@ 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"
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl show "$TEST_TMP_DIR2"/test.tar
[ "$status" -eq 1 ]
[[ ${lines[0]} == *"spec.dump: no such file or directory" ]]
}

@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"
touch "$TEST_TMP_DIR1"/spec.dump
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl show "$TEST_TMP_DIR2"/test.tar
Expand All @@ -73,17 +74,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]} == *"checkpoint: no such file or directory" ]]
}

@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 @@ -92,7 +93,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 @@ -103,8 +104,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 @@ -113,9 +114,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 @@ -124,21 +125,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[7]} == *"CRIU dump statistics"* ]]
[[ ${lines[9]} == *"MEMWRITE TIME"* ]]
[[ ${lines[11]} == *"446571 us"* ]]
[[ ${lines[11]} =~ [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 @@ -149,8 +150,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 @@ -161,9 +162,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 @@ -174,12 +175,12 @@ function teardown() {
[[ ${lines[12]} == *"/etc/hostname"* ]]
[[ ${lines[14]} == *"CRIU dump statistics"* ]]
[[ ${lines[16]} == *"MEMWRITE TIME"* ]]
[[ ${lines[18]} == *"446571 us"* ]]
[[ ${lines[18]} =~ [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 @@ -188,20 +189,35 @@ 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]} == *"checkpoint: no such file or directory"* ]]
}

@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
[ "$status" -eq 0 ]
[[ ${lines[5]} == *"CRI-O"* ]]
}

@test "Run checkpointctl show with tar file and --fds" {
cp data/config.dump \
data/spec.dump \
test-imgs/pstree.img \
test-imgs/files.img \
test-imgs/fdinfo-*.img \
test-imgs/ids-*.img \
test-imgs/fs-*.img "$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 --fds
[ "$status" -eq 0 ]
[[ ${lines[11]} == *"3 | /dev/null"* ]]
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
9 changes: 9 additions & 0 deletions test/loop/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CC ?= gcc

loop: loop.c
$(CC) $^ -o $@

clean:
@rm -f loop

.PHONY: clean
63 changes: 63 additions & 0 deletions test/loop/loop.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
pid_t pid;
pid_t sid;
int res = EXIT_FAILURE;
int start_pipe[2];

if (pipe(start_pipe)) {
perror("pipe failed!");
goto out;
}

pid = fork();
if (pid < 0) {
perror("fork failed!");
goto out;
}

if (pid == 0) {
close(start_pipe[0]);

sid = setsid();
if (sid < 0) {
perror("setsid failed!");
res = EXIT_FAILURE;
write(start_pipe[1], &res, sizeof(res));
close(start_pipe[1]);
exit(1);
}

// Create a file descriptor for "crit x ./ fds" test
open("/dev/null", O_RDONLY);

chdir("/");
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);

res = EXIT_SUCCESS;
write(start_pipe[1], &res, sizeof(res));
close(start_pipe[1]);

while (1) {
sleep(1);
}
}

close(start_pipe[1]);
read(start_pipe[0], &res, sizeof(res));
close(start_pipe[0]);

out:
if (res == EXIT_SUCCESS)
printf("%d\n", pid);
return res;
}
Binary file removed test/stats-dump
Binary file not shown.

0 comments on commit 48b6c18

Please sign in to comment.