Commit graph

72 commits

Author SHA1 Message Date
rcourtman
5c584b9eee test: Add comprehensive tests for HandleDockerHostOffline
HandleDockerHostOffline (0%→100%):
- Empty host ID is no-op
- Disabled alerts is no-op
- DisableAllDockerHostsOffline clears tracking and alert
- Override DisableConnectivity clears tracking and alert
- Existing alert updates LastSeen
- Requires 3 confirmations before alert
- Alert has correct metadata (resourceType, hostId, agentId)

Coverage: 55.6% → 56.9%
2025-12-01 16:39:10 +00:00
rcourtman
7bac96d60b test: Add comprehensive tests for HandleHostRemoved, ReevaluateGuestAlert
HandleHostRemoved (0%→100%):
- Empty host ID is no-op
- Clears host offline alert and confirmations
- Clears host metric alerts (CPU, memory)
- Clears host disk alerts
- Clears all alert types together

ReevaluateGuestAlert (0%→100%):
- No active alerts is no-op
- Clears alert when threshold disabled (nil)
- Clears alert when trigger is zero
- Clears alert when value below clear threshold
- Clears alert when value below trigger threshold
- Keeps alert when value above both thresholds
- Processes all metric types (7 types)
- Clears pending alert when threshold disabled
- Uses clear equals trigger when clear is zero
- Ignores alerts for different guests

NormalizeMetricTimeThresholds (0%→100%):
- Updated existing test to call public wrapper instead of internal function

Coverage: 54.6% → 55.6%
2025-12-01 16:36:48 +00:00
rcourtman
65e5eb84ae test: Add comprehensive tests for reevaluateActiveAlertsLocked
Tests major branches for alert re-evaluation on config change:
- Empty alerts map (no-op)
- Alert ID with insufficient parts (skipped)
- DisableAllPMG resolves PMG queue alerts
- DisableAllHosts resolves Host alerts via resourceType metadata
- Docker host offline alerts are skipped (not threshold-based)
- DisableAllDockerHosts resolves dockerhost metric alerts
- DisableAllNodes resolves Node alerts via Instance field
- DisableAllStorage resolves Storage alerts
- DisableAllPBS resolves PBS alerts
- DisableAllGuests resolves Guest alerts
- Disabled override resolves alert
- Alert below clear threshold is resolved
- Alert between clear and trigger is resolved on config change

Coverage improvement:
- reevaluateActiveAlertsLocked: 59.8% → 81.2%
- alerts package: 54.0% → 54.6%
2025-12-01 16:31:05 +00:00
rcourtman
46eccd561a test: Add comprehensive tests for HandleHostOffline function
Tests all branches:
- Empty host ID returns early
- Alerts disabled returns early
- DisableAllHostsOffline clears alert and confirmation tracking
- Override DisableConnectivity clears alert and returns
- Override Disabled clears alert and returns
- Existing alert updates LastSeen only
- Insufficient confirmations waits for more
- Sufficient confirmations (3) creates alert with metadata

Coverage improvement:
- HandleHostOffline: 64.0% → 100%
- alerts package: 53.5% → 54.0%
2025-12-01 16:26:56 +00:00
rcourtman
1647b232db test: Add comprehensive tests for applyGlobalOfflineSettingsLocked
Tests all 7 disable settings branches:
- DisableAllNodesOffline: clears node-offline-* alerts and nodeOfflineCount
- DisableAllPBSOffline: clears pbs-offline-* alerts and offlineConfirmations
- DisableAllGuestsOffline: clears guest-powered-off-* alerts and offlineConfirmations
- DisableAllDockerHostsOffline: clears docker-host-offline-* alerts and dockerOfflineCount
- DisableAllDockerContainers: clears docker-container-* alerts and tracking state
- DisableAllDockerServices: clears docker-service-* alerts
- No settings enabled: verifies no-op behavior

Coverage improvement:
- applyGlobalOfflineSettingsLocked: 57.1% → 100%
- alerts package: 53.0% → 53.5%
2025-12-01 16:23:45 +00:00
rcourtman
a4008f914f test: Add comprehensive tests for alert clearing functions
- TestClearBackupAlertsLocked: tests backup-age alert clearing with nil handling
- TestClearBackupAlerts: tests public wrapper function
- TestClearSnapshotAlertsForInstanceLocked: tests instance-specific snapshot clearing
- TestClearSnapshotAlertsForInstance: tests public wrapper function

