DAOS-18304 ddb: Add Go unit tests for ddb command layer#18086
Conversation
628036b to
c58c604
Compare
3c4faba to
24d96e6
Compare
|
Ticket title is 'Add unit test to ddb go code' |
24d96e6 to
f81f3be
Compare
62c66ea to
6e01e12
Compare
6e01e12 to
cda7452
Compare
|
Test stage Unit Test completed with status UNSTABLE. https://jenkins-3.daos.hpc.amslabs.hpecorp.net/job/daos-stack/job/daos//view/change-requests/job/PR-18086/11/testReport/ |
47f06b5 to
a511b14
Compare
|
Test stage Unit Test completed with status UNSTABLE. https://jenkins-3.daos.hpc.amslabs.hpecorp.net/job/daos-stack/job/daos//view/change-requests/job/PR-18086/12/testReport/ |
a511b14 to
03189b1
Compare
|
Test stage Unit Test completed with status UNSTABLE. https://jenkins-3.daos.hpc.amslabs.hpecorp.net/job/daos-stack/job/daos//view/change-requests/job/PR-18086/14/testReport/ |
c3dd676 to
bd9f1f2
Compare
|
Test stage Functional Hardware Medium MD on SSD completed with status FAILURE. https://jenkins-3.daos.hpc.amslabs.hpecorp.net//job/daos-stack/job/daos/view/change-requests/job/PR-18086/17/execution/node/717/log |
f6a67bd to
8b2e76b
Compare
Introduce the Go test suite for the ddb CLI layer, built on top of the build-tag CGo stub infrastructure landed in #18124: - Add test_helpers.go: newTestContext(t) resets all CGo stubs via resetDdbStubs() and returns a *DdbContext ready for use in tests. Test cases set per-function _Fn hook variables directly. - All test files carry the //go:build test_stubs tag so they only compile when the stub infrastructure is present. - TestCmds: open (default, write_mode, db_path), feature (show, enable, disable), and dtx_aggr (mutual exclusion, cmt_time, cmt_date, path). Adds skipCmdLine field for flags shared between CLI and grumble layers. - TestHelpCmds: unknown-command help flow. - TestParseOpts / TestRun: CLI-level option parsing and run() dispatch, including unknown-command detection for both command-line and command-file paths. - TestNewLogger: 6 sub-cases (default level, explicit debug, invalid level, valid LogDir, non-existent LogDir, LogDir is a file). - TestClosePoolIfOpen: Close not called when already closed, called when open, Close error tolerated. Test-tag: unittest Required-githooks: yes Signed-off-by: Cedric Koch-Hofer <cedric.koch-hofer@hpe.com>
8b2e76b to
658f2f3
Compare
|
Test stage NLT completed with status UNSTABLE. https://jenkins-3.daos.hpc.amslabs.hpecorp.net/job/daos-stack/job/daos//view/change-requests/job/PR-18086/22/testReport/ |
…pers Per reviewer feedback (r3318912192): replace the hand-rolled isArgEqual helper with the existing test.CmpAny utility. test.CmpAny uses cmp.Diff for clearer failure output and calls t.Fatalf directly, removing the error propagation boilerplate from stub closures. To flow the subtest t into the stub closures, setup fields in TestRun and TestCmds are changed from func() to func(*testing.T), and named helper factories (openFnChecking, openFnCheckingWriteMode, lsFnChecking, featureFnCheckingShow, dtxAggrFnChecking) gain a leading t *testing.T parameter. The isArgEqual function and its unused reflect import are removed from test_helpers.go. Since test.CmpAny calls t.Fatalf (which triggers runtime.Goexit), captureStdout is updated to use named return values and move w.Close() and <-done into the defer, ensuring the pipe and goroutine are always cleaned up even when the test fails mid-stub. Signed-off-by: Cedric Koch-Hofer <cedric.koch-hofer@hpe.com>
|
Test stage Functional on EL 9 completed with status FAILURE. https://jenkins-3.daos.hpc.amslabs.hpecorp.net//job/daos-stack/job/daos/view/change-requests/job/PR-18086/30/execution/node/1118/log |
Per reviewer feedback (r3318906385): remove the runMainFlow helper and
inline captureStdout(func() error { return runDdb(ctx, args) }) directly
at the 8 call sites in main_test.go and ddb_commands_test.go.
runMainFlow was a meaningful abstraction when it contained ~15 lines of
logic (parseOpts, version handling, run). After the runDdb extraction
commit it became a thin 3-line pass-through that adds indirection without
semantic value. Inlining makes each test site self-contained and explicit
about what it does: capture stdout while running the production entry point.
Signed-off-by: Cedric Koch-Hofer <cedric.koch-hofer@hpe.com>
…/daos-18304-patch-002
…Contains Per reviewer feedback (r3318926829): assertContainsAll has no ddb-specific logic and belongs in the shared test utilities package so it can be reused across the entire control-plane test suite. Add AssertStringContains(t, s string, substrings ...string) to common/test/utils.go. The variadic signature handles both single and multiple substring checks; existing slice call sites use the spread operator (expSections...). Remove assertContainsAll from test_helpers.go along with the now-unused fmt, strings, and common/test imports. Signed-off-by: Cedric Koch-Hofer <cedric.koch-hofer@hpe.com>
Per reviewer feedback (r3318965302): split the single TestRun function into two focused test functions. Previously TestRun ran each case in two modes (command-line and command-file) controlled by optional cmdFileArgs/cmdFileCmd struct fields and a conditional t.Run block. This made the table struct heavier and the runner harder to follow. After the split: - TestRun covers command-line mode only; the table has a flat (args, setup, expStdout, expErr) struct and a single straightforward runner body. - TestRunCommandFile covers command-file mode only; the table uses a (flags, cmdLine, setup, expStdout, expErr) struct that matches the command-file execution model directly. The five openFn* helper factories are moved to package level so both test functions can share them without duplication. Signed-off-by: Cedric Koch-Hofer <cedric.koch-hofer@hpe.com>
Per reviewer tip (r3318987058): follow the Test<PkgName>_<funcName> convention used in cmd/daos and other control-plane packages, so that failing tests are immediately identifiable by package when running the full unit test suite. Rename map (12 functions, 3 files): TestParseOpts -> TestDdb_parseOpts TestRun -> TestDdb_runDdb TestRunCommandFile -> TestDdb_runDdbCommandFile TestRunMultiLineCommandFile -> TestDdb_runFileCmds TestStrToLogLevels -> TestDdb_strToLogLevels TestNewLogger -> TestDdb_newLogger TestClosePoolIfOpen -> TestDdb_closePoolIfOpen TestHelpCmds -> TestDdb_HelpCmds TestCmds -> TestDdb_Cmds TestManPage -> TestDdb_ManPage TestListVosFiles -> TestDdb_listVosFiles TestFilterSuggestions -> TestDdb_filterSuggestions No logic changes. Signed-off-by: Cedric Koch-Hofer <cedric.koch-hofer@hpe.com>
The runHelpCmd helper was called in a single place with straightforward logic. Inlining it into the t.Run body makes TestDdb_HelpCmds fully self-contained without unnecessary indirection. Signed-off-by: Cedric Koch-Hofer <cedric.koch-hofer@hpe.com>
|
Test stage NLT completed with status UNSTABLE. https://jenkins-3.daos.hpc.amslabs.hpecorp.net/job/daos-stack/job/daos//view/change-requests/job/PR-18086/35/testReport/ |
|
Test stage Functional Hardware Medium MD on SSD completed with status UNSTABLE. https://jenkins-3.daos.hpc.amslabs.hpecorp.net/job/daos-stack/job/daos//view/change-requests/job/PR-18086/35/testReport/ |
…/daos-18304-patch-002
The helper was silently converting errHelpRequested to nil, hiding a sentinel that runDdb acts on. Unit tests should verify that parseOpts returns the sentinel when --help is passed. Remove the masking guard from runCmdToStdout and add expErr: errHelpRequested to the two help-message test cases. Move the expStdout check before the early-return guard so these cases still verify both the sentinel and the stdout output. Signed-off-by: Cedric Koch-Hofer <cedric.koch-hofer@hpe.com>
|
Test stage NLT completed with status UNSTABLE. https://jenkins-3.daos.hpc.amslabs.hpecorp.net/job/daos-stack/job/daos//view/change-requests/job/PR-18086/37/testReport/ |
Replace fmt.Println("Open called") in openFnChecking and
openFnCheckingWriteMode with a *bool pointer parameter. Each test case
declares a closure-scoped "called" bool, passes &called to the stub,
and registers t.Cleanup to assert invocation. The same pattern is applied
to TestDdb_runFileCmds which used fmt.Println in ls/version stubs.
This removes the dependency on captureStdout for stub verification and
eliminates the risk of false positives from production code printing the
same string. The remaining captureStdout usages (version output and help
text) are legitimate: grumble writes directly to os.Stdout with no
injection point.
Signed-off-by: Cedric Koch-Hofer <cedric.koch-hofer@hpe.com>
…/daos-18304-patch-002
|
Test stage NLT completed with status UNSTABLE. https://jenkins-3.daos.hpc.amslabs.hpecorp.net/job/daos-stack/job/daos//view/change-requests/job/PR-18086/39/testReport/ |
Thanks to your review which allowed to really improve the PR :-) |
| if err != nil { | ||
| exitWithError(errors.Wrap(err, loggerInitErr)) | ||
| var log *logging.LeveledLogger | ||
| if log, err = newLogger(opts); err != nil { |
There was a problem hiding this comment.
nit: Rather than declaring log explicitly, I would personally just use a different err variable name to avoid shadowing: if log, errIn := newLogger(opts); ...
There was a problem hiding this comment.
This solution is not possible as log will be out of scope.
However, the following solution seems to be indeed more idiomatic
log, err := newLogger(opts)
if err != nil {
...
}If this solution is OK for you, I will integrate it in the follow-up PR.
tanabarr
left a comment
There was a problem hiding this comment.
I'm personally not too worried about shadowing within an if statement, we know that using short variable declaration will result in a new variable scoped within the if statement.
…/daos-18304-patch-002
|
Test stage NLT completed with status UNSTABLE. https://jenkins-3.daos.hpc.amslabs.hpecorp.net/job/daos-stack/job/daos//view/change-requests/job/PR-18086/40/testReport/ |
|
Test stage Functional on EL 9 completed with status FAILURE. https://jenkins-3.daos.hpc.amslabs.hpecorp.net//job/daos-stack/job/daos/view/change-requests/job/PR-18086/40/execution/node/983/log |
…/daos-18304-patch-002
|
Test stage Functional Hardware Medium MD on SSD completed with status UNSTABLE. https://jenkins-3.daos.hpc.amslabs.hpecorp.net/job/daos-stack/job/daos//view/change-requests/job/PR-18086/41/testReport/ |
|
All CI failures in build #41 are pre-existing infrastructure or unrelated issues:
|
|
@daos-stack/daos-gatekeeper according to my previous comment, could you land this PR with the following commit:
|
Description
Overview
Go unit tests for the
ddbCLI command layer, building on the build-tag CGo stub infrastructureintroduced in the predecessor PR #18124.
Tests are gated behind the
test_stubsbuild tag and run without a live VOS environment. The CGofunction stubs provided by
libddb_stubs.goexpose configurable return-code variables(
ddb_init_RC,ddb_pool_is_open_RC, …) and hook variables (ddb_init_Fn, …) that let testscontrol stub behaviour without modifying production code.
New Files
test_helpers.goTest infrastructure shared across all test files:
newTestContext: allocates aDdbContextbacked by the CGo stubs.captureStdout: redirectsos.Stdoutto a pipe for the duration of a function call andreturns the captured output as a string.
runCmdToStdout: callsparseOpts()with given args and captures stdout.runMainFlow: simulates the fullmain()flow (parse → version check → run) withoutcalling
os.Exit().assertContainsAll: asserts that a string contains every element of a given slice — used byTestManPageto avoid repetitive loops.isArgEqual: type-safe argument comparison helper.ddb_commands_test.goTests for the grumble command definitions:
TestHelpCmds: verifies--helpoutput for thelsandopencommands.TestCmds: argument and option parsing forls(--recursive,--details),open(
--vos_path,--db_path,--write_mode),feature(--enable/--disable),dtx_aggr(mutual-exclusion validation),
close, andversion.TestManPage: verifies man page output both to stdout and to a file, using a sharedexpSectionslist.main_test.goTests for the CLI entry-point logic:
TestParseOpts: default option values, flag parsing (--debug,--write,--vos_path,--db_path,--version,--cmd,--cmd_file) and error cases (conflicting--cmd/--cmd_file, missing--vos_pathwhen--db_pathis set).TestRun: version output, unknown command detection,noAutoOpenlist (feature, open,smd_sync), auto-open via
--vos_path/--db_path,ctx.Init()failure,ctx.Open()failure.TestRunMultiLineCommandFile: verifies that a command file with multiple commands executesall of them in order.
TestStrToLogLevels: all supported log-level string conversions.TestNewLogger: logger creation for each log level.TestClosePoolIfOpen: pool-not-open, successful close, and close-error paths.Steps for the author:
After all prior steps are complete: