From 7308b342633ce6b61ec9b33e06e630622058ebcf Mon Sep 17 00:00:00 2001 From: nsz Date: Wed, 27 Jul 2011 13:06:58 +0200 Subject: [PATCH] initial commit --- Makefile | 14 ++++++++++++ Makefile.conf.def | 5 +++++ Makefile.inc | 52 +++++++++++++++++++++++++++++++++++++++++++++ README | 31 +++++++++++++++++++++++++++ common/main.c | 36 +++++++++++++++++++++++++++++++ common/test.h | 19 +++++++++++++++++ src/env/Makefile | 1 + src/env/env.c | 45 +++++++++++++++++++++++++++++++++++++++ src/misc/Makefile | 1 + src/misc/basename.c | 25 ++++++++++++++++++++++ src/misc/dirname.c | 27 +++++++++++++++++++++++ src/stdio/Makefile | 1 + src/stdio/fdopen.c | 35 ++++++++++++++++++++++++++++++ 13 files changed, 292 insertions(+) create mode 100644 Makefile create mode 100644 Makefile.conf.def create mode 100644 Makefile.inc create mode 100644 README create mode 100644 common/main.c create mode 100644 common/test.h create mode 100644 src/env/Makefile create mode 100644 src/env/env.c create mode 100644 src/misc/Makefile create mode 100644 src/misc/basename.c create mode 100644 src/misc/dirname.c create mode 100644 src/stdio/Makefile create mode 100644 src/stdio/fdopen.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..856eb33 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +ROOTDIR=. +include Makefile.inc + + +# build binary in each test dir +DIRS = $(sort $(wildcard src/*)) + +local: + for i in $(DIRS); do make -C $$i; done +localrun: local + for i in $(DIRS); do $$i/t; done +localclean: + for i in $(DIRS); do make -C $$i clean; done +cleanall: clean localclean diff --git a/Makefile.conf.def b/Makefile.conf.def new file mode 100644 index 0000000..619adf5 --- /dev/null +++ b/Makefile.conf.def @@ -0,0 +1,5 @@ +# copy to Makefile.conf and edit +usemusl=yes +prefix = /usr/local/musl +includedir = $(prefix)/include +libdir = $(prefix)/lib diff --git a/Makefile.inc b/Makefile.inc new file mode 100644 index 0000000..bfdc3dc --- /dev/null +++ b/Makefile.inc @@ -0,0 +1,52 @@ +# gnu makefile +# when included in src/*/Makefile then it builds a binary locally +# when included in ./Makefile then all tests are linked into one binary + +ROOTDIR ?= ../.. +ifeq ($(ROOTDIR), .) +SRCS = $(sort $(wildcard src/*/*.c)) +else +SRCS = $(sort $(wildcard *.c)) +endif +OBJS = $(SRCS:.c=.o) + +usemusl = yes +prefix = /usr/local/musl +includedir = $(prefix)/include +libdir = $(prefix)/lib +-include $(ROOTDIR)/Makefile.conf + + +CFLAGS += -g -std=c99 -pipe -Wall +LDFLAGS += -g +INC += -I$(ROOTDIR)/common + +ifeq ($(usemusl), yes) +CC=gcc +LIBCC=$(shell gcc -print-file-name=libgcc.a |sed 's,/libgcc.a,,') +#LIBCC=$(shell pcc -v /dev/null 2>&1 |sed -n 's,/crtbegin.o.*,,;s,.* /,/,p') +CFLAGS += -nostdinc -ffreestanding -fno-stack-protector +LDFLAGS += -nostdlib -Wl,-e,_start,-Bstatic $(libdir)/crti.o $(libdir)/crt1.o $(libdir)/crtn.o -L $(libdir) -lc -L $(LIBCC) -l$(CC) +INC += -isystem $(includedir) +endif + +all: t + +clean: + rm -f $(OBJS) t main.o main.h + +.c.o: + $(CC) $(CFLAGS) $(INC) -c -o $@ $< + +$(OBJS): $(ROOTDIR)/common/test.h + +main.h: $(OBJS) + nm -f posix $+ |awk '/^test/ && $$2=="T"{print "T(" $$1 ")"}' >main.h + +main.o: $(ROOTDIR)/common/main.c $(ROOTDIR)/common/test.h main.h + $(CC) $(CFLAGS) $(INC) -I. -c -o $@ $< + +t: $(OBJS) main.o + $(CC) $+ $(LDFLAGS) -o $@ + +.PHONY: all clean diff --git a/README b/README new file mode 100644 index 0000000..635966d --- /dev/null +++ b/README @@ -0,0 +1,31 @@ +simple libc tests based on the libc-testsuit of dalias +see http://git.etalabs.net/cgi-bin/gitweb.cgi + +build tests: + cp Makefile.conf.def Makefile.conf + # edit Makefile.conf + make +run tests: + ./t + +about the framework: + +the only hook in the test framework is error(...) which +prints a formatted message and sets the test to failed +see common/test.h + +in the root dir make builds an executable with all tests +in a src/* dir make builds only local tests +see Makefile.inc + +a test function looks like + void test_foo() { + if (foo != 42) + error("foo=%d expected 42\n", foo); + } +extern functions with name ~ /^test/ are recognized to be +test functions +see Makefile.inc + +edit the generated main.h to exclude certain tests +see common/main.c diff --git a/common/main.c b/common/main.c new file mode 100644 index 0000000..4c28f71 --- /dev/null +++ b/common/main.c @@ -0,0 +1,36 @@ +#include "test.h" + +#define T(t) void t(); +#include "main.h" +#undef T + +struct test test__ = {0}; + +static int verbose; +static int count; +static int nfailed; + +static void run(const char *n, void (*f)()) { + count++; + test__.failed = 0; + test__.name = n; + if (verbose) + fprintf(stderr, "running %s:\n", test__.name); + f(); + if (test__.failed) { + nfailed++; + fprintf(stderr, "FAILED %s\n", test__.name); + } else if (verbose) + fprintf(stderr, "PASSED %s\n", test__.name); +} + +static int summary() { + fprintf(stderr, "PASS:%d FAIL:%d\n", count-nfailed, nfailed); + return !!nfailed; +} + +int main() { +#define T(t) run(#t, t); +#include "main.h" + return summary(); +} diff --git a/common/test.h b/common/test.h new file mode 100644 index 0000000..b7b22bd --- /dev/null +++ b/common/test.h @@ -0,0 +1,19 @@ +#include +#include + +extern struct test { + int failed; + const char *name; +} test__; + +#define error(...) error__(__FILE__, __LINE__, __VA_ARGS__) + +static void error__(const char *n, int l, const char *s, ...) { + va_list ap; + + test__.failed = 1; + fprintf(stderr, "- ERROR %s at %s:%d: ", test__.name, n, l); + va_start(ap, s); + vfprintf(stderr, s, ap); + va_end(ap); +} diff --git a/src/env/Makefile b/src/env/Makefile new file mode 100644 index 0000000..ee4552b --- /dev/null +++ b/src/env/Makefile @@ -0,0 +1 @@ +include ../../Makefile.inc diff --git a/src/env/env.c b/src/env/env.c new file mode 100644 index 0000000..f12672d --- /dev/null +++ b/src/env/env.c @@ -0,0 +1,45 @@ +#define _XOPEN_SOURCE 700 +#include "test.h" +#include +#include +#include +#include + +extern char **environ; +int clearenv(void); + +void test_env() { + char *s; + int r; + + if (clearenv() || (environ && *environ)) + error("clrearenv: %s\n", strerror(errno)); + if (putenv("TEST=1")) + error("putenv: %s\n", strerror(errno)); + if ((s=environ[1])) + error("environ[1]: %p, wanted 0\n", s); + if (!(s=getenv("TEST"))) + error("getenv(\"TEST\"): 0, wanted \"1\"\n"); + if (strcmp(s,"1") != 0) + error("getenv(\"TEST\"): \"%s\", wanted \"1\"\n", s); + if (unsetenv("TEST")) + error("unsetenv: %s\n", strerror(errno)); + if ((s=*environ)) + error("*environ: %p != 0\n", s); + if ((s=getenv("TEST"))) + error("getenv(\"TEST\"): %p, wanted 0\n", s); + if (setenv("TEST", "2", 0)) + error("setenv: %s\n", strerror(errno)); + if (strcmp(s=getenv("TEST"),"2") != 0) + error("getenv(\"TEST\"): \"%s\", wanted \"2\"\n", s); + if (setenv("TEST", "3", 0)) + error("setenv: %s\n", strerror(errno)); + if (strcmp(s=getenv("TEST"),"2") != 0) + error("getenv(\"TEST\"): \"%s\", wanted \"2\"\n", s); + if (setenv("TEST", "3", 1)) + error("setenv: %s\n", strerror(errno)); + if (strcmp(s=getenv("TEST"),"3") != 0) + error("getenv(\"TEST\"): \"%s\", wanted \"3\"\n", s); + if ((r=setenv("","",0)) != -1 || errno != EINVAL) + error("setenv(\"\",\"\"): %d, errno: %d (%s), wanted -1, %d (EINVAL)\n", r, errno, strerror(errno), EINVAL); +} diff --git a/src/misc/Makefile b/src/misc/Makefile new file mode 100644 index 0000000..ee4552b --- /dev/null +++ b/src/misc/Makefile @@ -0,0 +1 @@ +include ../../Makefile.inc diff --git a/src/misc/basename.c b/src/misc/basename.c new file mode 100644 index 0000000..016b397 --- /dev/null +++ b/src/misc/basename.c @@ -0,0 +1,25 @@ +#define _GNU_SOURCE +#include "test.h" +#include +#include +#include + +static void t(char *p, char *b) { + char *tmp = strdup(p); + char *s = basename(tmp); + + if (strcmp(b,s) != 0) + error("basename(\"%s\") returned \"%s\"; expected \"%s\"\n", p, s, b); + free(tmp); +} + +void test_basename() { + if (strcmp(".", basename(0)) != 0) + error("basename(0) returned \"%s\"; expected \".\"\n", basename(0)); + t("", "."); + t("/usr/lib", "lib"); + t("/usr/", "usr"); + t("/", "/"); + t("///", "/"); + t("//usr//lib//", "lib"); +} diff --git a/src/misc/dirname.c b/src/misc/dirname.c new file mode 100644 index 0000000..d77226a --- /dev/null +++ b/src/misc/dirname.c @@ -0,0 +1,27 @@ +#define _GNU_SOURCE +#include "test.h" +#include +#include +#include + +static void t(char *p, char *b) { + char *tmp = strdup(p); + char *s = dirname(tmp); + + if (strcmp(b,s) != 0) + error("dirname(\"%s\") returned \"%s\"; expected \"%s\"\n", p, s, b); + free(tmp); +} + +void test_dirname() { + if (strcmp(dirname(0), ".") != 0) + error("dirname(0) returned \"%s\"; expected \".\"\n", dirname(0)); + t("", "."); + t("/usr/lib", "/usr"); + t("/usr/", "/"); + t("usr", "."); + t("/", "/"); + t("///", "/"); + t(".", "."); + t("..", "."); +} diff --git a/src/stdio/Makefile b/src/stdio/Makefile new file mode 100644 index 0000000..ee4552b --- /dev/null +++ b/src/stdio/Makefile @@ -0,0 +1 @@ +include ../../Makefile.inc diff --git a/src/stdio/fdopen.c b/src/stdio/fdopen.c new file mode 100644 index 0000000..7e85165 --- /dev/null +++ b/src/stdio/fdopen.c @@ -0,0 +1,35 @@ +#define _XOPEN_SOURCE 700 +#include "test.h" +#include +#include +#include +#include +#include + +#define TEST(c) do { \ + errno = 0; \ + if (!(c)) \ + error("%s failed (errno = %d)\n", #c, errno); \ +} while(0) + +void test_fdopen(void) +{ + char tmp[] = "/tmp/testsuite-XXXXXX"; + char foo[6]; + int fd; + FILE *f; + + TEST((fd = mkstemp(tmp)) > 2); + TEST(write(fd, "hello", 6)==6); + TEST(f = fdopen(fd, "rb")); + if (f) { + TEST(ftello(f)==6); + TEST(fseeko(f, 0, SEEK_SET)==0); + TEST(fgets(foo, sizeof foo, f)); + if (strcmp(foo,"hello") != 0) + error("fgets read back wrong message: \"%s\" wanted: \"hello\"\n", foo); + fclose(f); + } + if (fd > 2) + TEST(unlink(tmp) != -1); +} -- 2.20.1