...

Source file src/github.com/lib/pq/go19_test.go

Documentation: github.com/lib/pq

     1  //go:build go1.9
     2  // +build go1.9
     3  
     4  package pq
     5  
     6  import (
     7  	"context"
     8  	"database/sql"
     9  	"database/sql/driver"
    10  	"reflect"
    11  	"testing"
    12  )
    13  
    14  func TestPing(t *testing.T) {
    15  	ctx, cancel := context.WithCancel(context.Background())
    16  	db := openTestConn(t)
    17  	defer db.Close()
    18  
    19  	if _, ok := reflect.TypeOf(db).MethodByName("Conn"); !ok {
    20  		t.Skipf("Conn method undefined on type %T, skipping test (requires at least go1.9)", db)
    21  	}
    22  
    23  	if err := db.PingContext(ctx); err != nil {
    24  		t.Fatal("expected Ping to succeed")
    25  	}
    26  	defer cancel()
    27  
    28  	// grab a connection
    29  	conn, err := db.Conn(ctx)
    30  	if err != nil {
    31  		t.Fatal(err)
    32  	}
    33  
    34  	// start a transaction and read backend pid of our connection
    35  	tx, err := conn.BeginTx(ctx, &sql.TxOptions{
    36  		Isolation: sql.LevelDefault,
    37  		ReadOnly:  true,
    38  	})
    39  	if err != nil {
    40  		t.Fatal(err)
    41  	}
    42  
    43  	rows, err := tx.Query("SELECT pg_backend_pid()")
    44  	if err != nil {
    45  		t.Fatal(err)
    46  	}
    47  	defer rows.Close()
    48  
    49  	// read the pid from result
    50  	var pid int
    51  	for rows.Next() {
    52  		if err := rows.Scan(&pid); err != nil {
    53  			t.Fatal(err)
    54  		}
    55  	}
    56  	if rows.Err() != nil {
    57  		t.Fatal(err)
    58  	}
    59  	// Fail the transaction and make sure we can still ping.
    60  	if _, err := tx.Query("INVALID SQL"); err == nil {
    61  		t.Fatal("expected error")
    62  	}
    63  	if err := conn.PingContext(ctx); err != nil {
    64  		t.Fatal(err)
    65  	}
    66  	if err := tx.Rollback(); err != nil {
    67  		t.Fatal(err)
    68  	}
    69  
    70  	// kill the process which handles our connection and test if the ping fails
    71  	if _, err := db.Exec("SELECT pg_terminate_backend($1)", pid); err != nil {
    72  		t.Fatal(err)
    73  	}
    74  	if err := conn.PingContext(ctx); err != driver.ErrBadConn {
    75  		t.Fatalf("expected error %s, instead got %s", driver.ErrBadConn, err)
    76  	}
    77  }
    78  
    79  func TestCommitInFailedTransactionWithCancelContext(t *testing.T) {
    80  	db := openTestConn(t)
    81  	defer db.Close()
    82  
    83  	ctx, cancel := context.WithCancel(context.Background())
    84  	defer cancel()
    85  
    86  	txn, err := db.BeginTx(ctx, nil)
    87  	if err != nil {
    88  		t.Fatal(err)
    89  	}
    90  	rows, err := txn.Query("SELECT error")
    91  	if err == nil {
    92  		rows.Close()
    93  		t.Fatal("expected failure")
    94  	}
    95  	err = txn.Commit()
    96  	if err != ErrInFailedTransaction {
    97  		t.Fatalf("expected ErrInFailedTransaction; got %#v", err)
    98  	}
    99  }
   100  

View as plain text