diff --git a/lib/launcher/launcher.go b/lib/launcher/launcher.go index 4926b376..9d492c59 100644 --- a/lib/launcher/launcher.go +++ b/lib/launcher/launcher.go @@ -443,6 +443,7 @@ func (l *Launcher) Launch() (string, error) { port := l.Get(flags.RemoteDebuggingPort) u, err := ResolveURL(port) if err == nil { + close(l.exit) return u, nil } cmd = exec.Command(bin, args...) diff --git a/lib/launcher/launcher_test.go b/lib/launcher/launcher_test.go index 9414b5dc..8190b506 100644 --- a/lib/launcher/launcher_test.go +++ b/lib/launcher/launcher_test.go @@ -15,6 +15,7 @@ import ( "path/filepath" "strings" "testing" + "time" "github.com/go-rod/rod/lib/defaults" "github.com/go-rod/rod/lib/launcher" @@ -325,3 +326,41 @@ func TestLaunchMultiTimes(t *testing.T) { _, e = l.Launch() g.Eq(e, launcher.ErrAlreadyLaunched) } + +func TestLunchKill_GoroutineLeakCase1(t *testing.T) { + g := setup(t) + dfn := func() { panic("detect goroutine leak") } + g.DoAfter(10*time.Second, dfn) + port := 58472 + l := launcher.New().Leakless(false).RemoteDebuggingPort(port) + dir := l.Get(flags.UserDataDir) + u, e := l.Launch() + g.Neq(u, "") + g.E(e) + l2 := launcher.New().Leakless(false).RemoteDebuggingPort(port) + l2.UserDataDir(dir) + l2.Launch() + l.Kill() + l.Cleanup() + l2.Kill() + // It will hang if goroutine leak is detected. + l2.Cleanup() +} + +func TestLunchKill_GoroutineLeakCase2(t *testing.T) { + g := setup(t) + dfn := func() { panic("detect goroutine leak") } + g.DoAfter(10*time.Second, dfn) + port := 58472 + l := launcher.New().Leakless(false).RemoteDebuggingPort(port) + dir := l.Get(flags.UserDataDir) + u, e := l.Launch() + g.Neq(u, "") + g.E(e) + l2 := launcher.New().Leakless(false).RemoteDebuggingPort(port) + l2.UserDataDir(dir) + l2.Launch() + l2.Kill() + // It will hang if goroutine leak is detected. + l2.Cleanup() +}