| # Failing/Disabled Unit Tests |
| |
| Currently 33 tests are disabled. 10 are blocked by production code issues |
| (missing validation, source bugs, untestable singletons). 3 are blocked by |
| test infrastructure limitations (mock constraints, encode/decode mismatches). |
| 1 is blocked by a design issue (coroutine destructor safety). 11 are blocked |
| by long-running event response struct mismatches or async handler decode |
| assumptions (added 2026-03-18). 6 are blocked by a production code buffer |
| overflow in `getDeviceModeSettingsV2Handler` (added 2026-03-20). 4 added |
| 2026-03-30 (MctpDiscovery singleton, mock D-Bus path validation). |
| |
| --- |
| |
| ## Disabled Tests |
| |
| ### 1. NsmDotTest.DISABLED_UnlockInvalidEcdsaSignature |
| |
| **File**: `nsmd/nsmDot/test/nsmDot_test.cpp` |
| |
| **What fails**: Test expects `InvalidArgument` throw when a non-empty but |
| malformed ECDSA key is passed to `unlock()`. Production code only validates |
| empty strings synchronously; format/content validation is asynchronous. |
| |
| **Why it should pass**: Synchronous input validation for malformed ECDSA key |
| format should throw `InvalidArgument` immediately. |
| |
| **Status**: DISABLED_ — requires adding synchronous format validation to |
| `unlock()` in production code. |
| |
| --- |
| |
| ### 2. NsmDotTest.DISABLED_CAKRotateInvalidCAKKey |
| |
| **File**: `nsmd/nsmDot/test/nsmDot_test.cpp` |
| |
| **What fails**: Test expects `InvalidArgument` throw when a non-empty but |
| malformed CAK key is passed to `cakRotate()`. Same root cause as above. |
| |
| **Why it should pass**: Synchronous input validation for malformed CAK key |
| format should throw `InvalidArgument` immediately. |
| |
| **Status**: DISABLED_ — requires adding synchronous format validation to |
| `cakRotate()` in production code. |
| |
| --- |
| |
| ### 3. NsmDotTest.DISABLED_CAKRotateInvalidSignature |
| |
| **File**: `nsmd/nsmDot/test/nsmDot_test.cpp` |
| |
| **What fails**: Test expects `InvalidArgument` throw when a malformed |
| signature is passed to `cakRotate()`. Same root cause as above. |
| |
| **Why it should pass**: Synchronous input validation for malformed signature |
| format should throw `InvalidArgument` immediately. |
| |
| **Status**: DISABLED_ — requires adding synchronous format validation to |
| `cakRotate()` in production code. |
| |
| --- |
| |
| ### 4. NsmDotCreateTestFixture.DISABLED_badTestCreateDotDeviceNotFound |
| |
| **File**: `nsmd/nsmDot/test/nsmDot_test.cpp` |
| |
| **What fails**: Test expects that when a device is not found by UUID, the |
| object creation path handles the "not found" case. However, |
| `MockSensorManager::getNsmDeviceFromStaticUUID` always creates and returns a |
| new MockNsmDevice rather than returning null/not-found. |
| |
| **Why it should pass**: The production code path where `getNsmDeviceFromStaticUUID` |
| returns null (device not found) should be testable. |
| |
| **Status**: DISABLED_ — blocked by MockSensorManager always constructing |
| devices. Requires a NullReturnMockSensorManager variant for this test. |
| |
| --- |
| |
| ### 5. NsmChassisTest.DISABLED_goodTestCreateChassisAttributesWithAllFeatures |
| |
| **File**: `nsmd/nsmChassis/test/nsmChassis_test.cpp` |
| |
| **What fails**: Factory function registered via `REGISTER_NSM_CREATION_FUNCTION` |
| (`__attribute__((constructor))`) is not invoked because the linker does not |
| pull in the object file when linking with `link_with` (not `link_whole`). |
| `NsmObjectFactory::instance().creationFunctions.count(intf) == 0` at runtime. |
| |
| **Why it should pass**: All chassis attribute factory registrations should be |
| exercised in this integration test. |
| |
| **Status**: DISABLED_ — blocked by linker/factory registration issue. |
| Resolution requires `link_whole` for the relevant static library or a |
| direct forward-declaration workaround. |
| |
| --- |
| |
| ### 6. NsmChassisTest.DISABLED_goodTestCreateErrorInjectionPayload |
| |
| **File**: `nsmd/nsmChassis/test/nsmChassis_test.cpp` |
| |
| **What fails**: Encode/decode size mismatch — the encoded payload for |
| error injection is larger than what the decode function expects, causing |
| a length check failure and the test assertion to fail. |
| |
| **Why it should pass**: The encode and decode sizes for the error injection |
| payload should match. |
| |
| **Status**: DISABLED_ — possible source code bug or test construction issue. |
| Requires investigation of struct sizes in the error injection encode/decode path. |
| |
| --- |
| |
| ### 7. NsmProcessorBatch9Test.DISABLED_CreateNSMProcessor_BaseType |
| |
| **File**: `nsmd/nsmChassis/test/nsmChassis_test.cpp` (or nsmProcessor test) |
| |
| **What fails**: Required D-Bus property maps (object path → interface → |
| property value) are not registered in the test environment, causing |
| `coGetCachedBaseProperties` to return `NSM_SW_ERROR` and the processor |
| creation to fail before the tested code path is reached. |
| |
| **Why it should pass**: NSM_Processor base type creation path should be |
| testable once the required D-Bus properties are set up. |
| |
| **Status**: DISABLED_ — requires setting up the full set of D-Bus mock |
| property maps for the NSM_Processor base type creation path. |
| |
| --- |
| |
| ### 8. NsmRediscoveryEventTest.DISABLED_Handle_ValidEvent_ReturnsSuccess |
| |
| **File**: `nsmd/nsmEvent/test/nsmEvent_dump_test.cpp` |
| |
| **What fails**: Test requires `MctpDiscovery` singleton which has a |
| complex initialization path that cannot be safely constructed in a unit |
| test environment (accesses real D-Bus, real MCTP stack). |
| |
| **Why it should pass**: The `Handle_ValidEvent_ReturnsSuccess` path should |
| be exercisable if the MCTP discovery infrastructure were mockable. |
| |
| **Status**: DISABLED_ — permanently blocked. `MctpDiscovery` is a |
| non-injectable singleton with no virtual interface. Resolution requires |
| refactoring the production code to inject `MctpDiscovery` as a dependency. |
| |
| --- |
| |
| ### 9. NsmLeakDetectionPatchDeviceTest.DISABLED_OnDevice_EncodeFail_NullData |
| |
| **File**: `nsmd/nsmChassis/test/nsmLeakDetection_test.cpp` |
| |
| **What fails**: Production code dereferences a pointer before checking if |
| encoding succeeded (null data pointer), causing a null dereference / segfault |
| when encode returns null. |
| |
| **Why it should pass**: The encode-failure path should handle null gracefully |
| before dereferencing. This is a source code bug. |
| |
| **Status**: DISABLED_ — source code bug in the encode-failure path. Requires |
| a null-check guard in production code before dereferencing encode output. |
| |
| --- |
| |
| ### 10. CoroutineDestructorTest.DISABLED_DestroySuspendedHandle_NoMemoryLeak |
| |
| **File**: `common/test/common_utils_coroutine_test.cpp` |
| |
| **What fails**: The `~Coroutine()` fix (changing `if (handle && handle.done())` to |
| `if (handle)`) was reverted because it introduces a use-after-free risk in production. |
| When a coroutine is suspended waiting for an async response (e.g. MCTP), the async |
| infrastructure (boost::asio, sdbusplus) holds a copy of the `coroutine_handle<>`. |
| Destroying the frame in the destructor while the callback still references it causes |
| a crash when the response arrives and the callback tries to `resume()` the destroyed |
| handle. The test validates the fix that was reverted, so it must be disabled. |
| |
| **Why it should pass**: The old code (`if (handle && handle.done())`) leaks the frame |
| of suspended coroutines. A proper fix requires a cancellation mechanism, shared |
| ownership of the handle, or always using `detach()` before dropping a |
| potentially-suspended Coroutine. |
| |
| **Status**: DISABLED_ — design issue. Requires production code changes to safely |
| destroy suspended coroutine handles. |
| |
| --- |
| |
| ### 11. NsmNvlinkLedIntfTest.DISABLED_Update_DefaultLedState_SetsReadError |
| |
| **File**: `nsmd/nsmChassis/test/nsmChassisLED_test.cpp` |
| |
| **What fails**: The test targets a branch that is dead code in practice. |
| The NvLink LED state uses a 3-bit enum with only 2 valid values (Off/On), |
| and the switch statement covers all reachable values. The `default` branch |
| (which would set a read error) is never reachable with valid enum values |
| from the decode function. |
| |
| **Why it should pass**: If the enum had a third value that fell through to |
| default, the ReadError path would be exercised. |
| |
| **Status**: DISABLED_ — dead code branch. The `default:` path in the switch |
| is unreachable given the 3-bit enum's actual usage. No fix needed in tests; |
| production code could remove the dead default branch. |
| |
| --- |
| |
| ### 12–17. NsmProcessorBranch2Test — 6 DISABLED long-running event response tests |
| |
| **File**: `nsmd/nsmProcessor/test/nsmProcessorBranch2_test.cpp` |
| |
| | Test | What fails | |
| |------|-----------| |
| | `DISABLED_MigMode_HandleResp_LongRunning_Success` | `encode_get_MIG_mode_event_resp` produces a response that `handleResponseMsg` rejects — event response struct size differs from non-event struct | |
| | `DISABLED_MigMode_HandleResp_LongRunning_ErrorCC` | Same — event encode/decode struct mismatch | |
| | `DISABLED_EccMode_HandleResp_LongRunning_Success` | Same pattern for ECC mode event response | |
| | `DISABLED_EccMode_HandleResp_LongRunning_ErrorCC` | Same | |
| | `DISABLED_CurrentUtilization_HandleResp_LongRunning_Success_2` | Event response struct for utilization differs from poll response | |
| | `DISABLED_ThrottleDuration_HandleResp_LongRunning_Success_2` | Event response struct for violation duration differs from poll response | |
| |
| **Why they should pass**: The `isLongRunning=true` path in `handleResponseMsg` |
| calls the `_event_resp` decode variant, which expects a different struct layout |
| than the non-event response. The test encodes with the event encoder but the |
| buffer size is allocated for the non-event struct. |
| |
| **Status**: DISABLED_ — requires using the correct event response struct sizes |
| and verifying the event decode path works in COVERAGE_DISABLE_COROUTINES mode. |
| |
| --- |
| |
| ### 18–22. NsmDebugTokenNICBranchTest — 5 DISABLED async handler tests |
| |
| **File**: `nsmd/nsmDebugToken/test/nsmDebugTokenNICBranch_test.cpp` |
| |
| | Test | What fails | |
| |------|-----------| |
| | `DISABLED_disableTokensAsyncReasonCodeNotSuccess` | `reasonCode` field in decode response is not populated as expected — decode strips reasonCode when cc==NSM_SUCCESS | |
| | `DISABLED_getRequestAsyncTokenAlreadyActive` | `tokenAlreadyActiveReasonCode` constant not matching the decode output for query_token_parameters | |
| | `DISABLED_installTokenAsyncTokenAlreadyActive` | Same pattern — provide_token decode does not expose reasonCode in the expected way | |
| | `DISABLED_installTokenAsyncReasonCodeOther` | Same — reasonCode routing differs from test expectation | |
| | `DISABLED_updateEmptyDeviceId` | `update()` with empty deviceId requires specific decode path that doesn't trigger as expected in coverage mode | |
| |
| **Why they should pass**: The async handlers check `reasonCode` values after |
| decode, but the decode functions strip or transform reasonCode depending on cc. |
| Tests construct responses with specific reasonCodes but the decode layer doesn't |
| pass them through as expected. |
| |
| **Status**: DISABLED_ — requires deeper analysis of how each decode function |
| handles reasonCode passthrough vs transformation. |
| |
| --- |
| |
| ### 23–32. MctpEndpointProberBranchTest — 10 DISABLED NOT_READY retry tests |
| |
| **File**: `nsmd/test/mctpEndpointProberBranch_test.cpp` |
| |
| | Test | What fails | |
| |------|-----------| |
| | `DISABLED_Ping_NotReady_ThenSuccess` | Coroutine retry loop with co_await sleep not executing in COVERAGE_DISABLE_COROUTINES mode | |
| | `DISABLED_Ping_NotReady_AllRetriesExhausted` | Same — retry loop requires real coroutine execution | |
| | `DISABLED_Ping_NotReady_TransportFailDuringRetry` | Same | |
| | `DISABLED_Ping_NotReady_NonRetryableCcDuringRetry` | Same | |
| | `DISABLED_Ping_NotReady_SingleRetry_Success` | Same | |
| | `DISABLED_QueryDevId_NotReady_ThenSuccess` | Same — getQueryDeviceIdentification retry loop | |
| | `DISABLED_QueryDevId_NotReady_AllRetriesExhausted` | Same | |
| | `DISABLED_QueryDevId_NotReady_TransportFailDuringRetry` | Same | |
| | `DISABLED_QueryDevId_NotReady_NonRetryableCcDuringRetry` | Same | |
| | `DISABLED_QueryDevId_NotReady_SingleRetry_Success` | Same | |
| |
| **Why they fail**: The NOT_READY retry loop in `ping()` and |
| `getQueryDeviceIdentification()` uses `co_await` for delay between retries. |
| In COVERAGE_DISABLE_COROUTINES mode, coroutines run synchronously and |
| `co_await` on timers does not actually wait — the retry sequence callback |
| never fires, so the retry loop never progresses past the first attempt. |
| |
| **Status**: DISABLED_ — requires real coroutine executor or timer mock |
| to test retry behavior. |
| |
| --- |
| |
| ### 23–28. MockupResponderBranch3Test — 6 DISABLED GetDeviceModeSettingsV2 tests |
| |
| **File**: `mockupResponder/test/mockupResponderBranch3_test.cpp` |
| |
| | Test | What fails | |
| |------|-----------| |
| | `DISABLED_GetDeviceModeSettingsV2OneShotGpuPower` | Valgrind invalid write — buffer allocation off-by-one | |
| | `DISABLED_GetDeviceModeSettingsV2PersistentGpuPower` | Same | |
| | `DISABLED_GetDeviceModeSettingsV2OneShotCpuPower` | Same | |
| | `DISABLED_GetDeviceModeSettingsV2PersistentCpuPower` | Same | |
| | `DISABLED_GetDeviceModeSettingsV2DefaultIndex` | Same | |
| | `DISABLED_GetDeviceModeSettingsV2Quiet` (QuietTest fixture) | Same | |
| |
| **What fails**: Valgrind reports an invalid write of size 1 in |
| `encode_get_device_mode_settings_v2_resp` (device-configuration.c). |
| `MockupResponder::getDeviceModeSettingsV2Handler` allocates the response |
| buffer using `sizeof(nsm_get_device_mode_settings_v2_resp) + |
| currentModeData.size() + pendingModeData.size() - 2`. Since the struct |
| already includes 1 byte for `mode_data[1]`, the correct formula requires |
| `- 1` (not `- 2`), so the buffer is 1 byte too small and encode writes |
| past its end. |
| |
| **Why they should pass**: `getDeviceModeSettingsV2Handler` should allocate |
| a correctly-sized buffer before encoding. With `-1` instead of `-2`, the |
| overflow would be fixed and all tests would pass. |
| |
| **Status**: DISABLED_ — production code bug in `mockupResponder/mockupResponder.cpp` |
| at the buffer size calculation. Requires changing `- 2` to `- 1` in |
| `getDeviceModeSettingsV2Handler`. |
| |
| --- |
| |
| --- |
| |
| ### 29–31. NsmDeviceBranch2 — 3 DISABLED DumpNsmDeviceInfo tests |
| |
| **File**: `nsmd/test/nsmDeviceBranch2_test.cpp` |
| |
| | Test | What fails | |
| |------|-----------| |
| | `DISABLED_DumpNsmDeviceInfo_DoesNotCrash` | `dumpNsmDeviceInfo()` throws `std::runtime_error("MctpDiscovery instance is not initialized yet")` | |
| | `DISABLED_DumpNsmDeviceInfo_WithEventSubscriptionStatus` | Same | |
| | `DISABLED_DumpNsmDeviceInfo_LastEventRequestAndResponsePresent` | Same | |
| |
| **Why they should pass**: `dumpNsmDeviceInfo()` should launch a detached coroutine without |
| accessing the `MctpDiscovery` singleton synchronously. |
| |
| **Status**: DISABLED_ — `MctpDiscovery` is a non-injectable singleton; accessing it in a |
| unit-test context throws before the coroutine body executes. |
| |
| --- |
| |
| ### 32. NsmPowerSubSystemBranchTest.DISABLED_Factory_NameAbsent_FalseBranch_EmptyNameUsed |
| |
| **File**: `nsmd/nsmChassis/test/nsmPowerSubSystemBranch_test.cpp` |
| |
| **What fails**: With `Name` absent, an empty name is used to construct the D-Bus object path. |
| `sd_bus_add_object_vtable` rejects the empty/invalid path with `InvalidArgs`. |
| |
| **Why it should pass**: The production code path should handle an empty name without crashing |
| (or should validate earlier). The test assumed the mock D-Bus layer would not validate paths. |
| |
| **Status**: DISABLED_ — mock sdbusplus validates D-Bus object paths; an empty name produces |
| an invalid path. Requires non-empty name or earlier validation in production code. |
| |
| --- |
| |
| ## Fixed Tests (Historical) |
| |
| The following tests were previously disabled and have since been fixed: |
| |
| - `Contended_DeferFails_WaiterNotResumed` — fixed 2026-03-10: `coroutineSemaphore.hpp` |
| leak fixed by extracting `awaiterPtr` before `sd_event_add_defer`, deleting on |
| failure path. |
| - `EraseDebugInfo_UnsupportedType_SetsInternalFailure` — fixed 2026-03-10: use |
| `EraseInfoType::Other` instead of `static_cast<EraseInfoType>(99)` (sdbusplus |
| enum-to-string throws for out-of-range values). |
| - `HandleResponseMsg_ShortLen_ReturnsError` (nsmSwitchBranch) — fixed 2026-03-10: |
| buffer size corrected to `sizeof(nsm_msg_hdr)+sizeof(nsm_common_non_success_resp)` |
| with all-zeros (cc=NSM_SUCCESS), triggering the length check correctly. |
| - `NsmApSkuIdObjectTest.HandleResponseMsg_Success_SetsSku` — fixed 2026-03-13: |
| buffer enlarged to 512 bytes (TLV encode requires more space than raw struct); |
| expected SKU updated to `formatApSkuId(0)` (ap_sku_id not in TLV stream). |