Example #1
0
// 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")
	}
}
Example #2
0
// 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(&currentConn, 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")
	}
}