GEODE-8929: fix 'leaked disk space' issue in logger (#743)

- Logger wasn't calculating the size of existing files when
  initializing.  Thus the disk usage could grow by up to the space limit
  set by the app at each iteration (run).
- Added new test to start/stop logger several times and verify we're
  never exceeding disk space limits in toto.
- passing nullptr for file name to Log::Init() wasn't writing to a
  default file, now it writes to 'geode-native.log' in CWD.
- logging test for (#) in filename wasn't cleaning up its log file
- added test code to clean up any default-named log files
- Run all unit tests with "test" filename, and with default filename
  (geode-native.log)
- Add specific case to check for "leaked" disk space when specifying
  nullptr to get the default file name.
diff --git a/cppcache/src/Log.cpp b/cppcache/src/Log.cpp
index aaf71b9..d6d431c 100644
--- a/cppcache/src/Log.cpp
+++ b/cppcache/src/Log.cpp
@@ -105,8 +105,8 @@
 void Log::init(LogLevel level, const char* logFileName, int32_t logFileLimit,
                int64_t logDiskSpaceLimit) {
   auto logFileNameString =
-      logFileName ? std::string(logFileName) : std::string();
-  init(level, std::string(logFileNameString), logFileLimit, logDiskSpaceLimit);
+      logFileName ? std::string(logFileName) : std::string("geode-native.log");
+  init(level, logFileNameString, logFileLimit, logDiskSpaceLimit);
 }
 
 void Log::rollLogFile() {
@@ -138,6 +138,19 @@
     boost::filesystem::remove(fileToRemove);
     g_rollFiles.erase(index);
     g_spaceUsed -= fileSize;
+  } else {
+    throw IllegalStateException(
+        "Failed to free sufficient disk space for logs");
+  }
+}
+
+void Log::calculateUsedDiskSpace() {
+  g_spaceUsed = 0;
+  if (boost::filesystem::exists(g_fullpath)) {
+    g_spaceUsed = boost::filesystem::file_size(g_fullpath);
+    for (auto const& item : g_rollFiles) {
+      g_spaceUsed += boost::filesystem::file_size(item.second);
+    }
   }
 }
 
@@ -231,6 +244,10 @@
 
     buildRollFileMapping();
     setRollFileIndex();
+    calculateUsedDiskSpace();
+    while (g_spaceUsed > g_diskSpaceLimit) {
+      removeOldestRolledLogFile();
+    }
 
     if (boost::filesystem::exists(g_fullpath) && logFileLimit > 0) {
       rollLogFile();
@@ -239,8 +256,9 @@
   } catch (const boost::exception&) {
     auto msg = std::string("Unable to log to file '") + logFileName + "'";
     throw IllegalArgumentException(msg.c_str());
-  } catch (const std::exception&) {
-    auto msg = std::string("Unable to log to file '") + logFileName + "'";
+  } catch (const std::exception& ex) {
+    auto msg = std::string("Unable to log to file '") + logFileName +
+               "': " + ex.what();
     throw IllegalArgumentException(msg.c_str());
   }
 }
diff --git a/cppcache/src/util/Log.hpp b/cppcache/src/util/Log.hpp
index ae33fef..b9e17d6 100644
--- a/cppcache/src/util/Log.hpp
+++ b/cppcache/src/util/Log.hpp
@@ -213,6 +213,8 @@
   static void setSizeLimits(int32_t logFileLimit, int64_t logDiskSpaceLimit);
 
   static void logInternal(LogLevel level, const std::string& msg);
+
+  static void calculateUsedDiskSpace();
 };
 
 }  // namespace client
diff --git a/cppcache/test/LoggingTest.cpp b/cppcache/test/LoggingTest.cpp
index ce68ef9..5e62cd5 100644
--- a/cppcache/test/LoggingTest.cpp
+++ b/cppcache/test/LoggingTest.cpp
@@ -44,8 +44,6 @@
 
 const auto LENGTH_OF_BANNER = 16;
 
-auto testLogFileName = std::string("LoggingTest.log");
-
 const char* __1KStringLiteral =
     "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
     "AA"
@@ -75,32 +73,39 @@
     "AA"
     "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
 
