From 01809dfb1f59cc494994082e259fcadff60830d7 Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Tue, 20 Jan 2015 18:08:23 +1100 Subject: Add some skiboot snprintf test cases Initial implementation and support for more libc test cases Signed-off-by: Stewart Smith --- libc/test/Makefile.check | 40 +++++++++-- libc/test/run-snprintf-test.c | 55 ++++++++++++++++ libc/test/run-snprintf.c | 150 ++++++++++++++++++++++++++++++++++++++++++ libc/test/run-time.c | 2 +- 4 files changed, 242 insertions(+), 5 deletions(-) create mode 100644 libc/test/run-snprintf-test.c create mode 100644 libc/test/run-snprintf.c diff --git a/libc/test/Makefile.check b/libc/test/Makefile.check index d4efaf3..6247e30 100644 --- a/libc/test/Makefile.check +++ b/libc/test/Makefile.check @@ -1,23 +1,53 @@ # -*-Makefile-*- LIBC_TEST := libc/test/run-time -LCOV_EXCLUDE += $(LIBC_TEST:%=%.c) +# We have some tricky tests that have system libc and skiboot libc, +# so that we can test parts of skiboot libc but in userspace. -check: $(LIBC_TEST:%=%-check) +LIBC_DUALLIB_TEST := libc/test/run-snprintf -coverage: $(LIBC_TEST:%=%-gcov-run) +LCOV_EXCLUDE += $(LIBC_TEST:%=%.c) $(LIBC_DUALLIB_TEST:%=%.c) $(LIBC_DUALLIB_TEST:%=%-test.c) + +check: $(LIBC_TEST:%=%-check) $(LIBC_DUALLIB_TEST:%=%-check) + +coverage: $(LIBC_TEST:%=%-gcov-run) $(LIBC_DUALLIB_TEST:%=%-gcov-run) $(LIBC_TEST:%=%-gcov-run) : %-run: % $(call Q, TEST-COVERAGE ,$< , $<) +$(LIBC_DUALLIB_TEST:%=%-gcov-run) : %-run: % + $(eval LCOV_DIRS += -d $(dir $<) ) + $(call Q, TEST-COVERAGE , (cd $(dir $<); GCOV_PREFIX_STRIP=`(c=0; while [ "\`pwd\`" != '/' ]; do cd ..; c=\`expr 1 + $$c\`; done; echo $$c)` ./$(notdir $<) ), $< ) + $(LIBC_TEST:%=%-check) : %-check: % $(call Q, RUN-TEST ,$(VALGRIND) $<, $<) +$(LIBC_DUALLIB_TEST:%=%-check) : %-check: % + $(call Q, RUN-TEST ,$(VALGRIND) $<, $<) + $(LIBC_TEST) : % : %.c $(call Q, HOSTCC ,$(HOSTCC) $(HOSTCFLAGS) -O0 -g -I include -I . -I libfdt -I libc/include -o $@ $<, $<) $(LIBC_TEST:%=%-gcov): %-gcov : %.c % - $(call Q, HOSTCC ,$(HOSTCC) $(HOSTCFLAGS) -fprofile-arcs -ftest-coverage -lgcov -O0 -g -I include -I . -I libfdt -I libc/include -o $@ $<, $<) + $(call Q, HOSTCC ,(cd $(dir $<); $(HOSTCC) $(HOSTCFLAGS) -fprofile-arcs -ftest-coverage -lgcov -O0 -g -I$(shell pwd)/include -I$(shell pwd) -I$(shell pwd)/libfdt -I$(shell pwd)/libc/include -o $(notdir $@) $(notdir $<)), $<) + +$(LIBC_DUALLIB_TEST) : % : %.o %-test.o + $(call Q, HOSTCC ,$(HOSTCC) $(HOSTCFLAGS) -O0 -g -I include -I . -I libfdt -o $@ $@-test.o $<, $<) + +$(LIBC_DUALLIB_TEST:%=%-gcov) : %-gcov : %-gcov.o %-gcov-test.o + $(call Q, HOSTCC ,(cd $(dir $<); $(HOSTCC) $(HOSTCFLAGS) -fprofile-arcs -ftest-coverage -lgcov -O0 -pg -g -I$(shell pwd)/include -I$(shell pwd)/. -I$(shell pwd)/libfdt -o $(notdir $@) $(notdir $@)-test.o $(notdir $<)), $<) + +$(LIBC_DUALLIB_TEST:%=%-test.o): %-test.o : %-test.c + $(call Q, HOSTCC ,$(HOSTCC) $(HOSTCFLAGS) -O0 -g -I include -I . -I libfdt -I libc/include -ffreestanding -o $@ -c $<, $<) + +$(LIBC_DUALLIB_TEST:%=%.o): %.o : %.c + $(call Q, HOSTCC ,$(HOSTCC) $(HOSTCFLAGS) -O0 -g -o $@ -c $<, $<) + +$(LIBC_DUALLIB_TEST:%=%-gcov.o): %-gcov.o : %.c + $(call Q, HOSTCC ,(cd $(dir $<); $(HOSTCC) $(HOSTCFLAGS) -fprofile-arcs -ftest-coverage -lgcov -pg -O0 -g -o $(notdir $@) -c $(notdir $<)), $<) + +$(LIBC_DUALLIB_TEST:%=%-gcov-test.o): %-gcov-test.o : %-test.c % + $(call Q, HOSTCC ,(cd $(dir $<); $(HOSTCC) $(HOSTCFLAGS) -fprofile-arcs -ftest-coverage -lgcov -pg -O0 -g -I$(shell pwd)/include -I$(shell pwd)/. -I$(shell pwd)/libfdt -I$(shell pwd)/libc/include -ffreestanding -o $(notdir $@) -c $(notdir $<) ), $<) -include $(wildcard libc/test/*.d) @@ -25,3 +55,5 @@ clean: libc-test-clean libc-test-clean: $(RM) -f libc/test/*.[od] $(LIBC_TEST) $(LIBC_TEST:%=%-gcov) + $(RM) -f $(LIBC_DUALLIB_TEST) $(LIBC_DUALLIB_TEST:%=%-gcov) \ + $(LIBC_DUALLIB_TEST:%=%-test.o) diff --git a/libc/test/run-snprintf-test.c b/libc/test/run-snprintf-test.c new file mode 100644 index 0000000..b75d887 --- /dev/null +++ b/libc/test/run-snprintf-test.c @@ -0,0 +1,55 @@ +/* Copyright 2013-2015 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file is run with the skiboot libc files rather than system libc. + * This means we have a bit of "fun" with actually executing the tests on + * the host. + * Patches to make this less ugly are very welcome. + */ + +#include +#include + +#include "../stdio/snprintf.c" +#include "../stdio/vsnprintf.c" + +int test1(void); + +int test1(void) +{ + return snprintf(NULL, 1, "Hello"); +} + +int skiboot_snprintf(char *buf, size_t bufsz, size_t l, const char* format, ...); + +int skiboot_snprintf(char *buf, size_t bufsz, size_t l, const char* format, ...) +{ + va_list ar; + int count; + + if (buf) + memset(buf, 0, bufsz); + + if ((buf==NULL) || (format==NULL)) + return(-1); + + va_start(ar, format); + count = vsnprintf(buf, l, format, ar); + va_end(ar); + + return(count); +} diff --git a/libc/test/run-snprintf.c b/libc/test/run-snprintf.c new file mode 100644 index 0000000..7087a90 --- /dev/null +++ b/libc/test/run-snprintf.c @@ -0,0 +1,150 @@ +/* Copyright 2013-2015 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define BUFSZ 50 + +#include +#include +#include +#include + +int test1(void); +int skiboot_snprintf(char *buf, size_t bufsz, size_t l, const char* format, ...); + +static void test_printf_d(int n) +{ + char *buf, *buf2; + int blen; + int r; + int i; + + for(i=1; i<10; i++) + { + blen = i+1; + if (n<0) + blen++; + + buf = (char*)malloc(blen); + buf2 = (char*)malloc(blen); + r = skiboot_snprintf(buf, blen, blen, "%d", n); + snprintf(buf2, blen, "%d", n); + n = n * 10; + if (n<0) + assert(i+1 == r); + else + assert(i == r); + assert(0 == strncmp(buf, buf2, blen)); + free(buf); + free(buf2); + } +} + +static void test_printf_x(const char* f) +{ + char *buf, *buf2; + int blen; + int i, r, n=0x1; + + for (i=0; i<8; i++) + { + blen = i+2; + buf = (char*)malloc(blen); + buf2 = (char*)malloc(blen); + r = skiboot_snprintf(buf, blen, blen, f, n); + snprintf(buf2, blen, f, n); + assert(i+1 == r); + assert(0 == strncmp(buf, buf2, blen)); + free(buf); + free(buf2); + n = n << 4; + } +} + +static void test_printf_c(void) +{ + char *buf= (char*)malloc(2); + char buf2[2]; + unsigned char i= 0xff; + int r; + while(i) + { + r = skiboot_snprintf(buf, 2, 2, "%c", i); + snprintf(buf2, 2, "%c", i); + assert(r==1); + assert(0 == strncmp(buf, buf2, 2)); + i--; + } + free(buf); +} + +int main(void) +{ + char *buf; + int r; + + buf = (char*)malloc(BUFSZ); + memset(buf, 0, BUFSZ); + + assert(-1 == test1()); + + r = skiboot_snprintf(buf, BUFSZ, 2, "%%"); + assert(r==1); + assert(buf[0] == '%' && buf[1] == 0); + + r = skiboot_snprintf(buf, BUFSZ, 2, "%d", 137); + /* BUG/FIXME: + * skiboot libc does NOT return the length of the buffer you'd need + * Instead, it'll return something random, possibly zero (as here) + * but as you'll see in test_in_buf_len2, sometimes not. + * + * Basically, we're not POSIX printf and this is some day going to + * cause things to be awful. + */ + assert(0 == r); // BUG, should be 3 + assert(0 == strncmp(buf, "", 3)); + + r = skiboot_snprintf(buf, BUFSZ, 4, "%d", 137); + assert(3 == r); + assert(0 == strncmp(buf, "137", 3)); + assert(buf[3] == 0); + + /* Now we test the strange behaviour of our printf. + * For strings, we get partial prints going, but if we whack an + * integer on the end, we may or may not get that integer, depending + * on if we have enough size. We should test that though */ + + r = skiboot_snprintf(buf, BUFSZ, 4, "Hello %d", 137); + assert(3 == r); + assert(0 == strncmp(buf, "Hel", 3)); + assert(buf[3] == 0); + r = skiboot_snprintf(buf, BUFSZ, 7, "Hello %d", 137); + assert(6 == r); + assert(0 == strncmp(buf, "Hello ", 6)); + assert(buf[6] == 0); + r = skiboot_snprintf(buf, BUFSZ, 10, "Hello %d", 137); + assert(9 == r); + assert(0 == strncmp(buf, "Hello 137", 10)); + assert(buf[9] == 0); + free(buf); + + test_printf_d(1); + test_printf_d(-1); + test_printf_x("%x"); + test_printf_x("%X"); + test_printf_c(); + + return 0; +} diff --git a/libc/test/run-time.c b/libc/test/run-time.c index 0f377b5..aae7f4f 100644 --- a/libc/test/run-time.c +++ b/libc/test/run-time.c @@ -1,6 +1,6 @@ #include "/usr/include/assert.h" #include -#include +#include #include #include "../time.c" -- cgit v1.1