From 1bee0fca057b246c4ad8c8a28e96dec57a37c342 Mon Sep 17 00:00:00 2001 From: Cheng Chang Date: Fri, 5 Jun 2020 10:53:08 -0700 Subject: [PATCH] Make DestroyDir destroy directories recursively (#6934) Summary: Currently, `DeleteDir` only deletes the directory if there are no other directories under the target dir. This PR makes it delete directories recursively. Pull Request resolved: https://github.com/facebook/rocksdb/pull/6934 Test Plan: Added a new unit test in testutil_test.cc. `make testutil_test` Reviewed By: zhichao-cao Differential Revision: D21884211 Pulled By: cheng-chang fbshipit-source-id: 0b9a48a200f494ee007aef5d1763b4aa331f8b5a --- CMakeLists.txt | 1 + Makefile | 4 ++++ TARGETS | 7 +++++++ test_util/testutil.cc | 11 +++++++++- test_util/testutil_test.cc | 42 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 test_util/testutil_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f7ac239a..9ea39e5e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1090,6 +1090,7 @@ if(WITH_TESTS) table/sst_file_reader_test.cc table/table_test.cc table/block_fetcher_test.cc + test_util/testutil_test.cc tools/block_cache_analyzer/block_cache_trace_analyzer_test.cc tools/ldb_cmd_test.cc tools/reduce_levels_test.cc diff --git a/Makefile b/Makefile index f2ebba44b..874bf5993 100644 --- a/Makefile +++ b/Makefile @@ -639,6 +639,7 @@ TESTS = \ blob_file_garbage_test \ timer_test \ db_with_timestamp_compaction_test \ + testutil_test \ PARALLEL_TEST = \ backupable_db_test \ @@ -1866,6 +1867,9 @@ blob_file_garbage_test: db/blob/blob_file_garbage_test.o $(LIBOBJECTS) $(TESTHAR timer_test: util/timer_test.o $(LIBOBJECTS) $(TESTHARNESS) $(AM_LINK) +testutil_test: test_util/testutil_test.o $(LIBOBJECTS) $(TESTHARNESS) + $(AM_LINK) + #------------------------------------------------- # make install related stuff INSTALL_PATH ?= /usr/local diff --git a/TARGETS b/TARGETS index 6a68b3c69..83e51cfe6 100644 --- a/TARGETS +++ b/TARGETS @@ -1485,6 +1485,13 @@ ROCKS_TESTS = [ [], [], ], + [ + "testutil_test", + "test_util/testutil_test.cc", + "serial", + [], + [], + ], [ "thread_list_test", "util/thread_list_test.cc", diff --git a/test_util/testutil.cc b/test_util/testutil.cc index 16d02d6a6..e0bc9c851 100644 --- a/test_util/testutil.cc +++ b/test_util/testutil.cc @@ -464,7 +464,16 @@ Status DestroyDir(Env* env, const std::string& dir) { if (file_in_dir == "." || file_in_dir == "..") { continue; } - s = env->DeleteFile(dir + "/" + file_in_dir); + std::string path = dir + "/" + file_in_dir; + bool is_dir = false; + s = env->IsDirectory(path, &is_dir); + if (s.ok()) { + if (is_dir) { + s = DestroyDir(env, path); + } else { + s = env->DeleteFile(path); + } + } if (!s.ok()) { break; } diff --git a/test_util/testutil_test.cc b/test_util/testutil_test.cc new file mode 100644 index 000000000..d055af667 --- /dev/null +++ b/test_util/testutil_test.cc @@ -0,0 +1,42 @@ +// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. +// This source code is licensed under both the GPLv2 (found in the +// COPYING file in the root directory) and Apache 2.0 License +// (found in the LICENSE.Apache file in the root directory). + +#include "test_util/testutil.h" + +#include "port/port.h" +#include "port/stack_trace.h" +#include "test_util/testharness.h" + +namespace ROCKSDB_NAMESPACE { + +void CreateFile(Env* env, const std::string& path) { + std::unique_ptr f; + ASSERT_OK(env->NewWritableFile(path, &f, EnvOptions())); + f->Close(); +} + +TEST(TestUtil, DestroyDirRecursively) { + auto env = Env::Default(); + // test_util/file + // /dir + // /dir/file + std::string test_dir = test::PerThreadDBPath("test_util"); + ASSERT_OK(env->CreateDir(test_dir)); + CreateFile(env, test_dir + "/file"); + ASSERT_OK(env->CreateDir(test_dir + "/dir")); + CreateFile(env, test_dir + "/dir/file"); + + ASSERT_OK(test::DestroyDir(env, test_dir)); + auto s = env->FileExists(test_dir); + ASSERT_TRUE(s.IsNotFound()); +} + +} // namespace ROCKSDB_NAMESPACE + +int main(int argc, char** argv) { + ROCKSDB_NAMESPACE::port::InstallStackTraceHandler(); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +}