Use static functions instead of a singleton class for mtime manipulation.

PiperOrigin-RevId: 689335964
Change-Id: I62b1d8705e4e015cf6f7ab1188e93bc4f49d4446
diff --git a/src/main/cpp/archive_utils.cc b/src/main/cpp/archive_utils.cc
index a86d803..f999e91 100644
--- a/src/main/cpp/archive_utils.cc
+++ b/src/main/cpp/archive_utils.cc
@@ -25,9 +25,9 @@
 #include "src/main/cpp/util/errors.h"
 #include "src/main/cpp/util/exit_code.h"
 #include "src/main/cpp/util/file.h"
+#include "src/main/cpp/util/file_platform.h"
 #include "src/main/cpp/util/logging.h"
 #include "src/main/cpp/util/path.h"
-#include "src/main/cpp/util/strings.h"
 #include "third_party/ijar/zip.h"
 
 namespace blaze {
@@ -170,11 +170,9 @@
     }
     blaze_util::Path install_dir(install_base);
     // Check that all files are present and have timestamps from BlessFiles().
-    std::unique_ptr<blaze_util::IFileMtime> mtime(
-        blaze_util::CreateFileMtime());
     for (const auto &it : archive_contents) {
       blaze_util::Path path = install_dir.GetRelative(it);
-      if (!mtime->IsUntampered(path)) {
+      if (!IsUntampered(path)) {
         BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
             << "corrupt installation: file '" << path.AsPrintablePath()
             << "' is missing or modified.  Please remove '" << install_base
@@ -262,7 +260,6 @@
   // Walks the temporary directory recursively and collects full file paths.
   blaze_util::GetAllFilesUnder(embedded_binaries, &extracted_files);
 
-  std::unique_ptr<blaze_util::IFileMtime> mtime(blaze_util::CreateFileMtime());
   set<blaze_util::Path> synced_directories;
   for (const auto &f : extracted_files) {
     blaze_util::Path it(f);
@@ -274,7 +271,7 @@
     // releases so that the metadata cache knows that the files may have
     // changed. This is essential for the correctness of actions that use
     // embedded binaries as artifacts.
-    if (!mtime->SetToDistantFuture(it)) {
+    if (!SetMtimeToDistantFuture(it)) {
       string err = blaze_util::GetLastErrorString();
       BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
           << "failed to set timestamp on '" << it.AsPrintablePath()
diff --git a/src/main/cpp/blaze.cc b/src/main/cpp/blaze.cc
index 94c3e2a..2e72cd7 100644
--- a/src/main/cpp/blaze.cc
+++ b/src/main/cpp/blaze.cc
@@ -26,7 +26,6 @@
 #include "src/main/cpp/blaze.h"
 
 #include <assert.h>
-#include <ctype.h>
 #include <fcntl.h>
 #include <grpc/grpc.h>
 #include <grpcpp/channel.h>
@@ -1008,11 +1007,9 @@
     }
 
     // Update the mtime of the install base so that cleanup tools can
-    // find install bases that haven't been used for a long time
-    std::unique_ptr<blaze_util::IFileMtime> mtime(
-        blaze_util::CreateFileMtime());
-    // Ignore permissions errors (i.e. if the install base is not writable):
-    if (!mtime->SetToNowIfPossible(
+    // find install bases that haven't been used for a long time.
+    // Ignore permissions errors (i.e. if the install base is not writable).
+    if (!SetMtimeToNowIfPossible(
             blaze_util::Path(startup_options.install_base))) {
       string err = GetLastErrorString();
       BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
diff --git a/src/main/cpp/util/file_platform.h b/src/main/cpp/util/file_platform.h
index d885d35..3e0eb3d 100644
--- a/src/main/cpp/util/file_platform.h
+++ b/src/main/cpp/util/file_platform.h
@@ -17,7 +17,6 @@
 
 #include <time.h>
 
-#include <cinttypes>
 #include <string>
 #include <vector>
 
@@ -29,40 +28,26 @@
 
 IPipe* CreatePipe();
 
-// Class to query/manipulate the last modification time (mtime) of files.
-class IFileMtime {
- public:
-  virtual ~IFileMtime() {}
+// Checks if `path` is a file/directory in the embedded tools directory that
+// was not tampered with.
+// Returns true if `path` is a directory or directory symlink, or if `path` is
+// a file with an mtime in the distant future.
+// Returns false otherwise, or if querying the information failed.
+bool IsUntampered(const Path &path);
 
-  // Checks if `path` is a file/directory in the embedded tools directory that
-  // was not tampered with.
-  // Returns true if `path` is a directory or directory symlink, or if `path` is
-  // a file with an mtime in the distant future.
-  // Returns false otherwise, or if querying the information failed.
-  // TODO(laszlocsomor): move this function, and with it the whole IFileMtime
-  // class into blaze_util_<platform>.cc, because it is Bazel-specific logic,
-  // not generic file-handling logic.
-  virtual bool IsUntampered(const Path &path) = 0;
+// Sets the mtime of file under `path` to the current time.
+// Returns true if the mtime was changed successfully.
+bool SetMtimeToNow(const Path &path);
 
-  // Sets the mtime of file under `path` to the current time.
-  // Returns true if the mtime was changed successfully.
-  virtual bool SetToNow(const Path &path) = 0;
+// Attempt to set the mtime of file under `path` to the current time.
+// Returns true if the mtime was changed successfully OR if setting the mtime
+// failed due to permissions errors.
+bool SetMtimeToNowIfPossible(const Path &path);
 
-  // Attempt to set the mtime of file under `path` to the current time.
-  //
-  // Returns true if the mtime was changed successfully OR if setting the mtime
-  // failed due to permissions errors.
-  virtual bool SetToNowIfPossible(const Path &path) = 0;
-
-  // Sets the mtime of file under `path` to the distant future.
-  // "Distant future" should be on the order of some years into the future, like
-  // a decade.
-  // Returns true if the mtime was changed successfully.
-  virtual bool SetToDistantFuture(const Path &path) = 0;
-};
-
-// Creates a platform-specific implementation of `IFileMtime`.
-IFileMtime *CreateFileMtime();
+// Sets the mtime of file under `path` to the distant future, which should be
+// on the order of a decade.
+// Returns true if the mtime was changed successfully.
+bool SetMtimeToDistantFuture(const Path &path);
 
 #if defined(_WIN32) || defined(__CYGWIN__)
 // We cannot include <windows.h> because it #defines many symbols that conflict
diff --git a/src/main/cpp/util/file_posix.cc b/src/main/cpp/util/file_posix.cc
index 30ebf59..117dfc1 100644
--- a/src/main/cpp/util/file_posix.cc
+++ b/src/main/cpp/util/file_posix.cc
@@ -12,8 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/main/cpp/util/file_platform.h"
-
 #include <dirent.h>  // DIR, dirent, opendir, closedir
 #include <errno.h>
 #include <fcntl.h>   // O_RDONLY
@@ -21,19 +19,19 @@
 #include <stdlib.h>  // getenv
 #include <string.h>  // strncmp
 #include <sys/stat.h>
+#include <time.h>
 #include <unistd.h>  // access, open, close, fsync
 #include <utime.h>   // utime
 
 #include <string>
-#include <vector>
 
 #include "src/main/cpp/util/errors.h"
 #include "src/main/cpp/util/exit_code.h"
 #include "src/main/cpp/util/file.h"
+#include "src/main/cpp/util/file_platform.h"
 #include "src/main/cpp/util/logging.h"
 #include "src/main/cpp/util/path.h"
 #include "src/main/cpp/util/path_platform.h"
-#include "src/main/cpp/util/strings.h"
 
 namespace blaze_util {
 
@@ -447,50 +445,46 @@
 
 void SyncFile(const Path &path) { SyncFile(path.AsNativePath()); }
 
-class PosixFileMtime : public IFileMtime {
- public:
-  PosixFileMtime()
-      : near_future_(GetFuture(9)),
-        distant_future_({GetFuture(10), GetFuture(10)}) {}
+static time_t GetNow() {
+  time_t result = time(nullptr);
+  if (result == -1) {
+    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
+        << "time(nullptr) failed: " << GetLastErrorString();
+  }
+  return result;
+}
 
-  bool IsUntampered(const Path &path) override;
-  bool SetToNow(const Path &path) override;
-  bool SetToNowIfPossible(const Path &path) override;
-  bool SetToDistantFuture(const Path &path) override;
+static time_t GetYearsInFuture(int years) {
+  return GetNow() + 3600 * 24 * 365 * years;
+}
 
- private:
-  // 9 years in the future.
-  const time_t near_future_;
-  // 10 years in the future.
-  const struct utimbuf distant_future_;
+static bool SetMtime(const Path &path, time_t mtime) {
+  struct utimbuf times = {mtime, mtime};
+  return utime(path.AsNativePath().c_str(), &times) == 0;
+}
 
-  static bool Set(const Path &path, const struct utimbuf &mtime);
-  static time_t GetNow();
-  static time_t GetFuture(unsigned int years);
-};
+static const time_t kNearFuture = GetYearsInFuture(9);
+static const time_t kDistantFuture = GetYearsInFuture(10);
 
-bool PosixFileMtime::IsUntampered(const Path &path) {
+bool IsUntampered(const Path &path) {
   struct stat buf;
   if (stat(path.AsNativePath().c_str(), &buf)) {
     return false;
   }
 
-  // Compare the mtime with `near_future_`, not with `GetNow()` or
-  // `distant_future_`.
-  // This way we don't need to call GetNow() every time we want to compare and
-  // we also don't need to worry about potentially unreliable time equality
-  // check (in case it uses floats or something crazy).
-  return S_ISDIR(buf.st_mode) || (buf.st_mtime > near_future_);
+  // Compare with kNearFuture, not kDistantFuture.
+  // This way we don't need to worry about a potentially unreliable equality
+  // check if precision isn't preserved.
+  return S_ISDIR(buf.st_mode) || (buf.st_mtime > kNearFuture);
 }
 
-bool PosixFileMtime::SetToNow(const Path &path) {
-  time_t now(GetNow());
-  struct utimbuf times = {now, now};
-  return Set(path, times);
+bool SetMtimeToNow(const Path &path) {
+  time_t now = GetNow();
+  return SetMtime(path, now);
 }
 
-bool PosixFileMtime::SetToNowIfPossible(const Path &path) {
-  bool okay = this->SetToNow(path);
+bool SetMtimeToNowIfPossible(const Path &path) {
+  bool okay = SetMtimeToNow(path);
   if (!okay) {
     // `SetToNow`/`Set` are backed by `utime(2)` which can return `EROFS` and
     // `EPERM` when there's a permissions issue:
@@ -502,29 +496,10 @@
   return okay;
 }
 
-bool PosixFileMtime::SetToDistantFuture(const Path &path) {
-  return Set(path, distant_future_);
+bool SetMtimeToDistantFuture(const Path &path) {
+  return SetMtime(path, kDistantFuture);
 }
 
-bool PosixFileMtime::Set(const Path &path, const struct utimbuf &mtime) {
-  return utime(path.AsNativePath().c_str(), &mtime) == 0;
-}
-
-time_t PosixFileMtime::GetNow() {
-  time_t result = time(nullptr);
-  if (result == -1) {
-    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
-        << "time(nullptr) failed: " << GetLastErrorString();
-  }
-  return result;
-}
-
-time_t PosixFileMtime::GetFuture(unsigned int years) {
-  return GetNow() + 3600 * 24 * 365 * years;
-}
-
-IFileMtime *CreateFileMtime() { return new PosixFileMtime(); }
-
 // mkdir -p path. Returns true if the path was created or already exists and
 // could
 // be chmod-ed to exactly the given permissions. If final part of the path is a
diff --git a/src/main/cpp/util/file_windows.cc b/src/main/cpp/util/file_windows.cc
index 893a11e..555f935 100644
--- a/src/main/cpp/util/file_windows.cc
+++ b/src/main/cpp/util/file_windows.cc
@@ -14,7 +14,6 @@
 #ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN
 #endif
-#include <ctype.h>   // isalpha
 #include <wchar.h>   // wcslen
 #include <wctype.h>  // iswalpha
 #include <windows.h>
@@ -28,7 +27,6 @@
 #include "src/main/cpp/util/exit_code.h"
 #include "src/main/cpp/util/file.h"
 #include "src/main/cpp/util/logging.h"
-#include "src/main/cpp/util/path.h"
 #include "src/main/cpp/util/path_platform.h"
 #include "src/main/cpp/util/strings.h"
 #include "src/main/native/windows/file.h"
@@ -108,28 +106,54 @@
   return new WindowsPipe(read_handle, write_handle);
 }
 
-class WindowsFileMtime : public IFileMtime {
- public:
-  WindowsFileMtime()
-      : near_future_(GetFuture(9)), distant_future_(GetFuture(10)) {}
+static FILETIME GetNow() {
+  FILETIME now;
+  GetSystemTimeAsFileTime(&now);
+  return now;
+}
 
-  bool IsUntampered(const Path& path) override;
-  bool SetToNow(const Path& path) override;
-  bool SetToNowIfPossible(const Path& path) override;
-  bool SetToDistantFuture(const Path& path) override;
+static FILETIME GetYearsInFuture(WORD years) {
+  FILETIME result;
+  GetSystemTimeAsFileTime(&result);
 
- private:
-  // 9 years in the future.
-  const FILETIME near_future_;
-  // 10 years in the future.
-  const FILETIME distant_future_;
+  // 1 year in FILETIME.
+  constexpr ULONGLONG kOneYear = 365ULL * 24 * 60 * 60 * 10000000;
 
-  static FILETIME GetNow();
-  static FILETIME GetFuture(WORD years);
-  static bool Set(const Path& path, FILETIME time);
-};
+  ULARGE_INTEGER result_value;
+  result_value.LowPart = result.dwLowDateTime;
+  result_value.HighPart = result.dwHighDateTime;
+  result_value.QuadPart += kOneYear * years;
+  result.dwLowDateTime = result_value.LowPart;
+  result.dwHighDateTime = result_value.HighPart;
+  return result;
+}
 
-bool WindowsFileMtime::IsUntampered(const Path& path) {
+static bool SetMtime(const Path& path, FILETIME time) {
+  AutoHandle handle(::CreateFileW(
+      /* lpFileName */ path.AsNativePath().c_str(),
+      /* dwDesiredAccess */ FILE_WRITE_ATTRIBUTES,
+      /* dwShareMode */ FILE_SHARE_READ,
+      /* lpSecurityAttributes */ nullptr,
+      /* dwCreationDisposition */ OPEN_EXISTING,
+      /* dwFlagsAndAttributes */
+      IsDirectoryW(path.AsNativePath())
+          ? (FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS)
+          : FILE_ATTRIBUTE_NORMAL,
+      /* hTemplateFile */ nullptr));
+  if (!handle.IsValid()) {
+    return false;
+  }
+  return ::SetFileTime(
+             /* hFile */ handle,
+             /* lpCreationTime */ nullptr,
+             /* lpLastAccessTime */ nullptr,
+             /* lpLastWriteTime */ &time) == TRUE;
+}
+
+static const FILETIME kNearFuture = GetYearsInFuture(9);
+static const FILETIME kDistantFuture = GetYearsInFuture(10);
+
+bool IsUntampered(const Path& path) {
   if (path.IsEmpty() || path.IsNull()) {
     return false;
   }
@@ -166,22 +190,17 @@
       return false;
     }
 
-    // Compare the mtime with `near_future_`, not with `GetNow()` or
-    // `distant_future_`.
-    // This way we don't need to call GetNow() every time we want to compare
-    // (and thus convert a SYSTEMTIME to FILETIME), and we also don't need to
-    // worry about potentially unreliable FILETIME equality check (in case it
-    // uses floats or something crazy).
-    return CompareFileTime(&near_future_, &info.ftLastWriteTime) == -1;
+    // Compare with kNearFuture, not with kDistantFuture.
+    // This way we don't need to worry about a potentially unreliable equality
+    // check if precision isn't preserved.
+    return CompareFileTime(&kNearFuture, &info.ftLastWriteTime) == -1;
   }
 }
 
-bool WindowsFileMtime::SetToNow(const Path& path) {
-  return Set(path, GetNow());
-}
+bool SetMtimeToNow(const Path& path) { return SetMtime(path, GetNow()); }
 
-bool WindowsFileMtime::SetToNowIfPossible(const Path& path) {
-  bool okay = this->SetToNow(path);
+bool SetMtimeToNowIfPossible(const Path& path) {
+  bool okay = SetMtimeToNow(path);
   if (!okay) {
     // `SetToNow` is backed by `CreateFileW` + `SetFileTime`; the former can
     // return `ERROR_ACCESS_DENIED` if there's a permissions issue:
@@ -193,56 +212,10 @@
   return okay;
 }
 
-bool WindowsFileMtime::SetToDistantFuture(const Path& path) {
-  return Set(path, distant_future_);
+bool SetMtimeToDistantFuture(const Path& path) {
+  return SetMtime(path, kDistantFuture);
 }
 
-bool WindowsFileMtime::Set(const Path& path, FILETIME time) {
-  AutoHandle handle(::CreateFileW(
-      /* lpFileName */ path.AsNativePath().c_str(),
-      /* dwDesiredAccess */ FILE_WRITE_ATTRIBUTES,
-      /* dwShareMode */ FILE_SHARE_READ,
-      /* lpSecurityAttributes */ nullptr,
-      /* dwCreationDisposition */ OPEN_EXISTING,
-      /* dwFlagsAndAttributes */
-      IsDirectoryW(path.AsNativePath())
-          ? (FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS)
-          : FILE_ATTRIBUTE_NORMAL,
-      /* hTemplateFile */ nullptr));
-  if (!handle.IsValid()) {
-    return false;
-  }
-  return ::SetFileTime(
-             /* hFile */ handle,
-             /* lpCreationTime */ nullptr,
-             /* lpLastAccessTime */ nullptr,
-             /* lpLastWriteTime */ &time) == TRUE;
-}
-
-FILETIME WindowsFileMtime::GetNow() {
-  FILETIME now;
-  GetSystemTimeAsFileTime(&now);
-  return now;
-}
-
-FILETIME WindowsFileMtime::GetFuture(WORD years) {
-  FILETIME result;
-  GetSystemTimeAsFileTime(&result);
-
-  // 1 year in FILETIME.
-  constexpr ULONGLONG kOneYear = 365ULL * 24 * 60 * 60 * 10000000;
-
-  ULARGE_INTEGER result_value;
-  result_value.LowPart = result.dwLowDateTime;
-  result_value.HighPart = result.dwHighDateTime;
-  result_value.QuadPart += kOneYear * years;
-  result.dwLowDateTime = result_value.LowPart;
-  result.dwHighDateTime = result_value.HighPart;
-  return result;
-}
-
-IFileMtime* CreateFileMtime() { return new WindowsFileMtime(); }
-
 static bool OpenFileForReading(const Path& path, HANDLE* result) {
   *result = ::CreateFileW(
       /* lpFileName */ path.AsNativePath().c_str(),
diff --git a/src/main/cpp/util/path_posix.cc b/src/main/cpp/util/path_posix.cc
index d52855c..1a77c13 100644
--- a/src/main/cpp/util/path_posix.cc
+++ b/src/main/cpp/util/path_posix.cc
@@ -12,18 +12,18 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/main/cpp/util/path_platform.h"
-
 #include <limits.h>  // PATH_MAX
-
 #include <stdlib.h>  // getenv
 #include <string.h>  // strncmp
 #include <unistd.h>  // access, open, close, fsync
-#include "src/main/cpp/util/errors.h"
+
+#include <vector>
+
 #include "src/main/cpp/util/exit_code.h"
 #include "src/main/cpp/util/file_platform.h"
 #include "src/main/cpp/util/logging.h"
 #include "src/main/cpp/util/path.h"
+#include "src/main/cpp/util/path_platform.h"
 
 namespace blaze_util {
 
diff --git a/src/test/cpp/blaze_archive_test.cc b/src/test/cpp/blaze_archive_test.cc
index ef149aa..b7a58db 100644
--- a/src/test/cpp/blaze_archive_test.cc
+++ b/src/test/cpp/blaze_archive_test.cc
@@ -23,7 +23,6 @@
 #include "src/main/cpp/bazel_startup_options.h"
 #include "googlemock/include/gmock/gmock.h"
 #include "googletest/include/gtest/gtest.h"
-#include "absl/strings/escaping.h"
 #include "src/main/cpp/blaze.h"
 #include "src/main/cpp/blaze_util_platform.h"
 #include "src/main/cpp/util/file_platform.h"
@@ -139,10 +138,9 @@
   EXPECT_THAT(file::GetContents(baz_path, file::Defaults()),
               IsOkAndHolds("baz content"));
 
-  std::unique_ptr<blaze_util::IFileMtime> mtime(blaze_util::CreateFileMtime());
-  EXPECT_TRUE(mtime->IsUntampered(blaze_util::Path(foo_path)));
-  EXPECT_TRUE(mtime->IsUntampered(blaze_util::Path(bar_path)));
-  EXPECT_TRUE(mtime->IsUntampered(blaze_util::Path(baz_path)));
+  EXPECT_TRUE(IsUntampered(blaze_util::Path(foo_path)));
+  EXPECT_TRUE(IsUntampered(blaze_util::Path(bar_path)));
+  EXPECT_TRUE(IsUntampered(blaze_util::Path(baz_path)));
 
   const auto far_future = absl::Now() + absl::Hours(24 * 365 * 9);
   EXPECT_THAT(get_mtime(foo_path), IsOkAndHolds(Gt(far_future)));
diff --git a/src/test/cpp/util/file_test.cc b/src/test/cpp/util/file_test.cc
index 40062f8..5522765 100644
--- a/src/test/cpp/util/file_test.cc
+++ b/src/test/cpp/util/file_test.cc
@@ -11,6 +11,8 @@
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 // limitations under the License.
+#include "src/main/cpp/util/file.h"
+
 #include <stdio.h>
 #include <string.h>
 
@@ -18,9 +20,8 @@
 #include <map>
 #include <memory>  // unique_ptr
 #include <thread>  // NOLINT (to silence Google-internal linter)
-#include <vector>
 
-#include "src/main/cpp/util/file.h"
+#include "src/main/cpp/util/file_platform.h"
 #include "src/main/cpp/util/path.h"
 #include "src/main/cpp/util/path_platform.h"
 #include "src/test/cpp/util/test_util.h"
@@ -156,32 +157,31 @@
   ASSERT_NE(tempdir_cstr[0], 0);
   Path tempdir(tempdir_cstr);
 
-  std::unique_ptr<IFileMtime> mtime(CreateFileMtime());
   // Assert that a directory is always untampered with. (We do
   // not care about directories' mtimes.)
-  ASSERT_TRUE(mtime->IsUntampered(tempdir));
+  ASSERT_TRUE(IsUntampered(tempdir));
   // Create a new file, assert its mtime is not in the future.
   Path file = tempdir.GetRelative("foo.txt");
   ASSERT_TRUE(WriteFile("hello", 5, file));
-  ASSERT_FALSE(mtime->IsUntampered(file));
+  ASSERT_FALSE(IsUntampered(file));
   // Set the file's mtime to the future, assert that it's so.
-  ASSERT_TRUE(mtime->SetToDistantFuture(file));
-  ASSERT_TRUE(mtime->IsUntampered(file));
+  ASSERT_TRUE(SetMtimeToDistantFuture(file));
+  ASSERT_TRUE(IsUntampered(file));
   // Overwrite the file, resetting its mtime, assert that
   // IsUntampered notices.
   ASSERT_TRUE(WriteFile("world", 5, file));
-  ASSERT_FALSE(mtime->IsUntampered(file));
+  ASSERT_FALSE(IsUntampered(file));
   // Set it to the future again so we can reset it using SetToNow.
-  ASSERT_TRUE(mtime->SetToDistantFuture(file));
-  ASSERT_TRUE(mtime->IsUntampered(file));
+  ASSERT_TRUE(SetMtimeToDistantFuture(file));
+  ASSERT_TRUE(IsUntampered(file));
   // Assert that SetToNow resets the timestamp.
-  ASSERT_TRUE(mtime->SetToNow(file));
-  ASSERT_FALSE(mtime->IsUntampered(file));
+  ASSERT_TRUE(SetMtimeToNow(file));
+  ASSERT_FALSE(IsUntampered(file));
   // Delete the file and assert that we can no longer set or query its mtime.
   ASSERT_TRUE(UnlinkPath(file));
-  ASSERT_FALSE(mtime->SetToNow(file));
-  ASSERT_FALSE(mtime->SetToDistantFuture(file));
-  ASSERT_FALSE(mtime->IsUntampered(file));
+  ASSERT_FALSE(SetMtimeToNow(file));
+  ASSERT_FALSE(SetMtimeToDistantFuture(file));
+  ASSERT_FALSE(IsUntampered(file));
 }
 
 TEST(FileTest, TestCreateTempDir) {
diff --git a/src/test/cpp/util/file_windows_test.cc b/src/test/cpp/util/file_windows_test.cc
index e357170..5869f93 100644
--- a/src/test/cpp/util/file_windows_test.cc
+++ b/src/test/cpp/util/file_windows_test.cc
@@ -15,23 +15,17 @@
 #ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN
 #endif
-#include <windows.h>
-
 #include <stdio.h>
-#include <string.h>
+#include <windows.h>
 
 #include <algorithm>
 #include <memory>
-#include <string>
 
 #include "gtest/gtest.h"
-#include "src/main/cpp/util/file.h"
 #include "src/main/cpp/util/file_platform.h"
 #include "src/main/cpp/util/path.h"
 #include "src/main/cpp/util/path_platform.h"
-#include "src/main/cpp/util/strings.h"
 #include "src/main/native/windows/file.h"
-#include "src/main/native/windows/util.h"
 #include "src/test/cpp/util/test_util.h"
 #include "src/test/cpp/util/windows_test_util.h"
 
@@ -325,20 +319,19 @@
   Path target = tempdir.GetRelative("target" TOSTRING(__LINE__));
   EXPECT_TRUE(CreateDirectoryW(target.AsNativePath().c_str(), nullptr));
 
-  std::unique_ptr<IFileMtime> mtime(CreateFileMtime());
   // Assert that a directory is always a good embedded binary. (We do not care
   // about directories' mtimes.)
-  ASSERT_TRUE(mtime.get()->IsUntampered(target));
+  ASSERT_TRUE(IsUntampered(target));
   // Assert that junctions whose target exists are "good" embedded binaries.
   Path sym = tempdir.GetRelative("junc" TOSTRING(__LINE__));
   EXPECT_EQ(CreateJunction(sym.AsNativePath(), target.AsNativePath(), nullptr),
             CreateJunctionResult::kSuccess);
-  ASSERT_TRUE(mtime.get()->IsUntampered(sym));
+  ASSERT_TRUE(IsUntampered(sym));
   // Assert that checking fails for non-existent directories and dangling
   // junctions.
   EXPECT_TRUE(RemoveDirectoryW(target.AsNativePath().c_str()));
-  ASSERT_FALSE(mtime.get()->IsUntampered(target));
-  ASSERT_FALSE(mtime.get()->IsUntampered(sym));
+  ASSERT_FALSE(IsUntampered(target));
+  ASSERT_FALSE(IsUntampered(sym));
 }
 
 }  // namespace blaze_util