1 /*
2 * Copyright 2022 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 "UidCpuStatsCollector.h"
18
19 #include <android-base/file.h>
20 #include <android-base/stringprintf.h>
21 #include <gmock/gmock.h>
22
23 #include <inttypes.h>
24
25 #include <unordered_map>
26
27 namespace android {
28 namespace automotive {
29 namespace watchdog {
30
31 using ::android::base::StringAppendF;
32 using ::android::base::WriteStringToFile;
33 using ::testing::UnorderedElementsAreArray;
34
35 namespace {
36
toString(const std::unordered_map<uid_t,int64_t> & cpuTimeMillisByUid)37 std::string toString(const std::unordered_map<uid_t, int64_t>& cpuTimeMillisByUid) {
38 std::string buffer;
39 for (const auto& [uid, cpuTime] : cpuTimeMillisByUid) {
40 StringAppendF(&buffer, "{%d: %" PRId64 "}\n", uid, cpuTime);
41 }
42 return buffer;
43 }
44
45 } // namespace
46
TEST(UidCpuStatsCollectorTest,TestValidStatFile)47 TEST(UidCpuStatsCollectorTest, TestValidStatFile) {
48 // Format: <uid>: <user_time_micro_seconds> <system_time_micro_seconds>
49 constexpr char firstSnapshot[] = "0: 7000000 5000000\n"
50 "100: 1256700 4545636\n"
51 "1009: 500000 500000\n"
52 "1001000: 40000 30000\n";
53 std::unordered_map<uid_t, int64_t> expectedFirstUsage = {{0, 12'000},
54 {100, 5'801},
55 {1009, 1'000},
56 {1001000, 70}};
57
58 TemporaryFile tf;
59 ASSERT_NE(tf.fd, -1);
60 ASSERT_TRUE(WriteStringToFile(firstSnapshot, tf.path));
61
62 UidCpuStatsCollector collector(tf.path);
63 collector.init();
64
65 ASSERT_TRUE(collector.enabled()) << "Temporary file is inaccessible";
66 ASSERT_RESULT_OK(collector.collect());
67
68 const auto& actualFirstUsage = collector.deltaStats();
69 EXPECT_THAT(actualFirstUsage, UnorderedElementsAreArray(expectedFirstUsage))
70 << "Expected: " << toString(expectedFirstUsage)
71 << "Actual: " << toString(actualFirstUsage);
72
73 constexpr char secondSnapshot[] = "0: 7500000 5000000\n"
74 "100: 1266700 4565636\n"
75 "1009: 700000 600000\n"
76 "1001000: 40000 30000\n";
77 std::unordered_map<uid_t, int64_t> expectedSecondUsage = {{0, 500}, {100, 30}, {1009, 300}};
78
79 ASSERT_TRUE(WriteStringToFile(secondSnapshot, tf.path));
80 ASSERT_RESULT_OK(collector.collect());
81
82 const auto& actualSecondUsage = collector.deltaStats();
83 EXPECT_THAT(actualSecondUsage, UnorderedElementsAreArray(expectedSecondUsage))
84 << "Expected: " << toString(expectedSecondUsage)
85 << "Actual: " << toString(actualSecondUsage);
86 }
87
TEST(UidCpuStatsCollectorTest,TestErrorOnInvalidStatFile)88 TEST(UidCpuStatsCollectorTest, TestErrorOnInvalidStatFile) {
89 constexpr char contents[] = "0: 7000000 5000000\n"
90 "100: 1256700 4545636\n"
91 "1009: 500000 500000\n"
92 "1001000: CORRUPTED DATA\n";
93 TemporaryFile tf;
94 ASSERT_NE(tf.fd, -1);
95 ASSERT_TRUE(WriteStringToFile(contents, tf.path));
96
97 UidCpuStatsCollector collector(tf.path);
98 collector.init();
99
100 ASSERT_TRUE(collector.enabled()) << "Temporary file is inaccessible";
101 EXPECT_FALSE(collector.collect().ok()) << "No error returned for invalid file";
102 }
103
TEST(UidCpuStatsCollectorTest,TestErrorOnEmptyStatFile)104 TEST(UidCpuStatsCollectorTest, TestErrorOnEmptyStatFile) {
105 TemporaryFile tf;
106 ASSERT_NE(tf.fd, -1);
107
108 UidCpuStatsCollector collector(tf.path);
109 collector.init();
110
111 ASSERT_TRUE(collector.enabled()) << "Temporary file is inaccessible";
112 EXPECT_FALSE(collector.collect().ok()) << "No error returned for invalid file";
113 }
114
115 } // namespace watchdog
116 } // namespace automotive
117 } // namespace android
118