diff --git a/tools/ldb_cmd.cc b/tools/ldb_cmd.cc index 118f398022..ec4e0d0f66 100644 --- a/tools/ldb_cmd.cc +++ b/tools/ldb_cmd.cc @@ -3352,6 +3352,11 @@ void DBFileDumperCommand::DoCommand() { // remove the trailing '\n' manifest_filename.resize(manifest_filename.size() - 1); std::string manifest_filepath = db_->GetName() + "/" + manifest_filename; + // Correct concatenation of filepath and filename: + // Check that there is no double slashes (or more!) when concatenation + // happens. + manifest_filepath = NormalizePath(manifest_filepath); + std::cout << manifest_filepath << std::endl; DumpManifestFile(options_, manifest_filepath, false, false, false); std::cout << std::endl; @@ -3361,7 +3366,11 @@ void DBFileDumperCommand::DoCommand() { std::vector metadata; db_->GetLiveFilesMetaData(&metadata); for (auto& fileMetadata : metadata) { - std::string filename = fileMetadata.db_path + fileMetadata.name; + std::string filename = fileMetadata.db_path + "/" + fileMetadata.name; + // Correct concatenation of filepath and filename: + // Check that there is no double slashes (or more!) when concatenation + // happens. + filename = NormalizePath(filename); std::cout << filename << " level:" << fileMetadata.level << std::endl; std::cout << "------------------------------" << std::endl; DumpSstFile(options_, filename, false, true); diff --git a/tools/ldb_test.py b/tools/ldb_test.py index f329699a2e..699317b95d 100644 --- a/tools/ldb_test.py +++ b/tools/ldb_test.py @@ -423,8 +423,36 @@ class LDBTestCase(unittest.TestCase): self.assertRunOK("delete x1", "OK") self.assertRunOK("put x3 y3", "OK") dumpFilePath = os.path.join(self.TMP_DIR, "dump2") + + # Test that if the user provides a db path that ends with + # a slash '/', there is no double (or more!) slashes in the + # SST and manifest file names. + + # Add a '/' at the end of dbPath (which normally shouldnt contain any) + if dbPath[-1] != "/": + dbPath += "/" + + # Call the dump_live_files function with the edited dbPath name. self.assertTrue(self.dumpLiveFiles("--db=%s" % dbPath, dumpFilePath)) + # Investigate the output + with open(dumpFilePath, "r") as tmp: + data = tmp.read() + + # Check that all the SST filenames have a correct full path (no multiple '/'). + sstFileList = re.findall(r"%s.*\d+.sst" % dbPath, data) + for sstFilename in sstFileList: + filenumber = re.findall(r"\d+.sst", sstFilename)[0] + self.assertEqual(sstFilename, dbPath+filenumber) + + # Check that all the manifest filenames + # have a correct full path (no multiple '/'). + manifestFileList = re.findall(r"%s.*MANIFEST-\d+" % dbPath, data) + for manifestFilename in manifestFileList: + filenumber = re.findall(r"(?<=MANIFEST-)\d+", manifestFilename)[0] + self.assertEqual(manifestFilename, dbPath+"MANIFEST-"+filenumber) + + def getManifests(self, directory): return glob.glob(directory + "/MANIFEST-*")