Testing

May 27, 2026 · View on GitHub

This document describes vissr's unit-test and fuzz-test infrastructure as of the broad-coverage push landed alongside the stability/security batches (commit ef639f0 plus PRs #119, #120, #121, #122 and the present comprehensive-coverage PR).

Running the test suite

go test ./...

runs the entire test suite.

The paths to the different unit tests can be explicitly provided, enabling test of a reduced set of unit tests. Shown below are the paths to the complete set of unit tests as of 27-05-2026.

go test \
    ./utils \
    ./server/vissv2server \
    ./server/vissv2server/atServer \
    ./server/vissv2server/serviceMgr \
    ./server/vissv2server/mqttMgr \
    ./server/vissv2server/wsMgr \
    ./server/vissv2server/wsMgrFT \
    ./server/vissv2server/udsMgr \
    ./server/vissv2server/grpcMgr \
    ./server/agt_server \
    ./client/client-1.0/compress_client \
    ./client/client-1.0/csv_client \
    ./client/client-1.0/filetransfer_client \
    ./client/client-1.0/grpc_client \
    ./client/client-1.0/testClient \
    ./feeder/feeder-rl \
    ./feeder/feeder-template/feederv4 \
    ./feeder/feeder-evic \
    ./feeder/feeder-evic/evicSim

Race-detector tests

Tests for the mutex fixes shipped across the security batches (WsClientIndexMu, sessionListMu, jtiCacheMu in atServer and agt_server, udsClientIndexMu, grpcStateMu) are designed to fail under go test -race if the mutex protecting their shared state is removed. Run:

go test -race ./server/vissv2server/atServer \
              ./server/vissv2server/wsMgrFT \
              ./server/vissv2server/udsMgr \
              ./server/vissv2server/grpcMgr \
              ./server/agt_server \
              ./utils

Fuzz tests

Native Go fuzz harnesses cover parsers that consume attacker- controlled input. Run an individual fuzzer for ~30s:

go test -run='^$' -fuzz=FuzzValidateTransferName -fuzztime=30s \
    ./server/vissv2server/wsMgrFT

Run all of them in turn (CI nightly):

fuzzers=(
    'FuzzValidateTransferName   ./server/vissv2server/wsMgrFT'
    'FuzzSafeServerFilename     ./client/client-1.0/filetransfer_client'
    'FuzzEncodeDlRequest        ./client/client-1.0/filetransfer_client'
    'FuzzExtractKeyValue        ./server/vissv2server/atServer'
    'FuzzProcessHistoryCtrl     ./server/vissv2server/serviceMgr'
    'FuzzProcessHistoryGet      ./server/vissv2server/serviceMgr'
    'FuzzMapRequest             ./utils'
    'FuzzJsonSchemaValidate     ./utils'
    'FuzzGetFileDescriptorData  ./server/vissv2server'
    'FuzzGetRangeBoundaries     ./server/vissv2server'
    'FuzzGetValueForKey         ./server/vissv2server/wsMgr'
    'FuzzCompressTs             ./server/vissv2server/wsMgr'
)
for entry in "${fuzzers[@]}"; do
    set -- $entry
    echo "==== \$1 ===="
    go test -run='^$' -fuzz="\$1" -fuzztime=30s "\$2" || exit 1
done

Failures land under testdata/fuzz/<FuzzerName>/. Commit any that surface real bugs as part of the fix; the file then becomes a seed corpus entry.

Coverage by area

