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 org.mockito.Matchers.eq; 20 import static org.mockito.Mockito.verify; 21 import static org.mockito.Mockito.verifyNoMoreInteractions; 22 import static org.mockito.Mockito.when; 23 24 import android.content.Context; 25 import android.net.INetd; 26 import android.net.MacAddress; 27 import android.os.Handler; 28 import android.os.test.TestLooper; 29 30 import androidx.test.filters.SmallTest; 31 import androidx.test.runner.AndroidJUnit4; 32 33 import com.android.net.module.util.BaseNetdUnsolicitedEventListener; 34 import com.android.net.module.util.IBpfMap; 35 import com.android.net.module.util.InterfaceParams; 36 import com.android.net.module.util.Struct.U32; 37 38 import org.junit.Before; 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 import org.mockito.ArgumentCaptor; 42 import org.mockito.Mock; 43 import org.mockito.MockitoAnnotations; 44 45 @RunWith(AndroidJUnit4.class) 46 @SmallTest 47 public final class BpfInterfaceMapUpdaterTest { 48 private static final int TEST_INDEX = 1; 49 private static final int TEST_INDEX2 = 2; 50 private static final String TEST_INTERFACE_NAME = "test1"; 51 private static final String TEST_INTERFACE_NAME2 = "test2"; 52 53 private final TestLooper mLooper = new TestLooper(); 54 private BaseNetdUnsolicitedEventListener mListener; 55 private BpfInterfaceMapUpdater mUpdater; 56 @Mock private IBpfMap<U32, InterfaceMapValue> mBpfMap; 57 @Mock private INetd mNetd; 58 @Mock private Context mContext; 59 60 private class TestDependencies extends BpfInterfaceMapUpdater.Dependencies { 61 @Override getInterfaceMap()62 public IBpfMap<U32, InterfaceMapValue> getInterfaceMap() { 63 return mBpfMap; 64 } 65 66 @Override getInterfaceParams(String ifaceName)67 public InterfaceParams getInterfaceParams(String ifaceName) { 68 if (ifaceName.equals(TEST_INTERFACE_NAME)) { 69 return new InterfaceParams(TEST_INTERFACE_NAME, TEST_INDEX, 70 MacAddress.ALL_ZEROS_ADDRESS); 71 } else if (ifaceName.equals(TEST_INTERFACE_NAME2)) { 72 return new InterfaceParams(TEST_INTERFACE_NAME2, TEST_INDEX2, 73 MacAddress.ALL_ZEROS_ADDRESS); 74 } 75 76 return null; 77 } 78 79 @Override getINetd(Context ctx)80 public INetd getINetd(Context ctx) { 81 return mNetd; 82 } 83 } 84 85 @Before setUp()86 public void setUp() throws Exception { 87 MockitoAnnotations.initMocks(this); 88 when(mNetd.interfaceGetList()).thenReturn(new String[] {TEST_INTERFACE_NAME}); 89 mUpdater = new BpfInterfaceMapUpdater(mContext, new Handler(mLooper.getLooper()), 90 new TestDependencies()); 91 } 92 verifyStartUpdater()93 private void verifyStartUpdater() throws Exception { 94 mUpdater.start(); 95 mLooper.dispatchAll(); 96 final ArgumentCaptor<BaseNetdUnsolicitedEventListener> listenerCaptor = 97 ArgumentCaptor.forClass(BaseNetdUnsolicitedEventListener.class); 98 verify(mNetd).registerUnsolicitedEventListener(listenerCaptor.capture()); 99 mListener = listenerCaptor.getValue(); 100 verify(mBpfMap).updateEntry(eq(new U32(TEST_INDEX)), 101 eq(new InterfaceMapValue(TEST_INTERFACE_NAME))); 102 } 103 104 @Test testUpdateInterfaceMap()105 public void testUpdateInterfaceMap() throws Exception { 106 verifyStartUpdater(); 107 108 mListener.onInterfaceAdded(TEST_INTERFACE_NAME2); 109 mLooper.dispatchAll(); 110 verify(mBpfMap).updateEntry(eq(new U32(TEST_INDEX2)), 111 eq(new InterfaceMapValue(TEST_INTERFACE_NAME2))); 112 113 // Check that when onInterfaceRemoved is called, nothing happens. 114 mListener.onInterfaceRemoved(TEST_INTERFACE_NAME); 115 mLooper.dispatchAll(); 116 verifyNoMoreInteractions(mBpfMap); 117 } 118 } 119