tarantool / go-tarantool

Tarantool 1.10+ client for Go language
https://pkg.go.dev/github.com/tarantool/go-tarantool/v2
BSD 2-Clause "Simplified" License
179 stars 57 forks source link

Problems with setup and teardown Tarantool in tests #147

Open ligurio opened 2 years ago

ligurio commented 2 years ago
  1. Tarantool process is not killed when tests fail with panic(). I don't know why. The test has a line defer test_helpers.StopTarantoolWithCleanup(instance), according to blog post Defer, Panic, and Recover deferred function should be executed eve in case of panic():

    Panic is a built-in function that stops the ordinary flow of control and begins panicking. When the function F calls panic, execution of F stops, any deferred functions in F are executed normally, and then F returns to its caller. To the caller, F then behaves like a call to panic. The process continues up the stack until all functions in the current goroutine have returned, at which point the program crashes. Panics can be initiated by invoking panic directly. They can also be caused by runtime errors, such as out-of-bounds array accesses.

  2. on next attempt to run tests StartTarantool() is not failed when Tarantool is already run on the same TCP port

Version: d3b5696ec23b46fcdfbd72d975882d44d5341897

oleg-jukovec commented 2 years ago

It may be helpful: https://github.com/golang/go/issues/37206

oleg-jukovec commented 2 years ago

I have found only one simple way: kill child processes .

I works but this is OS-dependent code. It should be implemented after supporting of all target platforms on CI, after #157 at least.

an example for Linux ```patch diff --git a/test_helpers/cmd.go b/test_helpers/cmd.go new file mode 100644 index 0000000..94b62ff --- /dev/null +++ b/test_helpers/cmd.go @@ -0,0 +1,14 @@ +//go:build !linux + +package test_helpers + +import ( + "os/exec" +) + +// CommandKillOnExit tries to create a commant that will killed after a parent, +// see a problem: https://github.com/golang/go/issues/37206 +// The default implementation just call a exec.Comman. +func CommandKillOnExit(name string, arg ...string) *exec.Cmd { + return exec.Command(name, arg...) +} diff --git a/test_helpers/cmd_linux.go b/test_helpers/cmd_linux.go new file mode 100644 index 0000000..5721376 --- /dev/null +++ b/test_helpers/cmd_linux.go @@ -0,0 +1,18 @@ +//go:build linux + +package test_helpers + +import ( + "os/exec" + "syscall" +) + +// CommandKillOnExit tries to create a commant that will killed after a parent, +// see a problem: https://github.com/golang/go/issues/37206 +func CommandKillOnExit(name string, arg ...string) *exec.Cmd { + cmd := exec.Command(name, arg...) + cmd.SysProcAttr = &syscall.SysProcAttr{ + Pdeathsig: syscall.SIGTERM, + } + return cmd +} diff --git a/test_helpers/main.go b/test_helpers/main.go index 5c9d513..1e4a6a5 100644 --- a/test_helpers/main.go +++ b/test_helpers/main.go @@ -184,7 +184,7 @@ func RestartTarantool(inst *TarantoolInstance) error { func StartTarantool(startOpts StartOpts) (TarantoolInstance, error) { // Prepare tarantool command. var inst TarantoolInstance - inst.Cmd = exec.Command("tarantool", startOpts.InitScript) + inst.Cmd = CommandKillOnExit("tarantool", startOpts.InitScript) inst.Cmd.Env = append( os.Environ(), ```

Another way is to add guard code to each test case which will catch a panic.


func catchPanic() {
    if (recover() != nil) {
        // stop Tarantool
    }
}

func TestCase(t *testing.T) {
    defer catchPanic()
    // test code
}

But there are may be issues with subtests.

filonenko-mikhail commented 10 months ago

other solution is to use unix sockets

oleg-jukovec commented 10 months ago

other solution is to use unix sockets

Could you please explain how this can help?