Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add musl-libc testsuite #298

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ COVERAGE_FILE:=$(COVERAGE_DIR)/libopenlibm.info
coverage: clean-coverage
mkdir $(COVERAGE_DIR)
$(MAKE) test CODE_COVERAGE=1
$(MAKE) -C test/musl CODE_COVERAGE=1
lcov -d amd64 -d bsdsrc -d ld80 -d src \
--rc lcov_branch_coverage=1 --capture --output-file $(COVERAGE_FILE)
genhtml --legend --branch-coverage \
Expand All @@ -104,6 +105,7 @@ clean: clean-coverage
rm -f libopenlibm.a libopenlibm.*$(SHLIB_EXT)*
rm -f ./*/*.gcno
$(MAKE) -C test clean
$(MAKE) -C test/musl clean

openlibm.pc: openlibm.pc.in Make.inc Makefile
echo "version=${VERSION}" > openlibm.pc
Expand Down
8 changes: 8 additions & 0 deletions test/musl/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*.err
*.o
*.so
*.a
*.exe
config.mak
REPORT
options.h
7 changes: 7 additions & 0 deletions test/musl/AUTHORS
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Rich Felker
Szabolcs Nagy
Kirill Ternovsky
John Spencer
Jens Gustedt
Alexander Monakov
Julien Ramseier
29 changes: 29 additions & 0 deletions test/musl/COPYRIGHT
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
libc-test is licensed under the following standard MIT license:

Copyright © 2005-2013 libc-test AUTHORS

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Portions of this software is derived from software authored by
third parties:

math tests use numbers under BSD and GPL licenses see src/math/ucb/*
and src/math/crlibm/* for details
154 changes: 154 additions & 0 deletions test/musl/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
B:=src
SRCS:=$(sort $(wildcard src/*/*.c))
OBJS:=$(SRCS:src/%.c=$(B)/%.o)
LOBJS:=$(SRCS:src/%.c=$(B)/%.lo)
DIRS:=$(patsubst src/%/,%,$(sort $(dir $(SRCS))))
BDIRS:=$(DIRS:%=$(B)/%)
NAMES:=$(SRCS:src/%.c=%)
CFLAGS:=-I$(B)/common -Isrc/common
LDLIBS:=$(B)/common/libtest.a
AR = $(CROSS_COMPILE)ar
RANLIB = $(CROSS_COMPILE)ranlib
RUN_TEST = $(RUN_WRAP) $(B)/common/runtest.exe -w '$(RUN_WRAP)'

all:
%.mk:
# turn off evil implicit rules
.SUFFIXES:
%: %.o
%: %.c
%: %.cc
%: %.C
%: %.cpp
%: %.p
%: %.f
%: %.F
%: %.r
%: %.s
%: %.S
%: %.mod
%: %.sh
%: %,v
%: RCS/%,v
%: RCS/%
%: s.%
%: SCCS/s.%

config.mak:
cp config.mak.def $@
-include config.mak

define default_template
$(1).BINS_TEMPL:=bin.exe bin-static.exe
$(1).NAMES:=$$(filter $(1)/%,$$(NAMES))
$(1).OBJS:=$$($(1).NAMES:%=$(B)/%.o)
endef
$(foreach d,$(DIRS),$(eval $(call default_template,$(d))))
common.BINS_TEMPL:=
api.BINS_TEMPL:=
math.BINS_TEMPL:=bin.exe

define template
D:=$$(patsubst %/,%,$$(dir $(1)))
N:=$(1)
$(1).BINS := $$($$(D).BINS_TEMPL:bin%=$(B)/$(1)%)
-include src/$(1).mk
#$$(warning D $$(D) N $$(N) B $$($(1).BINS))
$(B)/$(1).exe $(B)/$(1)-static.exe: $$($(1).OBJS)
$(B)/$(1).so: $$($(1).LOBJS)
# make sure dynamic and static binaries are not run parallel (matters for some tests eg ipc)
$(B)/$(1)-static.err: $(B)/$(1).err
endef
$(foreach n,$(NAMES),$(eval $(call template,$(n))))

BINS:=$(foreach n,$(NAMES),$($(n).BINS)) $(B)/api/main.exe
LIBS:=$(foreach n,$(NAMES),$($(n).LIBS)) $(B)/common/runtest.exe
ERRS:=$(BINS:%.exe=%.err)

debug:
@echo NAMES $(NAMES)
@echo BINS $(BINS)
@echo LIBS $(LIBS)
@echo ERRS $(ERRS)
@echo DIRS $(DIRS)

