Commit graph

1223 commits

Author SHA1 Message Date
rcourtman
0657fca003 Fix docker-compose command not found in integration tests
Replace deprecated docker-compose with docker compose (Docker CLI plugin)
on modern Ubuntu runners.
2025-12-01 00:40:00 +00:00
rcourtman
679a20dfa4 Add unit tests for monitoring utility functions
Added comprehensive tests for 6 previously untested pure utility functions:
- sortContent: sorts comma-separated storage content values
- formatSeconds: converts total seconds to HH:MM:SS format
- dedupeStringsPreserveOrder: deduplicates strings while preserving order
- sanitizeGuestAddressStrings: validates and filters IP addresses
- copyFloatPointer: creates independent copy of float64 pointer
- clampInterval: clamps time.Duration to specified bounds

Tests cover edge cases including empty inputs, boundary conditions,
special values (DHCP, loopback addresses), and various separators.
Coverage increased from 36.8% to 37.5%.
2025-12-01 00:37:24 +00:00
rcourtman
6c18849f79 Add unit tests for cluster_client utility functions
Test coverage for error detection and retry logic:
- extractStatusCode: 13 test cases for HTTP status code extraction
- isTransientRateLimitError: 17 test cases for rate limit detection
- isNotImplementedError: 14 test cases for 501 error detection
- isVMSpecificError: 16 test cases for VM-scoped errors
- calculateRateLimitBackoff: backoff timing verification
- isAuthError: 12 test cases for authentication errors

Coverage 35.5% → 37.3%
2025-12-01 00:24:21 +00:00
rcourtman
0c648907a4 Add unit tests for RecoveryTokenStore
20 test cases covering:
- Token generation (uniqueness, expiry durations, format)
- Token validation (valid, invalid, expired, used, empty store)
- Concurrent use protection (replay attack prevention)
- Cleanup routine (expired tokens, used tokens, stop signal)
- Persistence (save, load, filter expired on load)
- Edge cases (missing file, invalid JSON)
2025-12-01 00:06:32 +00:00
rcourtman
69e87abf4e Add unit tests for normalizePVEUser and shouldSkipClusterAutoDetection 2025-11-30 23:53:41 +00:00
rcourtman
820f822476 Fix integration tests workflow missing frontend npm ci 2025-11-30 23:50:31 +00:00
rcourtman
8d3777858e Fix memory bar width not scaling correctly
The StackedMemoryBar component was using flex layout for segments,
but flex children grow by default regardless of percentage width.
Changed to absolute positioning (like MetricBar uses) so the width
percentages actually work as expected.

Related to #788
2025-11-30 23:46:56 +00:00
rcourtman
2d87746eb0 Add unit tests for security lockout and session management functions
Tests for internal/api/security.go:
- RecordFailedLogin: increments counts, triggers lockout at max attempts
- ClearFailedLogins: clears count and lockout state
- GetLockoutInfo: returns correct attempts/lockout status
- ResetLockout: admin lockout reset functionality
- TrackUserSession: user/session tracking
- GetSessionUsername: session lookup
- clearCSRFCookie: nil safety, cookie attributes
- issueNewCSRFCookie: nil safety, empty session handling
- FailedLogin/AuditEvent struct field validation

30 test cases covering lockout, session tracking, and CSRF functions.
2025-11-30 23:33:51 +00:00
rcourtman
b41611db72 Add unit tests for SessionStore (internal/api)
Coverage for sessionHash, CreateSession, ValidateSession,
ValidateAndExtendSession, DeleteSession, persistence, and cleanup.
21 test cases covering session lifecycle, expiration handling,
and disk persistence. Coverage 25.0% → 25.3%.
2025-11-30 23:18:34 +00:00
rcourtman
83303b61b9 Add unit tests for auth helper functions (internal/api)
Tests for detectProxy, isConnectionSecure, getCookieSettings, and
generateSessionToken functions. Covers proxy detection for various
headers including X-Forwarded-For, CF-Ray, Forwarded (RFC 7239),
and secure connection detection via TLS and proxy headers.
2025-11-30 23:04:44 +00:00
rcourtman
fb27ff7c75 Add unit tests for bootstrap token functions (internal/api)
20 test cases covering:
- generateBootstrapToken: uniqueness, format, hex encoding
- loadOrCreateBootstrapToken: new token creation, existing token loading,
  empty/whitespace paths, empty token files, directory creation, file permissions
