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

     1  // Copyright 2014 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 keys_test
    12  
    13  import (
    14  	"bytes"
    15  	"encoding/hex"
    16  	"fmt"
    17  	"math"
    18  	"testing"
    19  	"time"
    20  
    21  	"github.com/cockroachdb/apd"
    22  	"github.com/cockroachdb/cockroach/pkg/keys"
    23  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    24  	"github.com/cockroachdb/cockroach/pkg/util/bitarray"
    25  	"github.com/cockroachdb/cockroach/pkg/util/duration"
    26  	"github.com/cockroachdb/cockroach/pkg/util/encoding"
    27  	"github.com/cockroachdb/cockroach/pkg/util/keysutil"
    28  	"github.com/cockroachdb/cockroach/pkg/util/uuid"
    29  	"github.com/cockroachdb/errors"
    30  )
    31  
    32  func TestPrettyPrint(t *testing.T) {
    33  	tenSysCodec := keys.SystemSQLCodec
    34  	ten5Codec := keys.MakeSQLCodec(roachpb.MakeTenantID(5))
    35  	tm, _ := time.Parse(time.RFC3339Nano, "2016-03-30T13:40:35.053725008Z")
    36  	duration := duration.MakeDuration(1*time.Second.Nanoseconds(), 1, 1)
    37  	durationAsc, _ := encoding.EncodeDurationAscending(nil, duration)
    38  	durationDesc, _ := encoding.EncodeDurationDescending(nil, duration)
    39  	bitArray := bitarray.MakeBitArrayFromInt64(8, 58, 7)
    40  	txnID := uuid.MakeV4()
    41  
    42  	// Support for asserting that the ugly printer supports a key was added after
    43  	// most of the tests here were written.
    44  	revertSupportUnknown := false
    45  	revertMustSupport := true
    46  
    47  	// The following test cases encode keys with a mixture of ascending and descending direction,
    48  	// but always decode keys in the ascending direction. This is why some of the decoded values
    49  	// seem bizarre.
    50  	testCases := []struct {
    51  		key                   roachpb.Key
    52  		exp                   string
    53  		assertRevertSupported bool
    54  	}{
    55  		// local
    56  		{keys.StoreIdentKey(), "/Local/Store/storeIdent", revertSupportUnknown},
    57  		{keys.StoreGossipKey(), "/Local/Store/gossipBootstrap", revertSupportUnknown},
    58  		{keys.StoreClusterVersionKey(), "/Local/Store/clusterVersion", revertSupportUnknown},
    59  		{keys.StoreSuggestedCompactionKey(keys.MinKey, roachpb.Key("b")), `/Local/Store/suggestedCompaction/{/Min-"b"}`, revertSupportUnknown},
    60  		{keys.StoreSuggestedCompactionKey(roachpb.Key("a"), roachpb.Key("b")), `/Local/Store/suggestedCompaction/{"a"-"b"}`, revertSupportUnknown},
    61  		{keys.StoreSuggestedCompactionKey(roachpb.Key("a"), keys.MaxKey), `/Local/Store/suggestedCompaction/{"a"-/Max}`, revertSupportUnknown},
    62  
    63  		{keys.AbortSpanKey(roachpb.RangeID(1000001), txnID), fmt.Sprintf(`/Local/RangeID/1000001/r/AbortSpan/%q`, txnID), revertSupportUnknown},
    64  		{keys.RangeAppliedStateKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RangeAppliedState", revertSupportUnknown},
    65  		{keys.RaftAppliedIndexLegacyKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RaftAppliedIndex", revertSupportUnknown},
    66  		{keys.LeaseAppliedIndexLegacyKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/LeaseAppliedIndex", revertSupportUnknown},
    67  		{keys.RaftTruncatedStateLegacyKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RaftTruncatedState", revertSupportUnknown},
    68  		{keys.RaftTruncatedStateKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/u/RaftTruncatedState", revertSupportUnknown},
    69  		{keys.RangeLeaseKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RangeLease", revertSupportUnknown},
    70  		{keys.RangeStatsLegacyKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RangeStats", revertSupportUnknown},
    71  		{keys.RangeLastGCKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/r/RangeLastGC", revertSupportUnknown},
    72  
    73  		{keys.RaftHardStateKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/u/RaftHardState", revertSupportUnknown},
    74  		{keys.RangeTombstoneKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/u/RangeTombstone", revertSupportUnknown},
    75  		{keys.RaftLogKey(roachpb.RangeID(1000001), uint64(200001)), "/Local/RangeID/1000001/u/RaftLog/logIndex:200001", revertSupportUnknown},
    76  		{keys.RangeLastReplicaGCTimestampKey(roachpb.RangeID(1000001)), "/Local/RangeID/1000001/u/RangeLastReplicaGCTimestamp", revertSupportUnknown},
    77  
    78  		{keys.MakeRangeKeyPrefix(roachpb.RKey(tenSysCodec.TablePrefix(42))), `/Local/Range/Table/42`, revertSupportUnknown},
    79  		{keys.RangeDescriptorKey(roachpb.RKey(tenSysCodec.TablePrefix(42))), `/Local/Range/Table/42/RangeDescriptor`, revertSupportUnknown},
    80  		{keys.TransactionKey(tenSysCodec.TablePrefix(42), txnID), fmt.Sprintf(`/Local/Range/Table/42/Transaction/%q`, txnID), revertSupportUnknown},
    81  		{keys.QueueLastProcessedKey(roachpb.RKey(tenSysCodec.TablePrefix(42)), "foo"), `/Local/Range/Table/42/QueueLastProcessed/"foo"`, revertSupportUnknown},
    82  
    83  		{keys.MakeRangeKeyPrefix(roachpb.RKey(ten5Codec.TenantPrefix())), `/Local/Range/Tenant/5`, revertSupportUnknown},
    84  		{keys.MakeRangeKeyPrefix(roachpb.RKey(ten5Codec.TablePrefix(42))), `/Local/Range/Tenant/5/Table/42`, revertSupportUnknown},
    85  		{keys.RangeDescriptorKey(roachpb.RKey(ten5Codec.TablePrefix(42))), `/Local/Range/Tenant/5/Table/42/RangeDescriptor`, revertSupportUnknown},
    86  		{keys.TransactionKey(ten5Codec.TablePrefix(42), txnID), fmt.Sprintf(`/Local/Range/Tenant/5/Table/42/Transaction/%q`, txnID), revertSupportUnknown},
    87  		{keys.QueueLastProcessedKey(roachpb.RKey(ten5Codec.TablePrefix(42)), "foo"), `/Local/Range/Tenant/5/Table/42/QueueLastProcessed/"foo"`, revertSupportUnknown},
    88  
    89  		{keys.LocalMax, `/Meta1/""`, revertSupportUnknown}, // LocalMax == Meta1Prefix
    90  
    91  		// system
    92  		{makeKey(keys.Meta2Prefix, roachpb.Key("foo")), `/Meta2/"foo"`, revertSupportUnknown},
    93  		{makeKey(keys.Meta1Prefix, roachpb.Key("foo")), `/Meta1/"foo"`, revertSupportUnknown},
    94  		{keys.RangeMetaKey(roachpb.RKey("f")).AsRawKey(), `/Meta2/"f"`, revertSupportUnknown},
    95  
    96  		{keys.NodeLivenessKey(10033), "/System/NodeLiveness/10033", revertSupportUnknown},
    97  		{keys.NodeStatusKey(1111), "/System/StatusNode/1111", revertSupportUnknown},
    98  
    99  		{keys.SystemMax, "/System/Max", revertSupportUnknown},
   100  
   101  		// key of key
   102  		{keys.RangeMetaKey(roachpb.RKey(keys.MakeRangeKeyPrefix(roachpb.RKey(tenSysCodec.TablePrefix(42))))).AsRawKey(), `/Meta2/Local/Range/Table/42`, revertSupportUnknown},
   103  		{keys.RangeMetaKey(roachpb.RKey(makeKey(tenSysCodec.TablePrefix(42), roachpb.RKey("foo")))).AsRawKey(), `/Meta2/Table/42/"foo"`, revertSupportUnknown},
   104  		{keys.RangeMetaKey(roachpb.RKey(makeKey(keys.Meta2Prefix, roachpb.Key("foo")))).AsRawKey(), `/Meta1/"foo"`, revertSupportUnknown},
   105  
   106  		// table
   107  		{keys.SystemConfigSpan.Key, "/Table/SystemConfigSpan/Start", revertSupportUnknown},
   108  		{keys.UserTableDataMin, "/Table/50", revertMustSupport},
   109  		{tenSysCodec.TablePrefix(111), "/Table/111", revertMustSupport},
   110  		{makeKey(tenSysCodec.TablePrefix(42), encoding.EncodeUvarintAscending(nil, 1)), `/Table/42/1`, revertMustSupport},
   111  		{makeKey(tenSysCodec.TablePrefix(42), roachpb.RKey("foo")), `/Table/42/"foo"`, revertSupportUnknown},
   112  		{makeKey(tenSysCodec.TablePrefix(42),
   113  			roachpb.RKey(encoding.EncodeFloatAscending(nil, float64(233.221112)))),
   114  			"/Table/42/233.221112", revertSupportUnknown},
   115  		{makeKey(tenSysCodec.TablePrefix(42),
   116  			roachpb.RKey(encoding.EncodeFloatDescending(nil, float64(-233.221112)))),
   117  			"/Table/42/233.221112", revertSupportUnknown},
   118  		{makeKey(tenSysCodec.TablePrefix(42),
   119  			roachpb.RKey(encoding.EncodeFloatAscending(nil, math.Inf(1)))),
   120  			"/Table/42/+Inf", revertSupportUnknown},
   121  		{makeKey(tenSysCodec.TablePrefix(42),
   122  			roachpb.RKey(encoding.EncodeFloatAscending(nil, math.NaN()))),
   123  			"/Table/42/NaN", revertSupportUnknown},
   124  		{makeKey(tenSysCodec.TablePrefix(42),
   125  			roachpb.RKey(encoding.EncodeVarintAscending(nil, 1222)),
   126  			roachpb.RKey(encoding.EncodeStringAscending(nil, "handsome man"))),
   127  			`/Table/42/1222/"handsome man"`, revertSupportUnknown},
   128  		{makeKey(tenSysCodec.TablePrefix(42),
   129  			roachpb.RKey(encoding.EncodeVarintAscending(nil, 1222))),
   130  			`/Table/42/1222`, revertSupportUnknown},
   131  		{makeKey(tenSysCodec.TablePrefix(42),
   132  			roachpb.RKey(encoding.EncodeVarintDescending(nil, 1222))),
   133  			`/Table/42/-1223`, revertSupportUnknown},
   134  		{makeKey(tenSysCodec.TablePrefix(42),
   135  			roachpb.RKey(encoding.EncodeBytesAscending(nil, []byte{1, 2, 8, 255}))),
   136  			`/Table/42/"\x01\x02\b\xff"`, revertSupportUnknown},
   137  		{makeKey(tenSysCodec.TablePrefix(42),
   138  			roachpb.RKey(encoding.EncodeBytesAscending(nil, []byte{1, 2, 8, 255})),
   139  			roachpb.RKey("bar")), `/Table/42/"\x01\x02\b\xff"/"bar"`, revertSupportUnknown},
   140  		{makeKey(tenSysCodec.TablePrefix(42),
   141  			roachpb.RKey(encoding.EncodeBytesDescending(nil, []byte{1, 2, 8, 255})),
   142  			roachpb.RKey("bar")), `/Table/42/"\x01\x02\b\xff"/"bar"`, revertSupportUnknown},
   143  		{makeKey(tenSysCodec.TablePrefix(42),
   144  			roachpb.RKey(encoding.EncodeNullAscending(nil))), "/Table/42/NULL", revertSupportUnknown},
   145  		{makeKey(tenSysCodec.TablePrefix(42),
   146  			roachpb.RKey(encoding.EncodeNullDescending(nil))), "/Table/42/NULL", revertSupportUnknown},
   147  		{makeKey(tenSysCodec.TablePrefix(42),
   148  			roachpb.RKey(encoding.EncodeNotNullAscending(nil))), "/Table/42/!NULL", revertSupportUnknown},
   149  		{makeKey(tenSysCodec.TablePrefix(42),
   150  			roachpb.RKey(encoding.EncodeNotNullDescending(nil))), "/Table/42/#", revertSupportUnknown},
   151  		{makeKey(tenSysCodec.TablePrefix(42),
   152  			roachpb.RKey(encoding.EncodeTimeAscending(nil, tm))),
   153  			"/Table/42/2016-03-30T13:40:35.053725008Z", revertSupportUnknown},
   154  		{makeKey(tenSysCodec.TablePrefix(42),
   155  			roachpb.RKey(encoding.EncodeTimeDescending(nil, tm))),
   156  			"/Table/42/1923-10-04T10:19:23.946274991Z", revertSupportUnknown},
   157  		{makeKey(tenSysCodec.TablePrefix(42),
   158  			roachpb.RKey(encoding.EncodeDecimalAscending(nil, apd.New(1234, -2)))),
   159  			"/Table/42/12.34", revertSupportUnknown},
   160  		{makeKey(tenSysCodec.TablePrefix(42),
   161  			roachpb.RKey(encoding.EncodeDecimalDescending(nil, apd.New(1234, -2)))),
   162  			"/Table/42/-12.34", revertSupportUnknown},
   163  		{makeKey(tenSysCodec.TablePrefix(42),
   164  			roachpb.RKey(encoding.EncodeBitArrayAscending(nil, bitArray))),
   165  			"/Table/42/B00111010", revertSupportUnknown},
   166  		{makeKey(tenSysCodec.TablePrefix(42),
   167  			roachpb.RKey(encoding.EncodeBitArrayDescending(nil, bitArray))),
   168  			"/Table/42/B00111010", revertSupportUnknown},
   169  		// Regression test for #31115.
   170  		{roachpb.Key(makeKey(tenSysCodec.TablePrefix(42),
   171  			roachpb.RKey(encoding.EncodeBitArrayAscending(nil, bitarray.MakeZeroBitArray(64))),
   172  		)).PrefixEnd(),
   173  			"/Table/42/B0000000000000000000000000000000000000000000000000000000000000000/PrefixEnd", revertSupportUnknown},
   174  		{makeKey(tenSysCodec.TablePrefix(42),
   175  			roachpb.RKey(durationAsc)),
   176  			"/Table/42/1 mon 1 day 00:00:01", revertSupportUnknown},
   177  		{makeKey(tenSysCodec.TablePrefix(42),
   178  			roachpb.RKey(durationDesc)),
   179  			"/Table/42/-2 mons -2 days +743:59:58.999999+999ns", revertSupportUnknown},
   180  		// sequence
   181  		{tenSysCodec.SequenceKey(55), `/Table/55/1/0/0`, revertSupportUnknown},
   182  
   183  		// tenant table
   184  		{ten5Codec.TenantPrefix(), "/Tenant/5", revertMustSupport},
   185  		{ten5Codec.TablePrefix(0), "/Tenant/5/Table/SystemConfigSpan/Start", revertSupportUnknown},
   186  		{ten5Codec.TablePrefix(keys.MinUserDescID), "/Tenant/5/Table/50", revertMustSupport},
   187  		{ten5Codec.TablePrefix(111), "/Tenant/5/Table/111", revertMustSupport},
   188  		{makeKey(ten5Codec.TablePrefix(42), encoding.EncodeUvarintAscending(nil, 1)), `/Tenant/5/Table/42/1`, revertMustSupport},
   189  		{makeKey(ten5Codec.TablePrefix(42), roachpb.RKey("foo")), `/Tenant/5/Table/42/"foo"`, revertSupportUnknown},
   190  		{makeKey(ten5Codec.TablePrefix(42),
   191  			roachpb.RKey(encoding.EncodeFloatAscending(nil, float64(233.221112)))),
   192  			"/Tenant/5/Table/42/233.221112", revertSupportUnknown},
   193  		{makeKey(ten5Codec.TablePrefix(42),
   194  			roachpb.RKey(encoding.EncodeFloatDescending(nil, float64(-233.221112)))),
   195  			"/Tenant/5/Table/42/233.221112", revertSupportUnknown},
   196  		{makeKey(ten5Codec.TablePrefix(42),
   197  			roachpb.RKey(encoding.EncodeFloatAscending(nil, math.Inf(1)))),
   198  			"/Tenant/5/Table/42/+Inf", revertSupportUnknown},
   199  		{makeKey(ten5Codec.TablePrefix(42),
   200  			roachpb.RKey(encoding.EncodeFloatAscending(nil, math.NaN()))),
   201  			"/Tenant/5/Table/42/NaN", revertSupportUnknown},
   202  		{makeKey(ten5Codec.TablePrefix(42),
   203  			roachpb.RKey(encoding.EncodeVarintAscending(nil, 1222)),
   204  			roachpb.RKey(encoding.EncodeStringAscending(nil, "handsome man"))),
   205  			`/Tenant/5/Table/42/1222/"handsome man"`, revertSupportUnknown},
   206  		{makeKey(ten5Codec.TablePrefix(42),
   207  			roachpb.RKey(encoding.EncodeVarintAscending(nil, 1222))),
   208  			`/Tenant/5/Table/42/1222`, revertSupportUnknown},
   209  		{makeKey(ten5Codec.TablePrefix(42),
   210  			roachpb.RKey(encoding.EncodeVarintDescending(nil, 1222))),
   211  			`/Tenant/5/Table/42/-1223`, revertSupportUnknown},
   212  		{makeKey(ten5Codec.TablePrefix(42),
   213  			roachpb.RKey(encoding.EncodeBytesAscending(nil, []byte{1, 2, 8, 255}))),
   214  			`/Tenant/5/Table/42/"\x01\x02\b\xff"`, revertSupportUnknown},
   215  		{makeKey(ten5Codec.TablePrefix(42),
   216  			roachpb.RKey(encoding.EncodeBytesAscending(nil, []byte{1, 2, 8, 255})),
   217  			roachpb.RKey("bar")), `/Tenant/5/Table/42/"\x01\x02\b\xff"/"bar"`, revertSupportUnknown},
   218  		{makeKey(ten5Codec.TablePrefix(42),
   219  			roachpb.RKey(encoding.EncodeBytesDescending(nil, []byte{1, 2, 8, 255})),
   220  			roachpb.RKey("bar")), `/Tenant/5/Table/42/"\x01\x02\b\xff"/"bar"`, revertSupportUnknown},
   221  		{makeKey(ten5Codec.TablePrefix(42),
   222  			roachpb.RKey(encoding.EncodeNullAscending(nil))), "/Tenant/5/Table/42/NULL", revertSupportUnknown},
   223  		{makeKey(ten5Codec.TablePrefix(42),
   224  			roachpb.RKey(encoding.EncodeNullDescending(nil))), "/Tenant/5/Table/42/NULL", revertSupportUnknown},
   225  		{makeKey(ten5Codec.TablePrefix(42),
   226  			roachpb.RKey(encoding.EncodeNotNullAscending(nil))), "/Tenant/5/Table/42/!NULL", revertSupportUnknown},
   227  		{makeKey(ten5Codec.TablePrefix(42),
   228  			roachpb.RKey(encoding.EncodeNotNullDescending(nil))), "/Tenant/5/Table/42/#", revertSupportUnknown},
   229  		{makeKey(ten5Codec.TablePrefix(42),
   230  			roachpb.RKey(encoding.EncodeTimeAscending(nil, tm))),
   231  			"/Tenant/5/Table/42/2016-03-30T13:40:35.053725008Z", revertSupportUnknown},
   232  		{makeKey(ten5Codec.TablePrefix(42),
   233  			roachpb.RKey(encoding.EncodeTimeDescending(nil, tm))),
   234  			"/Tenant/5/Table/42/1923-10-04T10:19:23.946274991Z", revertSupportUnknown},
   235  		{makeKey(ten5Codec.TablePrefix(42),
   236  			roachpb.RKey(encoding.EncodeDecimalAscending(nil, apd.New(1234, -2)))),
   237  			"/Tenant/5/Table/42/12.34", revertSupportUnknown},
   238  		{makeKey(ten5Codec.TablePrefix(42),
   239  			roachpb.RKey(encoding.EncodeDecimalDescending(nil, apd.New(1234, -2)))),
   240  			"/Tenant/5/Table/42/-12.34", revertSupportUnknown},
   241  		{makeKey(ten5Codec.TablePrefix(42),
   242  			roachpb.RKey(encoding.EncodeBitArrayAscending(nil, bitArray))),
   243  			"/Tenant/5/Table/42/B00111010", revertSupportUnknown},
   244  		{makeKey(ten5Codec.TablePrefix(42),
   245  			roachpb.RKey(encoding.EncodeBitArrayDescending(nil, bitArray))),
   246  			"/Tenant/5/Table/42/B00111010", revertSupportUnknown},
   247  		// Regression test for #31115.
   248  		{roachpb.Key(makeKey(ten5Codec.TablePrefix(42),
   249  			roachpb.RKey(encoding.EncodeBitArrayAscending(nil, bitarray.MakeZeroBitArray(64))),
   250  		)).PrefixEnd(),
   251  			"/Tenant/5/Table/42/B0000000000000000000000000000000000000000000000000000000000000000/PrefixEnd", revertSupportUnknown},
   252  		{makeKey(ten5Codec.TablePrefix(42),
   253  			roachpb.RKey(durationAsc)),
   254  			"/Tenant/5/Table/42/1 mon 1 day 00:00:01", revertSupportUnknown},
   255  		{makeKey(ten5Codec.TablePrefix(42),
   256  			roachpb.RKey(durationDesc)),
   257  			"/Tenant/5/Table/42/-2 mons -2 days +743:59:58.999999+999ns", revertSupportUnknown},
   258  		// sequence
   259  		{ten5Codec.SequenceKey(55), `/Tenant/5/Table/55/1/0/0`, revertSupportUnknown},
   260  
   261  		// others
   262  		{makeKey([]byte("")), "/Min", revertSupportUnknown},
   263  		{keys.Meta1KeyMax, "/Meta1/Max", revertSupportUnknown},
   264  		{keys.Meta2KeyMax, "/Meta2/Max", revertSupportUnknown},
   265  		{makeKey(tenSysCodec.TablePrefix(42), roachpb.RKey([]byte{0xf6})), `/Table/42/109/PrefixEnd`, revertSupportUnknown},
   266  		{makeKey(tenSysCodec.TablePrefix(42), roachpb.RKey([]byte{0xf7})), `/Table/42/255/PrefixEnd`, revertSupportUnknown},
   267  		{makeKey(tenSysCodec.TablePrefix(42), roachpb.RKey([]byte{0x12, 'a', 0x00, 0x02})), `/Table/42/"a"/PrefixEnd`, revertSupportUnknown},
   268  		{makeKey(tenSysCodec.TablePrefix(42), roachpb.RKey([]byte{0x12, 'a', 0x00, 0x03})), `/Table/42/???`, revertSupportUnknown},
   269  		{makeKey(ten5Codec.TablePrefix(42), roachpb.RKey([]byte{0xf6})), `/Tenant/5/Table/42/109/PrefixEnd`, revertSupportUnknown},
   270  		{makeKey(ten5Codec.TablePrefix(42), roachpb.RKey([]byte{0xf7})), `/Tenant/5/Table/42/255/PrefixEnd`, revertSupportUnknown},
   271  		{makeKey(ten5Codec.TablePrefix(42), roachpb.RKey([]byte{0x12, 'a', 0x00, 0x02})), `/Tenant/5/Table/42/"a"/PrefixEnd`, revertSupportUnknown},
   272  		{makeKey(ten5Codec.TablePrefix(42), roachpb.RKey([]byte{0x12, 'a', 0x00, 0x03})), `/Tenant/5/Table/42/???`, revertSupportUnknown},
   273  	}
   274  	for i, test := range testCases {
   275  		t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
   276  			keyInfo := keys.MassagePrettyPrintedSpanForTest(keys.PrettyPrint(nil, /* valDirs */
   277  				test.key), nil)
   278  			exp := keys.MassagePrettyPrintedSpanForTest(test.exp, nil)
   279  			t.Logf(`---- test case #%d:
   280  input:  %q
   281  output: %s
   282  exp:    %s
   283  `, i+1, []byte(test.key), keyInfo, exp)
   284  			if exp != keyInfo {
   285  				t.Errorf("%d: expected %s, got %s", i, exp, keyInfo)
   286  			}
   287  
   288  			if exp != keys.MassagePrettyPrintedSpanForTest(test.key.String(), nil) {
   289  				t.Errorf("%d: from string expected %s, got %s", i, exp, test.key.String())
   290  			}
   291  
   292  			scanner := keysutil.MakePrettyScanner(nil /* tableParser */)
   293  			parsed, err := scanner.Scan(keyInfo)
   294  			if err != nil {
   295  				if !errors.HasType(err, (*keys.ErrUglifyUnsupported)(nil)) {
   296  					t.Errorf("%d: %s: %s", i, keyInfo, err)
   297  				} else if !test.assertRevertSupported {
   298  					t.Logf("%d: skipping parsing of %s; key is unsupported: %v", i, keyInfo, err)
   299  				} else {
   300  					t.Errorf("%d: ugly print expected unexpectedly unsupported (%s)", i, test.exp)
   301  				}
   302  			} else if exp, act := test.key, parsed; !bytes.Equal(exp, act) {
   303  				t.Errorf("%d: ugly print expected %q, got %q", i, exp, act)
   304  			}
   305  			if t.Failed() {
   306  				return
   307  			}
   308  		})
   309  	}
   310  }
   311  
   312  func TestPrettyPrintRange(t *testing.T) {
   313  	tenSysCodec := keys.SystemSQLCodec
   314  	ten5Codec := keys.MakeSQLCodec(roachpb.MakeTenantID(5))
   315  	key := makeKey([]byte("a"))
   316  	key2 := makeKey([]byte("z"))
   317  	tableKey := makeKey(tenSysCodec.TablePrefix(61), encoding.EncodeVarintAscending(nil, 4))
   318  	tableKey2 := makeKey(tenSysCodec.TablePrefix(61), encoding.EncodeVarintAscending(nil, 500))
   319  	tenTableKey := makeKey(ten5Codec.TablePrefix(61), encoding.EncodeVarintAscending(nil, 999))
   320  
   321  	testCases := []struct {
   322  		start, end roachpb.Key
   323  		maxChars   int
   324  		expected   string
   325  	}{
   326  		{key, nil, 20, "a"},
   327  		{tableKey, nil, 10, "/Table/61…"},
   328  		{tenTableKey, nil, 20, "/Tenant/5/Table/61/…"},
   329  		{key, key2, 20, "{a-z}"},
   330  		{keys.MinKey, tableKey, 8, "/{M…-T…}"},
   331  		{keys.MinKey, tableKey, 15, "/{Min-Tabl…}"},
   332  		{keys.MinKey, tableKey, 20, "/{Min-Table/6…}"},
   333  		{keys.MinKey, tableKey, 25, "/{Min-Table/61/4}"},
   334  		{keys.MinKey, tenTableKey, 8, "/{M…-T…}"},
   335  		{keys.MinKey, tenTableKey, 15, "/{Min-Tena…}"},
   336  		{keys.MinKey, tenTableKey, 20, "/{Min-Tenant/…}"},
   337  		{keys.MinKey, tenTableKey, 25, "/{Min-Tenant/5/…}"},
   338  		{keys.MinKey, tenTableKey, 30, "/{Min-Tenant/5/Tab…}"},
   339  		{tableKey, tableKey2, 8, "/Table/…"},
   340  		{tableKey, tableKey2, 15, "/Table/61/…"},
   341  		{tableKey, tableKey2, 20, "/Table/61/{4-500}"},
   342  		{tableKey, keys.MaxKey, 10, "/{Ta…-Max}"},
   343  		{tableKey, keys.MaxKey, 20, "/{Table/6…-Max}"},
   344  		{tableKey, keys.MaxKey, 25, "/{Table/61/4-Max}"},
   345  		{tenTableKey, keys.MaxKey, 10, "/{Te…-Max}"},
   346  		{tenTableKey, keys.MaxKey, 20, "/{Tenant/…-Max}"},
   347  		{tenTableKey, keys.MaxKey, 25, "/{Tenant/5/…-Max}"},
   348  		{tenTableKey, keys.MaxKey, 30, "/{Tenant/5/Tab…-Max}"},
   349  	}
   350  
   351  	for i, tc := range testCases {
   352  		str := keys.PrettyPrintRange(tc.start, tc.end, tc.maxChars)
   353  		if str != tc.expected {
   354  			t.Errorf("%d: expected \"%s\", got \"%s\"", i, tc.expected, str)
   355  		}
   356  	}
   357  }
   358  
   359  func TestFormatHexKey(t *testing.T) {
   360  	// Verify that we properly handling the 'x' formatting verb in
   361  	// roachpb.Key.Format.
   362  	key := keys.StoreIdentKey()
   363  	decoded, err := hex.DecodeString(fmt.Sprintf("%x", key))
   364  	if err != nil {
   365  		t.Fatal(err)
   366  	}
   367  	if !bytes.Equal(key, decoded) {
   368  		t.Fatalf("expected %s, but found %s", key, decoded)
   369  	}
   370  }
   371  
   372  func makeKey(keys ...[]byte) []byte {
   373  	return bytes.Join(keys, nil)
   374  }