Skip to content

TEST-PORTABILITY-HAL-002: Error Scenario Tests #309

Description

@zarfld

Test Information

Test ID: TEST-PORTABILITY-HAL-002
Type: Integration Test (Error Scenarios)
Priority: P0 (Critical)
Test Level: Integration

Traceability


Test Objective

Verify that all 10 error scenarios defined in REQ-NF-PORTABILITY-001 are handled correctly with appropriate NTSTATUS codes, event logging, and recovery mechanisms.


Test Cases

TC-ERR-001: Unsupported Device ID (ES-PORT-HAL-001)

Error Scenario: Device ID not in SelectHardwareOps switch
Expected NTSTATUS: STATUS_NOT_SUPPORTED (0xC00000BB)
Expected Event: 17301 (Error: Unsupported device)

Test Steps:

// Test unsupported device IDs
USHORT unsupportedDevices[] = {0x1521, 0x150E, 0x10C9, 0xFFFF};

for (int i = 0; i < ARRAYSIZE(unsupportedDevices); i++) {
    PHARDWARE_OPS ops = NULL;
    NTSTATUS status = SelectHardwareOps(unsupportedDevices[i], &ops);
    
    ASSERT_EQ(status, STATUS_NOT_SUPPORTED);
    ASSERT_EQ(ops, NULL);
    
    // Verify event 17301 logged
    ASSERT_EVENT_LOGGED(17301, unsupportedDevices[i]);
}

// Verify driver unloads for this adapter
FILTER_ADAPTER_CONTEXT ctx = {0};
status = InitializeHardwareContext(&ctx, NULL);  // Will fail with unsupported device
ASSERT_EQ(status, STATUS_NOT_SUPPORTED);
ASSERT_EQ(ctx.HwOps, NULL);
ASSERT_EQ(ctx.HwContext, NULL);

Pass Criteria:

  • STATUS_NOT_SUPPORTED returned
  • Event 17301 logged with device ID
  • No memory allocated

TC-ERR-002: NULL Hardware Operation (ES-PORT-HAL-002)

Error Scenario: Operation table has NULL function pointer
Expected NTSTATUS: STATUS_ACCESS_VIOLATION (0xC0000005)
Expected Event: 17302 (Critical: NULL operation pointer)

Test Steps:

// Create malformed operation table with NULL operation
HARDWARE_OPS badOps = HwOpsI210;
badOps.ReadPhc = NULL;  // Intentionally NULL

FILTER_ADAPTER_CONTEXT ctx = {0};
ctx.HwOps = &badOps;
ctx.HwContext = &mockContext;

// Attempt to call NULL operation
LARGE_INTEGER timestamp;
__try {
    NTSTATUS status = ctx.HwOps->ReadPhc(ctx.HwContext, &timestamp);
    FAIL("Should have caught NULL pointer");
} __except(EXCEPTION_EXECUTE_HANDLER) {
    // Expected: Access violation caught
    ASSERT_EVENT_LOGGED(17302);
}

// Static assertion check (compile-time)
// This should be in production code:
// C_ASSERT(offsetof(HARDWARE_OPS, ReadPhc) != NULL);

Pass Criteria:

  • NULL pointer detected (runtime or compile-time)
  • Event 17302 logged
  • System does not crash in production (static assertion prevents this)

TC-ERR-003: Hardware Capability Mismatch (ES-PORT-HAL-003)

Error Scenario: Driver attempts launch time on device without support
Expected NTSTATUS: STATUS_NOT_SUPPORTED (0xC00000BB)
Expected Event: 17303 (Warning: Feature not supported)

Test Steps:

// Create mock device without launch time support
HARDWARE_CAPABILITIES caps = {0};
caps.SupportsLaunchTime = FALSE;  // Feature disabled
caps.SupportsCreditBasedShaping = TRUE;
caps.NumTxQueues = 2;

FILTER_ADAPTER_CONTEXT ctx = {0};
ctx.HwOps = &HwOpsMock;
ctx.HwContext = &mockContext;
ctx.Caps = &caps;

// Attempt to enable launch time
NTSTATUS status = HandleEnableLaunchTime(&ctx, 0, TRUE);

// Expected: Check capability first, return error
ASSERT_EQ(status, STATUS_NOT_SUPPORTED);

// Verify event logged
ASSERT_EVENT_LOGGED(17303);

// Verify feature gracefully degraded
ASSERT_FALSE(ctx.LaunchTimeEnabled[0]);

Pass Criteria:

  • Feature check before hardware access
  • STATUS_NOT_SUPPORTED returned
  • Event 17303 logged
  • No hardware access attempted

TC-ERR-004: Register Offset Out of Bounds (ES-PORT-HAL-004)

Error Scenario: ReadRegister32 with offset >BAR0 size
Expected NTSTATUS: STATUS_INVALID_PARAMETER (0xC000000D)
Expected Event: 17304 (Error: Invalid register offset)

Test Steps:

#define BAR0_SIZE 0x10000  // 64KB typical size

FILTER_ADAPTER_CONTEXT ctx = {0};
ctx.HwOps = &HwOpsI210;
ctx.HwContext = &i210Context;

