mirror of
https://github.com/wneessen/go-mail.git
synced 2024-12-18 17:00:38 +01:00
Add tests for ConnPool close and concurrency issues
This commit introduces two new tests: `TestConnPool_Close` and `TestConnPool_Concurrency`. The former ensures the proper closing of connection pool resources, while the latter checks for concurrency issues by creating and closing multiple connections in parallel.
This commit is contained in:
parent
2abdee743d
commit
07e7b17ae8
1 changed files with 100 additions and 0 deletions
100
connpool_test.go
100
connpool_test.go
|
@ -255,6 +255,106 @@ func TestPoolConn_MarkUnusable(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConnPool_Close(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
serverPort := TestServerPortBase + 15
|
||||||
|
featureSet := "250-AUTH PLAIN\r\n250-8BITMIME\r\n250-DSN\r\n250 SMTPUTF8"
|
||||||
|
go func() {
|
||||||
|
if err := simpleSMTPServer(ctx, featureSet, true, serverPort); err != nil {
|
||||||
|
t.Errorf("failed to start test server: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
time.Sleep(time.Millisecond * 300)
|
||||||
|
|
||||||
|
pool, err := newConnPool(serverPort)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to create connection pool: %s", err)
|
||||||
|
}
|
||||||
|
pool.Close()
|
||||||
|
|
||||||
|
castPool := pool.(*connPool)
|
||||||
|
|
||||||
|
if castPool.conns != nil {
|
||||||
|
t.Error("closing pool failed: conns channel should be nil")
|
||||||
|
}
|
||||||
|
if castPool.dialCtxFunc != nil {
|
||||||
|
t.Error("closing pool failed: dialCtxFunc should be nil")
|
||||||
|
}
|
||||||
|
if castPool.dialContext != nil {
|
||||||
|
t.Error("closing pool failed: dialContext should be nil")
|
||||||
|
}
|
||||||
|
if castPool.dialAddress != "" {
|
||||||
|
t.Error("closing pool failed: dialAddress should be empty")
|
||||||
|
}
|
||||||
|
if castPool.dialNetwork != "" {
|
||||||
|
t.Error("closing pool failed: dialNetwork should be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := pool.Get()
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("closing pool failed: getting new connection should return an error")
|
||||||
|
}
|
||||||
|
if conn != nil {
|
||||||
|
t.Errorf("closing pool failed: getting new connection should return a nil-connection")
|
||||||
|
}
|
||||||
|
if pool.Size() != 0 {
|
||||||
|
t.Errorf("closing pool failed: pool size should be 0, but got: %d", pool.Size())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConnPool_Concurrency(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
serverPort := TestServerPortBase + 16
|
||||||
|
featureSet := "250-AUTH PLAIN\r\n250-8BITMIME\r\n250-DSN\r\n250 SMTPUTF8"
|
||||||
|
go func() {
|
||||||
|
if err := simpleSMTPServer(ctx, featureSet, true, serverPort); err != nil {
|
||||||
|
t.Errorf("failed to start test server: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
time.Sleep(time.Millisecond * 300)
|
||||||
|
|
||||||
|
pool, err := newConnPool(serverPort)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to create connection pool: %s", err)
|
||||||
|
}
|
||||||
|
defer pool.Close()
|
||||||
|
pipe := make(chan net.Conn)
|
||||||
|
|
||||||
|
getWg := sync.WaitGroup{}
|
||||||
|
closeWg := sync.WaitGroup{}
|
||||||
|
for i := 0; i < 30; i++ {
|
||||||
|
getWg.Add(1)
|
||||||
|
closeWg.Add(1)
|
||||||
|
go func() {
|
||||||
|
conn, err := pool.Get()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to get new connection from pool: %s", err)
|
||||||
|
}
|
||||||
|
pipe <- conn
|
||||||
|
getWg.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
conn := <-pipe
|
||||||
|
if conn == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = conn.Close(); err != nil {
|
||||||
|
t.Errorf("failed to close connection: %s", err)
|
||||||
|
}
|
||||||
|
closeWg.Done()
|
||||||
|
}()
|
||||||
|
getWg.Wait()
|
||||||
|
closeWg.Wait()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func newConnPool(port int) (Pool, error) {
|
func newConnPool(port int) (Pool, error) {
|
||||||
netDialer := net.Dialer{}
|
netDialer := net.Dialer{}
|
||||||
return NewConnPool(context.Background(), 5, 30, netDialer.DialContext, "tcp",
|
return NewConnPool(context.Background(), 5, 30, netDialer.DialContext, "tcp",
|
||||||
|
|
Loading…
Reference in a new issue