Skip to content

test: keep each test subject in one file per bucket - #218

Open
synackd wants to merge 14 commits into
mainfrom
test/organize
Open

synackd wants to merge 14 commits into
mainfrom
test/organize

Conversation

@synackd

@synackd synackd commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Fixes #190

Summary

CONTRIBUTING.md groups a subject's tests by suffix (<subject>_test.go,
_errors_test.go, _boundary_test.go), but 48 subject/bucket pairs on
main were split across two or three files. This PR moves each test into
one file per subject and bucket and adds a check so the layout can't drift
back.

This change only moves tests. Apart from 9 renames, every moved test,
helper and fixture is byte-identical to main and stays in its package.
The test count goes from 967 to 968; the one new test is the check.

In cmd, each test file is named after the command path it covers, with one
commit per family:

Family Change
smd Resource tests move from smd_test.go and smd_write*_test.go into smd_{group,group_member,iface,rfe,compep}*_test.go. smd_test.go keeps only TestSMDServiceStatus.
bss New bss_boot_params, bss_boot_script and bss_hosts test files. TestBSSBootImageSet moves to bss_boot_image_test.go. bss_test.go keeps the commands directly under bss (dumpstate, history, service status, deprecated status).
boot, metadata *_write*_test.go is folded into the family files. New boot_{bmc,config,node}_errors_test.go and metadata_group_test.go.
cloud-init Group and node tests move into their files. New cloud_init_defaults*_test.go. cloud_init_test.go keeps only the service tests.
pcs New pcs_status*_test.go. pcs_flags*_test.go is retired, and TestPCSTransitionStart_RequiresXname moves to pcs_transition_errors_test.go.
rcs rcs*_test.go → rcs_console*_test.go (every test covers rcs console).
discover discover static is the only command under discover, so discover_static*_test.go → discover*_test.go, and discover_static_flags_test.go is folded in.
root Seven tests in config*_test.go that run version or smd group get, not config, move to root*_test.go (new root_boundary_test.go). They check how the root command loads config and resolves a command's base URI and token.

The _write files' fixtures (bootAddPayload, metadataTypes,
addPayloadFor) moved with their users. Each moved file's file-level comment
now describes what the file holds.

Outside cmd, tests of the same function that lived in different files
were moved together:

  • internal/cli: the CheckToken/HandleToken tests go to cli_test.go
    (removing cli_token_validation_test.go). The IOStreams tests and their
    readError/writeError stubs go to runtime_test.go.
  • internal/configfile: the ReadConfigWithDefaults tests and their
    writeTemp/writeCfg helpers go to configfile_test.go (removing
    clusterdefaults_test.go and validate_test.go).
    clusterdefaults_errors_test.go → configfile_errors_test.go.
  • pkg/client: TestUseCACert_FileFailures goes to client_errors_test.go.
    TestShowConsole_ReturnsConnectionCloseError goes to
    rcs/rcs_errors_test.go.
  • pkg/config: the loadmerged_test.go tests go to config_test.go.

These tests are renamed:

  • TestRuntime_EnvironmentIsolation →
    TestSetTokenFromEnv_PerRuntimeEnvironment.
  • The six TestFile_* tests in pkg/config/transaction*_test.go →
    TestFileUpdate_*, since every File mutation goes through File.Update.
  • TestConfig_NullValueHandling and TestConfig_IgnoreConfigSkipsConfigFile
    → TestRootCommand_*, since they moved to root_boundary_test.go and the
    other TestConfig boundary tests stay in config_boundary_test.go.

Tests

The last commit adds TestTestFiles_SubjectInOneFile to
internal/conventions. It flags any subject (the part of a test name before
the first _) that has tests of one bucket in more than one file. Files
limited to some platforms, by a //go:build line or a GOOS/GOARCH file-name
suffix, are exempt. New fixtures in testdata/violations (widget_test.go
and widget_windows_test.go) check that it flags a split and allows the
platform exception.

CONTRIBUTING.md now documents the one-file rule, the platform exception and
the command-path naming in cmd.

