Add focused unit tests for four utility functions in temperature.go:
- extractTempInput: 16 test cases for sensor value extraction
- extractCoreNumber: 18 test cases for core number parsing
- extractHostname: 21 test cases for URL hostname extraction
- normalizeSMARTEntries: 15 test cases for SMART data normalization
70 test cases total covering type conversions, edge cases,
boundary conditions, and error handling paths.
- Test parseProgress: 23 test cases for progress parsing from install.sh output
- Test readLastLines: 11 test cases including edge cases
- Test version pattern validation: 45 test cases for command injection prevention
- Test DockerUpdater and AURUpdater basic functionality
- Fix bug in readLastLines: handle n<=0 to prevent slice bounds panic
Coverage increased from 35.9% to 38.2%
Test coverage for calculateBackoff (exponential backoff calculation),
NotificationQueueStatus constants, and QueuedNotification struct fields.
15 test cases covering backoff timing, cap behavior, and struct defaults.
83 test cases covering classifyStatus, isNumeric, looksLikeUUID,
normalizeSegment, and normalizeRoute functions used for Prometheus
metrics aggregation. Tests cover status code classification, numeric
string validation, UUID format detection, URL segment normalization,
and route path normalization with query param stripping.
Test coverage for pure functions in internal/updates/version.go:
- Version.String() - 6 test cases
- Version.Compare() - 14 test cases (major/minor/patch/prerelease)
- Version.IsNewerThan() - 4 test cases
- Version.IsPrerelease() - 4 test cases
- compareInts() - 7 test cases
- extractRCNumber() - 12 test cases
- envBool() - 17 test cases
- sanitizePrereleaseIdentifier() - 14 test cases
Coverage: 35.2% -> 35.9%
Test normalisePlatform (darwin->macos normalization, case handling,
whitespace trimming) and isLoopback (case-insensitive flag matching).
Package had no tests previously.
Test coverage for titleCase, formatDuration, pluralize, formatMetricValue,
and formatMetricThreshold functions. 71 test cases covering edge cases,
boundary conditions, and all metric type variants.
Tests for parseCIDRs, parseCIDRMap, environmentFromOverride,
shouldPruneContainerNetworks, isLikelyContainerPhase, filterPhasesForEnvironment,
and ApplyConfigToProfile. Coverage increased from 29.0% to 51.0%.
Test coverage for pure utility functions:
- isValidPrivateOrigin: validates private network origins (security)
- normalizeForwardedProto: normalizes ws/wss to http/https for proxies
- sanitizeValue: handles NaN/Inf values in JSON data
- cloneMetadata/cloneMetadataValue: deep copies metadata maps/slices
- cloneAlert/cloneAlertData: deep copies alert structures
Coverage increased from 20.9% to 37.3% (80 test cases).
Test coverage for 9 pure functions in internal/api/diagnostics.go:
- isFallbackMemorySource: 13 cases covering fallback and non-fallback sources
- copyStringSlice: 4 cases including nil handling and copy verification
- normalizeHostForComparison: 16 cases for URL normalization
- normalizeVersionLabel: 11 cases for version prefix handling
- contains: 8 cases for string slice membership
- containsFold: 11 cases for case-insensitive matching
- interfaceToStringSlice: 9 cases for type conversion
- preferredDockerHostName: 5 cases for name preference hierarchy
- formatTimeMaybe: 3 cases for time formatting
- Move normalizeVersion to utils.NormalizeVersion for single source of truth
- Update agentupdate and dockeragent packages to use shared function
- Add 14 test cases for version normalization
This prevents bugs like issue #773 where a fix applied to one copy
but not the other caused an update loop.
Tests for calculateCPUPercent, calculateMemoryUsage, safeFloat,
parseTime, trimLeadingSlash, and summarizeBlockIO. 28 test cases
covering edge cases like zero deltas, cache handling, NaN/Inf,
and case-insensitive op matching.
Coverage improved from 8.0% to 11.7%.
The function was using substring matching for sensitive param names,
causing parameters like "extra_token" or "myapikey" to be incorrectly
redacted when they matched "token=" or "apikey=" as substrings.
Now checks for proper boundary characters (? or &) before matching,
so only actual parameter names are redacted.
Related to ADA knowledge entry: "Query param redaction uses substring matching"
Tests cover the hostname lookup paths in HandleLookup:
- Exact hostname match (case-insensitive)
- DisplayName match (case-insensitive)
- Short hostname match (before first dot)
- Priority of exact over short match
- Sorted iteration order behavior
- Not-found cases
12 test cases covering all hostname matching code paths.
Test coverage for isCephStorageType, countServiceDaemons,
extractCephCheckSummary, and summarizeCephHealth functions.
These parse Ceph storage types and health status JSON.
Add comprehensive test coverage for security-critical URL and token
sanitization functions in config_handlers.go. These functions protect
the setup script endpoint from injection attacks.
TestSanitizeInstallerURL (23 cases): empty/whitespace handling, valid
http/https URLs, fragment stripping, query preservation, control character
rejection, invalid scheme rejection (ftp/file/javascript/data), and
missing host validation.
TestSanitizeSetupAuthToken (19 cases): empty/whitespace handling, valid
hex tokens of various lengths (32-128 chars), mixed case hex, control
character rejection, non-hex character rejection, and length validation.
The Telegram bot token redaction had an off-by-one bug: it searched for
the next "/" starting from the "/bot" position, which found the "/" in
"/bot" itself (offset 0) instead of the next "/" after the token.
Result: tokens were not properly redacted and the URL got corrupted with
duplicated path segments, potentially leaking secrets to logs/API responses.
Fix: search from idx+4 (after "/bot") and handle edge cases where there's
no trailing slash (token at end of URL or before query string).
Added 20 comprehensive test cases covering:
- No secrets (passthrough)
- Telegram bot tokens (various patterns)
- Query parameter secrets (token, apikey, api_key, key, secret, password)
- Multiple parameters and edge cases
Extract command status normalization logic from HandleCommandAck into
a dedicated helper function. This improves testability and makes the
status alias handling explicit and documented.
The function accepts client-provided status strings and maps them to
internal status constants:
- acknowledged: "", "ack", "acknowledged"
- completed: "success", "completed", "complete"
- failed: "fail", "failed", "error"
Adds 25 table-driven test cases covering all aliases, case insensitivity,
whitespace handling, and invalid inputs.
Test normalizeLabel, normalizeNodeLabel, splitInstanceKey,
breakerStateToValue, sanitizeInstanceLabels, makeMetricKey,
and makeNodeMetricKey with 36 test cases covering edge cases
like empty strings, whitespace, and invalid inputs.
Move the inline filesystem skip logic from pollVMsAndContainersEfficient
into a reusable ShouldSkipFilesystem function. This consolidates filtering
for virtual filesystems (tmpfs, cgroup, etc.), network mounts (nfs, cifs,
fuse), and special mountpoints (/dev, /proc, /snap, etc.) into one tested
location.
Reduces cyclomatic complexity of pollVMsAndContainersEfficient and adds
28 test cases covering virtual fs types, network mounts, special mounts,
Windows paths, and edge cases.
When api_tokens.json is modified on disk, the ConfigWatcher reloads
the tokens into memory. However, the Monitor's dockerTokenBindings and
hostTokenBindings maps were not synchronized with the new token set,
causing orphaned bindings when agents reconnect after reinstall.
Add SetAPITokenReloadCallback to ConfigWatcher that triggers Monitor's
new RebuildTokenBindings method after token reload. This method
reconstructs the binding maps from current Docker host and host agent
state, keeping only bindings for tokens that still exist in config.
Related to #773
- Add StackedMemoryBar component to visualize Active/Balloon/Swap memory
- Integrate StackedMemoryBar into NodeSummaryTable, GuestRow, HostsOverview, and DockerUnifiedTable
- Add TemperatureGauge component for temperature visualization
- Standardize replication job status indicators with StatusDot
- Fix mock data generator to use realistic balloon memory values (0 by default, small % when active)
- Add StackedContainerBar for Docker container status visualization
- Add ZFSHealthMap component for storage pool health visualization
The unified agent got the version normalization fix (1b866598), but the
standalone docker agent's checkForUpdates() still used direct string
comparison. When server returns "4.34.0" and agent has "v4.34.0", this
caused an infinite self-update loop.
Apply the same normalizeVersion() function used in the unified agent.
Related to #773
When systemUsage counter goes backward (common in unprivileged LXC
containers), the previous code used the absolute value as systemDelta.
This created an artificially small denominator, inflating CPU to ~100%.
Now leaves systemDelta as 0 on counter reset, falling through to the
time-based calculation which produces accurate results.
Related to #770
- Add hideLocalLogin handler in HandleUpdateSystemSettings() so the
toggle setting is saved to system.json
- Conditionally hide "or" divider and admin credentials message when
local login is hidden
Related to #750
The agent's CurrentVersion includes the "v" prefix (e.g., "v4.33.1") but
the server's /api/agent/version endpoint returns versions without it
(e.g., "4.33.1"). This caused the comparison to always fail, triggering
an infinite self-update loop every 30 seconds.
Normalize both versions by stripping the "v" prefix before comparison.
Related to #740
- Default enableDocker to false in UI to prevent unintended Docker
agent activation on host-only installs (Related to #766)
- Deploy agent scripts and binaries during web UI upgrades, not just
the main binary (Related to #760)
- Apply symlink resolution fix to standalone docker agent self-update
to prevent cross-device rename failures (Related to #737)
- Add content hash check to config watcher polling path to match fsnotify
behavior, preventing unnecessary restarts when .env is touched but
content unchanged (Related to #748)
- Change settings sidebar to expanded by default and persist user
preference using usePersistentSignal (Related to #764)
Remove ~900 lines of unused code identified by static analysis:
Go:
- internal/logging: Remove 10 unused functions (InitFromConfig, New,
FromContext, WithLogger, etc.) that were built but never integrated
- cmd/pulse-sensor-proxy: Remove 7 dead validation functions for a
removed command execution feature
- internal/metrics: Remove 8 unused notification metric functions and
10 Prometheus metrics that were never wired up
Frontend:
- Delete ActivationBanner.tsx stub component
- Remove unused exports: stopMetricsSampler, getSamplerStatus,
formatSpeedCompact, parseMetricKey, getResourceAlerts
Mark intentionally unused parameters with underscore to:
- Silence unparam warnings for legitimate unused parameters
- Keep function signatures intact for API compatibility
- Remove unused req from serveChecksum helper
- Replace custom maxInt64 helper with Go 1.21+ builtin max()
- Mark unused cfg parameter in newAdaptiveIntervalSelector
- Remove test for deleted helper function
- Use container.Summary instead of types.Container
- Use swarmtypes.ServiceListOptions instead of types.ServiceListOptions
- Use swarmtypes.TaskListOptions instead of types.TaskListOptions
These types were deprecated in favor of package-specific types.