Coverage improvement:
- clearBackupAlertsLocked: 75% → 100%
- clearBackupAlerts: 0% → 100%
- clearSnapshotAlertsForInstanceLocked: 50% → 100%
- clearSnapshotAlertsForInstance: 0% → 100%
- alerts package: 52.8% → 53.0%
2025-12-01 16:20:49 +00:00
rcourtman
876d81ea12 test: Add edge case tests for ClearActiveAlerts and sanitizeAlertKey
- TestClearActiveAlertsEmptyMaps: tests early return when both maps empty
- sanitizeAlertKey: test for input with only slashes/backslashes -> root

Coverage improvement:
- sanitizeAlertKey: 96.4% → 100%
- alerts package: 52.8%
2025-12-01 16:15:50 +00:00
rcourtman
6e779742d8 test: Add comprehensive tests for AcknowledgeAlert and UnacknowledgeAlert functions
- TestAcknowledgeAlertNotFound: tests error path when alert doesn't exist
- TestUnacknowledgeAlertNotFound: tests error path when alert doesn't exist
- TestUnacknowledgeAlertSuccess: tests successful unacknowledgement with state verification

Coverage improvement:
- AcknowledgeAlert: 92.3% → 100%
- UnacknowledgeAlert: 41.7% → 100%
- alerts package: 52.6% → 52.8%
2025-12-01 16:12:50 +00:00
rcourtman
edf0cae4f9 test: Add edge case tests for matchesDockerIgnoredPrefix function
- skips empty prefix in list
- all empty prefixes returns false
- empty name/id edge cases
- matchesDockerIgnoredPrefix 92.3%→100%
2025-12-01 16:08:21 +00:00
rcourtman
9052e48245 test: Add comprehensive tests for HandleHostOnline function
- clears offline alert and confirmation tracking
- clears confirmation even without alert
- empty host ID is noop
- HandleHostOnline 90%→100%
2025-12-01 16:06:06 +00:00
rcourtman
9229cf86be test: Add comprehensive tests for safeCallResolvedCallback function
- calls callback synchronously with alert ID
- calls callback asynchronously
- noop when callback is nil
- recovers from panic in sync and async callbacks
- safeCallResolvedCallback 90%→100%
2025-12-01 16:04:25 +00:00
rcourtman
9f1a5c2183 test: Add comprehensive tests for safeCallEscalateCallback function
- calls callback with alert and level
- noop when callback is nil
- recovers from panic in callback
- clones alert to prevent concurrent modification
- safeCallEscalateCallback 0%→100%
2025-12-01 16:02:19 +00:00
rcourtman
d7360c7b22 test: Add comprehensive tests for cleanupDockerContainerAlerts function
- clears alerts and state tracking not in seen set
- skips alerts from other hosts
- handles empty seen set (clears all)
- cleanupDockerContainerAlerts 75%→100%
2025-12-01 15:59:49 +00:00
rcourtman
b5a8817ee4 test: Add comprehensive tests for HandleDockerHostOnline function
- clears offline alert and tracking
- clears tracking even when no alert exists
- empty host ID is noop
- HandleDockerHostOnline 88.9%→100%
2025-12-01 15:57:44 +00:00
rcourtman
e7cf40c2c6 test: Add empty ID test for HandleDockerHostRemoved function
- empty host ID is noop (preserves existing alerts/tracking)
- HandleDockerHostRemoved 75%→100%
2025-12-01 15:56:11 +00:00
rcourtman
7580d0b3d5 test: Add comprehensive tests for cleanupHostDiskAlerts function
- clears alerts not in seen set (stale disk alerts)
- empty host ID is noop
- skips nil alerts without panic
- skips non-matching prefix (non-disk alerts)
- cleanupHostDiskAlerts 76.9%→100%
2025-12-01 15:54:33 +00:00
rcourtman
39a856aaf8 test: Add comprehensive tests for clearHostDiskAlerts function
- clears all disk alerts for specified host
- empty hostID is noop
- skips nil alerts without panic
- noop when no matching alerts
- clearHostDiskAlerts 72.7%→100%
2025-12-01 15:52:39 +00:00
rcourtman
32b346b8ce test: Add comprehensive tests for clearHostMetricAlerts function
- clears specified metrics from host
- defaults to cpu and memory when no metrics specified
- empty hostID is noop
- clearHostMetricAlerts 85.7%→100%
2025-12-01 15:50:59 +00:00
rcourtman
a3aef773ec test: Add comprehensive tests for clearStorageOfflineAlert function
- clears existing offline alert and confirmation
- triggers resolved callback
- noop when no alert exists
- clears offline confirmation even without alert
- clearStorageOfflineAlert 50%→100%
2025-12-01 15:48:32 +00:00
rcourtman
2fbf9cbe7b test: Add comprehensive tests for dockerServiceResourceID function
- with/without host ID (prefix selection)
- derives ID from service name with sanitization
- special chars replaced with dashes
- preserves alphanumeric, underscore, hyphen
- trims leading/trailing dashes/underscores
- truncates long IDs to 32 chars
- fallback to 'service' when empty
- dockerServiceResourceID 23.8%→100%
2025-12-01 15:46:34 +00:00
rcourtman
884d04ae61 test: Add comprehensive tests for dockerServiceDisplayName function
- returns name when present
- returns trimmed name
- returns truncated ID when name empty (first 12 chars)
- returns full short ID when < 12 chars
- returns 'service' when both empty/whitespace
- prefers name over ID
- dockerServiceDisplayName 33.3%→100%
2025-12-01 15:44:40 +00:00
rcourtman
a97a4a022c test: Add comprehensive tests for shouldNotifyAfterCooldown function
- cooldown disabled (0) allows notification
- negative cooldown allows notification
- first notification allowed when never notified
- notification blocked during cooldown period
- notification allowed after cooldown expires
- boundary condition (exact cooldown time)
- shouldNotifyAfterCooldown 42.9%→100%
2025-12-01 15:42:35 +00:00
rcourtman
46f0632c53 test: Add comprehensive tests for applyRelaxedGuestThresholds function
- nil thresholds get defaults (CPU 95, Memory 92, Disk 95)
- low thresholds raised to minimum relaxed values
- high thresholds unchanged
- clear adjusted when too close to trigger
- original config unchanged (no mutation)
- alerts package coverage improvement: applyRelaxedGuestThresholds 75%→93.8%
2025-12-01 15:40:19 +00:00
rcourtman
10498a0d54 test: Add comprehensive tests for checkRateLimit function
Cover all branches: disabled rate limit (zero/negative MaxAlertsHour),
under limit, at limit blocking, separate limits per alertID, old entry
cleanup, and mixed old/recent entries. Coverage improved from 71.4% to 100%.
2025-12-01 15:35:19 +00:00
rcourtman
c488956001 test: Add comprehensive tests for getMetricTimeThreshold function
Cover all branches: empty config, empty/whitespace metricType, direct
match, canonical key matching (vm→guest, container→guest), fallback
chain (default, _default, wildcard), precedence, and no-match scenarios.
Coverage improved from 77.8% to 100%.
2025-12-01 15:32:33 +00:00
rcourtman
844b9e5637 test: Add comprehensive tests for getBaseTimeThreshold function
Cover all branches: nil/empty TimeThresholds, direct match, canonical key
matching (vm→guest, container→guest), "all" fallback, specific match
precedence, and global threshold fallback. Coverage improved from 85.7% to 100%.
2025-12-01 15:25:18 +00:00
rcourtman
fecab94dc8 test: Add comprehensive tests for getGlobalMetricTimeThreshold function
Cover all branches: empty config, missing 'all' key, empty perType map,
empty/whitespace metricType, direct match, case insensitivity, default
fallback, _default fallback, wildcard fallback, and no-match scenarios.
Coverage improved from 58.8% to 100%.
2025-12-01 15:17:12 +00:00
rcourtman
7c0ea6a07b test: Add comprehensive tests for isInQuietHours function
Cover all branches: disabled state, invalid timezone fallback, day not
enabled, invalid start/end time parsing, overnight window spanning
midnight, and normal daytime window. Coverage improved from 61.5% to 96.2%.
2025-12-01 15:14:44 +00:00
rcourtman
606764f931 test: Add comprehensive tests for checkFlapping function
Cover all branches of flapping detection: disabled state, below/at/above
threshold, already-flapping state (no suppression update), and window
expiry pruning. Coverage improved from 61.9% to 95.2%.
2025-12-01 15:11:11 +00:00
rcourtman
c7d832c8d9 test: Add comprehensive tests for BuildGuestKey function
- Test different instance and node (full format)
- Test same instance and node (short format)
- Test empty instance defaults to node
- Test whitespace trimming
- Improves BuildGuestKey coverage from 71.4% to 100%
2025-12-01 15:04:37 +00:00
rcourtman
4058e575f7 test: Add tests for metric threshold lookup functions
- normalizeMetricTimeThresholds: key normalization, invalid value filtering
- getThresholdForMetric: all metric types, empty config, case sensitivity
- getThresholdForMetricFromConfig: hysteresis application, all metric types