+auto testFileNames = {"LoggingTest.log", "geode-native.log"};
+
 class LoggingTest : public testing::Test {
   void scrubTestLogFiles() {
-    // Close logger, just in case
-    apache::geode::client::Log::close();
+    for (auto name : testFileNames) {
+      // Close logger, just in case
+      apache::geode::client::Log::close();
 
-    if (boost::filesystem::exists(testLogFileName)) {
-      boost::filesystem::remove(testLogFileName);
-    }
+      if (boost::filesystem::exists(name)) {
+        boost::filesystem::remove(name);
+      }
 
-    std::map<int32_t, boost::filesystem::path> rolledFiles;
-    LoggingTest::findRolledFiles(boost::filesystem::current_path().string(),
-                                 rolledFiles);
-    for (auto& item : rolledFiles) {
-      boost::filesystem::remove(item.second);
+      std::map<int32_t, boost::filesystem::path> rolledFiles;
+      LoggingTest::findRolledFiles(boost::filesystem::current_path().string(),
+                                   name, rolledFiles);
+      for (auto& item : rolledFiles) {
+        boost::filesystem::remove(item.second);
+      }
     }
   }
 
-  virtual void SetUp() { scrubTestLogFiles(); }
+  virtual void SetUp() {
+    // scrubTestLogFiles();
+  }
 
   virtual void TearDown() { scrubTestLogFiles(); }
 
  public:
   static void writeRolledLogFile(const boost::filesystem::path& logdir,
-                                 int32_t rollIndex) {
+                                 const char* filename, int32_t rollIndex) {
+    auto baseName = boost::filesystem::path(filename).stem().string();
     auto rolledPath =
-        logdir / boost::filesystem::path("LoggingTest-" +
+        logdir / boost::filesystem::path(baseName + "-" +
                                          std::to_string(rollIndex) + ".log");
     auto rolledFile = fopen(rolledPath.string().c_str(), "w");
     fwrite("Test", 1, 4, rolledFile);
@@ -144,31 +149,33 @@
   }
 
   static void verifyLineCountAtLevel(LogLevel level) {
-    apache::geode::client::Log::init(level, testLogFileName);
+    for (auto logFilename : testFileNames) {
+      apache::geode::client::Log::init(level, logFilename);
 
-    LOGERROR("Error Message");
-    LOGWARN("Warning Message");
-    LOGINFO("Info Message");
-    LOGCONFIG("Config Message");
-    LOGFINE("Fine Message");
-    LOGFINER("Finer Message");
-    LOGFINEST("Finest Message");
-    LOGDEBUG("Debug Message");
+      LOGERROR("Error Message");
+      LOGWARN("Warning Message");
+      LOGINFO("Info Message");
+      LOGCONFIG("Config Message");
+      LOGFINE("Fine Message");
+      LOGFINER("Finer Message");
+      LOGFINEST("Finest Message");
+      LOGDEBUG("Debug Message");
 
-    int lines = LoggingTest::numOfLinesInFile(testLogFileName.c_str());
+      int lines = LoggingTest::numOfLinesInFile(logFilename);
 
-    ASSERT_TRUE(lines == LoggingTest::expectedWithBanner(level));
+      ASSERT_TRUE(lines == LoggingTest::expectedWithBanner(level));
 
-    apache::geode::client::Log::close();
-    boost::filesystem::remove(testLogFileName.c_str());
+      apache::geode::client::Log::close();
+      boost::filesystem::remove(logFilename);
+    }
   }
 
   static void findRolledFiles(
-      const std::string& logFilePath,
+      const std::string& logFilePath, const boost::filesystem::path& filename,
       std::map<int32_t, boost::filesystem::path>& rolledFiles) {
     const auto basePath =
         boost::filesystem::absolute(boost::filesystem::path(logFilePath)) /
-        testLogFileName;
+        filename;
     const auto filterstring = basePath.stem().string() + "-(\\d+)\\.log$";
     const std::regex my_filter(filterstring);
 
@@ -179,11 +186,11 @@
              basePath.parent_path().string());
          i != end_itr; ++i) {
       if (boost::filesystem::is_regular_file(i->status())) {
-        std::string filename = i->path().filename().string();
+        std::string rootFilename = i->path().filename().string();
         std::regex testPattern(filterstring);
         std::match_results<std::string::const_iterator> testMatches;
-        if (std::regex_search(std::string::const_iterator(filename.begin()),
-                              filename.cend(), testMatches, testPattern)) {
+        if (std::regex_search(std::string::const_iterator(rootFilename.begin()),
+                              rootFilename.cend(), testMatches, testPattern)) {
           auto index = std::atoi(
               std::string(testMatches[1].first, testMatches[1].second).c_str());
           rolledFiles[index] = i->path();
@@ -191,6 +198,46 @@
       }
     }
   }
+
+  static size_t calculateUsedDiskSpace(const std::string& logFilePath) {
+    std::map<int32_t, boost::filesystem::path> rolledLogFiles{};
+    findRolledFiles(boost::filesystem::current_path().string(),
+                    boost::filesystem::path(logFilePath), rolledLogFiles);
+
+    auto usedSpace = boost::filesystem::file_size(logFilePath);
+    for (auto const& item : rolledLogFiles) {
+      usedSpace += boost::filesystem::file_size(item.second);
+    }
+
+    return usedSpace;
+  }
+
+  void verifyDiskSpaceNotLeakedForFile(const char* filename) {
+    const int NUMBER_OF_ITERATIONS = 4 * __1K__;
+    const int DISK_SPACE_LIMIT = 2 * __1M__;
+
+    std::string logfileName = filename ? filename : "geode-native.log";
+
+    // Start/stop logger several times, make sure it's picking up any/all
+    // existing logs in its disk space calculations.
+    for (auto j = 0; j < 5; j++) {
+      ASSERT_NO_THROW(apache::geode::client::Log::init(
+          apache::geode::client::LogLevel::Debug, logfileName, 1, 2));
+      for (auto i = 0; i < NUMBER_OF_ITERATIONS; i++) {
+        LOGDEBUG(__1KStringLiteral);
+      }
+      apache::geode::client::Log::close();
+
+      // Original file should still be around
+      ASSERT_TRUE(boost::filesystem::exists(logfileName));
+
+      // We wrote 4x the log file limit, and 2x the disk space limit, so
+      // there should be one 'rolled' file.  Its name should be of the form
+      // <base>-n.log, where n is some reasonable number.
+      auto usedSpace = calculateUsedDiskSpace(logfileName);
+      ASSERT_TRUE(usedSpace < DISK_SPACE_LIMIT);
+    }
+  }
 };
 
 /**
@@ -198,40 +245,67 @@
  * filename, file size limit, and disk space limit
  */
 TEST_F(LoggingTest, logInit) {
-  // Check all valid levels
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::None, testLogFileName.c_str(), 1, 4));
-  apache::geode::client::Log::close();
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Error, testLogFileName.c_str(), 1, 4));
-  apache::geode::client::Log::close();
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Warning, testLogFileName.c_str(), 1, 4));
-  apache::geode::client::Log::close();
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Info, testLogFileName.c_str(), 1, 4));
-  apache::geode::client::Log::close();
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Default, testLogFileName.c_str(), 1, 4));
-  apache::geode::client::Log::close();
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Config, testLogFileName.c_str(), 1, 4));
-  apache::geode::client::Log::close();
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Fine, testLogFileName.c_str(), 1, 4));
-  apache::geode::client::Log::close();
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Finer, testLogFileName.c_str(), 1, 4));
-  apache::geode::client::Log::close();
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Finest, testLogFileName.c_str(), 1, 4));
-  apache::geode::client::Log::close();
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Debug, testLogFileName.c_str(), 1, 4));
-  apache::geode::client::Log::close();
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::All, testLogFileName.c_str(), 1, 4));
-  apache::geode::client::Log::close();
+  for (auto logFilename : testFileNames) {
+    // Check all valid levels
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::None, logFilename, 1, 4));
+    apache::geode::client::Log::close();
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Error, logFilename, 1, 4));
+    apache::geode::client::Log::close();
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Warning, logFilename, 1, 4));
+    apache::geode::client::Log::close();
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Info, logFilename, 1, 4));
+    apache::geode::client::Log::close();
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Default, logFilename, 1, 4));
+    apache::geode::client::Log::close();
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Config, logFilename, 1, 4));
+    apache::geode::client::Log::close();
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Fine, logFilename, 1, 4));
+    apache::geode::client::Log::close();
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Finer, logFilename, 1, 4));
+    apache::geode::client::Log::close();
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Finest, logFilename, 1, 4));
+    apache::geode::client::Log::close();
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Debug, logFilename, 1, 4));
+    apache::geode::client::Log::close();
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::All, logFilename, 1, 4));
+    apache::geode::client::Log::close();
+    // Specify a disk space limit smaller than the file size limit
+    ASSERT_THROW(
+        apache::geode::client::Log::init(
+            apache::geode::client::LogLevel::Config, logFilename, __1K__, 4),
+        apache::geode::client::IllegalArgumentException);
+
+    // Specify a file size limit above max allowed
+    ASSERT_THROW(
+        apache::geode::client::Log::init(
+            apache::geode::client::LogLevel::Config, logFilename, __1G__),
+        apache::geode::client::IllegalArgumentException);
+
+    // Specify a disk space limit above max allowed
+    ASSERT_THROW(
+        apache::geode::client::Log::init(
+            apache::geode::client::LogLevel::Config, logFilename, 1, __1G__),
+        apache::geode::client::IllegalArgumentException);
+
+    // Init twice without closing
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::All, logFilename, 1, 4));
+    ASSERT_THROW(apache::geode::client::Log::init(
+                     apache::geode::client::LogLevel::All, logFilename, 1, 4),
+                 apache::geode::client::IllegalStateException);
+    apache::geode::client::Log::close();
+  }
 
   // Init with valid filename
   ASSERT_NO_THROW(apache::geode::client::Log::init(
@@ -242,6 +316,7 @@
   ASSERT_NO_THROW(apache::geode::client::Log::init(
       apache::geode::client::LogLevel::Config, "LoggingTest (#).log"));
   apache::geode::client::Log::close();
+  boost::filesystem::remove("LoggingTest (#).log");
 
   // Init with invalid filename
   ASSERT_THROW(apache::geode::client::Log::init(
@@ -255,263 +330,247 @@
   ASSERT_NO_THROW(apache::geode::client::Log::init(
       apache::geode::client::LogLevel::Config, nullptr, 0, 4));
   apache::geode::client::Log::close();
-
-  // Specify a disk space limit smaller than the file size limit
-  ASSERT_THROW(
-      apache::geode::client::Log::init(apache::geode::client::LogLevel::Config,
-                                       testLogFileName, __1K__, 4),
-      apache::geode::client::IllegalArgumentException);
-
-  // Specify a file size limit above max allowed
-  ASSERT_THROW(
-      apache::geode::client::Log::init(apache::geode::client::LogLevel::Config,
-                                       testLogFileName, __1G__),
-      apache::geode::client::IllegalArgumentException);
-
-  // Specify a disk space limit above max allowed
-  ASSERT_THROW(
-      apache::geode::client::Log::init(apache::geode::client::LogLevel::Config,
-                                       testLogFileName, 1, __1G__),
-      apache::geode::client::IllegalArgumentException);
-
-  // Init twice without closing
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::All, testLogFileName.c_str(), 1, 4));
-  ASSERT_THROW(
-      apache::geode::client::Log::init(apache::geode::client::LogLevel::All,
-                                       testLogFileName.c_str(), 1, 4),
-      apache::geode::client::IllegalStateException);
-  apache::geode::client::Log::close();
 }
 
 TEST_F(LoggingTest, logToFileAtEachLevel) {
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Debug, testLogFileName));
-  LOGDEBUG("This is a debug string");
-  LOGDEBUG("This is a formatted debug string (%d)", __1K__);
-  apache::geode::client::Log::close();
-  ASSERT_TRUE(boost::filesystem::exists(testLogFileName));
-  ASSERT_TRUE(boost::filesystem::file_size(testLogFileName) > 0);
-  boost::filesystem::remove(testLogFileName);
-  ASSERT_FALSE(boost::filesystem::exists(testLogFileName));
+  for (auto logFilename : testFileNames) {
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Debug, logFilename));
+    LOGDEBUG("This is a debug string");
+    LOGDEBUG("This is a formatted debug string (%d)", __1K__);
+    apache::geode::client::Log::close();
+    ASSERT_TRUE(boost::filesystem::exists(logFilename));
+    ASSERT_TRUE(boost::filesystem::file_size(logFilename) > 0);
+    boost::filesystem::remove(logFilename);
+    ASSERT_FALSE(boost::filesystem::exists(logFilename));
 
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Finest, testLogFileName));
-  LOGFINEST("This is a 'finest' string");
-  LOGFINEST("This is a formatted 'finest' string (%d)", __1K__);
-  apache::geode::client::Log::close();
-  ASSERT_TRUE(boost::filesystem::exists(testLogFileName));
-  ASSERT_TRUE(boost::filesystem::file_size(testLogFileName) > 0);
-  boost::filesystem::remove(testLogFileName);
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Finest, logFilename));
+    LOGFINEST("This is a 'finest' string");
+    LOGFINEST("This is a formatted 'finest' string (%d)", __1K__);
+    apache::geode::client::Log::close();
+    ASSERT_TRUE(boost::filesystem::exists(logFilename));
+    ASSERT_TRUE(boost::filesystem::file_size(logFilename) > 0);
+    boost::filesystem::remove(logFilename);
 
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Finer, testLogFileName));
-  LOGFINER("This is a 'finer' string");
-  LOGFINER("This is a formatted 'finer' string (%d)", __1K__);
-  apache::geode::client::Log::close();
-  ASSERT_TRUE(boost::filesystem::exists(testLogFileName));
-  ASSERT_TRUE(boost::filesystem::file_size(testLogFileName) > 0);
-  boost::filesystem::remove(testLogFileName);
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Finer, logFilename));
+    LOGFINER("This is a 'finer' string");
+    LOGFINER("This is a formatted 'finer' string (%d)", __1K__);
+    apache::geode::client::Log::close();
+    ASSERT_TRUE(boost::filesystem::exists(logFilename));
+    ASSERT_TRUE(boost::filesystem::file_size(logFilename) > 0);
+    boost::filesystem::remove(logFilename);
 
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Fine, testLogFileName));
-  LOGFINE("This is a 'fine' string");
-  LOGFINE("This is a formatted 'fine' string (%d)", __1K__);
-  apache::geode::client::Log::close();
-  ASSERT_TRUE(boost::filesystem::exists(testLogFileName));
-  ASSERT_TRUE(boost::filesystem::file_size(testLogFileName) > 0);
-  boost::filesystem::remove(testLogFileName);
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Fine, logFilename));
+    LOGFINE("This is a 'fine' string");
+    LOGFINE("This is a formatted 'fine' string (%d)", __1K__);
+    apache::geode::client::Log::close();
+    ASSERT_TRUE(boost::filesystem::exists(logFilename));
+    ASSERT_TRUE(boost::filesystem::file_size(logFilename) > 0);
+    boost::filesystem::remove(logFilename);
 
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Config, testLogFileName));
-  LOGCONFIG("This is a 'config' string");
-  LOGCONFIG("This is a formatted 'config' string (%d)", __1K__);
-  apache::geode::client::Log::close();
-  ASSERT_TRUE(boost::filesystem::exists(testLogFileName));
-  ASSERT_TRUE(boost::filesystem::file_size(testLogFileName) > 0);
-  boost::filesystem::remove(testLogFileName);
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Config, logFilename));
+    LOGCONFIG("This is a 'config' string");
+    LOGCONFIG("This is a formatted 'config' string (%d)", __1K__);
+    apache::geode::client::Log::close();
+    ASSERT_TRUE(boost::filesystem::exists(logFilename));
+    ASSERT_TRUE(boost::filesystem::file_size(logFilename) > 0);
+    boost::filesystem::remove(logFilename);
 
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Info, testLogFileName));
-  LOGINFO("This is a 'finer' string");
-  LOGINFO("This is a formatted 'finer' string (%d)", __1K__);
-  apache::geode::client::Log::close();
-  ASSERT_TRUE(boost::filesystem::exists(testLogFileName));
-  ASSERT_TRUE(boost::filesystem::file_size(testLogFileName) > 0);
-  boost::filesystem::remove(testLogFileName);
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Info, logFilename));
+    LOGINFO("This is a 'finer' string");
+    LOGINFO("This is a formatted 'finer' string (%d)", __1K__);
+    apache::geode::client::Log::close();
+    ASSERT_TRUE(boost::filesystem::exists(logFilename));
+    ASSERT_TRUE(boost::filesystem::file_size(logFilename) > 0);
+    boost::filesystem::remove(logFilename);
 
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Warning, testLogFileName));
-  LOGWARN("This is a 'warning' string");
-  LOGWARN("This is a formatted 'warning' string (%d)", __1K__);
-  apache::geode::client::Log::close();
-  ASSERT_TRUE(boost::filesystem::exists(testLogFileName));
-  ASSERT_TRUE(boost::filesystem::file_size(testLogFileName) > 0);
-  boost::filesystem::remove(testLogFileName);
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Warning, logFilename));
+    LOGWARN("This is a 'warning' string");
+    LOGWARN("This is a formatted 'warning' string (%d)", __1K__);
+    apache::geode::client::Log::close();
+    ASSERT_TRUE(boost::filesystem::exists(logFilename));
+    ASSERT_TRUE(boost::filesystem::file_size(logFilename) > 0);
+    boost::filesystem::remove(logFilename);
 
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Error, testLogFileName));
-  LOGERROR("This is a 'error' string");
-  LOGERROR("This is a formatted 'error' string (%d)", __1K__);
-  apache::geode::client::Log::close();
-  ASSERT_TRUE(boost::filesystem::exists(testLogFileName));
-  ASSERT_TRUE(boost::filesystem::file_size(testLogFileName) > 0);
-  boost::filesystem::remove(testLogFileName);
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Error, logFilename));
+    LOGERROR("This is a 'error' string");
+    LOGERROR("This is a formatted 'error' string (%d)", __1K__);
+    apache::geode::client::Log::close();
+    ASSERT_TRUE(boost::filesystem::exists(logFilename));
+    ASSERT_TRUE(boost::filesystem::file_size(logFilename) > 0);
+    boost::filesystem::remove(logFilename);
+  }
 }
 
 TEST_F(LoggingTest, verifyFileSizeLimit) {
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Debug, testLogFileName, 1, 5));
-  for (auto i = 0; i < 4 * __1K__; i++) {
-    LOGDEBUG(__1KStringLiteral);
-  }
-  apache::geode::client::Log::close();
+  for (auto logFilename : testFileNames) {
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Debug, logFilename, 1, 5));
+    for (auto i = 0; i < 4 * __1K__; i++) {
+      LOGDEBUG(__1KStringLiteral);
+    }
+    apache::geode::client::Log::close();
 
