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

TestWhat fails
DISABLED_MigMode_HandleResp_LongRunning_Successencode_get_MIG_mode_event_resp produces a response that handleResponseMsg rejects — event response struct size differs from non-event struct
DISABLED_MigMode_HandleResp_LongRunning_ErrorCCSame — event encode/decode struct mismatch
DISABLED_EccMode_HandleResp_LongRunning_SuccessSame pattern for ECC mode event response
DISABLED_EccMode_HandleResp_LongRunning_ErrorCCSame
DISABLED_CurrentUtilization_HandleResp_LongRunning_Success_2Event response struct for utilization differs from poll response
DISABLED_ThrottleDuration_HandleResp_LongRunning_Success_2Event 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

TestWhat fails
DISABLED_disableTokensAsyncReasonCodeNotSuccessreasonCode field in decode response is not populated as expected — decode strips reasonCode when cc==NSM_SUCCESS
DISABLED_getRequestAsyncTokenAlreadyActivetokenAlreadyActiveReasonCode constant not matching the decode output for query_token_parameters
DISABLED_installTokenAsyncTokenAlreadyActiveSame pattern — provide_token decode does not expose reasonCode in the expected way
DISABLED_installTokenAsyncReasonCodeOtherSame — reasonCode routing differs from test expectation
DISABLED_updateEmptyDeviceIdupdate() 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

TestWhat fails
DISABLED_Ping_NotReady_ThenSuccessCoroutine retry loop with co_await sleep not executing in COVERAGE_DISABLE_COROUTINES mode
DISABLED_Ping_NotReady_AllRetriesExhaustedSame — retry loop requires real coroutine execution
DISABLED_Ping_NotReady_TransportFailDuringRetrySame
DISABLED_Ping_NotReady_NonRetryableCcDuringRetrySame
DISABLED_Ping_NotReady_SingleRetry_SuccessSame
DISABLED_QueryDevId_NotReady_ThenSuccessSame — getQueryDeviceIdentification retry loop
DISABLED_QueryDevId_NotReady_AllRetriesExhaustedSame
DISABLED_QueryDevId_NotReady_TransportFailDuringRetrySame
DISABLED_QueryDevId_NotReady_NonRetryableCcDuringRetrySame
DISABLED_QueryDevId_NotReady_SingleRetry_SuccessSame

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

TestWhat fails
DISABLED_GetDeviceModeSettingsV2OneShotGpuPowerValgrind invalid write — buffer allocation off-by-one
DISABLED_GetDeviceModeSettingsV2PersistentGpuPowerSame
DISABLED_GetDeviceModeSettingsV2OneShotCpuPowerSame
DISABLED_GetDeviceModeSettingsV2PersistentCpuPowerSame
DISABLED_GetDeviceModeSettingsV2DefaultIndexSame
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

TestWhat fails
DISABLED_DumpNsmDeviceInfo_DoesNotCrashdumpNsmDeviceInfo() throws std::runtime_error("MctpDiscovery instance is not initialized yet")
DISABLED_DumpNsmDeviceInfo_WithEventSubscriptionStatusSame
DISABLED_DumpNsmDeviceInfo_LastEventRequestAndResponsePresentSame

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).