Index: remoting/host/ack_or_timeout_reporter_unittest.cc |
diff --git a/remoting/host/ack_or_timeout_reporter_unittest.cc b/remoting/host/ack_or_timeout_reporter_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..fe0f309c2e5b636b8e5f181a64771ea68e520f20 |
--- /dev/null |
+++ b/remoting/host/ack_or_timeout_reporter_unittest.cc |
@@ -0,0 +1,130 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "remoting/host/ack_or_timeout_reporter.h" |
+ |
+#include "base/bind.h" |
+#include "base/location.h" |
+#include "base/memory/weak_ptr.h" |
+#include "base/sequenced_task_runner.h" |
+#include "base/time/time.h" |
+#include "remoting/host/mock_callback.h" |
+ |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace remoting { |
+ |
+class MockSequencedTaskRunner : public base::SequencedTaskRunner { |
+ public: |
+ MOCK_METHOD3(PostDelayedTask, bool( |
+ const tracked_objects::Location&, |
+ const base::Closure&, |
+ base::TimeDelta)); |
+ |
+ MOCK_CONST_METHOD0(RunsTasksOnCurrentThread, bool()); |
+ |
+ MOCK_METHOD3(PostNonNestableDelayedTask, bool( |
+ const tracked_objects::Location&, |
+ const base::Closure&, |
+ base::TimeDelta)); |
+ |
+ private: |
+ ~MockSequencedTaskRunner() { } |
+}; |
+ |
+const base::TimeDelta kTestTimeout = base::TimeDelta::FromSeconds(123); |
+ |
+static void CallReportAckOrTimeoutAndCaptureCallbacks( |
+ const base::Callback<void(AckOrTimeout)>& ack_or_timeout_callback, |
+ /* out */ base::Closure* captured_ack_callback, |
+ /* out */ base::Closure* captured_timeout_callback) { |
+ // Setup mocks. |
+ MockCallback<void(const base::Closure&)> mock_function_that_acks; |
+ scoped_refptr<MockSequencedTaskRunner> mock_task_runner( |
+ new MockSequencedTaskRunner()); |
+ |
+ // Capture |captured_ack_callback| and |captured_timeout_callback|. |
+ EXPECT_CALL(mock_function_that_acks, Run(testing::_)) |
+ .WillOnce(testing::SaveArg<0>(captured_ack_callback)); |
+ EXPECT_CALL(*mock_task_runner, |
+ PostDelayedTask(testing::_, testing::_, kTestTimeout)) |
+ .WillOnce(testing::DoAll( |
+ testing::SaveArg<1>(captured_timeout_callback), |
+ testing::Return(true))); |
+ |
+ // Call function-under-test. |
+ ReportAckOrTimeout( |
+ mock_function_that_acks.GetCallback(), |
+ kTestTimeout, |
+ mock_task_runner, |
+ ack_or_timeout_callback); |
+} |
+ |
+TEST(AckOrTimeoutReporterTest, FirstAckCalledAsynchronously) { |
+ MockCallback<void(AckOrTimeout)> mock_ack_or_timeout_callback; |
+ base::Closure captured_ack_callback; |
+ base::Closure captured_timeout_callback; |
+ |
+ // |mock_ack_or_timeout_callback| should not be called until |
+ // |captured_ack_callback| or |captured_timeout_callback| is called. |
+ EXPECT_CALL(mock_ack_or_timeout_callback, Run(testing::_)).Times(0); |
+ |
+ CallReportAckOrTimeoutAndCaptureCallbacks( |
+ mock_ack_or_timeout_callback.GetCallback(), |
+ &captured_ack_callback, |
+ &captured_timeout_callback); |
+ |
+ { |
+ // |mock_ack_or_timeout_callback| should be called as soon as |
+ // |captured_ack_callback| runs. |
+ EXPECT_CALL(mock_ack_or_timeout_callback, Run(AckOrTimeout::Ack)); |
+ captured_ack_callback.Run(); |
+ } |
+ |
+ // |ack_or_timeout_callback| should be dropped after being called once. |
+ // This is expectation is depended on by |MinimumHeartbeatSupporter| to |
+ // manage its lifetime (i.e. release references to self after getting an |
+ // ack). |
+ EXPECT_FALSE(mock_ack_or_timeout_callback.HasRemainingCallbacks()); |
+ |
+ // It should be safe to call the callbacks multiple times. |
+ captured_ack_callback.Run(); |
+ captured_timeout_callback.Run(); |
+} |
+ |
+TEST(AckOrTimeoutReporterTest, FirstTimeoutCalledAsynchronously) { |
+ MockCallback<void(AckOrTimeout)> mock_ack_or_timeout_callback; |
+ base::Closure captured_ack_callback; |
+ base::Closure captured_timeout_callback; |
+ |
+ // |mock_ack_or_timeout_callback| should not be called until |
+ // |captured_ack_callback| or |captured_timeout_callback| is called. |
+ EXPECT_CALL(mock_ack_or_timeout_callback, Run(testing::_)).Times(0); |
+ |
+ CallReportAckOrTimeoutAndCaptureCallbacks( |
+ mock_ack_or_timeout_callback.GetCallback(), |
+ &captured_ack_callback, |
+ &captured_timeout_callback); |
+ |
+ { |
+ // |mock_ack_or_timeout_callback| should be called as soon as |
+ // |captured_ack_callback| runs. |
+ EXPECT_CALL(mock_ack_or_timeout_callback, Run(AckOrTimeout::Timeout)); |
+ captured_timeout_callback.Run(); |
+ } |
+ |
+ // |ack_or_timeout_callback| should be dropped after being called once. |
+ // This is expectation is depended on by |MinimumHeartbeatSupporter| to |
+ // manage its lifetime (i.e. release references to self after getting an |
+ // ack). |
+ EXPECT_FALSE(mock_ack_or_timeout_callback.HasRemainingCallbacks()); |
+ |
+ // It should be safe to call the callbacks multiple times. |
+ captured_ack_callback.Run(); |
+ captured_timeout_callback.Run(); |
+} |
+ |
+} // namespace remoting |
+ |