[CRIU] [RFC 4/4] compel: add tests for compel

Dmitry Safonov dsafonov at virtuozzo.com
Fri May 6 09:14:59 PDT 2016


Yet they only test for ELF header, but soon I'll add more of them.
It's build with
  $ make test/compel/handle_binary
and test output is in TAP format:
  $ ./test/compel/handle_binary
  ok 1 - check zero ELF header
  ok 2 - check non-supported ELF header
  ok 3 - check non-relocatable ELF header
  ok 4 - check zero ELF header
  ok 5 - check non-supported ELF header
  ok 6 - check non-relocatable ELF header
(here two runs for x86_64 and x86_32 ELF binaries)
I'm planning to integrate it with Travis, so we will be
sure that compel is properly working (as this tests doesn't need
any ns and may be run on qemu-static).

Cc: Cyrill Gorcunov <gorcunov at openvz.org>
Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
 Makefile                                           |  4 ++
 compel/Makefile                                    | 16 +++++--
 test/compel/Makefile                               | 18 ++++++++
 .../arch/aarch64/include/arch_test_handle_binary.h | 21 +++++++++
 .../arch/arm/include/arch_test_handle_binary.h     | 18 ++++++++
 .../arch/ppc64/include/arch_test_handle_binary.h   | 21 +++++++++
 .../arch/x86/include/arch_test_handle_binary.h     | 45 ++++++++++++++++++
 test/compel/handle_binary.c                        | 39 ++++++++++++++++
 test/compel/handle_binary_32.c                     |  1 +
 test/compel/main.c                                 | 54 ++++++++++++++++++++++
 10 files changed, 234 insertions(+), 3 deletions(-)
 create mode 100644 test/compel/Makefile
 create mode 100644 test/compel/arch/aarch64/include/arch_test_handle_binary.h
 create mode 100644 test/compel/arch/arm/include/arch_test_handle_binary.h
 create mode 100644 test/compel/arch/ppc64/include/arch_test_handle_binary.h
 create mode 100644 test/compel/arch/x86/include/arch_test_handle_binary.h
 create mode 100644 test/compel/handle_binary.c
 create mode 120000 test/compel/handle_binary_32.c
 create mode 100644 test/compel/main.c

diff --git a/Makefile b/Makefile
index 032656356be7..eceb85041917 100644
--- a/Makefile
+++ b/Makefile
@@ -176,6 +176,9 @@ $(eval $(call gen-built-in,images))
 compel/%:
 	$(Q) $(MAKE) $(build)=compel $@
 
+test/compel/%:
+	$(Q) $(MAKE) $(build)=compel $@
+
 #
 # CRIU building done in own directory
 # with slightly different rules so we
@@ -207,6 +210,7 @@ subclean:
 	$(call msg-clean, criu)
 	$(Q) $(MAKE) -C lib clean
 	$(Q) $(MAKE) -C Documentation clean
+	$(Q) $(MAKE) $(build)=test/compel clean
 	$(Q) $(RM) .gitid
 .PHONY: subclean
 
diff --git a/compel/Makefile b/compel/Makefile
index ca4b761744b4..f4f945795f35 100644
--- a/compel/Makefile
+++ b/compel/Makefile
@@ -6,8 +6,10 @@ ccflags-y	+= -iquote compel/arch/$(ARCH)/include
 ccflags-y	+= -DCOMPEL_VERSION=\"$(COMPEL_SO_VERSION_MAJOR).$(COMPEL_SO_VERSION_MINOR)\"
 
 host-ccflags-y	+= $(ccflags-y)
-HOSTCFLAGS	+= $(WARNINGS) $(filter-out -DCONFIG_X86_64,$(DEFINES))
+HOSTCFLAGS	+= $(WARNINGS) $(DEFINES)
 HOSTLDFLAGS	+= $(LDFLAGS)
+HOSTCFLAGS	:= $(filter-out -DCONFIG_X86_64,$(HOSTCFLAGS))
+export host-ccflags-y HOSTCFLAGS HOSTLDFLAGS
 
 hostprogs-y	+= compel
 compel-objs	+= main.o
@@ -17,10 +19,18 @@ compel-objs	+= arch/$(ARCH)/handle-elf.o
 ifeq ($(ARCH),x86)
 # Add -DCONFIG_X86_64 or -DCONFIG_X86_32 to HOSTCFLAGS
 define ccflags-defines
-        HOSTCFLAGS_$(notdir $(1)) += -DCONFIG_X86_64
+        export HOSTCFLAGS_$(notdir $(1)) += -DCONFIG_X86_64
 endef
 $(eval $(call map,ccflags-defines,$(compel-objs)))
 
 compel-objs += handle-elf-32.o
-HOSTCFLAGS_handle-elf-32.o += -DCONFIG_X86_32
+export HOSTCFLAGS_handle-elf-32.o += -DCONFIG_X86_32
 endif # ARCH == x86
