omeid/conex

container.Drop() doesn't cleanup containers that need to be killed with SIGINT

Closed this issue · 3 comments

Not sure which part of the stack this makes sense, but right now for containers that need to be killed (after 10s), if you SIGINT in your tests, the defer container.Drop() will not complete and the program will exit without killing the container, leaving resources around.

Here's what I'm doing:

func TestMain(m *testing.M) {
	os.Exit(conex.Run(m))
}

func TestChromeConnect(t *testing.T) {
	chrome, container := chromebox.Box(t)
	defer container.Drop()
	defer chrome.Close()
	fmt.Println(chrome.WS())
        // SIGINT
}

UPDATE: spoke too soon! looks like it'll eventually cleanup after itself even though the go program has already exited.

omeid commented

While you're at it, please contribute your chromebox :) I can create a repository under github.com/conex and add you as collaborator so you can push.

Haha, the actual *chrome.Chrome client is a bit of mess right now and the Dockerfile isn't public yet (but there are other working dockerfiles on docker hub), but maybe this will be useful. *chrome.Chrome could probably be easily swapped out for: https://github.com/mafredri/cdp.

package chromebox

import (
	"net"
	"strconv"
	"testing"

	"github.com/matthewmueller/conex"
	"github.com/matthewmueller/vood.ooo/chrome"
)

// Image to use for the box.
var Image = "chromeless:latest"

func init() {
	conex.PullImages = false
	conex.Require(func() string { return Image })
}

// New returns a chrome client and headless chrome inside of docker
func New(t testing.TB) (*chrome.Chrome, conex.Container) {
	port, err := findPort()
	if err != nil {
		t.Fatal(err)
	}

	conf := &conex.Config{
		Image:  Image,
		Expose: []string{strconv.Itoa(port) + ":9222"},
	}

	container := conex.Box(t, conf)

	ch, err := chrome.New(&chrome.Settings{
		Addr: "127.0.0.1:" + strconv.Itoa(port),
	})
	if err != nil {
		container.Drop()
		t.Fatal(err)
	}

	return ch, container
}

// get an available port
func findPort() (int, error) {
	addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
	if err != nil {
		return 0, err
	}

	l, err := net.ListenTCP("tcp", addr)
	if err != nil {
		return 0, err
	}
	defer l.Close()

	return l.Addr().(*net.TCPAddr).Port, nil
}