Skip to content
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,13 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.

* Fixed the fluctuating behavior of the TestConnectionHandlerOpenUpdateClose
test by increasing the waiting time (#502).
* On Linux, tarantool processes started by `test_helpers.StartTarantool`
are now terminated when the parent test process dies, preventing leaked
instances after a panic (#147).
* Reordered tests to defer `test_helpers.StopTarantoolWithCleanup` only
after asserting `StartTarantool` did not return an error, so a failed
start no longer panics with a nil-pointer dereference in the deferred
cleanup (#147).

## [v2.4.1] - 2025-10-16

Expand Down
3 changes: 1 addition & 2 deletions arrow/tarantool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,11 @@ func runTestMain(m *testing.M) int {
ConnectRetry: 10,
RetryTimeout: 500 * time.Millisecond,
})
defer test_helpers.StopTarantoolWithCleanup(instance)

if err != nil {
log.Printf("Failed to prepare test Tarantool: %s", err)
return 1
}
defer test_helpers.StopTarantoolWithCleanup(instance)

return m.Run()
}
Expand Down
3 changes: 1 addition & 2 deletions crud/tarantool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1446,12 +1446,11 @@ func TestYieldEveryOption(t *testing.T) {
// https://stackoverflow.com/questions/27629380/how-to-exit-a-go-program-honoring-deferred-calls
func runTestMain(m *testing.M) int {
inst, err := test_helpers.StartTarantool(startOpts)
defer test_helpers.StopTarantoolWithCleanup(inst)

if err != nil {
log.Printf("Failed to prepare test tarantool: %s", err)
return 1
}
defer test_helpers.StopTarantoolWithCleanup(inst)

return m.Run()
}
Expand Down
3 changes: 1 addition & 2 deletions datetime/datetime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -981,12 +981,11 @@ func runTestMain(m *testing.M) int {
ConnectRetry: 10,
RetryTimeout: 500 * time.Millisecond,
})
defer test_helpers.StopTarantoolWithCleanup(instance)

if err != nil {
log.Printf("Failed to prepare test Tarantool: %s", err)
return 1
}
defer test_helpers.StopTarantoolWithCleanup(instance)

return m.Run()
}
Expand Down
3 changes: 1 addition & 2 deletions decimal/decimal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -599,12 +599,11 @@ func runTestMain(m *testing.M) int {
ConnectRetry: 10,
RetryTimeout: 500 * time.Millisecond,
})
defer test_helpers.StopTarantoolWithCleanup(instance)

if err != nil {
log.Printf("Failed to prepare test Tarantool: %s", err)
return 1
}
defer test_helpers.StopTarantoolWithCleanup(instance)

return m.Run()
}
Expand Down
8 changes: 4 additions & 4 deletions tarantool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2762,8 +2762,8 @@ func newWatcherReconnectionPrepareTestConnection(t *testing.T) (*Connection, con
ConnectRetry: 10,
RetryTimeout: 500 * time.Millisecond,
})
t.Cleanup(func() { test_helpers.StopTarantoolWithCleanup(inst) })
require.NoErrorf(t, err, "Unable to start Tarantool")
t.Cleanup(func() { test_helpers.StopTarantoolWithCleanup(inst) })

ctx, cancel := test_helpers.GetConnectContext()

Expand Down Expand Up @@ -2843,8 +2843,8 @@ func TestConnection_NewWatcher_reconnect(t *testing.T) {
ConnectRetry: 10,
RetryTimeout: 500 * time.Millisecond,
})
defer test_helpers.StopTarantoolWithCleanup(inst)
require.NoErrorf(t, err, "Unable to start Tarantool")
defer test_helpers.StopTarantoolWithCleanup(inst)

reconnectOpts := opts
reconnectOpts.Reconnect = 100 * time.Millisecond
Expand Down Expand Up @@ -3097,8 +3097,8 @@ func TestConnection_named_index_after_reconnect(t *testing.T) {
ConnectRetry: 10,
RetryTimeout: 500 * time.Millisecond,
})
defer test_helpers.StopTarantoolWithCleanup(inst)
require.NoErrorf(t, err, "Unable to start Tarantool")
defer test_helpers.StopTarantoolWithCleanup(inst)

reconnectOpts := opts
reconnectOpts.Reconnect = 100 * time.Millisecond
Expand Down Expand Up @@ -3205,8 +3205,8 @@ func TestConnectIsBlocked(t *testing.T) {
ConnectRetry: 10,
RetryTimeout: 500 * time.Millisecond,
})
defer test_helpers.StopTarantoolWithCleanup(inst)
require.NoErrorf(t, err, "Unable to start Tarantool")
defer test_helpers.StopTarantoolWithCleanup(inst)

var counter int
mockDialer := mockSlowDialer{original: testDialer, counter: &counter}
Expand Down
21 changes: 21 additions & 0 deletions test_helpers/cmd_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//go:build linux

package test_helpers

import (
"os/exec"
"syscall"
)

// commandKillOnExit returns an *exec.Cmd that will be terminated by the
// kernel when the parent process dies, see
// https://github.com/golang/go/issues/37206. Without this, a panic in a
// test leaves the spawned tarantool process running and blocking the TCP
// port for subsequent runs (issue #147).
func commandKillOnExit(name string, arg ...string) *exec.Cmd {
cmd := exec.Command(name, arg...)
cmd.SysProcAttr = &syscall.SysProcAttr{
Pdeathsig: syscall.SIGTERM,
}
return cmd
}
14 changes: 14 additions & 0 deletions test_helpers/cmd_other.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//go:build !linux

package test_helpers

import (
"os/exec"
)

// commandKillOnExit is a fallback for platforms without a Pdeathsig
// equivalent. It just delegates to exec.Command, so a parent panic may
// leave the tarantool child alive (issue #147).
func commandKillOnExit(name string, arg ...string) *exec.Cmd {
return exec.Command(name, arg...)
}
2 changes: 1 addition & 1 deletion test_helpers/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ func StartTarantool(startOpts StartOpts) (*TarantoolInstance, error) {
args = append(args, "--config", startOpts.ConfigFile)
args = append(args, "--name", startOpts.InstanceName)
}
inst.Cmd = exec.Command(getTarantoolExec(), args...)
inst.Cmd = commandKillOnExit(getTarantoolExec(), args...)
inst.Cmd.Dir = startOpts.WorkDir

inst.Cmd.Env = append(
Expand Down
3 changes: 1 addition & 2 deletions uuid/uuid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,11 @@ func runTestMain(m *testing.M) int {
ConnectRetry: 10,
RetryTimeout: 500 * time.Millisecond,
})
defer test_helpers.StopTarantoolWithCleanup(inst)

if err != nil {
log.Printf("Failed to prepare test tarantool: %s", err)
return 1
}
defer test_helpers.StopTarantoolWithCleanup(inst)

return m.Run()
}
Expand Down
Loading