blob: e804c40782c5984b8aaf6067afaa330d5b7a9ff2 [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>
Chenbo Feng4f6c2372018-04-26 10:37:55 -070037#include "bpf/BpfMap.h"
Chenbo Fengdc4e3252017-12-22 11:00:52 -080038#include "bpf/BpfNetworkStats.h"
39#include "bpf/BpfUtils.h"
40
41using namespace android::bpf;
42
43using ::testing::_;
44using ::testing::ByMove;
45using ::testing::Invoke;
46using ::testing::Return;
47using ::testing::StrictMock;
48using ::testing::Test;
49
50namespace android {
51namespace bpf {
52
53using base::unique_fd;
Chenbo Fengdc4e3252017-12-22 11:00:52 -080054
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 uint64_t TEST_BYTES0 = 1000;
62constexpr uint64_t TEST_BYTES1 = 2000;
Chenbo Fengdc4e3252017-12-22 11:00:52 -080063constexpr uint64_t TEST_PACKET0 = 100;
64constexpr uint64_t TEST_PACKET1 = 200;
Chenbo Feng4f6c2372018-04-26 10:37:55 -070065constexpr const char IFACE_NAME1[] = "lo";
66constexpr const char IFACE_NAME2[] = "wlan0";
67constexpr const char IFACE_NAME3[] = "rmnet_data0";
Chenbo Feng33a4de12018-03-16 18:10:07 -070068constexpr uint32_t IFACE_INDEX1 = 1;
69constexpr uint32_t IFACE_INDEX2 = 2;
70constexpr uint32_t IFACE_INDEX3 = 3;
Chenbo Feng7e974052018-02-28 22:57:21 -080071constexpr uint32_t UNKNOWN_IFACE = 0;
Chenbo Fengdc4e3252017-12-22 11:00:52 -080072
73class BpfNetworkStatsHelperTest : public testing::Test {
74 protected:
75 BpfNetworkStatsHelperTest() {}
Chenbo Feng4f6c2372018-04-26 10:37:55 -070076 BpfMap<uint64_t, UidTag> mFakeCookieTagMap;
77 BpfMap<StatsKey, StatsValue> mFakeUidStatsMap;
78 BpfMap<StatsKey, StatsValue> mFakeTagStatsMap;
79 BpfMap<uint32_t, IfaceValue> mFakeIfaceIndexNameMap;
80 BpfMap<uint32_t, StatsValue> mFakeIfaceStatsMap;
Chenbo Fengdc4e3252017-12-22 11:00:52 -080081
82 void SetUp() {
Chenbo Feng4f6c2372018-04-26 10:37:55 -070083 mFakeCookieTagMap = BpfMap<uint64_t, UidTag>(createMap(
84 BPF_MAP_TYPE_HASH, sizeof(uint64_t), sizeof(struct UidTag), TEST_MAP_SIZE, 0));
85 ASSERT_LE(0, mFakeCookieTagMap.getMap());
Chenbo Fengdc4e3252017-12-22 11:00:52 -080086
Chenbo Feng4f6c2372018-04-26 10:37:55 -070087 mFakeUidStatsMap =
88 BpfMap<StatsKey, StatsValue>(createMap(BPF_MAP_TYPE_HASH, sizeof(struct StatsKey),
89 sizeof(struct StatsValue), TEST_MAP_SIZE, 0));
90 ASSERT_LE(0, mFakeUidStatsMap.getMap());
Chenbo Fengdc4e3252017-12-22 11:00:52 -080091
Chenbo Feng4f6c2372018-04-26 10:37:55 -070092 mFakeTagStatsMap =
93 BpfMap<StatsKey, StatsValue>(createMap(BPF_MAP_TYPE_HASH, sizeof(struct StatsKey),
94 sizeof(struct StatsValue), TEST_MAP_SIZE, 0));
95 ASSERT_LE(0, mFakeTagStatsMap.getMap());
Chenbo Feng7e974052018-02-28 22:57:21 -080096
Chenbo Feng4f6c2372018-04-26 10:37:55 -070097 mFakeIfaceIndexNameMap = BpfMap<uint32_t, IfaceValue>(
98 createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(IfaceValue), TEST_MAP_SIZE, 0));
99 ASSERT_LE(0, mFakeIfaceIndexNameMap.getMap());
Chenbo Feng33a4de12018-03-16 18:10:07 -0700100
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700101 mFakeIfaceStatsMap = BpfMap<uint32_t, StatsValue>(createMap(
102 BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(struct StatsValue), TEST_MAP_SIZE, 0));
103 ASSERT_LE(0, mFakeIfaceStatsMap.getMap());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800104 }
105
106 void expectUidTag(uint64_t cookie, uid_t uid, uint32_t tag) {
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700107 auto tagResult = mFakeCookieTagMap.readValue(cookie);
108 EXPECT_TRUE(isOk(tagResult));
109 EXPECT_EQ(uid, tagResult.value().uid);
110 EXPECT_EQ(tag, tagResult.value().tag);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800111 }
112
113 void populateFakeStats(uid_t uid, uint32_t tag, uint32_t ifaceIndex, uint32_t counterSet,
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700114 StatsValue value, BpfMap<StatsKey, StatsValue>& map) {
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800115 StatsKey key = {
116 .uid = (uint32_t)uid, .tag = tag, .counterSet = counterSet, .ifaceIndex = ifaceIndex};
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700117 EXPECT_TRUE(isOk(map.writeValue(key, value, BPF_ANY)));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800118 }
Chenbo Feng7e974052018-02-28 22:57:21 -0800119
Chenbo Feng33a4de12018-03-16 18:10:07 -0700120 void updateIfaceMap(const char* ifaceName, uint32_t ifaceIndex) {
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700121 IfaceValue iface;
122 strlcpy(iface.name, ifaceName, IFNAMSIZ);
123 EXPECT_TRUE(isOk(mFakeIfaceIndexNameMap.writeValue(ifaceIndex, iface, BPF_ANY)));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700124 }
125
126 void expectStatsEqual(const StatsValue& target, const Stats& result) {
127 EXPECT_EQ(target.rxPackets, result.rxPackets);
128 EXPECT_EQ(target.rxBytes, result.rxBytes);
129 EXPECT_EQ(target.txPackets, result.txPackets);
130 EXPECT_EQ(target.txBytes, result.txBytes);
131 }
132
133 void expectStatsLineEqual(const StatsValue target, const char* iface, uint32_t uid,
134 int counterSet, uint32_t tag, const stats_line& result) {
135 EXPECT_EQ(0, strcmp(iface, result.iface));
136 EXPECT_EQ(uid, (uint32_t)result.uid);
137 EXPECT_EQ(counterSet, result.set);
138 EXPECT_EQ(tag, (uint32_t)result.tag);
139 EXPECT_EQ(target.rxPackets, (uint64_t)result.rxPackets);
140 EXPECT_EQ(target.rxBytes, (uint64_t)result.rxBytes);
141 EXPECT_EQ(target.txPackets, (uint64_t)result.txPackets);
142 EXPECT_EQ(target.txBytes, (uint64_t)result.txBytes);
Chenbo Feng7e974052018-02-28 22:57:21 -0800143 }
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800144};
145
146// TEST to verify the behavior of bpf map when cocurrent deletion happens when
147// iterating the same map.
148TEST_F(BpfNetworkStatsHelperTest, TestIterateMapWithDeletion) {
Chenbo Feng837ddfc2018-05-08 13:45:08 -0700149 SKIP_IF_BPF_NOT_SUPPORTED;
150
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800151 for (int i = 0; i < 5; i++) {
152 uint64_t cookie = i + 1;
153 struct UidTag tag = {.uid = TEST_UID1, .tag = TEST_TAG};
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700154 EXPECT_TRUE(isOk(mFakeCookieTagMap.writeValue(cookie, tag, BPF_ANY)));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800155 }
156 uint64_t curCookie = 0;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700157 auto nextCookie = mFakeCookieTagMap.getNextKey(curCookie);
158 EXPECT_TRUE(isOk(nextCookie));
159 uint64_t headOfMap = nextCookie.value();
160 curCookie = nextCookie.value();
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800161 // Find the second entry in the map, then immediately delete it.
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700162 nextCookie = mFakeCookieTagMap.getNextKey(curCookie);
163 EXPECT_TRUE(isOk(nextCookie));
164 EXPECT_TRUE(isOk(mFakeCookieTagMap.deleteValue((nextCookie.value()))));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800165 // Find the entry that is now immediately after headOfMap, then delete that.
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700166 nextCookie = mFakeCookieTagMap.getNextKey(curCookie);
167 EXPECT_TRUE(isOk(nextCookie));
168 EXPECT_TRUE(isOk(mFakeCookieTagMap.deleteValue((nextCookie.value()))));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800169 // Attempting to read an entry that has been deleted fails with ENOENT.
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700170 curCookie = nextCookie.value();
171 auto tagResult = mFakeCookieTagMap.readValue(curCookie);
172 EXPECT_EQ(ENOENT, tagResult.status().code());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800173 // Finding the entry after our deleted entry restarts iteration from the beginning of the map.
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700174 nextCookie = mFakeCookieTagMap.getNextKey(curCookie);
175 EXPECT_TRUE(isOk(nextCookie));
176 EXPECT_EQ(headOfMap, nextCookie.value());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800177}
178
Chenbo Fengc3bfd3e2018-04-24 11:50:02 -0700179TEST_F(BpfNetworkStatsHelperTest, TestBpfIterateMap) {
180 SKIP_IF_BPF_NOT_SUPPORTED;
181
182 for (int i = 0; i < 5; i++) {
183 uint64_t cookie = i + 1;
184 struct UidTag tag = {.uid = TEST_UID1, .tag = TEST_TAG};
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700185 EXPECT_TRUE(isOk(mFakeCookieTagMap.writeValue(cookie, tag, BPF_ANY)));
Chenbo Fengc3bfd3e2018-04-24 11:50:02 -0700186 }
187 int totalCount = 0;
188 int totalSum = 0;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700189 const auto iterateWithoutDeletion = [&totalCount, &totalSum](const uint64_t& key,
190 const BpfMap<uint64_t, UidTag>&) {
191 EXPECT_GE((uint64_t)5, key);
Chenbo Fengc3bfd3e2018-04-24 11:50:02 -0700192 totalCount++;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700193 totalSum += key;
194 return netdutils::status::ok;
Chenbo Fengc3bfd3e2018-04-24 11:50:02 -0700195 };
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700196 EXPECT_TRUE(isOk(mFakeCookieTagMap.iterate(iterateWithoutDeletion)));
Chenbo Fengc3bfd3e2018-04-24 11:50:02 -0700197 EXPECT_EQ(5, totalCount);
198 EXPECT_EQ(1 + 2 + 3 + 4 + 5, totalSum);
199}
200
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800201TEST_F(BpfNetworkStatsHelperTest, TestGetUidStatsTotal) {
Chenbo Feng837ddfc2018-05-08 13:45:08 -0700202 SKIP_IF_BPF_NOT_SUPPORTED;
203
Chenbo Feng33a4de12018-03-16 18:10:07 -0700204 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700205 updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
206 updateIfaceMap(IFACE_NAME3, IFACE_INDEX3);
Chenbo Fengeac6c472018-02-05 15:06:23 -0800207 StatsValue value1 = {.rxBytes = TEST_BYTES0,
208 .rxPackets = TEST_PACKET0,
209 .txBytes = TEST_BYTES1,
210 .txPackets = TEST_PACKET1,};
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700211 populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeUidStatsMap);
212 populateFakeStats(TEST_UID1, 0, IFACE_INDEX2, TEST_COUNTERSET1, value1, mFakeUidStatsMap);
213 populateFakeStats(TEST_UID2, 0, IFACE_INDEX3, TEST_COUNTERSET1, value1, mFakeUidStatsMap);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800214 Stats result1 = {};
215 ASSERT_EQ(0, bpfGetUidStatsInternal(TEST_UID1, &result1, mFakeUidStatsMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700216 StatsValue uid1Value = {
217 .rxBytes = TEST_BYTES0 * 2,
218 .rxPackets = TEST_PACKET0 * 2,
219 .txBytes = TEST_BYTES1 * 2,
220 .txPackets = TEST_PACKET1 * 2,
221 };
222 expectStatsEqual(uid1Value, result1);
223
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800224 Stats result2 = {};
225 ASSERT_EQ(0, bpfGetUidStatsInternal(TEST_UID2, &result2, mFakeUidStatsMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700226 expectStatsEqual(value1, result2);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800227 std::vector<stats_line> lines;
228 std::vector<std::string> ifaces;
Chenbo Feng16513482018-03-15 17:59:58 -0700229 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID1,
230 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800231 ASSERT_EQ((unsigned long)2, lines.size());
232 lines.clear();
Chenbo Feng16513482018-03-15 17:59:58 -0700233 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID2,
234 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800235 ASSERT_EQ((unsigned long)1, lines.size());
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700236 expectStatsLineEqual(value1, IFACE_NAME3, TEST_UID2, TEST_COUNTERSET1, 0, lines.front());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800237}
238
239TEST_F(BpfNetworkStatsHelperTest, TestGetIfaceStatsInternal) {
Chenbo Feng837ddfc2018-05-08 13:45:08 -0700240 SKIP_IF_BPF_NOT_SUPPORTED;
241
Chenbo Feng33a4de12018-03-16 18:10:07 -0700242 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
243 updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
244 updateIfaceMap(IFACE_NAME3, IFACE_INDEX3);
245 StatsValue value1 = {
246 .rxBytes = TEST_BYTES0,
247 .rxPackets = TEST_PACKET0,
248 .txBytes = TEST_BYTES1,
249 .txPackets = TEST_PACKET1,
250 };
251 StatsValue value2 = {
252 .rxBytes = TEST_BYTES1,
253 .rxPackets = TEST_PACKET1,
254 .txBytes = TEST_BYTES0,
255 .txPackets = TEST_PACKET0,
256 };
257 uint32_t ifaceStatsKey = IFACE_INDEX1;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700258 EXPECT_TRUE(isOk(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value1, BPF_ANY)));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700259 ifaceStatsKey = IFACE_INDEX2;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700260 EXPECT_TRUE(isOk(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value2, BPF_ANY)));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700261 ifaceStatsKey = IFACE_INDEX3;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700262 EXPECT_TRUE(isOk(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value1, BPF_ANY)));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700263
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800264 Stats result1 = {};
Chenbo Feng33a4de12018-03-16 18:10:07 -0700265 ASSERT_EQ(0, bpfGetIfaceStatsInternal(IFACE_NAME1, &result1, mFakeIfaceStatsMap,
266 mFakeIfaceIndexNameMap));
267 expectStatsEqual(value1, result1);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800268 Stats result2 = {};
Chenbo Feng33a4de12018-03-16 18:10:07 -0700269 ASSERT_EQ(0, bpfGetIfaceStatsInternal(IFACE_NAME2, &result2, mFakeIfaceStatsMap,
270 mFakeIfaceIndexNameMap));
271 expectStatsEqual(value2, result2);
272 Stats totalResult = {};
273 ASSERT_EQ(0, bpfGetIfaceStatsInternal(NULL, &totalResult, mFakeIfaceStatsMap,
274 mFakeIfaceIndexNameMap));
275 StatsValue totalValue = {
276 .rxBytes = TEST_BYTES0 * 2 + TEST_BYTES1,
277 .rxPackets = TEST_PACKET0 * 2 + TEST_PACKET1,
278 .txBytes = TEST_BYTES1 * 2 + TEST_BYTES0,
279 .txPackets = TEST_PACKET1 * 2 + TEST_PACKET0,
280 };
281 expectStatsEqual(totalValue, totalResult);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800282}
283
284TEST_F(BpfNetworkStatsHelperTest, TestGetStatsDetail) {
Chenbo Feng837ddfc2018-05-08 13:45:08 -0700285 SKIP_IF_BPF_NOT_SUPPORTED;
286
Chenbo Feng33a4de12018-03-16 18:10:07 -0700287 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
288 updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
Chenbo Fengeac6c472018-02-05 15:06:23 -0800289 StatsValue value1 = {.rxBytes = TEST_BYTES0,
290 .rxPackets = TEST_PACKET0,
291 .txBytes = TEST_BYTES1,
292 .txPackets = TEST_PACKET1,};
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700293 populateFakeStats(TEST_UID1, TEST_TAG, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeTagStatsMap);
294 populateFakeStats(TEST_UID1, TEST_TAG, IFACE_INDEX2, TEST_COUNTERSET0, value1, mFakeTagStatsMap);
295 populateFakeStats(TEST_UID1, TEST_TAG + 1, IFACE_INDEX1, TEST_COUNTERSET0, value1,
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800296 mFakeTagStatsMap);
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700297 populateFakeStats(TEST_UID2, TEST_TAG, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeTagStatsMap);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800298 std::vector<stats_line> lines;
299 std::vector<std::string> ifaces;
Chenbo Feng16513482018-03-15 17:59:58 -0700300 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL,
301 mFakeTagStatsMap, mFakeIfaceIndexNameMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700302 ASSERT_EQ((unsigned long)4, lines.size());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800303 lines.clear();
Chenbo Feng16513482018-03-15 17:59:58 -0700304 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID1,
305 mFakeTagStatsMap, mFakeIfaceIndexNameMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700306 ASSERT_EQ((unsigned long)3, lines.size());
307 lines.clear();
308 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TEST_TAG, TEST_UID1,
309 mFakeTagStatsMap, mFakeIfaceIndexNameMap));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800310 ASSERT_EQ((unsigned long)2, lines.size());
311 lines.clear();
Chenbo Feng33a4de12018-03-16 18:10:07 -0700312 ifaces.push_back(std::string(IFACE_NAME1));
Chenbo Feng16513482018-03-15 17:59:58 -0700313 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TEST_TAG, TEST_UID1,
314 mFakeTagStatsMap, mFakeIfaceIndexNameMap));
Chenbo Feng7e974052018-02-28 22:57:21 -0800315 ASSERT_EQ((unsigned long)1, lines.size());
Chenbo Feng33a4de12018-03-16 18:10:07 -0700316 expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID1, TEST_COUNTERSET0, TEST_TAG, lines.front());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800317}
318
319TEST_F(BpfNetworkStatsHelperTest, TestGetStatsWithSkippedIface) {
Chenbo Feng837ddfc2018-05-08 13:45:08 -0700320 SKIP_IF_BPF_NOT_SUPPORTED;
321
Chenbo Feng33a4de12018-03-16 18:10:07 -0700322 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
323 updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
Chenbo Fengeac6c472018-02-05 15:06:23 -0800324 StatsValue value1 = {.rxBytes = TEST_BYTES0,
325 .rxPackets = TEST_PACKET0,
326 .txBytes = TEST_BYTES1,
327 .txPackets = TEST_PACKET1,};
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700328 populateFakeStats(0, 0, 0, OVERFLOW_COUNTERSET, value1, mFakeUidStatsMap);
329 populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeUidStatsMap);
330 populateFakeStats(TEST_UID1, 0, IFACE_INDEX2, TEST_COUNTERSET0, value1, mFakeUidStatsMap);
331 populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET1, value1, mFakeUidStatsMap);
332 populateFakeStats(TEST_UID2, 0, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeUidStatsMap);
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800333 std::vector<stats_line> lines;
334 std::vector<std::string> ifaces;
Chenbo Feng16513482018-03-15 17:59:58 -0700335 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL,
336 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700337 ASSERT_EQ((unsigned long)4, lines.size());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800338 lines.clear();
Chenbo Feng16513482018-03-15 17:59:58 -0700339 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID1,
340 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700341 ASSERT_EQ((unsigned long)3, lines.size());
Chenbo Feng7e974052018-02-28 22:57:21 -0800342 lines.clear();
Chenbo Feng16513482018-03-15 17:59:58 -0700343 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID2,
344 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800345 ASSERT_EQ((unsigned long)1, lines.size());
Chenbo Feng33a4de12018-03-16 18:10:07 -0700346 expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID2, TEST_COUNTERSET0, 0, lines.front());
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800347 lines.clear();
Chenbo Feng33a4de12018-03-16 18:10:07 -0700348 ifaces.push_back(std::string(IFACE_NAME1));
Chenbo Feng16513482018-03-15 17:59:58 -0700349 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID1,
350 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800351 ASSERT_EQ((unsigned long)2, lines.size());
352}
353
Chenbo Feng7e974052018-02-28 22:57:21 -0800354TEST_F(BpfNetworkStatsHelperTest, TestUnkownIfaceError) {
Chenbo Feng837ddfc2018-05-08 13:45:08 -0700355 SKIP_IF_BPF_NOT_SUPPORTED;
356
Chenbo Feng33a4de12018-03-16 18:10:07 -0700357 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
Chenbo Feng7e974052018-02-28 22:57:21 -0800358 StatsValue value1 = {.rxBytes = TEST_BYTES0 * 20,
359 .rxPackets = TEST_PACKET0,
360 .txBytes = TEST_BYTES1 * 20,
361 .txPackets = TEST_PACKET1,};
362 uint32_t ifaceIndex = UNKNOWN_IFACE;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700363 populateFakeStats(TEST_UID1, 0, ifaceIndex, TEST_COUNTERSET0, value1, mFakeUidStatsMap);
364 populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeUidStatsMap);
Chenbo Feng33a4de12018-03-16 18:10:07 -0700365 StatsValue value2 = {.rxBytes = TEST_BYTES0 * 40,
366 .rxPackets = TEST_PACKET0,
367 .txBytes = TEST_BYTES1 * 40,
368 .txPackets = TEST_PACKET1,};
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700369 populateFakeStats(TEST_UID1, 0, IFACE_INDEX2, TEST_COUNTERSET0, value2, mFakeUidStatsMap);
Chenbo Feng7e974052018-02-28 22:57:21 -0800370 StatsKey curKey = {.uid = TEST_UID1,
371 .tag = 0,
372 .ifaceIndex = ifaceIndex,
373 .counterSet = TEST_COUNTERSET0};
374 char ifname[IFNAMSIZ];
Chenbo Feng33a4de12018-03-16 18:10:07 -0700375 int64_t unknownIfaceBytesTotal = 0;
376 ASSERT_EQ(-ENODEV, getIfaceNameFromMap(mFakeIfaceIndexNameMap, mFakeUidStatsMap, ifaceIndex,
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700377 ifname, curKey, &unknownIfaceBytesTotal));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700378 ASSERT_EQ(((int64_t)(TEST_BYTES0 * 20 + TEST_BYTES1 * 20)), unknownIfaceBytesTotal);
379 curKey.ifaceIndex = IFACE_INDEX2;
380 ASSERT_EQ(-ENODEV, getIfaceNameFromMap(mFakeIfaceIndexNameMap, mFakeUidStatsMap, ifaceIndex,
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700381 ifname, curKey, &unknownIfaceBytesTotal));
Chenbo Feng33a4de12018-03-16 18:10:07 -0700382 ASSERT_EQ(-1, unknownIfaceBytesTotal);
383 std::vector<stats_line> lines;
384 std::vector<std::string> ifaces;
385 // TODO: find a way to test the total of unknown Iface Bytes go above limit.
386 ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL,
387 mFakeUidStatsMap, mFakeIfaceIndexNameMap));
388 ASSERT_EQ((unsigned long)1, lines.size());
389 expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID1, TEST_COUNTERSET0, 0, lines.front());
Chenbo Feng7e974052018-02-28 22:57:21 -0800390}
391
Chenbo Fengf4b812d2018-04-18 15:27:19 -0700392TEST_F(BpfNetworkStatsHelperTest, TestGetIfaceStatsDetail) {
Chenbo Feng837ddfc2018-05-08 13:45:08 -0700393 SKIP_IF_BPF_NOT_SUPPORTED;
394
Chenbo Fengf4b812d2018-04-18 15:27:19 -0700395 updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
396 updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
397 updateIfaceMap(IFACE_NAME3, IFACE_INDEX3);
398 StatsValue value1 = {
399 .rxBytes = TEST_BYTES0,
400 .rxPackets = TEST_PACKET0,
401 .txBytes = TEST_BYTES1,
402 .txPackets = TEST_PACKET1,
403 };
404 StatsValue value2 = {
405 .rxBytes = TEST_BYTES1,
406 .rxPackets = TEST_PACKET1,
407 .txBytes = TEST_BYTES0,
408 .txPackets = TEST_PACKET0,
409 };
410 uint32_t ifaceStatsKey = IFACE_INDEX1;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700411 EXPECT_TRUE(isOk(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value1, BPF_ANY)));
Chenbo Fengf4b812d2018-04-18 15:27:19 -0700412 ifaceStatsKey = IFACE_INDEX2;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700413 EXPECT_TRUE(isOk(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value2, BPF_ANY)));
Chenbo Fengf4b812d2018-04-18 15:27:19 -0700414 ifaceStatsKey = IFACE_INDEX3;
Chenbo Feng4f6c2372018-04-26 10:37:55 -0700415 EXPECT_TRUE(isOk(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value1, BPF_ANY)));
Chenbo Fengf4b812d2018-04-18 15:27:19 -0700416 std::vector<stats_line> lines;
417 ASSERT_EQ(0,
418 parseBpfNetworkStatsDevInternal(&lines, mFakeIfaceStatsMap, mFakeIfaceIndexNameMap));
419 ASSERT_EQ((unsigned long)3, lines.size());
420 std::sort(lines.begin(), lines.end(), [](const auto& line1, const auto& line2)-> bool {
421 return strcmp(line1.iface, line2.iface) < 0;
422 });
423 expectStatsLineEqual(value1, IFACE_NAME1, UID_ALL, SET_ALL, TAG_NONE, lines[0]);
424 expectStatsLineEqual(value1, IFACE_NAME3, UID_ALL, SET_ALL, TAG_NONE, lines[1]);
425 expectStatsLineEqual(value2, IFACE_NAME2, UID_ALL, SET_ALL, TAG_NONE, lines[2]);
426}
Chenbo Fengdc4e3252017-12-22 11:00:52 -0800427} // namespace bpf
428} // namespace android