blob: d1f81576b23eaf2ece66d24bfb863761af80069e [file] [log] [blame]
Chenbo Fengdc4e3252017-12-22 11:00:52 -08001/*
2 * Copyright (C) 2018 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 <fstream>
18#include <iostream>
19#include <string>
20#include <vector>
21
22#include <fcntl.h>
23#include <inttypes.h>
24#include <linux/inet_diag.h>
25#include <linux/sock_diag.h>
26#include <net/if.h>
27#include <sys/socket.h>
28#include <sys/types.h>
29#include <unistd.h>
30
31#include <gtest/gtest.h>
32
33#include <android-base/stringprintf.h>
34#include <android-base/strings.h>
35
36#include <netdutils/MockSyscalls.h>
37#include "bpf/BpfNetworkStats.h"
38#include "bpf/BpfUtils.h"
39
40using namespace android::bpf;
41
42using ::testing::_;
43using ::testing::ByMove;
44using ::testing::Invoke;
45using ::testing::Return;
46using ::testing::StrictMock;
47using ::testing::Test;
48
49namespace android {
50namespace bpf {
51
52using base::unique_fd;
53using netdutils::status::ok;
54
55constexpr int TEST_MAP_SIZE = 10;
56constexpr uid_t TEST_UID1 = 10086;
57constexpr uid_t TEST_UID2 = 12345;
58constexpr uint32_t TEST_TAG = 42;
59constexpr int TEST_COUNTERSET0 = 0;
60constexpr int TEST_COUNTERSET1 = 1;
Chenbo Fengdc4e3252017-12-22 11:00:52 -080061constexpr const int COUNTERSETS_LIMIT = 2;
62constexpr uint64_t TEST_BYTES0 = 1000;
63constexpr uint64_t TEST_BYTES1 = 2000;
Chenbo Fengdc4e3252017-12-22 11:00:52 -080064constexpr uint64_t TEST_PACKET0 = 100;
65constexpr uint64_t TEST_PACKET1 = 200;
Chenbo Feng33a4de12018-03-16 18:10:07 -070066constexpr const char* IFACE_NAME1 = "lo";
67constexpr const char* IFACE_NAME2 = "wlan0";
68constexpr const char* IFACE_NAME3 = "rmnet_data0";
69constexpr uint32_t IFACE_INDEX1 = 1;
70constexpr uint32_t IFACE_INDEX2 = 2;
71constexpr uint32_t IFACE_INDEX3 = 3;
Chenbo Feng7e974052018-02-28 22:57:21 -080072constexpr uint32_t UNKNOWN_IFACE = 0;
Chenbo Fengdc4e3252017-12-22 11:00:52 -080073
74class BpfNetworkStatsHelperTest : public testing::Test {
75 protected:
76 BpfNetworkStatsHelperTest() {}
77 unique_fd mFakeCookieTagMap;
78 unique_fd mFakeUidStatsMap;
79 unique_fd mFakeTagStatsMap;
Chenbo Feng7e974052018-02-28 22:57:21 -080080 unique_fd mFakeIfaceIndexNameMap;
Chenbo Feng33a4de12018-03-16 18:10:07 -070081 unique_fd mFakeIfaceStatsMap;
Chenbo Fengdc4e3252017-12-22 11:00:52 -080082
83 void SetUp() {
84 mFakeCookieTagMap = unique_fd(createMap(BPF_MAP_TYPE_HASH, sizeof(uint64_t),
85 sizeof(struct UidTag), TEST_MAP_SIZE, 0));
86 ASSERT_LE(0, mFakeCookieTagMap);
87
88 mFakeUidStatsMap = unique_fd(createMap(BPF_MAP_TYPE_HASH, sizeof(struct StatsKey),
89 sizeof(struct StatsValue), TEST_MAP_SIZE, 0));
90 ASSERT_LE(0, mFakeUidStatsMap);
91
92 mFakeTagStatsMap = unique_fd(createMap(BPF_MAP_TYPE_HASH, sizeof(struct StatsKey),
93 sizeof(struct StatsValue), TEST_MAP_SIZE, 0));
94 ASSERT_LE(0, mFakeTagStatsMap);
Chenbo Feng7e974052018-02-28 22:57:21 -080095
96 mFakeIfaceIndexNameMap =
97 unique_fd(createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), IFNAMSIZ, TEST_MAP_SIZE, 0));
98 ASSERT_LE(0, mFakeIfaceIndexNameMap);
Chenbo Feng33a4de12018-03-16 18:10:07 -070099
100 mFakeIfaceStatsMap = unique_fd(createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t),
101 sizeof(struct StatsValue), TEST_MAP_SIZE, 0));
102 ASSERT_LE(0, mFakeIfaceStatsMap);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800103 }
104
105 void TearDown() {
106 mFakeCookieTagMap.reset();
107 mFakeUidStatsMap.reset();
108 mFakeTagStatsMap.reset();
Chenbo Feng33a4de12018-03-16 18:10:07 -0700109 mFakeIfaceIndexNameMap.reset();
110 mFakeIfaceStatsMap.reset();
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800111 }
112
113 void expectUidTag(uint64_t cookie, uid_t uid, uint32_t tag) {
114 struct UidTag tagResult;
115 EXPECT_EQ(0, findMapEntry(mFakeCookieTagMap, &cookie, &tagResult));
116 EXPECT_EQ(uid, tagResult.uid);
117 EXPECT_EQ(tag, tagResult.tag);
118 }
119
120 void populateFakeStats(uid_t uid, uint32_t tag, uint32_t ifaceIndex, uint32_t counterSet,
121 StatsValue* value, const base::unique_fd& map_fd) {
122 StatsKey key = {
123 .uid = (uint32_t)uid, .tag = tag, .counterSet = counterSet, .ifaceIndex = ifaceIndex};
124 EXPECT_EQ(0, writeToMapEntry(map_fd, &key, value, BPF_ANY));
125 }
Chenbo Feng7e974052018-02-28 22:57:21 -0800126
Chenbo Feng33a4de12018-03-16 18:10:07 -0700127 void updateIfaceMap(const char* ifaceName, uint32_t ifaceIndex) {
Chenbo Feng7e974052018-02-28 22:57:21 -0800128 char iface[IFNAMSIZ];
129 strlcpy(iface, ifaceName, IFNAMSIZ);
130 EXPECT_EQ(0, writeToMapEntry(mFakeIfaceIndexNameMap, &ifaceIndex, iface, BPF_ANY));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700131 }
132
133 void expectStatsEqual(const StatsValue& target, const Stats& result) {
134 EXPECT_EQ(target.rxPackets, result.rxPackets);
135 EXPECT_EQ(target.rxBytes, result.rxBytes);
136 EXPECT_EQ(target.txPackets, result.txPackets);
137 EXPECT_EQ(target.txBytes, result.txBytes);
138 }
139
140 void expectStatsLineEqual(const StatsValue target, const char* iface, uint32_t uid,
141 int counterSet, uint32_t tag, const stats_line& result) {
142 EXPECT_EQ(0, strcmp(iface, result.iface));
143 EXPECT_EQ(uid, (uint32_t)result.uid);
144 EXPECT_EQ(counterSet, result.set);
145 EXPECT_EQ(tag, (uint32_t)result.tag);
146 EXPECT_EQ(target.rxPackets, (uint64_t)result.rxPackets);
147 EXPECT_EQ(target.rxBytes, (uint64_t)result.rxBytes);
148 EXPECT_EQ(target.txPackets, (uint64_t)result.txPackets);
149 EXPECT_EQ(target.txBytes, (uint64_t)result.txBytes);
Chenbo Feng7e974052018-02-28 22:57:21 -0800150 }
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800151};
152
153// TEST to verify the behavior of bpf map when cocurrent deletion happens when
154// iterating the same map.
155TEST_F(BpfNetworkStatsHelperTest, TestIterateMapWithDeletion) {
Chenbo Feng837ddfc2018-05-08 13:45:08 -0700156 SKIP_IF_BPF_NOT_SUPPORTED;
157
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800158 for (int i = 0; i < 5; i++) {
159 uint64_t cookie = i + 1;
160 struct UidTag tag = {.uid = TEST_UID1, .tag = TEST_TAG};
161 EXPECT_EQ(0, writeToMapEntry(mFakeCookieTagMap, &cookie, &tag, BPF_ANY));
162 }
163 uint64_t curCookie = 0;
164 uint64_t nextCookie = 0;
165 struct UidTag tagResult;
166 EXPECT_EQ(0, getNextMapKey(mFakeCookieTagMap, &curCookie, &nextCookie));
167 uint64_t headOfMap = nextCookie;
168 curCookie = nextCookie;
169 // Find the second entry in the map, then immediately delete it.
170 EXPECT_EQ(0, getNextMapKey(mFakeCookieTagMap, &curCookie, &nextCookie));
171 EXPECT_EQ(0, deleteMapEntry(mFakeCookieTagMap, &nextCookie));
172 // Find the entry that is now immediately after headOfMap, then delete that.
173 EXPECT_EQ(0, getNextMapKey(mFakeCookieTagMap, &curCookie, &nextCookie));
174 EXPECT_EQ(0, deleteMapEntry(mFakeCookieTagMap, &nextCookie));
175 // Attempting to read an entry that has been deleted fails with ENOENT.
176 curCookie = nextCookie;
177 EXPECT_EQ(-1, findMapEntry(mFakeCookieTagMap, &curCookie, &tagResult));
178 EXPECT_EQ(ENOENT, errno);
179 // Finding the entry after our deleted entry restarts iteration from the beginning of the map.
180 EXPECT_EQ(0, getNextMapKey(mFakeCookieTagMap, &curCookie, &nextCookie));
181 EXPECT_EQ(headOfMap, nextCookie);
182}
183
184TEST_F(BpfNetworkStatsHelperTest, TestGetUidStatsTotal) {
Chenbo Feng837ddfc2018-05-08 13:45:08 -0700185 SKIP_IF_BPF_NOT_SUPPORTED;
186
Chenbo Feng33a4de12018-03-16 18:10:07 -0700187 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
Chenbo Fengeac6c472018-02-05 15:06:23 -0800188 StatsValue value1 = {.rxBytes = TEST_BYTES0,
189 .rxPackets = TEST_PACKET0,
190 .txBytes = TEST_BYTES1,
191 .txPackets = TEST_PACKET1,};
Chenbo Feng33a4de12018-03-16 18:10:07 -0700192 populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET0, &value1, mFakeUidStatsMap);
193 populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET1, &value1, mFakeUidStatsMap);
194 populateFakeStats(TEST_UID2, 0, IFACE_INDEX1, TEST_COUNTERSET1, &value1, mFakeUidStatsMap);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800195 Stats result1 = {};
196 ASSERT_EQ(0, bpfGetUidStatsInternal(TEST_UID1, &result1, mFakeUidStatsMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700197 StatsValue uid1Value = {
198 .rxBytes = TEST_BYTES0 * 2,
199 .rxPackets = TEST_PACKET0 * 2,
200 .txBytes = TEST_BYTES1 * 2,
201 .txPackets = TEST_PACKET1 * 2,
202 };
203 expectStatsEqual(uid1Value, result1);
204
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800205 Stats result2 = {};
206 ASSERT_EQ(0, bpfGetUidStatsInternal(TEST_UID2, &result2, mFakeUidStatsMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700207 expectStatsEqual(value1, result2);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800208 std::vector<stats_line> lines;
209 std::vector<std::string> ifaces;
Chenbo Feng16513482018-03-15 17:59:58 -0700210 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID1,
211 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800212 ASSERT_EQ((unsigned long)2, lines.size());
213 lines.clear();
Chenbo Feng16513482018-03-15 17:59:58 -0700214 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID2,
215 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800216 ASSERT_EQ((unsigned long)1, lines.size());
Chenbo Feng33a4de12018-03-16 18:10:07 -0700217 expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID2, TEST_COUNTERSET1, 0, lines.front());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800218}
219
220TEST_F(BpfNetworkStatsHelperTest, TestGetIfaceStatsInternal) {
Chenbo Feng837ddfc2018-05-08 13:45:08 -0700221 SKIP_IF_BPF_NOT_SUPPORTED;
222
Chenbo Feng33a4de12018-03-16 18:10:07 -0700223 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
224 updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
225 updateIfaceMap(IFACE_NAME3, IFACE_INDEX3);
226 StatsValue value1 = {
227 .rxBytes = TEST_BYTES0,
228 .rxPackets = TEST_PACKET0,
229 .txBytes = TEST_BYTES1,
230 .txPackets = TEST_PACKET1,
231 };
232 StatsValue value2 = {
233 .rxBytes = TEST_BYTES1,
234 .rxPackets = TEST_PACKET1,
235 .txBytes = TEST_BYTES0,
236 .txPackets = TEST_PACKET0,
237 };
238 uint32_t ifaceStatsKey = IFACE_INDEX1;
239 EXPECT_EQ(0, writeToMapEntry(mFakeIfaceStatsMap, &ifaceStatsKey, &value1, BPF_ANY));
240 ifaceStatsKey = IFACE_INDEX2;
241 EXPECT_EQ(0, writeToMapEntry(mFakeIfaceStatsMap, &ifaceStatsKey, &value2, BPF_ANY));
242 ifaceStatsKey = IFACE_INDEX3;
243 EXPECT_EQ(0, writeToMapEntry(mFakeIfaceStatsMap, &ifaceStatsKey, &value1, BPF_ANY));
244
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800245 Stats result1 = {};
Chenbo Feng33a4de12018-03-16 18:10:07 -0700246 ASSERT_EQ(0, bpfGetIfaceStatsInternal(IFACE_NAME1, &result1, mFakeIfaceStatsMap,
247 mFakeIfaceIndexNameMap));
248 expectStatsEqual(value1, result1);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800249 Stats result2 = {};
Chenbo Feng33a4de12018-03-16 18:10:07 -0700250 ASSERT_EQ(0, bpfGetIfaceStatsInternal(IFACE_NAME2, &result2, mFakeIfaceStatsMap,
251 mFakeIfaceIndexNameMap));
252 expectStatsEqual(value2, result2);
253 Stats totalResult = {};
254 ASSERT_EQ(0, bpfGetIfaceStatsInternal(NULL, &totalResult, mFakeIfaceStatsMap,
255 mFakeIfaceIndexNameMap));
256 StatsValue totalValue = {
257 .rxBytes = TEST_BYTES0 * 2 + TEST_BYTES1,
258 .rxPackets = TEST_PACKET0 * 2 + TEST_PACKET1,
259 .txBytes = TEST_BYTES1 * 2 + TEST_BYTES0,
260 .txPackets = TEST_PACKET1 * 2 + TEST_PACKET0,
261 };
262 expectStatsEqual(totalValue, totalResult);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800263}
264
265TEST_F(BpfNetworkStatsHelperTest, TestGetStatsDetail) {
Chenbo Feng837ddfc2018-05-08 13:45:08 -0700266 SKIP_IF_BPF_NOT_SUPPORTED;
267
Chenbo Feng33a4de12018-03-16 18:10:07 -0700268 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
269 updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
Chenbo Fengeac6c472018-02-05 15:06:23 -0800270 StatsValue value1 = {.rxBytes = TEST_BYTES0,
271 .rxPackets = TEST_PACKET0,
272 .txBytes = TEST_BYTES1,
273 .txPackets = TEST_PACKET1,};
Chenbo Feng33a4de12018-03-16 18:10:07 -0700274 populateFakeStats(TEST_UID1, TEST_TAG, IFACE_INDEX1, TEST_COUNTERSET0, &value1,
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800275 mFakeTagStatsMap);
Chenbo Feng33a4de12018-03-16 18:10:07 -0700276 populateFakeStats(TEST_UID1, TEST_TAG, IFACE_INDEX2, TEST_COUNTERSET0, &value1,
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800277 mFakeTagStatsMap);
Chenbo Feng33a4de12018-03-16 18:10:07 -0700278 populateFakeStats(TEST_UID1, TEST_TAG + 1, IFACE_INDEX1, TEST_COUNTERSET0, &value1,
279 mFakeTagStatsMap);
280 populateFakeStats(TEST_UID2, TEST_TAG, IFACE_INDEX1, TEST_COUNTERSET0, &value1,
281 mFakeTagStatsMap);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800282 std::vector<stats_line> lines;
283 std::vector<std::string> ifaces;
Chenbo Feng16513482018-03-15 17:59:58 -0700284 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL,
285 mFakeTagStatsMap, mFakeIfaceIndexNameMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700286 ASSERT_EQ((unsigned long)4, lines.size());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800287 lines.clear();
Chenbo Feng16513482018-03-15 17:59:58 -0700288 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID1,
289 mFakeTagStatsMap, mFakeIfaceIndexNameMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700290 ASSERT_EQ((unsigned long)3, lines.size());
291 lines.clear();
292 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TEST_TAG, TEST_UID1,
293 mFakeTagStatsMap, mFakeIfaceIndexNameMap));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800294 ASSERT_EQ((unsigned long)2, lines.size());
295 lines.clear();
Chenbo Feng33a4de12018-03-16 18:10:07 -0700296 ifaces.push_back(std::string(IFACE_NAME1));
Chenbo Feng16513482018-03-15 17:59:58 -0700297 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TEST_TAG, TEST_UID1,
298 mFakeTagStatsMap, mFakeIfaceIndexNameMap));
Chenbo Feng7e974052018-02-28 22:57:21 -0800299 ASSERT_EQ((unsigned long)1, lines.size());
Chenbo Feng33a4de12018-03-16 18:10:07 -0700300 expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID1, TEST_COUNTERSET0, TEST_TAG, lines.front());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800301}
302
303TEST_F(BpfNetworkStatsHelperTest, TestGetStatsWithSkippedIface) {
Chenbo Feng837ddfc2018-05-08 13:45:08 -0700304 SKIP_IF_BPF_NOT_SUPPORTED;
305
Chenbo Feng33a4de12018-03-16 18:10:07 -0700306 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
307 updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
Chenbo Fengeac6c472018-02-05 15:06:23 -0800308 StatsValue value1 = {.rxBytes = TEST_BYTES0,
309 .rxPackets = TEST_PACKET0,
310 .txBytes = TEST_BYTES1,
311 .txPackets = TEST_PACKET1,};
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800312 populateFakeStats(0, 0, 0, COUNTERSETS_LIMIT, &value1, mFakeUidStatsMap);
Chenbo Feng33a4de12018-03-16 18:10:07 -0700313 populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET0, &value1, mFakeUidStatsMap);
314 populateFakeStats(TEST_UID1, 0, IFACE_INDEX2, TEST_COUNTERSET0, &value1, mFakeUidStatsMap);
315 populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET1, &value1, mFakeUidStatsMap);
316 populateFakeStats(TEST_UID2, 0, IFACE_INDEX1, TEST_COUNTERSET0, &value1, mFakeUidStatsMap);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800317 std::vector<stats_line> lines;
318 std::vector<std::string> ifaces;
Chenbo Feng16513482018-03-15 17:59:58 -0700319 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL,
320 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700321 ASSERT_EQ((unsigned long)4, lines.size());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800322 lines.clear();
Chenbo Feng16513482018-03-15 17:59:58 -0700323 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID1,
324 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700325 ASSERT_EQ((unsigned long)3, lines.size());
Chenbo Feng7e974052018-02-28 22:57:21 -0800326 lines.clear();
Chenbo Feng16513482018-03-15 17:59:58 -0700327 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID2,
328 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800329 ASSERT_EQ((unsigned long)1, lines.size());
Chenbo Feng33a4de12018-03-16 18:10:07 -0700330 expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID2, TEST_COUNTERSET0, 0, lines.front());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800331 lines.clear();
Chenbo Feng33a4de12018-03-16 18:10:07 -0700332 ifaces.push_back(std::string(IFACE_NAME1));
Chenbo Feng16513482018-03-15 17:59:58 -0700333 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID1,
334 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800335 ASSERT_EQ((unsigned long)2, lines.size());
336}
337
Chenbo Feng16513482018-03-15 17:59:58 -0700338TEST_F(BpfNetworkStatsHelperTest, TestGetStatsWithNoExistKey) {
Chenbo Feng837ddfc2018-05-08 13:45:08 -0700339 SKIP_IF_BPF_NOT_SUPPORTED;
340
Chenbo Feng33a4de12018-03-16 18:10:07 -0700341 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
Chenbo Feng16513482018-03-15 17:59:58 -0700342 StatsValue value1 = {
343 .rxBytes = TEST_BYTES0,
344 .rxPackets = TEST_PACKET0,
345 .txBytes = TEST_BYTES1,
346 .txPackets = TEST_PACKET1,
347 };
348 populateFakeStats(DEFAULT_OVERFLOWUID, 0, 0, 0, &value1, mFakeUidStatsMap);
Chenbo Feng33a4de12018-03-16 18:10:07 -0700349 populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET0, &value1, mFakeUidStatsMap);
Chenbo Feng16513482018-03-15 17:59:58 -0700350 std::vector<stats_line> lines;
351 std::vector<std::string> ifaces;
352 ASSERT_EQ(-EUCLEAN,
353 parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL, mFakeUidStatsMap,
354 mFakeIfaceIndexNameMap));
355}
356
Chenbo Feng7e974052018-02-28 22:57:21 -0800357TEST_F(BpfNetworkStatsHelperTest, TestUnkownIfaceError) {
Chenbo Feng837ddfc2018-05-08 13:45:08 -0700358 SKIP_IF_BPF_NOT_SUPPORTED;
359
Chenbo Feng33a4de12018-03-16 18:10:07 -0700360 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
Chenbo Feng7e974052018-02-28 22:57:21 -0800361 StatsValue value1 = {.rxBytes = TEST_BYTES0 * 20,
362 .rxPackets = TEST_PACKET0,
363 .txBytes = TEST_BYTES1 * 20,
364 .txPackets = TEST_PACKET1,};
365 uint32_t ifaceIndex = UNKNOWN_IFACE;
366 populateFakeStats(TEST_UID1, 0, ifaceIndex, TEST_COUNTERSET0, &value1, mFakeUidStatsMap);
Chenbo Feng33a4de12018-03-16 18:10:07 -0700367 populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET0, &value1, mFakeUidStatsMap);
368 StatsValue value2 = {.rxBytes = TEST_BYTES0 * 40,
369 .rxPackets = TEST_PACKET0,
370 .txBytes = TEST_BYTES1 * 40,
371 .txPackets = TEST_PACKET1,};
372 populateFakeStats(TEST_UID1, 0, IFACE_INDEX2, TEST_COUNTERSET0, &value2, mFakeUidStatsMap);
Chenbo Feng7e974052018-02-28 22:57:21 -0800373 StatsKey curKey = {.uid = TEST_UID1,
374 .tag = 0,
375 .ifaceIndex = ifaceIndex,
376 .counterSet = TEST_COUNTERSET0};
377 char ifname[IFNAMSIZ];
Chenbo Feng33a4de12018-03-16 18:10:07 -0700378 int64_t unknownIfaceBytesTotal = 0;
379 ASSERT_EQ(-ENODEV, getIfaceNameFromMap(mFakeIfaceIndexNameMap, mFakeUidStatsMap, ifaceIndex,
380 ifname, &curKey, &unknownIfaceBytesTotal));
381 ASSERT_EQ(((int64_t)(TEST_BYTES0 * 20 + TEST_BYTES1 * 20)), unknownIfaceBytesTotal);
382 curKey.ifaceIndex = IFACE_INDEX2;
383 ASSERT_EQ(-ENODEV, getIfaceNameFromMap(mFakeIfaceIndexNameMap, mFakeUidStatsMap, ifaceIndex,
384 ifname, &curKey, &unknownIfaceBytesTotal));
385 ASSERT_EQ(-1, unknownIfaceBytesTotal);
386 std::vector<stats_line> lines;
387 std::vector<std::string> ifaces;
388 // TODO: find a way to test the total of unknown Iface Bytes go above limit.
389 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL,
390 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
391 ASSERT_EQ((unsigned long)1, lines.size());
392 expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID1, TEST_COUNTERSET0, 0, lines.front());
Chenbo Feng7e974052018-02-28 22:57:21 -0800393}
394
Chenbo Fengf4b812d2018-04-18 15:27:19 -0700395TEST_F(BpfNetworkStatsHelperTest, TestGetIfaceStatsDetail) {
Chenbo Feng837ddfc2018-05-08 13:45:08 -0700396 SKIP_IF_BPF_NOT_SUPPORTED;
397
Chenbo Fengf4b812d2018-04-18 15:27:19 -0700398 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
399 updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
400 updateIfaceMap(IFACE_NAME3, IFACE_INDEX3);
401 StatsValue value1 = {
402 .rxBytes = TEST_BYTES0,
403 .rxPackets = TEST_PACKET0,
404 .txBytes = TEST_BYTES1,
405 .txPackets = TEST_PACKET1,
406 };
407 StatsValue value2 = {
408 .rxBytes = TEST_BYTES1,
409 .rxPackets = TEST_PACKET1,
410 .txBytes = TEST_BYTES0,
411 .txPackets = TEST_PACKET0,
412 };
413 uint32_t ifaceStatsKey = IFACE_INDEX1;
414 EXPECT_EQ(0, writeToMapEntry(mFakeIfaceStatsMap, &ifaceStatsKey, &value1, BPF_ANY));
415 ifaceStatsKey = IFACE_INDEX2;
416 EXPECT_EQ(0, writeToMapEntry(mFakeIfaceStatsMap, &ifaceStatsKey, &value2, BPF_ANY));
417 ifaceStatsKey = IFACE_INDEX3;
418 EXPECT_EQ(0, writeToMapEntry(mFakeIfaceStatsMap, &ifaceStatsKey, &value1, BPF_ANY));
419 std::vector<stats_line> lines;
420 ASSERT_EQ(0,
421 parseBpfNetworkStatsDevInternal(&lines, mFakeIfaceStatsMap, mFakeIfaceIndexNameMap));
422 ASSERT_EQ((unsigned long)3, lines.size());
423 std::sort(lines.begin(), lines.end(), [](const auto& line1, const auto& line2)-> bool {
424 return strcmp(line1.iface, line2.iface) < 0;
425 });
426 expectStatsLineEqual(value1, IFACE_NAME1, UID_ALL, SET_ALL, TAG_NONE, lines[0]);
427 expectStatsLineEqual(value1, IFACE_NAME3, UID_ALL, SET_ALL, TAG_NONE, lines[1]);
428 expectStatsLineEqual(value2, IFACE_NAME2, UID_ALL, SET_ALL, TAG_NONE, lines[2]);
429}
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800430} // namespace bpf
431} // namespace android