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 dbus
6import inspect
7import json
8import logging
9import sets
10
11from autotest_lib.client.bin import test
12from autotest_lib.client.common_lib import error
13from autotest_lib.client.common_lib.cros.tendo import buffet_config
14from autotest_lib.client.common_lib.cros.tendo import buffet_dbus_helper
15from autotest_lib.client.common_lib.cros.tendo import privet_helper
16from autotest_lib.client.cros.networking import wifi_proxy
17
18def check(expected, value):
19    """Check that |value| == |expected|.
20
21    @param expected: expected value
22    @param value: actual value we found
23
24    """
25    if value != expected:
26        frame = inspect.getouterframes(inspect.currentframe())[1]
27        raise error.TestFail('%s:%s: "%s" != "%s"' % (frame[1], frame[2],
28                                                      expected, value))
29
30
31class buffet_BasicDBusAPI(test.test):
32    """Check that basic buffet daemon DBus APIs are functional."""
33    version = 1
34
35    def run_once(self):
36        """Test entry point."""
37        buffet_config.BuffetConfig(
38                disable_pairing_security=True).restart_with_config()
39        buffet = buffet_dbus_helper.BuffetDBusHelper()
40
41        check('', buffet.device_id)
42        check('Chromium', buffet.oem_name)
43        check('Brillo', buffet.model_name)
44        check('AATST', buffet.model_id)
45        check('', buffet.description)
46        check('', buffet.location)
47
48        buffet.manager.UpdateDeviceInfo(dbus.String('A'),
49                                        dbus.String('B'),
50                                        dbus.String('C'))
51
52        check('A', buffet.name)
53        check('B', buffet.description)
54        check('C', buffet.location)
55
56        # The test method better work.
57        test_message = 'Hello world!'
58        echoed_message = buffet.manager.TestMethod(test_message)
59        if test_message != echoed_message:
60            raise error.TestFail('Expected Manager.TestMethod to return %s '
61                                 'but got %s instead.' % (test_message,
62                                                          echoed_message))
63
64        # We should get the firmware version right.
65        expected_version = None
66        with open('/etc/lsb-release') as f:
67            for line in f.readlines():
68                pieces = line.split('=', 1)
69                if len(pieces) != 2:
70                    continue
71                key = pieces[0].strip()
72                if key == 'CHROMEOS_RELEASE_VERSION':
73                    expected_version = pieces[1].strip()
74
75        if expected_version is None:
76            raise error.TestError('Failed to read version from lsb-release')
77        raw_state = buffet.manager.GetState()
78        parsed_state = json.loads(raw_state)
79        logging.debug('%r', parsed_state)
80        actual_version = parsed_state['base']['firmwareVersion']
81        if actual_version != expected_version:
82            raise error.TestFail('Expected firmwareVersion "%s", but got "%s"' %
83                                 (expected_version, actual_version))
84
85        check(raw_state, buffet.state)
86        expected_base_keys = sets.Set(
87              ['firmwareVersion', 'localDiscoveryEnabled',
88               'localAnonymousAccessMaxRole', 'localPairingEnabled'])
89        missing_base_keys = sets.Set(expected_base_keys).difference(
90              parsed_state['base'].keys())
91        if missing_base_keys:
92            raise error.TestFail('Missing base keys "%s"' %  missing_base_keys)
93
94        # Privet API
95        shill = wifi_proxy.WifiProxy.get_proxy()
96        shill.remove_all_wifi_entries()
97
98        check({}, buffet.pairing_info)
99
100        # But we should still be able to pair.
101        helper = privet_helper.PrivetHelper()
102        data = {'pairing': 'pinCode', 'crypto': 'none'}
103        pairing = helper.send_privet_request(privet_helper.URL_PAIRING_START,
104                                             request_data=data)
105        # And now we should be able to see a pin code in our pairing status.
106        pairing_info = buffet.pairing_info
107        logging.debug(pairing_info)
108        check(pairing_info.get('sessionId', ''), pairing['sessionId'])
109
110        if not 'code' in pairing_info:
111            raise error.TestFail('No code in pairing info (%r)' % pairing_info)
112        # And if we start a new pairing session, the session ID should change.
113        old_session_id = pairing_info['sessionId']
114        pairing = helper.send_privet_request(privet_helper.URL_PAIRING_START,
115                                             request_data=data)
116        if pairing['sessionId'] == old_session_id:
117            raise error.TestFail('Session IDs should change on each new '
118                                 'pairing attempt.')
119        # And if we start and complete a pairing session, we should have no
120        # pairing information exposed.
121        helper.privet_auth()
122        check({}, buffet.pairing_info)
123
124    def cleanup(self):
125        """Clean up processes altered during the test."""
126        buffet_config.naive_restart()
127