- bootstrapTokenValid: nil router safety, empty hash/token handling
- clearBootstrapToken: nil safety, file deletion, state clearing

First test file for bootstrap_token.go security utilities.
2025-11-30 22:54:28 +00:00
rcourtman
fe4db29941 Add unit tests for diagnostic snapshot key generation functions
32 test cases covering makeNodeSnapshotKey and makeGuestSnapshotKey
utility functions used for diagnostic memory snapshot storage. Tests
cover simple inputs, edge cases (empty strings, negative VMIDs),
special characters, and key uniqueness verification. Also includes
struct field tests for NodeMemoryRaw and VMMemoryRaw.

First test file for diagnostic_snapshots.go. Coverage 36.7% → 36.8%.
2025-11-30 22:34:09 +00:00
rcourtman
c1fdb77b2c Add unit tests for UpdaterRegistry (internal/updates)
27 test cases covering:
- NewUpdaterRegistry initialization
- Register and Get operations
- Overwrite behavior when re-registering
- Error handling for unregistered deployment types
- Multiple deployment types
- UpdateRequest, UpdatePlan, UpdateProgress struct fields
- Mock updater interface compliance

Coverage 41.1% → 41.5%.
2025-11-30 22:19:06 +00:00
rcourtman
8361042ada Fix backup status indicator not showing for guests
The backup status indicator feature was incomplete - it added the UI
component but never populated VM/Container LastBackup from actual
backup data. Now SyncGuestBackupTimes() is called after storage
backups and PBS backups are polled, matching each guest's VMID to
its most recent backup timestamp.

Fixes #786
2025-11-30 22:13:46 +00:00
rcourtman
0b62038cab Fix host agent type badge flapping in UI
Add transient empty payload protection for hosts data, matching the
existing protection for dockerHosts. When a websocket message contains
an empty hosts array (transient state), the UI now waits for 3
consecutive empty payloads before applying the change.

This prevents the "Host" type badge from disappearing intermittently
in Settings → Agents → Managed Agents when the unified agent is
reporting both host and docker data.

Related to #773
2025-11-30 22:07:40 +00:00
rcourtman
18635fe960 Add unit tests for isRetryableWebhookError (internal/notifications)
47 test cases covering webhook retry logic classification:
- Network errors: timeout, connection refused/reset, DNS lookup, network unreachable
- HTTP 5xx server errors: all status codes 500-599 (retryable)
- HTTP 4xx client errors: all status codes 400-499 except 429 (not retryable)
- HTTP 429 rate limiting: special case (retryable)
- Case insensitivity verification
- Real-world error message patterns from Go net/http
- All status code boundary tests

Coverage 37.4% -> 38.0%.
2025-11-30 22:03:26 +00:00
rcourtman
3a84fab6d0 Add unit tests for State methods (internal/models)
51 test cases covering Docker host and generic Host state management:
- UpsertDockerHost, RemoveDockerHost, GetDockerHosts
- SetDockerHostStatus, SetDockerHostHidden, SetDockerHostPendingUninstall
- SetDockerHostCommand, SetDockerHostCustomDisplayName
- TouchDockerHost, RemoveStaleDockerHosts
- AddRemovedDockerHost, RemoveRemovedDockerHost, GetRemovedDockerHosts
- UpsertHost, GetHosts, RemoveHost, SetHostStatus, TouchHost
- UpdateRecentlyResolved