-  // Original file should still be around
-  ASSERT_TRUE(boost::filesystem::exists(testLogFileName));
+    // Original file should still be around
+    ASSERT_TRUE(boost::filesystem::exists(logFilename));
 
-  // Check for 'rolled' log files.  With a 1MB file size limit and each logged
-  // string having a length of 1K chars, we should have at least one less
-  // rolled log file than the number of strings logged, i.e. 3 rolled files
-  // for 4K strings in this case.  spdlog rolled files look like
-  // <<basename>>.<<#>>.<<extension>>, so for LoggingTest.log we should find
-  // LoggingTest.1.log, LoggingTest.2.log, etc.
-  auto base = boost::filesystem::path(testLogFileName).stem();
-  auto ext = boost::filesystem::path(testLogFileName).extension();
+    // Check for 'rolled' log files.  With a 1MB file size limit and each logged
+    // string having a length of 1K chars, we should have at least one less
+    // rolled log file than the number of strings logged, i.e. 3 rolled files
+    // for 4K strings in this case.  spdlog rolled files look like
+    // <<basename>>.<<#>>.<<extension>>, so for LoggingTest.log we should find
+    // LoggingTest.1.log, LoggingTest.2.log, etc.
+    auto base = boost::filesystem::path(logFilename).stem();
+    auto ext = boost::filesystem::path(logFilename).extension();
 
