13fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi/* 23fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi * Copyright (C) 2017 The Android Open Source Project 33fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi * 43fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi * Licensed under the Apache License, Version 2.0 (the "License"); 53fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi * you may not use this file except in compliance with the License. 63fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi * You may obtain a copy of the License at 73fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi * 83fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi * http://www.apache.org/licenses/LICENSE-2.0 93fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi * 103fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi * Unless required by applicable law or agreed to in writing, software 113fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi * distributed under the License is distributed on an "AS IS" BASIS, 123fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi * See the License for the specific language governing permissions and 143fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi * limitations under the License. 153fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi */ 163fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 173fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichipackage com.android.server.connectivity; 183fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 193fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport static org.junit.Assert.assertFalse; 203fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport static org.junit.Assert.assertNull; 213fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport static org.junit.Assert.assertTrue; 223fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport static org.mockito.Mockito.any; 233fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport static org.mockito.Mockito.eq; 243fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport static org.mockito.Mockito.times; 253fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport static org.mockito.Mockito.verify; 263fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport static org.mockito.Mockito.verifyNoMoreInteractions; 273fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport static org.mockito.Mockito.when; 283fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 293fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport android.net.ConnectivityManager; 303fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport android.net.InterfaceConfiguration; 313fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport android.net.LinkAddress; 323fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport android.net.LinkProperties; 333fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport android.net.NetworkInfo; 343fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport android.os.Handler; 353fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport android.os.INetworkManagementService; 363fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport android.os.test.TestLooper; 373fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport android.support.test.filters.SmallTest; 383fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport android.support.test.runner.AndroidJUnit4; 393fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 403fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport com.android.server.ConnectivityService; 413fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 423fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport org.junit.Before; 433fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport org.junit.Test; 443fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport org.junit.runner.RunWith; 453fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport org.mockito.ArgumentCaptor; 463fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport org.mockito.Mock; 473fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichiimport org.mockito.MockitoAnnotations; 483fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 493fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi@RunWith(AndroidJUnit4.class) 503fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi@SmallTest 513fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichipublic class Nat464XlatTest { 523fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 533fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi static final String BASE_IFACE = "test0"; 543fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi static final String STACKED_IFACE = "v4-test0"; 553fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi static final LinkAddress ADDR = new LinkAddress("192.0.2.5/29"); 563fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 573fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi @Mock ConnectivityService mConnectivity; 583fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi @Mock INetworkManagementService mNms; 593fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi @Mock InterfaceConfiguration mConfig; 603fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi @Mock NetworkAgentInfo mNai; 613fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 623fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi TestLooper mLooper; 633fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi Handler mHandler; 643fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 653fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi Nat464Xlat makeNat464Xlat() { 663fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi return new Nat464Xlat(mNms, mNai); 673fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi } 683fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 693fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi @Before 703fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi public void setUp() throws Exception { 713fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi mLooper = new TestLooper(); 723fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi mHandler = new Handler(mLooper.getLooper()); 733fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 743fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi MockitoAnnotations.initMocks(this); 753fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 763fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi mNai.linkProperties = new LinkProperties(); 773fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi mNai.linkProperties.setInterfaceName(BASE_IFACE); 783fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi mNai.networkInfo = new NetworkInfo(null); 793fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi mNai.networkInfo.setType(ConnectivityManager.TYPE_WIFI); 803fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi when(mNai.connService()).thenReturn(mConnectivity); 813fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi when(mNai.handler()).thenReturn(mHandler); 823fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 833fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi when(mNms.getInterfaceConfig(eq(STACKED_IFACE))).thenReturn(mConfig); 843fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi when(mConfig.getLinkAddress()).thenReturn(ADDR); 853fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi } 863fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 873fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi @Test 883fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi public void testNormalStartAndStop() throws Exception { 893fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi Nat464Xlat nat = makeNat464Xlat(); 903fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class); 913fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 923fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi // ConnectivityService starts clat. 933fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi nat.start(); 943fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 953fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).registerObserver(eq(nat)); 963fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).startClatd(eq(BASE_IFACE)); 973fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 983fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi // Stacked interface up notification arrives. 993fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi nat.interfaceLinkStateChanged(STACKED_IFACE, true); 1003fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi mLooper.dispatchNext(); 1013fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1023fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).getInterfaceConfig(eq(STACKED_IFACE)); 1033fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).setInterfaceIpv6NdOffload(eq(BASE_IFACE), eq(false)); 1043fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mConnectivity).handleUpdateLinkProperties(eq(mNai), c.capture()); 1053fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi assertFalse(c.getValue().getStackedLinks().isEmpty()); 1063fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi assertTrue(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); 1073fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi assertRunning(nat); 1083fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1093fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi // ConnectivityService stops clat (Network disconnects, IPv4 addr appears, ...). 1103fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi nat.stop(); 1113fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1123fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).stopClatd(eq(BASE_IFACE)); 1133fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).setInterfaceIpv6NdOffload(eq(BASE_IFACE), eq(true)); 1143fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1153fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi // Stacked interface removed notification arrives. 1163fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi nat.interfaceRemoved(STACKED_IFACE); 1173fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi mLooper.dispatchNext(); 1183fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1193fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).unregisterObserver(eq(nat)); 1203fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture()); 1213fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi assertTrue(c.getValue().getStackedLinks().isEmpty()); 1223fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); 1233fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi assertIdle(nat); 1243fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1253fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verifyNoMoreInteractions(mNms, mConnectivity); 1263fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi } 1273fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1283fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi @Test 1293fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi public void testClatdCrashWhileRunning() throws Exception { 1303fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi Nat464Xlat nat = makeNat464Xlat(); 1313fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class); 1323fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1333fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi // ConnectivityService starts clat. 1343fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi nat.start(); 1353fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1363fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).registerObserver(eq(nat)); 1373fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).startClatd(eq(BASE_IFACE)); 1383fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1393fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi // Stacked interface up notification arrives. 1403fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi nat.interfaceLinkStateChanged(STACKED_IFACE, true); 1413fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi mLooper.dispatchNext(); 1423fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1433fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).getInterfaceConfig(eq(STACKED_IFACE)); 1443fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).setInterfaceIpv6NdOffload(eq(BASE_IFACE), eq(false)); 1453fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mConnectivity, times(1)).handleUpdateLinkProperties(eq(mNai), c.capture()); 1463fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi assertFalse(c.getValue().getStackedLinks().isEmpty()); 1473fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi assertTrue(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); 1483fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi assertRunning(nat); 1493fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1503fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi // Stacked interface removed notification arrives (clatd crashed, ...). 1513fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi nat.interfaceRemoved(STACKED_IFACE); 1523fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi mLooper.dispatchNext(); 1533fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1543fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).unregisterObserver(eq(nat)); 1553fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).stopClatd(eq(BASE_IFACE)); 1563fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).setInterfaceIpv6NdOffload(eq(BASE_IFACE), eq(true)); 1573fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture()); 1583fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi assertTrue(c.getValue().getStackedLinks().isEmpty()); 1593fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); 1603fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi assertIdle(nat); 1613fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1623fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi // ConnectivityService stops clat: no-op. 1633fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi nat.stop(); 1643fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1653fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verifyNoMoreInteractions(mNms, mConnectivity); 1663fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi } 1673fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1683fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi @Test 1693fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi public void testStopBeforeClatdStarts() throws Exception { 1703fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi Nat464Xlat nat = makeNat464Xlat(); 1713fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1723fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi // ConnectivityService starts clat. 1733fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi nat.start(); 1743fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1753fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).registerObserver(eq(nat)); 1763fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).startClatd(eq(BASE_IFACE)); 1773fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1783fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi // ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...) 1793fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi nat.stop(); 1803fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1813fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).unregisterObserver(eq(nat)); 1823fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).stopClatd(eq(BASE_IFACE)); 1833fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi assertIdle(nat); 1843fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1853fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi // In-flight interface up notification arrives: no-op 1863fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi nat.interfaceLinkStateChanged(STACKED_IFACE, true); 1873fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi mLooper.dispatchNext(); 1883fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1893fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1903fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi // Interface removed notification arrives after stopClatd() takes effect: no-op. 1913fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi nat.interfaceRemoved(STACKED_IFACE); 1923fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi mLooper.dispatchNext(); 1933fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1943fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi assertIdle(nat); 1953fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1963fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verifyNoMoreInteractions(mNms, mConnectivity); 1973fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi } 1983fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 1993fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi @Test 2003fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi public void testStopAndClatdNeverStarts() throws Exception { 2013fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi Nat464Xlat nat = makeNat464Xlat(); 2023fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 2033fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi // ConnectivityService starts clat. 2043fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi nat.start(); 2053fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 2063fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).registerObserver(eq(nat)); 2073fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).startClatd(eq(BASE_IFACE)); 2083fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 2093fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi // ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...) 2103fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi nat.stop(); 2113fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 2123fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).unregisterObserver(eq(nat)); 2133fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verify(mNms).stopClatd(eq(BASE_IFACE)); 2143fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi assertIdle(nat); 2153fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 2163fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi verifyNoMoreInteractions(mNms, mConnectivity); 2173fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi } 2183fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 2193fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi static void assertIdle(Nat464Xlat nat) { 2203fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi assertTrue("Nat464Xlat was not IDLE", !nat.isStarted()); 2213fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi } 2223fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi 2233fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi static void assertRunning(Nat464Xlat nat) { 2243fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi assertTrue("Nat464Xlat was not RUNNING", nat.isRunning()); 2253fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi } 2263fb5f0db3ffe658fe039f0453c6bc0c46fd5441aHugo Benichi} 227