summaryrefslogtreecommitdiff
path: root/common/testutils/devicetests/com/android/testutils/TestBpfMap.java
diff options
context:
space:
mode:
Diffstat (limited to 'common/testutils/devicetests/com/android/testutils/TestBpfMap.java')
-rw-r--r--common/testutils/devicetests/com/android/testutils/TestBpfMap.java136
1 files changed, 136 insertions, 0 deletions
diff --git a/common/testutils/devicetests/com/android/testutils/TestBpfMap.java b/common/testutils/devicetests/com/android/testutils/TestBpfMap.java
new file mode 100644
index 00000000..5614a99a
--- /dev/null
+++ b/common/testutils/devicetests/com/android/testutils/TestBpfMap.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.testutils;
+
+import android.system.ErrnoException;
+
+import androidx.annotation.NonNull;
+
+import com.android.net.module.util.BpfMap;
+import com.android.net.module.util.Struct;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.function.BiConsumer;
+
+/**
+ *
+ * Fake BPF map class for tests that have no no privilege to access real BPF maps. All member
+ * functions which eventually call JNI to access the real native BPF map are overridden.
+ *
+ * Inherits from BpfMap instead of implementing IBpfMap so that any class using a BpfMap can use
+ * this class in its tests.
+ *
+ * @param <K> the key type
+ * @param <V> the value type
+ */
+public class TestBpfMap<K extends Struct, V extends Struct> extends BpfMap<K, V> {
+ private final HashMap<K, V> mMap = new HashMap<K, V>();
+
+ public TestBpfMap(final Class<K> key, final Class<V> value) {
+ super(key, value);
+ }
+
+ @Override
+ public void forEach(BiConsumer<K, V> action) throws ErrnoException {
+ // TODO: consider using mocked #getFirstKey and #getNextKey to iterate. It helps to
+ // implement the entry deletion in the iteration if required.
+ for (Map.Entry<K, V> entry : mMap.entrySet()) {
+ action.accept(entry.getKey(), entry.getValue());
+ }
+ }
+
+ @Override
+ public void updateEntry(K key, V value) throws ErrnoException {
+ mMap.put(key, value);
+ }
+
+ @Override
+ public void insertEntry(K key, V value) throws ErrnoException,
+ IllegalArgumentException {
+ // The entry is created if and only if it doesn't exist. See BpfMap#insertEntry.
+ if (mMap.get(key) != null) {
+ throw new IllegalArgumentException(key + " already exist");
+ }
+ mMap.put(key, value);
+ }
+
+ @Override
+ public void replaceEntry(K key, V value) throws ErrnoException, NoSuchElementException {
+ if (!mMap.containsKey(key)) throw new NoSuchElementException();
+ mMap.put(key, value);
+ }
+
+ @Override
+ public boolean insertOrReplaceEntry(K key, V value) throws ErrnoException {
+ // Returns true if inserted, false if replaced.
+ boolean ret = !mMap.containsKey(key);
+ mMap.put(key, value);
+ return ret;
+ }
+
+ @Override
+ public boolean deleteEntry(Struct key) throws ErrnoException {
+ return mMap.remove(key) != null;
+ }
+
+ @Override
+ public boolean isEmpty() throws ErrnoException {
+ return mMap.isEmpty();
+ }
+
+ @Override
+ public K getNextKey(@NonNull K key) {
+ // Expensive, but since this is only for tests...
+ Iterator<K> it = mMap.keySet().iterator();
+ while (it.hasNext()) {
+ if (Objects.equals(it.next(), key)) {
+ return it.hasNext() ? it.next() : null;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public K getFirstKey() {
+ for (K key : mMap.keySet()) {
+ return key;
+ }
+ return null;
+ }
+
+ @Override
+ public boolean containsKey(@NonNull K key) throws ErrnoException {
+ return mMap.containsKey(key);
+ }
+
+ @Override
+ public V getValue(@NonNull K key) throws ErrnoException {
+ // Return value for a given key. Otherwise, return null without an error ENOENT.
+ // BpfMap#getValue treats that the entry is not found as no error.
+ return mMap.get(key);
+ }
+
+ @Override
+ public void clear() throws ErrnoException {
+ // TODO: consider using mocked #getFirstKey and #deleteEntry to implement.
+ mMap.clear();
+ }
+}