Review notes

  • The commits are meant to be reviewed one at a time. git diff --color-moved (or --color-moved=dimmed-zebra) shows that the moved code is
    unchanged.
  • TestSMDDelete_* tables go to smd_errors_test.go, not
    commands_errors_test.go or per-resource tests as the issue suggested. They
    only cover smd, and other single-family tables (TestBootAdd_*,
    TestMetadataAdd_*, TestCloudInit_MalformedSuccessResponses) already sit
    in their family files. The issue's two options would either put a
    single-family table in the cross-family file or change test logic.
    CONTRIBUTING.md documents the resulting rule: tables over every resource
    of one family stay in the family file, error tables across families go to
    commands_errors_test.go, and other cross-family tests go in a file named
    after the behavior they check (prompts_test.go,
    service_status_test.go).
  • The issue suggested renaming the generic subjects outside cmd. Only two
    were too broad to group (TestRuntime, TestFile). The other split
    subjects named one specific function (CheckToken, HandleToken,
    ReadConfigWithDefaults, UseCACert, ShowConsole, LoadMerged), so they
    were moved together instead of renamed.
  • Per-family error tests that repeat a row of a table in
    commands_errors_test.go are left as is. The issue marks that question as
    out of scope.

Manual testing

make lint reuse mod test   # passes; 0 lint issues, no go.mod/go.sum changes

# Same test count as main, plus TestTestFiles_SubjectInOneFile
go test ./... -list . | grep -c '^Test'   # main: 967, this branch: 968

