• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python2
2# Copyright 2017 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import mock
7import unittest
8
9import common
10
11from autotest_lib.server import utils
12from autotest_lib.server.hosts import cros_label
13from autotest_lib.server.hosts.cros_label import BoardLabel
14from autotest_lib.server.hosts.cros_label import BluetoothLabel
15from autotest_lib.server.hosts.cros_label import BrandCodeLabel
16from autotest_lib.server.hosts.cros_label import Cr50Label
17from autotest_lib.server.hosts.cros_label import Cr50ROKeyidLabel
18from autotest_lib.server.hosts.cros_label import Cr50RWKeyidLabel
19from autotest_lib.server.hosts.cros_label import Cr50ROVersionLabel
20from autotest_lib.server.hosts.cros_label import Cr50RWVersionLabel
21from autotest_lib.server.hosts.cros_label import DeviceSkuLabel
22from autotest_lib.server.hosts.cros_label import ModelLabel
23from autotest_lib.server.hosts.cros_label import AudioLoopbackDongleLabel
24from autotest_lib.server.hosts.cros_label import ChameleonConnectionLabel
25from autotest_lib.server.hosts.cros_label import ChameleonLabel
26from autotest_lib.server.hosts.cros_label import ChameleonPeripheralsLabel
27from autotest_lib.server.hosts.cros_label import ServoLabel
28from autotest_lib.server.hosts import host_info
29
30# pylint: disable=missing-docstring
31
32NON_UNI_LSB_RELEASE_OUTPUT = """
33CHROMEOS_RELEASE_APPID={63A9F698-C1CA-4A75-95E7-6B90181B3718}
34CHROMEOS_BOARD_APPID={63A9F698-C1CA-4A75-95E7-6B90181B3718}
35CHROMEOS_CANARY_APPID={90F229CE-83E2-4FAF-8479-E368A34938B1}
36DEVICETYPE=CHROMEBOOK
37CHROMEOS_ARC_VERSION=4234098
38CHROMEOS_ARC_ANDROID_SDK_VERSION=25
39GOOGLE_RELEASE=9798.0.2017_08_02_1022
40CHROMEOS_DEVSERVER=http://shapiroc3.bld.corp.google.com:8080
41CHROMEOS_RELEASE_BOARD=pyro
42CHROMEOS_RELEASE_BUILD_NUMBER=9798
43CHROMEOS_RELEASE_BRANCH_NUMBER=0
44CHROMEOS_RELEASE_CHROME_MILESTONE=62
45CHROMEOS_RELEASE_PATCH_NUMBER=2017_08_02_1022
46CHROMEOS_RELEASE_TRACK=testimage-channel
47CHROMEOS_RELEASE_DESCRIPTION=9798.0.2017_08_02_1022 (Test Build)
48CHROMEOS_RELEASE_BUILD_TYPE=Test Build
49CHROMEOS_RELEASE_NAME=Chromium OS
50CHROMEOS_RELEASE_VERSION=9798.0.2017_08_02_1022
51CHROMEOS_AUSERVER=http://someserver.bld.corp.google.com:8080/update
52"""
53
54UNI_LSB_RELEASE_OUTPUT = """
55CHROMEOS_RELEASE_APPID={5A3AB642-2A67-470A-8F37-37E737A53CFC}
56CHROMEOS_BOARD_APPID={5A3AB642-2A67-470A-8F37-37E737A53CFC}
57CHROMEOS_CANARY_APPID={90F229CE-83E2-4FAF-8479-E368A34938B1}
58DEVICETYPE=CHROMEBOOK
59CHROMEOS_ARC_VERSION=4340813
60CHROMEOS_ARC_ANDROID_SDK_VERSION=25
61GOOGLE_RELEASE=9953.0.2017_09_18_1334
62CHROMEOS_DEVSERVER=http://server.bld.corp.google.com:8080
63CHROMEOS_RELEASE_BOARD=coral
64CHROMEOS_RELEASE_BUILD_NUMBER=9953
65CHROMEOS_RELEASE_BRANCH_NUMBER=0
66CHROMEOS_RELEASE_CHROME_MILESTONE=63
67CHROMEOS_RELEASE_PATCH_NUMBER=2017_09_18_1334
68CHROMEOS_RELEASE_TRACK=testimage-channel
69CHROMEOS_RELEASE_DESCRIPTION=9953.0.2017_09_18_1334 (Test Build)
70CHROMEOS_RELEASE_BUILD_TYPE=Test Build
71CHROMEOS_RELEASE_NAME=Chromium OS
72CHROMEOS_RELEASE_UNIBUILD=1
73CHROMEOS_RELEASE_VERSION=9953.0.2017_09_18_1334
74CHROMEOS_AUSERVER=http://server.bld.corp.google.com:8080/update
75CHROMEOS_RELEASE_MODELS=coral astronaut blue bruce lava nasher
76"""
77
78GSCTOOL_OUTPUT_PVT = """
79start
80target running protocol version 6
81keyids: RO 0xaa66150f, RW 0xde88588d
82offsets: backup RO at 0x40000, backup RW at 0x44000
83Current versions:
84RO 0.0.10
85RW 0.3.14
86"""
87
88GSCTOOL_OUTPUT_PREPVT = """
89start
90target running protocol version 6
91keyids: RO 0xaa66150f, RW 0xde88588d
92offsets: backup RO at 0x40000, backup RW at 0x44000
93Current versions:
94RO 0.0.10
95RW 0.4.15
96"""
97
98GSCTOOL_OUTPUT_DEV_RO = """
99start
100target running protocol version 6
101keyids: RO 0x3716ee6b, RW 0xde88588d
102offsets: backup RO at 0x40000, backup RW at 0x44000
103Current versions:
104RO 0.0.10
105RW 0.4.15
106"""
107
108GSCTOOL_OUTPUT_DEV_RW = """
109start
110target running protocol version 6
111keyids: RO 0xaa66150f, RW 0xb93d6539
112offsets: backup RO at 0x40000, backup RW at 0x44000
113Current versions:
114RO 0.0.10
115RW 0.4.15
116"""
117
118
119class MockCmd(object):
120    """Simple mock command with base command and results"""
121
122    def __init__(self, cmd, exit_status, stdout):
123        self.cmd = cmd
124        self.stdout = stdout
125        self.exit_status = exit_status
126
127
128class MockAFEHost(utils.EmptyAFEHost):
129
130    def __init__(self, labels=[], attributes={}):
131        self.labels = labels
132        self.attributes = attributes
133
134
135class MockHost(object):
136    """Simple host for running mock'd host commands"""
137
138    def __init__(self, labels, *args):
139        self._afe_host = MockAFEHost(labels)
140        self.mock_cmds = {c.cmd: c for c in args}
141        info = host_info.HostInfo(labels=labels)
142        self.host_info_store = host_info.InMemoryHostInfoStore(info)
143
144    def run(self, command, **kwargs):
145        """Finds the matching result by command value"""
146        return self.mock_cmds[command]
147
148
149class MockHostWithoutAFE(MockHost):
150
151    def __init__(self, labels, *args):
152        super(MockHostWithoutAFE, self).__init__(labels, *args)
153        self._afe_host = utils.EmptyAFEHost()
154
155
156class ModelLabelTests(unittest.TestCase):
157    """Unit tests for ModelLabel"""
158
159    def test_cros_config_succeeds(self):
160        cat_lsb_release_output = """
161CHROMEOS_RELEASE_BOARD=pyro
162CHROMEOS_RELEASE_UNIBUILD=1
163"""
164        host = MockHost([],
165                        MockCmd('cros_config / test-label', 0, 'coral\n'),
166                        MockCmd('cat /etc/lsb-release', 0,
167                                cat_lsb_release_output))
168        self.assertEqual(ModelLabel().generate_labels(host), ['coral'])
169
170    def test_cros_config_fails_mosys_succeeds(self):
171        cat_lsb_release_output = """
172CHROMEOS_RELEASE_BOARD=pyro
173CHROMEOS_RELEASE_UNIBUILD=1
174"""
175        host = MockHost([],
176                        MockCmd('cros_config / test-label', 1, ''),
177                        MockCmd('mosys platform model', 0, 'coral\n'),
178                        MockCmd('cat /etc/lsb-release', 0,
179                                cat_lsb_release_output))
180        self.assertEqual(ModelLabel().generate_labels(host), ['coral'])
181
182    def test_cros_config_fails_mosys_fails(self):
183        cat_lsb_release_output = """
184CHROMEOS_RELEASE_BOARD=pyro
185CHROMEOS_RELEASE_UNIBUILD=1
186"""
187        host = MockHost([],
188                        MockCmd('cros_config / test-label', 1, ''),
189                        MockCmd('mosys platform model', 1, ''),
190                        MockCmd('cat /etc/lsb-release', 0,
191                                cat_lsb_release_output))
192        self.assertEqual(ModelLabel().generate_labels(host), ['pyro'])
193
194    def test_cros_config_only_used_for_unibuilds(self):
195        cat_lsb_release_output = """
196CHROMEOS_RELEASE_BOARD=pyro
197"""
198        host = MockHost([],
199                        MockCmd('cat /etc/lsb-release', 0,
200                                cat_lsb_release_output))
201        self.assertEqual(ModelLabel().generate_labels(host), ['pyro'])
202
203    def test_existing_label(self):
204        host = MockHost(['model:existing'])
205        self.assertEqual(ModelLabel().generate_labels(host), ['existing'])
206
207    def test_existing_label_in_host_info_store(self):
208        host = MockHostWithoutAFE(['model:existing'])
209        self.assertEqual(ModelLabel().generate_labels(host), ['existing'])
210
211
212class BoardLabelTests(unittest.TestCase):
213    """Unit tests for BoardLabel"""
214
215    def test_new_label(self):
216        cat_cmd = 'cat /etc/lsb-release'
217        host = MockHost([], MockCmd(cat_cmd, 0, NON_UNI_LSB_RELEASE_OUTPUT))
218        self.assertEqual(BoardLabel().generate_labels(host), ['pyro'])
219
220    def test_existing_label(self):
221        host = MockHost(['board:existing'])
222        self.assertEqual(BoardLabel().generate_labels(host), ['existing'])
223
224    def test_existing_label_in_host_info_store(self):
225        host = MockHostWithoutAFE(['board:existing'])
226        self.assertEqual(BoardLabel().generate_labels(host), ['existing'])
227
228
229class DeviceSkuLabelTests(unittest.TestCase):
230    """Unit tests for DeviceSkuLabel"""
231
232    def test_new_label(self):
233        mosys_cmd = 'mosys platform sku'
234        host = MockHost([], MockCmd(mosys_cmd, 0, '27\n'))
235        self.assertEqual(DeviceSkuLabel().generate_labels(host), ['27'])
236
237    def test_new_label_mosys_fails(self):
238        mosys_cmd = 'mosys platform sku'
239        host = MockHost([], MockCmd(mosys_cmd, 1, '27\n'))
240        self.assertEqual(DeviceSkuLabel().generate_labels(host), [])
241
242    def test_existing_label(self):
243        host = MockHost(['device-sku:48'])
244        self.assertEqual(DeviceSkuLabel().generate_labels(host), ['48'])
245
246    def test_update_for_task(self):
247        self.assertTrue(DeviceSkuLabel().update_for_task(''))
248        self.assertFalse(DeviceSkuLabel().update_for_task('repair'))
249        self.assertTrue(DeviceSkuLabel().update_for_task('deploy'))
250
251
252class BrandCodeLabelTests(unittest.TestCase):
253    """Unit tests for DeviceSkuLabel"""
254
255    def test_new_label(self):
256        cros_config_cmd = 'cros_config / brand-code'
257        host = MockHost([], MockCmd(cros_config_cmd, 0, 'XXYZ\n'))
258        self.assertEqual(BrandCodeLabel().generate_labels(host), ['XXYZ'])
259
260    def test_new_label_cros_config_fails(self):
261        cros_config_cmd = 'cros_config / brand-code'
262        host = MockHost([], MockCmd(cros_config_cmd, 1, 'XXYZ\n'))
263        self.assertEqual(BrandCodeLabel().generate_labels(host), [])
264
265    def test_existing_label(self):
266        host = MockHost(['brand-code:ABCD'])
267        self.assertEqual(BrandCodeLabel().generate_labels(host), ['ABCD'])
268
269
270class BluetoothLabelTests(unittest.TestCase):
271    """Unit tests for BluetoothLabel"""
272
273    def test_new_label(self):
274        test_cmd = 'test -d /sys/class/bluetooth/hci0'
275        host = MockHost([], MockCmd(test_cmd, 0, ''))
276        self.assertEqual(BluetoothLabel().exists(host), True)
277
278    def test_existing_label(self):
279        host = MockHostWithoutAFE(['bluetooth'])
280        self.assertEqual(BoardLabel().exists(host), True)
281
282
283class Cr50Tests(unittest.TestCase):
284    """Unit tests for Cr50Label"""
285
286    def test_cr50_pvt(self):
287        host = MockHost([],
288                        MockCmd('gsctool -a -f', 0, GSCTOOL_OUTPUT_PVT))
289        self.assertEqual(Cr50Label().get(host), ['cr50:pvt'])
290
291    def test_cr50_prepvt(self):
292        host = MockHost([],
293                        MockCmd('gsctool -a -f', 0, GSCTOOL_OUTPUT_PREPVT))
294        self.assertEqual(Cr50Label().get(host), ['cr50:prepvt'])
295
296    def test_gsctool_fails(self):
297        host = MockHost([],
298                        MockCmd('gsctool -a -f', 1, ''))
299        self.assertEqual(Cr50Label().get(host), [])
300
301
302class Cr50RWKeyidTests(unittest.TestCase):
303    """Unit tests for Cr50RWKeyidLabel"""
304
305    def test_cr50_prod_rw(self):
306        host = MockHost([],
307                        MockCmd('gsctool -a -f', 0, GSCTOOL_OUTPUT_PVT))
308        self.assertEqual(Cr50RWKeyidLabel().get(host),
309                         ['cr50-rw-keyid:0xde88588d', 'cr50-rw-keyid:prod'])
310
311    def test_cr50_dev_rw(self):
312        host = MockHost([],
313                        MockCmd('gsctool -a -f', 0, GSCTOOL_OUTPUT_DEV_RW))
314        self.assertEqual(Cr50RWKeyidLabel().get(host),
315                         ['cr50-rw-keyid:0xb93d6539', 'cr50-rw-keyid:dev'])
316
317    def test_gsctool_fails(self):
318        host = MockHost([],
319                        MockCmd('gsctool -a -f', 1, ''))
320        self.assertEqual(Cr50RWKeyidLabel().get(host), [])
321
322
323class Cr50ROKeyidTests(unittest.TestCase):
324    """Unit tests for Cr50ROKeyidLabel"""
325
326    def test_cr50_prod_ro(self):
327        host = MockHost([],
328                        MockCmd('gsctool -a -f', 0, GSCTOOL_OUTPUT_PREPVT))
329        self.assertEqual(Cr50ROKeyidLabel().get(host),
330                         ['cr50-ro-keyid:0xaa66150f', 'cr50-ro-keyid:prod'])
331
332    def test_cr50_dev_ro(self):
333        host = MockHost([],
334                        MockCmd('gsctool -a -f', 0, GSCTOOL_OUTPUT_DEV_RO))
335        self.assertEqual(Cr50ROKeyidLabel().get(host),
336                         ['cr50-ro-keyid:0x3716ee6b', 'cr50-ro-keyid:dev'])
337
338    def test_gsctool_fails(self):
339        host = MockHost([],
340                        MockCmd('gsctool -a -f', 1, ''))
341        self.assertEqual(Cr50ROKeyidLabel().get(host), [])
342
343
344class Cr50RWVersionTests(unittest.TestCase):
345    """Unit tests for Cr50RWVersionLabel"""
346
347    def test_cr50_prod_rw(self):
348        host = MockHost([],
349                        MockCmd('gsctool -a -f', 0, GSCTOOL_OUTPUT_PVT))
350        self.assertEqual(Cr50RWVersionLabel().get(host),
351                         ['cr50-rw-version:0.3.14'])
352
353    def test_cr50_dev_rw(self):
354        host = MockHost([],
355                        MockCmd('gsctool -a -f', 0, GSCTOOL_OUTPUT_PREPVT))
356        self.assertEqual(Cr50RWVersionLabel().get(host),
357                         ['cr50-rw-version:0.4.15'])
358
359    def test_gsctool_fails(self):
360        host = MockHost([],
361                        MockCmd('gsctool -a -f', 1, ''))
362        self.assertEqual(Cr50RWVersionLabel().get(host), [])
363
364
365class Cr50ROVersionTests(unittest.TestCase):
366    """Unit tests for Cr50ROVersionLabel"""
367
368    def test_cr50_prod_ro(self):
369        host = MockHost([],
370                        MockCmd('gsctool -a -f', 0, GSCTOOL_OUTPUT_PREPVT))
371        self.assertEqual(Cr50ROVersionLabel().get(host),
372                         ['cr50-ro-version:0.0.10'])
373
374    def test_gsctool_fails(self):
375        host = MockHost([],
376                        MockCmd('gsctool -a -f', 1, ''))
377        self.assertEqual(Cr50ROVersionLabel().get(host), [])
378
379
380class HWIDLabelTests(unittest.TestCase):
381    def test_merge_hwid_label_lists_empty(self):
382        self.assertEqual(cros_label.HWIDLabel._merge_hwid_label_lists([], []), [])
383
384    def test_merge_hwid_label_lists_singleton(self):
385        self.assertEqual(cros_label.HWIDLabel._merge_hwid_label_lists([], ["4"]),
386                         ["4"])
387        self.assertEqual(cros_label.HWIDLabel._merge_hwid_label_lists(["7"], []),
388                         ["7"])
389
390    def test_merge_hwid_label_lists_override(self):
391        self.assertEqual(
392            cros_label.HWIDLabel._merge_hwid_label_lists(old=["7:a"], new=["7:b"]),
393            ["7:b"])
394
395    def test_merge_hwid_label_lists_no_override(self):
396        self.assertEqual(
397            cros_label.HWIDLabel._merge_hwid_label_lists(old=["7a"], new=["7b"]),
398            ["7a", "7b"])
399
400    def test_hwid_label_names(self):
401        class HWIDLabelTester(cros_label.HWIDLabel):
402            def get_all_labels(self):
403                return [], []
404
405        item = HWIDLabelTester()
406        self.assertEqual(item._hwid_label_names(), cros_label.HWID_LABELS_FALLBACK)
407
408
409class ServoLabelTests(unittest.TestCase):
410    """Unit tests for ServoLabel"""
411
412    def test_servo_working_and_in_cache(self):
413        host = MockHost(['servo_state:WORKING'])
414        servo = ServoLabel()
415        self.assertEqual(servo.get(host), ['servo', 'servo_state:WORKING'])
416        self.assertEqual(servo.exists(host), True)
417
418    def test_servo_working_and_in_cache_but_not_connected(self):
419        host = MockHost(['servo_state:NOT_CONNECTED'])
420        servo = ServoLabel()
421        self.assertEqual(servo.get(host), ['servo_state:BROKEN'])
422        self.assertEqual(servo.exists(host), False)
423
424    def test_servo_not_in_cache_and_not_working(self):
425        host = MockHostWithoutAFE(['not_servo_state:WORKING'])
426        servo = ServoLabel()
427        self.assertEqual(servo.get(host), ['servo_state:BROKEN'])
428        self.assertEqual(servo.exists(host), False)
429
430    @mock.patch('autotest_lib.server.hosts.servo_host.get_servo_args_for_host')
431    @mock.patch('autotest_lib.server.hosts.servo_host.servo_host_is_up')
432    def test_servo_not_in_cache_but_working(self,
433                                            servo_host_is_up,
434                                            get_servo_args_for_host):
435        get_servo_args_for_host.return_value = {"servo_host": "some_servo_host_name"}
436        servo_host_is_up.return_value = True
437        host = MockHostWithoutAFE(['not_servo_state:WORKING'])
438
439        servo = ServoLabel()
440        self.assertEqual(servo.get(host), ['servo', 'servo_state:WORKING'])
441        self.assertEqual(servo.exists(host), True)
442        get_servo_args_for_host.assert_called()
443        servo_host_is_up.assert_called()
444        servo_host_is_up.assert_called_with('some_servo_host_name')
445
446    def test_get_all_labels_lists_of_generating_labels(self):
447          servo = ServoLabel()
448          prefix_labels, full_labels = servo.get_all_labels()
449          self.assertEqual(prefix_labels, set(['servo_state']))
450          self.assertEqual(full_labels, set(['servo']))
451
452    def test_update_for_task(self):
453        self.assertTrue(ServoLabel().update_for_task(''))
454        self.assertTrue(ServoLabel().update_for_task('repair'))
455        self.assertFalse(ServoLabel().update_for_task('deploy'))
456
457
458class AudioLoopbackDongleLabelTests(unittest.TestCase):
459    def test_update_for_task(self):
460        self.assertTrue(AudioLoopbackDongleLabel().update_for_task(''))
461        self.assertTrue(AudioLoopbackDongleLabel().update_for_task('repair'))
462        self.assertFalse(AudioLoopbackDongleLabel().update_for_task('deploy'))
463
464
465class ChameleonConnectionLabelTests(unittest.TestCase):
466    def test_update_for_task(self):
467        self.assertTrue(ChameleonConnectionLabel().update_for_task(''))
468        self.assertFalse(ChameleonConnectionLabel().update_for_task('repair'))
469        self.assertTrue(ChameleonConnectionLabel().update_for_task('deploy'))
470
471
472class ChameleonLabelTests(unittest.TestCase):
473    def test_update_for_task(self):
474        self.assertTrue(ChameleonLabel().update_for_task(''))
475        self.assertTrue(ChameleonLabel().update_for_task('repair'))
476        self.assertFalse(ChameleonLabel().update_for_task('deploy'))
477
478
479class ChameleonPeripheralsLabelTests(unittest.TestCase):
480    def test_update_for_task(self):
481        self.assertTrue(ChameleonPeripheralsLabel().update_for_task(''))
482        self.assertFalse(ChameleonPeripheralsLabel().update_for_task('repair'))
483        self.assertTrue(ChameleonPeripheralsLabel().update_for_task('deploy'))
484
485
486if __name__ == '__main__':
487    unittest.main()
488