func TestInitialKeys(t *testing.T) { defer leaktest.AfterTest(t) ms := sql.MakeMetadataSchema() // IDGenerator + 2 for each system object in the default schema. kv := ms.GetInitialValues() if actual, expected := len(kv), 1+2*sql.NumSystemDescriptors; actual != expected { t.Fatalf("Wrong number of initial sql kv pairs: %d, wanted %d", actual, expected) } // Add a non-system database and table. db := sql.MakeMetadataDatabase("testdb", sql.NewPrivilegeDescriptor(security.RootUser, privilege.List{privilege.ALL})) db.AddTable("CREATE TABLE testdb.x (val INTEGER PRIMARY KEY)", sql.NewPrivilegeDescriptor(security.RootUser, privilege.List{privilege.ALL})) ms.AddDatabase(db) kv = ms.GetInitialValues() // IDGenerator + 2 for each system object + 2 for testdb + 2 for test table if actual, expected := len(kv), 1+2*sql.NumSystemDescriptors+4; actual != expected { t.Fatalf("Wrong number of initial sql kv pairs: %d, wanted %d", actual, expected) } // Verify that IDGenerator value is correct. found := false var idgenkv roachpb.KeyValue for _, v := range kv { if v.Key.Equal(keys.DescIDGenerator) { idgenkv = v found = true break } } if !found { t.Fatal("Could not find descriptor ID generator in initial key set") } // Expect 2 non-reserved IDs to have been allocated. i, err := idgenkv.Value.GetInt() if err != nil { t.Fatal(err) } if a, e := i, int64(keys.MaxReservedDescID+1); a != e { t.Fatalf("Expected next descriptor ID to be %d, was %d", e, a) } }
// AddEventLogToMetadataSchema adds the range event log table to the supplied // MetadataSchema. func AddEventLogToMetadataSchema(schema *sql.MetadataSchema) { allPrivileges := sql.NewPrivilegeDescriptor(security.RootUser, privilege.List{privilege.ALL}) schema.AddTable(rangeEventTableSchema, allPrivileges) }
// TestSystemPrivilegeValidate exercises validation for system descriptors. // We use 1 (the system database ID). func TestSystemPrivilegeValidate(t *testing.T) { defer leaktest.AfterTest(t) id := sql.ID(1) allowedPrivileges := sql.SystemAllowedPrivileges[id] hasPrivilege := func(pl privilege.List, p privilege.Kind) bool { for _, i := range pl { if i == p { return true } } return false } // Exhaustively grant/revoke all privileges. // Due to the way validation is done after Grant/Revoke, // we need to revert the just-performed change after errors. descriptor := sql.NewPrivilegeDescriptor(security.RootUser, allowedPrivileges) if err := descriptor.Validate(id); err != nil { t.Fatal(err) } for _, p := range privilege.ByValue { if hasPrivilege(allowedPrivileges, p) { // Grant allowed privileges. Either they are already // on (noop), or they're accepted. descriptor.Grant(security.RootUser, privilege.List{p}) if err := descriptor.Validate(id); err != nil { t.Fatal(err) } descriptor.Grant("foo", privilege.List{p}) if err := descriptor.Validate(id); err != nil { t.Fatal(err) } // Remove allowed privileges. This fails for root, // but passes for other users. descriptor.Revoke(security.RootUser, privilege.List{p}) if err := descriptor.Validate(id); err == nil { t.Fatal("unexpected success") } descriptor.Grant(security.RootUser, privilege.List{p}) } else { // Granting non-allowed privileges always. descriptor.Grant(security.RootUser, privilege.List{p}) if err := descriptor.Validate(id); err == nil { t.Fatal("unexpected success") } descriptor.Revoke(security.RootUser, privilege.List{p}) descriptor.Grant(security.RootUser, allowedPrivileges) descriptor.Grant("foo", privilege.List{p}) if err := descriptor.Validate(id); err == nil { t.Fatal("unexpected success") } descriptor.Revoke("foo", privilege.List{p}) descriptor.Grant("foo", allowedPrivileges) // Revoking non-allowed privileges always succeeds, // except when removing ALL for root. if p == privilege.ALL { // We need to reset privileges as Revoke(ALL) will clear // all bits. descriptor.Revoke(security.RootUser, privilege.List{p}) if err := descriptor.Validate(id); err == nil { t.Fatal("unexpected success") } descriptor.Grant(security.RootUser, allowedPrivileges) } else { descriptor.Revoke(security.RootUser, privilege.List{p}) if err := descriptor.Validate(id); err != nil { t.Fatal(err) } } } // We can always revoke anything from non-root users. descriptor.Revoke("foo", privilege.List{p}) if err := descriptor.Validate(id); err != nil { t.Fatal(err) } } }
func TestComputeSplits(t *testing.T) { defer leaktest.AfterTest(t) const ( start = keys.MaxReservedDescID + 1 reservedStart = keys.MaxSystemDescID + 1 ) schema := sql.MakeMetadataSchema() // Real SQL system tables only. baseSql := schema.GetInitialValues() // Real SQL system tables plus some user stuff. userSql := append(schema.GetInitialValues(), descriptor(start), descriptor(start+1), descriptor(start+5)) // Real SQL system with reserved non-system tables. allPrivileges := sql.NewPrivilegeDescriptor(security.RootUser, privilege.List{privilege.ALL}) db := sql.MakeMetadataDatabase("testdb", allPrivileges) db.AddTable("CREATE TABLE testdb.test (i INT PRIMARY KEY)", allPrivileges) db.AddTable("CREATE TABLE testdb.test2 (i INT PRIMARY KEY)", allPrivileges) schema.AddDatabase(db) reservedSql := schema.GetInitialValues() // Real SQL system with reserved non-system and user database. allSql := append(schema.GetInitialValues(), descriptor(start), descriptor(start+1), descriptor(start+5)) allUserSplits := []uint32{start, start + 1, start + 2, start + 3, start + 4, start + 5} allReservedSplits := []uint32{reservedStart, reservedStart + 1, reservedStart + 2} allSplits := append(allReservedSplits, allUserSplits...) testCases := []struct { values []roachpb.KeyValue start, end roachpb.RKey // Use ints in the testcase definitions, more readable. splits []uint32 }{ // No data. {nil, roachpb.RKeyMin, roachpb.RKeyMax, nil}, {nil, keys.MakeTablePrefix(start), roachpb.RKeyMax, nil}, {nil, keys.MakeTablePrefix(start), keys.MakeTablePrefix(start + 10), nil}, {nil, roachpb.RKeyMin, keys.MakeTablePrefix(start + 10), nil}, // No user data. {baseSql, roachpb.RKeyMin, roachpb.RKeyMax, nil}, {baseSql, keys.MakeTablePrefix(start), roachpb.RKeyMax, nil}, {baseSql, keys.MakeTablePrefix(start), keys.MakeTablePrefix(start + 10), nil}, {baseSql, roachpb.RKeyMin, keys.MakeTablePrefix(start + 10), nil}, // User descriptors. {userSql, roachpb.RKeyMin, roachpb.RKeyMax, allUserSplits}, {userSql, keys.MakeTablePrefix(start), roachpb.RKeyMax, allUserSplits[1:]}, {userSql, keys.MakeTablePrefix(start), keys.MakeTablePrefix(start + 10), allUserSplits[1:]}, {userSql, roachpb.RKeyMin, keys.MakeTablePrefix(start + 10), allUserSplits}, {userSql, keys.MakeTablePrefix(start + 4), keys.MakeTablePrefix(start + 10), allUserSplits[5:]}, {userSql, keys.MakeTablePrefix(start + 5), keys.MakeTablePrefix(start + 10), nil}, {userSql, keys.MakeTablePrefix(start + 6), keys.MakeTablePrefix(start + 10), nil}, {userSql, keys.MakeKey(keys.MakeTablePrefix(start), roachpb.RKey("foo")), keys.MakeTablePrefix(start + 10), allUserSplits[1:]}, {userSql, keys.MakeKey(keys.MakeTablePrefix(start), roachpb.RKey("foo")), keys.MakeTablePrefix(start + 5), allUserSplits[1:5]}, {userSql, keys.MakeKey(keys.MakeTablePrefix(start), roachpb.RKey("foo")), keys.MakeKey(keys.MakeTablePrefix(start+5), roachpb.RKey("bar")), allUserSplits[1:]}, {userSql, keys.MakeKey(keys.MakeTablePrefix(start), roachpb.RKey("foo")), keys.MakeKey(keys.MakeTablePrefix(start), roachpb.RKey("morefoo")), nil}, // Reserved descriptors. {reservedSql, roachpb.RKeyMin, roachpb.RKeyMax, allReservedSplits}, {reservedSql, keys.MakeTablePrefix(reservedStart), roachpb.RKeyMax, allReservedSplits[1:]}, {reservedSql, keys.MakeTablePrefix(start), roachpb.RKeyMax, nil}, {reservedSql, keys.MakeTablePrefix(reservedStart), keys.MakeTablePrefix(start + 10), allReservedSplits[1:]}, {reservedSql, roachpb.RKeyMin, keys.MakeTablePrefix(reservedStart + 2), allReservedSplits[:2]}, {reservedSql, roachpb.RKeyMin, keys.MakeTablePrefix(reservedStart + 10), allReservedSplits}, {reservedSql, keys.MakeTablePrefix(reservedStart), keys.MakeTablePrefix(reservedStart + 2), allReservedSplits[1:2]}, {reservedSql, keys.MakeKey(keys.MakeTablePrefix(reservedStart), roachpb.RKey("foo")), keys.MakeKey(keys.MakeTablePrefix(start+10), roachpb.RKey("foo")), allReservedSplits[1:]}, // Reserved/User mix. {allSql, roachpb.RKeyMin, roachpb.RKeyMax, allSplits}, {allSql, keys.MakeTablePrefix(reservedStart + 1), roachpb.RKeyMax, allSplits[2:]}, {allSql, keys.MakeTablePrefix(start), roachpb.RKeyMax, allSplits[4:]}, {allSql, keys.MakeTablePrefix(reservedStart), keys.MakeTablePrefix(start + 10), allSplits[1:]}, {allSql, roachpb.RKeyMin, keys.MakeTablePrefix(start + 2), allSplits[:5]}, {allSql, keys.MakeKey(keys.MakeTablePrefix(reservedStart), roachpb.RKey("foo")), keys.MakeKey(keys.MakeTablePrefix(start+5), roachpb.RKey("foo")), allSplits[1:9]}, } cfg := config.SystemConfig{} for tcNum, tc := range testCases { cfg.Values = tc.values splits := cfg.ComputeSplitKeys(tc.start, tc.end) if len(splits) == 0 && len(tc.splits) == 0 { continue } // Convert ints to actual keys. expected := []roachpb.RKey{} for _, s := range tc.splits { expected = append(expected, keys.MakeTablePrefix(s)) } if !reflect.DeepEqual(splits, expected) { t.Errorf("#%d: bad splits:\ngot: %v\nexpected: %v", tcNum, splits, expected) } } }
// AddEventLogToMetadataSchema adds the range event log table to the supplied // MetadataSchema. func AddEventLogToMetadataSchema(schema *sql.MetadataSchema) { allPrivileges := sql.NewPrivilegeDescriptor(security.RootUser, privilege.List{privilege.ALL}) db := sql.MakeMetadataDatabase("rangelog", allPrivileges) db.AddTable(rangeEventTableSchema, allPrivileges) schema.AddDatabase(db) }