Skip to content

Commit 19e050f

Browse files
kanard38knard38
authored andcommitted
DAOS-17321 ddb: Add checksum dump command to ddb GO code
Add the csum_dump command to the ddb Go CLI, wiring the ddb_run_csum_dump() C API (added in #18543) through the build-tag CGo stub layer introduced by #18124: - Add CsumDump() to DdbContext (commands_wrapper.go): builds the C csum_dump_options (path, optional dst, epoch) and invokes the C command. - Add real and stub ddb_run_csum_dump() wrappers (libddb.go / libddb_stubs.go), following the existing per-command _RC/_Fn hook pattern used for Go unit testing. - Register the "csum_dump" command in ddb_commands.go: a required positional path, an optional positional dst (file to dump the checksum to; prints to the screen when omitted), and a -e/--epoch flag (default EPOCH_MAX). - The epoch selects which version of the checksum to dump: for a single value akey it is the epoch at or before which the value is fetched; for an array akey it is the maximal epoch of the visible record extent(s) to select. Tests: add TestDdb_Cmds cases for csum_dump covering a missing required path argument, an invalid flag, the default epoch, the short and long --epoch forms, a file destination, and a destination combined with a custom epoch. Features: recovery Signed-off-by: Cedric Koch-Hofer <cedric.koch-hofer@hpe.com>
1 parent 12ed00d commit 19e050f

5 files changed

Lines changed: 128 additions & 4 deletions

File tree

src/control/cmd/ddb/commands_wrapper.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,3 +380,22 @@ func (ctx *DdbContext) DtxAggr(path string, cmtTime uint64, cmtDate string) erro
380380
/* Run the c code command */
381381
return daosError(ddb_run_dtx_aggr(&ctx.ctx, &options))
382382
}
383+
384+
// CsumDump dumps the visible checksum(s) at the VOS tree path to the screen, or to the
385+
// file at dst if provided. epoch selects which version to dump: for a single value akey
386+
// it is the epoch at or before which the value is fetched, and for an array akey it is the
387+
// maximal epoch of the visible record extent(s) to select. Pass math.MaxUint64 (EPOCH_MAX)
388+
// to select the latest.
389+
func (ctx *DdbContext) CsumDump(path string, dst string, epoch uint64) error {
390+
/* Set up the options */
391+
options := C.struct_csum_dump_options{}
392+
options.path = C.CString(path)
393+
defer freeString(options.path)
394+
if dst != "" {
395+
options.dst = C.CString(dst)
396+
defer freeString(options.dst)
397+
}
398+
options.epoch = C.uint64_t(epoch)
399+
/* Run the c code command */
400+
return daosError(ddb_run_csum_dump(&ctx.ctx, &options))
401+
}

src/control/cmd/ddb/ddb_commands.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,4 +481,30 @@ If --db_path is provided, a VOS file path must also be given as a positional arg
481481
},
482482
Completer: nil,
483483
})
484+
// Command csum_dump
485+
app.AddCommand(&grumble.Command{
486+
Name: "csum_dump",
487+
Aliases: nil,
488+
Help: "Dump visible checksum(s)",
489+
LongHelp: `Dump visible checksum(s) to the screen or in a file. The vos
490+
path should be a complete path, including the akey and if the value is an array
491+
value it should include the extent. If a path to a file was provided then the
492+
value(s) will be written to the file, else it will be printed to the screen.
493+
The --epoch flag selects which version of the checksum to dump: for a single
494+
value akey it selects the value visible at or before that epoch, and for an
495+
array value it defines the maximal epoch of the visible record extent to
496+
select`,
497+
HelpGroup: "vos",
498+
Args: func(a *grumble.Args) {
499+
a.String("path", "VOS tree path to dump.")
500+
a.String("dst", "Optional, file path to dump the value to.", grumble.Default(""))
501+
},
502+
Flags: func(f *grumble.Flags) {
503+
f.Uint64("e", "epoch", math.MaxUint64, "Maximal epoch of the checksum value to select (default EPOCH_MAX).")
504+
},
505+
Run: func(c *grumble.Context) error {
506+
return ctx.CsumDump(c.Args.String("path"), c.Args.String("dst"), c.Flags.Uint64("epoch"))
507+
},
508+
Completer: nil,
509+
})
484510
}