Coverage: alerts 49.0% → 49.9%
2025-12-01 14:01:25 +00:00
rcourtman
23794987f0 test: Add tests for alerts clone functions and parsePulseTags
- cloneThreshold: nil handling, value copying, pointer independence
- cloneStringPtr: nil handling, string copying, pointer independence
- cloneThresholdConfig: full config deep copy verification
- ensureHysteresisThreshold: default clear calculation, edge cases
- parsePulseTags: tag parsing, case insensitivity, whitespace handling

Coverage: alerts 48.9% → 49.0%
2025-12-01 13:52:09 +00:00
rcourtman
447478785b test: Add unit tests for filter_evaluation.go functions
Tests for alert filter evaluation logic:
- evaluateVMCondition: metric/text/raw conditions for VMs
- evaluateContainerCondition: same for containers
- evaluateFilterStack: AND/OR logic with multiple conditions
- evaluateFilterCondition: type dispatch

74 test cases covering:
- All metric types (cpu, memory, disk, diskread, diskwrite, network)
- All comparison operators (>, <, >=, <=, =, ==)
- Text search fields (name, node, vmid) with case insensitivity
- Raw text search across multiple fields
- Value type conversions (int to float64)
- Edge cases (zero, empty, invalid types)

Coverage improved from 46.8% to 48.9%.
2025-12-01 13:34:23 +00:00
rcourtman
f02a340d72 refactor: Extract filter evaluation functions to separate file
Move guest threshold resolution and filter evaluation logic from
alerts.go to filter_evaluation.go for better code organization.

