1# Copyright 2014 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import unittest
6
7from telemetry import decorators
8from telemetry.internal.browser import browser_options
9from telemetry.internal.platform import android_device
10from telemetry.testing import system_stub
11import mock
12
13from devil.android import device_utils
14from devil.android import device_blacklist
15
16
17class _BaseAndroidDeviceTest(unittest.TestCase):
18  def setUp(self):
19    def check_blacklist_arg(blacklist):
20      self.assertTrue(blacklist is None
21                      or isinstance(blacklist, device_blacklist.Blacklist))
22      return mock.DEFAULT
23
24    self._healthy_device_patcher = mock.patch(
25        'devil.android.device_utils.DeviceUtils.HealthyDevices')
26    self._healthy_device_mock = self._healthy_device_patcher.start()
27    self._healthy_device_mock.side_effect = check_blacklist_arg
28    self._android_device_stub = system_stub.Override(
29        android_device, ['subprocess', 'logging'])
30
31  def _GetMockDeviceUtils(self, device_serial, is_online=True):
32    device = device_utils.DeviceUtils(device_serial)
33    device.IsOnline = mock.MagicMock(return_value=is_online)
34    return device
35
36  def tearDown(self):
37    self._healthy_device_patcher.stop()
38    self._android_device_stub.Restore()
39
40
41class AndroidDeviceTest(_BaseAndroidDeviceTest):
42  @decorators.Enabled('android')
43  def testGetAllAttachedAndroidDevices(self):
44    self._healthy_device_mock.return_value = [
45        self._GetMockDeviceUtils('01'),
46        self._GetMockDeviceUtils('07', is_online=False),
47        self._GetMockDeviceUtils('02'),
48        self._GetMockDeviceUtils('03', is_online=False)]
49    self.assertEquals(
50        set(['01', '02']),
51        set(device.device_id for device in
52            android_device.AndroidDevice.GetAllConnectedDevices(None)))
53
54  @decorators.Enabled('android')
55  def testNoAdbReturnsNone(self):
56    finder_options = browser_options.BrowserFinderOptions()
57    with (
58        mock.patch('os.path.isabs', return_value=True)), (
59        mock.patch('os.path.exists', return_value=False)):
60      self.assertEquals([], self._android_device_stub.logging.warnings)
61      self.assertIsNone(android_device.GetDevice(finder_options))
62
63  @decorators.Enabled('android')
64  def testAdbNoDevicesReturnsNone(self):
65    finder_options = browser_options.BrowserFinderOptions()
66    with mock.patch('os.path.isabs', return_value=False):
67      self._healthy_device_mock.return_value = []
68      self.assertEquals([], self._android_device_stub.logging.warnings)
69      self.assertIsNone(android_device.GetDevice(finder_options))
70
71  @decorators.Enabled('android')
72  def testAdbTwoDevicesReturnsNone(self):
73    finder_options = browser_options.BrowserFinderOptions()
74    with mock.patch('os.path.isabs', return_value=False):
75      self._healthy_device_mock.return_value = [
76          self._GetMockDeviceUtils('015d14fec128220c'),
77          self._GetMockDeviceUtils('015d14fec128220d')]
78      device = android_device.GetDevice(finder_options)
79      self.assertEquals([
80          'Multiple devices attached. Please specify one of the following:\n'
81          '  --device=015d14fec128220c\n'
82          '  --device=015d14fec128220d'],
83          self._android_device_stub.logging.warnings)
84      self.assertIsNone(device)
85
86  @decorators.Enabled('android')
87  def testAdbPickOneDeviceReturnsDeviceInstance(self):
88    finder_options = browser_options.BrowserFinderOptions()
89    finder_options.device = '555d14fecddddddd'  # pick one
90    with mock.patch('os.path.isabs', return_value=False):
91      self._healthy_device_mock.return_value = [
92          self._GetMockDeviceUtils('015d14fec128220c'),
93          self._GetMockDeviceUtils('555d14fecddddddd')]
94      device = android_device.GetDevice(finder_options)
95      self.assertEquals([], self._android_device_stub.logging.warnings)
96      self.assertEquals('555d14fecddddddd', device.device_id)
97
98  @decorators.Enabled('android')
99  def testAdbOneDeviceReturnsDeviceInstance(self):
100    finder_options = browser_options.BrowserFinderOptions()
101    with mock.patch('os.path.isabs', return_value=False):
102      self._healthy_device_mock.return_value = [
103          self._GetMockDeviceUtils('015d14fec128220c')]
104      device = android_device.GetDevice(finder_options)
105      self.assertEquals([], self._android_device_stub.logging.warnings)
106      self.assertEquals('015d14fec128220c', device.device_id)
107
108
109class FindAllAvailableDevicesTest(_BaseAndroidDeviceTest):
110  @decorators.Enabled('android')
111  def testAdbNoDeviceReturnsEmptyList(self):
112    finder_options = browser_options.BrowserFinderOptions()
113    with mock.patch('os.path.isabs', return_value=False):
114      self._healthy_device_mock.return_value = []
115      devices = android_device.FindAllAvailableDevices(finder_options)
116      self.assertEquals([], self._android_device_stub.logging.warnings)
117      self.assertIsNotNone(devices)
118      self.assertEquals(len(devices), 0)
119
120  @decorators.Enabled('android')
121  def testAdbOneDeviceReturnsListWithOneDeviceInstance(self):
122    finder_options = browser_options.BrowserFinderOptions()
123    with mock.patch('os.path.isabs', return_value=False):
124      self._healthy_device_mock.return_value = [
125          self._GetMockDeviceUtils('015d14fec128220c')]
126      devices = android_device.FindAllAvailableDevices(finder_options)
127      self.assertEquals([], self._android_device_stub.logging.warnings)
128      self.assertIsNotNone(devices)
129      self.assertEquals(len(devices), 1)
130      self.assertEquals('015d14fec128220c', devices[0].device_id)
131
132  @decorators.Enabled('android')
133  def testAdbMultipleDevicesReturnsListWithAllDeviceInstances(self):
134    finder_options = browser_options.BrowserFinderOptions()
135    with mock.patch('os.path.isabs', return_value=False):
136      self._healthy_device_mock.return_value = [
137          self._GetMockDeviceUtils('015d14fec128220c'),
138          self._GetMockDeviceUtils('this0should0not0show', is_online=False),
139          self._GetMockDeviceUtils('015d14fec128220d'),
140          self._GetMockDeviceUtils('015d14fec128220e')]
141      devices = android_device.FindAllAvailableDevices(finder_options)
142      self.assertEquals([], self._android_device_stub.logging.warnings)
143      self.assertIsNotNone(devices)
144      self.assertEquals(len(devices), 3)
145      self.assertEquals(devices[0].guid, '015d14fec128220c')
146      self.assertEquals(devices[1].guid, '015d14fec128220d')
147      self.assertEquals(devices[2].guid, '015d14fec128220e')
148