Add absl::MockClock, a gMock implementation of absl::Clock for writing tests

PiperOrigin-RevId: 1004832177
diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake
index fdd4ae1..5b24d67 100644
--- a/CMake/AbseilDll.cmake
+++ b/CMake/AbseilDll.cmake
@@ -520,6 +520,7 @@
   "status/internal/status_matchers.h"
   "strings/cordz_test_helpers.h"
   "strings/cord_test_helpers.h"
+  "time/mock_clock.h"
 )
 
 if(DEFINED CMAKE_CXX_STANDARD AND CMAKE_CXX_STANDARD_REQUIRED)
diff --git a/absl/time/BUILD.bazel b/absl/time/BUILD.bazel
index 347e24b..7408def 100644
--- a/absl/time/BUILD.bazel
+++ b/absl/time/BUILD.bazel
@@ -92,6 +92,23 @@
 )
 
 cc_library(
+    name = "mock_clock",
+    testonly = True,
+    hdrs = ["mock_clock.h"],
+    copts = ABSL_DEFAULT_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
+    visibility = ["//visibility:public"],
+    deps = [
+        ":clock_interface",
+        ":time",
+        "//absl/base:config",
+        "//absl/base:core_headers",
+        "//absl/synchronization",
+        "@googletest//:gtest",
+    ],
+)
+
+cc_library(
     name = "simulated_clock",
     testonly = True,
     srcs = [
@@ -175,6 +192,24 @@
 )
 
 cc_test(
+    name = "mock_clock_test",
+    srcs = [
+        "mock_clock_test.cc",
+    ],
+    copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
+    deps = [
+        ":clock_interface",
+        ":mock_clock",
+        ":time",
+        "//absl/base:core_headers",
+        "//absl/synchronization",
+        "@googletest//:gtest",
+        "@googletest//:gtest_main",
+    ],
+)
+
+cc_test(
     name = "simulated_clock_test",
     srcs = [
         "simulated_clock_test.cc",
diff --git a/absl/time/CMakeLists.txt b/absl/time/CMakeLists.txt
index 79b99e8..709632d 100644
--- a/absl/time/CMakeLists.txt
+++ b/absl/time/CMakeLists.txt
@@ -168,6 +168,41 @@
 
 absl_cc_library(
   NAME
+    mock_clock
+  HDRS
+    "mock_clock.h"
+  COPTS
+    ${ABSL_DEFAULT_COPTS}
+  DEPS
+    absl::clock_interface
+    absl::config
+    absl::core_headers
+    absl::synchronization
+    absl::time
+    GTest::gmock
+    GTest::gtest
+  PUBLIC
+  TESTONLY
+)
+
+absl_cc_test(
+  NAME
+    mock_clock_test
+  SRCS
+    "mock_clock_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
+  DEPS
+    absl::clock_interface
+    absl::core_headers
+    absl::mock_clock
+    absl::synchronization
+    absl::time
+    GTest::gmock_main
+)
+
+absl_cc_library(
+  NAME
     simulated_clock
   HDRS
     "simulated_clock.h"
diff --git a/absl/time/mock_clock.h b/absl/time/mock_clock.h
new file mode 100644
index 0000000..3a1d151
--- /dev/null
+++ b/absl/time/mock_clock.h
@@ -0,0 +1,76 @@
+// Copyright 2026 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// 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.
+//
+// -----------------------------------------------------------------------------
+// File: mock_clock.h
+// -----------------------------------------------------------------------------
+
+#ifndef ABSL_TIME_MOCK_CLOCK_H_
+#define ABSL_TIME_MOCK_CLOCK_H_
+
+#include "gmock/gmock.h"
+#include "absl/base/config.h"
+#include "absl/base/macros.h"
+#include "absl/synchronization/mutex.h"
+#include "absl/time/clock_interface.h"
+#include "absl/time/time.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+
+// A gMock implementation of absl::Clock.
+//
+// This class is appropriate for testing single-threaded uses of
+// absl::Clock, particularly when calling
+// absl::Clock::Sleep().  absl::MockClock::Sleep() (by default) simply
+// advances simulated time and returns.
+//
+// For multithreaded testing, consider using absl::SimulatedClock.
+class MockClock : public absl::Clock {
+ public:
+  explicit MockClock(absl::Time now) : now_(now) {
+    ON_CALL(*this, TimeNow())
+        .WillByDefault(testing::Invoke(this, &MockClock::current_time));
+    ON_CALL(*this, Sleep(testing::A<absl::Duration>()))
+        .WillByDefault(testing::Invoke(this, &MockClock::SleepTime));
+    ON_CALL(*this, SleepUntil(testing::A<absl::Time>()))
+        .WillByDefault(testing::Invoke(this, &MockClock::SetTime));
+  }
+
+  MockClock() : MockClock(absl::UnixEpoch()) {}
+
+  MOCK_METHOD(absl::Time, TimeNow, (), (override));
+  MOCK_METHOD(void, Sleep, (absl::Duration d), (override));
+  MOCK_METHOD(void, SleepUntil, (absl::Time wakeup_time), (override));
+  MOCK_METHOD(bool, AwaitWithDeadline,
+              (absl::Mutex* mu, const absl::Condition& cond,
+               absl::Time wakeup_time),
+              (override));
+
+  absl::Time current_time() const { return now_; }
+
+  // Set the mock time to 'timestamp'.
+  void SetTime(absl::Time timestamp) { now_ = timestamp; }
+
+  // Advance the mock time and return immediately.
+  void SleepTime(absl::Duration d) { now_ += d; }
+
+ private:
+  absl::Time now_;  // The mock time.
+};
+
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+#endif  // ABSL_TIME_MOCK_CLOCK_H_
diff --git a/absl/time/mock_clock_test.cc b/absl/time/mock_clock_test.cc
new file mode 100644
index 0000000..006f232
--- /dev/null
+++ b/absl/time/mock_clock_test.cc
@@ -0,0 +1,42 @@
+// Copyright 2026 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// 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 "absl/time/mock_clock.h"
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "absl/time/time.h"
+
+namespace {
+
+using ::testing::A;
+
+TEST(MockClock, SatisfiesExpectations) {
+  absl::MockClock mock_clock;
+  const absl::Duration kDuration = absl::Seconds(100);
+  const absl::Time kWakeupTime = absl::UnixEpoch() + kDuration;
+  EXPECT_CALL(mock_clock, TimeNow()).Times(2);
+  EXPECT_CALL(mock_clock, Sleep(A<absl::Duration>()));
+  EXPECT_CALL(mock_clock, SleepUntil(A<absl::Time>()));
+
+  EXPECT_EQ(absl::UnixEpoch(), mock_clock.TimeNow());
+  mock_clock.Sleep(kDuration);
+  EXPECT_EQ(kWakeupTime, mock_clock.TimeNow());
+  mock_clock.SleepUntil(kWakeupTime);
+
+  absl::MockClock mock_clock_init(absl::UnixEpoch() + kDuration);
+  EXPECT_EQ(mock_clock_init.current_time(), absl::UnixEpoch() + kDuration);
+}
+
+}  // namespace