-  // File size limit is treated as a "soft" limit.  If the last message in the
-  // log puts the file size over the limit, the file is rolled and the message
-  // is preserved intact, rather than truncated or split across files.  We'll
-  // assume the file size never exceeds 110% of the specified limit.
-  auto adjustedFileSizeLimit =
-      static_cast<uint32_t>(static_cast<uint64_t>(__1M__) * 11 / 10);
+    // File size limit is treated as a "soft" limit.  If the last message in the
+    // log puts the file size over the limit, the file is rolled and the message
+    // is preserved intact, rather than truncated or split across files.  We'll
+    // assume the file size never exceeds 110% of the specified limit.
+    auto adjustedFileSizeLimit =
+        static_cast<uint32_t>(static_cast<uint64_t>(__1M__) * 11 / 10);
 
-  for (auto i = 0; i < 4; i++) {
-    auto rolledLogFileName =
-        base.string() + "-" + std::to_string(i) + ext.string();
+    for (auto i = 0; i < 4; i++) {
+      auto rolledLogFileName =
+          base.string() + "-" + std::to_string(i) + ext.string();
 
-    ASSERT_TRUE(boost::filesystem::exists(rolledLogFileName));
-    ASSERT_TRUE(adjustedFileSizeLimit >
-                boost::filesystem::file_size(rolledLogFileName));
+      ASSERT_TRUE(boost::filesystem::exists(rolledLogFileName));
+      ASSERT_TRUE(adjustedFileSizeLimit >
+                  boost::filesystem::file_size(rolledLogFileName));
+    }
   }
 }
 
 TEST_F(LoggingTest, verifyDiskSpaceLimit) {
-  const int NUMBER_OF_ITERATIONS = 4 * __1K__;
-  const int DISK_SPACE_LIMIT = 2 * __1M__;
+  for (auto logFilename : testFileNames) {
+    const int NUMBER_OF_ITERATIONS = 4 * __1K__;
+    const int DISK_SPACE_LIMIT = 2 * __1M__;
 
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Debug, testLogFileName, 1, 2));
-  for (auto i = 0; i < NUMBER_OF_ITERATIONS; i++) {
-    LOGDEBUG(__1KStringLiteral);
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Debug, logFilename, 1, 2));
+    for (auto i = 0; i < NUMBER_OF_ITERATIONS; i++) {
+      LOGDEBUG(__1KStringLiteral);
+    }
+    apache::geode::client::Log::close();
+
+    // Original file should still be around
+    ASSERT_TRUE(boost::filesystem::exists(logFilename));
+
+    auto size = boost::filesystem::file_size(logFilename);
+    auto numRolledFilesFound = 0;
+    auto base = boost::filesystem::path(logFilename).stem();
+    auto ext = boost::filesystem::path(logFilename).extension();
+
+    // We wrote 4x the log file limit, and 2x the disk space limit, so
+    // there should be one 'rolled' file.  Its name should be of the form
+    // <base>-n.log, where n is some reasonable number.
+    std::map<int32_t, boost::filesystem::path> rolledFiles;
+    LoggingTest::findRolledFiles(boost::filesystem::current_path().string(),
+                                 logFilename, rolledFiles);
+    ASSERT_TRUE(rolledFiles.size() == 1);
+
+    auto rolledFile = rolledFiles.begin()->second;
+    size += boost::filesystem::file_size(rolledFile);
+
+    ASSERT_TRUE(size <= DISK_SPACE_LIMIT);
   }
