diff options
author | EuAndreh <eu@euandre.org> | 2024-10-19 18:11:33 -0300 |
---|---|---|
committer | EuAndreh <eu@euandre.org> | 2024-10-20 03:27:09 -0300 |
commit | 149d33fa6adb9be835d1c1404346d82124dda454 (patch) | |
tree | d9c12a2d10ef32098cfb4485801446501797d0c4 | |
parent | src/guuid.go: Remove NewBytes() (diff) | |
download | uuid-149d33fa6adb9be835d1c1404346d82124dda454.tar.gz uuid-149d33fa6adb9be835d1c1404346d82124dda454.tar.xz |
Setup conventional functional tests, fuzz targets and benchmarks
-rw-r--r-- | .gitignore | 10 | ||||
-rw-r--r-- | Makefile | 81 | ||||
-rw-r--r-- | deps.mk | 61 | ||||
-rwxr-xr-x | mkdeps.sh | 25 | ||||
-rw-r--r-- | tests/benchmarks/string-roundtrip/guuid.go | 37 | ||||
l--------- | tests/benchmarks/string-roundtrip/main.go | 1 | ||||
-rw-r--r-- | tests/functional/string-round-trip/guuid.go | 62 | ||||
l--------- | tests/functional/string-round-trip/main.go | 1 | ||||
-rw-r--r-- | tests/fuzz/from-string/guuid.go | 30 | ||||
l--------- | tests/fuzz/from-string/main.go | 1 | ||||
-rw-r--r-- | tests/fuzz/new-from/guuid.go | 31 | ||||
l--------- | tests/fuzz/new-from/main.go | 1 | ||||
-rw-r--r-- | tests/libbuild.go | 11 |
13 files changed, 310 insertions, 42 deletions
@@ -1,4 +1,14 @@ /src/version.go +/*.bin /src/*.a +/src/*.bin /tests/*.a /tests/*.bin +/tests/functional/*/*.a +/tests/functional/*/*.bin +/tests/fuzz/*/*.a +/tests/fuzz/*/*.bin +/tests/benchmarks/*/*.a +/tests/benchmarks/*/*.bin +/tests/benchmarks/*/*.txt +/tests/fuzz/corpus/ @@ -17,7 +17,7 @@ MANDIR = $(SHAREDIR)/man EXEC = ./ ## Where to store the installation. Empty by default. DESTDIR = -LDLIBS = +LDLIBS = --static GOCFLAGS = -I $(GOLIBDIR) GOLDFLAGS = -L $(GOLIBDIR) @@ -26,17 +26,26 @@ GOLDFLAGS = -L $(GOLIBDIR) .SUFFIXES: .SUFFIXES: .go .a .bin .bin-check +.go.a: + go tool compile $(GOCFLAGS) -I $(@D) -o $@ -p $(*F) \ + `find $< $$(if [ $(*F) != main ]; then \ + echo src/$(NAME).go src/version.go; fi) | uniq` + +.a.bin: + go tool link $(GOLDFLAGS) -L $(@D) -o $@ --extldflags '$(LDLIBS)' $< + all: include deps.mk -objects = \ - src/$(NAME).a \ - tests/$(NAME).a \ - tests/main.a \ - tests/libbuild.a \ +libs.a = $(libs.go:.go=.a) +mains.a = $(mains.go:.go=.a) +mains.bin = $(mains.go:.go=.bin) +functional-tests/lib.a = $(functional-tests/lib.go:.go=.a) +fuzz-targets/lib.a = $(fuzz-targets/lib.go:.go=.a) +benchmarks/lib.a = $(benchmarks/lib.go:.go=.a) sources = \ src/$(NAME).go \ @@ -45,11 +54,13 @@ sources = \ derived-assets = \ src/version.go \ - $(objects) \ - tests/main.bin \ - tests/libbuild.bin \ + $(libs.a) \ + $(mains.a) \ + $(mains.bin) \ side-assets = \ + tests/fuzz/corpus/ \ + tests/benchmarks/*/main.txt \ @@ -58,26 +69,13 @@ side-assets = \ all: $(derived-assets) -$(objects): Makefile - -src/$(NAME).a: src/$(NAME).go src/version.go - go tool compile $(GOCFLAGS) -o $@ -p $(*F) -I $(@D) $*.go src/version.go - -tests/main.a: tests/main.go tests/$(NAME).a -tests/main.a: - go tool compile $(GOCFLAGS) -o $@ -p $(*F) -I $(@D) $*.go +$(libs.a): Makefile deps.mk +$(libs.a): src/$(NAME).go src/version.go -tests/libbuild.a: tests/libbuild.go src/$(NAME).a - go tool compile $(GOCFLAGS) -o $@ -p main -I src $*.go -tests/$(NAME).a: tests/$(NAME).go src/$(NAME).go src/version.go - go tool compile $(GOCFLAGS) -o $@ -p $(*F) $*.go src/$(*F).go src/version.go - -tests/libbuild.bin: tests/libbuild.a - go tool link $(GOLDFLAGS) -o $@ -L src $*.a - -tests/main.bin: tests/main.a - go tool link $(GOLDFLAGS) -o $@ -L $(@D) --extldflags '$(LDLIBS)' $*.a +$(fuzz-targets/lib.a): + go tool compile $(GOCFLAGS) -o $@ -p $(NAME) -d=libfuzzer \ + $*.go src/$(NAME).go src/version.go src/version.go: Makefile echo 'package $(NAME); const Version = "$(VERSION)"' > $@ @@ -85,11 +83,9 @@ src/version.go: Makefile tests.bin-check = \ - tests/main.bin-check \ - tests/libbuild.bin-check \ + tests/main.bin-check \ + $(functional-tests/main.go:.go=.bin-check) \ -tests/main.bin-check: tests/main.bin -tests/libbuild.bin-check: tests/libbuild.bin $(tests.bin-check): $(EXEC)$*.bin @@ -104,6 +100,7 @@ $(integration-tests): ALWAYS sh $@ check-integration: $(integration-tests) +check-integration: fuzz ## Run all tests. Each test suite is isolated, so that a parallel @@ -113,6 +110,27 @@ check: check-unit check-integration +FUZZSEC=1 +fuzz-targets/main.bin-check = $(fuzz-targets/main.go:.go=.bin-check) +$(fuzz-targets/main.bin-check): + $(EXEC)$*.bin --test.fuzztime=$(FUZZSEC)s \ + --test.fuzz='.*' --test.fuzzcachedir=tests/fuzz/corpus + +fuzz: $(fuzz-targets/main.bin-check) + + + +benchmarks/main.bin-check = $(benchmarks/main.go:.go=.bin-check) +$(benchmarks/main.bin-check): + rm -f $*.txt + printf '%s\n' '$(EXEC)$*.bin' >> $*.txt + LANG=POSIX.UTF-8 time -p $(EXEC)$*.bin 2>> $*.txt + printf '%s\n' '$*.txt' + +bench: $(benchmarks/main.bin-check) + + + ## Remove *all* derived artifacts produced during the build. ## A dedicated test asserts that this is always true. clean: @@ -138,4 +156,5 @@ uninstall: '$(DESTDIR)$(SRCDIR)' \ + ALWAYS: @@ -0,0 +1,61 @@ +libs.go = \ + src/guuid.go \ + tests/benchmarks/string-roundtrip/guuid.go \ + tests/functional/string-round-trip/guuid.go \ + tests/fuzz/from-string/guuid.go \ + tests/fuzz/new-from/guuid.go \ + tests/guuid.go \ + +mains.go = \ + tests/benchmarks/string-roundtrip/main.go \ + tests/functional/string-round-trip/main.go \ + tests/fuzz/from-string/main.go \ + tests/fuzz/new-from/main.go \ + tests/main.go \ + +functional-tests/lib.go = \ + tests/functional/string-round-trip/guuid.go \ + +functional-tests/main.go = \ + tests/functional/string-round-trip/main.go \ + +fuzz-targets/lib.go = \ + tests/fuzz/from-string/guuid.go \ + tests/fuzz/new-from/guuid.go \ + +fuzz-targets/main.go = \ + tests/fuzz/from-string/main.go \ + tests/fuzz/new-from/main.go \ + +benchmarks/lib.go = \ + tests/benchmarks/string-roundtrip/guuid.go \ + +benchmarks/main.go = \ + tests/benchmarks/string-roundtrip/main.go \ + +src/guuid.a: src/guuid.go +tests/benchmarks/string-roundtrip/guuid.a: tests/benchmarks/string-roundtrip/guuid.go +tests/benchmarks/string-roundtrip/main.a: tests/benchmarks/string-roundtrip/main.go +tests/functional/string-round-trip/guuid.a: tests/functional/string-round-trip/guuid.go +tests/functional/string-round-trip/main.a: tests/functional/string-round-trip/main.go +tests/fuzz/from-string/guuid.a: tests/fuzz/from-string/guuid.go +tests/fuzz/from-string/main.a: tests/fuzz/from-string/main.go +tests/fuzz/new-from/guuid.a: tests/fuzz/new-from/guuid.go +tests/fuzz/new-from/main.a: tests/fuzz/new-from/main.go +tests/guuid.a: tests/guuid.go +tests/main.a: tests/main.go +tests/benchmarks/string-roundtrip/main.bin: tests/benchmarks/string-roundtrip/main.a +tests/functional/string-round-trip/main.bin: tests/functional/string-round-trip/main.a +tests/fuzz/from-string/main.bin: tests/fuzz/from-string/main.a +tests/fuzz/new-from/main.bin: tests/fuzz/new-from/main.a +tests/main.bin: tests/main.a +tests/benchmarks/string-roundtrip/main.bin-check: tests/benchmarks/string-roundtrip/main.bin +tests/functional/string-round-trip/main.bin-check: tests/functional/string-round-trip/main.bin +tests/fuzz/from-string/main.bin-check: tests/fuzz/from-string/main.bin +tests/fuzz/new-from/main.bin-check: tests/fuzz/new-from/main.bin +tests/main.bin-check: tests/main.bin +tests/benchmarks/string-roundtrip/main.a: tests/benchmarks/string-roundtrip/$(NAME).a +tests/functional/string-round-trip/main.a: tests/functional/string-round-trip/$(NAME).a +tests/fuzz/from-string/main.a: tests/fuzz/from-string/$(NAME).a +tests/fuzz/new-from/main.a: tests/fuzz/new-from/$(NAME).a +tests/main.a: tests/$(NAME).a @@ -2,3 +2,28 @@ set -eu export LANG=POSIX.UTF-8 + + +libs() { + find src tests -name '*.go' | grep -v '/main\.go$' | + grep -v '/version\.go$' +} + +mains() { + find src tests -name '*.go' | grep '/main\.go$' +} + +libs | varlist 'libs.go' +mains | varlist 'mains.go' + +find tests/functional/*/*.go -not -name main.go | varlist 'functional-tests/lib.go' +find tests/functional/*/main.go | varlist 'functional-tests/main.go' +find tests/fuzz/*/*.go -not -name main.go | varlist 'fuzz-targets/lib.go' +find tests/fuzz/*/main.go | varlist 'fuzz-targets/main.go' +find tests/benchmarks/*/*.go -not -name main.go | varlist 'benchmarks/lib.go' +find tests/benchmarks/*/main.go | varlist 'benchmarks/main.go' + +{ libs; mains; } | sort | sed 's/^\(.*\)\.go$/\1.a:\t\1.go/' +mains | sort | sed 's/^\(.*\)\.go$/\1.bin:\t\1.a/' +mains | sort | sed 's/^\(.*\)\.go$/\1.bin-check:\t\1.bin/' +mains | sort | sed 's|^\(.*\)/main\.go$|\1/main.a:\t\1/$(NAME).a|' diff --git a/tests/benchmarks/string-roundtrip/guuid.go b/tests/benchmarks/string-roundtrip/guuid.go new file mode 100644 index 0000000..9fef55c --- /dev/null +++ b/tests/benchmarks/string-roundtrip/guuid.go @@ -0,0 +1,37 @@ +package guuid + +import ( + "flag" + "fmt" +) + + + +var nFlag = flag.Int( + "n", + 10_000_000, + "The number of iterations to execute", +) + +func MainTest() { + flag.Parse() + n := *nFlag + + uuid := New() + + for i := 0; i < n; i++ { + derived, err := FromString(uuid.String()) + if err != nil { + panic(err) + } + + eq := uuid == derived + if !eq { + panic(fmt.Sprintf( + "bad round trip: orig (%#v); derived (%#v)", + uuid, + derived, + )) + } + } +} diff --git a/tests/benchmarks/string-roundtrip/main.go b/tests/benchmarks/string-roundtrip/main.go new file mode 120000 index 0000000..f67563d --- /dev/null +++ b/tests/benchmarks/string-roundtrip/main.go @@ -0,0 +1 @@ +../../main.go
\ No newline at end of file diff --git a/tests/functional/string-round-trip/guuid.go b/tests/functional/string-round-trip/guuid.go new file mode 100644 index 0000000..764576e --- /dev/null +++ b/tests/functional/string-round-trip/guuid.go @@ -0,0 +1,62 @@ +package guuid + +import ( + "fmt" + "os" + "reflect" +) + + + +func showColour() bool { + return os.Getenv("NO_COLOUR") == "" +} + +func testing(message string, body func()) { + if showColour() { + fmt.Fprintf( + os.Stderr, + "\033[0;33mtesting\033[0m: %s... ", + message, + ) + body() + fmt.Fprintf(os.Stderr, "\033[0;32mOK\033[0m.\n") + } else { + fmt.Fprintf(os.Stderr, "testing: %s... ", message) + body() + fmt.Fprintf(os.Stderr, "OK.\n") + } +} + +func assertEq(given any, expected any) { + if !reflect.DeepEqual(given, expected) { + if showColour() { + fmt.Fprintf(os.Stderr, "\033[0;31mERR\033[0m.\n") + } else { + fmt.Fprintf(os.Stderr, "ERR.\n") + } + fmt.Fprintf(os.Stderr, "given != expected\n") + fmt.Fprintf(os.Stderr, "given: %#v\n", given) + fmt.Fprintf(os.Stderr, "expected: %#v\n", expected) + os.Exit(1) + } +} + + + +func MainTest() { + testing("string is the same after round-trip", func() { + str1 := New().String() + id, err := FromString(str1) + assertEq(err, nil) + str2 := id.String() + assertEq(str1, str2) + }) + + testing("UUID is the same after round-trip", func() { + id1 := New() + id2, err := FromString(id1.String()) + assertEq(err, nil) + assertEq(id1, id2) + }) +} diff --git a/tests/functional/string-round-trip/main.go b/tests/functional/string-round-trip/main.go new file mode 120000 index 0000000..f67563d --- /dev/null +++ b/tests/functional/string-round-trip/main.go @@ -0,0 +1 @@ +../../main.go
\ No newline at end of file diff --git a/tests/fuzz/from-string/guuid.go b/tests/fuzz/from-string/guuid.go new file mode 100644 index 0000000..8971cbb --- /dev/null +++ b/tests/fuzz/from-string/guuid.go @@ -0,0 +1,30 @@ +package guuid + +import ( + "os" + "testing" + "testing/internal/testdeps" +) + + + +func fn(f *testing.F) { + f.Fuzz(func(t *testing.T, str string) { + FromString(str) + }) +} + + + +func MainTest() { + fuzzTargets := []testing.InternalFuzzTarget{ + { "fn", fn }, + } + + deps := testdeps.TestDeps{} + tests := []testing.InternalTest {} + benchmarks := []testing.InternalBenchmark{} + examples := []testing.InternalExample {} + m := testing.MainStart(deps, tests, benchmarks, fuzzTargets, examples) + os.Exit(m.Run()) +} diff --git a/tests/fuzz/from-string/main.go b/tests/fuzz/from-string/main.go new file mode 120000 index 0000000..f67563d --- /dev/null +++ b/tests/fuzz/from-string/main.go @@ -0,0 +1 @@ +../../main.go
\ No newline at end of file diff --git a/tests/fuzz/new-from/guuid.go b/tests/fuzz/new-from/guuid.go new file mode 100644 index 0000000..a786c66 --- /dev/null +++ b/tests/fuzz/new-from/guuid.go @@ -0,0 +1,31 @@ +package guuid + +import ( + "bytes" + "os" + "testing" + "testing/internal/testdeps" +) + + + +func fn(f *testing.F) { + f.Fuzz(func(t *testing.T, payload []byte) { + NewFrom(bytes.NewReader(payload)) + }) +} + + + +func MainTest() { + fuzzTargets := []testing.InternalFuzzTarget{ + { "fn", fn }, + } + + deps := testdeps.TestDeps{} + tests := []testing.InternalTest {} + benchmarks := []testing.InternalBenchmark{} + examples := []testing.InternalExample {} + m := testing.MainStart(deps, tests, benchmarks, fuzzTargets, examples) + os.Exit(m.Run()) +} diff --git a/tests/fuzz/new-from/main.go b/tests/fuzz/new-from/main.go new file mode 120000 index 0000000..f67563d --- /dev/null +++ b/tests/fuzz/new-from/main.go @@ -0,0 +1 @@ +../../main.go
\ No newline at end of file diff --git a/tests/libbuild.go b/tests/libbuild.go deleted file mode 100644 index 2c02686..0000000 --- a/tests/libbuild.go +++ /dev/null @@ -1,11 +0,0 @@ -package main - -import ( - "fmt" - - "guuid" -) - -func main() { - fmt.Println(guuid.New()) -} |