github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/err_count_test.go (about)

     1  // Copyright 2016 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package sql_test
    12  
    13  import (
    14  	"context"
    15  	gosql "database/sql"
    16  	"testing"
    17  
    18  	"github.com/cockroachdb/cockroach/pkg/server/telemetry"
    19  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
    20  	"github.com/cockroachdb/cockroach/pkg/sql/tests"
    21  	"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
    22  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    23  	"github.com/cockroachdb/errors"
    24  	"github.com/lib/pq"
    25  )
    26  
    27  func TestErrorCounts(t *testing.T) {
    28  	defer leaktest.AfterTest(t)()
    29  
    30  	telemetry.GetFeatureCounts(telemetry.Raw, telemetry.ResetCounts)
    31  
    32  	params, _ := tests.CreateTestServerParams()
    33  	s, db, _ := serverutils.StartServer(t, params)
    34  	defer s.Stopper().Stop(context.Background())
    35  
    36  	count1 := telemetry.GetRawFeatureCounts()["errorcodes."+pgcode.Syntax]
    37  
    38  	_, err := db.Query("SELECT 1+")
    39  	if err == nil {
    40  		t.Fatal("expected error, got no error")
    41  	}
    42  
    43  	count2 := telemetry.GetRawFeatureCounts()["errorcodes."+pgcode.Syntax]
    44  
    45  	if count2-count1 != 1 {
    46  		t.Fatalf("expected 1 syntax error, got %d", count2-count1)
    47  	}
    48  
    49  	rows, err := db.Query(`SHOW SYNTAX 'SELECT 1+'`)
    50  	if err != nil {
    51  		t.Fatalf("%+v", err)
    52  	}
    53  	for rows.Next() {
    54  		// Do nothing. SHOW SYNTAX itself is tested elsewhere.
    55  		// We just check the counts below.
    56  	}
    57  	rows.Close()
    58  
    59  	count3 := telemetry.GetRawFeatureCounts()["errorcodes."+pgcode.Syntax]
    60  
    61  	if count3-count2 != 1 {
    62  		t.Fatalf("expected 1 syntax error, got %d", count3-count2)
    63  	}
    64  }
    65  
    66  func TestUnimplementedCounts(t *testing.T) {
    67  	defer leaktest.AfterTest(t)()
    68  
    69  	telemetry.GetFeatureCounts(telemetry.Raw, telemetry.ResetCounts)
    70  
    71  	params, _ := tests.CreateTestServerParams()
    72  	s, db, _ := serverutils.StartServer(t, params)
    73  	defer s.Stopper().Stop(context.Background())
    74  
    75  	if _, err := db.Exec(`
    76  CREATE TABLE t(x INT8); 
    77  SET enable_experimental_alter_column_type_general = true;
    78  BEGIN;
    79  `); err != nil {
    80  		t.Fatal(err)
    81  	}
    82  	if _, err := db.Exec("ALTER TABLE t ALTER COLUMN x SET DATA TYPE STRING"); err == nil {
    83  		t.Fatal("expected error, got no error")
    84  	}
    85  
    86  	if telemetry.GetRawFeatureCounts()["unimplemented.#49351"] == 0 {
    87  		t.Fatal("expected unimplemented telemetry, got nothing")
    88  	}
    89  }
    90  
    91  func TestTransactionRetryErrorCounts(t *testing.T) {
    92  	defer leaktest.AfterTest(t)()
    93  
    94  	telemetry.GetFeatureCounts(telemetry.Raw, telemetry.ResetCounts)
    95  
    96  	// Transaction retry errors aren't given a pg error code until deep
    97  	// in pgwire (pgwire.convertToErrWithPGCode). Make sure we're
    98  	// reporting errors at a level that allows this code to be recorded.
    99  
   100  	params, _ := tests.CreateTestServerParams()
   101  	s, db, _ := serverutils.StartServer(t, params)
   102  	defer s.Stopper().Stop(context.Background())
   103  
   104  	if _, err := db.Exec("CREATE TABLE accounts (id INT8 PRIMARY KEY, balance INT8)"); err != nil {
   105  		t.Fatal(err)
   106  	}
   107  	if _, err := db.Exec("INSERT INTO accounts VALUES (1, 100)"); err != nil {
   108  		t.Fatal(err)
   109  	}
   110  
   111  	txn1, err := db.Begin()
   112  	if err != nil {
   113  		t.Fatal(err)
   114  	}
   115  
   116  	txn2, err := db.Begin()
   117  	if err != nil {
   118  		t.Fatal(err)
   119  	}
   120  
   121  	for _, txn := range []*gosql.Tx{txn1, txn2} {
   122  		rows, err := txn.Query("SELECT * FROM accounts WHERE id = 1")
   123  		if err != nil {
   124  			t.Fatal(err)
   125  		}
   126  		for rows.Next() {
   127  		}
   128  		rows.Close()
   129  	}
   130  
   131  	for _, txn := range []*gosql.Tx{txn1, txn2} {
   132  		if _, err := txn.Exec("UPDATE accounts SET balance = balance - 100 WHERE id = 1"); err != nil {
   133  			if pqErr := (*pq.Error)(nil); errors.As(err, &pqErr) &&
   134  				pqErr.Code == pgcode.SerializationFailure {
   135  				if err := txn.Rollback(); err != nil {
   136  					t.Fatal(err)
   137  				}
   138  				return
   139  			}
   140  			t.Fatal(err)
   141  		}
   142  		if err := txn.Commit(); err != nil {
   143  			if pqErr := (*pq.Error)(nil); !errors.As(err, &pqErr) ||
   144  				pqErr.Code != pgcode.SerializationFailure {
   145  				t.Fatal(err)
   146  			}
   147  		}
   148  	}
   149  
   150  	if telemetry.GetRawFeatureCounts()["errorcodes.40001"] == 0 {
   151  		t.Fatal("expected error code telemetry, got nothing")
   152  	}
   153  }