Add focused branch coverage and repair infrastructure source contract

Contract-Neutral: test-only coverage and source-contract assertions; no runtime or contract behavior changed
This commit is contained in:
rcourtman
2026-07-20 22:41:19 +01:00
parent 9f9e02e811
commit 4f43878ebb
8 changed files with 3751 additions and 3 deletions
@@ -414,10 +414,14 @@ describe('infrastructure operations model', () => {
expect(agentUpgradeSource).toContain(
'| bash -s -- --update --url ${shellQuoteArg(url)} --non-interactive',
);
expect(operationsStateSource).toContain('getAgentConnectionUpgradeCommandRequiresToken');
expect(operationsStateSource).toContain(
"getConnectionUpgradePlatform(connection) === 'windows' && installState.requiresToken()",
const requiresTokenEnd = operationsStateSource.indexOf('return {', agentUpgradeEnd);
expect(requiresTokenEnd).toBeGreaterThan(agentUpgradeEnd);
const requiresTokenSource = operationsStateSource.slice(agentUpgradeEnd, requiresTokenEnd);
expect(requiresTokenSource).toContain(
'platformOverride ?? getConnectionUpgradePlatform(connection)',
);
expect(requiresTokenSource).toContain("=== 'windows'");
expect(requiresTokenSource).toContain('installState.requiresToken()');
expect(unixUpgradeSource).not.toContain('command += ` --token ${shellQuoteArg(token)}`;');
expect(unixUpgradeSource).not.toContain('--agent-id');
expect(unixUpgradeSource).not.toContain('--hostname');
@@ -0,0 +1,205 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import type { PatrolRunRecord, PatrolStatus } from '@/api/patrol';
import {
schedulePatrolRunAcceptanceReconciliation,
type PatrolRunAcceptanceOutcome,
} from '../patrolRunAcceptance';
const runningStatus = (currentRunId?: string): PatrolStatus =>
({
runtime_state: 'running',
running: true,
enabled: true,
...(currentRunId !== undefined ? { current_run_id: currentRunId } : {}),
}) as PatrolStatus;
const idleStatus = (): PatrolStatus =>
({ runtime_state: 'active', running: false, enabled: true }) as PatrolStatus;
const completedRun = (id: string): PatrolRunRecord =>
({ id, status: 'healthy' }) as PatrolRunRecord;
interface Scenario {
runId?: string;
delayMs?: number;
refreshTimeoutMs?: number;
isCurrent?: () => boolean;
getStatus: () => Promise<PatrolStatus | null>;
getHistory: () => Promise<PatrolRunRecord[]>;
}
const scheduleScenario = (scenario: Scenario) => {
const onResult = vi.fn<(outcome: PatrolRunAcceptanceOutcome) => void>();
const cancel = schedulePatrolRunAcceptanceReconciliation({
runId: scenario.runId ?? 'run-1',
delayMs: scenario.delayMs ?? 1_000,
refreshTimeoutMs: scenario.refreshTimeoutMs ?? 5_000,
getStatus: scenario.getStatus,
getHistory: scenario.getHistory,
isCurrent: scenario.isCurrent ?? (() => true),
onResult,
});
return { onResult, cancel };
};
describe('schedulePatrolRunAcceptanceReconciliation — branch coverage', () => {
beforeEach(() => {
vi.useFakeTimers();
});
afterEach(() => {
vi.useRealTimers();
});
describe("kind 'running'", () => {
it('accepts when status.current_run_id === runId', async () => {
const { onResult } = scheduleScenario({
getStatus: async () => runningStatus('run-1'),
getHistory: async () => [],
});
await vi.advanceTimersByTimeAsync(1_000);
expect(onResult).toHaveBeenCalledTimes(1);
const outcome = onResult.mock.calls[0][0];
expect(outcome.kind).toBe('running');
expect((outcome as { status: PatrolStatus }).status.current_run_id).toBe('run-1');
});
it('accepts when runId is empty (no specific run tracked)', async () => {
const { onResult } = scheduleScenario({
runId: '',
getStatus: async () => runningStatus('run-1'),
getHistory: async () => [],
});
await vi.advanceTimersByTimeAsync(1_000);
expect(onResult).toHaveBeenCalledTimes(1);
expect(onResult.mock.calls[0][0].kind).toBe('running');
});
it('accepts when status has no current_run_id', async () => {
const { onResult } = scheduleScenario({
getStatus: async () => runningStatus(undefined),
getHistory: async () => [],
});
await vi.advanceTimersByTimeAsync(1_000);
expect(onResult).toHaveBeenCalledTimes(1);
expect(onResult.mock.calls[0][0].kind).toBe('running');
});
});
describe("kind 'recorded'", () => {
it('records when patrol is idle but history contains the accepted run', async () => {
const { onResult } = scheduleScenario({
getStatus: async () => idleStatus(),
getHistory: async () => [completedRun('run-1')],
});
await vi.advanceTimersByTimeAsync(1_000);
expect(onResult).toHaveBeenCalledTimes(1);
const outcome = onResult.mock.calls[0][0];
expect(outcome.kind).toBe('recorded');
expect((outcome as { run: PatrolRunRecord }).run.id).toBe('run-1');
});
it('records when a newer run has taken over the patrol slot', async () => {
const { onResult } = scheduleScenario({
getStatus: async () => runningStatus('run-newer'),
getHistory: async () => [completedRun('run-1')],
});
await vi.advanceTimersByTimeAsync(1_000);
expect(onResult).toHaveBeenCalledWith(
expect.objectContaining({
kind: 'recorded',
run: expect.objectContaining({ id: 'run-1' }),
}),
);
});
});
describe("kind 'refresh_failed'", () => {
it('reports the status read rejection reason', async () => {
const statusError = new Error('status down');
const { onResult } = scheduleScenario({
getStatus: () => Promise.reject(statusError),
getHistory: async () => [],
});
await vi.advanceTimersByTimeAsync(1_000);
expect(onResult).toHaveBeenCalledTimes(1);
const outcome = onResult.mock.calls[0][0];
expect(outcome.kind).toBe('refresh_failed');
expect((outcome as { error: unknown }).error).toBe(statusError);
});
it('reports the history read rejection reason', async () => {
const historyError = new Error('history down');
const { onResult } = scheduleScenario({
getStatus: async () => idleStatus(),
getHistory: () => Promise.reject(historyError),
});
await vi.advanceTimersByTimeAsync(1_000);
expect(onResult).toHaveBeenCalledTimes(1);
const outcome = onResult.mock.calls[0][0];
expect(outcome.kind).toBe('refresh_failed');
expect((outcome as { error: unknown }).error).toBe(historyError);
});
it('bounds hung reads with the refresh timeout', async () => {
const { onResult } = scheduleScenario({
delayMs: 1_000,
refreshTimeoutMs: 2_000,
getStatus: () => new Promise<PatrolStatus | null>(() => undefined),
getHistory: () => new Promise<PatrolRunRecord[]>(() => undefined),
});
await vi.advanceTimersByTimeAsync(3_000);
expect(onResult).toHaveBeenCalledTimes(1);
expect(onResult.mock.calls[0][0].kind).toBe('refresh_failed');
});
});
describe("kind 'missing'", () => {
it('falls through when idle, history lacks the run, and no refresh failed', async () => {
const { onResult } = scheduleScenario({
getStatus: async () => idleStatus(),
getHistory: async () => [completedRun('run-other')],
});
await vi.advanceTimersByTimeAsync(1_000);
expect(onResult).toHaveBeenCalledWith({ kind: 'missing' });
});
it('falls through to missing when no runId is tracked and nothing is running', async () => {
const { onResult } = scheduleScenario({
runId: '',
getStatus: async () => idleStatus(),
getHistory: async () => [completedRun('run-1')],
});
await vi.advanceTimersByTimeAsync(1_000);
expect(onResult).toHaveBeenCalledWith({ kind: 'missing' });
});
});
describe('guard branches', () => {
it('suppresses onResult when isCurrent() is false after the delay', async () => {
const getStatus = vi.fn(async () => runningStatus('run-1'));
const getHistory = vi.fn(async () => [] as PatrolRunRecord[]);
const { onResult } = scheduleScenario({
getStatus,
getHistory,
isCurrent: () => false,
});
await vi.advanceTimersByTimeAsync(1_000);
expect(getStatus).toHaveBeenCalledTimes(1);
expect(getHistory).toHaveBeenCalledTimes(1);
expect(onResult).not.toHaveBeenCalled();
});
it('cancels before the delay fires: clears the timer and skips the reads', async () => {
const getStatus = vi.fn(async () => runningStatus('run-1'));
const getHistory = vi.fn(async () => [] as PatrolRunRecord[]);
const { onResult, cancel } = scheduleScenario({ getStatus, getHistory });
cancel();
await vi.advanceTimersByTimeAsync(10_000);
expect(getStatus).not.toHaveBeenCalled();
expect(getHistory).not.toHaveBeenCalled();
expect(onResult).not.toHaveBeenCalled();
});
});
});
@@ -0,0 +1,677 @@
import { describe, expect, it } from 'vitest';
import type { PhysicalDiskFieldStatus, Resource } from '@/types/resource';
import {
PHYSICAL_DISK_MUTED_PLACEHOLDER_CLASS,
buildPhysicalDiskPresentationDataMap,
buildPhysicalDiskGroupFilterOptions,
buildPhysicalDiskRoleFilterOptions,
comparePhysicalDiskPresentation,
extractPhysicalDiskPresentationData,
filterAndSortPhysicalDisks,
getPhysicalDiskCollectionMessages,
getPhysicalDiskEmptyStatePresentation,
getPhysicalDiskFieldStatusMessage,
getPhysicalDiskHealthStatus,
getPhysicalDiskHealthSummary,
getPhysicalDiskHostLabel,
getPhysicalDiskLifeTextClass,
getPhysicalDiskNormalizedHealth,
getPhysicalDiskPlatformLabel,
getPhysicalDiskRoleLabel,
getPhysicalDiskSourceBadgePresentation,
hasPhysicalDiskSmartWarning,
hasUnraidPhysicalDiskFaultSignal,
isUnraidPhysicalDisk,
matchesPhysicalDiskHealthFilter,
matchesPhysicalDiskSearch,
type PhysicalDiskPresentationData,
} from '@/features/storageBackups/diskPresentation';
function makeDiskData(
overrides: Partial<PhysicalDiskPresentationData> = {},
): PhysicalDiskPresentationData {
return {
node: '',
instance: '',
devPath: '',
model: '',
serial: '',
wwn: '',
size: 0,
health: 'UNKNOWN',
riskReasons: [],
wearout: -1,
type: '',
temperature: 0,
rpm: 0,
used: '',
...overrides,
};
}
describe('diskPresentation.branchcov0720pm', () => {
describe('getPhysicalDiskHealthFilterEmptyTitle switch arms', () => {
it('returns the matching empty-state title for the healthy filter', () => {
expect(
getPhysicalDiskEmptyStatePresentation({
selectedNodeName: null,
searchTerm: '',
diskCount: 2,
hasPVENodes: true,
healthFilter: 'healthy',
}).title,
).toBe('No healthy disks found');
});
it('returns the matching empty-state title for the warning filter', () => {
expect(
getPhysicalDiskEmptyStatePresentation({
selectedNodeName: null,
searchTerm: '',
diskCount: 2,
hasPVENodes: true,
healthFilter: 'warning',
}).title,
).toBe('No warning disks found');
});
it('returns the matching empty-state title for the critical filter', () => {
expect(
getPhysicalDiskEmptyStatePresentation({
selectedNodeName: null,
searchTerm: '',
diskCount: 2,
hasPVENodes: true,
healthFilter: 'critical',
}).title,
).toBe('No critical disks found');
});
it('returns the matching empty-state title for the offline filter', () => {
expect(
getPhysicalDiskEmptyStatePresentation({
selectedNodeName: null,
searchTerm: '',
diskCount: 2,
hasPVENodes: true,
healthFilter: 'offline',
}).title,
).toBe('No offline disks found');
});
it('returns the matching empty-state title for the unknown filter', () => {
expect(
getPhysicalDiskEmptyStatePresentation({
selectedNodeName: null,
searchTerm: '',
diskCount: 2,
hasPVENodes: true,
healthFilter: 'unknown',
}).title,
).toBe('No disks with unknown health');
});
it('falls back to the default-empty title when healthFilter is "all" but disks are present', () => {
expect(
getPhysicalDiskEmptyStatePresentation({
selectedNodeName: null,
searchTerm: 'zzz',
diskCount: 2,
hasPVENodes: true,
healthFilter: 'all',
}).title,
).toBe('No disks match these filters');
});
});
describe('getPhysicalDiskEmptyStatePresentation ternary arms', () => {
it('returns null nodeMessage and searchMessage when nothing is selected', () => {
const presentation = getPhysicalDiskEmptyStatePresentation({
selectedNodeName: null,
searchTerm: '',
diskCount: 0,
hasPVENodes: false,
});
expect(presentation.nodeMessage).toBeNull();
expect(presentation.searchMessage).toBeNull();
expect(presentation.showRequirements).toBe(false);
});
it('returns a searchMessage when a searchTerm is supplied', () => {
const presentation = getPhysicalDiskEmptyStatePresentation({
selectedNodeName: null,
searchTerm: 'wd20',
diskCount: 0,
hasPVENodes: false,
});
expect(presentation.searchMessage).toBe('matching "wd20"');
});
});
describe('getPhysicalDiskFieldStatusMessage default arm', () => {
it('returns empty string for an unrecognized state via the default switch arm', () => {
const malformed = {
state: 'totally-bogus',
source: 'test',
} as unknown as PhysicalDiskFieldStatus;
expect(getPhysicalDiskFieldStatusMessage('Field', malformed)).toBe('');
});
it('returns empty string when status is null or available', () => {
expect(getPhysicalDiskFieldStatusMessage('Field', null)).toBe('');
expect(
getPhysicalDiskFieldStatusMessage('Field', { state: 'available', source: 'test' }),
).toBe('');
});
});
describe('getPhysicalDiskCollectionMessages empty paths', () => {
it('returns an empty array when the disk has no collection evidence', () => {
expect(getPhysicalDiskCollectionMessages(makeDiskData())).toEqual([]);
});
});
describe('getPhysicalDiskPlatformLabel fallback', () => {
it('returns "Unknown" when no fallback label is supplied', () => {
expect(getPhysicalDiskPlatformLabel({} as Resource, '')).toBe('Unknown');
});
});
describe('getPhysicalDiskSourceBadgePresentation fallback arms', () => {
it('falls back to the platform-derived label and base tone when the presentation is missing', () => {
const badge = getPhysicalDiskSourceBadgePresentation({
platformType: '',
} as unknown as Resource);
expect(badge.label).toBe('Unknown');
expect(badge.className).toContain('text-base-content');
});
});
describe('getPhysicalDiskHostLabel fallback arms', () => {
it('falls back to resource.parentName when disk.node is empty', () => {
expect(
getPhysicalDiskHostLabel(makeDiskData(), { parentName: 'pve-node-1' } as Resource),
).toBe('pve-node-1');
});
it('returns an empty string when neither node nor parentName is set', () => {
expect(getPhysicalDiskHostLabel(makeDiskData(), {} as Resource)).toBe('');
});
});
describe('extractPhysicalDiskPresentationData fallback arms', () => {
it('reads physicalDisk from platformData when the top-level field is absent', () => {
const resource = {
name: 'fallback-disk',
platformData: { physicalDisk: { devPath: '/dev/sdz', health: 'PASSED', wearout: 88 } },
} as unknown as Resource;
const data = extractPhysicalDiskPresentationData(resource);
expect(data.devPath).toBe('/dev/sdz');
expect(data.health).toBe('PASSED');
expect(data.wearout).toBe(88);
});
it('returns defaults when neither physicalDisk nor platformData.physicalDisk is present', () => {
const data = extractPhysicalDiskPresentationData({ name: 'empty' } as unknown as Resource);
expect(data.devPath).toBe('');
expect(data.model).toBe('empty');
expect(data.health).toBe('UNKNOWN');
expect(data.wearout).toBe(-1);
expect(data.temperature).toBe(0);
expect(data.rpm).toBe(0);
expect(data.riskLevel).toBeUndefined();
expect(data.smartAttributes).toBeUndefined();
});
it('coerces zero values through the ?? and || branches', () => {
const data = extractPhysicalDiskPresentationData({
name: 'zeroed',
physicalDisk: {
devPath: '',
model: '',
serial: '',
wwn: '',
diskType: '',
sizeBytes: 0,
health: '',
wearout: 0,
temperature: 0,
rpm: 0,
used: '',
},
} as unknown as Resource);
expect(data.model).toBe('zeroed');
expect(data.health).toBe('UNKNOWN');
expect(data.size).toBe(0);
});
it('returns an empty model when neither pd.model nor resource.name is set', () => {
const data = extractPhysicalDiskPresentationData({
name: '',
physicalDisk: { devPath: '/dev/sda' },
} as unknown as Resource);
expect(data.model).toBe('');
});
it('reads sources from platformData.sourceStatus object keys', () => {
const resource = {
name: 'src',
platformData: { sourceStatus: { proxmox: { ok: true }, agent: { ok: false } } },
} as unknown as Resource;
expect(getPhysicalDiskNormalizedHealth(resource, makeDiskData({ health: 'UNKNOWN' }))).toBe(
'unknown',
);
});
it('treats a non-object sourceStatus as no extra sources', () => {
const resource = {
name: 'srcstr',
platformData: { sourceStatus: 'not-an-object' as unknown as object },
} as unknown as Resource;
expect(getPhysicalDiskNormalizedHealth(resource, makeDiskData({ health: 'UNKNOWN' }))).toBe(
'unknown',
);
});
});
describe('Unraid detection branch arms', () => {
it('detects Unraid disks via storageState + storageRole without the unraid-array group', () => {
const disk = makeDiskData({
storageRole: 'parity',
storageState: 'online',
storageGroup: 'other-group',
});
expect(isUnraidPhysicalDisk(disk)).toBe(true);
});
it('rejects disks whose role is not a known Unraid role even with a storage state', () => {
const disk = makeDiskData({
storageRole: 'spare',
storageState: 'online',
storageGroup: 'other-group',
});
expect(isUnraidPhysicalDisk(disk)).toBe(false);
});
it('rejects disks with no storageState and a non-unraid group', () => {
const disk = makeDiskData({
storageRole: 'data',
storageState: '',
storageGroup: 'other-group',
});
expect(isUnraidPhysicalDisk(disk)).toBe(false);
});
it('returns false from the fault-signal helper for non-Unraid disks', () => {
expect(
hasUnraidPhysicalDiskFaultSignal(makeDiskData({ health: 'FAILED', storageRole: 'spare' })),
).toBe(false);
});
it('flags Unraid disks via bad health states even without errorCount', () => {
const disk = makeDiskData({
health: 'FAULTED',
storageRole: 'data',
storageGroup: 'unraid-array',
storageState: 'disabled',
});
expect(hasUnraidPhysicalDiskFaultSignal(disk)).toBe(true);
});
});
describe('hasPhysicalDiskSmartWarning attribute arms', () => {
it('detects warnings from reallocated sectors', () => {
expect(
hasPhysicalDiskSmartWarning({
...makeDiskData(),
smartAttributes: { reallocatedSectors: 1 },
}),
).toBe(true);
});
it('detects warnings from media errors', () => {
expect(
hasPhysicalDiskSmartWarning({
...makeDiskData(),
smartAttributes: { mediaErrors: 4 },
}),
).toBe(true);
});
it('returns false when attrs are present but all counters are zero', () => {
expect(
hasPhysicalDiskSmartWarning({
...makeDiskData(),
smartAttributes: { reallocatedSectors: 0, pendingSectors: 0, mediaErrors: 0 },
}),
).toBe(false);
});
});
describe('getPhysicalDiskHealthStatus remaining arms', () => {
it('returns Healthy for PASSED health on a non-Unraid disk', () => {
const disk = makeDiskData({ health: 'PASSED', type: 'ssd', wearout: 90 });
expect(getPhysicalDiskHealthStatus(disk)).toMatchObject({
label: 'Healthy',
summary: 'No active disk-health issues.',
});
});
it('returns Healthy for GOOD health', () => {
const disk = makeDiskData({ health: 'GOOD', type: 'hdd', wearout: 90 });
expect(getPhysicalDiskHealthStatus(disk).label).toBe('Healthy');
});
it('returns Unknown for an Unraid disk that is not in the online state', () => {
const disk = makeDiskData({
health: 'UNKNOWN',
storageRole: 'data',
storageGroup: 'unraid-array',
storageState: 'standby',
});
expect(getPhysicalDiskHealthStatus(disk).label).toBe('Unknown');
});
it('uses "SMART counters indicate elevated risk." when low life is not the cause', () => {
const disk = makeDiskData({
health: 'PASSED',
type: 'hdd',
wearout: 60,
smartAttributes: { pendingSectors: 5 },
});
expect(getPhysicalDiskHealthStatus(disk).summary).toBe(
'SMART counters indicate elevated risk.',
);
});
it('uses "SSD life is running low." when wearout is below 10', () => {
const disk = makeDiskData({
health: 'PASSED',
type: 'ssd',
wearout: 5,
});
expect(getPhysicalDiskHealthStatus(disk).summary).toBe('SSD life is running low.');
});
});
describe('getPhysicalDiskNormalizedHealth coverage', () => {
it('classifies an offline resource as offline', () => {
const disk = makeDiskData({ health: 'PASSED', type: 'ssd', wearout: 90 });
const resource = { status: 'offline' } as Resource;
expect(getPhysicalDiskNormalizedHealth(resource, disk)).toBe('offline');
});
it('classifies a failed disk as critical', () => {
const disk = makeDiskData({ health: 'FAILED', riskLevel: 'critical' });
expect(getPhysicalDiskNormalizedHealth({} as Resource, disk)).toBe('critical');
});
it('classifies a SMART-warning disk as warning', () => {
const disk = makeDiskData({
health: 'PASSED',
type: 'hdd',
wearout: 60,
smartAttributes: { pendingSectors: 2 },
});
expect(getPhysicalDiskNormalizedHealth({} as Resource, disk)).toBe('warning');
});
it('classifies a healthy disk as healthy', () => {
const disk = makeDiskData({ health: 'PASSED', type: 'ssd', wearout: 90 });
expect(getPhysicalDiskNormalizedHealth({} as Resource, disk)).toBe('healthy');
});
it('classifies an UNKNOWN-health non-Unraid disk as unknown', () => {
const disk = makeDiskData({ health: 'UNKNOWN' });
expect(getPhysicalDiskNormalizedHealth({} as Resource, disk)).toBe('unknown');
});
it('treats an empty/undefined health string as Unknown label', () => {
const empty = makeDiskData({ health: '' as unknown as undefined });
expect(getPhysicalDiskHealthStatus(empty).label).toBe('Unknown');
const undefinedHealth = makeDiskData({
health: undefined as unknown as string,
});
expect(getPhysicalDiskHealthStatus(undefinedHealth).label).toBe('Unknown');
});
});
describe('matchesPhysicalDiskHealthFilter', () => {
it('returns true for the all filter regardless of health', () => {
expect(matchesPhysicalDiskHealthFilter('unknown', 'all')).toBe(true);
});
it('returns true for the attention filter against offline', () => {
expect(matchesPhysicalDiskHealthFilter('offline', 'attention')).toBe(true);
});
it('returns false for the attention filter against healthy', () => {
expect(matchesPhysicalDiskHealthFilter('healthy', 'attention')).toBe(false);
});
it('returns true for an exact match against the warning filter', () => {
expect(matchesPhysicalDiskHealthFilter('warning', 'warning')).toBe(true);
});
it('returns false for a non-match against the critical filter', () => {
expect(matchesPhysicalDiskHealthFilter('warning', 'critical')).toBe(false);
});
});
describe('getPhysicalDiskHealthSummary empty arm', () => {
it('returns an empty string when the summary is whitespace', () => {
expect(
getPhysicalDiskHealthSummary({
label: 'Healthy',
summary: ' ',
tone: 'text-base-content',
}),
).toBe('');
});
});
describe('getPhysicalDiskRoleLabel ssd/hdd arms', () => {
it('returns SSD for type ssd', () => {
expect(getPhysicalDiskRoleLabel(makeDiskData({ type: 'ssd' }))).toBe('SSD');
});
it('returns HDD for type hdd', () => {
expect(getPhysicalDiskRoleLabel(makeDiskData({ type: 'hdd' }))).toBe('HDD');
});
it('returns a Titleized disk label for other types', () => {
expect(getPhysicalDiskRoleLabel(makeDiskData({ type: 'usb-c' }))).toBe('Usb C disk');
});
it('returns empty string when no role or type is set', () => {
expect(getPhysicalDiskRoleLabel(makeDiskData())).toBe('');
});
});
describe('getPhysicalDiskLifeTextClass muted placeholder arm', () => {
it('returns the muted placeholder class when wearout is 0', () => {
expect(getPhysicalDiskLifeTextClass(makeDiskData({ wearout: 0 }))).toBe(
PHYSICAL_DISK_MUTED_PLACEHOLDER_CLASS,
);
});
it('returns the muted placeholder class when wearout is not a number', () => {
expect(
getPhysicalDiskLifeTextClass(makeDiskData({ wearout: 'nan' as unknown as number })),
).toBe(PHYSICAL_DISK_MUTED_PLACEHOLDER_CLASS);
});
});
describe('matchesPhysicalDiskSearch empty freeTerms arm', () => {
it('returns true when only node terms match and there are no free terms', () => {
const disk = makeDiskData({ node: 'tower' });
const resource = { parentName: 'tower' } as Resource;
expect(matchesPhysicalDiskSearch(resource, disk, 'node:tower')).toBe(true);
});
it('returns true when the search term is empty', () => {
const disk = makeDiskData({ node: 'tower' });
const resource = { parentName: 'tower' } as Resource;
expect(matchesPhysicalDiskSearch(resource, disk, '')).toBe(true);
});
});
describe('comparePhysicalDiskPresentation tie-breaker arms', () => {
it('falls back to node localeCompare when priorities match', () => {
const aDisk = makeDiskData({ node: 'alpha', devPath: '/dev/sda' });
const bDisk = makeDiskData({ node: 'beta', devPath: '/dev/sda' });
expect(
comparePhysicalDiskPresentation({} as Resource, aDisk, {} as Resource, bDisk),
).toBeLessThan(0);
});
it('falls back to devPath localeCompare when priority and node match', () => {
const aDisk = makeDiskData({ node: 'tower', devPath: '/dev/sda' });
const bDisk = makeDiskData({ node: 'tower', devPath: '/dev/sdb' });
expect(
comparePhysicalDiskPresentation({} as Resource, aDisk, {} as Resource, bDisk),
).toBeLessThan(0);
});
it('falls back to resource.name when devPath is empty', () => {
const aDisk = makeDiskData({ node: 'tower', devPath: '' });
const bDisk = makeDiskData({ node: 'tower', devPath: '' });
expect(
comparePhysicalDiskPresentation(
{ name: 'aaa' } as Resource,
aDisk,
{ name: 'bbb' } as Resource,
bDisk,
),
).toBeLessThan(0);
});
});
describe('buildPhysicalDiskPresentationDataMap empty input arm', () => {
it('returns an empty Map when disks is null', () => {
expect(buildPhysicalDiskPresentationDataMap(null as unknown as Resource[]).size).toBe(0);
});
});
describe('filterAndSortPhysicalDisks null/selectedNode arms', () => {
it('returns an empty array when disks is null', () => {
expect(
filterAndSortPhysicalDisks(null as unknown as Resource[], {
selectedNode: null,
searchTerm: '',
getDiskData: () => makeDiskData(),
matchesNode: () => true,
}),
).toEqual([]);
});
it('filters by selected node via the provided matchesNode callback', () => {
const inNode = {
id: 'a',
name: 'a',
physicalDisk: { devPath: '/dev/sda', health: 'PASSED' },
} as unknown as Resource;
const outNode = {
id: 'b',
name: 'b',
physicalDisk: { devPath: '/dev/sdb', health: 'PASSED' },
} as unknown as Resource;
const result = filterAndSortPhysicalDisks([inNode, outNode], {
selectedNode: { id: 'node-1', name: 'tower' } as Resource,
searchTerm: '',
getDiskData: (disk) => extractPhysicalDiskPresentationData(disk),
matchesNode: (disk, node) => disk.id === 'a' && node.id === 'node-1',
});
expect(result.map((d) => d.id)).toEqual(['a']);
});
it('exposes the proxmox instance from the selected node to the matchesNode callback', () => {
const inNode = {
id: 'a',
name: 'a',
physicalDisk: { devPath: '/dev/sda', health: 'PASSED' },
} as unknown as Resource;
const result = filterAndSortPhysicalDisks([inNode], {
selectedNode: {
id: 'node-1',
name: 'tower',
platformData: { proxmox: { instance: 'pve1' } },
} as unknown as Resource,
searchTerm: '',
getDiskData: (disk) => extractPhysicalDiskPresentationData(disk),
matchesNode: (_disk, node) => node.instance === 'pve1',
});
expect(result.map((d) => d.id)).toEqual(['a']);
});
});
describe('buildPhysicalDisk*FilterOptions null input arm', () => {
it('returns only the "all" option when disks is null', () => {
expect(buildPhysicalDiskRoleFilterOptions(null as unknown as Resource[])).toHaveLength(1);
expect(buildPhysicalDiskGroupFilterOptions(null as unknown as Resource[])).toHaveLength(1);
});
});
describe('filter state "all" arms', () => {
it('skips source/health/role/group checks when filters are at their defaults', () => {
const resource = {
id: 'd1',
name: 'd1',
physicalDisk: { devPath: '/dev/sda', health: 'PASSED', diskType: 'ssd' },
} as unknown as Resource;
const resource2 = {
id: 'd2',
name: 'd2',
physicalDisk: { devPath: '/dev/sdb', health: 'PASSED', diskType: 'hdd' },
} as unknown as Resource;
const result = filterAndSortPhysicalDisks([resource, resource2], {
selectedNode: null,
sourceFilter: 'all',
healthFilter: 'all',
roleFilter: 'all',
groupFilter: 'all',
searchTerm: '',
getDiskData: (d) => extractPhysicalDiskPresentationData(d),
matchesNode: () => true,
});
expect(result.map((d) => d.id)).toEqual(['d1', 'd2']);
});
it('rejects disks whose computed role filter value differs from the selected role', () => {
const resource = {
id: 'd1',
name: 'd1',
physicalDisk: { devPath: '/dev/sda', health: 'PASSED', diskType: 'ssd' },
} as unknown as Resource;
const result = filterAndSortPhysicalDisks([resource], {
selectedNode: null,
roleFilter: 'parity',
searchTerm: '',
getDiskData: (d) => extractPhysicalDiskPresentationData(d),
matchesNode: () => true,
});
expect(result).toEqual([]);
});
it('rejects disks whose computed group filter value differs from the selected group', () => {
const resource = {
id: 'd1',
name: 'd1',
physicalDisk: {
devPath: '/dev/sda',
health: 'PASSED',
diskType: 'ssd',
storageGroup: 'tank',
},
} as unknown as Resource;
const result = filterAndSortPhysicalDisks([resource], {
selectedNode: null,
groupFilter: 'other-pool',
searchTerm: '',
getDiskData: (d) => extractPhysicalDiskPresentationData(d),
matchesNode: () => true,
});
expect(result).toEqual([]);
});
});
});
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,164 @@
package monitoring
import (
"reflect"
"testing"
"github.com/rcourtman/pulse-go-rewrite/internal/models"
)
// This file adds branch-coverage tests for findLikelyHostPeer in
// agent_fleet_doctor.go. The function iterates the supplied hosts, SKIPS any
// host whose ID == subject.id (skip-self takes precedence over any identity
// match), and returns the first host for which sameAgentIdentity is true;
// otherwise it returns the zero models.Host and false.
//
// Because findLikelyHostPeer forwards host.ID as both the `id` and `agentID`
// arguments to sameAgentIdentity, an "agent id" match happens when
// subject.agentID == host.ID. Each match case below isolates exactly one
// identity signal so the branch of sameAgentIdentity being exercised is
// unambiguous. Tests are selected by `-run 'HostPeer|FindLikelyHostPeer|Branchcov0720pm'`.
func TestFindLikelyHostPeerBranchcov0720pm(t *testing.T) {
t.Parallel()
// A host that is unrelated to the subject on every identity axis; useful as
// a non-matching filler when building multi-host slices.
unrelated := func(id string) models.Host {
return models.Host{ID: id, Hostname: "totally-unrelated", TokenID: "tok-unrelated"}
}
cases := []struct {
name string
subject agentFleetSubject
hosts []models.Host
wantOK bool
wantHostID string
wantHostHostname string
}{
// Branch: empty/nil hosts slice -> loop body never runs -> (zero, false).
{
name: "empty hosts slice returns zero and false",
subject: agentFleetSubject{id: "self", agentID: "a1", tokenID: "t1", hostname: "h"},
hosts: nil,
wantOK: false,
},
// Branch: skip-self (host.ID == subject.id) taken, then loop ends ->
// (zero, false). The subject carries identity signals but the only host
// is self, so it is skipped before sameAgentIdentity is ever consulted.
{
name: "only host is self id skipped returns zero and false",
subject: agentFleetSubject{id: "self", agentID: "self", tokenID: "t1", hostname: "h"},
hosts: []models.Host{{ID: "self", Hostname: "h", TokenID: "t1"}},
wantOK: false,
},
// Branch: match via the agentID signal. subject.agentID == host.ID
// (both id and agentID args are host.ID). subject.tokenID/hostname are
// empty so the match is unambiguously the agentID branch.
{
name: "match by agent id subject agentID equals host ID",
subject: agentFleetSubject{id: "self", agentID: "agent-x"},
hosts: []models.Host{{ID: "agent-x", Hostname: "unrelated", TokenID: ""}},
wantOK: true,
wantHostID: "agent-x",
wantHostHostname: "unrelated",
},
// Branch: match via the tokenID signal. subject.agentID is empty (so the
// agentID branch is skipped) and subject.hostname is empty (so the
// hostname branch is skipped); only the token branch can fire.
{
name: "match by token id",
subject: agentFleetSubject{id: "self", tokenID: "tok-1"},
hosts: []models.Host{{ID: "host-a", Hostname: "unrelated", TokenID: "tok-1"}},
wantOK: true,
wantHostID: "host-a",
wantHostHostname: "unrelated",
},
// Branch: match via the hostname signal, case-insensitively
// (subject.hostname "Node1" vs host.Hostname "node1"). subject.agentID
// and subject.tokenID are empty and host.TokenID is empty, so only the
// hostname branch of sameAgentIdentity can match.
{
name: "match by hostname case insensitive",
subject: agentFleetSubject{id: "self", hostname: "Node1"},
hosts: []models.Host{{ID: "host-b", Hostname: "node1", TokenID: ""}},
wantOK: true,
wantHostID: "host-b",
wantHostHostname: "node1",
},
// Branch: skip-self takes precedence over match. The single host has
// ID == subject.id AND would match on ALL THREE identity signals
// (agentID, tokenID, hostname) — yet it is still skipped, yielding
// (zero, false). This pins the ordering: the self check runs before
// sameAgentIdentity is called.
{
name: "self host that would match is still skipped",
subject: agentFleetSubject{id: "self-id", agentID: "self-id", tokenID: "tok-1", hostname: "node1"},
hosts: []models.Host{{ID: "self-id", Hostname: "node1", TokenID: "tok-1"}},
wantOK: false,
},
// Branch: first non-self match wins. host[0] neither matches nor is
// self (exercises a sameAgentIdentity==false iteration); host[1] is the
// first match and must be returned; host[2] would also match but must
// never be reached.
{
name: "first non-self match wins among multiple hosts",
subject: agentFleetSubject{id: "self", hostname: "match-host"},
hosts: []models.Host{
unrelated("nope-1"),
{ID: "winner", Hostname: "match-host", TokenID: ""},
{ID: "also-match", Hostname: "match-host", TokenID: ""},
},
wantOK: true,
wantHostID: "winner",
wantHostHostname: "match-host",
},
// Branch: no host matches. The single candidate is not self but
// sameAgentIdentity returns false on every signal -> loop completes ->
// (zero, false).
{
name: "no host matches returns zero and false",
subject: agentFleetSubject{id: "self", agentID: "a1", tokenID: "t1", hostname: "real"},
hosts: []models.Host{{ID: "other", Hostname: "different", TokenID: "t2"}},
wantOK: false,
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
got, ok := findLikelyHostPeer(tc.subject, tc.hosts)
if ok != tc.wantOK {
t.Fatalf("findLikelyHostPeer ok = %v, want %v (subject=%+v, hosts=%#v)",
ok, tc.wantOK, tc.subject, tc.hosts)
}
if tc.wantOK {
// Assert the EXACT host was returned so ordering/identity is
// verified, not just "some host".
if got.ID != tc.wantHostID {
t.Fatalf("returned host ID = %q, want %q", got.ID, tc.wantHostID)
}
if got.Hostname != tc.wantHostHostname {
t.Fatalf("returned host Hostname = %q, want %q", got.Hostname, tc.wantHostHostname)
}
return
}
// Non-match path must return the zero-value models.Host exactly.
if !reflect.DeepEqual(got, models.Host{}) {
t.Fatalf("findLikelyHostPeer returned non-zero host on no-match: %#v", got)
}
})
}
}
@@ -0,0 +1,195 @@
package unifiedresources
import (
"reflect"
"testing"
"github.com/rcourtman/pulse-go-rewrite/pkg/diskinventory"
)
// TestPhysicalDiskViewBranchcov0720pm covers the five PhysicalDiskView
// accessors that were previously 0% covered:
// - Controller() string
// - Target() string
// - StorageGroup() string
// - IO() *PhysicalDiskIOMeta
// - Collection() *diskinventory.CollectionStatus
//
// Each accessor exercises three arms where they exist:
//
// (a) nil-receiver and nil-backing (v.r == nil, then v.r != nil but
// v.r.PhysicalDisk == nil) — must be nil/""-safe, no panic;
// (b) populated backing but the nested field empty/nil (whitespace-only
// strings trim to ""; IO()/Collection() inner pointers nil → nil);
// (c) fully populated — assert the exact returned value, and for the
// pointer-returning accessors assert the clone is field-equal and
// mutation-independent from the live source.
func TestPhysicalDiskViewBranchcov0720pm(t *testing.T) {
t.Run("Controller", func(t *testing.T) {
// (a) nil receiver.
var zero PhysicalDiskView
if got := zero.Controller(); got != "" {
t.Fatalf("nil receiver: expected %q, got %q", "", got)
}
// (a) populated Resource, nil PhysicalDisk backing.
r := &Resource{ID: "pd-ctrl-1", Type: ResourceTypePhysicalDisk}
if got := NewPhysicalDiskView(r).Controller(); got != "" {
t.Fatalf("nil PhysicalDisk: expected %q, got %q", "", got)
}
// (b) PhysicalDisk present, Controller whitespace-only → trims to "".
r.PhysicalDisk = &PhysicalDiskMeta{Controller: " "}
if got := NewPhysicalDiskView(r).Controller(); got != "" {
t.Fatalf("whitespace Controller: expected trimmed %q, got %q", "", got)
}
// (c) Fully populated → trimmed exact value.
r.PhysicalDisk.Controller = " mega-raid-0 "
if got, want := NewPhysicalDiskView(r).Controller(), "mega-raid-0"; got != want {
t.Fatalf("expected Controller %q, got %q", want, got)
}
})
t.Run("Target", func(t *testing.T) {
// (a) nil receiver.
var zero PhysicalDiskView
if got := zero.Target(); got != "" {
t.Fatalf("nil receiver: expected %q, got %q", "", got)
}
// (a) populated Resource, nil PhysicalDisk backing.
r := &Resource{ID: "pd-tgt-1", Type: ResourceTypePhysicalDisk}
if got := NewPhysicalDiskView(r).Target(); got != "" {
t.Fatalf("nil PhysicalDisk: expected %q, got %q", "", got)
}
// (b) PhysicalDisk present, Target whitespace-only → trims to "".
r.PhysicalDisk = &PhysicalDiskMeta{Target: " "}
if got := NewPhysicalDiskView(r).Target(); got != "" {
t.Fatalf("whitespace Target: expected trimmed %q, got %q", "", got)
}
// (c) Fully populated → trimmed exact value.
r.PhysicalDisk.Target = " 0:0:0:0 "
if got, want := NewPhysicalDiskView(r).Target(), "0:0:0:0"; got != want {
t.Fatalf("expected Target %q, got %q", want, got)
}
})
t.Run("StorageGroup", func(t *testing.T) {
// (a) nil receiver.
var zero PhysicalDiskView
if got := zero.StorageGroup(); got != "" {
t.Fatalf("nil receiver: expected %q, got %q", "", got)
}
// (a) populated Resource, nil PhysicalDisk backing.
r := &Resource{ID: "pd-sg-1", Type: ResourceTypePhysicalDisk}
if got := NewPhysicalDiskView(r).StorageGroup(); got != "" {
t.Fatalf("nil PhysicalDisk: expected %q, got %q", "", got)
}
// (b) PhysicalDisk present, StorageGroup whitespace-only → trims to "".
r.PhysicalDisk = &PhysicalDiskMeta{StorageGroup: "\t "}
if got := NewPhysicalDiskView(r).StorageGroup(); got != "" {
t.Fatalf("whitespace StorageGroup: expected trimmed %q, got %q", "", got)
}
// (c) Fully populated → trimmed exact value.
r.PhysicalDisk.StorageGroup = " sg-fast "
if got, want := NewPhysicalDiskView(r).StorageGroup(), "sg-fast"; got != want {
t.Fatalf("expected StorageGroup %q, got %q", want, got)
}
})
t.Run("IO", func(t *testing.T) {
// (a) nil receiver.
var zero PhysicalDiskView
if got := zero.IO(); got != nil {
t.Fatalf("nil receiver: expected nil, got %+v", got)
}
// (a) populated Resource, nil PhysicalDisk backing.
r := &Resource{ID: "pd-io-1", Type: ResourceTypePhysicalDisk}
if got := NewPhysicalDiskView(r).IO(); got != nil {
t.Fatalf("nil PhysicalDisk: expected nil, got %+v", got)
}
// (b) PhysicalDisk present, IO pointer nil → accessor returns nil.
r.PhysicalDisk = &PhysicalDiskMeta{} // IO is nil
if got := NewPhysicalDiskView(r).IO(); got != nil {
t.Fatalf("nil IO: expected nil, got %+v", got)
}
// (c) Fully populated → field-equal clone on a fresh allocation.
want := &PhysicalDiskIOMeta{
Device: "sda",
ReadBytes: 100,
WriteBytes: 200,
ReadOps: 1,
WriteOps: 2,
ReadTimeMs: 3,
WriteTimeMs: 4,
IOTimeMs: 5,
}
r.PhysicalDisk.IO = want
got := NewPhysicalDiskView(r).IO()
if got == nil {
t.Fatal("populated: expected non-nil")
}
if !reflect.DeepEqual(*got, *want) {
t.Fatalf("expected field-equal clone, got %+v want %+v", *got, *want)
}
// Returned pointer must be a fresh allocation, not the live source.
if got == r.PhysicalDisk.IO {
t.Fatal("expected IO() to return a fresh pointer, not the source pointer")
}
// Mutating the clone must not leak back to the source.
got.ReadBytes = 9999
got.Device = "mutated"
if r.PhysicalDisk.IO.ReadBytes != 100 || r.PhysicalDisk.IO.Device != "sda" {
t.Fatalf("mutation leaked to source: got %+v", *r.PhysicalDisk.IO)
}
})
t.Run("Collection", func(t *testing.T) {
// (a) nil receiver.
var zero PhysicalDiskView
if got := zero.Collection(); got != nil {
t.Fatalf("nil receiver: expected nil, got %+v", got)
}
// (a) populated Resource, nil PhysicalDisk backing.
r := &Resource{ID: "pd-coll-1", Type: ResourceTypePhysicalDisk}
if got := NewPhysicalDiskView(r).Collection(); got != nil {
t.Fatalf("nil PhysicalDisk: expected nil, got %+v", got)
}
// (b) PhysicalDisk present, Collection pointer nil → accessor returns nil
// (diskinventory.CloneStatus(nil) returns nil).
r.PhysicalDisk = &PhysicalDiskMeta{} // Collection is nil
if got := NewPhysicalDiskView(r).Collection(); got != nil {
t.Fatalf("nil Collection: expected nil, got %+v", got)
}
// (c) Fully populated → field-equal clone on a fresh allocation.
want := &diskinventory.CollectionStatus{
Serial: diskinventory.Available("smartctl"),
Temperature: diskinventory.Unavailable("smartctl", "no sensor"),
IO: diskinventory.FieldStatus{State: diskinventory.FieldAvailable, Source: "sysfs"},
Controller: diskinventory.Unsupported("nvme", "n/a"),
Pool: diskinventory.Missing("zfs", "not imported"),
}
r.PhysicalDisk.Collection = want
got := NewPhysicalDiskView(r).Collection()
if got == nil {
t.Fatal("populated: expected non-nil")
}
if !reflect.DeepEqual(*got, *want) {
t.Fatalf("expected field-equal clone, got %+v want %+v", *got, *want)
}
// Returned pointer must be a fresh allocation, not the live source.
if got == r.PhysicalDisk.Collection {
t.Fatal("expected Collection() to return a fresh pointer, not the source pointer")
}
// Mutating the clone (scalar via value field on the cloned struct) must
// not leak back to the source. CollectionStatus is a flat struct of
// FieldStatus values, so mutating a nested FieldStatus proves
// independence.
got.Serial = diskinventory.FieldStatus{State: diskinventory.FieldMissing, Source: "mutated"}
got.IO.Source = "leaked"
if r.PhysicalDisk.Collection.Serial.State != diskinventory.FieldAvailable ||
r.PhysicalDisk.Collection.Serial.Source != "smartctl" {
t.Fatalf("Serial mutation leaked to source: %+v", r.PhysicalDisk.Collection.Serial)
}
if r.PhysicalDisk.Collection.IO.Source != "sysfs" {
t.Fatalf("IO.Source mutation leaked to source: %q", r.PhysicalDisk.Collection.IO.Source)
}
})
}
@@ -0,0 +1,92 @@
package diskinventory
import (
"reflect"
"testing"
)
// TestCloneStatusBranchcov0720pm exercises CloneStatus for nil-safety,
// deep value equality on fully-populated and zero-value inputs, and
// bidirectional deep-copy independence (mutating the clone must not affect
// the original and vice versa).
func TestCloneStatusBranchcov0720pm(t *testing.T) {
t.Run("nil input returns nil", func(t *testing.T) {
got := CloneStatus(nil)
if got != nil {
t.Fatalf("CloneStatus(nil) = %v, want nil", got)
}
})
t.Run("zero value clones equal", func(t *testing.T) {
orig := &CollectionStatus{}
clone := CloneStatus(orig)
if clone == nil {
t.Fatalf("CloneStatus returned nil for non-nil zero-value input")
}
if clone == orig {
t.Fatalf("CloneStatus returned identical pointer; want distinct value-equal instance")
}
if !reflect.DeepEqual(*clone, *orig) {
t.Fatalf("zero-value clone not equal to original: clone=%+v orig=%+v", *clone, *orig)
}
})
t.Run("fully populated clones deeply equal", func(t *testing.T) {
orig := fullyPopulatedStatus()
clone := CloneStatus(orig)
if clone == orig {
t.Fatalf("CloneStatus returned identical pointer; want distinct value-equal instance")
}
if !reflect.DeepEqual(*clone, *orig) {
t.Fatalf("clone not deeply equal to original: clone=%+v orig=%+v", *clone, *orig)
}
})
t.Run("clone mutations leave original unchanged", func(t *testing.T) {
orig := fullyPopulatedStatus()
snapshot := *orig
clone := CloneStatus(orig)
// Mutate every field on the clone. CollectionStatus contains only
// value-typed FieldStatus fields (no slices/maps/pointers), so this
// exercises each value field's independence directly.
clone.Serial = Unavailable("clone-mut", "serial")
clone.Temperature = Available("clone-mut")
clone.IO = Unsupported("clone-mut", "io")
clone.Controller = Missing("clone-mut", "controller")
clone.Pool = Unavailable("clone-mut", "pool")
if !reflect.DeepEqual(*orig, snapshot) {
t.Fatalf("original changed after mutating clone: orig=%+v snapshot=%+v", *orig, snapshot)
}
})
t.Run("original mutations leave clone unchanged", func(t *testing.T) {
orig := fullyPopulatedStatus()
clone := CloneStatus(orig)
cloneSnapshot := *clone
orig.Serial = Unavailable("orig-mut", "serial")
orig.Temperature = Available("orig-mut")
orig.IO = Unsupported("orig-mut", "io")
orig.Controller = Missing("orig-mut", "controller")
orig.Pool = Unavailable("orig-mut", "pool")
if !reflect.DeepEqual(*clone, cloneSnapshot) {
t.Fatalf("clone changed after mutating original: clone=%+v snapshot=%+v", *clone, cloneSnapshot)
}
})
}
// fullyPopulatedStatus returns a CollectionStatus with every field set to a
// distinct, non-zero FieldStatus so equality and independence checks are
// sensitive to every field on the struct.
func fullyPopulatedStatus() *CollectionStatus {
return &CollectionStatus{
Serial: Available("smartctl"),
Temperature: Unavailable("smartctl", "deadline exceeded"),
IO: Missing("kernel", "counter absent"),
Controller: Unsupported("provider", "not exposed"),
Pool: Available("provider"),
}
}