feat: add fault injection tests and support - #914
niteshpurohit wants to merge 3 commits into
Conversation
812df6f to
4c5788d
Compare
4c5788d to
6ff0269
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Four moderate findings remain, including incomplete mapping support, missing descriptor-close coverage, and a CMake include-interface issue.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds test-only fault-injection support for allocation, descriptor, and I/O paths, with contextual callbacks and build integration.
Changes:
- Adds deterministic fault plans, adapters, and failure tests.
- Threads context through mapping and descriptor operations.
- Integrates new sources and tests into CMake metadata.
File summaries
| File | Summary | Final findings |
|---|---|---|
tests/support/laghu_test_faults.hpp |
Fault-injection interfaces and identifiers. | Moderate (1 vote): Mapping injection points lack an adapter and are rejected by fail_syscall_on; implement support or remove them. |
tests/support/laghu_test_faults.cpp |
Fault-injection implementations. | Moderate (2 votes): Mapping failure IDs are unusable because no mapping adapter calls FailurePlan::next; add the adapter/tests or remove the IDs. |
tests/support/fault_injection.cpp |
Allocation and I/O fault-injection tests. | Moderate (1 vote): Add coverage for the descriptor-close adapter and injected errno. |
tests/core/mapped_regions.cpp |
Context-aware mapping test callbacks. | — |
tests/core/fd_handles.cpp |
Context-aware descriptor test callbacks. | — |
src/os/private/laghu/os/internal/io_operations.hpp |
I/O operation interface. | — |
src/os/io_operations.cpp |
Default I/O implementations. | — |
src/core/private/laghu/core/internal/mapping_operations.hpp |
Mapping callback contexts. | — |
src/core/private/laghu/core/internal/descriptor_operations.hpp |
Descriptor callback context. | — |
src/core/mapped_regions.cpp |
Mapping context propagation. | — |
src/core/handles.cpp |
Descriptor context propagation. | — |
CMakeLists.txt |
Builds and registers fault-injection tests. | Moderate (1 vote): Public support headers depend on private include paths unavailable to consumers; propagate the interface paths or split the target. |
cmake/LaghuDependencyDag.cmake |
Adds the I/O source to dependency metadata. | — |
cmake/LaghuBuildIdentity.cmake |
Tracks new I/O files in build identity inputs. | — |
Review details
Suppressed comments (3)
CMakeLists.txt:66
laghu_test_faults.hppis exposed throughlaghu_test_support's PUBLIC include directory, but its core/os internal header dependencies are only on PRIVATE include paths. Consumers of the support library cannot include this new framework unless they duplicate the source-private include roots, as the fault-injection target does at lines 81-83. Propagate the required interface include paths or split the fault support into a target with a complete interface.
target_include_directories(laghu_test_support PRIVATE
"${CMAKE_SOURCE_DIR}/src/core/contract"
"${CMAKE_SOURCE_DIR}/src/core/private"
"${CMAKE_SOURCE_DIR}/src/os/private")
tests/support/fault_injection.cpp:117
- This suite only registers allocation and read/write tests; it never exercises the newly added descriptor-close adapter and plan rule. The existing fd tests use a separate callback, so regressions in
fault_closeor descriptor scheduling can pass unnoticed. Add a case that configuresdescriptor_close, adopts a handle withFaultInjectedDescriptorOperations::operations(), and asserts the injected errno.
int main() {
constexpr std::array tests{
laghu::test::TestCase{"fault_injection.allocation_rollback", check_allocation_rollback},
laghu::test::TestCase{"fault_injection.short_io_and_eintr", check_short_io_and_eintr},
};
tests/support/laghu_test_faults.hpp:17
mapping_mapandmapping_unmapare declared as injection points, but there is noFaultInjectedMappingOperationsadapter andFailurePlan::fail_syscall_onrejects both (it only accepts I/O points ordescriptor_close). Callers therefore cannot configure either mapping failure through this framework. Implement the mapping adapter/tests or remove these IDs until they are supported.
mapping_map = 3,
mapping_unmap = 4,
- Files reviewed: 14/14 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Introduced `laghu_test_fault_injection_test` to validate fault injection scenarios. - Added `laghu_test_faults.cpp` and `laghu_test_faults.hpp` to implement fault injection mechanisms for allocation and I/O operations. - Enhanced `CMakeLists.txt` to include new test files and support for fault injection. - Updated `DescriptorOperations` and `MappingOperations` to include context for better fault handling. - Created `io_operations.cpp` and `io_operations.hpp` to manage I/O operations with fault injection capabilities. - Modified existing tests to utilize the new fault injection framework, ensuring robustness against failure scenarios. closes: #78
6ff0269 to
000831b
Compare
There was a problem hiding this comment.
🟡 Changes recommended
The CMake link-target issue and unsupported mapping fault points remain unresolved.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (2)
tests/support/laghu_test_faults.cpp:125
mapping_mapandmapping_unmapare exposed as stable failure points, but this predicate rejects both and there is no mapping adapter that callsFailurePlan::next()for them. Consequentlyfail_syscall_on(FailurePoint::mapping_map, ...)andmapping_unmapalways returnfalse, so the advertised map/unmap seams cannot be injected. Add the mapping adapter and coverage, or remove these IDs until they are supported.
return (is_io_point(point) || point == FailurePoint::descriptor_close) && native_error != 0 &&
set(point, nth_call, FailureAction{FailureActionKind::errno_failure, native_error, 0});
tests/support/laghu_test_faults.hpp:17
- These mapping failure points are advertised but cannot currently be injected:
fail_syscall_onrejects both values, and noFaultInjectedMappingOperationswrapper callsFailurePlan::nextfor them. A plan configured formapping_mapormapping_unmaptherefore cannot trigger the corresponding syscall failure, so either wire these points throughMappingOperationsor remove the IDs until they are supported.
mapping_map = 3,
mapping_unmap = 4,
- Files reviewed: 14/14 changed files
- Comments generated: 2
- Review effort level: Lite
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved correctness and test-safety issues remain in the fault-injection implementation and tests.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (3)
Previously missed (1) — in code that hasn't changed since the last review.
tests/support/fault_injection.cpp:163
- The short-I/O behavior of
fault_readis not exercised here: this test covers a short write and an interrupted read, but never configuresshort_io_on(os_read, ...). A regression in the read-side count clamping could therefore pass while the advertised read short-I/O seam is broken; add a read case that verifies the returned count and bytes.
tests/support/fault_injection.cpp:173
- This blocking read happens before checking
partial; if the injected write returns an error or fewer than two bytes, the pipe's write end remains open and the test can hang indefinitely instead of reporting a failure. Guard the read on the expected successful count (or make the pipe nonblocking) so fault regressions fail promptly.
const ssize_t read_count = ::read(pipe_descriptors[0], received.data(), received.size());
tests/support/laghu_test_faults.cpp:237
- When the wrapped source has
release == nullptr, this always suppliesfault_releaseas a non-nullBufferBlockSource::Release, soBoundedBufferaccepts the source, can acquire a block, and then silently drops it becausefault_releasedoes nothing. Preserve the invalid-source signal by returning a null release callback when the underlying release callback is absent, soBoundedBufferrejects it before allocating.
laghu::core::BufferBlockSource FaultInjectedBufferSource::block_source() noexcept {
return laghu::core::BufferBlockSource{this, fault_acquire, fault_release};
}
- Files reviewed: 14/14 changed files
- Comments generated: 1
- Review effort level: Lite
laghu_test_fault_injection_testto validate fault injection scenarios.laghu_test_faults.cppandlaghu_test_faults.hppto implement fault injection mechanisms for allocation and I/O operations.CMakeLists.txtto include new test files and support for fault injection.DescriptorOperationsandMappingOperationsto include context for better fault handling.io_operations.cppandio_operations.hppto manage I/O operations with fault injection capabilities.closes: #78