Add BpfDump#dumpMapStatus
Test: atest NetworkStaticLibTests
Change-Id: I77d397b16380a397573cc528fe7f15f381cda21f
diff --git a/staticlibs/device/com/android/net/module/util/BpfDump.java b/staticlibs/device/com/android/net/module/util/BpfDump.java
index 2534d61..7549e71 100644
--- a/staticlibs/device/com/android/net/module/util/BpfDump.java
+++ b/staticlibs/device/com/android/net/module/util/BpfDump.java
@@ -15,6 +15,8 @@
*/
package com.android.net.module.util;
+import static android.system.OsConstants.R_OK;
+
import android.system.ErrnoException;
import android.system.Os;
import android.util.Base64;
@@ -110,6 +112,24 @@
}
}
+ /**
+ * Dump the BpfMap status
+ */
+ public static <K extends Struct, V extends Struct> void dumpMapStatus(IBpfMap<K, V> map,
+ PrintWriter pw, String mapName, String path) {
+ if (map != null) {
+ pw.println(mapName + ": OK");
+ return;
+ }
+ try {
+ Os.access(path, R_OK);
+ pw.println(mapName + ": NULL(map is pinned to " + path + ")");
+ } catch (ErrnoException e) {
+ pw.println(mapName + ": NULL(map is not pinned to " + path + ": "
+ + Os.strerror(e.errno) + ")");
+ }
+ }
+
// TODO: add a helper to dump bpf map content with the map name, the header line
// (ex: "BPF ingress map: iif nat64Prefix v6Addr -> v4Addr oif"), a lambda that
// knows how to dump each line, and the PrintWriter.
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/BpfDumpTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/BpfDumpTest.java
index 3932925..4e48332 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/BpfDumpTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/BpfDumpTest.java
@@ -16,10 +16,19 @@
package com.android.net.module.util;
+import static android.system.OsConstants.EPERM;
+import static android.system.OsConstants.R_OK;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
+import android.system.ErrnoException;
+import android.system.Os;
import android.util.Pair;
import androidx.test.filters.SmallTest;
@@ -29,6 +38,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.MockitoSession;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -118,4 +128,36 @@
assertTrue(dump.contains("key=123, val=456"));
assertTrue(dump.contains("key=789, val=123"));
}
+
+ private String getDumpMapStatus(final IBpfMap<Struct.U32, Struct.U32> map) {
+ final StringWriter sw = new StringWriter();
+ BpfDump.dumpMapStatus(map, new PrintWriter(sw), "mapName", "mapPath");
+ return sw.toString();
+ }
+
+ @Test
+ public void testGetMapStatus() {
+ final IBpfMap<Struct.U32, Struct.U32> map =
+ new TestBpfMap<>(Struct.U32.class, Struct.U32.class);
+ assertEquals("mapName: OK\n", getDumpMapStatus(map));
+ }
+
+ @Test
+ public void testGetMapStatusNull() {
+ final MockitoSession session = mockitoSession()
+ .spyStatic(Os.class)
+ .startMocking();
+ try {
+ // Os.access succeeds
+ doReturn(true).when(() -> Os.access("mapPath", R_OK));
+ assertEquals("mapName: NULL(map is pinned to mapPath)\n", getDumpMapStatus(null));
+
+ // Os.access throws EPERM
+ doThrow(new ErrnoException("", EPERM)).when(() -> Os.access("mapPath", R_OK));
+ assertEquals("mapName: NULL(map is not pinned to mapPath: Operation not permitted)\n",
+ getDumpMapStatus(null));
+ } finally {
+ session.finishMocking();
+ }
+ }
}