src/control/cmd/ddb/ddb_commands_test.go

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ package main
1010

1111
import (
1212
"fmt"
13+
"math"
1314
"os"
1415
"path"
1516
"path/filepath"
@@ -32,6 +33,10 @@ func TestDdb_HelpCmds(t *testing.T) {
3233
cmdStr: "open",
3334
helpSubStr: "Usage:\n open [flags] path\n",
3435
},
36+
"help for 'csum_dump' command": {
37+
cmdStr: "csum_dump",
38+
helpSubStr: "Usage:\n csum_dump [flags] path [dst]\n",
39+
},
3540
// TODO(follow-up PR): Add help tests for the remaining commands.
3641
} {
3742
t.Run(name, func(t *testing.T) {
@@ -52,8 +57,7 @@ func TestDdb_HelpCmds(t *testing.T) {
5257
if err != nil {
5358
t.Fatalf("unexpected error when running '%s --help' via command file: want nil, got %v", tc.cmdStr, err)
5459
}
55-
test.AssertTrue(t, strings.Contains(stdoutCmdFile, tc.helpSubStr),
56-
fmt.Sprintf("expected stdout to contain %q: got\n%s", tc.helpSubStr, stdoutCmdFile))
60+
test.AssertStringContains(t, stdoutCmdFile, tc.helpSubStr)
5761

5862
// Run the help command with a command line
5963
args = test.JoinArgs(nil, tc.cmdStr, "--help")
@@ -63,8 +67,7 @@ func TestDdb_HelpCmds(t *testing.T) {
6367
if err != nil {
6468
t.Fatalf("unexpected error when running '%s --help' via command line: want nil, got %v", tc.cmdStr, err)
6569
}
66-
test.AssertTrue(t, strings.Contains(stdoutCmdLine, tc.helpSubStr),
67-
fmt.Sprintf("expected stdout to contain %q: got\n%s", tc.helpSubStr, stdoutCmdLine))
70+
test.AssertStringContains(t, stdoutCmdLine, tc.helpSubStr)
6871

6972
// Compare command line and command file outputs
7073
test.AssertEqual(t, stdoutCmdFile, stdoutCmdLine,
@@ -132,6 +135,16 @@ func TestDdb_Cmds(t *testing.T) {
132135
}
133136
}
134137

138+
csumDumpFnChecking := func(t *testing.T, wantPath, wantDst string, wantEpoch uint64) func(string, string, uint64) error {
139+
return func(path, dst string, epoch uint64) error {
140+
fmt.Println("csum_dump called")
141+
test.CmpAny(t, "path", wantPath, path)
142+
test.CmpAny(t, "dst", wantDst, dst)
143+
test.CmpAny(t, "epoch", wantEpoch, epoch)
144+
return nil
145+
}
146+
}
147+
135148
for name, tc := range map[string]struct {
136149
args []string
137150
setup func(*testing.T)
@@ -394,6 +407,51 @@ func TestDdb_Cmds(t *testing.T) {
394407
expStdout: []string{"prov_mem called"},
395408
},
396409

410+
// --- csum_dump command ---
411+
"csum_dump missing path": {
412+
args: []string{"csum_dump"},
413+
expErr: ddbTestErr("missing argument 'path'"),
414+
},
415+
"csum_dump invalid options": {
416+
args: []string{"csum_dump", "--bar"},
417+
expErr: ddbTestErr("invalid flag: --bar"),
418+
},
419+
"csum_dump default": {
420+
args: []string{"csum_dump", "/[0]"},
421+
setup: func(t *testing.T) {
422+
ddb_run_csum_dump_Fn = csumDumpFnChecking(t, "/[0]", "", math.MaxUint64)
423+
},
424+
expStdout: []string{"csum_dump called"},
425+
},
426+
"csum_dump epoch short": {
427+
args: []string{"csum_dump", "-e", "999", "/[0]"},
428+
setup: func(t *testing.T) {
429+
ddb_run_csum_dump_Fn = csumDumpFnChecking(t, "/[0]", "", 999)
430+
},
431+
expStdout: []string{"csum_dump called"},
432+
},
433+
"csum_dump epoch long": {
434+
args: []string{"csum_dump", "--epoch=666", "/[0]"},
435+
setup: func(t *testing.T) {
436+
ddb_run_csum_dump_Fn = csumDumpFnChecking(t, "/[0]", "", 666)
437+
},
438+
expStdout: []string{"csum_dump called"},
439+
},
440+
"csum_dump destination": {
441+
args: []string{"csum_dump", "/[0]", "/tmp/csum_dump.out"},
442+
setup: func(t *testing.T) {
443+
ddb_run_csum_dump_Fn = csumDumpFnChecking(t, "/[0]", "/tmp/csum_dump.out", math.MaxUint64)
444+
},
445+
expStdout: []string{"csum_dump called"},
446+
},
447+
"csum_dump destination with epoch": {
448+
args: []string{"csum_dump", "-e", "500", "/[0]", "/tmp/csum_dump.out"},
449+
setup: func(t *testing.T) {
450+
ddb_run_csum_dump_Fn = csumDumpFnChecking(t, "/[0]", "/tmp/csum_dump.out", 500)
451+
},
452+
expStdout: []string{"csum_dump called"},
453+
},
454+
397455
// TODO(follow-up PR): Add TestCmds cases for the remaining commands.
398456
// Each new test case follows the same pattern as the cases above: set the
399457
// corresponding ddb_run_<cmd>_Fn hook in setup() to verify argument passing,

src/control/cmd/ddb/libddb.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,7 @@ func ddb_run_prov_mem(ctx *C.struct_ddb_ctx, opts *C.struct_prov_mem_options) C.
131131
func ddb_run_dtx_aggr(ctx *C.struct_ddb_ctx, opts *C.struct_dtx_aggr_options) C.int {
132132
return C.ddb_run_dtx_aggr(ctx, opts)
133133
}
134+
135+
func ddb_run_csum_dump(ctx *C.struct_ddb_ctx, opts *C.struct_csum_dump_options) C.int {
136+
return C.ddb_run_csum_dump(ctx, opts)
137+
}

src/control/cmd/ddb/libddb_stubs.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ func resetDdbStubs() {
5959
ddb_run_dtx_stat_RC, ddb_run_dtx_stat_Fn = 0, nil
6060
ddb_run_prov_mem_RC, ddb_run_prov_mem_Fn = 0, nil
6161
ddb_run_dtx_aggr_RC, ddb_run_dtx_aggr_Fn = 0, nil
62+
ddb_run_csum_dump_RC, ddb_run_csum_dump_Fn = 0, nil
6263
}
6364

6465
var ddb_init_RC C.int = 0
@@ -458,3 +459,19 @@ func ddb_run_dtx_aggr(_ *C.struct_ddb_ctx, opts *C.struct_dtx_aggr_options) C.in
458459
}
459460
return ddb_run_dtx_aggr_RC
460461
}
462+
463+
var (
464+
ddb_run_csum_dump_RC C.int = 0
465+
ddb_run_csum_dump_Fn func(path string, dst string, epoch uint64) error
466+
)
467+
468+
func ddb_run_csum_dump(_ *C.struct_ddb_ctx, opts *C.struct_csum_dump_options) C.int {
469+
if ddb_run_csum_dump_Fn != nil {
470+
return fromGoErr(ddb_run_csum_dump_Fn(
471+
C.GoString(opts.path),
472+
C.GoString(opts.dst),
473+
uint64(opts.epoch),
474+
))
475+
}
476+
return ddb_run_csum_dump_RC
477+
}

0 commit comments

Comments
 (0)