From 0cbb7cf5ee17b2c32e2e217cfa0c7f40c7561475 Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Mon, 10 Mar 2014 13:08:06 -0500 Subject: [PATCH] add automated testing system This commit introduces a simple automated testing system with 3 simple testcase. For each test case there is a .c, a .patch, and a .inventory file. The .c is compiled, using the flags from the kflags file, to create the original object. The .c file is then patched with the .patch file and rebuilt to create the patched object. The files are then analyzed by the differencing tool and an output object is generated with a .inventory file that lists the sections and symbol included in the output object. That inventory file is then compared to the .inventory file for that testcase. If they are the same, the test passes. If not, the differences in the inventory files are displayed, and the test fails. Signed-off-by: Seth Jennings --- test/Makefile | 5 +++++ test/test01.c | 16 ++++++++++++++++ test/test01.inventory | 11 +++++++++++ test/test01.patch | 11 +++++++++++ test/test02.c | 22 ++++++++++++++++++++++ test/test02.inventory | 13 +++++++++++++ test/test02.patch | 10 ++++++++++ test/test03.c | 13 +++++++++++++ test/test03.inventory | 15 +++++++++++++++ test/test03.patch | 15 +++++++++++++++ test/testall.sh | 7 +++++++ test/testone.sh | 33 +++++++++++++++++++++++++++++++++ 12 files changed, 171 insertions(+) create mode 100644 test/Makefile create mode 100644 test/test01.c create mode 100644 test/test01.inventory create mode 100644 test/test01.patch create mode 100644 test/test02.c create mode 100644 test/test02.inventory create mode 100644 test/test02.patch create mode 100644 test/test03.c create mode 100644 test/test03.inventory create mode 100644 test/test03.patch create mode 100755 test/testall.sh create mode 100755 test/testone.sh diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..f890506 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,5 @@ +all: + ./testall.sh +clean: + rm -f output.o output.o.inventory reference.inventory test.inventory + diff --git a/test/test01.c b/test/test01.c new file mode 100644 index 0000000..b45be2f --- /dev/null +++ b/test/test01.c @@ -0,0 +1,16 @@ +#include + +void test_func() { + printf("this is before\n"); +} + +/* + * This test case ensures that deep inspection for rela entries + * that reference strings is taking place. The text and rela sections + * for test_func() are the same between the original and patched + * versions. However, the tool should detect that the string referenced + * by the printf has changed. + * + * Verification points: test_func bundle and the rodata.str1.8 section + * are included. + */ diff --git a/test/test01.inventory b/test/test01.inventory new file mode 100644 index 0000000..5fa4a73 --- /dev/null +++ b/test/test01.inventory @@ -0,0 +1,11 @@ +section .rodata.str1.1 +section .text.test_func +section .rela.text.test_func +section .shstrtab +section .symtab +section .strtab +symbol test01.c 4 0 +symbol .rodata.str1.1 3 0 +symbol .text.test_func 3 0 +symbol test_func 2 1 +symbol puts 0 1 diff --git a/test/test01.patch b/test/test01.patch new file mode 100644 index 0000000..cdec9ac --- /dev/null +++ b/test/test01.patch @@ -0,0 +1,11 @@ +--- test01.c.orig 2014-03-10 14:34:02.547250917 -0500 ++++ test01.c 2014-03-10 14:34:02.549250971 -0500 +@@ -1,7 +1,7 @@ + #include + + void test_func() { +- printf("this is before\n"); ++ printf("this is after\n"); + } + + /* diff --git a/test/test02.c b/test/test02.c new file mode 100644 index 0000000..e3ea0d0 --- /dev/null +++ b/test/test02.c @@ -0,0 +1,22 @@ +#include + +static int a = 1; + +void test_func() { + printf("%d\n",a); +} + +/* this is to ensure that a isn't optimized out by the compiler */ +void test_func2() { + a = 2; +} + +/* + * This test case ensures that static data structures, normally referenced + * by section in rela entries that reference them, are being converted to + * symbol references, so they can later be linked to the location of the + * data structure in the running kernel + * + * Verification points: test_func() bundle and 'a' symbol should be included. + * 'a' should have GLOBAL bind and NOTYPE type. + */ diff --git a/test/test02.inventory b/test/test02.inventory new file mode 100644 index 0000000..10d8641 --- /dev/null +++ b/test/test02.inventory @@ -0,0 +1,13 @@ +section .rodata.str1.1 +section .text.test_func +section .rela.text.test_func +section .shstrtab +section .symtab +section .strtab +symbol test02.c 4 0 +symbol .rodata.str1.1 3 0 +symbol .text.test_func 3 0 +symbol a 0 1 +symbol test_func 2 1 +symbol printf 0 1 +symbol puts 0 1 diff --git a/test/test02.patch b/test/test02.patch new file mode 100644 index 0000000..b7d5e08 --- /dev/null +++ b/test/test02.patch @@ -0,0 +1,10 @@ +--- test02.c.orig 2014-03-10 14:34:02.556251118 -0500 ++++ test02.c 2014-03-10 14:34:02.558251160 -0500 +@@ -4,6 +4,7 @@ + + void test_func() { + printf("%d\n",a); ++ printf("this is after\n"); + } + + /* this is to ensure that a isn't optimized out by the compiler */ diff --git a/test/test03.c b/test/test03.c new file mode 100644 index 0000000..118aee3 --- /dev/null +++ b/test/test03.c @@ -0,0 +1,13 @@ +#include + +void test_func() { + printf("this is before\n"); +} + +/* + * This test case introduces a new function called by an existing function + * and ensure that the bundle for that function is included. + * + * Verification points: bundles for test_func() and test_func2() should be + * included. + */ diff --git a/test/test03.inventory b/test/test03.inventory new file mode 100644 index 0000000..ef9d1d4 --- /dev/null +++ b/test/test03.inventory @@ -0,0 +1,15 @@ +section .rodata.str1.1 +section .text.test_func2 +section .rela.text.test_func2 +section .text.test_func +section .rela.text.test_func +section .shstrtab +section .symtab +section .strtab +symbol test03.c 4 0 +symbol .rodata.str1.1 3 0 +symbol .text.test_func2 3 0 +symbol test_func2 2 0 +symbol .text.test_func 3 0 +symbol puts 0 1 +symbol test_func 2 1 diff --git a/test/test03.patch b/test/test03.patch new file mode 100644 index 0000000..90359f1 --- /dev/null +++ b/test/test03.patch @@ -0,0 +1,15 @@ +--- test03.c.orig 2014-03-10 14:34:02.564251278 -0500 ++++ test03.c 2014-03-10 14:34:02.566251318 -0500 +@@ -1,7 +1,12 @@ + #include + ++static void test_func2() { ++ printf("this is after\n"); ++} ++ + void test_func() { + printf("this is before\n"); ++ test_func2(); + } + + /* diff --git a/test/testall.sh b/test/testall.sh new file mode 100755 index 0000000..0059cf0 --- /dev/null +++ b/test/testall.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +for i in *.c +do + TESTCASE=${i%.*} + ./testone.sh $TESTCASE +done diff --git a/test/testone.sh b/test/testone.sh new file mode 100755 index 0000000..8f9387f --- /dev/null +++ b/test/testone.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +if [[ $# -ne 1 ]] +then + echo "test.sh testcase" + exit 1 +fi + +TESTCASE=$1 +FLAGS="-fno-strict-aliasing -fno-common -fno-delete-null-pointer-checks -O2 -m64 -mpreferred-stack-boundary=4 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -fno-asynchronous-unwind-tables -fno-stack-protector -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-strict-overflow -fconserve-stack -ffunction-sections -fdata-sections -fno-inline" +CFLAGS="$FLAGS" make $TESTCASE.o > /dev/null 2>&1 || exit 1 +mv -f $TESTCASE.o $TESTCASE.o.orig +patch $TESTCASE.c $TESTCASE.patch > /dev/null 2>&1 || exit 1 +CFLAGS="$FLAGS" make $TESTCASE.o > /dev/null 2>&1 || exit 1 +if [[ ! -e ../kpatch-build/create-diff-object ]] +then + make -C ../kpatch-build create-diff-object || exit 1 +fi +../kpatch-build/create-diff-object -i $TESTCASE.o.orig $TESTCASE.o output.o > /dev/null 2>&1 || exit 1 +rm -f $TESTCASE.o $TESTCASE.o.orig > /dev/null 2>&1 +patch -R $TESTCASE.c $TESTCASE.patch > /dev/null 2>&1 || echo "warning: unable to unpatch file $TESTCASE.c" + +sort $TESTCASE.inventory > reference.inventory +sort output.o.inventory > test.inventory +rm -f output.o.inventory > /dev/null 2>&1 +diff reference.inventory test.inventory +if [[ $? -ne 0 ]] +then + echo "$TESTCASE failed" && exit 1 +else + echo "$TESTCASE passed" +fi +rm -f reference.inventory test.inventory output.o