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 com.android.server.vcn;
18 
19 import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertTrue;
24 import static org.mockito.Matchers.any;
25 import static org.mockito.Mockito.never;
26 import static org.mockito.Mockito.verify;
27 
28 import android.net.ipsec.ike.IkeSessionParams;
29 
30 import androidx.test.filters.SmallTest;
31 import androidx.test.runner.AndroidJUnit4;
32 
33 import org.junit.Before;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.mockito.ArgumentCaptor;
37 
38 /** Tests for VcnGatewayConnection.ConnectingState */
39 @RunWith(AndroidJUnit4.class)
40 @SmallTest
41 public class VcnGatewayConnectionConnectingStateTest extends VcnGatewayConnectionTestBase {
42     private VcnIkeSession mIkeSession;
43 
44     @Before
setUp()45     public void setUp() throws Exception {
46         super.setUp();
47 
48         mGatewayConnection.setUnderlyingNetwork(TEST_UNDERLYING_NETWORK_RECORD_1);
49         mGatewayConnection.transitionTo(mGatewayConnection.mConnectingState);
50         mTestLooper.dispatchAll();
51 
52         mIkeSession = mGatewayConnection.getIkeSession();
53     }
54 
55     @Test
testEnterStateCreatesNewIkeSession()56     public void testEnterStateCreatesNewIkeSession() throws Exception {
57         final ArgumentCaptor<IkeSessionParams> paramsCaptor =
58                 ArgumentCaptor.forClass(IkeSessionParams.class);
59         verify(mDeps).newIkeSession(any(), paramsCaptor.capture(), any(), any(), any());
60         assertEquals(
61                 TEST_UNDERLYING_NETWORK_RECORD_1.network, paramsCaptor.getValue().getNetwork());
62     }
63 
64     @Test
testNullNetworkTriggersDisconnect()65     public void testNullNetworkTriggersDisconnect() throws Exception {
66         mGatewayConnection
67                 .getUnderlyingNetworkControllerCallback()
68                 .onSelectedUnderlyingNetworkChanged(null);
69         mTestLooper.dispatchAll();
70 
71         assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
72         verify(mIkeSession).kill();
73         verifyDisconnectRequestAlarmAndGetCallback(false /* expectCanceled */);
74     }
75 
76     @Test
testNewNetworkTriggersReconnect()77     public void testNewNetworkTriggersReconnect() throws Exception {
78         mGatewayConnection
79                 .getUnderlyingNetworkControllerCallback()
80                 .onSelectedUnderlyingNetworkChanged(TEST_UNDERLYING_NETWORK_RECORD_2);
81         mTestLooper.dispatchAll();
82 
83         assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
84         verify(mIkeSession).close();
85         verify(mIkeSession, never()).kill();
86         verifyTeardownTimeoutAlarmAndGetCallback(false /* expectCanceled */);
87     }
88 
89     @Test
testSameNetworkDoesNotTriggerReconnect()90     public void testSameNetworkDoesNotTriggerReconnect() throws Exception {
91         mGatewayConnection
92                 .getUnderlyingNetworkControllerCallback()
93                 .onSelectedUnderlyingNetworkChanged(TEST_UNDERLYING_NETWORK_RECORD_1);
94         mTestLooper.dispatchAll();
95 
96         assertEquals(mGatewayConnection.mConnectingState, mGatewayConnection.getCurrentState());
97     }
98 
99     @Test
testChildSessionClosedTriggersDisconnect()100     public void testChildSessionClosedTriggersDisconnect() throws Exception {
101         getChildSessionCallback().onClosed();
102         mTestLooper.dispatchAll();
103 
104         assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
105         verify(mIkeSession).close();
106         verifyTeardownTimeoutAlarmAndGetCallback(false /* expectCanceled */);
107     }
108 
109     @Test
testIkeSessionClosedTriggersDisconnect()110     public void testIkeSessionClosedTriggersDisconnect() throws Exception {
111         getIkeSessionCallback().onClosed();
112         mTestLooper.dispatchAll();
113 
114         assertEquals(mGatewayConnection.mRetryTimeoutState, mGatewayConnection.getCurrentState());
115         verify(mIkeSession).close();
116         verifyTeardownTimeoutAlarmAndGetCallback(true /* expectCanceled */);
117     }
118 
119     @Test
testSafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent()120     public void testSafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent() {
121         verifySafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent(
122                 mGatewayConnection.mConnectingState);
123     }
124 
125     @Test
testTeardown()126     public void testTeardown() throws Exception {
127         mGatewayConnection.teardownAsynchronously();
128         mTestLooper.dispatchAll();
129 
130         // Verify that sending a non-quitting disconnect request does not unset the isQuitting flag
131         mGatewayConnection.sendDisconnectRequestedAndAcquireWakelock("TEST", false);
132         mTestLooper.dispatchAll();
133 
134         assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
135         assertTrue(mGatewayConnection.isQuitting());
136     }
137 
138     @Test
testNonTeardownDisconnectRequest()139     public void testNonTeardownDisconnectRequest() throws Exception {
140         mGatewayConnection.sendDisconnectRequestedAndAcquireWakelock("TEST", false);
141         mTestLooper.dispatchAll();
142 
143         assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
144         assertFalse(mGatewayConnection.isQuitting());
145     }
146 }
147