The live tests reached one shared bus and assert, read and remove the mesh's own objects by their fixed names, so packages run in parallel deleted what each other read and the suite passed only one package at a time; a red suite read as noise. internal/testbus starts a server per test, linked in at the nats-server release go.mod pins, and a test holds that pin to the catalogue's bus image and to the facts snapshot's bus when there is one, so the tests never run a bus the mesh does not. The waiter test read a timing (the most connections held at one look) and now reads the state it means (the fewest held across the wait). make check runs the packages in parallel under the race detector, with a timeout.
161 lines
4.3 KiB
Go
161 lines
4.3 KiB
Go
//go:build enable_antithesis_sdk && linux && amd64 && cgo
|
|
|
|
package internal
|
|
|
|
import (
|
|
"fmt"
|
|
"unsafe"
|
|
"os"
|
|
)
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// To build and run an executable with this package
|
|
//
|
|
// CC=clang CGO_ENABLED=1 go run ./main.go
|
|
// --------------------------------------------------------------------------------
|
|
|
|
// \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
|
|
//
|
|
// The commented lines below, and the `import "C"` line which must directly follow
|
|
// the commented lines are used by CGO. They are load-bearing, and should not be
|
|
// changed without first understanding how CGO uses them.
|
|
//
|
|
// \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
|
|
|
|
// #cgo LDFLAGS: -ldl
|
|
//
|
|
// #include <dlfcn.h>
|
|
// #include <stdbool.h>
|
|
// #include <stdint.h>
|
|
// #include <stdlib.h>
|
|
//
|
|
// typedef void (*go_fuzz_json_data_fn)(const char *data, size_t size);
|
|
// void
|
|
// go_fuzz_json_data(void *f, const char *data, size_t size) {
|
|
// ((go_fuzz_json_data_fn)f)(data, size);
|
|
// }
|
|
//
|
|
// typedef void (*go_fuzz_flush_fn)(void);
|
|
// void
|
|
// go_fuzz_flush(void *f) {
|
|
// ((go_fuzz_flush_fn)f)();
|
|
// }
|
|
//
|
|
// typedef uint64_t (*go_fuzz_get_random_fn)(void);
|
|
// uint64_t
|
|
// go_fuzz_get_random(void *f) {
|
|
// return ((go_fuzz_get_random_fn)f)();
|
|
// }
|
|
//
|
|
// typedef bool (*go_notify_coverage_fn)(size_t);
|
|
// int
|
|
// go_notify_coverage(void *f, size_t edges) {
|
|
// bool b = ((go_notify_coverage_fn)f)(edges);
|
|
// return b ? 1 : 0;
|
|
// }
|
|
//
|
|
// typedef uint64_t (*go_init_coverage_fn)(size_t num_edges, const char *symbols);
|
|
// uint64_t
|
|
// go_init_coverage(void *f, size_t num_edges, const char *symbols) {
|
|
// return ((go_init_coverage_fn)f)(num_edges, symbols);
|
|
// }
|
|
//
|
|
import "C"
|
|
|
|
const (
|
|
defaultNativeLibraryPath = "/usr/lib/libvoidstar.so"
|
|
)
|
|
|
|
type voidstarHandler struct {
|
|
fuzzJsonData unsafe.Pointer
|
|
fuzzFlush unsafe.Pointer
|
|
fuzzGetRandom unsafe.Pointer
|
|
initCoverage unsafe.Pointer
|
|
notifyCoverage unsafe.Pointer
|
|
}
|
|
|
|
func (h *voidstarHandler) output(message string) {
|
|
msg_len := len(message)
|
|
if msg_len == 0 {
|
|
return
|
|
}
|
|
cstrMessage := C.CString(message)
|
|
defer C.free(unsafe.Pointer(cstrMessage))
|
|
C.go_fuzz_json_data(h.fuzzJsonData, cstrMessage, C.ulong(msg_len))
|
|
C.go_fuzz_flush(h.fuzzFlush)
|
|
}
|
|
|
|
func (h *voidstarHandler) random() uint64 {
|
|
return uint64(C.go_fuzz_get_random(h.fuzzGetRandom))
|
|
}
|
|
|
|
func (h *voidstarHandler) init_coverage(num_edge uint64, symbols string) uint64 {
|
|
cstrSymbols := C.CString(symbols)
|
|
defer C.free(unsafe.Pointer(cstrSymbols))
|
|
return uint64(C.go_init_coverage(h.initCoverage, C.ulong(num_edge), cstrSymbols))
|
|
}
|
|
|
|
func (h *voidstarHandler) notify(edge uint64) bool {
|
|
ival := int(C.go_notify_coverage(h.notifyCoverage, C.ulong(edge)))
|
|
return ival == 1
|
|
}
|
|
|
|
// Attempt to load libvoidstar and some symbols from `path`
|
|
func openSharedLib(path string) (*voidstarHandler, error) {
|
|
cstrPath := C.CString(path)
|
|
defer C.free(unsafe.Pointer(cstrPath))
|
|
|
|
dlError := func(message string) error {
|
|
return fmt.Errorf("%s: (%s)", message, C.GoString(C.dlerror()))
|
|
}
|
|
|
|
sharedLib := C.dlopen(cstrPath, C.int(C.RTLD_NOW))
|
|
if sharedLib == nil {
|
|
return nil, dlError("Can not load the Antithesis native library")
|
|
}
|
|
|
|
loadFunc := func(name string) (symbol unsafe.Pointer, err error) {
|
|
cstrName := C.CString(name)
|
|
defer C.free(unsafe.Pointer(cstrName))
|
|
if symbol = C.dlsym(sharedLib, cstrName); symbol == nil {
|
|
err = dlError(fmt.Sprintf("Can not access symbol %s", name))
|
|
}
|
|
return
|
|
}
|
|
|
|
fuzzJsonData, err := loadFunc("fuzz_json_data")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
fuzzFlush, err := loadFunc("fuzz_flush")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
fuzzGetRandom, err := loadFunc("fuzz_get_random")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
notifyCoverage, err := loadFunc("notify_coverage")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
initCoverage, err := loadFunc("init_coverage_module")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &voidstarHandler{fuzzJsonData, fuzzFlush, fuzzGetRandom, initCoverage, notifyCoverage}, nil
|
|
}
|
|
|
|
// If we have a file at `defaultNativeLibraryPath`, we load the shared library
|
|
// (and panic on any error encountered during load).
|
|
func init_in_antithesis() libHandler {
|
|
if _, err := os.Stat(defaultNativeLibraryPath); err == nil {
|
|
handler, err := openSharedLib(defaultNativeLibraryPath)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return handler
|
|
}
|
|
return nil
|
|
}
|