1 /*
2  * Copyright (C) 2010 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 package com.android.tradefed.device;
17 
18 import static org.mockito.Mockito.mock;
19 import static org.mockito.Mockito.when;
20 
21 import com.android.ddmlib.IDevice;
22 import com.android.tradefed.command.remote.DeviceDescriptor;
23 import com.android.tradefed.device.ITestDevice.RecoveryMode;
24 import com.android.tradefed.util.CommandResult;
25 import com.android.tradefed.util.ConditionPriorityBlockingQueue;
26 import com.android.tradefed.util.ConditionPriorityBlockingQueue.IMatcher;
27 import com.android.tradefed.util.IRunUtil;
28 
29 import org.junit.Assert;
30 import org.mockito.Mockito;
31 
32 import java.io.PrintWriter;
33 import java.util.ArrayList;
34 import java.util.List;
35 import java.util.concurrent.TimeUnit;
36 
37 /**
38  * A {@link IDeviceManager} that simulates the resource allocation of {@link DeviceManager} for a
39  * configurable set of devices.
40  */
41 public class MockDeviceManager implements IDeviceManager {
42 
43     // acts as an available device queue
44     ConditionPriorityBlockingQueue<ITestDevice> mAvailableDeviceQueue =
45             new ConditionPriorityBlockingQueue<ITestDevice>();
46 
47     private int mTotalDevices;
48     private DeviceMonitorMultiplexer mDvcMon = new DeviceMonitorMultiplexer();
49     private boolean mGceDeviceRequested = false;
50     private boolean mNullDeviceRequested = false;
51     private boolean mStubDeviceRequested = false;
52     private int mStopAdbBridgeCallCount = 0;
53     private int mRestartAdbBridgeCallCount = 0;
54 
MockDeviceManager(int numDevices)55     public MockDeviceManager(int numDevices) {
56         setNumDevices(numDevices);
57     }
58 
setNumDevices(int numDevices)59     public void setNumDevices(int numDevices) {
60         setNumDevicesInternal(numDevices, true);
61     }
62 
setNumDevicesUnresponsive(int numDevices)63     public void setNumDevicesUnresponsive(int numDevices) {
64         setNumDevicesInternal(numDevices, false);
65     }
66 
setNumDevicesInternal(int numDevices, boolean responsive)67     private void setNumDevicesInternal(int numDevices, boolean responsive) {
68         mAvailableDeviceQueue.clear();
69         mTotalDevices = numDevices;
70         for (int i = 0; i < numDevices; i++) {
71             ITestDevice mockDevice = mock(ITestDevice.class);
72             when(mockDevice.getSerialNumber()).thenReturn("serial" + i);
73             IDevice mockIDevice = mock(IDevice.class);
74             when(mockIDevice.getSerialNumber()).thenReturn("serial" + i);
75             when(mockDevice.getIDevice()).thenReturn(mockIDevice);
76             when(mockDevice.getDeviceState()).thenReturn(TestDeviceState.ONLINE);
77             when(mockDevice.waitForDeviceShell(Mockito.anyLong())).thenReturn(responsive);
78 
79             mAvailableDeviceQueue.add(mockDevice);
80         }
81     }
82 
83     /** Create a real {@link ITestDevice} with recovery mode NONE */
setNumDevicesCustomRealNoRecovery(int numDevices, Class<IDevice> idevicetype)84     public void setNumDevicesCustomRealNoRecovery(int numDevices, Class<IDevice> idevicetype) {
85         mAvailableDeviceQueue.clear();
86         mTotalDevices = numDevices;
87         for (int i = 0; i < numDevices; i++) {
88             IDevice mockIDevice = mock(idevicetype);
89             when(mockIDevice.getSerialNumber()).thenReturn("serial" + i);
90             IDeviceStateMonitor stateMonitor = mock(IDeviceStateMonitor.class);
91             IDeviceMonitor allocationMonitor = mock(IDeviceMonitor.class);
92 
93             ITestDevice mockDevice =
94                     new TestDevice(mockIDevice, stateMonitor, allocationMonitor) {
95                         @Override
96                         public boolean waitForDeviceShell(long waitTime) {
97                             return true;
98                         }
99                     };
100             mockDevice.setRecoveryMode(RecoveryMode.NONE);
101             mAvailableDeviceQueue.add(mockDevice);
102         }
103     }
104 
setNumDevicesCustom( int numDevices, TestDeviceState state, Class<? extends IDevice> idevicetype)105     public void setNumDevicesCustom(
106             int numDevices, TestDeviceState state, Class<? extends IDevice> idevicetype) {
107         mAvailableDeviceQueue.clear();
108         mTotalDevices = numDevices;
109         for (int i = 0; i < numDevices; i++) {
110             ITestDevice mockDevice = mock(ITestDevice.class);
111             when(mockDevice.getSerialNumber()).thenReturn("serial" + i);
112             IDevice mockIDevice = mock(idevicetype);
113             when(mockIDevice.getSerialNumber()).thenReturn("serial" + i);
114             when(mockDevice.getIDevice()).thenReturn(mockIDevice);
115             when(mockDevice.getDeviceState()).thenReturn(state);
116 
117             mAvailableDeviceQueue.add(mockDevice);
118         }
119     }
120 
setNumDevicesStub(int numDevices, TestDeviceState state, IDevice idevice)121     public void setNumDevicesStub(int numDevices, TestDeviceState state, IDevice idevice) {
122         if (idevice instanceof RemoteAvdIDevice) {
123             mGceDeviceRequested = true;
124         } else if (idevice instanceof NullDevice) {
125             mNullDeviceRequested = true;
126         } else if (idevice instanceof StubDevice) {
127             mStubDeviceRequested = true;
128         }
129         mAvailableDeviceQueue.clear();
130         mTotalDevices = numDevices;
131         for (int i = 0; i < numDevices; i++) {
132             ITestDevice mockDevice = mock(ITestDevice.class);
133             when(mockDevice.getSerialNumber()).thenReturn("serial" + i);
134             IDevice mockIDevice = idevice;
135             // when(mockIDevice.getSerialNumber()).thenReturn("serial" + i);
136             when(mockDevice.getIDevice()).thenReturn(mockIDevice);
137             when(mockDevice.getDeviceState()).thenReturn(state);
138 
139             mAvailableDeviceQueue.add(mockDevice);
140         }
141     }
142 
addDevice(ITestDevice mockDevice)143     public void addDevice(ITestDevice mockDevice) {
144         mTotalDevices += 1;
145         mAvailableDeviceQueue.add(mockDevice);
146     }
147 
clearAllDevices()148     public void clearAllDevices() {
149         mTotalDevices = 0;
150         mAvailableDeviceQueue.clear();
151     }
152 
153     private static class TestDeviceMatcher implements IMatcher<ITestDevice> {
154         private IDeviceSelection mDeviceOptions;
155 
156         /**
157          * @param deviceSelectionOptions
158          */
TestDeviceMatcher(IDeviceSelection deviceSelectionOptions)159         public TestDeviceMatcher(IDeviceSelection deviceSelectionOptions) {
160             mDeviceOptions = deviceSelectionOptions;
161         }
162 
163         /** {@inheritDoc} */
164         @Override
matches(ITestDevice element)165         public boolean matches(ITestDevice element) {
166             return mDeviceOptions.matches(element.getIDevice());
167         }
168     }
169 
getQueueOfAvailableDeviceSize()170     public int getQueueOfAvailableDeviceSize() {
171         return mAvailableDeviceQueue.size();
172     }
173 
174     /** {@inheritDoc} */
175     @Override
addFastbootListener(IFastbootListener listener)176     public void addFastbootListener(IFastbootListener listener) {
177         // ignore
178     }
179 
180     /** {@inheritDoc} */
181     @Override
allocateDevice()182     public ITestDevice allocateDevice() {
183         try {
184             return mAvailableDeviceQueue.take();
185         } catch (InterruptedException e) {
186             return null;
187         }
188     }
189 
190     /** {@inheritDoc} */
191     @Override
allocateDevice(IDeviceSelection options)192     public ITestDevice allocateDevice(IDeviceSelection options) {
193         return allocateDevice(options, false);
194     }
195 
196     /** {@inheritDoc} */
197     @Override
allocateDevice(IDeviceSelection options, boolean isTemporary)198     public ITestDevice allocateDevice(IDeviceSelection options, boolean isTemporary) {
199         if (mGceDeviceRequested) {
200             ((DeviceSelectionOptions) options).setGceDeviceRequested(true);
201         }
202         if (mNullDeviceRequested) {
203             ((DeviceSelectionOptions) options).setNullDeviceRequested(true);
204         }
205         if (mStubDeviceRequested) {
206             ((DeviceSelectionOptions) options).setStubEmulatorRequested(true);
207         }
208         ITestDevice d = mAvailableDeviceQueue.poll(new TestDeviceMatcher(options));
209         if (d != null) {
210             mDvcMon.notifyDeviceStateChange(
211                     d.getSerialNumber(),
212                     DeviceAllocationState.Available,
213                     DeviceAllocationState.Allocated);
214         }
215         return d;
216     }
217 
218     /** {@inheritDoc} */
219     @Override
freeDevice(ITestDevice device, FreeDeviceState state)220     public void freeDevice(ITestDevice device, FreeDeviceState state) {
221         if (!state.equals(FreeDeviceState.UNAVAILABLE)) {
222             mAvailableDeviceQueue.add(device);
223             mDvcMon.notifyDeviceStateChange(
224                     device.getSerialNumber(),
225                     DeviceAllocationState.Allocated,
226                     DeviceAllocationState.Available);
227         }
228     }
229 
230     /** {@inheritDoc} */
231     @Override
forceAllocateDevice(String serial)232     public ITestDevice forceAllocateDevice(String serial) {
233         throw new UnsupportedOperationException();
234     }
235 
236     /** {@inheritDoc} */
237     @Override
removeFastbootListener(IFastbootListener listener)238     public void removeFastbootListener(IFastbootListener listener) {
239         // ignore
240     }
241 
242     /** {@inheritDoc} */
243     @Override
terminate()244     public void terminate() {
245         // ignore
246     }
247 
248     /** {@inheritDoc} */
249     @Override
terminateDeviceRecovery()250     public void terminateDeviceRecovery() {
251         // ignore
252     }
253 
254     /** {@inheritDoc} */
255     @Override
terminateDeviceMonitor()256     public void terminateDeviceMonitor() {
257         // ignore
258     }
259 
260     /** {@inheritDoc} */
261     @Override
terminateHard()262     public void terminateHard() {
263         // ignore
264     }
265 
266     @Override
init()267     public void init() {
268         // ignore
269     }
270 
271     /** {@inheritDoc} */
272     @Override
init( IDeviceSelection globalDeviceFilter, List<IDeviceMonitor> globalDeviceMonitors)273     public void init(
274             IDeviceSelection globalDeviceFilter, List<IDeviceMonitor> globalDeviceMonitors) {
275         // ignore
276     }
277 
278     /** {@inheritDoc} */
279     @Override
stopAdbBridge()280     public void stopAdbBridge() {
281         mStopAdbBridgeCallCount += 1;
282     }
283 
284     /** {@inheritDoc} */
285     @Override
restartAdbBridge()286     public void restartAdbBridge() {
287         mRestartAdbBridgeCallCount += 1;
288     }
289 
290     /**
291      * Verifies that all devices were returned to queue.
292      *
293      * @throws AssertionError
294      */
assertDevicesFreed()295     public void assertDevicesFreed() throws AssertionError {
296         Assert.assertEquals(
297                 "allocated device was not returned to queue",
298                 mTotalDevices,
299                 mAvailableDeviceQueue.size());
300     }
301 
302     /** {@inheritDoc} */
303     @Override
reconnectDeviceToTcp(ITestDevice usbDevice)304     public ITestDevice reconnectDeviceToTcp(ITestDevice usbDevice)
305             throws DeviceNotAvailableException {
306         return null;
307     }
308 
309     /** {@inheritDoc} */
310     @Override
connectToTcpDevice(String ipAndPort)311     public ITestDevice connectToTcpDevice(String ipAndPort) {
312         return null;
313     }
314 
315     /** {@inheritDoc} */
316     @Override
disconnectFromTcpDevice(ITestDevice tcpDevice)317     public boolean disconnectFromTcpDevice(ITestDevice tcpDevice) {
318         return false;
319     }
320 
321     /** {@inheritDoc} */
322     @Override
launchEmulator( ITestDevice device, long bootTimeout, IRunUtil runUtil, List<String> emulatorArgs)323     public void launchEmulator(
324             ITestDevice device, long bootTimeout, IRunUtil runUtil, List<String> emulatorArgs)
325             throws DeviceNotAvailableException {
326         // ignore
327     }
328 
329     /** {@inheritDoc} */
330     @Override
killEmulator(ITestDevice device)331     public void killEmulator(ITestDevice device) throws DeviceNotAvailableException {
332         // ignore
333     }
334 
335     /** {@inheritDoc} */
336     @Override
displayDevicesInfo(PrintWriter stream, boolean includeStub)337     public void displayDevicesInfo(PrintWriter stream, boolean includeStub) {
338         // ignore
339     }
340 
341     /** {@inheritDoc} */
342     @Override
listAllDevices()343     public List<DeviceDescriptor> listAllDevices() {
344         return new ArrayList<DeviceDescriptor>();
345     }
346 
347     /** {@inheritDoc} */
348     @Override
listAllDevices(boolean shortDescriptor)349     public List<DeviceDescriptor> listAllDevices(boolean shortDescriptor) {
350         return new ArrayList<DeviceDescriptor>();
351     }
352 
353     /** {@inheritDoc} */
354     @Override
getDeviceDescriptor(String serial)355     public DeviceDescriptor getDeviceDescriptor(String serial) {
356         return new DeviceDescriptor(
357                 serial,
358                 false,
359                 DeviceAllocationState.Available,
360                 "product",
361                 "productVariant",
362                 "sdkVersion",
363                 "buildId",
364                 "batteryLevel");
365     }
366 
367     @Override
isNullDevice(String serial)368     public boolean isNullDevice(String serial) {
369         return false;
370     }
371 
372     @Override
isEmulator(String serial)373     public boolean isEmulator(String serial) {
374         return false;
375     }
376 
377     @Override
addDeviceMonitor(IDeviceMonitor mon)378     public void addDeviceMonitor(IDeviceMonitor mon) {
379         mDvcMon.addMonitor(mon);
380     }
381 
382     @Override
removeDeviceMonitor(IDeviceMonitor mon)383     public void removeDeviceMonitor(IDeviceMonitor mon) {
384         mDvcMon.removeMonitor(mon);
385     }
386 
387     @Override
getAdbPath()388     public String getAdbPath() {
389         return "adb";
390     }
391 
392     @Override
getFastbootPath()393     public String getFastbootPath() {
394         return "fastboot";
395     }
396 
397     @Override
waitForFirstDeviceAdded(long timeout)398     public boolean waitForFirstDeviceAdded(long timeout) {
399         return false;
400     }
401 
402     /**
403      * Enable unittest for stopAdbBridge().
404      *
405      * @return number of times stopAdbBridge() was called.
406      */
getStopAdbBridgeCallCount()407     public int getStopAdbBridgeCallCount() {
408         return mStopAdbBridgeCallCount;
409     }
410 
411     /**
412      * Enable unittest for restartAdbBridge().
413      *
414      * @return number of times restartAdbBridge() was called.
415      */
getRestartAdbBridgeCallCount()416     public int getRestartAdbBridgeCallCount() {
417         return mRestartAdbBridgeCallCount;
418     }
419 
420     @Override
executeCmdOnAvailableDevice( String serial, String command, long timeout, TimeUnit timeUnit)421     public CommandResult executeCmdOnAvailableDevice(
422             String serial, String command, long timeout, TimeUnit timeUnit) {
423         return null;
424     }
425 
426     @Override
getAdbVersion()427     public String getAdbVersion() {
428         return null;
429     }
430 
431     @Override
addMonitoringTcpFastbootDevice(String serial, String fastboot_serial)432     public void addMonitoringTcpFastbootDevice(String serial, String fastboot_serial) {
433         // ignore
434     }
435 }
436