diff --git a/cmd/bbolt/main.go b/cmd/bbolt/main.go index 3f21a42ff..7ba8c8a7f 100644 --- a/cmd/bbolt/main.go +++ b/cmd/bbolt/main.go @@ -909,7 +909,7 @@ func newKeysCommand(m *Main) *keysCommand { func (cmd *keysCommand) Run(args ...string) error { // Parse flags. fs := flag.NewFlagSet("", flag.ContinueOnError) - optionsFormat := fs.String("format", "bytes", "Output format. One of: "+FORMAT_MODES+" (default: bytes)") + optionsFormat := fs.String("format", "auto", "Output format. One of: "+FORMAT_MODES+" (default: auto)") help := fs.Bool("h", false, "") if err := fs.Parse(args); err != nil { return err @@ -969,7 +969,7 @@ Print a list of keys in the given (sub)bucket. Additional options include: --format - Output format. One of: `+FORMAT_MODES+` (default=bytes) + Output format. One of: `+FORMAT_MODES+` (default=auto) Print a list of keys in the given bucket. `, "\n") diff --git a/cmd/bbolt/main_test.go b/cmd/bbolt/main_test.go index abc57ccac..e137db3e9 100644 --- a/cmd/bbolt/main_test.go +++ b/cmd/bbolt/main_test.go @@ -320,37 +320,68 @@ func TestBucketsCommand_Run(t *testing.T) { // Ensure the "keys" command can print a list of keys for a bucket. func TestKeysCommand_Run(t *testing.T) { - db := btesting.MustCreateDB(t) + testCases := []struct { + name string + printable bool + testBucket string + expected string + }{ + { + name: "printable keys", + printable: true, + testBucket: "foo", + expected: "foo-0\nfoo-1\nfoo-2\n", + }, + { + name: "non printable keys", + printable: false, + testBucket: "bar", + expected: convertInt64KeysIntoHexString(100001, 100002, 100003), + }, + } - if err := db.Update(func(tx *bolt.Tx) error { - for _, name := range []string{"foo", "bar"} { - b, err := tx.CreateBucket([]byte(name)) - if err != nil { - return err - } - for i := 0; i < 3; i++ { - key := fmt.Sprintf("%s-%d", name, i) - if err := b.Put([]byte(key), []byte{0}); err != nil { - return err + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + t.Logf("creating test database for subtest '%s'", tc.name) + db := btesting.MustCreateDB(t) + + err := db.Update(func(tx *bolt.Tx) error { + t.Logf("creating test bucket %s", tc.testBucket) + b, bErr := tx.CreateBucketIfNotExists([]byte(tc.testBucket)) + if bErr != nil { + return fmt.Errorf("error creating test bucket %q: %v", tc.testBucket, bErr) } - } - } - return nil - }); err != nil { - t.Fatal(err) - } - db.Close() - defer requireDBNoChange(t, dbData(t, db.Path()), db.Path()) + t.Logf("inserting test data into test bucket %s", tc.testBucket) + if tc.printable { + for i := 0; i < 3; i++ { + key := fmt.Sprintf("%s-%d", tc.testBucket, i) + if pErr := b.Put([]byte(key), []byte{0}); pErr != nil { + return pErr + } + } + } else { + for i := 100001; i < 100004; i++ { + k := convertInt64IntoBytes(int64(i)) + if pErr := b.Put(k, []byte{0}); pErr != nil { + return pErr + } + } + } + return nil + }) + require.NoError(t, err) + db.Close() - expected := "foo-0\nfoo-1\nfoo-2\n" + defer requireDBNoChange(t, dbData(t, db.Path()), db.Path()) - // Run the command. - m := NewMain() - if err := m.Run("keys", db.Path(), "foo"); err != nil { - t.Fatal(err) - } else if actual := m.Stdout.String(); actual != expected { - t.Fatalf("unexpected stdout:\n\n%s", actual) + t.Log("running Keys cmd") + m := NewMain() + kErr := m.Run("keys", db.Path(), tc.testBucket) + require.NoError(t, kErr) + actual := m.Stdout.String() + assert.Equal(t, tc.expected, actual) + }) } } @@ -704,3 +735,11 @@ func convertInt64IntoBytes(num int64) []byte { n := binary.PutVarint(buf, num) return buf[:n] } + +func convertInt64KeysIntoHexString(nums ...int64) string { + var res []string + for _, num := range nums { + res = append(res, hex.EncodeToString(convertInt64IntoBytes(num))) + } + return strings.Join(res, "\n") + "\n" // last newline char +}