criu: add unit testing for config file parser

This tries to add a unit test for the configuration file parser.

Signed-off-by: Adrian Reber <areber@redhat.com>
This commit is contained in:
Adrian Reber 2021-06-22 14:52:09 +00:00 committed by Andrei Vagin
parent 45bde968a2
commit 1a197d4d86
7 changed files with 243 additions and 0 deletions

1
.gitignore vendored
View file

@ -24,6 +24,7 @@ images/google/protobuf/*.c
images/google/protobuf/*.h
.gitid
criu/criu
criu/unittest/unittest
crit/crit
criu/arch/*/sys-exec-tbl*.c
# x86 syscalls-table is not generated

View file

@ -257,6 +257,10 @@ crit: criu
$(Q) $(MAKE) $(build)=crit all
.PHONY: crit
unittest: $(criu-deps)
$(Q) $(MAKE) $(build)=criu unittest
.PHONY: unittest
#
# Libraries next once crit it ready
@ -393,6 +397,7 @@ help:
@echo ' cscope - Generate cscope database'
@echo ' test - Run zdtm test-suite'
@echo ' gcov - Make code coverage report'
@echo ' unittest - Run unit tests'
.PHONY: help
lint:

View file

@ -87,6 +87,26 @@ $(obj)/criu: $(PROGRAM-BUILTINS)
$(call msg-link, $@)
$(Q) $(CC) $(CFLAGS) $^ $(LIBS) $(WRAPFLAGS) $(LDFLAGS) $(GMONLDOPT) -rdynamic -o $@
UNIT-BUILTINS += $(obj)/config.o
UNIT-BUILTINS += $(obj)/log.o
UNIT-BUILTINS += $(obj)/string.o
UNIT-BUILTINS += $(obj)/unittest/built-in.o
$(obj)/unittest/Makefile: ;
$(obj)/unittest/%: .FORCE
$(obj)/unittest/built-in.o: .FORCE
$(Q) $(MAKE) $(call build-as,Makefile,criu/unittest) all
$(obj)/unittest/unittest: $(UNIT-BUILTINS)
$(call msg-link, $@)
$(Q) $(CC) $(CFLAGS) $^ $(LIBS) $(WRAPFLAGS) $(LDFLAGS) -rdynamic -o $@
unittest: $(obj)/unittest/unittest
$(Q) $(obj)/unittest/$@
.PHONY: unittest
#
# Clean the most, except generated c files
@ -97,6 +117,7 @@ subclean:
$(Q) $(MAKE) $(build)=$(ARCH_DIR) clean
$(Q) $(MAKE) $(call build-as,Makefile.library,$(PIE_DIR)) clean
$(Q) $(MAKE) $(call build-as,Makefile.crtools,criu) clean
$(Q) $(MAKE) $(call build-as,Makefile,criu/unittest) clean
$(Q) $(MAKE) $(build)=$(PIE_DIR) clean
.PHONY: subclean
cleanup-y += $(obj)/criu

6
criu/unittest/Makefile Normal file
View file

@ -0,0 +1,6 @@
ldflags-y += -r
obj-y += unit.o
obj-y += mock.o
cleanup-y += $(obj)/unittest

99
criu/unittest/mock.c Normal file
View file

@ -0,0 +1,99 @@
/* This file contains dummy functions to make the unittest compile */
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
int add_external(char *key)
{
return 0;
}
int irmap_scan_path_add(char *path)
{
return 0;
}
bool add_fsname_auto(const char *names)
{
return true;
}
bool add_skip_mount(const char *mountpoint)
{
return true;
}
int check_add_feature(char *feat)
{
return 0;
}
int inherit_fd_parse(char *optarg)
{
return 0;
}
int new_cg_root_add(char *controller, char *newroot)
{
return 0;
}
int add_script(char *path)
{
return 0;
}
int veth_pair_add(char *in, char *out)
{
return 0;
}
int unix_sk_ids_parse(char *optarg)
{
return 0;
}
bool cgp_add_dump_controller(const char *name)
{
return 0;
}
int join_ns_add(const char *type, char *ns_file, char *extra_opts)
{
return 0;
}
int ext_mount_add(char *key, char *val)
{
return 0;
}
int check_namespace_opts(void)
{
return 0;
}
int get_service_fd(int type)
{
return -1;
}
void *shmalloc(size_t bytes)
{
return malloc(bytes);
}
int install_service_fd(int type, int fd)
{
return 0;
}
int close_service_fd(int type)
{
return 0;
}
void compel_log_init(int log_fn, unsigned int level)
{
}