Extracted functions:
- evaluateFilterCondition
- evaluateVMCondition
- evaluateContainerCondition
- evaluateFilterStack
- getGuestThresholds

This reduces alerts.go by ~370 lines and isolates the rule evaluation
engine that determines which thresholds apply to guests.
2025-12-01 11:28:43 +00:00
rcourtman
8ebc8fc892 ADA changes (auto-committed by cron safety check) 2025-12-01 09:51:17 +00:00
rcourtman
562fc59c56 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
0d22d3d2e4 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
rcourtman
d69e1545f2 Add unit tests for alert utility functions (alerts)
Test coverage for pure utility functions:
- sanitizeAlertKey: string normalization for alert IDs
- abs: absolute value for float64
- isQueueOutlier: queue anomaly detection logic
- scaleThreshold: threshold scaling with ceiling
- calculateMedianInt: integer median calculation

78 test cases added, coverage improved from 45.3% to 46.2%.
2025-11-30 06:34:55 +00:00
rcourtman
36b1c9cf63 Add unit tests for Alert clone and metadata utility functions (alerts)
Tests for:
- normalizePoweredOffSeverity: Verifies severity normalization to warning/critical
- cloneMetadata: Deep copy functionality for metadata maps
- cloneMetadataValue: Type-specific cloning for various slice and map types
- Alert.Clone: Full alert cloning with pointer field independence

46 test cases covering nil handling, deep copy verification, slice/map
independence, and all supported metadata value types.

