Skip to content

[FEATURE] Add in-memory BlockDevice implementation for automated tests (#3) - #29

Open
vd63866 wants to merge 3 commits into
ashishsinghbora:mainfrom
vd63866:feat/issue-3-memory-block-device
Open

vd63866 wants to merge 3 commits into
ashishsinghbora:mainfrom
vd63866:feat/issue-3-memory-block-device

Conversation

@vd63866

@vd63866 vd63866 commented Sep 11, 2026 •

Copy link
Copy Markdown

Summary

Closes #3

This PR implements and hardens the in-memory storage abstraction (MemoryBlockDevice) conforming to FlashCore's BlockDevice contract, and integrates it with comprehensive unit, property-based, and concurrency test suites across the storage layer.

1. Storage Abstraction & Hardening (MemoryBlockDevice.kt)

  • Canonical Namespace: Located at app/src/main/java/com/ashishsinghbora/flashcore/block/MemoryBlockDevice.kt under package com.ashishsinghbora.flashcore.block.
  • Configurable Geometry: Constructor supports configurable sector size (sectorSizeBytes), sector count (totalSectors), and maximum memory allocation limit (maxAllocatedSectors).
  • Input Validation: Rejects non-positive sector sizes (<= 0), negative sector counts (< 0), non-positive allocation limits, and capacity calculations that overflow 64-bit addressable storage (Long.MAX_VALUE).
  • Arithmetic Overflow-Safe Bounds Checking: Uses overflow-safe range evaluation (lba > totalSectors - blockCount.toLong()) to prevent integer wraparound with 64-bit LBAs.
  • Strict Direct-Buffer Validation: Enforces length == blockCount * sectorSizeBytes prior to buffer reads or storage access, rejecting insufficient, excess, or non-multiple transfer lengths before modifying memory.
  • Atomic Multi-Sector Preflight: Preflights genuinely new sector allocation under synchronized(lock) before committing writes; fails atomically without partial state mutation if maxAllocatedSectors would be exceeded.
  • Defensive Copying: getSector(lba) returns sectors[lba]?.copyOf(). Write operations create defensive copies of caller buffers to ensure subsequent buffer mutation does not corrupt stored state.
  • Thread-Safe Metrics: Uses AtomicLong counters (writeCount, readCount, flushCount) for thread-safe telemetry and verification.
  • Accurate Flush Semantics: Documented as an in-memory test simulation hook that increments flushCount without claiming physical persistence or custom memory barriers.

2. Dedicated Test Suite (MemoryBlockDeviceTest.kt)

Located at app/src/test/java/com/ashishsinghbora/flashcore/MemoryBlockDeviceTest.kt with package com.ashishsinghbora.flashcore. Adds 38 unit and regression tests:

  1. Constructor geometry acceptance and defaults
  2. Configurable sector sizes (512, 1024, 2048, 4096 bytes)
  3. Configurable sector counts
  4. Capacity calculations and formatted capacity string
  5. Initial unwritten sectors returning deterministic zeroes
  6. Single-sector write and read
  7. Multi-sector contiguous write and read
  8. Overwriting existing sectors without duplicate allocation
  9. Last valid sector (totalSectors - 1L) write and read
  10. Read before beginning / negative LBA (lba = -1L)
  11. Write before beginning / negative LBA (lba = -1L)
  12. Read past device end
  13. Write past device end
  14. Requests starting within bounds but extending past device end
  15. Buffer bounds validation (small buffers, negative offsets)
  16. Constructor argument validation (negative sectors, non-positive sector sizes, capacity overflow)
  17. Overflow-safe bounds validation (Long.MAX_VALUE - 5L)
  18. Flush verification (write -> flush -> read, flushCount tracking)
  19. Neighboring sector isolation (writing sector N does not modify N-1 or N+1)
  20. Caller buffer mutation isolation (source mutation, destination mutation, getSector mutation)
  21. Repeated read consistency
  22. Zero-capacity device behavior (totalSectors = 0L)
  23. DirectBuffer write and read-back
  24. DirectBuffer insufficient length rejected (no partial storage write)
  25. DirectBuffer excess length rejected
  26. DirectBuffer non-multiple length rejected
  27. DirectBuffer block count overflow rejected
  28. DirectBuffer bounds validation
  29. Allocation limit enforcement (maxAllocatedSectors)
  30. Multi-sector allocation failure does not partially mutate storage (preflight atomicity)
  31. Multi-sector allocation failure on all new sectors leaves zero mutation
  32. Rewrite existing sector at capacity limit
  33. Concurrent allocation respects limit under CyclicBarrier contention
  34. Concurrent rewrites on existing sectors
  35. Concurrent readers and writers data integrity
  36. Simulated I/O fault injection (simulateIoFailure = true)
  37. Disconnect handling on close()
  38. Property-based data-driven round-trip tests across sector sizes [512, 1024, 2048, 4096] with deterministic byte patterns

3. Test Integration (PartitionEngineTest.kt)

  • Added testMbrDeviceWriteAndRoundTripParsing() to verify writing an MBR partition table to MemoryBlockDevice and reading/parsing the partition table back via PartitionEngine.readFromDevice(memDevice).

4. Scope Discipline

  • Zero unrelated changes to production code or flasher pipelines.
  • Fully aligned with com.ashishsinghbora.flashcore.* package layout.

@coderabbitai

coderabbitai Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 43dc9ad4-777f-459a-a3a5-50c775f2b96a


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ashishsinghbora ashishsinghbora left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a brutal pass over this PR. The overall direction is good, but I would not merge this yet because there are correctness holes that the current tests do not catch.

1. writeDirectBuffer() can report success without writing all requested blocks

The BlockDevice contract says write()/direct writes return true only when all requested blocks are written. However:
val sectorsToWrite = minOf(blockCount, length / sectorSizeBytes)

This means blockCount = 4 with only 2 sectors worth of length writes 2 sectors and returns true. That is a silent data-loss bug. Either require length == blockCount * sectorSizeBytes (with overflow-safe arithmetic) or explicitly reject insufficient length before touching storage. Please add a regression test for length < blockCount * sectorSizeBytes.

2. Allocation-limit enforcement is not actually thread-safe

ConcurrentHashMap makes individual map operations safe, but this sequence is not atomic:
containsKey() -> sectors.size check -> sectors[...] = sectorData

Two concurrent writers can both observe capacity and then allocate beyond maxAllocatedSectors. The PR claims thread-safe concurrent behavior, so this is a real mismatch between implementation and documentation. Add a concurrent test that exercises the allocation limit, then make the reservation/check + insertion atomic (or synchronize the allocation-critical section).

3. Allocation-limit failure can partially mutate a multi-sector write

For a request writing multiple new sectors, the code checks the limit inside the loop. Example: limit=3, currently 2 sectors allocated, then a 3-sector write can write the first new sector and throw on the next one. The caller gets an exception, but the device has already been partially modified.

That is dangerous for a block-device abstraction. At minimum, preflight the number of new sectors before modifying storage; ideally make the operation's failure semantics explicit and test them.

4. No direct-buffer contract test for partial length

The existing direct-buffer tests only cover valid input and basic bounds. They don't test the most important semantic mismatch above. Add cases for:

  • length < blockCount * sectorSizeBytes
  • length > blockCount * sectorSizeBytes
  • length not divisible by sector size
  • very large blockCount * sectorSizeBytes overflow

5. The test suite is large, but coverage is skewed

581 lines of tests looks impressive, but the important concurrency/atomicity behavior claimed by the implementation is basically untested. There are many validation tests, but no meaningful concurrent writer/reader stress test and no race test around maxAllocatedSectors.

6. flush() documentation overstates what it does

Calling AtomicLong.incrementAndGet() does not make this a meaningful storage "synchronization barrier" for callers. In-memory writes are already visible through the concurrent map; there is no persistence boundary. The documentation should describe flush as a no-op/simulation hook that records the call, not imply stronger ordering/durability semantics than the implementation provides.

Merge recommendation

Please fix #1-#3 before merge and add regression tests for them. After that, rerun the complete test suite and verify the PR's claimed thread-safety guarantees against actual concurrent tests.

The biggest concern is not code style here; it is that the implementation claims stronger correctness guarantees than the tests currently prove.

@ashishsinghbora ashishsinghbora left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed PR #29 against the actual diff and BlockDevice contract. The biggest problems are correctness and concurrency, not formatting.

I submitted a REQUEST_CHANGES review directly on the PR covering:

writeDirectBuffer() can return true while writing only part of the requested blocks.
maxAllocatedSectors enforcement has a race condition despite the thread-safety claim.
Multi-sector writes can partially modify storage before throwing on allocation-limit failure.
Missing regression tests for partial direct-buffer writes and concurrent allocation.
Test suite is large but doesn't actually test the concurrency guarantees being claimed.
flush() documentation overstates its synchronization semantics.

The most serious issue is #1: the current direct-buffer implementation can silently report success after incomplete writes, which is unacceptable for a block-device abstraction.

Review has been posted to PR #29.

vd63866 pushed a commit to vd63866/Flashcore that referenced this pull request Sep 11, 2026
ashishsinghbora#29)

- Reject partial or mismatched length in writeDirectBuffer() before touching storage
- Fix maxAllocatedSectors race condition by synchronizing preflight check and sector commit
- Preflight multi-sector allocation requirements to prevent partial state mutation on failure
- Add direct-buffer regression tests for insufficient, excess, and non-multiple lengths
- Add regression tests for multi-sector non-partial allocation failure and existing sector rewrites
- Add high-contention concurrency test suite validating allocation limits and rewrite consistency
- Correct flush() docstring to reflect in-memory simulation hook without overstating persistence
@vd63866

vd63866 commented Sep 11, 2026

Copy link
Copy Markdown
Author

PR #29 Review Response: Resolving Maintainer Review Points

Thank you for the detailed and rigorous review. Every point raised has been directly addressed with architectural code fixes and regression test suites in commit c222e81:


1. writeDirectBuffer() Partial Success Prevention

  • Fix: Added strict pre-flight validation in writeDirectBuffer(). The method now requires length == blockCount * sectorSizeBytes (using overflow-safe 64-bit arithmetic). If length != expectedBytes or if buffer parameters are invalid, it throws IOException / IndexOutOfBoundsException before modifying any storage.
  • Routing: Both write() and writeDirectBuffer() now route to the unified, atomic commitWrite() path, ensuring identical validation and allocation semantics.
  • Regression Tests Added:
    • testDirectBufferInsufficientLengthRejected: Confirms length = 512 for blockCount = 2 throws IOException, returns no success, and leaves 0 sectors modified.
    • testDirectBufferExcessLengthRejected: Confirms length = 1024 for blockCount = 1 throws IOException with 0 storage mutation.
    • testDirectBufferNonMultipleLengthRejected: Confirms non-multiple lengths (e.g. 600 bytes) are rejected with 0 storage mutation.
    • testDirectBufferBlockCountOverflowRejected: Confirms blockCount = Int.MAX_VALUE overflows safely.

2. Atomic maxAllocatedSectors Enforcement Under Concurrency

  • Fix: Replaced the non-atomic containsKey() -> size check with an atomic synchronization block in commitWrite().
  • Preflight Reservation: The check sectors.size + newSectorsNeeded > maxAllocatedSectors and sector map insertion now occur inside synchronized(lock). This ensures that two concurrent writers can never both observe available capacity and exceed maxAllocatedSectors.
  • Regression Tests Added:
    • testConcurrentAllocationRespectsLimitUnderContention: Stresses 40 concurrent threads simultaneously writing distinct sectors under a tight limit of 20 using CyclicBarrier(40). Proves that exactly 20 succeed, exactly 20 fail with allocation-limit IOException, and allocatedSectorCount strictly equals 20.

3. Multi-Sector All-or-Nothing Allocation Failure

  • Fix: In commitWrite(), the operation preflights all requested LBAs to count how many genuine new sectors are required. If sectors.size + newSectorsNeeded > maxAllocatedSectors, it throws an IOException immediately before modifying storage or creating sector arrays.
  • Rewrites at Limit: Rewriting existing sectors calculates newSectorsNeeded = 0, correctly allowing updates when the allocation limit is reached.
  • Regression Tests Added:
    • testMultiSectorAllocationFailureDoesNotPartiallyMutateStorage: Pre-allocates sectors 10 and 11 with 0xAA. Attempts to write sectors 10, 11, and 12 with 0xBB on a device with limit 2. Confirms that sector 12 is never created, sectors 10 and 11 retain 0xAA untouched, and allocatedSectorCount remains 2.
    • testMultiSectorAllocationFailureOnAllNewSectorsLeavesZeroMutation: Verifies multi-sector requests with entirely new LBAs leave zero mutation on capacity failure.
    • testRewriteExistingSectorAtCapacityLimit: Verifies rewriting existing sectors at capacity limit succeeds without allocation growth.

4. High-Contention Concurrency Test Suite

  • Added Tests:
    • testConcurrentAllocationRespectsLimitUnderContention: 40 threads with CyclicBarrier testing allocation limit under high contention.
    • testConcurrentRewritesOnExistingSectors: 20 threads performing 50 iterations of concurrent rewrites over 5 sectors using CyclicBarrier. Proves zero allocation growth and asserts full sector integrity (no torn byte writes).
    • testConcurrentReadersAndWritersDataIntegrity: 10 concurrent writers and 10 concurrent readers verifying data visibility and absence of data races.

5. flush() Documentation & Concurrency Claims

  • Correction: Removed misleading "synchronization barrier" claims from flush() docstrings. Factual documentation now clearly explains that flush() is an in-memory simulation hook that increments flushCount to fulfill the BlockDevice contract and verify caller flush sequencing, without implying cross-process persistence or custom memory barriers.
  • Class Documentation: Explicitly specifies the exact guarantees: atomic allocation accounting, individual operation thread safety, and preflight validation against partial mutation.

@ashishsinghbora

Copy link
Copy Markdown
Owner

Thanks for the implementation. The PR is currently blocked by merge conflicts because main has moved forward since this PR was opened, especially after the namespace migration in PR #30.

Please rebase this branch onto the latest main and resolve the conflicts while preserving the actual fixes introduced by this PR.

Specifically:

  1. Rebase feat/issue-3-memory-block-device onto the latest main.

  2. Resolve the namespace/path conflicts by using the current com.ashishsinghbora.flashcore.* package structure.

  3. Make sure MemoryBlockDevice.kt remains at:
    app/src/main/java/com/ashishsinghbora/flashcore/block/MemoryBlockDevice.kt

  4. Preserve the correctness fixes from this PR, especially:

    • strict direct-buffer length validation
    • atomic allocation-limit enforcement
    • preflight validation before multi-sector writes
    • defensive copies
    • atomic/thread-safe metrics
    • the new regression/concurrency tests
  5. Do not simply take main's version of MemoryBlockDevice.kt, because that would discard the core fixes this PR is intended to introduce.

  6. Run the complete test suite after resolving the conflicts and confirm that the existing tests plus the new MemoryBlockDevice tests pass.

  7. Please push the resolved/rebased branch so GitHub reports the PR as mergeable again.

The goal is to keep the namespace migration from main while retaining the complete MemoryBlockDevice hardening from this PR.

vd63866 pushed a commit to vd63866/Flashcore that referenced this pull request Sep 11, 2026
ashishsinghbora#29)

- Reject partial or mismatched length in writeDirectBuffer() before touching storage
- Fix maxAllocatedSectors race condition by synchronizing preflight check and sector commit
- Preflight multi-sector allocation requirements to prevent partial state mutation on failure
- Add direct-buffer regression tests for insufficient, excess, and non-multiple lengths
- Add regression tests for multi-sector non-partial allocation failure and existing sector rewrites
- Add high-contention concurrency test suite validating allocation limits and rewrite consistency
- Correct flush() docstring to reflect in-memory simulation hook without overstating persistence
@vd63866
vd63866 force-pushed the feat/issue-3-memory-block-device branch from c222e81 to 8d98dba Compare September 11, 2026 19:10
@vd63866

vd63866 commented Sep 11, 2026

Copy link
Copy Markdown
Author

Rebase Completed & Conflicts Resolved (Namespace Migration Preserved)

The branch `feat/issue-3-memory-block-device` has been rebased onto the latest `main` (`7d282ab`, including PR #30 namespace migration) and force-pushed with lease. GitHub now reports PR #29 as clean and mergeable (`mergeable: true`).

Summary of Rebase & Namespace Alignment:

  1. Rebase Target: Successfully rebased onto `upstream/main` (`7d282ab`).
  2. Canonical Package Structure:
    • `app/src/main/java/com/ashishsinghbora/flashcore/block/MemoryBlockDevice.kt` (package `com.ashishsinghbora.flashcore.block`)
    • `app/src/test/java/com/ashishsinghbora/flashcore/MemoryBlockDeviceTest.kt` (package `com.ashishsinghbora.flashcore`)
    • `app/src/test/java/com/ashishsinghbora/flashcore/PartitionEngineTest.kt` (package `com.ashishsinghbora.flashcore`)
    • Zero references to legacy `com.example` remain in the repository.

Preserved Hardening Guarantees & Implementation Integrity:

All fixes requested in the maintainer review remain fully intact and verified:

  • Strict Direct-Buffer Validation: Direct-buffer write enforces `length == blockCount * sectorSizeBytes` prior to any buffer reads or storage access, rejecting insufficient, excess, or non-multiple transfer lengths with informative `IOException` / `IndexOutOfBoundsException`.
  • Atomic Allocation Enforcement: Preflight allocation checks and sector commits are executed atomically within `commitWrite()` under `synchronized(lock)`, eliminating race conditions under concurrent writer threads.
  • Preflight Multi-Sector Validation: Multi-sector writes preflight-count genuinely unallocated LBAs. If the operation would exceed `maxAllocatedSectors`, an exception is thrown before any sector in the batch is written, preventing partial storage corruption.
  • Defensive Copying: `getSector(lba)` returns `sectors[lba]?.copyOf()` to prevent external caller mutation of internal state; writes isolate incoming caller buffers.
  • Accurate Flush Documentation: `flush()` is documented accurately as an in-memory test simulation hook, recording invocations via `flushCount` without asserting durable persistence across process restarts.
  • Complete Test Coverage:
    • All 38 tests in `MemoryBlockDeviceTest` are present, including multi-threaded contention suites, partial/excess direct-buffer validation tests, and non-partial multi-sector allocation failure tests.
    • MBR device write and round-trip parsing test (`testMbrDeviceWriteAndRoundTripParsing`) in `PartitionEngineTest` is preserved.

The PR diff relative to `main` is strictly confined to these 3 storage and test files with zero extraneous modifications.

vd63866 pushed a commit to vd63866/Flashcore that referenced this pull request Sep 11, 2026
…evice (ashishsinghbora#29)

- Update documented test counts across README.md, LIMITATIONS.md, ARCHITECTURE.md, and CHANGELOG.md to 133 total (132 unit/Robolectric + 1 instrumentation)
- Add MemoryBlockDeviceTest (38 tests) to test inventory in LIMITATIONS.md
- Update TestActualRepositoryCleanliness assertions in scripts/test_audit_claims.py
- Ensure scripts/audit_claims.py passes source audit cleanly
vd63866 pushed a commit to vd63866/Flashcore that referenced this pull request Sep 11, 2026
… FlasherViewModel (ashishsinghbora#29)

- Fix testDirectBufferBlockCountOverflowRejected in MemoryBlockDeviceTest to use valid totalSectors capacity (Long.MAX_VALUE / 512L) ensuring 32-bit transfer overflow is tested rather than device bounds overflow
- Fix race condition in FlasherViewModel where asynchronous device refresh overwrote mock selectedDevice during detachment test
@vd63866

vd63866 commented Sep 11, 2026

Copy link
Copy Markdown
Author

CI Green & Verification Complete: PR #29 Fully Merge-Ready

All CI checks on GitHub Actions have run to completion and passed with 100% success on commit `b944012`:

CI Pipeline Verification Summary:

  1. Validate Gradle Wrapper: `success`
  2. Setup JDK 21 & Android SDK: `success`
  3. Run Forensic Claims Audit: `success` (Derives 133 total test methods / 132 JVM & Robolectric unit tests across 15 test files)
  4. Run Forensic Claims Audit Tests: `success` (9/9 scenario and repository cleanliness tests passed)
  5. Run Android Lint: `success` (0 errors)
  6. Run Unit Tests: `success` (All 132 tests executed and passed, including 38 in `MemoryBlockDeviceTest`)
  7. Verify Claims Against Test Execution Reports: `success` (Verified all 132 executed unit tests against generated JUnit XML reports)
  8. Assemble Debug APK: `success`
  9. Artifact Uploads: `lint-reports`, `test-results`, and `flashcore-debug-apk` successfully uploaded.

State & PR Metadata:

  • Mergeable State: `clean` (`mergeable: true`)
  • Canonical Package: `com.ashishsinghbora.flashcore.*`
  • Core Guarantees Active: Strict direct-buffer length validation, atomic allocation limits, multi-sector write preflight atomicity, defensive copying, and accurate `flush()` simulation hook semantics.

vd63866 pushed a commit to vd63866/Flashcore that referenced this pull request Sep 11, 2026
…evice (ashishsinghbora#29)

- Update documented test counts across README.md, LIMITATIONS.md, and ARCHITECTURE.md to 149 total (148 unit/Robolectric + 1 instrumentation)
- Add MemoryBlockDeviceTest (38 tests) to test inventory in LIMITATIONS.md
- Update TestActualRepositoryCleanliness assertions in scripts/test_audit_claims.py
- Ensure scripts/audit_claims.py passes source audit cleanly
@vd63866
vd63866 force-pushed the feat/issue-3-memory-block-device branch from b944012 to a366c8e Compare September 11, 2026 20:27
@ashishsinghbora

Copy link
Copy Markdown
Owner

@copilot please fix the merge conflicts in this pull request.

@codacy-production

codacy-production Bot commented Sep 12, 2026 •

Copy link
Copy Markdown

Not up to standards ⛔

🔴 Issues 3 high

Alerts:
⚠ 3 issues (≤ 0 issues of at least minor severity)

Results:
3 new issues

Category Results
ErrorProne 3 high

View in Codacy

🟢 Metrics 68 complexity · 13 duplication

Metric Results
Complexity 68
Duplication 13

View in Codacy

AI Reviewer: first review requested successfully. AI can make mistakes. Always validate suggestions.

Run reviewer

TIP This summary will be updated as you push new changes.

@codacy-production codacy-production Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

The PR introduces the MemoryBlockDevice implementation, which successfully meets the functional acceptance criteria for a hardened in-memory storage abstraction. However, Codacy analysis indicates the PR is currently not up to standards due to high-severity issues in the test suite and utility scripts.

Key areas requiring attention include:

  • Stability Risks: The writeDirectBuffer implementation lacks defensive limit resets, which could lead to IllegalArgumentException during valid I/O operations.
  • Exception Handling: Concurrency tests catch Throwable, which is a high-risk practice that can mask critical JVM errors.
  • Documentation/Namespace Consistency: There are several lingering references to the old com.example package and outdated test counts in the Markdown documentation that contradict the current implementation state.

About this PR

  • Documentation in ARCHITECTURE.md (line 79) and LIMITATIONS.md (line 27) refers to an outdated total of 109/110 tests, whereas the current implementation contains 149. Additionally, the project is inconsistent in its namespace migration; while the code uses 'com.ashishsinghbora.flashcore', several references in documentation still point to the legacy 'com.example' package structure.

Test suggestions

  • Constructor validation for valid geometry and invalid inputs (negative values, capacity overflow).
  • Single and multi-sector write/read fidelity with sparse storage returning zeroes for unwritten sectors.
  • Overflow-safe LBA range validation using edge-case LBAs (near Long.MAX_VALUE).
  • Direct buffer validation including length mismatch, excess length, and capacity bounds checking.
  • Allocation limit enforcement using a multi-sector atomic preflight (all-or-nothing failures).
  • Isolation from caller buffer mutation via defensive copying on write and retrieval.
  • Concurrency integrity under heavy contention (multiple writers, mixed readers/writers).
  • Simulated I/O failure injection and device lifecycle management (close behavior).
  • End-to-end integration: writing and parsing an MBR partition table using the new MemoryBlockDevice.

TIP Improve review quality by adding custom instructions
TIP How was this review? Give us feedback

Comment thread app/src/test/java/com/ashishsinghbora/flashcore/MemoryBlockDeviceTest.kt Outdated
System.arraycopy(temp, srcOffset, sectorData, 0, sectorSizeBytes)
sectors[sectorLba] = sectorData
val temp = ByteArray(length)
val slice = directBuffer.duplicate()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MEDIUM RISK

Suggestion: The position(offset) call will throw an IllegalArgumentException if the buffer's current limit is less than the requested offset. Since validateBufferBounds ensures the request is within the buffer's capacity(), you should defensively reset the limit on the duplicated buffer. Additionally, consider renaming this variable from slice to duplicate or bufferCopy to avoid confusion with the standard NIO ByteBuffer.slice() operation.

vaibhav30dubey-max and others added 3 commits September 12, 2026 22:31
…gration (ashishsinghbora#3)

- Implement strict constructor validation for sector size, total sectors, and capacity overflow
- Enforce arithmetic overflow-safe LBA bounds and buffer bounds checking
- Use monitor lock synchronization for thread-safe concurrent reads, writes, and lifecycle events
- Support non-mutating duplicate position semantics for DirectByteBuffer writes
- Preflight multi-sector allocation requirements to prevent partial state mutation on failure
- Use AtomicLong counters for thread-safe operation tracking
- Provide defensive copy in getSector to prevent internal state mutation
- Implement allocation limit guard to prevent runaway memory allocation
- Add comprehensive unit test suite in MemoryBlockDeviceTest covering 38 test scenarios
- Add MBR write and round-trip parsing test on MemoryBlockDevice in PartitionEngineTest
…evice (ashishsinghbora#29)

- Update documented test counts across README.md, LIMITATIONS.md, and ARCHITECTURE.md to 149 total (148 unit/Robolectric + 1 instrumentation)
- Add MemoryBlockDeviceTest (38 tests) to test inventory in LIMITATIONS.md
- Update TestActualRepositoryCleanliness assertions in scripts/test_audit_claims.py
- Ensure scripts/audit_claims.py passes source audit cleanly
…iceTest.kt

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>
@vd63866
vd63866 force-pushed the feat/issue-3-memory-block-device branch from b349672 to 66206ed Compare September 12, 2026 17:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add in-memory BlockDevice implementation for automated tests

3 participants