-  apache::geode::client::Log::close();
-
-  // Original file should still be around
-  ASSERT_TRUE(boost::filesystem::exists(testLogFileName));
-
-  auto size = boost::filesystem::file_size(testLogFileName);
-  auto numRolledFilesFound = 0;
-  auto base = boost::filesystem::path(testLogFileName).stem();
-  auto ext = boost::filesystem::path(testLogFileName).extension();
-
-  // We wrote 4x the log file limit, and 2x the disk space limit, so
-  // there should be one 'rolled' file.  Its name should be of the form
-  // <base>-n.log, where n is some reasonable number.
-  std::map<int32_t, boost::filesystem::path> rolledFiles;
-  LoggingTest::findRolledFiles(boost::filesystem::current_path().string(),
-                               rolledFiles);
-  ASSERT_TRUE(rolledFiles.size() == 1);
-
-  auto rolledFile = rolledFiles.begin()->second;
-  size += boost::filesystem::file_size(rolledFile);
-
-  ASSERT_TRUE(size <= DISK_SPACE_LIMIT);
 }
 
 TEST_F(LoggingTest, verifyWithExistingRolledFile) {
-  LoggingTest::writeRolledLogFile(boost::filesystem::current_path(), 11);
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Debug, testLogFileName, 1, 5));
-  for (auto i = 0; i < 2 * __1K__; i++) {
-    LOGDEBUG(__1KStringLiteral);
-  }
-  apache::geode::client::Log::close();
+  for (auto logFilename : testFileNames) {
+    LoggingTest::writeRolledLogFile(boost::filesystem::current_path(),
+                                    logFilename, 11);
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Debug, logFilename, 1, 5));
+    for (auto i = 0; i < 2 * __1K__; i++) {
+      LOGDEBUG(__1KStringLiteral);
+    }
+    apache::geode::client::Log::close();
 