+
+export compel-objs
+test/compel/%:
+	$(Q) $(MAKE) $(build)=test/compel $@
+
+test: test/compel/test_handle_binary
+
+.PHONY: test
diff --git a/test/compel/Makefile b/test/compel/Makefile
new file mode 100644
index 000000000000..a23097f621ce
--- /dev/null
+++ b/test/compel/Makefile
@@ -0,0 +1,18 @@
+# Relative path to original objects
+define compel_obj_path
+        $(addprefix ../../compel/,$(1))
+endef
+
+host-ccflags-y		+= -iquote test/compel/arch/$(ARCH)/include
+test_objs		:= $(filter-out main.o,$(compel-objs))
+
+hostprogs-y		+= handle_binary
+handle_binary-objs	+= $(call compel_obj_path,$(test_objs))
+handle_binary-objs	+= main.o
+handle_binary-objs	+= handle_binary.o
+
+ifeq ($(ARCH),x86)
+    handle_binary-objs	+= handle_binary_32.o
+    HOSTCFLAGS_handle_binary.o		+= -DCONFIG_X86_64
+    HOSTCFLAGS_handle_binary_32.o	+= -DCONFIG_X86_32
+endif
diff --git a/test/compel/arch/aarch64/include/arch_test_handle_binary.h b/test/compel/arch/aarch64/include/arch_test_handle_binary.h
new file mode 100644
index 000000000000..9ed25c9f5aed
--- /dev/null
+++ b/test/compel/arch/aarch64/include/arch_test_handle_binary.h
@@ -0,0 +1,21 @@
+#ifndef __ARCH_TEST_HANDLE_BINARY__
+#define __ARCH_TEST_HANDLE_BINARY__
+
+#include "uapi/elf64-types.h"
+#define __run_tests	arch_run_tests
+
+static __maybe_unused void arch_test_set_elf_hdr_ident(void *mem)
+{
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+	memcpy(mem, elf_ident_64_le, sizeof(elf_ident_64_le));
+#else
+	memcpy(mem, elf_ident_64_be, sizeof(elf_ident_64_be));
+#endif
+}
+
+static __maybe_unused void arch_test_set_elf_hdr_machine(Ehdr_t *hdr)
+{
+	hdr->e_machine = EM_AARCH64;
+}
+
+#endif /* __ARCH_TEST_HANDLE_BINARY__ */
diff --git a/test/compel/arch/arm/include/arch_test_handle_binary.h b/test/compel/arch/arm/include/arch_test_handle_binary.h
new file mode 100644
index 000000000000..4b14b2bf682b
--- /dev/null
+++ b/test/compel/arch/arm/include/arch_test_handle_binary.h
@@ -0,0 +1,18 @@
+#ifndef __ARCH_TEST_HANDLE_BINARY__
+#define __ARCH_TEST_HANDLE_BINARY__
+
+#include "uapi/elf32-types.h"
+#define __run_tests	arch_run_tests
+
+static __maybe_unused void arch_test_set_elf_hdr_ident(void *mem)
+{
+	memcpy(mem, elf_ident_32, sizeof(elf_ident_32));
+}
+
+static __maybe_unused void arch_test_set_elf_hdr_machine(Ehdr_t *hdr)
+{
+	hdr->e_machine = EM_ARM;
+}
+
+
+#endif /* __ARCH_TEST_HANDLE_BINARY__ */
diff --git a/test/compel/arch/ppc64/include/arch_test_handle_binary.h b/test/compel/arch/ppc64/include/arch_test_handle_binary.h
new file mode 100644
index 000000000000..7bf80b25d524
--- /dev/null
+++ b/test/compel/arch/ppc64/include/arch_test_handle_binary.h
@@ -0,0 +1,21 @@
+#ifndef __ARCH_TEST_HANDLE_BINARY__
+#define __ARCH_TEST_HANDLE_BINARY__
+
+#include "uapi/elf64-types.h"
+#define __run_tests	arch_run_tests
+
+static __maybe_unused void arch_test_set_elf_hdr_ident(void *mem)
+{
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+	memcpy(mem, elf_ident_64_le, sizeof(elf_ident_64_le));
+#else
+	memcpy(mem, elf_ident_64_be, sizeof(elf_ident_64_be));
+#endif
+}
+
+static __maybe_unused void arch_test_set_elf_hdr_machine(Ehdr_t *hdr)
+{
+	hdr->e_machine = EM_PPC64;
+}
+
+#endif /* __ARCH_TEST_HANDLE_BINARY__ */
diff --git a/test/compel/arch/x86/include/arch_test_handle_binary.h b/test/compel/arch/x86/include/arch_test_handle_binary.h
new file mode 100644
index 000000000000..cbc240e5892a
--- /dev/null
+++ b/test/compel/arch/x86/include/arch_test_handle_binary.h
@@ -0,0 +1,45 @@
+#ifndef __ARCH_TEST_HANDLE_BINARY__
+#define __ARCH_TEST_HANDLE_BINARY__
+
+#include <string.h>
+
+#ifdef CONFIG_X86_64
+#include "uapi/elf64-types.h"
+#define __run_tests	run_tests_64
+
+static __maybe_unused void arch_test_set_elf_hdr_ident(void *mem)
+{
+	memcpy(mem, elf_ident_64_le, sizeof(elf_ident_64_le));
+}
+
+static __maybe_unused void arch_test_set_elf_hdr_machine(Ehdr_t *hdr)
+{
+	hdr->e_machine = EM_X86_64;
+}
+
+#else /* !CONFIG_X86_64 */
+
+#include "uapi/elf32-types.h"
+#define __run_tests	run_tests_32
+
+static __maybe_unused void arch_test_set_elf_hdr_ident(void *mem)
+{
+	memcpy(mem, elf_ident_32, sizeof(elf_ident_32));
+}
+
+static __maybe_unused void arch_test_set_elf_hdr_machine(Ehdr_t *hdr)
+{
+	hdr->e_machine = EM_386;
+}
+
+#endif /* CONFIG_X86_32 */
+
+extern void run_tests_64(void *mem);
+extern void run_tests_32(void *mem);
+
+static __maybe_unused void arch_run_tests(void *mem)
+{
+	run_tests_64(mem);
+	run_tests_32(mem);
+}
+#endif /* __ARCH_TEST_HANDLE_BINARY__ */
diff --git a/test/compel/handle_binary.c b/test/compel/handle_binary.c
new file mode 100644
index 000000000000..a1d0bc0a09d8
--- /dev/null
+++ b/test/compel/handle_binary.c
@@ -0,0 +1,39 @@
+#include <string.h>
+
+#include "uapi/piegen-err.h"
+#include "piegen.h"
+
+#include "arch_test_handle_binary.h"
+
+extern int launch_test(void *mem, int expected_ret, const char *test_name);
+
+static void set_elf_hdr_relocatable(Ehdr_t *hdr)
+{
+	hdr->e_type = ET_REL;
+	hdr->e_version = EV_CURRENT;
+}
+
+static int test_prepare_elf_header(void *elf)
+{
+	memset(elf, 0, sizeof(Ehdr_t));
+	if (launch_test(elf, -E_NOT_ELF, "check zero ELF header"))
+		return -1;
+
+	arch_test_set_elf_hdr_ident(elf);
+	if (launch_test(elf, -E_NOT_ELF, "check non-supported ELF header"))
+		return -1;
+
+	arch_test_set_elf_hdr_machine(elf);
+	if (launch_test(elf, -E_NOT_ELF, "check non-relocatable ELF header"))
+		return -1;
+
+	set_elf_hdr_relocatable(elf);
+
+	return 0;
+}
+
+void __run_tests(void *mem)
+{
+	if (test_prepare_elf_header(mem))
+		return;
+}
diff --git a/test/compel/handle_binary_32.c b/test/compel/handle_binary_32.c
new file mode 120000
index 000000000000..5364be3e42ac
--- /dev/null
+++ b/test/compel/handle_binary_32.c
@@ -0,0 +1 @@
+handle_binary.c
\ No newline at end of file
diff --git a/test/compel/main.c b/test/compel/main.c
new file mode 100644
index 000000000000..e272dfb766da
--- /dev/null
+++ b/test/compel/main.c
@@ -0,0 +1,54 @@
+/*
+ * Test for handle_binary().
+ * In this test ELF binary file is constructed from
+ * header up to sections and relocations.
+ * On each stage it tests non-valid ELF binaries to be parsed.
+ * For passing test, handle_binary should return errors for all
+ * non-valid binaries and handle all relocations.
+ *
+ * Test author: Dmitry Safonov <dsafonov at virtuozzo.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "piegen.h"
+#include "arch_test_handle_binary.h"
+
+/* size of buffer with formed ELF file */
+#define ELF_BUF_SIZE	4096
+
+extern int handle_binary(void *mem, size_t size);
+extern void run_tests(void *mem);
+
+piegen_opt_t opts = {
+	.fout		= NULL,
+	.ferr		= NULL,
+	.fdebug		= NULL,
+};
+
+int launch_test(void *mem, int expected_ret, const char *test_name)
+{
+	static unsigned test_nr = 1;
+	int ret = handle_binary(mem, ELF_BUF_SIZE);
+
+	if (ret != expected_ret)
+		printf("not ok %u - %s, expected %d but ret is %d\n",
+				test_nr, test_name, expected_ret, ret);
+	else
+		printf("ok %u - %s\n", test_nr, test_name);
+	test_nr++;
+	fflush(stdout);
+
+	return ret != expected_ret;
+}
+
+int main(int argc, char **argv)
+{
+	void *elf_buf = malloc(ELF_BUF_SIZE);
+
+	arch_run_tests(elf_buf);
+	free(elf_buf);
+	return 0;
+}
-- 
2.8.0



More information about the CRIU mailing list