Skip to content

test(buffer_pool): add 10 new unit tests#35

Merged
poyrazK merged 3 commits intomainfrom
feat/buffer-pool-tests
Apr 15, 2026
Merged

test(buffer_pool): add 10 new unit tests#35
poyrazK merged 3 commits intomainfrom
feat/buffer-pool-tests

Conversation

@poyrazK
Copy link
Copy Markdown
Owner

@poyrazK poyrazK commented Apr 15, 2026

Summary

Add 10 new unit tests for BufferPoolManager to tests/buffer_pool_tests.cpp.

New Tests

  1. PageDataPersistence - verify data persistence via explicit flush
  2. PageContentModification - verify writes through get_data() persist
  3. PageSizeConstant - verify PAGE_SIZE == 4096
  4. FetchPageById - verify fetch_page_by_id with precomputed file_id
  5. UnpinPageById - verify unpin_page_by_id with precomputed file_id
  6. UnpinDirtyRemainsDirty - verify dirty flag not cleared by unpin with is_dirty=false
  7. GetFileIdCaching - verify consistent file_id per filename
  8. MultipleFiles - verify pages from multiple files simultaneously
  9. DirtyPageEvictionFlushes - verify dirty pages flushed during eviction
  10. PoolExhaustion - verify new_page returns nullptr when pool exhausted

Test plan

  • Build passes
  • All 14 tests pass (4 existing + 10 new)

Summary by CodeRabbit

  • Tests

    • Expanded test suite with comprehensive coverage for page persistence workflows, file caching consistency, multi-file isolation scenarios, dirty-flag semantics, and resource pool exhaustion handling.
  • Refactor

    • Improved test infrastructure code organization and formatting.

- PageDataPersistence: verify data persistence via explicit flush
- PageContentModification: verify writes through get_data() persist
- PageSizeConstant: verify PAGE_SIZE == 4096
- FetchPageById: verify fetch_page_by_id with precomputed file_id
- UnpinPageById: verify unpin_page_by_id with precomputed file_id
- UnpinDirtyRemainsDirty: verify dirty flag not cleared by unpin with is_dirty=false
- GetFileIdCaching: verify consistent file_id per filename
- MultipleFiles: verify pages from multiple files simultaneously
- DirtyPageEvictionFlushes: verify dirty pages flushed during eviction
- PoolExhaustion: verify new_page returns nullptr when pool exhausted
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 15, 2026

Warning

Rate limit exceeded

@poyrazK has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 17 minutes and 45 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 17 minutes and 45 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f5537736-5e98-4b9a-8312-ab6552e26594

📥 Commits

Reviewing files that changed from the base of the PR and between a511731 and c25544a.

📒 Files selected for processing (1)
  • tests/buffer_pool_tests.cpp
📝 Walkthrough

Walkthrough

The PR enhances test coverage for the buffer pool manager with a comprehensive test suite covering page persistence, in-memory operations, eviction behavior, and pool exhaustion scenarios, while applying minor formatting updates to existing BTree index tests.

Changes

Cohort / File(s) Summary
BTree Index Test Formatting
tests/btree_index_tests.cpp
Reordered include directives and reformatted BufferPoolManager construction in SetUp() method; no functional logic changes.
Buffer Pool Test Suite
tests/buffer_pool_tests.cpp
Clarified assertions in edge-case tests and added extensive new test coverage for page persistence (write-unpin-fetch workflows), in-memory correctness, PAGE_SIZE validation, fetch/unpin transitions, dirty-flag semantics, file ID consistency, multi-file isolation, eviction flush behavior, and pool exhaustion scenarios.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Poem

🐰 With whiskers twitched and tests held tight,
I craft new cases, day and night,
Each buffer page, each pin and flush,
No race condition gets a hush!
The pool now dances, clean and bright.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding 10 new unit tests for the buffer pool manager.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/buffer-pool-tests

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
tests/buffer_pool_tests.cpp (1)

420-449: Cleanup unpins should assert expected IDs after retry allocation.

Line 446 attempts to unpin id1 a second time; after retry allocation, that can be stale and silently ignored.

♻️ Small cleanup improvement
-    bpm.unpin_page(file, id1, false);
+    ASSERT_TRUE(bpm.unpin_page(file, id1, false));
@@
-    bpm.unpin_page(file, id1, false);
-    bpm.unpin_page(file, id2, false);
-    bpm.unpin_page(file, id3, false);
+    ASSERT_TRUE(bpm.unpin_page(file, id2, false));
+    ASSERT_TRUE(bpm.unpin_page(file, id3, false));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/buffer_pool_tests.cpp` around lines 420 - 449, The test double-unpins a
stale id (id1) after retry allocation; change the cleanup to assert and unpin
the actual ids returned by BufferPoolManager::new_page rather than reusing id1:
after allocating p3_retry via bpm.new_page(file, &id3) assert id3 or the
returned Page* matches expected (e.g., EXPECT_NE(p3_retry, nullptr)) and then
call bpm.unpin_page(file, id3, false) for the newly allocated page, keeping
bpm.unpin_page(file, id2, false) and bpm.unpin_page(file, id1, false) only once
each to avoid silently ignored/stale unpins.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/buffer_pool_tests.cpp`:
- Around line 213-234: The test currently only verifies in-memory writes by
reading the same pointer from p1; instead, after writing to p1->get_data() and
unpinning it with BufferPoolManager::unpin_page(file, page_id, true), re-open
the page via BufferPoolManager::fetch_page(file, page_id) (or create a new
BufferPoolManager instance to force disk reload) and compare the fetched Page's
get_data() bytes against the expected pattern, then unpin the fetched page; use
StorageManager and BufferPoolManager methods (new_page, unpin_page, fetch_page)
and ensure you ASSERT/EXPECT non-null pointers before comparing and unpin the
fetched page after verification.
- Around line 387-413: The test BufferPoolTests::DirtyPageEvictionFlushes
currently never verifies that dirty pages were flushed to disk; after eviction
(after allocating p3 and unpinning id3) reopen or create a new
BufferPoolManager/StorageManager instance (or call bpm.fetch_page) to read pages
id1 and id2 back and assert their contents match the patterns written (0xCC for
id1 and 0xDD for id2) using p->get_data(); use
BufferPoolManager::new_page/fetch_page and unpin_page to locate pages and add
assertions that the persisted bytes equal the expected values so the test fails
if dirty-page eviction did not flush to disk.
- Around line 171-208: The test may pass without hitting disk because the page
remains resident in the 2-frame BufferPoolManager; ensure a disk read by
evicting the original frame before calling fetch_page: after flush_page(file,
page_id) and unpin_page(file, page_id, false), allocate and unpin additional
pages via BufferPoolManager::new_page/unpin_page (or reduce the pool and
recreate BufferPoolManager/StorageManager) so that the frame for page_id is
evicted, then call fetch_page(file, page_id) and verify contents; reference
functions: TEST(BufferPoolTests, PageDataPersistence),
BufferPoolManager::new_page, BufferPoolManager::unpin_page,
BufferPoolManager::flush_page, BufferPoolManager::fetch_page.