-  // Original file should still be around
-  ASSERT_TRUE(boost::filesystem::exists(testLogFileName));
+    // Original file should still be around
+    ASSERT_TRUE(boost::filesystem::exists(logFilename));
 
-  // Check for 'rolled' log files.  With a 1MB file size limit and each logged
-  // string having a length of 1K chars, we should have at least one less
-  // rolled log file than the number of strings logged, i.e. 3 rolled files
-  // for 4K strings in this case.  spdlog rolled files look like
-  // <<basename>>.<<#>>.<<extension>>, so for LoggingTest.log we should find
-  // LoggingTest.1.log, LoggingTest.2.log, etc.
-  auto base = boost::filesystem::path(testLogFileName).stem();
-  auto ext = boost::filesystem::path(testLogFileName).extension();
+    // Check for 'rolled' log files.  With a 1MB file size limit and each logged
+    // string having a length of 1K chars, we should have at least one less
+    // rolled log file than the number of strings logged, i.e. 3 rolled files
+    // for 4K strings in this case.  spdlog rolled files look like
+    // <<basename>>.<<#>>.<<extension>>, so for LoggingTest.log we should find
+    // LoggingTest.1.log, LoggingTest.2.log, etc.
+    auto base = boost::filesystem::path(logFilename).stem();
+    auto ext = boost::filesystem::path(logFilename).extension();
 