// Attempt to read beyond BAR0 size
ULONG value;
NTSTATUS status = ctx.HwOps->ReadRegister32(ctx.HwContext, 0xFFFFFFFF, &value);

ASSERT_EQ(status, STATUS_INVALID_PARAMETER);
ASSERT_EVENT_LOGGED(17304, 0xFFFFFFFF);

// Attempt to read at BAR0_SIZE (boundary)
status = ctx.HwOps->ReadRegister32(ctx.HwContext, BAR0_SIZE, &value);
ASSERT_EQ(status, STATUS_INVALID_PARAMETER);

// Valid read (within bounds)
status = ctx.HwOps->ReadRegister32(ctx.HwContext, 0x1000, &value);
ASSERT_EQ(status, STATUS_SUCCESS);

Pass Criteria:

  • Offset validation before hardware access
  • STATUS_INVALID_PARAMETER for out-of-bounds
  • Event 17304 logged
  • No page fault or system crash

TC-ERR-005: Hardware Initialization Failure (ES-PORT-HAL-005)

Error Scenario: Initialize() returns error (e.g., BAR0 not mapped)
Expected NTSTATUS: STATUS_DEVICE_CONFIGURATION_ERROR (0xC0000182)
Expected Event: 17305 (Error: Hardware init failed)

Test Steps:

// Simulate BAR0 mapping failure
FILTER_ADAPTER_CONTEXT ctx = {0};
ctx.FilterHandle = MockFilterHandle;

// Mock NDIS to return NULL BAR0
MockNdisGetBar0(NULL);  // Simulate failure

NTSTATUS status = InitializeHardwareContext(&ctx, NULL);

ASSERT_EQ(status, STATUS_DEVICE_CONFIGURATION_ERROR);
ASSERT_EVENT_LOGGED(17305);

// Verify cleanup occurred
ASSERT_EQ(ctx.HwOps, NULL);
ASSERT_EQ(ctx.HwContext, NULL);

// Verify no memory leaked
ASSERT_NO_POOL_LEAKS('CWHA');

Pass Criteria:

  • STATUS_DEVICE_CONFIGURATION_ERROR returned
  • Event 17305 logged
  • Resources cleaned up
  • No memory leaks

TC-ERR-006: Operation Table Version Mismatch (ES-PORT-HAL-007)

Error Scenario: Core expects v2 operations, driver provides v1 table
Expected NTSTATUS: STATUS_REVISION_MISMATCH (0xC0000059)
Expected Event: 17307 (Error: HAL version mismatch)

Test Steps:

// Simulate v1 operation table (missing new operations)
typedef struct _HARDWARE_OPS_V1 {
    ULONG Version;  // Set to 1
    NTSTATUS (*ReadPhc)(PVOID Context, PLARGE_INTEGER Timestamp);
    NTSTATUS (*AdjustPhcFrequency)(PVOID Context, LONG FrequencyPpb);
    // Missing newer operations...
} HARDWARE_OPS_V1;

HARDWARE_OPS_V1 opsV1 = {0};
opsV1.Version = 1;

FILTER_ADAPTER_CONTEXT ctx = {0};

// Attempt to use v1 ops with v2 core
NTSTATUS status = ValidateOperationTableVersion((PHARDWARE_OPS)&opsV1);

ASSERT_EQ(status, STATUS_REVISION_MISMATCH);
ASSERT_EVENT_LOGGED(17307, 1, 2);  // Expected v2, got v1

// Verify driver load fails
status = InitializeHardwareContext(&ctx, NULL);
ASSERT_NE(status, STATUS_SUCCESS);

Pass Criteria:

  • Version field checked at initialization
  • STATUS_REVISION_MISMATCH returned
  • Event 17307 logged
  • Driver load aborted

TC-ERR-007: Concurrent Operation Calls (ES-PORT-HAL-008)

Error Scenario: Two threads call operations concurrently without lock
Expected: Spinlock protects hardware state
Expected Event: 17308 (Warning: Concurrent operation detected)

Test Steps:

FILTER_ADAPTER_CONTEXT ctx = {0};
ctx.HwOps = &HwOpsI210;
ctx.HwContext = &i210Context;

volatile LONG threadCount = 0;
volatile LONG raceDetected = 0;

// Thread 1: Read PHC
HANDLE thread1 = CreateThread(NULL, 0, [](LPVOID param) -> DWORD {
    PFILTER_ADAPTER_CONTEXT ctx = (PFILTER_ADAPTER_CONTEXT)param;
    
    for (int i = 0; i < 10000; i++) {
        LARGE_INTEGER timestamp;
        
        // Acquire lock before hardware access
        NdisAcquireSpinLock(&ctx->RegisterLock);
        
        // Detect concurrent access (should not happen with lock)
        if (InterlockedIncrement(&threadCount) > 1) {
            InterlockedIncrement(&raceDetected);
        }
        
        ctx->HwOps->ReadPhc(ctx->HwContext, &timestamp);
        
        InterlockedDecrement(&threadCount);
        NdisReleaseSpinLock(&ctx->RegisterLock);
    }
    
    return 0;
}, &ctx, 0, NULL);

