Flutter Engine
test_timeout_listener.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "flutter/testing/test_timeout_listener.h"
6 
7 #include <map>
8 #include <sstream>
9 
10 namespace flutter {
11 namespace testing {
12 
13 class PendingTests : public std::enable_shared_from_this<PendingTests> {
14  public:
15  static std::shared_ptr<PendingTests> Create(
16  fml::RefPtr<fml::TaskRunner> host_task_runner,
17  fml::TimeDelta timeout) {
18  return std::shared_ptr<PendingTests>(
19  new PendingTests(std::move(host_task_runner), timeout));
20  }
21 
22  ~PendingTests() = default;
23 
24  void OnTestBegin(const std::string& test_name, fml::TimePoint test_time) {
25  FML_CHECK(tests_.find(test_name) == tests_.end())
26  << "Attempting to start a test that is already pending.";
27  tests_[test_name] = test_time;
28 
29  host_task_runner_->PostDelayedTask(
30  [weak = weak_from_this()] {
31  if (auto strong = weak.lock()) {
32  strong->CheckTimedOutTests();
33  }
34  },
35  timeout_);
36  }
37 
38  void OnTestEnd(const std::string& test_name) { tests_.erase(test_name); }
39 
40  void CheckTimedOutTests() const {
41  const auto now = fml::TimePoint::Now();
42 
43  for (const auto& test : tests_) {
44  auto delay = now - test.second;
45  FML_CHECK(delay < timeout_)
46  << "Test " << test.first << " did not complete in "
47  << timeout_.ToSeconds()
48  << " seconds and is assumed to be hung. Killing the test harness.";
49  }
50  }
51 
52  private:
53  using TestData = std::map<std::string, fml::TimePoint>;
54 
55  fml::RefPtr<fml::TaskRunner> host_task_runner_;
56  TestData tests_;
57  const fml::TimeDelta timeout_;
58 
60  fml::TimeDelta timeout)
61  : host_task_runner_(std::move(host_task_runner)), timeout_(timeout) {}
62 
63  FML_DISALLOW_COPY_AND_ASSIGN(PendingTests);
64 };
65 
66 template <class T>
67 auto WeakPtr(std::shared_ptr<T> pointer) {
68  return std::weak_ptr<T>{pointer};
69 }
70 
72  : timeout_(timeout),
73  listener_thread_("test_timeout_listener"),
74  listener_thread_runner_(listener_thread_.GetTaskRunner()),
75  pending_tests_(PendingTests::Create(listener_thread_runner_, timeout_)) {
76  FML_LOG(INFO) << "Test timeout of " << timeout_.ToSeconds()
77  << " seconds per test case will be enforced.";
78 }
79 
81  listener_thread_runner_->PostTask(
82  [tests = std::move(pending_tests_)]() mutable { tests.reset(); });
83  FML_CHECK(pending_tests_ == nullptr);
84 }
85 
86 static std::string GetTestNameFromTestInfo(
87  const ::testing::TestInfo& test_info) {
88  std::stringstream stream;
89  stream << test_info.test_suite_name();
90  stream << ".";
91  stream << test_info.name();
92  if (auto type_param = test_info.type_param()) {
93  stream << "/" << type_param;
94  }
95  if (auto value_param = test_info.value_param()) {
96  stream << "/" << value_param;
97  }
98  return stream.str();
99 }
100 
101 // |testing::EmptyTestEventListener|
102 void TestTimeoutListener::OnTestStart(const ::testing::TestInfo& test_info) {
103  listener_thread_runner_->PostTask([weak_tests = WeakPtr(pending_tests_),
104  name = GetTestNameFromTestInfo(test_info),
105  now = fml::TimePoint::Now()]() {
106  if (auto tests = weak_tests.lock()) {
107  tests->OnTestBegin(std::move(name), now);
108  }
109  });
110 }
111 
112 // |testing::EmptyTestEventListener|
113 void TestTimeoutListener::OnTestEnd(const ::testing::TestInfo& test_info) {
114  listener_thread_runner_->PostTask(
115  [weak_tests = WeakPtr(pending_tests_),
116  name = GetTestNameFromTestInfo(test_info)]() {
117  if (auto tests = weak_tests.lock()) {
118  tests->OnTestEnd(std::move(name));
119  }
120  });
121 }
122 
123 } // namespace testing
124 } // namespace flutter
void OnTestEnd(const std::string &test_name)
auto WeakPtr(std::shared_ptr< T > pointer)
constexpr int64_t ToSeconds() const
Definition: time_delta.h:64
void OnTestBegin(const std::string &test_name, fml::TimePoint test_time)
virtual void PostTask(const fml::closure &task)
Definition: task_runner.cc:24
#define FML_LOG(severity)
Definition: logging.h:65
const char * name
Definition: fuchsia.cc:50
#define FML_CHECK(condition)
Definition: logging.h:68
static std::shared_ptr< PendingTests > Create(fml::RefPtr< fml::TaskRunner > host_task_runner, fml::TimeDelta timeout)
static std::string GetTestNameFromTestInfo(const ::testing::TestInfo &test_info)
static TimePoint Now()
Definition: time_point.cc:26
virtual void PostDelayedTask(const fml::closure &task, fml::TimeDelta delay)
Definition: task_runner.cc:33