-  // File size limit is treated as a "soft" limit.  If the last message in the
-  // log puts the file size over the limit, the file is rolled and the message
-  // is preserved intact, rather than truncated or split across files.  We'll
-  // assume the file size never exceeds 110% of the specified limit.
-  auto adjustedFileSizeLimit =
-      static_cast<uint32_t>(static_cast<uint64_t>(__1M__) * 11 / 10);
+    // File size limit is treated as a "soft" limit.  If the last message in the
+    // log puts the file size over the limit, the file is rolled and the message
+    // is preserved intact, rather than truncated or split across files.  We'll
+    // assume the file size never exceeds 110% of the specified limit.
+    auto adjustedFileSizeLimit =
+        static_cast<uint32_t>(static_cast<uint64_t>(__1M__) * 11 / 10);
 
-  auto rolledLogFileName =
-      base.string() + "-" + std::to_string(12) + ext.string();
+    auto rolledLogFileName =
+        base.string() + "-" + std::to_string(12) + ext.string();
 
-  ASSERT_TRUE(boost::filesystem::exists(rolledLogFileName));
-  ASSERT_TRUE(adjustedFileSizeLimit >
-              boost::filesystem::file_size(rolledLogFileName));
-}
-
-void verifyWithPath(const boost::filesystem::path& path, int32_t fileSizeLimit,
-                    int64_t diskSpaceLimit) {
-  auto relativePath = path / boost::filesystem::path(testLogFileName);
-
-  ASSERT_NO_THROW(apache::geode::client::Log::init(
-      apache::geode::client::LogLevel::Debug, relativePath.string(),
-      fileSizeLimit, diskSpaceLimit));
-  for (auto i = 0; i < ((3 * fileSizeLimit) / 2) * __1K__; i++) {
-    LOGDEBUG(__1KStringLiteral);
-  }
-  apache::geode::client::Log::close();
-
-  // Original file should still be around
-  ASSERT_TRUE(boost::filesystem::exists(relativePath));
-
-  // Check for 'rolled' log files.  With a 1MB file size limit and each logged
-  // string having a length of 1K chars, we should have at least one less
-  // rolled log file than the number of strings logged, i.e. 3 rolled files
-  // for 4K strings in this case.  spdlog rolled files look like
-  // <<basename>>.<<#>>.<<extension>>, so for LoggingTest.log we should find
-  // LoggingTest.1.log, LoggingTest.2.log, etc.
-  auto base = boost::filesystem::path(relativePath).stem();
-  auto ext = boost::filesystem::path(relativePath).extension();
-
-  // File size limit is treated as a "soft" limit.  If the last message in the
-  // log puts the file size over the limit, the file is rolled and the message
-  // is preserved intact, rather than truncated or split across files.  We'll
-  // assume the file size never exceeds 110% of the specified limit.
-  auto adjustedFileSizeLimit = static_cast<uint32_t>(
-      static_cast<uint64_t>(__1M__ * fileSizeLimit) * 11 / 10);
-
-  auto rolledLogFileName =
-      relativePath.parent_path() /
-      boost::filesystem::path(base.string() + "-" + std::to_string(0) +
-                              ext.string());
-
-  if (fileSizeLimit == diskSpaceLimit) {
-    // If the limits are equal, we should *never* roll logs, just delete the
-    // current file and start over
-    ASSERT_FALSE(boost::filesystem::exists(rolledLogFileName));
-  } else {
     ASSERT_TRUE(boost::filesystem::exists(rolledLogFileName));
     ASSERT_TRUE(adjustedFileSizeLimit >
                 boost::filesystem::file_size(rolledLogFileName));
   }
-  ASSERT_TRUE(adjustedFileSizeLimit >
-              boost::filesystem::file_size(relativePath));
+}
+
+void verifyWithPath(const boost::filesystem::path& path, int32_t fileSizeLimit,
+                    int64_t diskSpaceLimit) {
+  for (auto logFilename : testFileNames) {
+    auto relativePath = path / boost::filesystem::path(logFilename);
+
+    ASSERT_NO_THROW(apache::geode::client::Log::init(
+        apache::geode::client::LogLevel::Debug, relativePath.string(),
+        fileSizeLimit, diskSpaceLimit));
+    for (auto i = 0; i < ((3 * fileSizeLimit) / 2) * __1K__; i++) {
+      LOGDEBUG(__1KStringLiteral);
+    }
+    apache::geode::client::Log::close();
+
+    // Original file should still be around
+    ASSERT_TRUE(boost::filesystem::exists(relativePath));
+
+    // Check for 'rolled' log files.  With a 1MB file size limit and each logged
+    // string having a length of 1K chars, we should have at least one less
+    // rolled log file than the number of strings logged, i.e. 3 rolled files
+    // for 4K strings in this case.  spdlog rolled files look like
+    // <<basename>>.<<#>>.<<extension>>, so for LoggingTest.log we should find
+    // LoggingTest.1.log, LoggingTest.2.log, etc.
+    auto base = boost::filesystem::path(relativePath).stem();
+    auto ext = boost::filesystem::path(relativePath).extension();
+
+    // File size limit is treated as a "soft" limit.  If the last message in the
+    // log puts the file size over the limit, the file is rolled and the message
+    // is preserved intact, rather than truncated or split across files.  We'll
+    // assume the file size never exceeds 110% of the specified limit.
+    auto adjustedFileSizeLimit = static_cast<uint32_t>(
+        static_cast<uint64_t>(__1M__ * fileSizeLimit) * 11 / 10);
+
+    auto rolledLogFileName =
+        relativePath.parent_path() /
+        boost::filesystem::path(base.string() + "-" + std::to_string(0) +
+                                ext.string());
+
+    if (fileSizeLimit == diskSpaceLimit) {
+      // If the limits are equal, we should *never* roll logs, just delete the
+      // current file and start over
+      ASSERT_FALSE(boost::filesystem::exists(rolledLogFileName));
+    } else {
+      ASSERT_TRUE(boost::filesystem::exists(rolledLogFileName));
+      ASSERT_TRUE(adjustedFileSizeLimit >
+                  boost::filesystem::file_size(rolledLogFileName));
+    }
+    ASSERT_TRUE(adjustedFileSizeLimit >
+                boost::filesystem::file_size(relativePath));
+  }
 }
 
 TEST_F(LoggingTest, verifyWithRelativePathFromCWD) {
@@ -574,23 +633,25 @@
            LogLevel::Finest,
            LogLevel::Debug,
        }) {
-    apache::geode::client::Log::init(level, testLogFileName);
+    for (auto logFilename : testFileNames) {
+      apache::geode::client::Log::init(level, logFilename);
 
-    LOGERROR("Error Message");
-    LOGWARN("Warning Message");
-    LOGINFO("Info Message");
-    LOGCONFIG("Config Message");
-    LOGFINE("Fine Message");
-    LOGFINER("Finer Message");
-    LOGFINEST("Finest Message");
-    LOGDEBUG("Debug Message");
+      LOGERROR("Error Message");
+      LOGWARN("Warning Message");
+      LOGINFO("Info Message");
+      LOGCONFIG("Config Message");
+      LOGFINE("Fine Message");
+      LOGFINER("Finer Message");
+      LOGFINEST("Finest Message");
+      LOGDEBUG("Debug Message");
 
-    int lines = LoggingTest::numOfLinesInFile(testLogFileName.c_str());
+      int lines = LoggingTest::numOfLinesInFile(logFilename);
 
-    ASSERT_TRUE(lines == LoggingTest::expectedWithBanner(level));
+      ASSERT_TRUE(lines == LoggingTest::expectedWithBanner(level));
 
-    apache::geode::client::Log::close();
-    boost::filesystem::remove(testLogFileName);
+      apache::geode::client::Log::close();
+      boost::filesystem::remove(logFilename);
+    }
   }
 }
 
@@ -612,4 +673,14 @@
 
 TEST_F(LoggingTest, countLinesNone) { verifyLineCountAtLevel(LogLevel::None); }
 
+TEST_F(LoggingTest, verifyDiskSpaceNotLeaked) {
+  for (auto logFilename : testFileNames) {
+    verifyDiskSpaceNotLeakedForFile(logFilename);
+  }
+}
+
+TEST_F(LoggingTest, verifyDiskSpaceNotLeakedWithDefaultLogName) {
+  verifyDiskSpaceNotLeakedForFile(nullptr);
+}
+
 }  // namespace