@@ -17,6 +17,7 @@ import (
17
17
"github.com/cockroachdb/cockroach/pkg/base"
18
18
"github.com/cockroachdb/cockroach/pkg/clusterversion"
19
19
"github.com/cockroachdb/cockroach/pkg/gossip"
20
+ "github.com/cockroachdb/cockroach/pkg/kv/kvserver/concurrency/lock"
20
21
"github.com/cockroachdb/cockroach/pkg/roachpb"
21
22
"github.com/cockroachdb/cockroach/pkg/server"
22
23
"github.com/cockroachdb/cockroach/pkg/settings/cluster"
@@ -25,9 +26,11 @@ import (
25
26
"github.com/cockroachdb/cockroach/pkg/testutils"
26
27
"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
27
28
"github.com/cockroachdb/cockroach/pkg/testutils/testcluster"
29
+ "github.com/cockroachdb/cockroach/pkg/util/hlc"
28
30
"github.com/cockroachdb/cockroach/pkg/util/leaktest"
29
31
"github.com/cockroachdb/cockroach/pkg/util/log"
30
32
"github.com/cockroachdb/cockroach/pkg/util/stop"
33
+ "github.com/cockroachdb/cockroach/pkg/util/uuid"
31
34
)
32
35
33
36
func createStore (t * testing.T , path string ) {
@@ -136,3 +139,110 @@ func TestParsePositiveDuration(t *testing.T) {
136
139
t .Errorf ("Expected to fail parsing negative duration -5m" )
137
140
}
138
141
}
142
+
143
+ // TestDebugDecodeKeyEngineKeyPaths tests the new engine key decoding logic in debug.go
144
+ func TestDebugDecodeKeyEngineKeyPaths (t * testing.T ) {
145
+ defer leaktest .AfterTest (t )()
146
+ defer log .Scope (t ).Close (t )
147
+
148
+ t .Run ("lock_table_keys" , func (t * testing.T ) {
149
+ // Create lock table keys and test they decode properly
150
+ uuid1 := uuid .Must (uuid .FromString ("6ba7b810-9dad-11d1-80b4-00c04fd430c8" ))
151
+
152
+ lockKeys := []storage.LockTableKey {
153
+ {Key : roachpb .Key ("test" ), Strength : lock .Shared , TxnUUID : uuid1 },
154
+ {Key : roachpb .Key ("foo" ), Strength : lock .Exclusive , TxnUUID : uuid1 },
155
+ {Key : roachpb .Key ("bar" ), Strength : lock .Intent , TxnUUID : uuid1 },
156
+ }
157
+
158
+ for i , lockKey := range lockKeys {
159
+ t .Run (fmt .Sprintf ("lock_%d_%s" , i , lockKey .Strength ), func (t * testing.T ) {
160
+ engineKey , _ := lockKey .ToEngineKey (nil )
161
+ encoded := engineKey .Encode ()
162
+ hexKey := fmt .Sprintf ("%x" , encoded )
163
+
164
+ out , err := TestCLI {}.RunWithCaptureArgs ([]string {
165
+ "debug" , "decode-key" , "--encoding" , "hex" , hexKey ,
166
+ })
167
+
168
+ if err != nil {
169
+ t .Fatalf ("Unexpected error: %v" , err )
170
+ }
171
+
172
+ // Verify the output contains lock strength and key
173
+ if ! strings .Contains (out , lockKey .Strength .String ()) {
174
+ t .Errorf ("Expected output to contain lock strength %s, got: %s" , lockKey .Strength , out )
175
+ }
176
+ if ! strings .Contains (out , string (lockKey .Key )) {
177
+ t .Errorf ("Expected output to contain key %s, got: %s" , lockKey .Key , out )
178
+ }
179
+ })
180
+ }
181
+ })
182
+
183
+ t .Run ("mvcc_keys_via_engine_key" , func (t * testing.T ) {
184
+ // Test MVCC keys that are decoded via the EngineKey.IsMVCCKey() path
185
+ mvccKey := storage.MVCCKey {
186
+ Key : roachpb .Key ("mvcc_test" ),
187
+ Timestamp : hlc.Timestamp {WallTime : 123456 },
188
+ }
189
+
190
+ encoded := storage .EncodeMVCCKey (mvccKey )
191
+ hexKey := fmt .Sprintf ("%x" , encoded )
192
+
193
+ out , err := TestCLI {}.RunWithCaptureArgs ([]string {
194
+ "debug" , "decode-key" , "--encoding" , "hex" , hexKey ,
195
+ })
196
+
197
+ if err != nil {
198
+ t .Fatalf ("Unexpected error: %v" , err )
199
+ }
200
+
201
+ if ! strings .Contains (out , "mvcc_test" ) {
202
+ t .Errorf ("Expected output to contain key content, got: %s" , out )
203
+ }
204
+ })
205
+
206
+ t .Run ("engine_key_other_types" , func (t * testing.T ) {
207
+ // Test engine keys that are neither lock table nor MVCC keys
208
+ // These should be printed as-is via the "else" branch
209
+ // For now, we'll test with a simple case that should trigger this path
210
+
211
+ // This will test the fallback path when DecodeEngineKey returns false
212
+ invalidEngineKey := "ff"
213
+
214
+ out , err := TestCLI {}.RunWithCaptureArgs ([]string {
215
+ "debug" , "decode-key" , "--encoding" , "hex" , invalidEngineKey ,
216
+ })
217
+
218
+ if err != nil {
219
+ t .Fatalf ("Unexpected error: %v" , err )
220
+ }
221
+
222
+ // Should trigger the MVCC fallback path and show an error
223
+ if ! strings .Contains (out , "ERROR" ) {
224
+ t .Errorf ("Expected output to contain error from MVCC fallback, got: %s" , out )
225
+ }
226
+ })
227
+
228
+ t .Run ("backwards_compatibility_fallback" , func (t * testing.T ) {
229
+ // Test the fallback path: when DecodeEngineKey fails,
230
+ // it should fall back to DecodeMVCCKey for backwards compatibility
231
+
232
+ // Use the same test case from existing tests that should trigger fallback
233
+ invalidKey := "jg==" // base64 encoded "8e"
234
+
235
+ out , err := TestCLI {}.RunWithCaptureArgs ([]string {
236
+ "debug" , "decode-key" , "--encoding" , "base64" , invalidKey ,
237
+ })
238
+
239
+ if err != nil {
240
+ t .Fatalf ("Unexpected error: %v" , err )
241
+ }
242
+
243
+ // Should contain error message from MVCC key decoding fallback
244
+ if ! strings .Contains (out , "ERROR: invalid encoded mvcc key" ) {
245
+ t .Errorf ("Expected fallback to MVCC decoding with error message, got: %s" , out )
246
+ }
247
+ })
248
+ }
0 commit comments