github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/config/system_test.go (about) 1 // Copyright 2015 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 config_test 12 13 import ( 14 "sort" 15 "testing" 16 17 "github.com/cockroachdb/cockroach/pkg/config" 18 "github.com/cockroachdb/cockroach/pkg/config/zonepb" 19 "github.com/cockroachdb/cockroach/pkg/keys" 20 "github.com/cockroachdb/cockroach/pkg/roachpb" 21 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 22 "github.com/cockroachdb/cockroach/pkg/testutils" 23 "github.com/cockroachdb/cockroach/pkg/util/encoding" 24 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 25 "github.com/gogo/protobuf/proto" 26 ) 27 28 // TODO(benesch): Don't reinvent the key encoding here. 29 30 func plainKV(k, v string) roachpb.KeyValue { 31 return kv([]byte(k), []byte(v)) 32 } 33 34 func tkey(tableID uint32, chunks ...string) []byte { 35 key := keys.SystemSQLCodec.TablePrefix(tableID) 36 for _, c := range chunks { 37 key = append(key, []byte(c)...) 38 } 39 return key 40 } 41 42 func sqlKV(tableID uint32, indexID, descriptorID uint64) roachpb.KeyValue { 43 k := tkey(tableID) 44 k = encoding.EncodeUvarintAscending(k, indexID) 45 k = encoding.EncodeUvarintAscending(k, descriptorID) 46 k = encoding.EncodeUvarintAscending(k, 12345) // Column ID, but could be anything. 47 return kv(k, nil) 48 } 49 50 func descriptor(descriptorID uint64) roachpb.KeyValue { 51 k := sqlbase.MakeDescMetadataKey(keys.SystemSQLCodec, sqlbase.ID(descriptorID)) 52 v := sqlbase.WrapDescriptor(&sqlbase.TableDescriptor{}) 53 kv := roachpb.KeyValue{Key: k} 54 if err := kv.Value.SetProto(v); err != nil { 55 panic(err) 56 } 57 return kv 58 } 59 60 func zoneConfig(descriptorID uint32, spans ...zonepb.SubzoneSpan) roachpb.KeyValue { 61 kv := roachpb.KeyValue{ 62 Key: config.MakeZoneKey(descriptorID), 63 } 64 if err := kv.Value.SetProto(&zonepb.ZoneConfig{SubzoneSpans: spans}); err != nil { 65 panic(err) 66 } 67 return kv 68 } 69 70 func subzone(start, end string) zonepb.SubzoneSpan { 71 return zonepb.SubzoneSpan{Key: []byte(start), EndKey: []byte(end)} 72 } 73 74 func kv(k, v []byte) roachpb.KeyValue { 75 return roachpb.KeyValue{ 76 Key: k, 77 Value: roachpb.MakeValueFromBytes(v), 78 } 79 } 80 81 func TestGet(t *testing.T) { 82 defer leaktest.AfterTest(t)() 83 84 emptyKeys := []roachpb.KeyValue{} 85 someKeys := []roachpb.KeyValue{ 86 plainKV("a", "vala"), 87 plainKV("c", "valc"), 88 plainKV("d", "vald"), 89 } 90 91 aVal := roachpb.MakeValueFromString("vala") 92 bVal := roachpb.MakeValueFromString("valc") 93 cVal := roachpb.MakeValueFromString("vald") 94 95 testCases := []struct { 96 values []roachpb.KeyValue 97 key string 98 value *roachpb.Value 99 }{ 100 {emptyKeys, "a", nil}, 101 {emptyKeys, "b", nil}, 102 {emptyKeys, "c", nil}, 103 {emptyKeys, "d", nil}, 104 {emptyKeys, "e", nil}, 105 106 {someKeys, "", nil}, 107 {someKeys, "b", nil}, 108 {someKeys, "e", nil}, 109 {someKeys, "a0", nil}, 110 111 {someKeys, "a", &aVal}, 112 {someKeys, "c", &bVal}, 113 {someKeys, "d", &cVal}, 114 } 115 116 cfg := config.NewSystemConfig(zonepb.DefaultZoneConfigRef()) 117 for tcNum, tc := range testCases { 118 cfg.Values = tc.values 119 if val := cfg.GetValue([]byte(tc.key)); !proto.Equal(val, tc.value) { 120 t.Errorf("#%d: expected=%s, found=%s", tcNum, tc.value, val) 121 } 122 } 123 } 124 125 func TestGetLargestID(t *testing.T) { 126 defer leaktest.AfterTest(t)() 127 128 type testCase struct { 129 values []roachpb.KeyValue 130 largest uint32 131 maxID uint32 132 errStr string 133 } 134 135 testCases := []testCase{ 136 // No data. 137 {nil, 0, 0, "descriptor table not found"}, 138 139 // Some data, but not from the system span. 140 {[]roachpb.KeyValue{plainKV("a", "b")}, 0, 0, "descriptor table not found"}, 141 142 // Some real data, but no descriptors. 143 {[]roachpb.KeyValue{ 144 sqlKV(keys.NamespaceTableID, 1, 1), 145 sqlKV(keys.NamespaceTableID, 1, 2), 146 sqlKV(keys.UsersTableID, 1, 3), 147 }, 0, 0, "descriptor table not found"}, 148 149 // Single correct descriptor entry. 150 {[]roachpb.KeyValue{sqlKV(keys.DescriptorTableID, 1, 1)}, 1, 0, ""}, 151 152 // Surrounded by other data. 153 {[]roachpb.KeyValue{ 154 sqlKV(keys.NamespaceTableID, 1, 20), 155 sqlKV(keys.NamespaceTableID, 1, 30), 156 sqlKV(keys.DescriptorTableID, 1, 8), 157 sqlKV(keys.ZonesTableID, 1, 40), 158 }, 8, 0, ""}, 159 160 // Descriptors with holes. Index ID does not matter. 161 {[]roachpb.KeyValue{ 162 sqlKV(keys.DescriptorTableID, 1, 1), 163 sqlKV(keys.DescriptorTableID, 2, 5), 164 sqlKV(keys.DescriptorTableID, 3, 8), 165 sqlKV(keys.DescriptorTableID, 4, 12), 166 }, 12, 0, ""}, 167 168 // Real SQL layout. 169 func() testCase { 170 ms := sqlbase.MakeMetadataSchema(keys.SystemSQLCodec, zonepb.DefaultZoneConfigRef(), zonepb.DefaultSystemZoneConfigRef()) 171 descIDs := ms.DescriptorIDs() 172 maxDescID := descIDs[len(descIDs)-1] 173 kvs, _ /* splits */ := ms.GetInitialValues() 174 return testCase{kvs, uint32(maxDescID), 0, ""} 175 }(), 176 177 // Test non-zero max. 178 {[]roachpb.KeyValue{ 179 sqlKV(keys.DescriptorTableID, 1, 1), 180 sqlKV(keys.DescriptorTableID, 2, 5), 181 sqlKV(keys.DescriptorTableID, 3, 8), 182 sqlKV(keys.DescriptorTableID, 4, 12), 183 }, 8, 8, ""}, 184 185 // Test non-zero max. 186 {[]roachpb.KeyValue{ 187 sqlKV(keys.DescriptorTableID, 1, 1), 188 sqlKV(keys.DescriptorTableID, 2, 5), 189 sqlKV(keys.DescriptorTableID, 3, 8), 190 sqlKV(keys.DescriptorTableID, 4, 12), 191 }, 5, 7, ""}, 192 } 193 194 cfg := config.NewSystemConfig(zonepb.DefaultZoneConfigRef()) 195 for tcNum, tc := range testCases { 196 cfg.Values = tc.values 197 ret, err := cfg.GetLargestObjectID(tc.maxID) 198 if !testutils.IsError(err, tc.errStr) { 199 t.Errorf("#%d: expected err=%q, got %v", tcNum, tc.errStr, err) 200 continue 201 } 202 if err != nil { 203 continue 204 } 205 if ret != tc.largest { 206 t.Errorf("#%d: expected largest=%d, got %d", tcNum, tc.largest, ret) 207 } 208 } 209 } 210 211 func TestStaticSplits(t *testing.T) { 212 defer leaktest.AfterTest(t)() 213 214 splits := config.StaticSplits() 215 for i := 1; i < len(splits); i++ { 216 if !splits[i-1].Less(splits[i]) { 217 t.Errorf("previous split %q should be less than next split %q", splits[i-1], splits[i]) 218 } 219 } 220 } 221 222 // TestComputeSplitKeyTableIDs tests ComputeSplitKey for cases where the split 223 // is within the system ranges. Other cases are tested below by 224 // TestComputeSplitKeyTableIDs. 225 func TestComputeSplitKeySystemRanges(t *testing.T) { 226 defer leaktest.AfterTest(t)() 227 228 testCases := []struct { 229 start, end roachpb.RKey 230 split roachpb.Key 231 }{ 232 {roachpb.RKeyMin, roachpb.RKeyMax, keys.NodeLivenessPrefix}, 233 {roachpb.RKeyMin, tkey(1), keys.NodeLivenessPrefix}, 234 {roachpb.RKeyMin, roachpb.RKey(keys.TimeseriesPrefix), keys.NodeLivenessPrefix}, 235 {roachpb.RKeyMin, roachpb.RKey(keys.SystemPrefix.Next()), nil}, 236 {roachpb.RKeyMin, roachpb.RKey(keys.SystemPrefix), nil}, 237 {roachpb.RKeyMin, roachpb.RKey(keys.MetaMax), nil}, 238 {roachpb.RKeyMin, roachpb.RKey(keys.Meta2KeyMax), nil}, 239 {roachpb.RKeyMin, roachpb.RKey(keys.Meta1KeyMax), nil}, 240 {roachpb.RKey(keys.Meta1KeyMax), roachpb.RKey(keys.SystemPrefix), nil}, 241 {roachpb.RKey(keys.Meta1KeyMax), roachpb.RKey(keys.SystemPrefix.Next()), nil}, 242 {roachpb.RKey(keys.Meta1KeyMax), roachpb.RKey(keys.NodeLivenessPrefix), nil}, 243 {roachpb.RKey(keys.Meta1KeyMax), roachpb.RKey(keys.NodeLivenessPrefix.Next()), keys.NodeLivenessPrefix}, 244 {roachpb.RKey(keys.Meta1KeyMax), roachpb.RKeyMax, keys.NodeLivenessPrefix}, 245 {roachpb.RKey(keys.SystemPrefix), roachpb.RKey(keys.SystemPrefix), nil}, 246 {roachpb.RKey(keys.SystemPrefix), roachpb.RKey(keys.SystemPrefix.Next()), nil}, 247 {roachpb.RKey(keys.SystemPrefix), roachpb.RKeyMax, keys.NodeLivenessPrefix}, 248 {roachpb.RKey(keys.NodeLivenessPrefix), roachpb.RKey(keys.NodeLivenessPrefix.Next()), nil}, 249 {roachpb.RKey(keys.NodeLivenessPrefix), roachpb.RKey(keys.NodeLivenessKeyMax), nil}, 250 {roachpb.RKey(keys.NodeLivenessPrefix), roachpb.RKeyMax, keys.NodeLivenessKeyMax}, 251 {roachpb.RKey(keys.NodeLivenessKeyMax), roachpb.RKeyMax, keys.TimeseriesPrefix}, 252 {roachpb.RKey(keys.MigrationPrefix), roachpb.RKey(keys.NodeLivenessPrefix), nil}, 253 {roachpb.RKey(keys.MigrationPrefix), roachpb.RKey(keys.NodeLivenessKeyMax), nil}, 254 {roachpb.RKey(keys.MigrationPrefix), roachpb.RKey(keys.StoreIDGenerator), nil}, 255 {roachpb.RKey(keys.MigrationPrefix), roachpb.RKey(keys.TimeseriesPrefix), nil}, 256 {roachpb.RKey(keys.MigrationPrefix), roachpb.RKey(keys.TimeseriesPrefix.Next()), keys.TimeseriesPrefix}, 257 {roachpb.RKey(keys.MigrationPrefix), roachpb.RKeyMax, keys.TimeseriesPrefix}, 258 {roachpb.RKey(keys.TimeseriesPrefix), roachpb.RKey(keys.TimeseriesPrefix.Next()), nil}, 259 {roachpb.RKey(keys.TimeseriesPrefix), roachpb.RKey(keys.TimeseriesPrefix.PrefixEnd()), nil}, 260 {roachpb.RKey(keys.TimeseriesPrefix), roachpb.RKeyMax, keys.TimeseriesPrefix.PrefixEnd()}, 261 {roachpb.RKey(keys.TimeseriesPrefix.PrefixEnd()), roachpb.RKey(keys.TimeseriesPrefix.PrefixEnd()), nil}, 262 {roachpb.RKey(keys.TimeseriesPrefix.PrefixEnd()), roachpb.RKeyMax, keys.SystemConfigSplitKey}, 263 } 264 265 cfg := config.NewSystemConfig(zonepb.DefaultZoneConfigRef()) 266 kvs, _ /* splits */ := sqlbase.MakeMetadataSchema( 267 keys.SystemSQLCodec, cfg.DefaultZoneConfig, zonepb.DefaultSystemZoneConfigRef(), 268 ).GetInitialValues() 269 cfg.SystemConfigEntries = config.SystemConfigEntries{ 270 Values: kvs, 271 } 272 for tcNum, tc := range testCases { 273 splitKey := cfg.ComputeSplitKey(tc.start, tc.end) 274 expected := roachpb.RKey(tc.split) 275 if !splitKey.Equal(expected) { 276 t.Errorf("#%d: bad split:\ngot: %v\nexpected: %v", tcNum, splitKey, expected) 277 } 278 } 279 } 280 281 // TestComputeSplitKeyTableIDs tests ComputeSplitKey for cases where the split 282 // is at the start of a SQL table. Other cases are tested above by 283 // TestComputeSplitKeySystemRanges. 284 func TestComputeSplitKeyTableIDs(t *testing.T) { 285 defer leaktest.AfterTest(t)() 286 287 const ( 288 start = keys.MinUserDescID 289 reservedStart = keys.MaxSystemConfigDescID + 1 290 ) 291 292 // Used in place of roachpb.RKeyMin in order to test the behavior of splits 293 // at the start of the system config and user tables rather than within the 294 // system ranges that come earlier in the keyspace. Those splits are tested 295 // separately above. 296 minKey := roachpb.RKey(keys.TimeseriesPrefix.PrefixEnd()) 297 298 schema := sqlbase.MakeMetadataSchema( 299 keys.SystemSQLCodec, zonepb.DefaultZoneConfigRef(), zonepb.DefaultSystemZoneConfigRef(), 300 ) 301 // Real system tables only. 302 baseSql, _ /* splits */ := schema.GetInitialValues() 303 // Real system tables plus some user stuff. 304 kvs, _ /* splits */ := schema.GetInitialValues() 305 userSQL := append(kvs, descriptor(start), descriptor(start+1), descriptor(start+5)) 306 // Real system tables and partitioned user tables. 307 var subzoneSQL = make([]roachpb.KeyValue, len(userSQL)) 308 copy(subzoneSQL, userSQL) 309 subzoneSQL = append(subzoneSQL, 310 zoneConfig(start+1, subzone("a", ""), subzone("c", "e")), 311 zoneConfig(start+5, subzone("b", ""), subzone("c", "d"), subzone("d", ""))) 312 313 sort.Sort(roachpb.KeyValueByKey(userSQL)) 314 sort.Sort(roachpb.KeyValueByKey(subzoneSQL)) 315 316 testCases := []struct { 317 values []roachpb.KeyValue 318 start, end roachpb.RKey 319 split roachpb.RKey // nil to indicate no split is expected 320 }{ 321 // No data. 322 {nil, minKey, roachpb.RKeyMax, tkey(0)}, 323 {nil, tkey(start), roachpb.RKeyMax, nil}, 324 {nil, tkey(start), tkey(start + 10), nil}, 325 {nil, minKey, tkey(start + 10), tkey(0)}, 326 327 // Reserved descriptors. 328 {baseSql, minKey, roachpb.RKeyMax, tkey(0)}, 329 {baseSql, tkey(start), roachpb.RKeyMax, nil}, 330 {baseSql, tkey(start), tkey(start + 10), nil}, 331 {baseSql, minKey, tkey(start + 10), tkey(0)}, 332 {baseSql, tkey(reservedStart), roachpb.RKeyMax, tkey(reservedStart + 1)}, 333 {baseSql, tkey(reservedStart), tkey(start + 10), tkey(reservedStart + 1)}, 334 {baseSql, minKey, tkey(reservedStart + 2), tkey(0)}, 335 {baseSql, minKey, tkey(reservedStart + 10), tkey(0)}, 336 {baseSql, tkey(reservedStart), tkey(reservedStart + 2), tkey(reservedStart + 1)}, 337 {baseSql, tkey(reservedStart, "foo"), tkey(start+10, "foo"), tkey(reservedStart + 1)}, 338 339 // Reserved + User descriptors. 340 {userSQL, tkey(start - 1), roachpb.RKeyMax, tkey(start)}, 341 {userSQL, tkey(start), roachpb.RKeyMax, tkey(start + 1)}, 342 {userSQL, tkey(start), tkey(start + 10), tkey(start + 1)}, 343 {userSQL, tkey(start - 1), tkey(start + 10), tkey(start)}, 344 {userSQL, tkey(start + 4), tkey(start + 10), tkey(start + 5)}, 345 {userSQL, tkey(start + 5), tkey(start + 10), nil}, 346 {userSQL, tkey(start + 6), tkey(start + 10), nil}, 347 {userSQL, tkey(start, "foo"), tkey(start + 10), tkey(start + 1)}, 348 {userSQL, tkey(start, "foo"), tkey(start + 5), tkey(start + 1)}, 349 {userSQL, tkey(start, "foo"), tkey(start+5, "bar"), tkey(start + 1)}, 350 {userSQL, tkey(start, "foo"), tkey(start, "morefoo"), nil}, 351 {userSQL, minKey, roachpb.RKeyMax, tkey(0)}, 352 {userSQL, tkey(reservedStart + 1), roachpb.RKeyMax, tkey(reservedStart + 2)}, 353 {userSQL, tkey(reservedStart), tkey(start + 10), tkey(reservedStart + 1)}, 354 {userSQL, minKey, tkey(start + 2), tkey(0)}, 355 {userSQL, tkey(reservedStart, "foo"), tkey(start+5, "foo"), tkey(reservedStart + 1)}, 356 357 // Partitioned user descriptors. 358 {subzoneSQL, tkey(start), roachpb.RKeyMax, tkey(start + 1)}, 359 {subzoneSQL, tkey(start), tkey(start + 1), nil}, 360 {subzoneSQL, tkey(start + 1), tkey(start + 2), tkey(start+1, "a")}, 361 {subzoneSQL, tkey(start+1, "a"), tkey(start + 2), tkey(start+1, "b")}, 362 {subzoneSQL, tkey(start+1, "b"), tkey(start + 2), tkey(start+1, "c")}, 363 {subzoneSQL, tkey(start+1, "b"), tkey(start+1, "c"), nil}, 364 {subzoneSQL, tkey(start+1, "ba"), tkey(start+1, "bb"), nil}, 365 {subzoneSQL, tkey(start+1, "c"), tkey(start + 2), tkey(start+1, "e")}, 366 {subzoneSQL, tkey(start+1, "e"), tkey(start + 2), nil}, 367 {subzoneSQL, tkey(start + 4), tkey(start + 6), tkey(start + 5)}, 368 {subzoneSQL, tkey(start + 5), tkey(start + 5), nil}, 369 {subzoneSQL, tkey(start + 5), tkey(start + 6), tkey(start+5, "b")}, 370 {subzoneSQL, tkey(start+5, "a"), tkey(start+5, "ae"), nil}, 371 {subzoneSQL, tkey(start+5, "b"), tkey(start + 6), tkey(start+5, "c")}, 372 {subzoneSQL, tkey(start+5, "c"), tkey(start + 6), tkey(start+5, "d")}, 373 {subzoneSQL, tkey(start+5, "d"), tkey(start + 6), tkey(start+5, "e")}, 374 {subzoneSQL, tkey(start+5, "e"), tkey(start + 6), nil}, 375 376 // Testing that no splits are required for IDs that 377 // that do not map to descriptors. 378 {userSQL, tkey(start + 1), tkey(start + 5), nil}, 379 } 380 381 cfg := config.NewSystemConfig(zonepb.DefaultZoneConfigRef()) 382 for tcNum, tc := range testCases { 383 cfg.Values = tc.values 384 splitKey := cfg.ComputeSplitKey(tc.start, tc.end) 385 if !splitKey.Equal(tc.split) { 386 t.Errorf("#%d: bad split:\ngot: %v\nexpected: %v", tcNum, splitKey, tc.split) 387 } 388 } 389 } 390 391 func TestGetZoneConfigForKey(t *testing.T) { 392 defer leaktest.AfterTest(t)() 393 394 testCases := []struct { 395 key roachpb.RKey 396 expectedID uint32 397 }{ 398 {roachpb.RKeyMin, keys.MetaRangesID}, 399 {roachpb.RKey(keys.Meta1Prefix), keys.MetaRangesID}, 400 {roachpb.RKey(keys.Meta1Prefix.Next()), keys.MetaRangesID}, 401 {roachpb.RKey(keys.Meta2Prefix), keys.MetaRangesID}, 402 {roachpb.RKey(keys.Meta2Prefix.Next()), keys.MetaRangesID}, 403 {roachpb.RKey(keys.MetaMax), keys.SystemRangesID}, 404 {roachpb.RKey(keys.SystemPrefix), keys.SystemRangesID}, 405 {roachpb.RKey(keys.SystemPrefix.Next()), keys.SystemRangesID}, 406 {roachpb.RKey(keys.MigrationLease), keys.SystemRangesID}, 407 {roachpb.RKey(keys.NodeLivenessPrefix), keys.LivenessRangesID}, 408 {roachpb.RKey(keys.SystemSQLCodec.DescIDSequenceKey()), keys.SystemRangesID}, 409 {roachpb.RKey(keys.NodeIDGenerator), keys.SystemRangesID}, 410 {roachpb.RKey(keys.RangeIDGenerator), keys.SystemRangesID}, 411 {roachpb.RKey(keys.StoreIDGenerator), keys.SystemRangesID}, 412 {roachpb.RKey(keys.StatusPrefix), keys.SystemRangesID}, 413 {roachpb.RKey(keys.TimeseriesPrefix), keys.TimeseriesRangesID}, 414 {roachpb.RKey(keys.TimeseriesPrefix.Next()), keys.TimeseriesRangesID}, 415 {roachpb.RKey(keys.TimeseriesPrefix.PrefixEnd()), keys.SystemRangesID}, 416 {roachpb.RKey(keys.TableDataMin), keys.SystemDatabaseID}, 417 {roachpb.RKey(keys.SystemConfigSplitKey), keys.SystemDatabaseID}, 418 419 // Gossiped system tables should refer to the SystemDatabaseID. 420 {tkey(keys.ZonesTableID), keys.SystemDatabaseID}, 421 422 // Non-gossiped system tables should refer to themselves. 423 {tkey(keys.LeaseTableID), keys.LeaseTableID}, 424 {tkey(keys.JobsTableID), keys.JobsTableID}, 425 {tkey(keys.LocationsTableID), keys.LocationsTableID}, 426 {tkey(keys.NamespaceTableID), keys.NamespaceTableID}, 427 428 // Pseudo-tables should refer to the SystemDatabaseID. 429 {tkey(keys.MetaRangesID), keys.SystemDatabaseID}, 430 {tkey(keys.SystemRangesID), keys.SystemDatabaseID}, 431 {tkey(keys.TimeseriesRangesID), keys.SystemDatabaseID}, 432 {tkey(keys.LivenessRangesID), keys.SystemDatabaseID}, 433 434 // User tables should refer to themselves. 435 {tkey(keys.MinUserDescID), keys.MinUserDescID}, 436 {tkey(keys.MinUserDescID + 22), keys.MinUserDescID + 22}, 437 {roachpb.RKeyMax, keys.RootNamespaceID}, 438 } 439 440 originalZoneConfigHook := config.ZoneConfigHook 441 defer func() { 442 config.ZoneConfigHook = originalZoneConfigHook 443 }() 444 cfg := config.NewSystemConfig(zonepb.DefaultZoneConfigRef()) 445 446 kvs, _ /* splits */ := sqlbase.MakeMetadataSchema( 447 keys.SystemSQLCodec, cfg.DefaultZoneConfig, zonepb.DefaultSystemZoneConfigRef(), 448 ).GetInitialValues() 449 cfg.SystemConfigEntries = config.SystemConfigEntries{ 450 Values: kvs, 451 } 452 for tcNum, tc := range testCases { 453 var objectID uint32 454 config.ZoneConfigHook = func( 455 _ *config.SystemConfig, id uint32, 456 ) (*zonepb.ZoneConfig, *zonepb.ZoneConfig, bool, error) { 457 objectID = id 458 return &zonepb.ZoneConfig{}, nil, false, nil 459 } 460 _, err := cfg.GetZoneConfigForKey(tc.key) 461 if err != nil { 462 t.Errorf("#%d: GetZoneConfigForKey(%v) got error: %v", tcNum, tc.key, err) 463 } 464 if objectID != tc.expectedID { 465 t.Errorf("#%d: GetZoneConfigForKey(%v) got %d; want %d", tcNum, tc.key, objectID, tc.expectedID) 466 } 467 } 468 }