Coverage 44.0% → 68.3%.
2025-11-30 21:49:43 +00:00
rcourtman
0ad83bf27e Fix WORKFLOW_PAT secret reference syntax 2025-11-30 21:34:27 +00:00
rcourtman
d65a2fc87a Add unit tests for MetricsHistory (internal/monitoring)
58 test cases covering:
- NewMetricsHistory: constructor and initialization (4 cases)
- appendMetric: time-series append with retention and max limits (5 cases)
- cleanupMetrics: old point removal with cutoff time (5 cases)
- AddGuestMetric: all 7 metric types + unknown type handling (8 cases)
- AddNodeMetric: cpu/memory/disk + unknown type (4 cases)
- AddStorageMetric: usage/used/total/avail + unknown type (5 cases)
- GetGuestMetrics: duration filtering, nonexistent, zero duration (6 cases)
- GetNodeMetrics: duration filtering and edge cases (5 cases)
- GetAllGuestMetrics: multi-metric retrieval (3 cases)
- GetAllStorageMetrics: storage metric retrieval (2 cases)
- Cleanup: retention enforcement across all metric types (1 case)
- Multiple guests isolation: verify metrics don't leak (1 case)
- MaxDataPoints enforcement: oldest points dropped (1 case)
- RetentionTime enforcement: old points removed on append (1 case)

First comprehensive unit test file for metrics_history.go core
functions. Existing concurrency test in separate file.
2025-11-30 21:34:07 +00:00
rcourtman
120474d1f5 Use WORKFLOW_PAT for demo server dispatch if available 2025-11-30 21:31:39 +00:00
rcourtman
cb939c3532 Add unit tests for HTTPClient (internal/tempproxy)
23 test cases covering NewHTTPClient, IsAvailable, GetTemperature,
and HealthCheck including success paths, error handling (401, 403,
429, 5xx), JSON parsing, URL encoding, retry behavior, and connection
errors.

Coverage: 22.4% → 47.6%
2025-11-30 21:18:14 +00:00
rcourtman
5d61864495 Add unit tests for importTransaction (internal/config)
24 test cases covering transaction lifecycle: staging, commit, rollback, and cleanup.
Tests include atomic commit behavior, backup/restore on failure, directory creation,
permission handling, and idempotent cleanup.

First test file for import_transaction.go. Coverage 42.4% → 42.7%.
2025-11-30 21:04:41 +00:00
rcourtman
973f1f9866 Fix SSH key collision when installing sensor-proxy on multiple cluster nodes
When running install-sensor-proxy.sh on multiple nodes in a cluster, each
installation was removing all existing pulse-managed-key entries before
adding its own. This caused the following scenario:

1. Run script on node A: node A's key is added to all nodes
2. Run script on node B: node B's key replaces node A's key on all nodes
3. Result: node A's proxy can no longer SSH to other nodes

The fix changes the behavior to:
- Check if the specific SSH key already exists on the target
- Only add the key if not present (idempotent)
- Never remove existing pulse-managed-key entries

This allows multiple sensor-proxy installations to coexist in a cluster,
with each node's proxy key authorized on all nodes.

Related to #738
2025-11-30 21:03:36 +00:00
rcourtman
59a77ddecc Bump version to 4.35.0 2025-11-30 20:51:26 +00:00
rcourtman
33e3744f08 Add unit tests for GuestMetadataStore (internal/config)
22 test cases covering CRUD operations (Get, GetAll, Set, Delete,
ReplaceAll), persistence (Load, save with atomic write, directory
creation), legacy ID migration (GetWithLegacyMigration for clustered
and standalone formats), round-trip verification, and concurrency.

First test file for guest_metadata.go, complementing the similar
docker_metadata_test.go added in previous run.
2025-11-30 20:48:05 +00:00
rcourtman
0223a52f82 Fix cluster proxy token collision - store per-node control tokens
When multiple cluster nodes register sensor-proxy, each registration
was overwriting the previous node's control token on the shared
PVEInstance. This caused "Proxy token not recognized" errors on all
but the last-registered node.

