1 /*
2  * Copyright (C) 2020 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/proto/active_chrome_processes_tracker.h"
18 
19 #include "perfetto/base/logging.h"
20 #include "test/gtest_and_gmock.h"
21 
22 namespace perfetto {
23 namespace trace_processor {
24 
operator ==(const ProcessWithDataLoss & lhs,const ProcessWithDataLoss & rhs)25 static bool operator==(const ProcessWithDataLoss& lhs,
26                        const ProcessWithDataLoss& rhs) {
27   return lhs.upid == rhs.upid && lhs.reliable_from == rhs.reliable_from;
28 }
29 
30 namespace {
31 
32 using ::testing::IsEmpty;
33 using ::testing::UnorderedElementsAre;
34 
35 constexpr int64_t kNanosecondsInSecond = 1000 * 1000 * 1000;
36 
TEST(ActiveChromeProcessesTrackerTest,NoMetadataAndNoDescriptors)37 TEST(ActiveChromeProcessesTrackerTest, NoMetadataAndNoDescriptors) {
38   // No metadata and no descriptor = no processes are missing.
39   ActiveChromeProcessesTracker tracker(nullptr);
40   EXPECT_THAT(tracker.GetProcessesWithDataLoss(), IsEmpty());
41 }
42 
TEST(ActiveChromeProcessesTrackerTest,NoDescriptors)43 TEST(ActiveChromeProcessesTrackerTest, NoDescriptors) {
44   ActiveChromeProcessesTracker tracker(nullptr);
45   tracker.AddActiveProcessMetadata(/*timestamp=*/10, /*upid=*/1);
46   tracker.AddActiveProcessMetadata(/*timestamp=*/10, /*upid=*/2);
47   EXPECT_THAT(tracker.GetProcessesWithDataLoss(),
48               UnorderedElementsAre(ProcessWithDataLoss{1, std::nullopt},
49                                    ProcessWithDataLoss{2, std::nullopt}));
50 }
51 
TEST(ActiveChromeProcessesTrackerTest,InexactMatch)52 TEST(ActiveChromeProcessesTrackerTest, InexactMatch) {
53   ActiveChromeProcessesTracker tracker(nullptr);
54   tracker.AddActiveProcessMetadata(/*timestamp=*/10 * kNanosecondsInSecond,
55                                    /*upid=*/1);
56   tracker.AddActiveProcessMetadata(/*timestamp=*/15 * kNanosecondsInSecond,
57                                    /*upid=*/1);
58   tracker.AddProcessDescriptor(
59       /*timestamp=*/10 * kNanosecondsInSecond - 200 * 1000 * 1000, /*upid=*/1);
60   tracker.AddProcessDescriptor(
61       /*timestamp=*/15 * kNanosecondsInSecond + 200 * 1000 * 1000, /*upid=*/1);
62   EXPECT_THAT(tracker.GetProcessesWithDataLoss(), IsEmpty());
63 }
64 
TEST(ActiveChromeProcessesTrackerTest,InexactMatchTooBigDiff)65 TEST(ActiveChromeProcessesTrackerTest, InexactMatchTooBigDiff) {
66   ActiveChromeProcessesTracker tracker(nullptr);
67   tracker.AddActiveProcessMetadata(/*timestamp=*/10 * kNanosecondsInSecond,
68                                    /*upid=*/1);
69   tracker.AddActiveProcessMetadata(/*timestamp=*/15 * kNanosecondsInSecond,
70                                    /*upid=*/1);
71   tracker.AddProcessDescriptor(
72       /*timestamp=*/10 * kNanosecondsInSecond - 200 * 1000 * 1000 - 1,
73       /*upid=*/1);
74   tracker.AddProcessDescriptor(
75       /*timestamp=*/15 * kNanosecondsInSecond + 200 * 1000 * 1000 + 1,
76       /*upid=*/1);
77   EXPECT_THAT(tracker.GetProcessesWithDataLoss(),
78               UnorderedElementsAre(ProcessWithDataLoss{
79                   1, 15 * kNanosecondsInSecond + 200 * 1000 * 1000 + 1}));
80 }
81 
TEST(ActiveChromeProcessesTrackerTest,ExtraDescriptor)82 TEST(ActiveChromeProcessesTrackerTest, ExtraDescriptor) {
83   // There're more descriptors than metadata packets - this is OK.
84   ActiveChromeProcessesTracker tracker(nullptr);
85   tracker.AddActiveProcessMetadata(/*timestamp=*/15 * kNanosecondsInSecond,
86                                    /*upid=*/1);
87   tracker.AddProcessDescriptor(/*timestamp=*/10 * kNanosecondsInSecond,
88                                /*upid=*/1);
89   tracker.AddProcessDescriptor(/*timestamp=*/15 * kNanosecondsInSecond,
90                                /*upid=*/1);
91   EXPECT_THAT(tracker.GetProcessesWithDataLoss(), IsEmpty());
92 }
93 
TEST(ActiveChromeProcessesTracker,TemrinatedProcess)94 TEST(ActiveChromeProcessesTracker, TemrinatedProcess) {
95   ActiveChromeProcessesTracker tracker(nullptr);
96   // First metadata packet - two processes.
97   tracker.AddActiveProcessMetadata(/*timestamp=*/10, /*upid=*/1);
98   tracker.AddActiveProcessMetadata(/*timestamp=*/10, /*upid=*/2);
99   // Second metadata packet - only one process, the first process terminated.
100   tracker.AddActiveProcessMetadata(/*timestamp=*/15, /*upid=*/2);
101 
102   // The first process is reliable since the second snapshot - it terminated,
103   // so it has no data loss.
104   // The second process has data loss till the end of the trace.
105   EXPECT_THAT(tracker.GetProcessesWithDataLoss(),
106               UnorderedElementsAre(ProcessWithDataLoss{1, 15},
107                                    ProcessWithDataLoss{2, std::nullopt}));
108 }
109 
110 }  // namespace
111 }  // namespace trace_processor
112 }  // namespace perfetto
113