1 /* 2 * Copyright (C) 2024 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 // ktlint does not allow annotating function argument literals inline. Disable the specific rule 17 // since this negatively affects readability. 18 @file:Suppress("ktlint:standard:comment-wrapping") 19 20 package com.android.server.ethernet 21 22 import android.content.Context 23 import android.net.NetworkCapabilities 24 import android.net.NetworkProvider 25 import android.net.NetworkProvider.NetworkOfferCallback 26 import android.os.Build 27 import android.os.Handler 28 import android.os.test.TestLooper 29 import androidx.test.filters.SmallTest 30 import com.android.testutils.DevSdkIgnoreRule 31 import com.android.testutils.DevSdkIgnoreRunner 32 import org.junit.Test 33 import org.junit.runner.RunWith 34 import org.mockito.ArgumentCaptor 35 import org.mockito.ArgumentMatchers.any 36 import org.mockito.ArgumentMatchers.eq 37 import org.mockito.Mock 38 import org.mockito.Mockito.inOrder 39 import org.mockito.Mockito.verify 40 import org.mockito.MockitoAnnotations 41 42 private const val IFACE = "eth0" 43 private val CAPS = NetworkCapabilities.Builder().build() 44 45 @SmallTest 46 @RunWith(DevSdkIgnoreRunner::class) 47 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2) 48 class EthernetInterfaceStateMachineTest { 49 private lateinit var looper: TestLooper 50 private lateinit var handler: Handler 51 private lateinit var ifaceState: EthernetInterfaceStateMachine 52 53 @Mock private lateinit var context: Context 54 @Mock private lateinit var provider: NetworkProvider 55 @Mock private lateinit var deps: EthernetNetworkFactory.Dependencies 56 57 // There seems to be no (obvious) way to force execution of @Before and @Test annotation on the 58 // same thread. Since SyncStateMachine requires all interactions to be called from the same 59 // thread that is provided at construction time (in this case, the thread that TestLooper() is 60 // called on), setUp() must be called directly from the @Test method. 61 // TODO: find a way to fix this in the test runner. setUpnull62 fun setUp() { 63 looper = TestLooper() 64 handler = Handler(looper.looper) 65 MockitoAnnotations.initMocks(this) 66 67 ifaceState = EthernetInterfaceStateMachine(IFACE, handler, context, CAPS, provider, deps) 68 } 69 70 @Test testUpdateLinkState_networkOfferRegisteredAndRetractednull71 fun testUpdateLinkState_networkOfferRegisteredAndRetracted() { 72 setUp() 73 74 ifaceState.updateLinkState(/* up= */ true) 75 76 // link comes up: validate the NetworkOffer is registered and capture callback object. 77 val inOrder = inOrder(provider) 78 val networkOfferCb = ArgumentCaptor.forClass(NetworkOfferCallback::class.java).also { 79 inOrder.verify(provider).registerNetworkOffer(any(), any(), any(), it.capture()) 80 }.value 81 82 ifaceState.updateLinkState(/* up */ false) 83 84 // link goes down: validate the NetworkOffer is retracted 85 inOrder.verify(provider).unregisterNetworkOffer(eq(networkOfferCb)) 86 } 87 } 88