Changes:
- Add TemperatureProxyControlToken field to ClusterEndpoint struct
- Store control tokens per-endpoint for cluster registrations
- Check both instance-level and endpoint-level tokens when validating

Related to #738
2025-11-30 20:37:58 +00:00
rcourtman
bb2090bb26 Add unit tests for UpdateHistory (internal/updates)
47 test cases covering:
- NewUpdateHistory: directory creation, loading existing entries
- CreateEntry: event ID generation, timestamp handling, persistence
- UpdateEntry: updates, persistence verification, error handling
- GetEntry: retrieval by ID, non-existent entry errors
- ListEntries: filtering by status/action/deployment type, limits
- GetLatestSuccessful: finding recent successful entries
- Cache management: trimming when exceeding max size
- LoadCache: malformed JSON handling, empty lines
- Type definitions and constant validation
2025-11-30 20:34:40 +00:00
rcourtman
94c54ae1df Add unit tests for DockerMetadataStore (internal/config)
22 test cases covering:
- Get/GetAll: retrieval of container/service metadata
- GetHostMetadata/GetAllHostMetadata: retrieval of host metadata
- Set: add/update metadata with persistence
- SetHostMetadata: add/update/delete host metadata
- Delete: remove container metadata
- ReplaceAll: bulk replace with nil entry handling
- Load: versioned format, legacy format, nonexistent file, invalid JSON
- Save: directory creation, atomic write
- Round-trip: full persistence cycle verification
- Concurrent access safety

First test file for docker_metadata.go.
2025-11-30 17:20:46 +00:00
rcourtman
97672b4701 Add unit tests for validation utility functions (pulse-sensor-proxy)
Add 42 test cases for security-critical validation utility functions:

- TestStripNodeDelimiters (10 cases): IPv6 bracket handling, edge cases
- TestParseNodeIP (10 cases): IPv4/IPv6 parsing with bracket support
- TestNormalizeAllowlistEntry (11 cases): case normalization, whitespace
  handling, IPv6 full form compression
- TestIPAllowed (11 cases): CIDR matching, hosts map lookup, nil handling

These functions are used for node allowlist validation to prevent SSRF
attacks in the sensor proxy.
2025-11-30 17:04:43 +00:00
rcourtman
8b851bc80b Add unit tests for mdadm parseDetail function 2025-11-30 16:42:12 +00:00
rcourtman
1678f4cc88 Add unit tests for OIDC configuration helpers
Test coverage for internal/config/oidc.go functions:
- normaliseList: 8 cases for deduplication, trimming, empty handling
- parseDelimited: 8 cases for comma/space separation
- DefaultRedirectURL: 7 cases for URL construction
- OIDCConfig.Clone: 2 cases for deep copy behavior
- OIDCConfig.ApplyDefaults: 9 cases for defaults and normalization
- OIDCConfig.Validate: 9 cases for validation rules
- OIDCConfig.MergeFromEnv: 5 cases for environment variable merging
- NewOIDCConfig: constructor verification

Total: 56 new test cases (583 lines).
2025-11-30 16:22:43 +00:00
rcourtman
dc76294ce1 Add unit tests for discovery package utility functions
Test coverage for pure utility functions: friendlyPhaseName,
defaultProductsForPort, cloneHeader, copyMetadata, and
ensurePolicyDefaults.
2025-11-30 16:05:11 +00:00
rcourtman
4431c8773e Add unit tests for security.go IP parsing utilities
- extractRemoteIP: 17 test cases for remote address parsing
  (IPv4/IPv6 with/without ports, bracketed notation, edge cases)
- firstValidForwardedIP: 21 test cases for X-Forwarded-For parsing
  (single/multiple IPs, invalid entries, IPv4/IPv6 mixed)
- isPrivateIPExtended: 33 test cases extending existing coverage
  (RFC 1918 boundaries, loopback range, IPv6 private/local, ports)

