xref: /aosp_15_r20/external/perfetto/src/trace_processor/importers/common/clock_tracker_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "src/trace_processor/importers/common/clock_tracker.h"
18 
19 #include <optional>
20 #include <random>
21 
22 #include "src/trace_processor/importers/common/machine_tracker.h"
23 #include "src/trace_processor/importers/common/metadata_tracker.h"
24 #include "src/trace_processor/storage/trace_storage.h"
25 #include "src/trace_processor/types/trace_processor_context.h"
26 #include "test/gtest_and_gmock.h"
27 
28 #include "protos/perfetto/common/builtin_clock.pbzero.h"
29 #include "protos/perfetto/trace/clock_snapshot.pbzero.h"
30 
31 namespace perfetto {
32 namespace trace_processor {
33 
34 class ClockTrackerTest : public ::testing::Test {
35  public:
ClockTrackerTest()36   ClockTrackerTest() {
37     context_.storage.reset(new TraceStorage());
38     context_.metadata_tracker.reset(
39         new MetadataTracker(context_.storage.get()));
40   }
41 
42   // using ClockId = uint64_t;
43   TraceProcessorContext context_;
44   ClockTracker ct_{&context_};
Convert(ClockTracker::ClockId src_clock_id,int64_t src_timestamp,ClockTracker::ClockId target_clock_id)45   base::StatusOr<int64_t> Convert(ClockTracker::ClockId src_clock_id,
46                                   int64_t src_timestamp,
47                                   ClockTracker::ClockId target_clock_id) {
48     return ct_.Convert(src_clock_id, src_timestamp, target_clock_id);
49   }
50 };
51 
52 namespace {
53 
54 using ::testing::NiceMock;
55 using Clock = protos::pbzero::ClockSnapshot::Clock;
56 
57 constexpr auto REALTIME = protos::pbzero::BUILTIN_CLOCK_REALTIME;
58 constexpr auto BOOTTIME = protos::pbzero::BUILTIN_CLOCK_BOOTTIME;
59 constexpr auto MONOTONIC = protos::pbzero::BUILTIN_CLOCK_MONOTONIC;
60 constexpr auto MONOTONIC_COARSE =
61     protos::pbzero::BUILTIN_CLOCK_MONOTONIC_COARSE;
62 constexpr auto MONOTONIC_RAW = protos::pbzero::BUILTIN_CLOCK_MONOTONIC_RAW;
63 
TEST_F(ClockTrackerTest,ClockDomainConversions)64 TEST_F(ClockTrackerTest, ClockDomainConversions) {
65   EXPECT_FALSE(ct_.ToTraceTime(REALTIME, 0).ok());
66 
67   ct_.AddSnapshot({{REALTIME, 10}, {BOOTTIME, 10010}});
68   ct_.AddSnapshot({{REALTIME, 20}, {BOOTTIME, 20220}});
69   ct_.AddSnapshot({{REALTIME, 30}, {BOOTTIME, 30030}});
70   ct_.AddSnapshot({{MONOTONIC, 1000}, {BOOTTIME, 100000}});
71 
72   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 0), 10000);
73   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 1), 10001);
74   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 9), 10009);
75   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 10), 10010);
76   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 11), 10011);
77   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 19), 10019);
78   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 20), 20220);
79   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 21), 20221);
80   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 29), 20229);
81   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 30), 30030);
82   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 40), 30040);
83 
84   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC, 0), 100000 - 1000);
85   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC, 999), 100000 - 1);
86   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC, 1000), 100000);
87   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC, 1e6),
88             static_cast<int64_t>(100000 - 1000 + 1e6));
89 }
90 
TEST_F(ClockTrackerTest,ToTraceTimeFromSnapshot)91 TEST_F(ClockTrackerTest, ToTraceTimeFromSnapshot) {
92   EXPECT_FALSE(ct_.ToTraceTime(REALTIME, 0).ok());
93 
94   EXPECT_EQ(*ct_.ToTraceTimeFromSnapshot({{REALTIME, 10}, {BOOTTIME, 10010}}),
95             10010);
96   EXPECT_EQ(ct_.ToTraceTimeFromSnapshot({{MONOTONIC, 10}, {REALTIME, 10010}}),
97             std::nullopt);
98 }
99 
100 // When a clock moves backwards conversions *from* that clock are forbidden
101 // but conversions *to* that clock should still work.
102 // Think to the case of REALTIME going backwards from 3AM to 2AM during DST day.
103 // You can't convert 2.10AM REALTIME to BOOTTIME because there are two possible
104 // answers, but you can still unambiguosly convert BOOTTIME into REALTIME.
TEST_F(ClockTrackerTest,RealTimeClockMovingBackwards)105 TEST_F(ClockTrackerTest, RealTimeClockMovingBackwards) {
106   ct_.AddSnapshot({{BOOTTIME, 10010}, {REALTIME, 10}});
107 
108   // At this point conversions are still possible in both ways because we
109   // haven't broken monotonicity yet.
110   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 11), 10011);
111 
112   ct_.AddSnapshot({{BOOTTIME, 10020}, {REALTIME, 20}});
113   ct_.AddSnapshot({{BOOTTIME, 30040}, {REALTIME, 40}});
114   ct_.AddSnapshot({{BOOTTIME, 40030}, {REALTIME, 30}});
115 
116   // Now only BOOTIME -> REALTIME conversion should be possible.
117   EXPECT_FALSE(ct_.ToTraceTime(REALTIME, 11).ok());
118   EXPECT_EQ(*Convert(BOOTTIME, 10011, REALTIME), 11);
119   EXPECT_EQ(*Convert(BOOTTIME, 10029, REALTIME), 29);
120   EXPECT_EQ(*Convert(BOOTTIME, 40030, REALTIME), 30);
121   EXPECT_EQ(*Convert(BOOTTIME, 40040, REALTIME), 40);
122 
123   ct_.AddSnapshot({{BOOTTIME, 50000}, {REALTIME, 50}});
124   EXPECT_EQ(*Convert(BOOTTIME, 50005, REALTIME), 55);
125 
126   ct_.AddSnapshot({{BOOTTIME, 60020}, {REALTIME, 20}});
127   EXPECT_EQ(*Convert(BOOTTIME, 60020, REALTIME), 20);
128 }
129 
130 // Simulate the following scenario:
131 // MONOTONIC = MONOTONIC_COARSE + 10
132 // BOOTTIME = MONOTONIC + 1000 (until T=200)
133 // BOOTTIME = MONOTONIC + 2000 (from T=200)
134 // Then resolve MONOTONIC_COARSE. This requires a two-level resolution:
135 // MONOTONIC_COARSE -> MONOTONIC -> BOOTTIME.
TEST_F(ClockTrackerTest,ChainedResolutionSimple)136 TEST_F(ClockTrackerTest, ChainedResolutionSimple) {
137   ct_.AddSnapshot({{MONOTONIC_COARSE, 1}, {MONOTONIC, 11}});
138   ct_.AddSnapshot({{MONOTONIC, 100}, {BOOTTIME, 1100}});
139   ct_.AddSnapshot({{MONOTONIC, 200}, {BOOTTIME, 2200}});
140 
141   // MONOTONIC_COARSE@100 == MONOTONIC@110 == BOOTTIME@1100.
142   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC, 110), 1110);
143   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC_COARSE, 100), 100 + 10 + 1000);
144   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC_COARSE, 202), 202 + 10 + 2000);
145 }
146 
TEST_F(ClockTrackerTest,ChainedResolutionHard)147 TEST_F(ClockTrackerTest, ChainedResolutionHard) {
148   // MONOTONIC_COARSE = MONOTONIC_RAW - 1.
149   ct_.AddSnapshot({{MONOTONIC_RAW, 10}, {MONOTONIC_COARSE, 9}});
150 
151   // MONOTONIC = MONOTONIC_COARSE - 50.
152   ct_.AddSnapshot({{MONOTONIC_COARSE, 100}, {MONOTONIC, 50}});
153 
154   // BOOTTIME = MONOTONIC + 1000 until T=100 (see below).
155   ct_.AddSnapshot({{MONOTONIC, 1}, {BOOTTIME, 1001}, {REALTIME, 10001}});
156 
157   // BOOTTIME = MONOTONIC + 2000 from T=100.
158   // At the same time, REALTIME goes backwards.
159   ct_.AddSnapshot({{MONOTONIC, 101}, {BOOTTIME, 2101}, {REALTIME, 9101}});
160 
161   // 1-hop conversions.
162   EXPECT_EQ(*Convert(MONOTONIC_RAW, 2, MONOTONIC_COARSE), 1);
163   EXPECT_EQ(*Convert(MONOTONIC_COARSE, 1, MONOTONIC_RAW), 2);
164   EXPECT_EQ(*Convert(MONOTONIC_RAW, 100001, MONOTONIC_COARSE), 100000);
165   EXPECT_EQ(*Convert(MONOTONIC_COARSE, 100000, MONOTONIC_RAW), 100001);
166 
167   // 2-hop conversions (MONOTONIC_RAW <-> MONOTONIC_COARSE <-> MONOTONIC).
168   // From above, MONOTONIC = (MONOTONIC_RAW - 1) - 50.
169   EXPECT_EQ(*Convert(MONOTONIC_RAW, 53, MONOTONIC), 53 - 1 - 50);
170   EXPECT_EQ(*Convert(MONOTONIC, 2, MONOTONIC_RAW), 2 + 1 + 50);
171 
172   // 3-hop conversions (as above + BOOTTIME)
173   EXPECT_EQ(*Convert(MONOTONIC_RAW, 53, BOOTTIME), 53 - 1 - 50 + 1000);
174   EXPECT_EQ(*Convert(BOOTTIME, 1002, MONOTONIC_RAW), 1002 - 1000 + 1 + 50);
175 
176   EXPECT_EQ(*Convert(MONOTONIC_RAW, 753, BOOTTIME), 753 - 1 - 50 + 2000);
177   EXPECT_EQ(*Convert(BOOTTIME, 2702, MONOTONIC_RAW), 2702 - 2000 + 1 + 50);
178 
179   // 3-hop conversion to REALTIME, one way only (REALTIME goes backwards).
180   EXPECT_EQ(*Convert(MONOTONIC_RAW, 53, REALTIME), 53 - 1 - 50 + 10000);
181   EXPECT_EQ(*Convert(MONOTONIC_RAW, 753, REALTIME), 753 - 1 - 50 + 9000);
182 }
183 
184 // Regression test for b/158182858. When taking two snapshots back-to-back,
185 // MONOTONIC_COARSE might be stuck to the last value. We should still be able
186 // to convert both ways in this case.
TEST_F(ClockTrackerTest,NonStrictlyMonotonic)187 TEST_F(ClockTrackerTest, NonStrictlyMonotonic) {
188   ct_.AddSnapshot({{BOOTTIME, 101}, {MONOTONIC, 51}, {MONOTONIC_COARSE, 50}});
189   ct_.AddSnapshot({{BOOTTIME, 105}, {MONOTONIC, 55}, {MONOTONIC_COARSE, 50}});
190 
191   // This last snapshot is deliberately identical to the previous one. This
192   // is to simulate the case of taking two snapshots so close to each other
193   // that all clocks are identical.
194   ct_.AddSnapshot({{BOOTTIME, 105}, {MONOTONIC, 55}, {MONOTONIC_COARSE, 50}});
195 
196   EXPECT_EQ(*Convert(MONOTONIC_COARSE, 49, MONOTONIC), 50);
197   EXPECT_EQ(*Convert(MONOTONIC_COARSE, 50, MONOTONIC), 55);
198   EXPECT_EQ(*Convert(MONOTONIC_COARSE, 51, MONOTONIC), 56);
199 
200   EXPECT_EQ(*Convert(MONOTONIC_COARSE, 40, BOOTTIME), 91);
201   EXPECT_EQ(*Convert(MONOTONIC_COARSE, 50, BOOTTIME), 105);
202   EXPECT_EQ(*Convert(MONOTONIC_COARSE, 55, BOOTTIME), 110);
203 
204   EXPECT_EQ(*Convert(BOOTTIME, 91, MONOTONIC_COARSE), 40);
205   EXPECT_EQ(*Convert(BOOTTIME, 105, MONOTONIC_COARSE), 50);
206   EXPECT_EQ(*Convert(BOOTTIME, 110, MONOTONIC_COARSE), 55);
207 }
208 
TEST_F(ClockTrackerTest,SequenceScopedClocks)209 TEST_F(ClockTrackerTest, SequenceScopedClocks) {
210   ct_.AddSnapshot({{MONOTONIC, 1000}, {BOOTTIME, 100000}});
211 
212   ClockTracker::ClockId c64_1 = ct_.SequenceToGlobalClock(1, 64);
213   ClockTracker::ClockId c65_1 = ct_.SequenceToGlobalClock(1, 65);
214   ClockTracker::ClockId c66_1 = ct_.SequenceToGlobalClock(1, 66);
215   ClockTracker::ClockId c66_2 = ct_.SequenceToGlobalClock(2, 64);
216 
217   ct_.AddSnapshot(
218       {{MONOTONIC, 10000},
219        {c64_1, 100000},
220        {c65_1, 100, /*unit_multiplier_ns=*/1000, /*is_incremental=*/false},
221        {c66_1, 10, /*unit_multiplier_ns=*/1000, /*is_incremental=*/true}});
222 
223   // c64_1 is non-incremental and in nanos.
224   EXPECT_EQ(*Convert(c64_1, 150000, MONOTONIC), 60000);
225   EXPECT_EQ(*Convert(c64_1, 150000, BOOTTIME), 159000);
226   EXPECT_EQ(*ct_.ToTraceTime(c64_1, 150000), 159000);
227 
228   // c65_1 is non-incremental and in micros.
229   EXPECT_EQ(*Convert(c65_1, 150, MONOTONIC), 60000);
230   EXPECT_EQ(*Convert(c65_1, 150, BOOTTIME), 159000);
231   EXPECT_EQ(*ct_.ToTraceTime(c65_1, 150), 159000);
232 
233   // c66_1 is incremental and in micros.
234   EXPECT_EQ(*Convert(c66_1, 1 /* abs 11 */, MONOTONIC), 11000);
235   EXPECT_EQ(*Convert(c66_1, 1 /* abs 12 */, MONOTONIC), 12000);
236   EXPECT_EQ(*Convert(c66_1, 1 /* abs 13 */, BOOTTIME), 112000);
237   EXPECT_EQ(*ct_.ToTraceTime(c66_1, 2 /* abs 15 */), 114000);
238 
239   ct_.AddSnapshot(
240       {{MONOTONIC, 20000},
241        {c66_1, 20, /*unit_multiplier_ns=*/1000, /*incremental=*/true}});
242   ct_.AddSnapshot(
243       {{MONOTONIC, 20000},
244        {c66_2, 20, /*unit_multiplier_ns=*/1000, /*incremental=*/true}});
245 
246   // c66_1 and c66_2 are both incremental and in micros, but shouldn't affect
247   // each other.
248   EXPECT_EQ(*Convert(c66_1, 1 /* abs 21 */, MONOTONIC), 21000);
249   EXPECT_EQ(*Convert(c66_2, 2 /* abs 22 */, MONOTONIC), 22000);
250   EXPECT_EQ(*Convert(c66_1, 1 /* abs 22 */, MONOTONIC), 22000);
251   EXPECT_EQ(*Convert(c66_2, 2 /* abs 24 */, MONOTONIC), 24000);
252   EXPECT_EQ(*Convert(c66_1, 1 /* abs 23 */, BOOTTIME), 122000);
253   EXPECT_EQ(*Convert(c66_2, 2 /* abs 26 */, BOOTTIME), 125000);
254   EXPECT_EQ(*ct_.ToTraceTime(c66_1, 2 /* abs 25 */), 124000);
255   EXPECT_EQ(*ct_.ToTraceTime(c66_2, 4 /* abs 30 */), 129000);
256 }
257 
258 // Tests that the cache doesn't affect the results of Convert() in unexpected
259 // ways.
TEST_F(ClockTrackerTest,CacheDoesntAffectResults)260 TEST_F(ClockTrackerTest, CacheDoesntAffectResults) {
261   std::minstd_rand rnd;
262   int last_mono = 0;
263   int last_boot = 0;
264   int last_raw = 0;
265   static const int increments[] = {1, 2, 10};
266   for (int i = 0; i < 1000; i++) {
267     last_mono += increments[rnd() % base::ArraySize(increments)];
268     last_boot += increments[rnd() % base::ArraySize(increments)];
269     ct_.AddSnapshot({{MONOTONIC, last_mono}, {BOOTTIME, last_boot}});
270 
271     last_raw += increments[rnd() % base::ArraySize(increments)];
272     last_boot += increments[rnd() % base::ArraySize(increments)];
273     ct_.AddSnapshot({{MONOTONIC_RAW, last_raw}, {BOOTTIME, last_boot}});
274   }
275 
276   for (int i = 0; i < 1000; i++) {
277     int64_t val = static_cast<int64_t>(rnd()) % 10000;
278     for (int j = 0; j < 5; j++) {
279       ClockTracker::ClockId src;
280       ClockTracker::ClockId tgt;
281       if (j == 0) {
282         std::tie(src, tgt) = std::make_tuple(MONOTONIC, BOOTTIME);
283       } else if (j == 1) {
284         std::tie(src, tgt) = std::make_tuple(MONOTONIC_RAW, BOOTTIME);
285       } else if (j == 2) {
286         std::tie(src, tgt) = std::make_tuple(BOOTTIME, MONOTONIC);
287       } else if (j == 3) {
288         std::tie(src, tgt) = std::make_tuple(BOOTTIME, MONOTONIC_RAW);
289       } else if (j == 4) {
290         std::tie(src, tgt) = std::make_tuple(MONOTONIC_RAW, MONOTONIC);
291       } else {
292         PERFETTO_FATAL("j out of bounds");
293       }
294       // It will still write the cache, just not lookup.
295       ct_.set_cache_lookups_disabled_for_testing(true);
296       auto not_cached = Convert(src, val, tgt);
297 
298       // This should 100% hit the cache.
299       ct_.set_cache_lookups_disabled_for_testing(false);
300       auto cached = Convert(src, val, tgt);
301 
302       ASSERT_EQ(not_cached.value(), cached.value());
303     }
304   }
305 }
306 
307 // Test clock conversion with offset to the host.
TEST_F(ClockTrackerTest,ClockOffset)308 TEST_F(ClockTrackerTest, ClockOffset) {
309   EXPECT_FALSE(ct_.ToTraceTime(REALTIME, 0).ok());
310 
311   context_.machine_tracker =
312       std::make_unique<MachineTracker>(&context_, 0x1001);
313 
314   // Client-to-host BOOTTIME offset is -10000 ns.
315   ct_.SetClockOffset(BOOTTIME, -10000);
316 
317   ct_.AddSnapshot({{REALTIME, 10}, {BOOTTIME, 10010}});
318   ct_.AddSnapshot({{REALTIME, 20}, {BOOTTIME, 20220}});
319   ct_.AddSnapshot({{REALTIME, 30}, {BOOTTIME, 30030}});
320   ct_.AddSnapshot({{MONOTONIC, 1000}, {BOOTTIME, 100000}});
321 
322   auto seq_clock_1 = ct_.SequenceToGlobalClock(1, 64);
323   auto seq_clock_2 = ct_.SequenceToGlobalClock(2, 64);
324   ct_.AddSnapshot({{MONOTONIC, 2000}, {seq_clock_1, 1200}});
325   ct_.AddSnapshot({{seq_clock_1, 1300}, {seq_clock_2, 2000, 10, false}});
326 
327   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 0), 20000);
328   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 1), 20001);
329   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 9), 20009);
330   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 10), 20010);
331   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 11), 20011);
332   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 19), 20019);
333   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 20), 30220);
334   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 21), 30221);
335   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 29), 30229);
336   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 30), 40030);
337   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 40), 40040);
338 
339   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC, 0), 100000 - 1000 + 10000);
340   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC, 999), 100000 - 1 + 10000);
341   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC, 1000), 100000 + 10000);
342   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC, 1e6),
343             static_cast<int64_t>(100000 - 1000 + 1e6 + 10000));
344 
345   // seq_clock_1 -> MONOTONIC -> BOOTTIME -> apply offset.
346   EXPECT_EQ(*ct_.ToTraceTime(seq_clock_1, 1100), -100 + 1000 + 100000 + 10000);
347   // seq_clock_2 -> seq_clock_1 -> MONOTONIC -> BOOTTIME -> apply offset.
348   EXPECT_EQ(*ct_.ToTraceTime(seq_clock_2, 2100),
349             100 * 10 + 100 + 1000 + 100000 + 10000);
350 }
351 
352 // Test conversion of remote machine timestamps without offset. This can happen
353 // if timestamp conversion for remote machines is done by trace data
354 // post-processing.
TEST_F(ClockTrackerTest,RemoteNoClockOffset)355 TEST_F(ClockTrackerTest, RemoteNoClockOffset) {
356   context_.machine_tracker =
357       std::make_unique<MachineTracker>(&context_, 0x1001);
358 
359   ct_.AddSnapshot({{REALTIME, 10}, {BOOTTIME, 10010}});
360   ct_.AddSnapshot({{REALTIME, 20}, {BOOTTIME, 20220}});
361   ct_.AddSnapshot({{MONOTONIC, 1000}, {BOOTTIME, 100000}});
362 
363   auto seq_clock_1 = ct_.SequenceToGlobalClock(1, 64);
364   auto seq_clock_2 = ct_.SequenceToGlobalClock(2, 64);
365   ct_.AddSnapshot({{MONOTONIC, 2000}, {seq_clock_1, 1200}});
366   ct_.AddSnapshot({{seq_clock_1, 1300}, {seq_clock_2, 2000, 10, false}});
367 
368   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 0), 10000);
369   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 9), 10009);
370   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 10), 10010);
371   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 11), 10011);
372   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 19), 10019);
373   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 20), 20220);
374   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 21), 20221);
375 
376   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC, 0), 100000 - 1000);
377   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC, 999), 100000 - 1);
378   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC, 1000), 100000);
379   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC, 1e6),
380             static_cast<int64_t>(100000 - 1000 + 1e6));
381 
382   // seq_clock_1 -> MONOTONIC -> BOOTTIME.
383   EXPECT_EQ(*ct_.ToTraceTime(seq_clock_1, 1100), -100 + 1000 + 100000);
384   // seq_clock_2 -> seq_clock_1 -> MONOTONIC -> BOOTTIME.
385   EXPECT_EQ(*ct_.ToTraceTime(seq_clock_2, 2100),
386             100 * 10 + 100 + 1000 + 100000);
387 }
388 
389 // Test clock offset of non-defualt trace time clock domain.
TEST_F(ClockTrackerTest,NonDefaultTraceTimeClock)390 TEST_F(ClockTrackerTest, NonDefaultTraceTimeClock) {
391   context_.machine_tracker =
392       std::make_unique<MachineTracker>(&context_, 0x1001);
393 
394   ct_.SetTraceTimeClock(MONOTONIC);
395   ct_.SetClockOffset(MONOTONIC, -2000);
396   ct_.SetClockOffset(BOOTTIME, -10000);  // This doesn't take effect.
397 
398   ct_.AddSnapshot({{REALTIME, 10}, {BOOTTIME, 10010}});
399   ct_.AddSnapshot({{MONOTONIC, 1000}, {BOOTTIME, 100000}});
400 
401   auto seq_clock_1 = ct_.SequenceToGlobalClock(1, 64);
402   ct_.AddSnapshot({{MONOTONIC, 2000}, {seq_clock_1, 1200}});
403 
404   int64_t realtime_to_trace_time_delta = -10 + 10010 - 100000 + 1000 - (-2000);
405   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 9), 9 + realtime_to_trace_time_delta);
406   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 10), 10 + realtime_to_trace_time_delta);
407   EXPECT_EQ(*ct_.ToTraceTime(REALTIME, 20), 20 + realtime_to_trace_time_delta);
408 
409   int64_t mono_to_trace_time_delta = -2000;
410   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC, 0), 0 - mono_to_trace_time_delta);
411   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC, 999), 999 - mono_to_trace_time_delta);
412   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC, 1000), 1000 - mono_to_trace_time_delta);
413   EXPECT_EQ(*ct_.ToTraceTime(MONOTONIC, 1e6),
414             static_cast<int64_t>(1e6) - mono_to_trace_time_delta);
415 
416   // seq_clock_1 -> MONOTONIC.
417   EXPECT_EQ(*ct_.ToTraceTime(seq_clock_1, 1100), 1100 - 1200 + 2000 - (-2000));
418 }
419 
420 }  // namespace
421 }  // namespace trace_processor
422 }  // namespace perfetto
423