The split-subject script from #190 now reports only the platform-specific
files (sync_windows_test.go; owner*_test.go is //go:build unix) and the
check's own fixtures:

internal/conventions/testdata/violations TestWidget plain widget_more_test.go widget_test.go widget_windows_test.go
pkg/config TestSyncParentDirectory plain sync_test.go sync_windows_test.go
pkg/config TestWriteFile errors owner_errors_test.go write_errors_test.go
pkg/config TestWriteFile plain owner_test.go write_test.go

Checklist

  • My code follows the style guidelines of this project
  • I have added/updated comments where needed
  • I have added tests that prove my fix is effective or my feature works
  • I have run make test (or equivalent) locally and all tests pass
  • I have updated the relevant documentation (CLI examples, man pages, README, other docs, etc.)
    (CONTRIBUTING.md)
  • DCO Sign-off: All commits are signed off (git commit -s) with my real name and email
  • REUSE Compliance:
    • Each new/modified source file has SPDX copyright and license headers
    • Any non-commentable files include a <filename>.license sidecar
    • All referenced licenses are present in the LICENSES/ directory

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Dependency update
  • Build system/CI

@synackd
synackd marked this pull request as ready for review October 23, 2026 04:32
@synackd
synackd requested a review from a team October 23, 2026 04:33
@synackd
synackd force-pushed the test/organize branch 2 times, most recently from 94190fa to 2c98ca0 Compare October 23, 2026 16:26
synackd added a commit that referenced this pull request Oct 23, 2026
Replace the two SMD-specific CA cases with a shared matrix of all 108
network commands to verify trust consistently across the command tree.
Keep the cross-family behavior tests in cacert_test.go to follow the
file organization documented in PR #218.

Check that each command rejects the TLS server without a trusted CA and
succeeds with --cacert. Reuse the same invocations for missing-CA tests
and compare the matrix with network leaf commands exposing --uri so new
commands cannot silently miss CA coverage. Reuse existing payload
fixtures and keep server setup in one place to limit duplication.

Fix the RCS console trust failure exposed by the broader tests. Clone
the WebSocket dialer and use the HTTP client's TLS configuration at dial
time to honor CA certificates loaded after client construction. Keep
trust settings local to each connection instead of changing the shared
dialer. Remove an unused errcheck suppression flagged by lint in the
same file.

Preserve behavior through TLS requests rather than asserting certificate
load counts, which would couple tests to the refactor's implementation.

Validate with go test -race ./... -count=1 and golangci-lint run.

Signed-off-by: Devon Bautista <17506592+synackd@users.noreply.github.com>
synackd added a commit that referenced this pull request Oct 23, 2026
Replace the two SMD-specific CA cases from #216 with a shared matrix of
all 108 network commands to verify trust consistently across the tree.
Keep cross-family behavior tests in cacert_test.go to follow the file
organization documented in #218 without including its reorganization.

Check that each command rejects an untrusted TLS server and succeeds
with --cacert. Reuse the same invocations for missing-CA tests and
compare the matrix with network leaf commands exposing --uri so new
commands cannot silently miss CA coverage. Reuse existing payload
fixtures and keep server setup in one place to limit duplication.

Fix RCS console trust by cloning the WebSocket dialer and the HTTP
client's TLS configuration at dial time. Honor certificates loaded after
client construction and keep trust settings local to each connection.
Explicitly discard post-interrupt read errors to preserve a clean exit
and satisfy both supported local and CI linter versions.

Keep the test server open until the console client sends its WebSocket
close reply and TLS close notification to avoid broken pipes on Linux.
Bound the drain with a read deadline and await the hijacked handler
before ending the test, since httptest.Server.Close does not wait for
it.

Verify behavior through TLS requests rather than counting certificate
loads, which would couple tests to the refactor's implementation.

Validate with make test PARALLEL=4, make coverage PARALLEL=4, 100 race
runs of both console TLS cases, and golangci-lint v2.15.0.

Signed-off-by: Devon Bautista <17506592+synackd@users.noreply.github.com>
Tests of the smd resource commands were spread across smd_test.go,
smd_errors_test.go, smd_write_test.go, and smd_write_errors_test.go as
well as each resource's own files, so the tests for one command had no
single home.

Move each smd group, group member, iface, rfe, and compep test into its
resource's smd_<resource>_test.go or _errors_test.go file, leaving
smd_test.go and smd_errors_test.go with only the commands directly
under smd and the TestSMDDelete_* tables over every smd resource.
Retire smd_write_test.go and smd_write_errors_test.go. No test logic
changes.

Signed-off-by: Devon Bautista <17506592+synackd@users.noreply.github.com>
bss_test.go and bss_errors_test.go held tests for every bss command, and
the boot params set/update tests sat in bss_params_write_test.go and
bss_params_write_errors_test.go, so the tests for one command were split
across files.

Move the boot params, boot script, boot image, and hosts tests into
bss_boot_params_test.go, bss_boot_script_test.go,
bss_boot_image_test.go, and bss_hosts_test.go and their _errors_test.go
companions, leaving bss_test.go and bss_errors_test.go with only the
commands directly under bss. Retire the bss_params_write files. No test
logic changes.

Signed-off-by: Devon Bautista <17506592+synackd@users.noreply.github.com>
The add, set, patch, and delete tests of the boot and metadata commands
sat in boot_write_test.go and metadata_write_test.go (and their
_errors_test.go companions), apart from the other tests of the same
subjects in boot_test.go and metadata_test.go.

Fold the write files into the family files, which hold the tables over
every resource type, and move the tests of a single resource type's
commands into boot_<type>_errors_test.go and metadata_group_test.go. No
test logic changes.

Signed-off-by: Devon Bautista <17506592+synackd@users.noreply.github.com>
cloud_init_test.go held happy-path tests for the group, node, and
defaults commands, whose other tests live in cloud_init_group_test.go
and cloud_init_node_test.go.

Move them into the matching cloud_init_<command>_test.go files, and the
defaults tests into new cloud_init_defaults_test.go and
cloud_init_defaults_errors_test.go files, leaving cloud_init_test.go
with only the service commands. No test logic changes.

Signed-off-by: Devon Bautista <17506592+synackd@users.noreply.github.com>
pcs_test.go and pcs_errors_test.go held the pcs status tests next to
the service ones, and pcs_flags_test.go and pcs_flags_errors_test.go
held one flag test each for subjects whose other tests live elsewhere.

Move the status tests into new pcs_status_test.go and
pcs_status_errors_test.go files, and the flag tests into the files of
the commands they cover, retiring the pcs_flags files. No test logic
changes.

Signed-off-by: Devon Bautista <17506592+synackd@users.noreply.github.com>
rcs_test.go and rcs_errors_test.go hold only tests of the "rcs console"
commands. Rename them rcs_console_test.go and rcs_console_errors_test.go
so the file names follow the command path, as for the other families.

Signed-off-by: Devon Bautista <17506592+synackd@users.noreply.github.com>
"discover static" is the only command under "discover", so its tests
belong in the family files, as the tests of "bss dumpstate" and "bss
history" are in bss_test.go. Rename discover_static_test.go and
discover_static_errors_test.go to discover_test.go and
discover_errors_test.go, and move the one TestDiscoverStatic test in
discover_static_flags_test.go into discover_test.go, retiring the topic
file. No test logic changes.

Signed-off-by: Devon Bautista <17506592+synackd@users.noreply.github.com>
Seven tests in config*_test.go run "version" or "smd group get", not
the "config" commands: they check that the root command loads the
config file and resolves a command's base URI and token from its
cluster. Move them to root_test.go, root_errors_test.go, and a new
root_boundary_test.go, keeping each test's bucket. Rename the two
boundary tests from TestConfig_* to TestRootCommand_* so the TestConfig
boundary tests stay in one file. No test logic changes.

Signed-off-by: Devon Bautista <17506592+synackd@users.noreply.github.com>
The CheckToken, HandleToken, and IOStreams tests were each spread over
two or three files, and TestRuntime_EnvironmentIsolation was named for
the whole Runtime though it tests SetTokenFromEnv.

Move the lone CheckToken and HandleToken tests into cli_test.go with the
others for their method, retiring cli_token_validation_test.go, and the
IOStreams tests (with the reader and writer stubs only they use) into
runtime_test.go beside the IOStreams accessors test. Rename
TestRuntime_EnvironmentIsolation to
TestSetTokenFromEnv_PerRuntimeEnvironment and move it next to the other
SetTokenFromEnv test. No test logic changes.

Signed-off-by: Devon Bautista <17506592+synackd@users.noreply.github.com>
The happy-path ReadConfigWithDefaults tests were split across
clusterdefaults_test.go, configfile_test.go, and validate_test.go.

Move them, with their temp-file helpers, into configfile_test.go next to
the function's other tests, and rename clusterdefaults_errors_test.go
to configfile_errors_test.go to match. No test logic changes.

Signed-off-by: Devon Bautista <17506592+synackd@users.noreply.github.com>
TestUseCACert_FileFailures sat in request_layer_errors_test.go and
TestShowConsole_ReturnsConnectionCloseError in session_errors_test.go,
apart from the other error tests of the same functions. Move them into
client_errors_test.go and rcs_errors_test.go. No test logic changes.

Signed-off-by: Devon Bautista <17506592+synackd@users.noreply.github.com>
The tests in transaction_test.go and transaction_errors_test.go shared
the TestFile_ subject with the per-method tests in file_test.go and
file_errors_test.go, though they cover the staged write that File.Update
performs for every mutation. Rename them TestFileUpdate_* so each file
holds a distinct subject. No test logic changes.

Signed-off-by: Devon Bautista <17506592+synackd@users.noreply.github.com>
loadmerged_test.go held one LoadMerged test and one UserConfigPath test
apart from the others for those functions in config_test.go. Move them
there and retire loadmerged_test.go. No test logic changes.

Signed-off-by: Devon Bautista <17506592+synackd@users.noreply.github.com>
CONTRIBUTING.md's suffix taxonomy implies one file per subject and
bucket, but nothing enforced it, so tests of one subject spread across
several files as new batches added new files.

Add a source check that flags a subject (the part of a test's name
before its first underscore) whose tests in one bucket (plain, _errors,
or _boundary) are in more than one file of a package. Files that build
only on some platforms, by a //go:build constraint or a GOOS/GOARCH file
name suffix, are exempt. Add fixtures for a split subject and an exempt
platform file.

Document the rule in CONTRIBUTING.md, along with naming command tests
after the command path they cover.

Signed-off-by: Devon Bautista <17506592+synackd@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[DEV] Tests for one subject are spread across several files

1 participant