Total: 71 new test cases for IP address handling utilities.
2025-11-30 15:48:45 +00:00
rcourtman
14081a0aaf Add unit tests for router.go proxy header utility functions (api)
Add 77 test cases for 4 previously untested utility functions:
- firstForwardedValue: 14 cases for X-Forwarded-For header parsing
- sanitizeForwardedHost: 27 cases for host sanitization with scheme/port handling
- isLoopbackHost: 20 cases for loopback detection (localhost, 127.x, ::1)
- shouldAppendForwardedPort: 16 cases for port appending decisions

Key edge cases covered:
- IPv6 address bracket handling in sanitizeForwardedHost
- Case-insensitive localhost detection
- Full 127.0.0.0/8 loopback range validation
- strconv.Atoi accepts negative port strings (documented as current behavior)
2025-11-30 15:34:32 +00:00
rcourtman
786a78af85 Add unit tests for dedupeUint32 and dedupeStrings (pulse-sensor-proxy) 2025-11-30 15:26:42 +00:00
rcourtman
f5a48c7445 Add unit tests for normalizeUnifiedAgentArch and getClientIP (api)
Tests for unified_agent.go:
- normalizeUnifiedAgentArch: 51 test cases covering all supported
  architectures (linux/darwin/windows), case insensitivity,
  whitespace handling, and invalid inputs

Tests for updates.go:
- getClientIP: 18 test cases covering X-Forwarded-For priority,
  X-Real-IP fallback, RemoteAddr extraction, IPv4/IPv6 support,
  nil header safety, and case insensitivity
2025-11-30 15:05:37 +00:00
rcourtman
ad17e29420 Add unit tests for CSRF token store (api) 2025-11-30 14:55:47 +00:00
rcourtman
305d0d468c Add unit tests for responseWriter middleware wrapper (api)
Tests for the responseWriter struct in middleware.go:
- APIError.Error() interface implementation (3 cases)
- WriteHeader once-only semantics (4 cases)
- Write with implicit WriteHeader (3 cases)
- StatusCode nil safety (4 cases)
- Hijack support detection (2 cases)
- Flush support detection (3 cases)
- Full flow integration and edge cases (4 cases)

First test file for middleware.go. 22 test cases total covering
HTTP response wrapper behavior used by ErrorHandler middleware.
2025-11-30 14:33:38 +00:00
rcourtman
48af5615b9 Add unit tests for pulse-sensor-proxy utility functions
- hashIPToUID: 11 test cases covering IP hashing for rate limiting
  (determinism, range bounds, collision detection, boundary values)
- extractNodesFromYAML: 17 test cases covering YAML node list parsing
  (map format, list format, mixed types, edge cases)

First test files for config_cmd.go and http_server.go utilities.
2025-11-30 14:19:43 +00:00
rcourtman
4c39f2f58f Add unit tests for temperature proxy utility functions (api)
- extractHostPart: 22 test cases covering URL parsing, hostname extraction
- buildAuthorizedNodeList: 8 test cases for PVE instance node list building
- generateSecureToken: 5 test cases for cryptographic token generation
- proxySyncState: 6 test cases for sync status tracking and snapshots