Coverage improved from 44.8% to 45.3%.
2025-11-30 05:19:38 +00:00
rcourtman
67b60adb65 style: fix revive linter warnings
- Mark unused stub parameters with underscore
- Rename 'copy' variable to avoid shadowing builtin
- Remove unnecessary else blocks after return statements
2025-11-27 10:26:26 +00:00
rcourtman
31927f71e9 fix: mark unused parameters to satisfy unparam linter
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
2025-11-27 10:12:48 +00:00
rcourtman
8a1ee3b05e style: fix staticcheck style warnings
- Merge variable declaration with assignment (S1021)
- Use unconditional strings.TrimPrefix (S1017)
- Remove unnecessary nil checks around range (S1031)
- Remove unnecessary fmt.Sprintf (S1039)
- Use copy() instead of manual loop (S1001)
- Use time.Until instead of t.Sub(time.Now()) (S1024)
- Use buf.String() instead of string(buf.Bytes()) (S1030)
2025-11-27 09:19:33 +00:00
rcourtman
4fd3bdbc04 chore: fix staticcheck U1000 unused code warnings
- Remove unused ipv6Regex from validation.go
- Suppress unused recordAlertFired/recordAlertResolved hooks (kept for future use)
- Remove unused apiLimiter rate limiter
- Remove unused stopOnce fields from csrf_store.go and session_store.go
- Remove unused lastBroadcast field from hub.go
- Remove unused lastUsedIndex field from cluster_client.go
2025-11-27 09:12:17 +00:00
rcourtman
2fe7bb6141 style: fix gofmt formatting inconsistencies
Run gofmt -w to fix tab/space inconsistencies across 33 files.
2025-11-26 23:44:36 +00:00
rcourtman
6ff54beb38 Handle ignored docker containers during alert reevaluation (related to #561) 2025-11-21 22:19:19 +00:00
rcourtman
4e68675e0b Add recovery notifications and grouping controls 2025-11-21 22:07:00 +00:00
rcourtman
bb7ca93c18 feat: Add mdadm RAID monitoring support for host agents
Implements comprehensive mdadm RAID array monitoring for Linux hosts
via pulse-host-agent. Arrays are automatically detected and monitored
with real-time status updates, rebuild progress tracking, and automatic
alerting for degraded or failed arrays.

Key changes:

**Backend:**
- Add mdadm package for parsing mdadm --detail output
- Extend host agent report structure with RAID array data
- Integrate mdadm collection into host agent (Linux-only, best-effort)
- Add RAID array processing in monitoring system
- Implement automatic alerting:
  - Critical alerts for degraded arrays or arrays with failed devices
  - Warning alerts for rebuilding/resyncing arrays with progress tracking
  - Auto-clear alerts when arrays return to healthy state

**Frontend:**
- Add TypeScript types for RAID arrays and devices
- Display RAID arrays in host details drawer with:
  - Array status (clean/degraded/recovering) with color-coded indicators
  - Device counts (active/total/failed/spare)
  - Rebuild progress percentage and speed when applicable
  - Green for healthy, amber for rebuilding, red for degraded

**Documentation:**
- Document mdadm monitoring feature in HOST_AGENT.md
- Explain requirements (Linux, mdadm installed, root access)
- Clarify scope (software RAID only, hardware RAID not supported)

**Testing:**
- Add comprehensive tests for mdadm output parsing
- Test parsing of healthy, degraded, and rebuilding arrays
- Verify proper extraction of device states and rebuild progress

All builds pass successfully. RAID monitoring is automatic and best-effort
- if mdadm is not installed or no arrays exist, host agent continues
reporting other metrics normally.

Related to #676
2025-11-09 16:36:33 +00:00
rcourtman
8f05fc0a57 Improve backup-age alerts to show VM/CT names in multi-cluster setups (related to #668)
This change fixes backup-age alert notifications to display VM/CT names
instead of just "VMID XXX" in multi-cluster environments where backups
are stored on PBS.

Changes:
- Store all guests per VMID (not just first match) to handle VMID collisions across clusters
- Persist last-known guest names/types in metadata store for deleted VMs
- Enrich backup correlation with persisted metadata when live inventory is empty
- Update CheckBackups to handle multiple VMID matches intelligently

The fix addresses two scenarios:
1. Multiple PVE clusters with same VMID backing up to one PBS
2. VMs deleted from Proxmox but backups still exist on PBS

Backup-age alerts will now show proper VM/CT names when:
- A unique guest exists with that VMID (live or persisted)
- Multiple guests share a VMID (uses first match, consistent with current behavior)

When truly ambiguous (multiple live VMs, same VMID, no way to determine origin),
the alert gracefully falls back to showing "VMID XXX".
2025-11-08 18:24:04 +00:00
rcourtman
1183b87fa1 Fix critical alert system concurrency and memory leak issues
This commit addresses 7 critical issues identified during the alert system audit:

**P0 Critical - Race Conditions Fixed:**

1. **dispatchAlert race in NotifyExistingAlert** (lines 5486-5497)
   - Changed from RLock to Lock to hold mutex during dispatchAlert call
   - dispatchAlert calls checkFlapping which writes to maps (flappingHistory, flappingActive, suppressedUntil)
   - Previous code: grabbed RLock, got alert pointer, released lock, then called dispatchAlert (RACE)
   - Fixed: hold Lock through dispatchAlert call

2. **dispatchAlert race in LoadActiveAlerts startup** (lines 8216-8235)
   - Startup goroutines called dispatchAlert without holding lock
   - Added m.mu.Lock/Unlock around dispatchAlert call in goroutine
   - Also added cancellation via escalationStop channel to prevent goroutine leaks on shutdown

3. **checkFlapping documentation** (line 738)
   - Added clear comment that checkFlapping requires caller to hold m.mu
   - Prevents future race conditions from improper usage

**P1 Important - Data Loss Prevention:**

4. **History save race condition** (lines 177-180 in history.go)
   - Added saveMu mutex to serialize disk writes
   - Previous: concurrent saves could interleave, causing newer data to be overwritten by older snapshots
   - Fixed: saveMu.Lock at start of saveHistoryWithRetry ensures atomic disk writes
   - Newer snapshots now always win over older ones

**P2 Memory Leak Prevention:**

5. **PMG anomaly tracker cleanup** (lines 7318-7331)
   - Added cleanup for pmgAnomalyTrackers map (24 hour TTL based on LastSampleTime)
   - Prevents unbounded growth from decommissioned/transient PMG instances
   - Each tracker: ~1-2KB (48 samples + baselines)

6. **PMG quarantine history cleanup** (lines 7333-7354)
   - Added cleanup for pmgQuarantineHistory map (7 day TTL based on last snapshot)
   - Prevents memory leak for deleted PMG instances
   - Removes both empty histories and very old histories

**P2 Goroutine Leak Prevention:**

7. **Startup notification goroutine cancellation** (lines 8218-8234)
   - Added select with escalationStop channel to cancel startup notifications
   - Prevents goroutines from continuing after Stop() is called
   - Scales with number of restored critical alerts

All fixes maintain proper lock ordering and prevent deadlocks by ensuring locks are held when accessing shared maps.
2025-11-07 09:12:28 +00:00
rcourtman
4891f06e76 Fix webhook alerts persisting when DisableAll* flags are enabled
The original fix in c6c0ac63e only handled per-resource overrides when
thresholds were disabled (trigger <= 0 or Disabled=true). It did not
handle global DisableAll* flags (DisableAllStorage, DisableAllNodes,
DisableAllGuests, etc.).

When a user toggled a DisableAll* flag from false to true:
- Check* functions returned early without processing
- Existing active alerts remained in m.activeAlerts map
- Those alerts continued generating webhook notifications
- reevaluateActiveAlertsLocked didn't check DisableAll* flags

This commit fixes the issue by:

1. Updating reevaluateActiveAlertsLocked to check all DisableAll* flags
   and resolve alerts for those resource types during config updates

2. Adding alert cleanup to Check* functions before early returns:
   - CheckStorage: clears usage and offline alerts
   - CheckNode: clears cpu/memory/disk/temperature and offline alerts
   - CheckPMG: clears queue/message alerts and offline alerts
   - CheckPBS: clears cpu/memory and offline alerts
   - CheckHost: calls existing cleanup helpers

3. Adding comprehensive test coverage for DisableAllStorage scenario

Related to #561
2025-11-06 21:17:56 +00:00