Fixed race condition in admin module commands tests by passing --race flag to build command for modules

This commit is contained in:
Kelvin Clement Mwinuka
2024-05-08 23:53:12 +08:00
parent b3ceecf80f
commit c5c1487799
2 changed files with 60 additions and 25 deletions

View File

@@ -19,5 +19,7 @@ test-unit:
CGO_ENABLED=1 go test ./... -coverprofile coverage/coverage.out CGO_ENABLED=1 go test ./... -coverprofile coverage/coverage.out
test-race: test-race:
env CGO_ENABLED=1 CC=x86_64-linux-musl-gcc GOOS=linux GOARCH=amd64 DEST=internal/modules/admin/testdata/modules make build-modules && \ CGO_ENABLED=1 go build -buildmode=plugin --race -o internal/modules/admin/testdata/modules/module_set/module_set.so ./volumes/modules/module_set/module_set.go && \
go clean -testcache && go test ./... --race CGO_ENABLED=1 go build -buildmode=plugin --race -o internal/modules/admin/testdata/modules/module_get/module_get.so ./volumes/modules/module_get/module_get.go && \
go clean -testcache && \
CGO_ENABLED=1 go test ./... --race

View File

@@ -34,7 +34,6 @@ import (
str "github.com/echovault/echovault/internal/modules/string" str "github.com/echovault/echovault/internal/modules/string"
"github.com/tidwall/resp" "github.com/tidwall/resp"
"net" "net"
"os"
"reflect" "reflect"
"slices" "slices"
"strings" "strings"
@@ -43,30 +42,20 @@ import (
"unsafe" "unsafe"
) )
var mockServer *echovault.EchoVault func setupServer(port uint16) (*echovault.EchoVault, error) {
var port uint16
func init() {
p, _ := internal.GetFreePort()
port = uint16(p)
setupServer(port)
}
func setupServer(port uint16) *echovault.EchoVault {
cfg := echovault.DefaultConfig() cfg := echovault.DefaultConfig()
cfg.DataDir = "" cfg.DataDir = ""
cfg.BindAddr = "localhost" cfg.BindAddr = "localhost"
cfg.Port = port cfg.Port = port
cfg.EvictionPolicy = constants.NoEviction cfg.EvictionPolicy = constants.NoEviction
mockServer, _ = echovault.NewEchoVault(echovault.WithConfig(cfg)) return echovault.NewEchoVault(echovault.WithConfig(cfg))
return mockServer
} }
func getUnexportedField(field reflect.Value) interface{} { func getUnexportedField(field reflect.Value) interface{} {
return reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem().Interface() return reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem().Interface()
} }
func getHandler(commands ...string) internal.HandlerFunc { func getHandler(mockServer *echovault.EchoVault, commands ...string) internal.HandlerFunc {
if len(commands) == 0 { if len(commands) == 0 {
return nil return nil
} }
@@ -89,7 +78,7 @@ func getHandler(commands ...string) internal.HandlerFunc {
return nil return nil
} }
func getHandlerFuncParams(ctx context.Context, cmd []string, conn *net.Conn) internal.HandlerFuncParams { func getHandlerFuncParams(ctx context.Context, mockServer *echovault.EchoVault, cmd []string, conn *net.Conn) internal.HandlerFuncParams {
getCommands := getCommands :=
getUnexportedField(reflect.ValueOf(mockServer).Elem().FieldByName("getCommands")).(func() []internal.Command) getUnexportedField(reflect.ValueOf(mockServer).Elem().FieldByName("getCommands")).(func() []internal.Command)
return internal.HandlerFuncParams{ return internal.HandlerFuncParams{
@@ -101,13 +90,27 @@ func getHandlerFuncParams(ctx context.Context, cmd []string, conn *net.Conn) int
} }
func Test_AdminCommand(t *testing.T) { func Test_AdminCommand(t *testing.T) {
t.Cleanup(func() { // t.Cleanup(func() {
_ = os.RemoveAll("./testdata") // _ = os.RemoveAll("./testdata")
}) // })
t.Run("Test COMMANDS command", func(t *testing.T) { t.Run("Test COMMANDS command", func(t *testing.T) {
t.Parallel() t.Parallel()
res, err := getHandler("COMMANDS")(getHandlerFuncParams(context.Background(), []string{"commands"}, nil))
port, err := internal.GetFreePort()
if err != nil {
t.Error(err)
return
}
mockServer, err := setupServer(uint16(port))
if err != nil {
t.Error(err)
return
}
res, err := getHandler(mockServer, "COMMANDS")(
getHandlerFuncParams(context.Background(), mockServer, []string{"commands"}, nil),
)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@@ -150,6 +153,18 @@ func Test_AdminCommand(t *testing.T) {
t.Run("Test MODULE LOAD command", func(t *testing.T) { t.Run("Test MODULE LOAD command", func(t *testing.T) {
t.Parallel() t.Parallel()
port, err := internal.GetFreePort()
if err != nil {
t.Error(err)
return
}
mockServer, err := setupServer(uint16(port))
if err != nil {
t.Error(err)
return
}
tests := []struct { tests := []struct {
name string name string
execCommand []resp.Value execCommand []resp.Value
@@ -308,8 +323,17 @@ func Test_AdminCommand(t *testing.T) {
t.Run("Test MODULE UNLOAD command", func(t *testing.T) { t.Run("Test MODULE UNLOAD command", func(t *testing.T) {
t.Parallel() t.Parallel()
port, _ := internal.GetFreePort()
mockServer := setupServer(uint16(port)) port, err := internal.GetFreePort()
if err != nil {
t.Error(err)
return
}
mockServer, err := setupServer(uint16(port))
if err != nil {
t.Error(err)
return
}
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
wg.Add(1) wg.Add(1)
@@ -488,8 +512,17 @@ func Test_AdminCommand(t *testing.T) {
t.Run("Test MODULE LIST command", func(t *testing.T) { t.Run("Test MODULE LIST command", func(t *testing.T) {
t.Parallel() t.Parallel()
port, _ := internal.GetFreePort()
mockServer := setupServer(uint16(port)) port, err := internal.GetFreePort()
if err != nil {
t.Error(err)
return
}
mockServer, err := setupServer(uint16(port))
if err != nil {
t.Error(err)
return
}
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
wg.Add(1) wg.Add(1)