github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ccl/backupccl/targets_test.go (about) 1 // Copyright 2016 The Cockroach Authors. 2 // 3 // Licensed as a CockroachDB Enterprise file under the Cockroach Community 4 // License (the "License"); you may not use this file except in compliance with 5 // the License. You may obtain a copy of the License at 6 // 7 // https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt 8 9 package backupccl 10 11 import ( 12 "context" 13 "fmt" 14 "reflect" 15 "sort" 16 "testing" 17 18 "github.com/cockroachdb/cockroach/pkg/sql/parser" 19 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 20 "github.com/cockroachdb/cockroach/pkg/sql/sessiondata" 21 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 22 "github.com/cockroachdb/cockroach/pkg/testutils" 23 "github.com/cockroachdb/cockroach/pkg/util/hlc" 24 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 25 ) 26 27 func TestDescriptorsMatchingTargets(t *testing.T) { 28 defer leaktest.AfterTest(t)() 29 30 descriptors := []sqlbase.Descriptor{ 31 *sqlbase.WrapDescriptor(&sqlbase.DatabaseDescriptor{ID: 0, Name: "system"}), 32 *sqlbase.WrapDescriptor(&sqlbase.TableDescriptor{ID: 1, Name: "foo", ParentID: 0}), 33 *sqlbase.WrapDescriptor(&sqlbase.TableDescriptor{ID: 2, Name: "bar", ParentID: 0}), 34 *sqlbase.WrapDescriptor(&sqlbase.TableDescriptor{ID: 4, Name: "baz", ParentID: 3}), 35 *sqlbase.WrapDescriptor(&sqlbase.TableDescriptor{ID: 6, Name: "offline", ParentID: 0, State: sqlbase.TableDescriptor_OFFLINE}), 36 *sqlbase.WrapDescriptor(&sqlbase.DatabaseDescriptor{ID: 3, Name: "data"}), 37 *sqlbase.WrapDescriptor(&sqlbase.DatabaseDescriptor{ID: 5, Name: "empty"}), 38 } 39 // Set the timestamp on the table descriptors. 40 for _, d := range descriptors { 41 d.Table(hlc.Timestamp{WallTime: 1}) 42 } 43 44 tests := []struct { 45 sessionDatabase string 46 pattern string 47 expected []string 48 expectedDBs []string 49 err string 50 }{ 51 {"", "DATABASE system", []string{"system", "foo", "bar"}, []string{"system"}, ``}, 52 {"", "DATABASE system, noexist", nil, nil, `unknown database "noexist"`}, 53 {"", "DATABASE system, system", []string{"system", "foo", "bar"}, []string{"system"}, ``}, 54 {"", "DATABASE data", []string{"data", "baz"}, []string{"data"}, ``}, 55 {"", "DATABASE system, data", []string{"system", "foo", "bar", "data", "baz"}, []string{"data", "system"}, ``}, 56 {"", "DATABASE system, data, noexist", nil, nil, `unknown database "noexist"`}, 57 {"system", "DATABASE system", []string{"system", "foo", "bar"}, []string{"system"}, ``}, 58 {"system", "DATABASE system, noexist", nil, nil, `unknown database "noexist"`}, 59 {"system", "DATABASE data", []string{"data", "baz"}, []string{"data"}, ``}, 60 {"system", "DATABASE system, data", []string{"system", "foo", "bar", "data", "baz"}, []string{"data", "system"}, ``}, 61 {"system", "DATABASE system, data, noexist", nil, nil, `unknown database "noexist"`}, 62 63 {"", "TABLE foo", nil, nil, `table "foo" does not exist`}, 64 {"system", "TABLE foo", []string{"system", "foo"}, nil, ``}, 65 {"system", "TABLE foo, foo", []string{"system", "foo"}, nil, ``}, 66 {"data", "TABLE foo", nil, nil, `table "foo" does not exist`}, 67 68 {"", "TABLE *", nil, nil, `"\*" does not match any valid database or schema`}, 69 {"", "TABLE *, system.public.foo", nil, nil, `"\*" does not match any valid database or schema`}, 70 {"noexist", "TABLE *", nil, nil, `"\*" does not match any valid database or schema`}, 71 {"system", "TABLE *", []string{"system", "foo", "bar"}, nil, ``}, 72 {"data", "TABLE *", []string{"data", "baz"}, nil, ``}, 73 {"empty", "TABLE *", []string{"empty"}, nil, ``}, 74 75 {"", "TABLE foo, baz", nil, nil, `table "(foo|baz)" does not exist`}, 76 {"system", "TABLE foo, baz", nil, nil, `table "baz" does not exist`}, 77 {"data", "TABLE foo, baz", nil, nil, `table "foo" does not exist`}, 78 79 {"", "TABLE system.foo", []string{"system", "foo"}, nil, ``}, 80 {"", "TABLE system.foo, foo", []string{"system", "foo"}, nil, `table "foo" does not exist`}, 81 {"", "TABLE system.public.foo", []string{"system", "foo"}, nil, ``}, 82 {"", "TABLE system.public.foo, foo", []string{"system", "foo"}, nil, `table "foo" does not exist`}, 83 84 {"", "TABLE system.public.foo, bar", []string{"system", "foo"}, nil, `table "bar" does not exist`}, 85 {"", "TABLE system.foo, bar", []string{"system", "foo"}, nil, `table "bar" does not exist`}, 86 {"system", "TABLE system.public.foo, bar", []string{"system", "foo", "bar"}, nil, ``}, 87 {"system", "TABLE system.foo, bar", []string{"system", "foo", "bar"}, nil, ``}, 88 89 {"", "TABLE noexist.*", nil, nil, `"noexist\.\*" does not match any valid database or schema`}, 90 {"", "TABLE empty.*", []string{"empty"}, nil, ``}, 91 {"", "TABLE system.*", []string{"system", "foo", "bar"}, nil, ``}, 92 {"", "TABLE system.public.*", []string{"system", "foo", "bar"}, nil, ``}, 93 {"", "TABLE system.public.*, foo, baz", nil, nil, `table "(foo|baz)" does not exist`}, 94 {"system", "TABLE system.public.*, foo, baz", nil, nil, `table "baz" does not exist`}, 95 {"data", "TABLE system.public.*, baz", []string{"system", "foo", "bar", "data", "baz"}, nil, ``}, 96 {"data", "TABLE system.public.*, foo, baz", nil, nil, `table "(foo|baz)" does not exist`}, 97 98 {"", "TABLE SyStEm.FoO", []string{"system", "foo"}, nil, ``}, 99 {"", "TABLE SyStEm.pUbLic.FoO", []string{"system", "foo"}, nil, ``}, 100 {"", `TABLE system."FoO"`, nil, nil, `table "system.FoO" does not exist`}, 101 {"system", `TABLE "FoO"`, nil, nil, `table "FoO" does not exist`}, 102 103 {"", `TABLE system."foo"`, []string{"system", "foo"}, nil, ``}, 104 {"", `TABLE system.public."foo"`, []string{"system", "foo"}, nil, ``}, 105 {"system", `TABLE "foo"`, []string{"system", "foo"}, nil, ``}, 106 107 {"system", `TABLE offline`, nil, nil, `table "offline" does not exist`}, 108 {"", `TABLE system.offline`, []string{"system", "foo"}, nil, `table "system.public.offline" does not exist`}, 109 {"system", `TABLE *`, []string{"system", "foo", "bar"}, nil, ``}, 110 } 111 searchPath := sessiondata.MakeSearchPath([]string{"public", "pg_catalog"}) 112 for i, test := range tests { 113 t.Run(fmt.Sprintf("%d/%s/%s", i, test.sessionDatabase, test.pattern), func(t *testing.T) { 114 sql := fmt.Sprintf(`GRANT ALL ON %s TO ignored`, test.pattern) 115 stmt, err := parser.ParseOne(sql) 116 if err != nil { 117 t.Fatal(err) 118 } 119 targets := stmt.AST.(*tree.Grant).Targets 120 121 matched, err := descriptorsMatchingTargets(context.Background(), 122 test.sessionDatabase, searchPath, descriptors, targets) 123 if test.err != "" { 124 if !testutils.IsError(err, test.err) { 125 t.Fatalf("expected error matching '%v', but got '%v'", test.err, err) 126 } 127 } else if err != nil { 128 t.Fatal(err) 129 } else { 130 var matchedNames []string 131 for _, m := range matched.descs { 132 matchedNames = append(matchedNames, m.GetName()) 133 } 134 var matchedDBNames []string 135 for _, m := range matched.requestedDBs { 136 matchedDBNames = append(matchedDBNames, m.GetName()) 137 } 138 sort.Strings(test.expected) 139 sort.Strings(test.expectedDBs) 140 sort.Strings(matchedNames) 141 sort.Strings(matchedDBNames) 142 if !reflect.DeepEqual(test.expected, matchedNames) { 143 t.Fatalf("expected %q got %q", test.expected, matchedNames) 144 } 145 if !reflect.DeepEqual(test.expectedDBs, matchedDBNames) { 146 t.Fatalf("expected %q got %q", test.expectedDBs, matchedDBNames) 147 } 148 } 149 }) 150 } 151 }