1 /*
2  * Copyright (C) 2022 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 package com.android.server.net;
18 
19 import static android.system.OsConstants.EPERM;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertNull;
23 import static org.junit.Assert.assertTrue;
24 import static org.mockito.Mockito.doThrow;
25 import static org.mockito.Mockito.spy;
26 
27 import android.os.Build;
28 import android.system.ErrnoException;
29 import android.util.IndentingPrintWriter;
30 
31 import androidx.test.filters.SmallTest;
32 
33 import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
34 import com.android.net.module.util.IBpfMap;
35 import com.android.net.module.util.Struct.S32;
36 import com.android.testutils.DevSdkIgnoreRule;
37 import com.android.testutils.DevSdkIgnoreRunner;
38 import com.android.testutils.TestBpfMap;
39 
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 import org.mockito.MockitoAnnotations;
44 
45 import java.io.PrintWriter;
46 import java.io.StringWriter;
47 
48 @SmallTest
49 @RunWith(DevSdkIgnoreRunner.class)
50 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
51 public final class BpfInterfaceMapHelperTest {
52     private static final int TEST_INDEX = 1;
53     private static final int TEST_INDEX2 = 2;
54     private static final String TEST_INTERFACE_NAME = "test1";
55     private static final String TEST_INTERFACE_NAME2 = "test2";
56 
57     private BaseNetdUnsolicitedEventListener mListener;
58     private BpfInterfaceMapHelper mUpdater;
59     private IBpfMap<S32, InterfaceMapValue> mBpfMap =
60             spy(new TestBpfMap<>(S32.class, InterfaceMapValue.class));
61 
62     private class TestDependencies extends BpfInterfaceMapHelper.Dependencies {
63         @Override
getInterfaceMap()64         public IBpfMap<S32, InterfaceMapValue> getInterfaceMap() {
65             return mBpfMap;
66         }
67     }
68 
69     @Before
setUp()70     public void setUp() throws Exception {
71         MockitoAnnotations.initMocks(this);
72         mUpdater = new BpfInterfaceMapHelper(new TestDependencies());
73     }
74 
75     @Test
testGetIfNameByIndex()76     public void testGetIfNameByIndex() throws Exception {
77         mBpfMap.updateEntry(new S32(TEST_INDEX), new InterfaceMapValue(TEST_INTERFACE_NAME));
78         assertEquals(TEST_INTERFACE_NAME, mUpdater.getIfNameByIndex(TEST_INDEX));
79     }
80 
81     @Test
testGetIfNameByIndexNoEntry()82     public void testGetIfNameByIndexNoEntry() {
83         assertNull(mUpdater.getIfNameByIndex(TEST_INDEX));
84     }
85 
86     @Test
testGetIfNameByIndexException()87     public void testGetIfNameByIndexException() throws Exception {
88         doThrow(new ErrnoException("", EPERM)).when(mBpfMap).getValue(new S32(TEST_INDEX));
89         assertNull(mUpdater.getIfNameByIndex(TEST_INDEX));
90     }
91 
assertDumpContains(final String dump, final String message)92     private void assertDumpContains(final String dump, final String message) {
93         assertTrue(String.format("dump(%s) does not contain '%s'", dump, message),
94                 dump.contains(message));
95     }
96 
getDump()97     private String getDump() {
98         final StringWriter sw = new StringWriter();
99         mUpdater.dump(new IndentingPrintWriter(new PrintWriter(sw), " "));
100         return sw.toString();
101     }
102 
103     @Test
testDump()104     public void testDump() throws ErrnoException {
105         mBpfMap.updateEntry(new S32(TEST_INDEX), new InterfaceMapValue(TEST_INTERFACE_NAME));
106         mBpfMap.updateEntry(new S32(TEST_INDEX2), new InterfaceMapValue(TEST_INTERFACE_NAME2));
107 
108         final String dump = getDump();
109         assertDumpContains(dump, "IfaceIndexNameMap: OK");
110         assertDumpContains(dump, "ifaceIndex=1 ifaceName=test1");
111         assertDumpContains(dump, "ifaceIndex=2 ifaceName=test2");
112     }
113 }
114