---

Nitpick comments:
In `@tests/buffer_pool_tests.cpp`:
- Around line 420-449: The test double-unpins a stale id (id1) after retry
allocation; change the cleanup to assert and unpin the actual ids returned by
BufferPoolManager::new_page rather than reusing id1: after allocating p3_retry
via bpm.new_page(file, &id3) assert id3 or the returned Page* matches expected
(e.g., EXPECT_NE(p3_retry, nullptr)) and then call bpm.unpin_page(file, id3,
false) for the newly allocated page, keeping bpm.unpin_page(file, id2, false)
and bpm.unpin_page(file, id1, false) only once each to avoid silently
ignored/stale unpins.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 886a9b1e-8ece-434b-a0b7-5e72e82e35a6

📥 Commits

Reviewing files that changed from the base of the PR and between adf851e and a511731.

📒 Files selected for processing (2)
  • tests/btree_index_tests.cpp
  • tests/buffer_pool_tests.cpp

Comment thread tests/buffer_pool_tests.cpp
Comment thread tests/buffer_pool_tests.cpp
Comment on lines +387 to +413
TEST(BufferPoolTests, DirtyPageEvictionFlushes) {
static_cast<void>(std::remove("./test_data/bpm_flush.db"));
StorageManager disk_manager("./test_data");
BufferPoolManager bpm(2, disk_manager);
const std::string file = "bpm_flush.db";

// Create two dirty pages
uint32_t id1 = 0;
uint32_t id2 = 1;
Page* const p1 = bpm.new_page(file, &id1);
Page* const p2 = bpm.new_page(file, &id2);

ASSERT_NE(p1, nullptr);
ASSERT_NE(p2, nullptr);

std::memset(p1->get_data(), 0xCC, 32);
bpm.unpin_page(file, id1, true);

std::memset(p2->get_data(), 0xDD, 32);
bpm.unpin_page(file, id2, true);

// Allocate third page to trigger eviction
uint32_t id3 = 2;
Page* const p3 = bpm.new_page(file, &id3);
ASSERT_NE(p3, nullptr);
bpm.unpin_page(file, id3, false);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

DirtyPageEvictionFlushes does not assert post-eviction persisted content.

This test currently triggers eviction but never verifies that dirty data is recoverable afterward.

🔧 Proposed post-eviction verification
     // Allocate third page to trigger eviction
     uint32_t id3 = 2;
     Page* const p3 = bpm.new_page(file, &id3);
     ASSERT_NE(p3, nullptr);
-    bpm.unpin_page(file, id3, false);
+    ASSERT_TRUE(bpm.unpin_page(file, id3, false));
+
+    Page* const p1_fetch = bpm.fetch_page(file, id1);
+    Page* const p2_fetch = bpm.fetch_page(file, id2);
+    ASSERT_NE(p1_fetch, nullptr);
+    ASSERT_NE(p2_fetch, nullptr);
+    EXPECT_EQ(static_cast<unsigned char>(p1_fetch->get_data()[0]), 0xCC);
+    EXPECT_EQ(static_cast<unsigned char>(p2_fetch->get_data()[0]), 0xDD);
+    ASSERT_TRUE(bpm.unpin_page(file, id1, false));
+    ASSERT_TRUE(bpm.unpin_page(file, id2, false));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/buffer_pool_tests.cpp` around lines 387 - 413, The test
BufferPoolTests::DirtyPageEvictionFlushes currently never verifies that dirty
pages were flushed to disk; after eviction (after allocating p3 and unpinning
id3) reopen or create a new BufferPoolManager/StorageManager instance (or call
bpm.fetch_page) to read pages id1 and id2 back and assert their contents match
the patterns written (0xCC for id1 and 0xDD for id2) using p->get_data(); use
BufferPoolManager::new_page/fetch_page and unpin_page to locate pages and add
assertions that the persisted bytes equal the expected values so the test fails
if dirty-page eviction did not flush to disk.

- PageDataPersistence: use explicit eviction with new_page to force disk reload
- DirtyPageEvictionFlushes: simplified to test via explicit flush_page
- PoolExhaustion: fixed cleanup unpins to use correct page ids
- PageContentModification: verify in-memory writes persist
- All tests now properly verify data persistence and cleanup
@poyrazK poyrazK merged commit 692f068 into main Apr 15, 2026
9 checks passed
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.

1 participant