107
criu/unittest/unit.c Normal file
View file

@ -0,0 +1,107 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "log.h"
#include "criu-log.h"
int parse_statement(int i, char *line, char **configuration);
int main(int argc, char *argv[], char *envp[])
{
char **configuration;
int i;
configuration = malloc(10 * sizeof(char *));
log_init(NULL);
i = parse_statement(0, "", configuration);
assert(i == 0);
i = parse_statement(0, "\n", configuration);
assert(i == 0);
i = parse_statement(0, "# comment\n", configuration);
assert(i == 0);
i = parse_statement(0, "#comment\n", configuration);
assert(i == 0);
i = parse_statement(0, "tcp-close #comment\n", configuration);
assert(i == 1);
assert(!strcmp(configuration[0], "--tcp-close"));
i = parse_statement(0, " tcp-close #comment\n", configuration);
assert(i == 1);
assert(!strcmp(configuration[0], "--tcp-close"));
i = parse_statement(0, "test \"test\"\n", configuration);
assert(i == 2);
assert(!strcmp(configuration[0], "--test"));
assert(!strcmp(configuration[1], "test"));
i = parse_statement(0, "dsfa \"aaaaa \\\"bbbbbb\\\"\"\n", configuration);
assert(i == 2);
assert(!strcmp(configuration[0], "--dsfa"));
assert(!strcmp(configuration[1], "aaaaa \"bbbbbb\""));
i = parse_statement(0, "verbosity 4\n", configuration);
assert(i == 2);
assert(!strcmp(configuration[0], "--verbosity"));
assert(!strcmp(configuration[1], "4"));
i = parse_statement(0, "verbosity \"\n", configuration);
assert(i == -1);
i = parse_statement(0, "verbosity 4#comment\n", configuration);
assert(i == 2);
assert(!strcmp(configuration[0], "--verbosity"));
assert(!strcmp(configuration[1], "4"));
i = parse_statement(0, "verbosity 4 #comment\n", configuration);
assert(i == 2);
assert(!strcmp(configuration[0], "--verbosity"));
assert(!strcmp(configuration[1], "4"));
i = parse_statement(0, "verbosity 4 #comment\n", configuration);
assert(i == 2);
assert(!strcmp(configuration[0], "--verbosity"));
assert(!strcmp(configuration[1], "4"));
i = parse_statement(0, "verbosity 4 no-comment\n", configuration);
assert(i == -1);
i = parse_statement(0, "lsm-profile \"\" # more comments\n", configuration);
assert(i == 2);
assert(!strcmp(configuration[0], "--lsm-profile"));
assert(!strcmp(configuration[1], ""));
i = parse_statement(0, "lsm-profile \"something\"# comment\n", configuration);
assert(i == 2);
assert(!strcmp(configuration[0], "--lsm-profile"));
assert(!strcmp(configuration[1], "something"));
i = parse_statement(0, "#\n", configuration);
assert(i == 0);
i = parse_statement(0, "lsm-profile \"selinux:something\\\"with\\\"quotes\"\n", configuration);
assert(i == 2);
assert(!strcmp(configuration[0], "--lsm-profile"));
assert(!strcmp(configuration[1], "selinux:something\"with\"quotes"));
i = parse_statement(0, "work-dir \"/tmp with spaces\" no-comment\n", configuration);
assert(i == -1);
i = parse_statement(0, "work-dir \"/tmp with spaces\"\n", configuration);
assert(i == 2);
assert(!strcmp(configuration[0], "--work-dir"));
assert(!strcmp(configuration[1], "/tmp with spaces"));
i = parse_statement(0, "a b c d e f g h i\n", configuration);
assert(i == -1);
pr_msg("OK\n");
return 0;
}

View file

@ -126,6 +126,10 @@ if [ "$WIDTH" -gt 80 ]; then
exit 1
fi
# Unit tests at this point do not require any kernel or hardware capabilities.
# Just try to run it everywhere for now.
time make unittest
[ -n "$SKIP_CI_TEST" ] && exit 0
ulimit -c unlimited