First test file for temperature_proxy.go utility functions.
2025-11-30 14:07:04 +00:00
rcourtman
ee124e1df4 Add unit tests for GetRateLimiterForEndpoint (api)
37 test cases covering endpoint routing to rate limiters:
- Authentication endpoints (login, logout, change-password, auth/*)
- Recovery endpoints (security/recovery)
- Export/Import endpoints (config/export, config/import)
- Configuration write operations (POST/PUT/DELETE to config/*)
- Configuration read operations (GET to config/*, discover, security/status)
- Update endpoints (updates/*)
- WebSocket endpoints (/ws/*)
- Public endpoints (health, version, metrics, etc.)
- General API fallback
- Case insensitivity (uppercase paths)
- Lazy initialization when globalRateLimitConfig is nil
- Priority ordering tests for overlapping patterns
2025-11-30 13:48:23 +00:00
rcourtman
9e056674cc Add unit tests for DemoModeMiddleware (api)
26 test cases covering:
- Demo mode disabled (all requests pass through)
- Demo mode enabled with read-only methods (GET/HEAD/OPTIONS allowed)
- WebSocket upgrade handling (case-insensitive)
- Auth endpoint allowlist (login, OIDC, logout)
- Modification request blocking (POST/PUT/DELETE/PATCH)
- Partial path match rejection (security)
- Response format verification (JSON error response)

First test file for demo_middleware.go. Tests verify correct header
setting (X-Demo-Mode) and error response structure.
2025-11-30 13:34:08 +00:00
rcourtman
ea70c038b9 Add unit tests for container disk usage utility functions (monitoring) 2025-11-30 13:20:39 +00:00
rcourtman
a647d424de Add unit tests for missing ToFrontend converters (models)
Added 17 new test functions covering:
- DockerHost.ToFrontend() with variants for empty display name, swarm,
  services, tasks, and command status
- Host.ToFrontend() with display name fallback logic
- CephCluster.ToFrontend() including empty pools/services case
- ReplicationJob.ToFrontend() including nil time handling
- DockerServiceUpdate.ToFrontend()
- DockerContainer.ToFrontend() for Podman info

Coverage improved from 33.0% to 44.0% in internal/models package.
2025-11-30 13:03:45 +00:00
rcourtman
e0ccd2b8db Add unit tests for ZFS storage utility functions (hostmetrics)
65 test cases covering 8 functions:
- parseZpoolList: zpool command output parsing (15 cases)
- uniqueZFSPools: pool name deduplication (7 cases)
- bestZFSMountpoints: mountpoint selection logic (8 cases)
- zfsMountpointScore: mountpoint scoring algorithm (7 cases)
- zfsPoolFromDevice: pool name extraction (6 cases)
- calculatePercent: percentage calculation (7 cases)
- clampPercent: value clamping (8 cases)
- bestZFSPoolDatasets: dataset selection (7 cases)

First comprehensive unit test coverage for internal/hostmetrics
package ZFS utilities.
2025-11-30 12:50:58 +00:00
rcourtman
729adc12fd Add unit tests for toDockerHostCommandFrontend converter 2025-11-30 12:38:59 +00:00
rcourtman
d71e00bdbd Fix Windows agent self-update restart failure
syscall.Exec is not supported on Windows, causing self-update to fail
with "failed to restart: not supported by windows".

Split restart logic into platform-specific files:
- restart_unix.go: Uses syscall.Exec for in-place process replacement
- restart_windows.go: Uses os.Exit(0) to let Windows SCM restart service

Related to #735
2025-11-30 12:02:43 +00:00
rcourtman
0254fc7397 Add unit tests for discovery config functions (config)
Add tests for CloneDiscoveryConfig and NormalizeDiscoveryConfig:
- CloneDiscoveryConfig: 7 tests verifying deep copy, slice independence
- NormalizeDiscoveryConfig: 16 tests covering defaults, validation,
  sanitization, edge cases

Total: 23 test cases for discovery config handling.
2025-11-30 10:49:03 +00:00
rcourtman
760f24dc5e Add unit tests for alert utility functions (alerts)
Test coverage for isMonitorOnlyAlert, quietHoursCategoryForAlert, and
ensureValidHysteresis functions that were previously untested. Improves
internal/alerts coverage from 46.4% to 46.8%.
2025-11-30 10:35:22 +00:00
rcourtman
82231877d5 Add unit tests for host alert utility functions (alerts)
Test hostResourceID, hostDisplayName, hostInstanceName,
sanitizeHostComponent, sanitizeRAIDDevice, and hostDiskResourceID.
2025-11-30 10:20:26 +00:00