@@ -233,4 +233,165 @@ TEST_F(StorageManagerTests, WriteAndReadDifferentPages) {
233233 EXPECT_EQ (std::memcmp (page5, read_buf, StorageManager::PAGE_SIZE), 0 );
234234}
235235
236+ // ============= New Tests =============
237+
238+ /* *
239+ * @brief Verifies PAGE_SIZE constant value
240+ */
241+ TEST_F (StorageManagerTests, PageSizeConstant) {
242+ EXPECT_EQ (StorageManager::PAGE_SIZE, 4096U );
243+ }
244+
245+ /* *
246+ * @brief Verifies read_page auto-opens file if not already open
247+ */
248+ TEST_F (StorageManagerTests, ReadNonOpenedFileAutoOpens) {
249+ const std::string filename = " non_opened_read.db" ;
250+ cleanup_file (" ./test_data" , filename);
251+
252+ // StorageManager auto-opens files, so read should succeed
253+ char buf[StorageManager::PAGE_SIZE];
254+ EXPECT_TRUE (sm_->read_page (filename, 0 , buf));
255+ }
256+
257+ /* *
258+ * @brief Verifies write_page auto-opens file if not already open
259+ */
260+ TEST_F (StorageManagerTests, WriteNonOpenedFileAutoOpens) {
261+ const std::string filename = " non_opened_write.db" ;
262+ cleanup_file (" ./test_data" , filename);
263+
264+ char buf[StorageManager::PAGE_SIZE];
265+ std::memset (buf, 0xAB , StorageManager::PAGE_SIZE);
266+ // StorageManager auto-opens files, so write should succeed
267+ EXPECT_TRUE (sm_->write_page (filename, 0 , buf));
268+ }
269+
270+ /* *
271+ * @brief Verifies data persists across file open/close cycle
272+ */
273+ TEST_F (StorageManagerTests, DataPersistenceAcrossOpenClose) {
274+ const std::string filename = " persist_test.db" ;
275+ cleanup_file (" ./test_data" , filename);
276+
277+ // Write data to page 0
278+ ASSERT_TRUE (sm_->open_file (filename));
279+ char write_buf[StorageManager::PAGE_SIZE];
280+ for (int i = 0 ; i < StorageManager::PAGE_SIZE; ++i) {
281+ write_buf[i] = static_cast <char >(i & 0xFF );
282+ }
283+ ASSERT_TRUE (sm_->write_page (filename, 0 , write_buf));
284+ ASSERT_TRUE (sm_->close_file (filename));
285+
286+ // Reopen and read - data should persist
287+ ASSERT_TRUE (sm_->open_file (filename));
288+ char read_buf[StorageManager::PAGE_SIZE];
289+ ASSERT_TRUE (sm_->read_page (filename, 0 , read_buf));
290+ EXPECT_EQ (std::memcmp (write_buf, read_buf, StorageManager::PAGE_SIZE), 0 );
291+ ASSERT_TRUE (sm_->close_file (filename));
292+ }
293+
294+ /* *
295+ * @brief Verifies stats track bytes_read and bytes_written accurately
296+ */
297+ TEST_F (StorageManagerTests, StatsBytesAccurate) {
298+ const std::string filename = " stats_bytes_test.db" ;
299+ cleanup_file (" ./test_data" , filename);
300+
301+ const auto & stats = sm_->get_stats ();
302+ auto initial_bytes_read = stats.bytes_read .load ();
303+ auto initial_bytes_written = stats.bytes_written .load ();
304+
305+ ASSERT_TRUE (sm_->open_file (filename));
306+
307+ char buf[StorageManager::PAGE_SIZE];
308+ std::memset (buf, 0xAB , StorageManager::PAGE_SIZE);
309+ ASSERT_TRUE (sm_->write_page (filename, 0 , buf));
310+ ASSERT_TRUE (sm_->read_page (filename, 0 , buf));
311+
312+ EXPECT_EQ (stats.bytes_written .load (), initial_bytes_written + StorageManager::PAGE_SIZE);
313+ EXPECT_EQ (stats.bytes_read .load (), initial_bytes_read + StorageManager::PAGE_SIZE);
314+ }
315+
316+ /* *
317+ * @brief Verifies data isolation between multiple files
318+ */
319+ TEST_F (StorageManagerTests, MultipleFilesDataIsolation) {
320+ const std::string file1 = " isolate1.db" ;
321+ const std::string file2 = " isolate2.db" ;
322+ cleanup_file (" ./test_data" , file1);
323+ cleanup_file (" ./test_data" , file2);
324+
325+ ASSERT_TRUE (sm_->open_file (file1));
326+ ASSERT_TRUE (sm_->open_file (file2));
327+
328+ char buf1[StorageManager::PAGE_SIZE];
329+ char buf2[StorageManager::PAGE_SIZE];
330+ char read_buf[StorageManager::PAGE_SIZE];
331+
332+ std::memset (buf1, 0x11 , StorageManager::PAGE_SIZE);
333+ std::memset (buf2, 0x22 , StorageManager::PAGE_SIZE);
334+
335+ ASSERT_TRUE (sm_->write_page (file1, 0 , buf1));
336+ ASSERT_TRUE (sm_->write_page (file2, 0 , buf2));
337+
338+ // Read from file1 - should have file1's data
339+ ASSERT_TRUE (sm_->read_page (file1, 0 , read_buf));
340+ EXPECT_EQ (std::memcmp (buf1, read_buf, StorageManager::PAGE_SIZE), 0 );
341+
342+ // Read from file2 - should have file2's data
343+ ASSERT_TRUE (sm_->read_page (file2, 0 , read_buf));
344+ EXPECT_EQ (std::memcmp (buf2, read_buf, StorageManager::PAGE_SIZE), 0 );
345+ }
346+
347+ /* *
348+ * @brief Verifies deallocate_page stub doesn't crash
349+ */
350+ TEST_F (StorageManagerTests, DeallocatePageStub) {
351+ const std::string filename = " dealloc_test.db" ;
352+ cleanup_file (" ./test_data" , filename);
353+
354+ // deallocate_page is a stub but shouldn't crash
355+ EXPECT_NO_THROW (StorageManager::deallocate_page (filename, 0 ));
356+ }
357+
358+ /* *
359+ * @brief Verifies complex byte patterns persist correctly
360+ */
361+ TEST_F (StorageManagerTests, ReadAfterWriteDifferentPatterns) {
362+ const std::string filename = " patterns_test.db" ;
363+ cleanup_file (" ./test_data" , filename);
364+
365+ ASSERT_TRUE (sm_->open_file (filename));
366+
367+ // Write alternating pattern
368+ char page[StorageManager::PAGE_SIZE];
369+ for (size_t i = 0 ; i < StorageManager::PAGE_SIZE; ++i) {
370+ page[i] = (i % 2 == 0 ) ? 0xAA : 0x55 ;
371+ }
372+ ASSERT_TRUE (sm_->write_page (filename, 0 , page));
373+
374+ char read_buf[StorageManager::PAGE_SIZE];
375+ ASSERT_TRUE (sm_->read_page (filename, 0 , read_buf));
376+ EXPECT_EQ (std::memcmp (page, read_buf, StorageManager::PAGE_SIZE), 0 );
377+ }
378+
379+ /* *
380+ * @brief Verifies files_opened stat increments correctly
381+ */
382+ TEST_F (StorageManagerTests, FilesOpenedStatAccurate) {
383+ const std::string file1 = " stat_file1.db" ;
384+ const std::string file2 = " stat_file2.db" ;
385+ cleanup_file (" ./test_data" , file1);
386+ cleanup_file (" ./test_data" , file2);
387+
388+ const auto & stats = sm_->get_stats ();
389+ auto initial_files_opened = stats.files_opened .load ();
390+
391+ ASSERT_TRUE (sm_->open_file (file1));
392+ ASSERT_TRUE (sm_->open_file (file2));
393+
394+ EXPECT_EQ (stats.files_opened .load (), initial_files_opened + 2 );
395+ }
396+
236397} // namespace
0 commit comments