@@ -632,6 +632,114 @@ class StressCase008: public StressBase, public StressInterImpl {
632632 }
633633};
634634
635+ /*
636+ * TC009
637+ *
638+ * Test the scenario of deleting first and then creating files/dirs.
639+ */
640+ class StressCase009 : public StressBase , public StressInterImpl {
641+ private:
642+ std::map<int , std::set<std::string>> mp;
643+ std::set<std::string> deleted_names;
644+ public:
645+ StressCase009 (std::string path, int layers): StressBase(path, layers) {}
646+
647+ bool build_gen_mod (StressNode *node, StressHostFile *file) override {
648+ return StressInterImpl::build_gen_mod (node, file);
649+ }
650+ bool build_gen_own (StressNode *node, StressHostFile *file) override {
651+ return StressInterImpl::build_gen_own (node, file);
652+ }
653+ bool build_gen_xattrs (StressNode *node, StressHostFile *file) override {
654+ return StressInterImpl::build_gen_xattrs (node, file);
655+ }
656+ bool build_gen_content (StressNode *node, StressHostFile *file) override {
657+ return StressInterImpl::build_gen_content (node, file);
658+ }
659+
660+ bool verify_gen_mod (StressNode *node, photon::fs::IFile *erofs_file) override {
661+ return StressInterImpl::verify_gen_mod (node, erofs_file);
662+ }
663+ bool verify_gen_own (StressNode *node, photon::fs::IFile *erofs_file) override {
664+ return StressInterImpl::verify_gen_own (node, erofs_file);
665+ }
666+ bool verify_gen_xattrs (StressNode *node, photon::fs::IFile *erofs_file) override {
667+ return StressInterImpl::verify_gen_xattrs (node, erofs_file);
668+ }
669+ bool verify_gen_content (StressNode *node, photon::fs::IFile *erofs_file) override {
670+ return StressInterImpl::verify_gen_content (node, erofs_file);
671+ }
672+
673+ std::string generate_name (int idx, int depth, std::string root_path, NODE_TYPE type) override {
674+ std::string res;
675+ int cnt = 0 ;
676+
677+ if (mp.find (idx) == mp.end ())
678+ mp[idx] = std::set<std::string>();
679+
680+ if (idx == 0 )
681+ res = get_randomstr (type ? MAX_FILE_NAME : MAX_DIR_NAME, true );
682+ else if (idx == 1 ) {
683+ res = tree->get_same_name (idx, depth, root_path, type, true );
684+ if (res.length () == 0 )
685+ res = get_randomstr (type ? MAX_FILE_NAME : MAX_DIR_NAME, true );
686+ /* if it is already been used, then generate a random name */
687+ while (mp[idx].find (res) != mp[idx].end ()) {
688+ res = get_randomstr (type ? MAX_FILE_NAME : MAX_DIR_NAME, true );
689+ cnt ++;
690+ if (cnt > 1000 )
691+ LOG_ERROR_RETURN (-1 , " " , " fail to generate name" );
692+ }
693+ mp[idx].insert (res);
694+ if (tree->get_type (root_path + " /" + res) == type && depth > 0 ) {
695+ deleted_names.insert (root_path + " /" + res);
696+ LOG_INFO (" delete file/dir: `, type: `" , res, tree->get_type (root_path + " /" + res));
697+ res = std::string (EROFS_WHOUT_PREFIX) + res;
698+ }
699+ } else if (idx == 2 ) {
700+ if (depth == 0 )
701+ res = tree->get_same_name (idx, depth, root_path, type, true );
702+ else {
703+ root_path += " /" ;
704+ for (const std::string& name: deleted_names) {
705+ if (str_n_equal (name, root_path, root_path.length ())) {
706+ std::string last_component = name.substr (root_path.length ());
707+ if (last_component.length () > 0 && !is_substring (last_component, " /" )) {
708+ if (mp[idx].find (last_component) == mp[idx].end ()) {
709+ res = last_component;
710+ LOG_INFO (" find deleted name: `, reuse it" , res);
711+ break ;
712+ }
713+ }
714+ }
715+ }
716+ }
717+ if (res.length () == 0 )
718+ res = get_randomstr (type ? MAX_FILE_NAME : MAX_DIR_NAME, true );
719+ goto check_res;
720+ } else {
721+ res = get_randomstr (type ? MAX_FILE_NAME : MAX_DIR_NAME, true );
722+ check_res: while (mp[idx].find (res) != mp[idx].end ()) {
723+ res = get_randomstr (type ? MAX_FILE_NAME : MAX_DIR_NAME, true );
724+ cnt ++;
725+ if (cnt > 1000 )
726+ LOG_ERROR_RETURN (-1 , " " , " fail to generate name" );
727+ }
728+ mp[idx].insert (res);
729+ }
730+ return res;
731+ }
732+
733+ std::vector<int > layer_dirs (int idx) {
734+ std::vector<int > ret;
735+
736+ /* 1000 dirs, each contains 2 files */
737+ for (int i = 0 ; i < 1000 ; i ++)
738+ ret.emplace_back (2 );
739+ return ret;
740+ }
741+ };
742+
635743TEST (ErofsStressTest, TC001) {
636744 std::srand (static_cast <unsigned int >(std::time (0 )));
637745 StressCase001 *tc001 = new StressCase001 (" ./erofs_stress_001" , 20 );
@@ -698,6 +806,14 @@ TEST(ErofsStressTest, TC008) {
698806 delete tc008;
699807}
700808
809+ TEST (ErofsStressTest, TC009) {
810+ std::srand (static_cast <unsigned int >(std::time (0 )));
811+ StressCase009 *tc009 = new StressCase009 (" ./erofs_stress_009" , 3 );
812+
813+ ASSERT_EQ (tc009->run (), true );
814+ delete tc009;
815+ }
816+
701817int main (int argc, char **argv) {
702818
703819 ::testing::InitGoogleTest (&argc, argv);
0 commit comments