1 /*
2  * Copyright (C) 2020 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 android.net.networkstack
18 
19 import android.content.Context
20 import android.net.IIpMemoryStoreCallbacks
21 import android.net.INetworkMonitorCallbacks
22 import android.net.INetworkStackConnector
23 import android.net.Network
24 import android.net.NetworkStack
25 import android.net.dhcp.DhcpServingParamsParcel
26 import android.net.dhcp.IDhcpServerCallbacks
27 import android.net.ip.IIpClientCallbacks
28 import android.os.Build
29 import android.os.IBinder
30 import androidx.test.ext.junit.runners.AndroidJUnit4
31 import androidx.test.filters.SmallTest
32 import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
33 import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
34 import com.android.testutils.DevSdkIgnoreRule
35 import org.junit.After
36 import org.junit.Before
37 import org.junit.Rule
38 import org.junit.Test
39 import org.junit.runner.RunWith
40 import org.mockito.ArgumentMatchers.any
41 import org.mockito.Mock
42 import org.mockito.Mockito.never
43 import org.mockito.Mockito.timeout
44 import org.mockito.Mockito.verify
45 import org.mockito.MockitoAnnotations
46 
47 @RunWith(AndroidJUnit4::class)
48 @SmallTest
49 class ModuleNetworkStackClientTest {
50     private val TEST_IFNAME = "testiface"
51     private val TEST_NETWORK = Network(43)
52     private val TEST_TIMEOUT_MS = 500L
53 
54     // ModuleNetworkStackClient is only available after Q
55     @Rule @JvmField
56     val mIgnoreRule = DevSdkIgnoreRule(ignoreClassUpTo = Build.VERSION_CODES.Q)
57 
58     @Mock
59     private lateinit var mContext: Context
60     @Mock
61     private lateinit var mConnectorBinder: IBinder
62     @Mock
63     private lateinit var mConnector: INetworkStackConnector
64     @Mock
65     private lateinit var mIpClientCb: IIpClientCallbacks
66     @Mock
67     private lateinit var mDhcpServerCb: IDhcpServerCallbacks
68     @Mock
69     private lateinit var mNetworkMonitorCb: INetworkMonitorCallbacks
70     @Mock
71     private lateinit var mIpMemoryStoreCb: IIpMemoryStoreCallbacks
72 
73     @Before
setUpnull74     fun setUp() {
75         MockitoAnnotations.initMocks(this)
76         // Use DESCRIPTOR and not class name, as the descriptor is the original class name before
77         // jarjar, and is always what is used to query the interface.
78         doReturn(mConnector).`when`(mConnectorBinder).queryLocalInterface(
79                 INetworkStackConnector.DESCRIPTOR)
80     }
81 
82     @After
tearDownnull83     fun tearDown() {
84         ModuleNetworkStackClient.resetInstanceForTest()
85         NetworkStack.setServiceForTest(null)
86     }
87 
88     @Test
testIpClientServiceAvailableImmediatelynull89     fun testIpClientServiceAvailableImmediately() {
90         NetworkStack.setServiceForTest(mConnectorBinder)
91         ModuleNetworkStackClient.getInstance(mContext).makeIpClient(TEST_IFNAME, mIpClientCb)
92         verify(mConnector).makeIpClient(TEST_IFNAME, mIpClientCb)
93     }
94 
95     @Test
testIpClientServiceAvailableAfterPollingnull96     fun testIpClientServiceAvailableAfterPolling() {
97         // Force NetworkStack.getService() to return null: this cannot be done with
98         // setServiceForTest, as passing null just restores default behavior.
99         val session = mockitoSession().spyStatic(NetworkStack::class.java).startMocking()
100         try {
101             doReturn(null).`when` { NetworkStack.getService() }
102             ModuleNetworkStackClient.getInstance(mContext).makeIpClient(TEST_IFNAME, mIpClientCb)
103 
104             Thread.sleep(TEST_TIMEOUT_MS)
105             verify(mConnector, never()).makeIpClient(any(), any())
106             NetworkStack.setServiceForTest(mConnectorBinder)
107         } finally {
108             // Restore behavior of NetworkStack to return what was set in setServiceForTest
109             session.finishMocking()
110         }
111 
112         // Use a longer timeout as polling can cause larger delays
113         verify(mConnector, timeout(TEST_TIMEOUT_MS * 4)).makeIpClient(TEST_IFNAME, mIpClientCb)
114     }
115 
116     @Test
testDhcpServerAvailableImmediatelynull117     fun testDhcpServerAvailableImmediately() {
118         NetworkStack.setServiceForTest(mConnectorBinder)
119         val testParams = DhcpServingParamsParcel()
120         ModuleNetworkStackClient.getInstance(mContext).makeDhcpServer(TEST_IFNAME, testParams,
121                 mDhcpServerCb)
122         verify(mConnector).makeDhcpServer(TEST_IFNAME, testParams, mDhcpServerCb)
123     }
124 
125     @Test
testNetworkMonitorAvailableImmediatelynull126     fun testNetworkMonitorAvailableImmediately() {
127         NetworkStack.setServiceForTest(mConnectorBinder)
128         val testName = "NetworkMonitorName"
129         ModuleNetworkStackClient.getInstance(mContext).makeNetworkMonitor(TEST_NETWORK, testName,
130                 mNetworkMonitorCb)
131         verify(mConnector).makeNetworkMonitor(TEST_NETWORK, testName, mNetworkMonitorCb)
132     }
133 
134     @Test
testIpMemoryStoreAvailableImmediatelynull135     fun testIpMemoryStoreAvailableImmediately() {
136         NetworkStack.setServiceForTest(mConnectorBinder)
137         ModuleNetworkStackClient.getInstance(mContext).fetchIpMemoryStore(mIpMemoryStoreCb)
138         verify(mConnector).fetchIpMemoryStore(mIpMemoryStoreCb)
139     }
140 }