github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/acceptance/compose/gss/psql/gss_test.go (about) 1 // Copyright 2019 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 // "make test" would normally test this file, but it should only be tested 12 // within docker compose. We also can't use just "gss" here because that 13 // tag is reserved for the toplevel Makefile's linux-gnu build. 14 15 // +build gss_compose 16 17 package gss 18 19 import ( 20 gosql "database/sql" 21 "fmt" 22 "os/exec" 23 "regexp" 24 "strings" 25 "testing" 26 27 "github.com/cockroachdb/cockroach/pkg/util/timeutil" 28 "github.com/cockroachdb/errors" 29 "github.com/lib/pq" 30 ) 31 32 func TestGSS(t *testing.T) { 33 connector, err := pq.NewConnector("user=root sslmode=require") 34 if err != nil { 35 t.Fatal(err) 36 } 37 db := gosql.OpenDB(connector) 38 defer db.Close() 39 40 tests := []struct { 41 // The hba.conf file/setting. 42 conf string 43 user string 44 // Error message of hba conf 45 hbaErr string 46 // Error message of gss login. 47 gssErr string 48 }{ 49 { 50 conf: `host all all all gss include_realm=0 nope=1`, 51 hbaErr: `unsupported option`, 52 }, 53 { 54 conf: `host all all all gss include_realm=1`, 55 hbaErr: `include_realm must be set to 0`, 56 }, 57 { 58 conf: `host all all all gss`, 59 hbaErr: `missing "include_realm=0"`, 60 }, 61 { 62 conf: `host all all all gss include_realm=0`, 63 user: "tester", 64 gssErr: `GSS authentication requires an enterprise license`, 65 }, 66 { 67 conf: `host all tester all gss include_realm=0`, 68 user: "tester", 69 gssErr: `GSS authentication requires an enterprise license`, 70 }, 71 { 72 conf: `host all nope all gss include_realm=0`, 73 user: "tester", 74 gssErr: "no server.host_based_authentication.configuration entry", 75 }, 76 { 77 conf: `host all all all gss include_realm=0 krb_realm=MY.EX`, 78 user: "tester", 79 gssErr: `GSS authentication requires an enterprise license`, 80 }, 81 { 82 conf: `host all all all gss include_realm=0 krb_realm=NOPE.EX`, 83 user: "tester", 84 gssErr: `GSSAPI realm \(MY.EX\) didn't match any configured realm`, 85 }, 86 { 87 conf: `host all all all gss include_realm=0 krb_realm=NOPE.EX krb_realm=MY.EX`, 88 user: "tester", 89 gssErr: `GSS authentication requires an enterprise license`, 90 }, 91 } 92 for i, tc := range tests { 93 t.Run(fmt.Sprint(i), func(t *testing.T) { 94 if _, err := db.Exec(`SET CLUSTER SETTING server.host_based_authentication.configuration = $1`, tc.conf); !IsError(err, tc.hbaErr) { 95 t.Fatalf("expected err %v, got %v", tc.hbaErr, err) 96 } 97 if tc.hbaErr != "" { 98 return 99 } 100 if _, err := db.Exec(fmt.Sprintf(`CREATE USER IF NOT EXISTS '%s'`, tc.user)); err != nil { 101 t.Fatal(err) 102 } 103 out, err := exec.Command("psql", "-c", "SELECT 1", "-U", tc.user).CombinedOutput() 104 err = errors.Wrap(err, strings.TrimSpace(string(out))) 105 if !IsError(err, tc.gssErr) { 106 t.Errorf("expected err %v, got %v", tc.gssErr, err) 107 } 108 }) 109 } 110 } 111 112 func TestGSSFileDescriptorCount(t *testing.T) { 113 // When the docker-compose.yml added a ulimit for the cockroach 114 // container the open file count would just stop there, it wouldn't 115 // cause cockroach to panic or error like I had hoped since it would 116 // allow a test to assert that multiple gss connections didn't leak 117 // file descriptors. Another possibility would be to have something 118 // track the open file count in the cockroach container, but that seems 119 // brittle and probably not worth the effort. However this test is 120 // useful when doing manual tracking of file descriptor count. 121 t.Skip("skip") 122 123 rootConnector, err := pq.NewConnector("user=root sslmode=require") 124 if err != nil { 125 t.Fatal(err) 126 } 127 rootDB := gosql.OpenDB(rootConnector) 128 defer rootDB.Close() 129 130 if _, err := rootDB.Exec(`SET CLUSTER SETTING server.host_based_authentication.configuration = $1`, "host all all all gss include_realm=0"); err != nil { 131 t.Fatal(err) 132 } 133 const user = "tester" 134 if _, err := rootDB.Exec(fmt.Sprintf(`CREATE USER IF NOT EXISTS '%s'`, user)); err != nil { 135 t.Fatal(err) 136 } 137 138 start := timeutil.Now() 139 for i := 0; i < 1000; i++ { 140 fmt.Println(i, timeutil.Since(start)) 141 out, err := exec.Command("psql", "-c", "SELECT 1", "-U", user).CombinedOutput() 142 if IsError(err, "GSS authentication requires an enterprise license") { 143 t.Log(string(out)) 144 t.Fatal(err) 145 } 146 } 147 } 148 149 func IsError(err error, re string) bool { 150 if err == nil && re == "" { 151 return true 152 } 153 if err == nil || re == "" { 154 return false 155 } 156 matched, merr := regexp.MatchString(re, err.Error()) 157 if merr != nil { 158 return false 159 } 160 return matched 161 }