aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/jackc/pgx/tx_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/jackc/pgx/tx_test.go')
-rw-r--r--vendor/github.com/jackc/pgx/tx_test.go297
1 files changed, 297 insertions, 0 deletions
diff --git a/vendor/github.com/jackc/pgx/tx_test.go b/vendor/github.com/jackc/pgx/tx_test.go
new file mode 100644
index 0000000..435521a
--- /dev/null
+++ b/vendor/github.com/jackc/pgx/tx_test.go
@@ -0,0 +1,297 @@
+package pgx_test
+
+import (
+ "github.com/jackc/pgx"
+ "testing"
+ "time"
+)
+
+func TestTransactionSuccessfulCommit(t *testing.T) {
+ t.Parallel()
+
+ conn := mustConnect(t, *defaultConnConfig)
+ defer closeConn(t, conn)
+
+ createSql := `
+ create temporary table foo(
+ id integer,
+ unique (id) initially deferred
+ );
+ `
+
+ if _, err := conn.Exec(createSql); err != nil {
+ t.Fatalf("Failed to create table: %v", err)
+ }
+
+ tx, err := conn.Begin()
+ if err != nil {
+ t.Fatalf("conn.Begin failed: %v", err)
+ }
+
+ _, err = tx.Exec("insert into foo(id) values (1)")
+ if err != nil {
+ t.Fatalf("tx.Exec failed: %v", err)
+ }
+
+ err = tx.Commit()
+ if err != nil {
+ t.Fatalf("tx.Commit failed: %v", err)
+ }
+
+ var n int64
+ err = conn.QueryRow("select count(*) from foo").Scan(&n)
+ if err != nil {
+ t.Fatalf("QueryRow Scan failed: %v", err)
+ }
+ if n != 1 {
+ t.Fatalf("Did not receive correct number of rows: %v", n)
+ }
+}
+
+func TestTxCommitWhenTxBroken(t *testing.T) {
+ t.Parallel()
+
+ conn := mustConnect(t, *defaultConnConfig)
+ defer closeConn(t, conn)
+
+ createSql := `
+ create temporary table foo(
+ id integer,
+ unique (id) initially deferred
+ );
+ `
+
+ if _, err := conn.Exec(createSql); err != nil {
+ t.Fatalf("Failed to create table: %v", err)
+ }
+
+ tx, err := conn.Begin()
+ if err != nil {
+ t.Fatalf("conn.Begin failed: %v", err)
+ }
+
+ if _, err := tx.Exec("insert into foo(id) values (1)"); err != nil {
+ t.Fatalf("tx.Exec failed: %v", err)
+ }
+
+ // Purposely break transaction
+ if _, err := tx.Exec("syntax error"); err == nil {
+ t.Fatal("Unexpected success")
+ }
+
+ err = tx.Commit()
+ if err != pgx.ErrTxCommitRollback {
+ t.Fatalf("Expected error %v, got %v", pgx.ErrTxCommitRollback, err)
+ }
+
+ var n int64
+ err = conn.QueryRow("select count(*) from foo").Scan(&n)
+ if err != nil {
+ t.Fatalf("QueryRow Scan failed: %v", err)
+ }
+ if n != 0 {
+ t.Fatalf("Did not receive correct number of rows: %v", n)
+ }
+}
+
+func TestTxCommitSerializationFailure(t *testing.T) {
+ t.Parallel()
+
+ pool := createConnPool(t, 5)
+ defer pool.Close()
+
+ pool.Exec(`drop table if exists tx_serializable_sums`)
+ _, err := pool.Exec(`create table tx_serializable_sums(num integer);`)
+ if err != nil {
+ t.Fatalf("Unable to create temporary table: %v", err)
+ }
+ defer pool.Exec(`drop table tx_serializable_sums`)
+
+ tx1, err := pool.BeginIso(pgx.Serializable)
+ if err != nil {
+ t.Fatalf("BeginIso failed: %v", err)
+ }
+ defer tx1.Rollback()
+
+ tx2, err := pool.BeginIso(pgx.Serializable)
+ if err != nil {
+ t.Fatalf("BeginIso failed: %v", err)
+ }
+ defer tx2.Rollback()
+
+ _, err = tx1.Exec(`insert into tx_serializable_sums(num) select sum(num) from tx_serializable_sums`)
+ if err != nil {
+ t.Fatalf("Exec failed: %v", err)
+ }
+
+ _, err = tx2.Exec(`insert into tx_serializable_sums(num) select sum(num) from tx_serializable_sums`)
+ if err != nil {
+ t.Fatalf("Exec failed: %v", err)
+ }
+
+ err = tx1.Commit()
+ if err != nil {
+ t.Fatalf("Commit failed: %v", err)
+ }
+
+ err = tx2.Commit()
+ if pgErr, ok := err.(pgx.PgError); !ok || pgErr.Code != "40001" {
+ t.Fatalf("Expected serialization error 40001, got %#v", err)
+ }
+}
+
+func TestTransactionSuccessfulRollback(t *testing.T) {
+ t.Parallel()
+
+ conn := mustConnect(t, *defaultConnConfig)
+ defer closeConn(t, conn)
+
+ createSql := `
+ create temporary table foo(
+ id integer,
+ unique (id) initially deferred
+ );
+ `
+
+ if _, err := conn.Exec(createSql); err != nil {
+ t.Fatalf("Failed to create table: %v", err)
+ }
+
+ tx, err := conn.Begin()
+ if err != nil {
+ t.Fatalf("conn.Begin failed: %v", err)
+ }
+
+ _, err = tx.Exec("insert into foo(id) values (1)")
+ if err != nil {
+ t.Fatalf("tx.Exec failed: %v", err)
+ }
+
+ err = tx.Rollback()
+ if err != nil {
+ t.Fatalf("tx.Rollback failed: %v", err)
+ }
+
+ var n int64
+ err = conn.QueryRow("select count(*) from foo").Scan(&n)
+ if err != nil {
+ t.Fatalf("QueryRow Scan failed: %v", err)
+ }
+ if n != 0 {
+ t.Fatalf("Did not receive correct number of rows: %v", n)
+ }
+}
+
+func TestBeginIso(t *testing.T) {
+ t.Parallel()
+
+ conn := mustConnect(t, *defaultConnConfig)
+ defer closeConn(t, conn)
+
+ isoLevels := []string{pgx.Serializable, pgx.RepeatableRead, pgx.ReadCommitted, pgx.ReadUncommitted}
+ for _, iso := range isoLevels {
+ tx, err := conn.BeginIso(iso)
+ if err != nil {
+ t.Fatalf("conn.BeginIso failed: %v", err)
+ }
+
+ var level string
+ conn.QueryRow("select current_setting('transaction_isolation')").Scan(&level)
+ if level != iso {
+ t.Errorf("Expected to be in isolation level %v but was %v", iso, level)
+ }
+
+ err = tx.Rollback()
+ if err != nil {
+ t.Fatalf("tx.Rollback failed: %v", err)
+ }
+ }
+}
+
+func TestTxAfterClose(t *testing.T) {
+ t.Parallel()
+
+ conn := mustConnect(t, *defaultConnConfig)
+ defer closeConn(t, conn)
+
+ tx, err := conn.Begin()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ var zeroTime, t1, t2 time.Time
+ tx.AfterClose(func(tx *pgx.Tx) {
+ t1 = time.Now()
+ })
+
+ tx.AfterClose(func(tx *pgx.Tx) {
+ t2 = time.Now()
+ })
+
+ tx.Rollback()
+
+ if t1 == zeroTime {
+ t.Error("First Tx.AfterClose callback not called")
+ }
+
+ if t2 == zeroTime {
+ t.Error("Second Tx.AfterClose callback not called")
+ }
+
+ if t1.Before(t2) {
+ t.Errorf("AfterClose callbacks called out of order: %v, %v", t1, t2)
+ }
+}
+
+func TestTxStatus(t *testing.T) {
+ t.Parallel()
+
+ conn := mustConnect(t, *defaultConnConfig)
+ defer closeConn(t, conn)
+
+ tx, err := conn.Begin()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if status := tx.Status(); status != pgx.TxStatusInProgress {
+ t.Fatalf("Expected status to be %v, but it was %v", pgx.TxStatusInProgress, status)
+ }
+
+ if err := tx.Rollback(); err != nil {
+ t.Fatal(err)
+ }
+
+ if status := tx.Status(); status != pgx.TxStatusRollbackSuccess {
+ t.Fatalf("Expected status to be %v, but it was %v", pgx.TxStatusRollbackSuccess, status)
+ }
+}
+
+func TestTxErr(t *testing.T) {
+ t.Parallel()
+
+ conn := mustConnect(t, *defaultConnConfig)
+ defer closeConn(t, conn)
+
+ tx, err := conn.Begin()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ // Purposely break transaction
+ if _, err := tx.Exec("syntax error"); err == nil {
+ t.Fatal("Unexpected success")
+ }
+
+ if err := tx.Commit(); err != pgx.ErrTxCommitRollback {
+ t.Fatalf("Expected error %v, got %v", pgx.ErrTxCommitRollback, err)
+ }
+
+ if status := tx.Status(); status != pgx.TxStatusCommitFailure {
+ t.Fatalf("Expected status to be %v, but it was %v", pgx.TxStatusRollbackSuccess, status)
+ }
+
+ if err := tx.Err(); err != pgx.ErrTxCommitRollback {
+ t.Fatalf("Expected error %v, got %v", pgx.ErrTxCommitRollback, err)
+ }
+}