Regression coverage of the stability/security batches (PR #122)

Fix areaTest file
validateTransferName path traversal (wsMgrFT)server/vissv2server/wsMgrFT/wsMgrFT_test.go
getDataSessionIndex claim step + sessionListMu raceserver/vissv2server/wsMgrFT/wsMgrFT_test.go
safeServerFilename client-side path traversalclient/client-1.0/filetransfer_client/filetransfer_client_test.go
extractKeyValue safe type-assert (atServer)server/vissv2server/atServer/atServer_fixes_test.go
jtiCache mutex (atServer, agt_server)server/vissv2server/atServer/atServer_fixes_test.go, server/agt_server/agt_server_test.go
AGT / AT / HTTP POST body limits (MaxBytesReader)server/agt_server/agt_server_test.go, server/vissv2server/atServer/atServer_fixes_test.go, utils/managerhandlers_test.go
processHistoryCtrl panic + index + bufSize capserver/vissv2server/serviceMgr/serviceMgr_test.go
processHistoryGet panic + indexserver/vissv2server/serviceMgr/serviceMgr_test.go
activate/deactivateInterval ticker-leakserver/vissv2server/serviceMgr/serviceMgr_test.go
getBrokerSocket env-var / fallback / TLS (mqttMgr)server/vissv2server/mqttMgr/mqttMgr_test.go
JsonSchemaValidate nil-deref guardutils/common_fixes_test.go
WsClientIndexMu raceutils/managerhandlers_test.go
udsClientIndexMu race + -1 pool-exhaustion guardserver/vissv2server/udsMgr/udsMgr_test.go
grpcStateMu raceserver/vissv2server/grpcMgr/grpcMgr_test.go
getFileDescriptorData type-assert (vissv2server)server/vissv2server/vissv2server_test.go
TouchFile mode 0644feeder/feeder-rl/feeder-rl_test.go
onNotificationList lookup contractfeeder/feeder-template/feederv4/feederv4_test.go

Broader coverage of pure helpers (PR #122)

AreaTest file
utils.IsNumber, IsBoolean predicatesutils/common_broader_test.go
utils.PathToUrlUrlToPath round-triputils/common_broader_test.go
utils.GetMaxValidationutils/common_broader_test.go
utils.ExtractRootNameutils/common_broader_test.go
utils.GenerateHmac / VerifyTokenSignature round-trip + tamperutils/common_broader_test.go
utils.AddKeyValue no-Marshal value injectionutils/common_broader_test.go
utils.MapRequest fuzzutils/common_fixes_test.go
wsMgr.getValueForKey, getSortedPaths, dcCacheserver/vissv2server/wsMgr/wsMgr_test.go

Whole-subsystem coverage (this PR)

vissv2server core

HelperTest file
extractMgrId (mgrId?clientId parser)server/vissv2server/vissv2server_helpers_test.go
getPathLen (NUL-aware buffer length)server/vissv2server/vissv2server_helpers_test.go
countPathSegmentsserver/vissv2server/vissv2server_helpers_test.go
getTokenErrorMessage (all indices)server/vissv2server/vissv2server_helpers_test.go
setTokenErrorResponseserver/vissv2server/vissv2server_helpers_test.go
singleToDoubleQuoteserver/vissv2server/vissv2server_helpers_test.go
extractNoScopeElementsLevel1 / Level2server/vissv2server/vissv2server_helpers_test.go
getTokenContext (safe defaults)server/vissv2server/vissv2server_helpers_test.go
removeLocalPropertyserver/vissv2server/vissv2server_helpers_test.go
getInternalFileNameserver/vissv2server/vissv2server_helpers_test.go
calculateHash (SHA-1)server/vissv2server/vissv2server_helpers_test.go
getRangeBoundary / getRangeBoundariesserver/vissv2server/vissv2server_helpers_test.go
FuzzGetRangeBoundariesserver/vissv2server/vissv2server_helpers_test.go

wsMgr (beyond pure helpers covered in PR #122)

HelperTest file
getDcConfigserver/vissv2server/wsMgr/wsMgr_helpers_test.go
setDcValue (pc + tsc parsing)server/vissv2server/wsMgr/wsMgr_helpers_test.go
dcCacheInsert / getDcCacheIndex / resetDcCache / updatepayloadId lifecycleserver/vissv2server/wsMgr/wsMgr_helpers_test.go
signedTimeDiffserver/vissv2server/wsMgr/wsMgr_helpers_test.go
compressTs malformed-JSON rejectionserver/vissv2server/wsMgr/wsMgr_helpers_test.go
getDpTsList (single / array / unknown)server/vissv2server/wsMgr/wsMgr_helpers_test.go
FuzzGetValueForKey, FuzzCompressTsserver/vissv2server/wsMgr/wsMgr_helpers_test.go

grpcMgr (beyond mutex tests covered in PR #122)

HelperTest file
getSubscriptionId (valid / missing / malformed JSON)server/vissv2server/grpcMgr/grpcMgr_helpers_test.go
extractClientId (valid + malformed parse)server/vissv2server/grpcMgr/grpcMgr_helpers_test.go

Clients (client/client-1.0/)

ClientTest file
compress_clientclient/client-1.0/compress_client/compress_client_test.go
csv_clientclient/client-1.0/csv_client/csv_client_test.go
filetransfer_clientclient/client-1.0/filetransfer_client/filetransfer_client_helpers_test.go
grpc_clientclient/client-1.0/grpc_client/grpc_client_test.go
testClientclient/client-1.0/testClient/testClient_test.go

Each covers the pure helpers in that client (path conversion, JSON parsing, request marshalling, file reading). Network-driven entry points are tested via runtest.sh integration.

Feeders

FeederTest file
feeder-rlfeeder/feeder-rl/feeder-rl_test.go (PR #122)
feeder-template/feederv4feeder/feeder-template/feederv4/feederv4_helpers_test.go
feeder-evicfeeder/feeder-evic/evicFeeder_test.go
feeder-evic/evicSimfeeder/feeder-evic/evicSim/evicSim_test.go

Covers fileExists, deSerializeUInt (1/2/4-byte), inFeederScope, splitToDomainDataAndTs, convertToDomainData, makeDataPoint, calcInputValue, incDpIndex, enumConversion, linearConversion.

Functions that need code refactoring to be unit-testable

Documented inline as TODO(testing): comments in each test file. Listed here for visibility:

FunctionWhy not testableRefactor approach
mqttMgr::createSubscribeClient, publishMessage (post-os.Exit removal)The fix is "absence of process exit". Helpers are wrapped around MQTT.NewClient.Extract a client-factory function so a mock MQTT.Client can be injected.
vissv2server::issueServiceRequest dt[:5] panic fixInline in the main message-dispatch goroutine.Extract the SET-on-struct-Type branch into a function that takes (requestMap, dt).
vissv2server::initiateFileTransfer uid bounds checkEmbedded in channel-driven flow.Extract validateFileDescriptorUid([]byte) error; call from initiateFileTransfer.
feederv4::feederRegister, statestorageSetCoupled to live UDS / SQLite / Redis / memcache.Inject a storage interface; mock for tests.
feederv4::udsReader, udsWriterInline goroutine loops driving channels.Extract per-message dispatch function; test it directly.
feederv4::simulateInput, selectRandomInput, getRandomVssfMapIndexNon-deterministic (math/rand).Inject *rand.Rand; seed in tests.
feeder-evic::statestorageSet, udsReader/Writer, canDriverClient, serverSession, reDialerCoupled to live network / DB.Same shape: inject interfaces / extract per-message handlers.
All client initWebSocket*, controlClient, dataClient, downloadFile, uploadFileNeed a running vissv2server.Already integration-tested via runtest.sh.
grpcMgr::GetRequest, SetRequest, UnsubscribeRequest, SubscribeRequestStreaming gRPC handlers; need a full gRPC fixture.Extract per-request body into a function taking plain Go values; test the helper.
httpMgr (entire package)Two functions, both giant goroutine loops with no extractable pure-function surface.Refactor HttpMgrInit to call out to a handleRequest(msg) string helper.

Subsystems with genuinely no .go code

  • server/vissv2server/forest/ — VSS-tree binary data files only.
  • server/transport_sec/ — TLS certs and transportSec.json config only.
  • client/client-1.0/Javascript/, mqtt_client/, transport_sec/ — no Go code (JS client, certs, sample configs).

Note on .gitignore

The repo's .gitignore has unanchored patterns feeder and agt_server (lines 30, 53) that silently swallow any path with those names — multiple test files in this PR and PR #122 needed git add -f. The patterns should be anchored (/feeder/feeder-template/feederv4/feeder for the actual built binary, etc.) in a separate cleanup PR.

Note on dependency between PRs

This test PR depends on PRs #119, #120, #121, and #122 being merged first. The tests reference helpers and mutexes added across those batches; without them, go test against this branch alone will not build. Once the four prior PRs land, the full suite builds and passes.