// test if connections can notify pool for their expiration // which re-generates new connection to the pool func TestSourcePool_connsReturning(t *testing.T) { src := &testSource{} expires := time.Millisecond pool := store.Pool(src, 1, expires) pool.Open() getConn := func() <-chan store.Conn { out := make(chan store.Conn) go func() { conn, _ := pool.Open() out <- conn close(out) }() return out } select { case <-getConn(): // skip case <-time.After((expires * 15) / 10): // wait some more to see if get new connection t.Errorf("failed to get connection after conn expires") } }
// test normal blocking func TestSourcePool_Open(t *testing.T) { src := &testSource{} pool := store.Pool(src, 10, 300*time.Second) grace := 10 * time.Millisecond getConn := func() <-chan store.Conn { out := make(chan store.Conn) go func() { conn, _ := pool.Open() out <- conn close(out) }() return out } // test getting connection within pool size timeout := false OuterLoop: // should open 9 times without blocking for i := 0; i < 9; i++ { select { case <-getConn(): break case <-time.After(grace): timeout = true t.Logf("time out on loop %d", i+1) break OuterLoop } } if want, have := false, timeout; want != have { t.Errorf("loop timeout before running 9 times") } // test getting the last connection in the pool var lastConn store.Conn select { case lastConn = <-getConn(): break case <-time.After(grace): timeout = true } if want, have := false, timeout; want != have { t.Errorf("loop timeout before getting the last connection") } if lastConn == nil { t.Errorf("lastConn is nil") return } var currentConn *store.PoolConn setPoolConnPtr := func(currentConn **store.PoolConn, in <-chan store.Conn) { conn := <-in *currentConn, _ = conn.(*store.PoolConn) } // test getting connection after pool is dry off go setPoolConnPtr(¤tConn, getConn()) time.Sleep(grace + 10*time.Millisecond) // wait long enough if currentConn != nil { t.Errorf("blocking failed. currentConn is not nil: %#v", currentConn) } // close a connection and see if the pool regains // the connection lastConn.Close() time.Sleep(30 * time.Millisecond) // wait for goroutine to do the work if currentConn == nil { t.Errorf("failed to connect after old connection closed") } }