go-mysql-server icon indicating copy to clipboard operation
go-mysql-server copied to clipboard

multi-package go unit tests failing because previous test server not shutdown

Open tebruno99 opened this issue 2 years ago • 1 comments

I am attempting to use the in-memory database for go unit testing a sdk that contains multiple packages (each package connects to a different database & or api). I'm running into an issue where the first package runs great, but all packages after have issues with the previous test's go-mysql-server still running. (using go test ./... from module root)

A new server is being created for each package because my understanding is that TestMain exits and cannot init resources for sub or other packages

Each package has a TestMain to setup the server and the db connection it will be using. I cannot find a way to know that the server has actually successfully shut down so the Next package unit test can successfully create a new server on the same port & free up memory before the next test. (2nd test errors; panic: Port localhost:3306 already in use)

...
var wg sync.WaitGroup()
func TestMain(m *testing.M) {
	config := server.Config{
		Protocol: "tcp",
		Address:  fmt.Sprintf("%s:%d", address, port),
	}
	s, err := server.NewDefaultServer(config, engine)
	wg.Add(1)
	go StartServer(s)`

	tdb, err := sql.Open("mysql".......
	// then ping here until server is up and running
	code := m.Run()
	tdb.Close()
	s.Close()
	wg.Wait()
	os.Exit(code)
}

func StartServer(s *server.Server) {
	if err := s.Start(); err != nil {
		panic(err)
	}
	wg.Done()
}

If there were to a way to ask or wait to know that the server has fully shutdown before exiting the test, this would be a lot easier to accomplish..

Is this the wrong approach? Do anyone have any suggestions? (making a single TestMain and not using sub packages isn't an option, there are dozens of packages out of my control & only some of them use go-msyql-server).

tebruno99 avatar Oct 26 '23 17:10 tebruno99

There is a stupid way to solve this. In Linux, if you use 127.0.0.1:0, it means that you will use a random (may be ince in system) port. So you wont care about port confluence.

engine := sqle.NewDefault(
		memory.NewDBProvider(
			createTestDatabase(ctx),
		))
config := server.Config{
		Protocol: "tcp",
		Address:  "localhost:0",
	}
s, err = server.NewServer()
go  s.Start()
s.Listener.Addr().String()

yes , You can use s.Listener.Addr().String() to get addr

kom0055 avatar Dec 04 '23 15:12 kom0055