libgo: update to final Go 1.8 release

Along with the update this fixes a problem that was always present but
    only showed up with the new reflect test.  When a program used a
    **unsafe.Pointer and stored the value in an interface type, the
    generated type descriptor pointed to the GC data for *unsafe.Pointer.
    It did that by name, but we were not generating a variable with the
    right name.
    
    Reviewed-on: https://go-review.googlesource.com/37144

From-SVN: r245535
This commit is contained in:
Ian Lance Taylor 2017-02-17 15:43:39 +00:00
parent 4bcd6597a3
commit 00b2a30fd4
20 changed files with 895 additions and 266 deletions

View file

@ -153,8 +153,13 @@ func closeDB(t testing.TB, db *DB) {
if err != nil {
t.Fatalf("error closing DB: %v", err)
}
if count := db.numOpenConns(); count != 0 {
t.Fatalf("%d connections still open after closing DB", count)
var numOpen int
if !waitCondition(5*time.Second, 5*time.Millisecond, func() bool {
numOpen = db.numOpenConns()
return numOpen == 0
}) {
t.Fatalf("%d connections still open after closing DB", numOpen)
}
}
@ -276,6 +281,7 @@ func TestQuery(t *testing.T) {
}
}
// TestQueryContext tests canceling the context while scanning the rows.
func TestQueryContext(t *testing.T) {
db := newTestDB(t, "people")
defer closeDB(t, db)
@ -297,7 +303,7 @@ func TestQueryContext(t *testing.T) {
for rows.Next() {
if index == 2 {
cancel()
time.Sleep(10 * time.Millisecond)
waitForRowsClose(t, rows, 5*time.Second)
}
var r row
err = rows.Scan(&r.age, &r.name)
@ -313,9 +319,13 @@ func TestQueryContext(t *testing.T) {
got = append(got, r)
index++
}
err = rows.Err()
if err != nil {
t.Fatalf("Err: %v", err)
select {
case <-ctx.Done():
if err := ctx.Err(); err != context.Canceled {
t.Fatalf("context err = %v; want context.Canceled")
}
default:
t.Fatalf("context err = nil; want context.Canceled")
}
want := []row{
{age: 1, name: "Alice"},
@ -327,6 +337,7 @@ func TestQueryContext(t *testing.T) {
// And verify that the final rows.Next() call, which hit EOF,
// also closed the rows connection.
waitForRowsClose(t, rows, 5*time.Second)
waitForFree(t, db, 5*time.Second, 1)
if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
t.Errorf("executed %d Prepare statements; want 1", prepares)
@ -356,12 +367,27 @@ func waitForFree(t *testing.T, db *DB, maxWait time.Duration, want int) {
}
}
func waitForRowsClose(t *testing.T, rows *Rows, maxWait time.Duration) {
if !waitCondition(maxWait, 5*time.Millisecond, func() bool {
rows.closemu.RLock()
defer rows.closemu.RUnlock()
return rows.closed
}) {
t.Fatal("failed to close rows")
}
}
// TestQueryContextWait ensures that rows and all internal statements are closed when
// a query context is closed during execution.
func TestQueryContextWait(t *testing.T) {
db := newTestDB(t, "people")
defer closeDB(t, db)
prepares0 := numPrepares(t, db)
ctx, _ := context.WithTimeout(context.Background(), time.Millisecond*15)
// TODO(kardianos): convert this from using a timeout to using an explicit
// cancel when the query signals that is is "executing" the query.
ctx, cancel := context.WithTimeout(context.Background(), 300*time.Millisecond)
defer cancel()
// This will trigger the *fakeConn.Prepare method which will take time
// performing the query. The ctxDriverPrepare func will check the context
@ -374,10 +400,15 @@ func TestQueryContextWait(t *testing.T) {
// Verify closed rows connection after error condition.
waitForFree(t, db, 5*time.Second, 1)
if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
t.Errorf("executed %d Prepare statements; want 1", prepares)
// TODO(kardianos): if the context timeouts before the db.QueryContext
// executes this check may fail. After adjusting how the context
// is canceled above revert this back to a Fatal error.
t.Logf("executed %d Prepare statements; want 1", prepares)
}
}
// TestTxContextWait tests the transaction behavior when the tx context is canceled
// during execution of the query.
func TestTxContextWait(t *testing.T) {
db := newTestDB(t, "people")
defer closeDB(t, db)
@ -386,6 +417,10 @@ func TestTxContextWait(t *testing.T) {
tx, err := db.BeginTx(ctx, nil)
if err != nil {
// Guard against the context being canceled before BeginTx completes.
if err == context.DeadlineExceeded {
t.Skip("tx context canceled prior to first use")
}
t.Fatal(err)
}
@ -398,12 +433,6 @@ func TestTxContextWait(t *testing.T) {
}
waitForFree(t, db, 5*time.Second, 0)
// Ensure the dropped connection allows more connections to be made.
// Checked on DB Close.
waitCondition(5*time.Second, 5*time.Millisecond, func() bool {
return db.numOpenConns() == 0
})
}
func TestMultiResultSetQuery(t *testing.T) {
@ -527,6 +556,63 @@ func TestQueryNamedArg(t *testing.T) {
}
}
func TestPoolExhaustOnCancel(t *testing.T) {
if testing.Short() {
t.Skip("long test")
}
db := newTestDB(t, "people")
defer closeDB(t, db)
max := 3
db.SetMaxOpenConns(max)
// First saturate the connection pool.
// Then start new requests for a connection that is cancelled after it is requested.
var saturate, saturateDone sync.WaitGroup
saturate.Add(max)
saturateDone.Add(max)
for i := 0; i < max; i++ {
go func() {
saturate.Done()
rows, err := db.Query("WAIT|500ms|SELECT|people|name,photo|")
if err != nil {
t.Fatalf("Query: %v", err)
}
rows.Close()
saturateDone.Done()
}()
}
saturate.Wait()
// Now cancel the request while it is waiting.
ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
defer cancel()
for i := 0; i < max; i++ {
ctxReq, cancelReq := context.WithCancel(ctx)
go func() {
time.Sleep(time.Millisecond * 100)
cancelReq()
}()
err := db.PingContext(ctxReq)
if err != context.Canceled {
t.Fatalf("PingContext (Exhaust): %v", err)
}
}
saturateDone.Wait()
// Now try to open a normal connection.
err := db.PingContext(ctx)
if err != nil {
t.Fatalf("PingContext (Normal): %v", err)
}
}
func TestByteOwnership(t *testing.T) {
db := newTestDB(t, "people")
defer closeDB(t, db)
@ -2677,7 +2763,6 @@ func TestIssue18429(t *testing.T) {
}()
}
wg.Wait()
time.Sleep(milliWait * 3 * time.Millisecond)
}
// TestIssue18719 closes the context right before use. The sql.driverConn
@ -2720,14 +2805,8 @@ func TestIssue18719(t *testing.T) {
// Do not explicitly rollback. The rollback will happen from the
// canceled context.
// Wait for connections to return to pool.
var numOpen int
if !waitCondition(5*time.Second, 5*time.Millisecond, func() bool {
numOpen = db.numOpenConns()
return numOpen == 0
}) {
t.Fatalf("open conns after hitting EOF = %d; want 0", numOpen)
}
cancel()
waitForRowsClose(t, rows, 5*time.Second)
}
func TestConcurrency(t *testing.T) {