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