@@ -269,14 +269,18 @@ class ErofsPax : public ::testing::Test {
269269
270270 virtual void TearDown () override {
271271 ASSERT_NE (nullptr , host_fs);
272- if (host_fs->access (src_path.c_str (), 0 ) == 0 )
272+ if (host_fs->access (src_path.c_str (), 0 ) == 0 ) {
273273 ASSERT_EQ (0 , host_fs->unlink (src_path.c_str ()));
274- if (host_fs->access (fn_idx.c_str (), 0 ) == 0 )
274+ }
275+ if (host_fs->access (fn_idx.c_str (), 0 ) == 0 ) {
275276 ASSERT_EQ (0 , host_fs->unlink (fn_idx.c_str ()));
276- if (host_fs->access (fn_meta.c_str (), 0 ) == 0 )
277+ }
278+ if (host_fs->access (fn_meta.c_str (), 0 ) == 0 ) {
277279 ASSERT_EQ (0 , host_fs->unlink (fn_meta.c_str ()));
278- if (host_fs->access (sha256_path.c_str (), 0 ) == 0 )
280+ }
281+ if (host_fs->access (sha256_path.c_str (), 0 ) == 0 ) {
279282 ASSERT_EQ (0 , host_fs->unlink (sha256_path.c_str ()));
283+ }
280284 delete host_fs;
281285 }
282286
@@ -534,7 +538,7 @@ TEST_F(ErofsPax, pax_test) {
534538 auto dir = erofs_fs->opendir (tmp.c_str ());
535539 while (dir->next ()) {
536540 dirent *dent = dir->get ();
537- items.emplace_back (tmp + " /" + dent->d_name );
541+ items.emplace_back (tmp + " /" + std::string ( dent->d_name ) );
538542 }
539543 dir->closedir ();
540544 delete dir;
@@ -551,6 +555,233 @@ TEST_F(ErofsPax, pax_test) {
551555 delete sha256file;
552556}
553557
558+ /* test for the internal ErofsCache */
559+ typedef uint64_t u64 ;
560+ class ErofsCache {
561+ public:
562+ ErofsCache (photon::fs::IFile *file, unsigned long int capacity):
563+ file (file), capacity(capacity)
564+ {}
565+ ~ErofsCache () {}
566+ ssize_t write_sector (u64 addr, char *buf);
567+ ssize_t read_sector (u64 addr, char *buf);
568+ int flush ();
569+ public:
570+ photon::fs::IFile *file;
571+ long unsigned int capacity;
572+ std::map<u64 , struct liberofs_inmem_sector *>caches;
573+ std::set<u64 > dirty;
574+ };
575+
576+ /* helper functions for reading and writing photon files */
577+ extern ssize_t erofs_read_photon_file (void *buf, u64 offset, size_t len,
578+ ErofsCache *cache);
579+ extern ssize_t erofs_write_photon_file (const void *buf, u64 offset,
580+ size_t len, ErofsCache *cache);
581+ class ErofsCacheTest : public ::testing::Test {
582+ protected:
583+ std::string workdir = " /tmp/erofs_cache_test" ;
584+ std::string file_path = workdir + " /img_file" ;
585+ photon::fs::IFileSystem *host_fs;
586+ photon::fs::IFile *img_file;
587+ ErofsCache *cache;
588+
589+ virtual void SetUp () override {
590+ /* prepare for workdir */
591+ host_fs = photon::fs::new_localfs_adaptor ();
592+ ASSERT_NE (nullptr , host_fs);
593+ if (host_fs->access (workdir.c_str (), 0 )) {
594+ ASSERT_EQ (host_fs->mkdir (workdir.c_str (), 0755 ), 0 );
595+ }
596+
597+ /* prepare for img_file */
598+ img_file = host_fs->open (file_path.c_str (), O_RDWR | O_CREAT | O_TRUNC ,
599+ 0666 );
600+ ASSERT_NE (nullptr , img_file);
601+
602+ /*
603+ * prepare for cache. here, we use a cache with a size of only
604+ * one sector to simulate a memory-constrained situation.
605+ */
606+ cache = new ErofsCache (img_file, 1 );
607+ ASSERT_NE (nullptr , cache);
608+ }
609+
610+ virtual void TearDown () override {
611+ ASSERT_NE (nullptr , host_fs);
612+ if (host_fs->access (file_path.c_str (), 0 ) == 0 ) {
613+ ASSERT_EQ (host_fs->unlink (file_path.c_str ()), 0 );
614+ }
615+ delete host_fs;
616+ delete img_file;
617+ delete cache;
618+ }
619+ };
620+
621+ TEST_F (ErofsCacheTest, erofs_cache) {
622+
623+ #define SECTOR_SIZE 512ULL
624+ #define HALF_SECTOR (SECTOR_SIZE / 2 )
625+ #define BIG_OFFSET ((1ULL << 32 ) - 1 )
626+ #define round_down_blk (addr ) ((addr) & (~(SECTOR_SIZE - 1 )))
627+ #define round_up_blk (addr ) (round_down_blk((addr) + SECTOR_SIZE - 1 ))
628+
629+ char buffer[SECTOR_SIZE ];
630+ char buffer_cmp[SECTOR_SIZE ];
631+
632+ /*
633+ * TC001
634+ * 1. write 0xff to [0, 512]
635+ * 2. write 0x00 to [256, 512]
636+ * 3. compare
637+ */
638+ memset (buffer, 0xff , SECTOR_SIZE );
639+ ASSERT_EQ (SECTOR_SIZE , erofs_write_photon_file (buffer, 0 , SECTOR_SIZE ,
640+ cache));
641+ memset (buffer, 0x00 , SECTOR_SIZE );
642+ ASSERT_EQ (HALF_SECTOR , erofs_write_photon_file (buffer, HALF_SECTOR ,
643+ HALF_SECTOR , cache));
644+ memset (buffer_cmp, 0xff , HALF_SECTOR );
645+ memset (buffer_cmp + HALF_SECTOR , 0x00 , HALF_SECTOR );
646+ ASSERT_EQ (SECTOR_SIZE , erofs_read_photon_file (buffer, 0 , SECTOR_SIZE ,
647+ cache));
648+ ASSERT_EQ (0 , memcmp (buffer, buffer_cmp, SECTOR_SIZE ));
649+
650+ /*
651+ * TC002
652+ * 1. write 0xff to [0, 1024]
653+ * 2. write 0x00 to [0, 512]
654+ * 3. flush, then read and compare
655+ */
656+ memset (buffer, 0xff , SECTOR_SIZE );
657+ ASSERT_EQ (SECTOR_SIZE , erofs_write_photon_file (buffer, 0 , SECTOR_SIZE ,
658+ cache));
659+ ASSERT_EQ (SECTOR_SIZE , erofs_write_photon_file (buffer, SECTOR_SIZE ,
660+ SECTOR_SIZE , cache));
661+ memset (buffer, 0x00 , SECTOR_SIZE );
662+ ASSERT_EQ (SECTOR_SIZE , erofs_write_photon_file (buffer, 0 , SECTOR_SIZE ,
663+ cache));
664+ cache->flush ();
665+ memset (buffer, 0x00 , SECTOR_SIZE );
666+ ASSERT_EQ (SECTOR_SIZE , img_file->pread (buffer_cmp, SECTOR_SIZE , 0 ));
667+ ASSERT_EQ (0 , memcmp (buffer, buffer_cmp, SECTOR_SIZE ));
668+ memset (buffer, 0xff , SECTOR_SIZE );
669+ ASSERT_EQ (SECTOR_SIZE , img_file->pread (buffer_cmp, SECTOR_SIZE ,
670+ SECTOR_SIZE ));
671+ ASSERT_EQ (0 , memcmp (buffer, buffer_cmp, SECTOR_SIZE ));
672+
673+ /*
674+ * TC003
675+ * write 11 blocks, odd blocks contain
676+ * 0xff and even blocks contain 0x00
677+ */
678+ for (int i = 0 ; i < 11 ; i ++) {
679+ if (i & 1 )
680+ memset (buffer, 0xff , SECTOR_SIZE );
681+ else
682+ memset (buffer, 0x00 , SECTOR_SIZE );
683+ ASSERT_EQ (SECTOR_SIZE , erofs_write_photon_file (buffer, SECTOR_SIZE * i,
684+ SECTOR_SIZE , cache));
685+ }
686+ cache->flush ();
687+ for (int i = 0 ; i < 11 ; i ++) {
688+ if (i & 1 )
689+ memset (buffer_cmp, 0xff , SECTOR_SIZE );
690+ else
691+ memset (buffer_cmp, 0x00 , SECTOR_SIZE );
692+ ASSERT_EQ (SECTOR_SIZE , erofs_read_photon_file (buffer, SECTOR_SIZE * i,
693+ SECTOR_SIZE , cache));
694+ ASSERT_EQ (0 , memcmp (buffer, buffer_cmp, SECTOR_SIZE ));
695+ ASSERT_EQ (SECTOR_SIZE , img_file->pread (buffer, SECTOR_SIZE ,
696+ SECTOR_SIZE * i));
697+ ASSERT_EQ (0 , memcmp (buffer, buffer_cmp, SECTOR_SIZE ));
698+ }
699+
700+ /*
701+ * TC 004
702+ * test for non-aligned blocks
703+ */
704+ for (int i = 0 ; i < 10 ; i ++) {
705+ if (i & 1 )
706+ memset (buffer, 0xff , SECTOR_SIZE );
707+ else
708+ memset (buffer, 0x00 , SECTOR_SIZE );
709+ ASSERT_EQ (SECTOR_SIZE , erofs_write_photon_file (buffer,
710+ HALF_SECTOR + SECTOR_SIZE * i, SECTOR_SIZE , cache));
711+ }
712+ cache->flush ();
713+ for (int i = 0 ; i < 10 ; i ++) {
714+ if (i & 1 )
715+ memset (buffer_cmp, 0xff , SECTOR_SIZE );
716+ else
717+ memset (buffer_cmp, 0x00 , SECTOR_SIZE );
718+ ASSERT_EQ (SECTOR_SIZE , erofs_read_photon_file (buffer,
719+ HALF_SECTOR + SECTOR_SIZE * i, SECTOR_SIZE , cache));
720+ ASSERT_EQ (0 , memcmp (buffer, buffer_cmp, SECTOR_SIZE ));
721+ ASSERT_EQ (SECTOR_SIZE , img_file->pread (buffer, SECTOR_SIZE ,
722+ HALF_SECTOR + SECTOR_SIZE * i));
723+ ASSERT_EQ (0 , memcmp (buffer, buffer_cmp, SECTOR_SIZE ));
724+ }
725+
726+ /*
727+ * TC 005
728+ * test for offset bigger than 2^32 (block-aligned)
729+ */
730+ for (int i = 0 ; i < 11 ; i ++) {
731+ if (i & 1 )
732+ memset (buffer, 0xff , SECTOR_SIZE );
733+ else
734+ memset (buffer, 0x00 , SECTOR_SIZE );
735+ ASSERT_EQ (SECTOR_SIZE , erofs_write_photon_file (buffer,
736+ round_up_blk (BIG_OFFSET ) + SECTOR_SIZE * i, SECTOR_SIZE , cache));
737+ }
738+ cache->flush ();
739+ for (int i = 0 ; i < 11 ; i ++) {
740+ if (i & 1 )
741+ memset (buffer_cmp, 0xff , SECTOR_SIZE );
742+ else
743+ memset (buffer_cmp, 0x00 , SECTOR_SIZE );
744+ ASSERT_EQ (SECTOR_SIZE , erofs_read_photon_file (buffer,
745+ round_up_blk (BIG_OFFSET ) + SECTOR_SIZE * i, SECTOR_SIZE , cache));
746+ ASSERT_EQ (0 , memcmp (buffer, buffer_cmp, SECTOR_SIZE ));
747+ ASSERT_EQ (SECTOR_SIZE , img_file->pread (buffer, SECTOR_SIZE ,
748+ round_up_blk (BIG_OFFSET ) + SECTOR_SIZE * i));
749+ ASSERT_EQ (0 , memcmp (buffer, buffer_cmp, SECTOR_SIZE ));
750+ }
751+
752+ /*
753+ * TC 006
754+ * test for offset bigger than 2^32 (non-aligned)
755+ */
756+ for (int i = 0 ; i < 10 ; i ++) {
757+ if (i & 1 )
758+ memset (buffer, 0xff , SECTOR_SIZE );
759+ else
760+ memset (buffer, 0x00 , SECTOR_SIZE );
761+ ASSERT_EQ (SECTOR_SIZE , erofs_write_photon_file (buffer,
762+ BIG_OFFSET + SECTOR_SIZE * i, SECTOR_SIZE , cache));
763+ }
764+ cache->flush ();
765+ for (int i = 0 ; i < 10 ; i ++) {
766+ if (i & 1 )
767+ memset (buffer_cmp, 0xff , SECTOR_SIZE );
768+ else
769+ memset (buffer_cmp, 0x00 , SECTOR_SIZE );
770+ ASSERT_EQ (SECTOR_SIZE , erofs_read_photon_file (buffer,
771+ BIG_OFFSET + SECTOR_SIZE * i, SECTOR_SIZE , cache));
772+ ASSERT_EQ (0 , memcmp (buffer, buffer_cmp, SECTOR_SIZE ));
773+ ASSERT_EQ (SECTOR_SIZE , img_file->pread (buffer, SECTOR_SIZE ,
774+ BIG_OFFSET + SECTOR_SIZE * i));
775+ ASSERT_EQ (0 , memcmp (buffer, buffer_cmp, SECTOR_SIZE ));
776+ }
777+
778+ #undef SECTOR_SIZE
779+ #undef HALF_SECTOR
780+ #undef BIG_OFFSET
781+ #undef round_down_blk
782+ #undef round_up_blk
783+ }
784+
554785int main (int argc, char **argv) {
555786
556787 ::testing::InitGoogleTest (&argc, argv);
0 commit comments