define target_template
$(1).ERRS:=$$(filter $(B)/$(1)/%,$$(ERRS))
$(B)/$(1)/all: $(B)/$(1)/REPORT
$(B)/$(1)/run: $(B)/$(1)/cleanerr $(B)/$(1)/REPORT
$(B)/$(1)/cleanerr:
rm -f $$(filter-out $(B)/$(1)/%-static.err,$$($(1).ERRS))
$(B)/$(1)/clean:
rm -f $$(filter $(B)/$(1)/%,$$(OBJS) $$(LOBJS) $$(BINS) $$(LIBS)) $(B)/$(1)/*.err
$(B)/$(1)/REPORT: $$($(1).ERRS)
cat $(B)/$(1)/*.err >$$@
run: $(B)/$(1)/run
$(B)/REPORT: $(B)/$(1)/REPORT
.PHONY: $(B)/$(1)/all $(B)/$(1)/clean
endef
$(foreach d,$(DIRS),$(eval $(call target_template,$(d))))

$(B)/common/libtest.a: $(common.OBJS)
rm -f $@
$(AR) rc $@ $^
$(RANLIB) $@

$(B)/common/all: $(B)/common/runtest.exe

$(ERRS): $(B)/common/runtest.exe | $(BDIRS)
$(BINS) $(LIBS): $(B)/common/libtest.a
$(OBJS): src/common/test.h | $(BDIRS)
$(BDIRS):
mkdir -p $@

$(B)/common/options.h: src/common/options.h.in
$(CC) -E - <$< | awk ' \
/optiongroups_unistd_end/ {s=1; next} \
!s || !NF || /^#/ {next} \
!a {a=$$1; if(NF==1)next} \
{print "#define "a" "$$NF; a=""}' >[email protected]
mv [email protected] $@

$(B)/common/mtest.o: src/common/mtest.h
$(math.OBJS): src/common/mtest.h

$(B)/api/main.exe: $(api.OBJS)
api/main.OBJS:=$(api.OBJS)
$(api.OBJS):$(B)/common/options.h
$(api.OBJS):CFLAGS+=-pedantic-errors -Werror -Wno-unused -D_XOPEN_SOURCE=700

all run: $(B)/REPORT
grep FAIL $< || echo PASS
clean:
rm -f $(OBJS) $(BINS) $(LIBS) $(B)/common/libtest.a $(B)/common/runtest.exe $(B)/common/options.h $(B)/*/*.err
cleanall: clean
rm -f $(B)/REPORT $(B)/*/REPORT
$(B)/REPORT:
cat $^ >$@

$(B)/%.o:: src/%.c
$(CC) $(CFLAGS) $($*.CFLAGS) -c -o $@ $< 2>[email protected] || echo BUILDERROR $@; cat [email protected]
$(B)/%.s:: src/%.c
$(CC) $(CFLAGS) $($*.CFLAGS) -S -o $@ $< || echo BUILDERROR $@; cat [email protected]
$(B)/%.lo:: src/%.c
$(CC) $(CFLAGS) $($*.CFLAGS) -fPIC -DSHARED -c -o $@ $< 2>[email protected] || echo BUILDERROR $@; cat [email protected]
$(B)/%.so: $(B)/%.lo
$(CC) -shared $(LDFLAGS) $($*.so.LDFLAGS) -o $@ $(sort $< $($*.so.LOBJS)) $(LDLIBS) $($*.so.LDLIBS) 2>[email protected] || echo BUILDERROR $@; cat [email protected]
$(B)/%-static.exe: $(B)/%.o
$(CC) -static $(LDFLAGS) $($*-static.LDFLAGS) -o $@ $(sort $< $($*-static.OBJS)) $(LDLIBS) $($*-static.LDLIBS) 2>[email protected] || echo BUILDERROR $@; cat [email protected]
$(B)/%.exe: $(B)/%.o
$(CC) $(LDFLAGS) $($*.LDFLAGS) -o $@ $(sort $< $($*.OBJS)) $(LDLIBS) $($*.LDLIBS) 2>[email protected] || echo BUILDERROR $@; cat [email protected]

%.o.err: %.o
touch $@
%.lo.err: %.lo
touch $@
%.so.err: %.so
touch $@
%.ld.err: %.exe
touch $@
%.err: %.exe
$(RUN_TEST) $< >$@ || true

.PHONY: all run clean cleanall

105 changes: 105 additions & 0 deletions test/musl/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
libc-test is developed as part of the musl project
http://www.musl-libc.org/

configuring:
cp config.mak.def config.mak
edit config.mak
build and run tests:
make
clean up:
make clean

make builds all test binaries and runs them to create
a REPORT file that contains all build and runtime errors
(this means that make does not stop at build failures)

contributing tests:

design goals:

- tests should be easy to run and build even a single test in isolation
(so test should be self contained if possible)
- failure of one test should not interfere with others
(build failure, crash or unexpected results are all failures)
- test output should point to the cause of the failure
- test results should be robust
- the test system should have minimal dependency
(libc, posix sh, gnu make)
- the test system should run on all archs and libcs
- tests should leave the system in a clean state

conventions:

each test is in a separate file at a path like src/directory/file.c with
its own main

the test should return 0 on success and non-0 on failure, on failure it
should print error messages to standard out if possible, on success no
message should be printed

to help with the above test protocol use t_error function for printing
errors and return t_status from main, see src/common/test.h
(t_error allows standard printf formatting, outputs at most 512bytes
in a single write call to fd 1, so there is no buffering, long outputs
are truncated, it sets the global t_status to 1)

it is common to do many similar checks in a test, in such cases macros
may be used to simplify the code like
#define T1(a,b) (check(a,b) || (t_error("check(%s,%s) failed\n", a, b),0))
#define T2(f,w) (result=(f), result==(w) || (t_error("%s failed: got %s, want %s\n", #f, result, w),0))

binaries should be possible to run from arbitrary directory.
the build system runs the tests using the src/common/runtest tool which
kills the test process after a timeout and reports the exit status
in case of failure

directories:

src/api: interface tests, build time include header tests
src/common: common utilities compiled into libtest.a
src/functional: functional tests aiming for large coverage of libc
src/math: tests for each math function with input-output test vectors
src/regression: regression tests aiming for testing particular bugs

initial set of functional tests are derived from the libc-testsuit of
Rich Felker, regression tests should contain reference of the bug
(musl commit hash, glibc bug tracker url, etc)

build system:

the main non-file make targets are all, run, clean and cleanall.
(cleanall removes the reports unlike clean, run reruns the dynamically
linked executables)

make variable can be overridden from config.mak or the make command line,
the variable B sets the build directory which is src by default

for each directory under src there are targets like $(B)/directory/all,
$(B)/directory/run and $(B)/directory/clean to make only the contents
of that directory, each directory has its own Makefile set up so it
invokes the top level make with B=src src/directory/foo for the foo
target, so it is possible to work only under a specific test directory

the build and runtime errors of each target are accumulated into a
target.err file and in the end they are concatenated into a REPORT

each .c file in src/functional and src/regression are built into a
dynamic linked and a static linked executable test binary by default,
this behaviour can be changed by a similarly named .mk file changing
make variables and specifying additional rules:

$(B)/$(N) is the name of the binary target (the file name without the .c)
$(B)/$(N)-static is the name of the static binary target
$(B)/$(D) is the build directory
$(N).CFLAGS are added to the CFLAGS at compilation
$(N).LDFLAGS are added to the LDFLAGS at linking
$(N).LDLIBS are added to the LDLIBS at linking
$(N).BINS are the targets (if empty no binaries are built)
$(N).LIBS are the non-executable targets (shared objects may use it)

if a binary is linked together from several .o files then they
have to be specified as prerequisits for the binary targets and
added to the $(N).LDLIBS as well

if a binary depends on a file at runtime (eg. a .so opened by dlopen)
then the $(N).err target should depend on that file
30 changes: 30 additions & 0 deletions test/musl/config.mak.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
CFLAGS += -pipe -std=c99 -D_POSIX_C_SOURCE=200809L -Wall -Wno-unused-function -Wno-missing-braces -Wno-unused -Wno-overflow
CFLAGS += -Wno-unknown-pragmas -fno-builtin -frounding-math
CFLAGS += -Werror=implicit-function-declaration -Werror=implicit-int -Werror=pointer-sign -Werror=pointer-arith
CFLAGS += -g
LDFLAGS += -g
# XXX: link libm later
LDLIBS += -lpthread -lrt

# glibc specific settings
# XXX: Not using the Glibc settings
# CFLAGS += -D_FILE_OFFSET_BITS=64
# LDLIBS += -lcrypt -ldl -lresolv -lutil -lpthread

# XXX: ---- OpenlibM settings
OPENLIBM_HOME=$(abspath ../..)
include $(OPENLIBM_HOME)/Make.inc

# Set rpath of tests to builddir for loading shared library
OPENLIBM_LIB = -L$(OPENLIBM_HOME) -lopenlibm
ifneq ($(OS),WINNT)
ifneq ($(OS),Darwin)
OPENLIBM_LIB += -Wl,-rpath=$(OPENLIBM_HOME)
endif
else # WINNT
CFLAGS_add += -DIMPORT_EXPORTS
endif

CFLAGS += $(CFLAGS_add)
LDFLAGS += $(LDFLAGS_add)
LDLIBS += $(OPENLIBM_LIB)
5 changes: 5 additions & 0 deletions test/musl/src/api/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
all:
%: FORCE
$(MAKE) -C ../.. B=src src/api/$@
.SUFFIXES:
FORCE: ;
Loading