1 /*
2  * Copyright (C) 2019 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.internal.net.ipsec.test.ike;
18 
19 import static com.android.internal.net.ipsec.test.ike.IkeLocalRequestScheduler.REQUEST_PRIORITY_HIGH;
20 import static com.android.internal.net.ipsec.test.ike.IkeLocalRequestScheduler.REQUEST_PRIORITY_NORMAL;
21 import static com.android.internal.net.ipsec.test.ike.IkeLocalRequestScheduler.REQUEST_PRIORITY_URGENT;
22 import static com.android.internal.net.ipsec.test.ike.IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE;
23 import static com.android.internal.net.ipsec.test.ike.IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE;
24 import static com.android.internal.net.ipsec.test.ike.IkeSessionStateMachine.CMD_LOCAL_REQUEST_MOBIKE;
25 
26 import static org.junit.Assert.assertEquals;
27 import static org.mockito.Matchers.any;
28 import static org.mockito.Mockito.any;
29 import static org.mockito.Mockito.anyInt;
30 import static org.mockito.Mockito.anyString;
31 import static org.mockito.Mockito.doReturn;
32 import static org.mockito.Mockito.eq;
33 import static org.mockito.Mockito.inOrder;
34 import static org.mockito.Mockito.mock;
35 import static org.mockito.Mockito.never;
36 import static org.mockito.Mockito.spy;
37 import static org.mockito.Mockito.times;
38 import static org.mockito.Mockito.verify;
39 import static org.mockito.Mockito.when;
40 
41 import android.content.Context;
42 import android.os.PowerManager;
43 import android.os.PowerManager.WakeLock;
44 
45 import androidx.test.InstrumentationRegistry;
46 
47 import com.android.internal.net.ipsec.test.ike.IkeLocalRequestScheduler.IProcedureConsumer;
48 import com.android.internal.net.ipsec.test.ike.IkeLocalRequestScheduler.LocalRequest;
49 import com.android.internal.net.ipsec.test.ike.IkeLocalRequestScheduler.LocalRequestFactory;
50 
51 import org.junit.Before;
52 import org.junit.Test;
53 import org.mockito.ArgumentCaptor;
54 import org.mockito.InOrder;
55 
56 public final class IkeLocalRequestSchedulerTest {
57     private static final int REQUESTS_TO_QUEUE = 10;
58 
59     private IkeLocalRequestScheduler mScheduler;
60 
61     private IProcedureConsumer mMockConsumer;
62     private LocalRequest[] mMockRequestArray;
63 
64     private int mNextRequestId;
65 
66     private ArgumentCaptor<LocalRequest> mLocalRequestCaptor =
67             ArgumentCaptor.forClass(LocalRequest.class);
68 
69     private Context mSpyContext;
70     private PowerManager mMockPowerManager;
71     protected PowerManager.WakeLock mMockWakelock;
72 
73     @Before
setUp()74     public void setUp() {
75         mMockConsumer = mock(IProcedureConsumer.class);
76 
77         mSpyContext = spy(InstrumentationRegistry.getContext());
78         mMockPowerManager = mock(PowerManager.class);
79         mMockWakelock = mock(WakeLock.class);
80 
81         doReturn(mMockPowerManager).when(mSpyContext).getSystemService(eq(PowerManager.class));
82         doReturn(mMockWakelock).when(mMockPowerManager).newWakeLock(anyInt(), anyString());
83 
84         mScheduler = new IkeLocalRequestScheduler(mMockConsumer, mSpyContext);
85 
86         mNextRequestId = 0;
87 
88         mMockRequestArray = new LocalRequest[REQUESTS_TO_QUEUE];
89         for (int i = 0; i < mMockRequestArray.length; i++) {
90             mMockRequestArray[i] = mock(LocalRequest.class);
91             when(mMockRequestArray[i].getPriority()).thenReturn(REQUEST_PRIORITY_NORMAL);
92         }
93     }
94 
95     @Test
testAddMultipleRequestProcessOnlyOne()96     public void testAddMultipleRequestProcessOnlyOne() {
97         addAllRequestsToScheduler(mMockRequestArray);
98 
99         // Verify that no procedure was preemptively pulled from the queue
100         verify(mMockConsumer, never()).onNewProcedureReady(any());
101 
102         // Check that the onNewPrcedureReady called exactly once, on the first item
103         mScheduler.readyForNextProcedure();
104         verify(mMockConsumer, times(1)).onNewProcedureReady(any());
105         verify(mMockConsumer, times(1)).onNewProcedureReady(mMockRequestArray[0]);
106         for (int i = 1; i < mMockRequestArray.length; i++) {
107             verify(mMockConsumer, never()).onNewProcedureReady(mMockRequestArray[i]);
108         }
109     }
110 
addAllRequestsToScheduler(LocalRequest[] mockRequests)111     private void addAllRequestsToScheduler(LocalRequest[] mockRequests) {
112         for (LocalRequest r : mockRequests) {
113             when(r.getRequestId()).thenReturn(mNextRequestId++);
114             mScheduler.addRequest(r);
115         }
116     }
117 
118     @Test
testProcessOrder()119     public void testProcessOrder() {
120         InOrder inOrder = inOrder(mMockConsumer);
121 
122         addAllRequestsToScheduler(mMockRequestArray);
123         for (int i = 0; i < mMockRequestArray.length; i++) mScheduler.readyForNextProcedure();
124 
125         for (LocalRequest r : mMockRequestArray) {
126             inOrder.verify(mMockConsumer).onNewProcedureReady(r);
127         }
128     }
129 
130     @Test
testPriorityProcessOrder()131     public void testPriorityProcessOrder() {
132         InOrder inOrder = inOrder(mMockConsumer);
133 
134         LocalRequest[] mockUrgentPriorityRequestArray =
135                 createMockRequestArrayWithPriority(REQUEST_PRIORITY_URGENT);
136         LocalRequest[] mockHighPriorityRequestArray =
137                 createMockRequestArrayWithPriority(REQUEST_PRIORITY_HIGH);
138 
139         addAllRequestsToScheduler(mMockRequestArray);
140         addAllRequestsToScheduler(mockHighPriorityRequestArray);
141         addAllRequestsToScheduler(mockUrgentPriorityRequestArray);
142 
143         int requestsToHandle =
144                 mockUrgentPriorityRequestArray.length
145                         + mockHighPriorityRequestArray.length
146                         + mMockRequestArray.length;
147         for (int i = 0; i < requestsToHandle; i++) {
148             mScheduler.readyForNextProcedure();
149         }
150 
151         // Verify processing order: mockUrgentPriorityRequestArray before
152         // mockHighPriorityRequestArray before mMockRequestArray
153         for (LocalRequest r : mockUrgentPriorityRequestArray) {
154             inOrder.verify(mMockConsumer).onNewProcedureReady(r);
155         }
156         for (LocalRequest r : mockHighPriorityRequestArray) {
157             inOrder.verify(mMockConsumer).onNewProcedureReady(r);
158         }
159         for (LocalRequest r : mMockRequestArray) {
160             inOrder.verify(mMockConsumer).onNewProcedureReady(r);
161         }
162     }
163 
createMockRequestArrayWithPriority(int requestPriority)164     private LocalRequest[] createMockRequestArrayWithPriority(int requestPriority) {
165         LocalRequest[] mockRequestArray = new LocalRequest[REQUESTS_TO_QUEUE];
166         for (int i = 0; i < mockRequestArray.length; i++) {
167             mockRequestArray[i] = mock(LocalRequest.class);
168 
169             when(mockRequestArray[i].getPriority()).thenReturn(requestPriority);
170         }
171         return mockRequestArray;
172     }
173 
174     @Test
testProcedureTypeToPriority()175     public void testProcedureTypeToPriority() {
176         assertEquals(
177                 REQUEST_PRIORITY_URGENT,
178                 LocalRequestFactory.procedureTypeToPriority(CMD_LOCAL_REQUEST_DELETE_IKE));
179         assertEquals(
180                 REQUEST_PRIORITY_HIGH,
181                 LocalRequestFactory.procedureTypeToPriority(CMD_LOCAL_REQUEST_MOBIKE));
182         assertEquals(
183                 REQUEST_PRIORITY_NORMAL,
184                 LocalRequestFactory.procedureTypeToPriority(CMD_LOCAL_REQUEST_CREATE_IKE));
185     }
186 }
187