From bdf159de2f085bbd45e278470544698063337adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Koz=C5=82owski?= Date: Fri, 27 Sep 2024 10:58:30 +0200 Subject: [PATCH] Implement initial test framework This should make testing across multiple platforms easier. --- Makefile | 17 ++++++++++--- tests/Makefile | 25 +++++++++++++++++++ tests/run.sh | 46 ++++++++++++++++++++++++++++++++++ tests/test-malloc.c | 61 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 tests/Makefile create mode 100755 tests/run.sh create mode 100644 tests/test-malloc.c diff --git a/Makefile b/Makefile index b00793a..8070cb4 100644 --- a/Makefile +++ b/Makefile @@ -166,13 +166,16 @@ $(B)/libencrypt.so: libencrypt.c @size $@ +tests: $(B)/memcr + $(MAKE) -C tests CC=$(CC) MEMCR=../$< + + clean: rm -f $(B)/*.o $(B)/*.s $(B)/*.bin $(B)/parasite-blob.h $(B)/memcr $(B)/memcr-client $(B)/libencrypt.so + $(MAKE) -C tests clean + help: - @echo 'Clean target:' - @echo ' clean - remove generated files' - @echo '' @echo 'Build targets:' @echo ' all - build all targets' @echo ' memcr - build memcr binary' @@ -181,5 +184,11 @@ help: @echo ' COMPRESS_LZ4=1 - compile in support for memory dump LZ4 compression' @echo ' CHECKSUM_MD5=1 - compile in support for memory dump MD5 checksumming' @echo ' ENCRYPT=1 - compile libencrypt.so that can be preloaded for memcr' + @echo '' + @echo 'Test targets:' + @echo ' tests - build and run memcr tests' + @echo '' + @echo 'Clean targets:' + @echo ' clean - remove generated files' -.PHONY: all clean help +.PHONY: all tests clean help diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..cb8175b --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,25 @@ +MAKEFLAGS += -rR + +ifeq ("$(origin CC)", "default") + undefine CC +endif + +CC ?= $(CROSS_COMPILE)gcc + +CFLAGS = -Wall -Werror -g -O2 + +SRC = $(wildcard *.c) +BIN = $(SRC:%.c=%) + +MEMCR ?= ../memcr + +all: $(BIN) + @./run.sh $(MEMCR) + +$(BIN): %: %.c Makefile + $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS) + +clean: + rm -f $(BIN) + +.PHONY: all clean diff --git a/tests/run.sh b/tests/run.sh new file mode 100755 index 0000000..bf46dcf --- /dev/null +++ b/tests/run.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +#set -x + +# $1 should point to memcr executable +[ -n "$1" ] || exit 1 +[ -x "$1" ] || exit 2 + +MEMCR=$1 + +CUID=$(id -u) +if [ "$CUID" != "0" ]; then + DO="sudo" +else + DO="" +fi + +TESTS="test-malloc" + +for TEST in $TESTS; do + echo "######## running $TEST ########" + + # start the test + ./$TEST & + + # wait + sleep 0.2 + + # memcr + $DO $MEMCR -p $! -n -f + if [ $? -ne 0 ]; then + kill $! + echo "[-] $TEST failed" + break + fi + + # stop the test + kill -USR1 $! + wait $! + if [ $? -eq 0 ]; then + echo "[+] $TEST passed" + else + echo "[-] $TEST failed" + break + fi +done diff --git a/tests/test-malloc.c b/tests/test-malloc.c new file mode 100644 index 0000000..a3773d3 --- /dev/null +++ b/tests/test-malloc.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PFX "[test-malloc] " + +#define TEST_SIZE (16 * 1024 * 1024) /* 16 MB */ + +static volatile sig_atomic_t signalled; + +static char mema[TEST_SIZE]; + +static void sighandler(int num) +{ + signalled = num; +} + +int main(int argc, char *argv[]) +{ + int ret; + void *memb; + + signal(SIGUSR1, sighandler); + + printf(PFX "pid %d\n", getpid()); + + memset(mema, 0x5b, sizeof(mema)); + + memb = malloc(TEST_SIZE); + assert(memb); + + memset(mema, 0x5b, sizeof(mema)); + memcpy(memb, mema, sizeof(mema)); + + ret = memcmp(mema, memb, sizeof(mema)); + assert(ret == 0); + + printf(PFX "mema %d kB @ %p\n", TEST_SIZE / 1024, mema); + printf(PFX "memb %d kB @ %p\n", TEST_SIZE / 1024, memb); + + printf(PFX "waiting for SIGUSR1\n"); + + while (!signalled) + usleep(10 * 1000); + + printf(PFX "signalled (%s)\n", strsignal(signalled)); + + ret = memcmp(mema, memb, sizeof(mema)); + assert(ret == 0); + + printf(PFX "ok\n"); + + free(memb); + return 0; +} \ No newline at end of file