// Thread 2: Adjust PHC
HANDLE thread2 = CreateThread(NULL, 0, [](LPVOID param) -> DWORD {
    PFILTER_ADAPTER_CONTEXT ctx = (PFILTER_ADAPTER_CONTEXT)param;
    
    for (int i = 0; i < 10000; i++) {
        NdisAcquireSpinLock(&ctx->RegisterLock);
        
        if (InterlockedIncrement(&threadCount) > 1) {
            InterlockedIncrement(&raceDetected);
        }
        
        ctx->HwOps->AdjustPhcFrequency(ctx->HwContext, 100);
        
        InterlockedDecrement(&threadCount);
        NdisReleaseSpinLock(&ctx->RegisterLock);
    }
    
    return 0;
}, &ctx, 0, NULL);

WaitForMultipleObjects(2, (HANDLE[]){thread1, thread2}, TRUE, INFINITE);

// Verify no race conditions detected
ASSERT_EQ(raceDetected, 0);

Pass Criteria:

  • Spinlock prevents concurrent hardware access
  • No race conditions detected
  • Event 17308 logged if concurrent access detected (without lock)

TC-ERR-008: Device-Specific State Overflow (ES-PORT-HAL-009)

Error Scenario: HW_CONTEXT.DeviceSpecific union too small for new hardware
Expected: Compile-time assertion failure

Test Steps:

// Static assertion in production code:
// C_ASSERT(sizeof(HW_CONTEXT.DeviceSpecific) >= sizeof(I210_CONTEXT));
// C_ASSERT(sizeof(HW_CONTEXT.DeviceSpecific) >= sizeof(I225_CONTEXT));
// C_ASSERT(sizeof(HW_CONTEXT.DeviceSpecific) >= sizeof(I226_CONTEXT));

// Runtime test: Verify union size
ASSERT_GE(sizeof(((HW_CONTEXT*)0)->DeviceSpecific), sizeof(I210_CONTEXT));
ASSERT_GE(sizeof(((HW_CONTEXT*)0)->DeviceSpecific), sizeof(I225_CONTEXT));
ASSERT_GE(sizeof(((HW_CONTEXT*)0)->DeviceSpecific), sizeof(I226_CONTEXT));

// Simulate new hardware with larger context
typedef struct {
    UCHAR Buffer[2048];  // Intentionally large
} I227_CONTEXT;

// This should fail at compile time if static assertion exists
// ASSERT_GE(sizeof(((HW_CONTEXT*)0)->DeviceSpecific), sizeof(I227_CONTEXT));

Pass Criteria:

  • Static assertions prevent deployment
  • Union size checked at compile time
  • Build failure prevents introduction of oversized context

TC-ERR-009: Missing Operation Implementation (ES-PORT-HAL-010)

Error Scenario: New feature added but not implemented for all devices
Expected NTSTATUS: STATUS_NOT_IMPLEMENTED (0xC0000002)
Expected Event: 17310 (Info: Operation not implemented)

Test Steps:

// Simulate new operation added to HAL
typedef NTSTATUS (*GET_TEMPERATURE_FN)(PVOID Context, PLONG Temperature);

typedef struct {
    HARDWARE_OPS Base;
    GET_TEMPERATURE_FN GetTemperature;  // New operation
} HARDWARE_OPS_V2;

// i225 implements new operation
NTSTATUS I225_GetTemperature(PVOID Context, PLONG Temperature) {
    *Temperature = 45;  // Mock value
    return STATUS_SUCCESS;
}

// i210 uses default stub (not implemented)
NTSTATUS Default_GetTemperature(PVOID Context, PLONG Temperature) {
    TraceInfo("GetTemperature not implemented for this device");
    EventLog(17310, "GetTemperature");
    return STATUS_NOT_IMPLEMENTED;
}

// Test with i225 (implemented)
LONG temp;
NTSTATUS status = I225_GetTemperature(NULL, &temp);
ASSERT_EQ(status, STATUS_SUCCESS);
ASSERT_EQ(temp, 45);

// Test with i210 (not implemented)
status = Default_GetTemperature(NULL, &temp);
ASSERT_EQ(status, STATUS_NOT_IMPLEMENTED);
ASSERT_EVENT_LOGGED(17310);

Pass Criteria:

  • Default stub returns STATUS_NOT_IMPLEMENTED
  • Event 17310 logged
  • Feature gracefully unavailable on older hardware

Test Environment

Hardware: Mock hardware + real i210/i225 NICs (for integration tests)
Software:

  • Windows 10/11 with Driver Verifier enabled
  • Multi-threaded test harness
  • Event log monitoring

Pass/Fail Criteria

Pass:

  • All error scenarios handled correctly (10/10)
  • Correct NTSTATUS codes returned
  • All events logged correctly
  • No system crashes or memory corruption

Fail:

  • Any error scenario not handled
  • Wrong NTSTATUS code
  • Missing event log entries
  • System crash or data corruption

Created: 2025-12-30
Status: Ready for Implementation

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions