blob: 33df0f200c03f85c4eab9e74096215de279f5326 [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) {
156 for (int i = 0; i < 5; i++) {
157 uint64_t cookie = i + 1;
158 struct UidTag tag = {.uid = TEST_UID1, .tag = TEST_TAG};
159 EXPECT_EQ(0, writeToMapEntry(mFakeCookieTagMap, &cookie, &tag, BPF_ANY));
160 }
161 uint64_t curCookie = 0;
162 uint64_t nextCookie = 0;
163 struct UidTag tagResult;
164 EXPECT_EQ(0, getNextMapKey(mFakeCookieTagMap, &curCookie, &nextCookie));
165 uint64_t headOfMap = nextCookie;
166 curCookie = nextCookie;
167 // Find the second entry in the map, then immediately delete it.
168 EXPECT_EQ(0, getNextMapKey(mFakeCookieTagMap, &curCookie, &nextCookie));
169 EXPECT_EQ(0, deleteMapEntry(mFakeCookieTagMap, &nextCookie));
170 // Find the entry that is now immediately after headOfMap, then delete that.
171 EXPECT_EQ(0, getNextMapKey(mFakeCookieTagMap, &curCookie, &nextCookie));
172 EXPECT_EQ(0, deleteMapEntry(mFakeCookieTagMap, &nextCookie));
173 // Attempting to read an entry that has been deleted fails with ENOENT.
174 curCookie = nextCookie;
175 EXPECT_EQ(-1, findMapEntry(mFakeCookieTagMap, &curCookie, &tagResult));
176 EXPECT_EQ(ENOENT, errno);
177 // Finding the entry after our deleted entry restarts iteration from the beginning of the map.
178 EXPECT_EQ(0, getNextMapKey(mFakeCookieTagMap, &curCookie, &nextCookie));
179 EXPECT_EQ(headOfMap, nextCookie);
180}
181
182TEST_F(BpfNetworkStatsHelperTest, TestGetUidStatsTotal) {
Chenbo Feng33a4de12018-03-16 18:10:07 -0700183 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
Chenbo Fengeac6c472018-02-05 15:06:23 -0800184 StatsValue value1 = {.rxBytes = TEST_BYTES0,
185 .rxPackets = TEST_PACKET0,
186 .txBytes = TEST_BYTES1,
187 .txPackets = TEST_PACKET1,};
Chenbo Feng33a4de12018-03-16 18:10:07 -0700188 populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET0, &value1, mFakeUidStatsMap);
189 populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET1, &value1, mFakeUidStatsMap);
190 populateFakeStats(TEST_UID2, 0, IFACE_INDEX1, TEST_COUNTERSET1, &value1, mFakeUidStatsMap);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800191 Stats result1 = {};
192 ASSERT_EQ(0, bpfGetUidStatsInternal(TEST_UID1, &result1, mFakeUidStatsMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700193 StatsValue uid1Value = {
194 .rxBytes = TEST_BYTES0 * 2,
195 .rxPackets = TEST_PACKET0 * 2,
196 .txBytes = TEST_BYTES1 * 2,
197 .txPackets = TEST_PACKET1 * 2,
198 };
199 expectStatsEqual(uid1Value, result1);
200
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800201 Stats result2 = {};
202 ASSERT_EQ(0, bpfGetUidStatsInternal(TEST_UID2, &result2, mFakeUidStatsMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700203 expectStatsEqual(value1, result2);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800204 std::vector<stats_line> lines;
205 std::vector<std::string> ifaces;
Chenbo Feng16513482018-03-15 17:59:58 -0700206 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID1,
207 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800208 ASSERT_EQ((unsigned long)2, lines.size());
209 lines.clear();
Chenbo Feng16513482018-03-15 17:59:58 -0700210 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID2,
211 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800212 ASSERT_EQ((unsigned long)1, lines.size());
Chenbo Feng33a4de12018-03-16 18:10:07 -0700213 expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID2, TEST_COUNTERSET1, 0, lines.front());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800214}
215
216TEST_F(BpfNetworkStatsHelperTest, TestGetIfaceStatsInternal) {
Chenbo Feng33a4de12018-03-16 18:10:07 -0700217 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
218 updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
219 updateIfaceMap(IFACE_NAME3, IFACE_INDEX3);
220 StatsValue value1 = {
221 .rxBytes = TEST_BYTES0,
222 .rxPackets = TEST_PACKET0,
223 .txBytes = TEST_BYTES1,
224 .txPackets = TEST_PACKET1,
225 };
226 StatsValue value2 = {
227 .rxBytes = TEST_BYTES1,
228 .rxPackets = TEST_PACKET1,
229 .txBytes = TEST_BYTES0,
230 .txPackets = TEST_PACKET0,
231 };
232 uint32_t ifaceStatsKey = IFACE_INDEX1;
233 EXPECT_EQ(0, writeToMapEntry(mFakeIfaceStatsMap, &ifaceStatsKey, &value1, BPF_ANY));
234 ifaceStatsKey = IFACE_INDEX2;
235 EXPECT_EQ(0, writeToMapEntry(mFakeIfaceStatsMap, &ifaceStatsKey, &value2, BPF_ANY));
236 ifaceStatsKey = IFACE_INDEX3;
237 EXPECT_EQ(0, writeToMapEntry(mFakeIfaceStatsMap, &ifaceStatsKey, &value1, BPF_ANY));
238
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800239 Stats result1 = {};
Chenbo Feng33a4de12018-03-16 18:10:07 -0700240 ASSERT_EQ(0, bpfGetIfaceStatsInternal(IFACE_NAME1, &result1, mFakeIfaceStatsMap,
241 mFakeIfaceIndexNameMap));
242 expectStatsEqual(value1, result1);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800243 Stats result2 = {};
Chenbo Feng33a4de12018-03-16 18:10:07 -0700244 ASSERT_EQ(0, bpfGetIfaceStatsInternal(IFACE_NAME2, &result2, mFakeIfaceStatsMap,
245 mFakeIfaceIndexNameMap));
246 expectStatsEqual(value2, result2);
247 Stats totalResult = {};
248 ASSERT_EQ(0, bpfGetIfaceStatsInternal(NULL, &totalResult, mFakeIfaceStatsMap,
249 mFakeIfaceIndexNameMap));
250 StatsValue totalValue = {
251 .rxBytes = TEST_BYTES0 * 2 + TEST_BYTES1,
252 .rxPackets = TEST_PACKET0 * 2 + TEST_PACKET1,
253 .txBytes = TEST_BYTES1 * 2 + TEST_BYTES0,
254 .txPackets = TEST_PACKET1 * 2 + TEST_PACKET0,
255 };
256 expectStatsEqual(totalValue, totalResult);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800257}
258
259TEST_F(BpfNetworkStatsHelperTest, TestGetStatsDetail) {
Chenbo Feng33a4de12018-03-16 18:10:07 -0700260 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
261 updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
Chenbo Fengeac6c472018-02-05 15:06:23 -0800262 StatsValue value1 = {.rxBytes = TEST_BYTES0,
263 .rxPackets = TEST_PACKET0,
264 .txBytes = TEST_BYTES1,
265 .txPackets = TEST_PACKET1,};
Chenbo Feng33a4de12018-03-16 18:10:07 -0700266 populateFakeStats(TEST_UID1, TEST_TAG, IFACE_INDEX1, TEST_COUNTERSET0, &value1,
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800267 mFakeTagStatsMap);
Chenbo Feng33a4de12018-03-16 18:10:07 -0700268 populateFakeStats(TEST_UID1, TEST_TAG, IFACE_INDEX2, TEST_COUNTERSET0, &value1,
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800269 mFakeTagStatsMap);
Chenbo Feng33a4de12018-03-16 18:10:07 -0700270 populateFakeStats(TEST_UID1, TEST_TAG + 1, IFACE_INDEX1, TEST_COUNTERSET0, &value1,
271 mFakeTagStatsMap);
272 populateFakeStats(TEST_UID2, TEST_TAG, IFACE_INDEX1, TEST_COUNTERSET0, &value1,
273 mFakeTagStatsMap);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800274 std::vector<stats_line> lines;
275 std::vector<std::string> ifaces;
Chenbo Feng16513482018-03-15 17:59:58 -0700276 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL,
277 mFakeTagStatsMap, mFakeIfaceIndexNameMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700278 ASSERT_EQ((unsigned long)4, lines.size());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800279 lines.clear();
Chenbo Feng16513482018-03-15 17:59:58 -0700280 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID1,
281 mFakeTagStatsMap, mFakeIfaceIndexNameMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700282 ASSERT_EQ((unsigned long)3, lines.size());
283 lines.clear();
284 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TEST_TAG, TEST_UID1,
285 mFakeTagStatsMap, mFakeIfaceIndexNameMap));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800286 ASSERT_EQ((unsigned long)2, lines.size());
287 lines.clear();
Chenbo Feng33a4de12018-03-16 18:10:07 -0700288 ifaces.push_back(std::string(IFACE_NAME1));
Chenbo Feng16513482018-03-15 17:59:58 -0700289 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TEST_TAG, TEST_UID1,
290 mFakeTagStatsMap, mFakeIfaceIndexNameMap));
Chenbo Feng7e974052018-02-28 22:57:21 -0800291 ASSERT_EQ((unsigned long)1, lines.size());
Chenbo Feng33a4de12018-03-16 18:10:07 -0700292 expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID1, TEST_COUNTERSET0, TEST_TAG, lines.front());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800293}
294
295TEST_F(BpfNetworkStatsHelperTest, TestGetStatsWithSkippedIface) {
Chenbo Feng33a4de12018-03-16 18:10:07 -0700296 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
297 updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
Chenbo Fengeac6c472018-02-05 15:06:23 -0800298 StatsValue value1 = {.rxBytes = TEST_BYTES0,
299 .rxPackets = TEST_PACKET0,
300 .txBytes = TEST_BYTES1,
301 .txPackets = TEST_PACKET1,};
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800302 populateFakeStats(0, 0, 0, COUNTERSETS_LIMIT, &value1, mFakeUidStatsMap);
Chenbo Feng33a4de12018-03-16 18:10:07 -0700303 populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET0, &value1, mFakeUidStatsMap);
304 populateFakeStats(TEST_UID1, 0, IFACE_INDEX2, TEST_COUNTERSET0, &value1, mFakeUidStatsMap);
305 populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET1, &value1, mFakeUidStatsMap);
306 populateFakeStats(TEST_UID2, 0, IFACE_INDEX1, TEST_COUNTERSET0, &value1, mFakeUidStatsMap);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800307 std::vector<stats_line> lines;
308 std::vector<std::string> ifaces;
Chenbo Feng16513482018-03-15 17:59:58 -0700309 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL,
310 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700311 ASSERT_EQ((unsigned long)4, lines.size());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800312 lines.clear();
Chenbo Feng16513482018-03-15 17:59:58 -0700313 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID1,
314 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700315 ASSERT_EQ((unsigned long)3, lines.size());
Chenbo Feng7e974052018-02-28 22:57:21 -0800316 lines.clear();
Chenbo Feng16513482018-03-15 17:59:58 -0700317 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID2,
318 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800319 ASSERT_EQ((unsigned long)1, lines.size());
Chenbo Feng33a4de12018-03-16 18:10:07 -0700320 expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID2, TEST_COUNTERSET0, 0, lines.front());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800321 lines.clear();
Chenbo Feng33a4de12018-03-16 18:10:07 -0700322 ifaces.push_back(std::string(IFACE_NAME1));
Chenbo Feng16513482018-03-15 17:59:58 -0700323 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID1,
324 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800325 ASSERT_EQ((unsigned long)2, lines.size());
326}
327
Chenbo Feng16513482018-03-15 17:59:58 -0700328TEST_F(BpfNetworkStatsHelperTest, TestGetStatsWithNoExistKey) {
Chenbo Feng33a4de12018-03-16 18:10:07 -0700329 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
Chenbo Feng16513482018-03-15 17:59:58 -0700330 StatsValue value1 = {
331 .rxBytes = TEST_BYTES0,
332 .rxPackets = TEST_PACKET0,
333 .txBytes = TEST_BYTES1,
334 .txPackets = TEST_PACKET1,
335 };
336 populateFakeStats(DEFAULT_OVERFLOWUID, 0, 0, 0, &value1, mFakeUidStatsMap);
Chenbo Feng33a4de12018-03-16 18:10:07 -0700337 populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET0, &value1, mFakeUidStatsMap);
Chenbo Feng16513482018-03-15 17:59:58 -0700338 std::vector<stats_line> lines;
339 std::vector<std::string> ifaces;
340 ASSERT_EQ(-EUCLEAN,
341 parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL, mFakeUidStatsMap,
342 mFakeIfaceIndexNameMap));
343}
344
Chenbo Feng7e974052018-02-28 22:57:21 -0800345TEST_F(BpfNetworkStatsHelperTest, TestUnkownIfaceError) {
Chenbo Feng33a4de12018-03-16 18:10:07 -0700346 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
Chenbo Feng7e974052018-02-28 22:57:21 -0800347 StatsValue value1 = {.rxBytes = TEST_BYTES0 * 20,
348 .rxPackets = TEST_PACKET0,
349 .txBytes = TEST_BYTES1 * 20,
350 .txPackets = TEST_PACKET1,};
351 uint32_t ifaceIndex = UNKNOWN_IFACE;
352 populateFakeStats(TEST_UID1, 0, ifaceIndex, TEST_COUNTERSET0, &value1, mFakeUidStatsMap);
Chenbo Feng33a4de12018-03-16 18:10:07 -0700353 populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET0, &value1, mFakeUidStatsMap);
354 StatsValue value2 = {.rxBytes = TEST_BYTES0 * 40,
355 .rxPackets = TEST_PACKET0,
356 .txBytes = TEST_BYTES1 * 40,
357 .txPackets = TEST_PACKET1,};
358 populateFakeStats(TEST_UID1, 0, IFACE_INDEX2, TEST_COUNTERSET0, &value2, mFakeUidStatsMap);
Chenbo Feng7e974052018-02-28 22:57:21 -0800359 StatsKey curKey = {.uid = TEST_UID1,
360 .tag = 0,
361 .ifaceIndex = ifaceIndex,
362 .counterSet = TEST_COUNTERSET0};
363 char ifname[IFNAMSIZ];
Chenbo Feng33a4de12018-03-16 18:10:07 -0700364 int64_t unknownIfaceBytesTotal = 0;
365 ASSERT_EQ(-ENODEV, getIfaceNameFromMap(mFakeIfaceIndexNameMap, mFakeUidStatsMap, ifaceIndex,
366 ifname, &curKey, &unknownIfaceBytesTotal));
367 ASSERT_EQ(((int64_t)(TEST_BYTES0 * 20 + TEST_BYTES1 * 20)), unknownIfaceBytesTotal);
368 curKey.ifaceIndex = IFACE_INDEX2;
369 ASSERT_EQ(-ENODEV, getIfaceNameFromMap(mFakeIfaceIndexNameMap, mFakeUidStatsMap, ifaceIndex,
370 ifname, &curKey, &unknownIfaceBytesTotal));
371 ASSERT_EQ(-1, unknownIfaceBytesTotal);
372 std::vector<stats_line> lines;
373 std::vector<std::string> ifaces;
374 // TODO: find a way to test the total of unknown Iface Bytes go above limit.
375 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL,
376 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
377 ASSERT_EQ((unsigned long)1, lines.size());
378 expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID1, TEST_COUNTERSET0, 0, lines.front());
Chenbo Feng7e974052018-02-28 22:57:21 -0800379}
380
Chenbo Fengf4b812d2018-04-18 15:27:19 -0700381TEST_F(BpfNetworkStatsHelperTest, TestGetIfaceStatsDetail) {
382 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
383 updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
384 updateIfaceMap(IFACE_NAME3, IFACE_INDEX3);
385 StatsValue value1 = {
386 .rxBytes = TEST_BYTES0,
387 .rxPackets = TEST_PACKET0,
388 .txBytes = TEST_BYTES1,
389 .txPackets = TEST_PACKET1,
390 };
391 StatsValue value2 = {
392 .rxBytes = TEST_BYTES1,
393 .rxPackets = TEST_PACKET1,
394 .txBytes = TEST_BYTES0,
395 .txPackets = TEST_PACKET0,
396 };
397 uint32_t ifaceStatsKey = IFACE_INDEX1;
398 EXPECT_EQ(0, writeToMapEntry(mFakeIfaceStatsMap, &ifaceStatsKey, &value1, BPF_ANY));
399 ifaceStatsKey = IFACE_INDEX2;
400 EXPECT_EQ(0, writeToMapEntry(mFakeIfaceStatsMap, &ifaceStatsKey, &value2, BPF_ANY));
401 ifaceStatsKey = IFACE_INDEX3;
402 EXPECT_EQ(0, writeToMapEntry(mFakeIfaceStatsMap, &ifaceStatsKey, &value1, BPF_ANY));
403 std::vector<stats_line> lines;
404 ASSERT_EQ(0,
405 parseBpfNetworkStatsDevInternal(&lines, mFakeIfaceStatsMap, mFakeIfaceIndexNameMap));
406 ASSERT_EQ((unsigned long)3, lines.size());
407 std::sort(lines.begin(), lines.end(), [](const auto& line1, const auto& line2)-> bool {
408 return strcmp(line1.iface, line2.iface) < 0;
409 });
410 expectStatsLineEqual(value1, IFACE_NAME1, UID_ALL, SET_ALL, TAG_NONE, lines[0]);
411 expectStatsLineEqual(value1, IFACE_NAME3, UID_ALL, SET_ALL, TAG_NONE, lines[1]);
412 expectStatsLineEqual(value2, IFACE_NAME2, UID_ALL, SET_ALL, TAG_NONE, lines[2]);
413}
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800414} // namespace bpf
415} // namespace android