[M108 Migration][VD] Avoid pending frame counter becoming negative
[platform/framework/web/chromium-efl.git] / cc / metrics / events_metrics_manager_unittest.cc
1 // Copyright 2020 The Chromium Authors
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 "cc/metrics/events_metrics_manager.h"
6
7 #include <utility>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/test/simple_test_tick_clock.h"
12 #include "cc/metrics/event_metrics.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "ui/events/types/event_type.h"
16 #include "ui/events/types/scroll_input_type.h"
17
18 namespace cc {
19 namespace {
20
21 MATCHER(UniquePtrMatches, negation ? "do not match" : "match") {
22   return std::get<0>(arg).get() == std::get<1>(arg);
23 }
24
25 EventsMetricsManager::ScopedMonitor::DoneCallback CreateSimpleDoneCallback(
26     std::unique_ptr<EventMetrics> metrics) {
27   return base::BindOnce(
28       [](std::unique_ptr<EventMetrics> metrics, bool handled) {
29         std::unique_ptr<EventMetrics> result =
30             handled ? std::move(metrics) : nullptr;
31         return result;
32       },
33       std::move(metrics));
34 }
35
36 }  // namespace
37
38 #define EXPECT_SCOPED(statements) \
39   {                               \
40     SCOPED_TRACE("");             \
41     statements;                   \
42   }
43
44 using ::testing::IsEmpty;
45 using ::testing::Message;
46 using ::testing::UnorderedPointwise;
47
48 class EventsMetricsManagerTest : public testing::Test {
49  public:
50   EventsMetricsManagerTest() = default;
51   ~EventsMetricsManagerTest() override = default;
52
53  protected:
54   std::unique_ptr<EventMetrics> CreateEventMetrics(ui::EventType type) {
55     test_tick_clock_.Advance(base::Microseconds(10));
56     base::TimeTicks event_time = test_tick_clock_.NowTicks();
57     test_tick_clock_.Advance(base::Microseconds(10));
58     return EventMetrics::CreateForTesting(type, event_time, &test_tick_clock_);
59   }
60
61   EventsMetricsManager manager_;
62   base::SimpleTestTickClock test_tick_clock_;
63 };
64
65 // Tests that EventMetrics are saved only if they have an event type we are
66 // interested in, and SaveActiveEventMetrics() is called inside their
67 // corresponding monitor's scope.
68 TEST_F(EventsMetricsManagerTest, EventsMetricsSaved) {
69   enum class Behavior {
70     kDoNotSave,
71     kSaveInsideScope,
72     kSaveOutsideScope,
73   };
74
75   std::pair<std::unique_ptr<EventMetrics>, Behavior> events[] = {
76       // An interesting event type for which SaveActiveEventMetrics() is not
77       // called.
78       {CreateEventMetrics(ui::ET_MOUSE_PRESSED), Behavior::kDoNotSave},
79
80       // An interesting event type for which SaveActiveEventMetrics() is called
81       // inside its monitor scope.
82       {CreateEventMetrics(ui::ET_MOUSE_PRESSED), Behavior::kSaveInsideScope},
83
84       // An interesting event type for which SaveActiveEventMetrics() is called
85       // after its monitor scope is finished.
86       {CreateEventMetrics(ui::ET_MOUSE_PRESSED), Behavior::kSaveOutsideScope},
87
88       // A non-interesting event type for which SaveActiveEventMetrics() is
89       // called inside its monitor scope.
90       {CreateEventMetrics(ui::ET_MOUSE_MOVED), Behavior::kSaveInsideScope},
91   };
92   EXPECT_NE(events[0].first, nullptr);
93   EXPECT_NE(events[1].first, nullptr);
94   EXPECT_NE(events[2].first, nullptr);
95   EXPECT_EQ(events[3].first, nullptr);
96
97   // Out of the above events, only those with an interesting event type, for
98   // which SaveActiveEventMetrics() is called inside its monitor scope, are
99   // expected to be saved.
100   const EventMetrics* expected_saved_events[] = {
101       events[1].first.get(),
102   };
103
104   for (auto& event : events) {
105     {
106       auto monitor = manager_.GetScopedMonitor(
107           CreateSimpleDoneCallback(std::move(event.first)));
108       if (event.second == Behavior::kSaveInsideScope)
109         manager_.SaveActiveEventMetrics();
110       // Ending the scope destroys the |monitor|.
111     }
112     if (event.second == Behavior::kSaveOutsideScope)
113       manager_.SaveActiveEventMetrics();
114   }
115
116   // Check saved event metrics are as expected.
117   EXPECT_THAT(manager_.TakeSavedEventsMetrics(),
118               UnorderedPointwise(UniquePtrMatches(), expected_saved_events));
119
120   // The first call to TakeSavedEventsMetrics() should remove events metrics
121   // from the manager, so the second call should return empty list.
122   EXPECT_THAT(manager_.TakeSavedEventsMetrics(), IsEmpty());
123 }
124
125 // Tests that metrics for nested event loops are handled properly in a few
126 // different configurations.
127 TEST_F(EventsMetricsManagerTest, NestedEventsMetrics) {
128   struct {
129     // Type of event to use for the outer scope. `ui::EventType::ET_UNKNOWN` if
130     // no event should be used.
131     ui::EventType outer_event_type;
132
133     // Whether to save the outer scope metrics before starting the inner scope.
134     bool save_outer_metrics_before_inner;
135
136     // Type of event to use for the inner scope. `ui::EventType::ET_UNKNOWN` if
137     // no event should be used.
138     ui::EventType inner_event_type;
139
140     // Whether to save the inner scope metrics.
141     bool save_inner_metrics;
142
143     // Whether to save the outer scope metrics after the inner scope ended.
144     bool save_outer_metrics_after_inner;
145   } configs[] = {
146       // Config #0.
147       {
148           /*outer_event_type=*/ui::EventType::ET_MOUSE_PRESSED,
149           /*save_outer_metrics_before_inner=*/true,
150           /*inner_event_type=*/ui::EventType::ET_MOUSE_RELEASED,
151           /*save_inner_metrics=*/true,
152           /*save_outer_metrics_after_inner=*/false,
153       },
154
155       // Config #1.
156       {
157           /*outer_event_type=*/ui::EventType::ET_MOUSE_PRESSED,
158           /*save_outer_metrics_before_inner=*/false,
159           /*inner_event_type=*/ui::EventType::ET_MOUSE_RELEASED,
160           /*save_inner_metrics=*/true,
161           /*save_outer_metrics_after_inner=*/true,
162       },
163
164       // Config #2.
165       {
166           /*outer_event_type=*/ui::EventType::ET_MOUSE_PRESSED,
167           /*save_outer_metrics_before_inner=*/true,
168           /*inner_event_type=*/ui::EventType::ET_MOUSE_RELEASED,
169           /*save_inner_metrics=*/true,
170           /*save_outer_metrics_after_inner=*/true,
171       },
172
173       // Config #3.
174       {
175           /*outer_event_type=*/ui::EventType::ET_MOUSE_PRESSED,
176           /*save_outer_metrics_before_inner=*/false,
177           /*inner_event_type=*/ui::EventType::ET_UNKNOWN,
178           /*save_inner_metrics=*/false,
179           /*save_outer_metrics_after_inner=*/true,
180       },
181
182       // Config #4.
183       {
184           /*outer_event_type=*/ui::EventType::ET_UNKNOWN,
185           /*save_outer_metrics_before_inner=*/false,
186           /*inner_event_type=*/ui::EventType::ET_MOUSE_PRESSED,
187           /*save_inner_metrics=*/true,
188           /*save_outer_metrics_after_inner=*/false,
189       },
190   };
191
192   for (size_t i = 0; i < std::size(configs); i++) {
193     auto& config = configs[i];
194     std::vector<const EventMetrics*> expected_saved_metrics;
195
196     {  // Start outer scope.
197       std::unique_ptr<EventMetrics> outer_metrics;
198       if (config.outer_event_type != ui::EventType::ET_UNKNOWN) {
199         outer_metrics = CreateEventMetrics(config.outer_event_type);
200         DCHECK_NE(outer_metrics, nullptr);
201         expected_saved_metrics.push_back(outer_metrics.get());
202       }
203       auto outer_monitor = manager_.GetScopedMonitor(
204           CreateSimpleDoneCallback(std::move(outer_metrics)));
205       if (config.save_outer_metrics_before_inner)
206         manager_.SaveActiveEventMetrics();
207
208       {  // Start inner scope.
209         std::unique_ptr<EventMetrics> inner_metrics;
210         if (config.inner_event_type != ui::EventType::ET_UNKNOWN) {
211           inner_metrics = CreateEventMetrics(config.inner_event_type);
212           DCHECK_NE(inner_metrics, nullptr);
213           expected_saved_metrics.push_back(inner_metrics.get());
214         }
215         auto inner_monitor = manager_.GetScopedMonitor(
216             CreateSimpleDoneCallback(std::move(inner_metrics)));
217         if (config.save_inner_metrics)
218           manager_.SaveActiveEventMetrics();
219       }  // End inner scope
220
221       if (config.save_outer_metrics_after_inner)
222         manager_.SaveActiveEventMetrics();
223     }  // End outer scope.
224
225     SCOPED_TRACE(Message() << "Config #" << i);
226     EXPECT_THAT(manager_.TakeSavedEventsMetrics(),
227                 UnorderedPointwise(UniquePtrMatches(), expected_saved_metrics));
228   }
229 }
230
231 }  // namespace cc