Home | History | Annotate | Download | only in tendo
      1 # Copyright 2015 The Chromium OS 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 
      5 import logging
      6 import random
      7 import string
      8 
      9 from autotest_lib.client.common_lib import utils
     10 from autotest_lib.client.common_lib.cros.fake_device_server import oauth
     11 from autotest_lib.client.common_lib.cros.fake_device_server import server
     12 
     13 TEST_CONFIG_PATH = '/tmp/buffet.fake.conf'
     14 TEST_STATE_PATH = '/tmp/buffet.fake.state'
     15 
     16 LOCAL_SERVER_PORT = server.PORT
     17 LOCAL_OAUTH_URL = 'http://localhost:%d/%s/' % (LOCAL_SERVER_PORT,
     18                                                oauth.OAUTH_PATH)
     19 LOCAL_SERVICE_URL = 'http://localhost:%d/' % LOCAL_SERVER_PORT
     20 TEST_API_KEY = oauth.TEST_API_KEY
     21 
     22 def build_unique_device_name():
     23     """@return a test-unique name for a device."""
     24     RAND_CHARS = string.ascii_lowercase + string.digits
     25     NUM_RAND_CHARS = 16
     26     rand_token = ''.join([random.choice(RAND_CHARS)
     27                           for _ in range(NUM_RAND_CHARS)])
     28     name = 'CrOS_%s' % rand_token
     29     logging.debug('Generated unique device name %s', name)
     30     return name
     31 
     32 
     33 TEST_CONFIG = {
     34     'client_id': 'this_is_my_client_id',
     35     'client_secret': 'this_is_my_client_secret',
     36     'api_key': TEST_API_KEY,
     37     'oauth_url': LOCAL_OAUTH_URL,
     38     'service_url': LOCAL_SERVICE_URL,
     39     'model_id': 'AATST',
     40     'wifi_auto_setup_enabled': 'false',
     41     'name': build_unique_device_name()
     42 }
     43 
     44 
     45 def bool_to_flag(value):
     46     """Converts boolean value into lowercase string
     47 
     48     @param value: Boolean value.
     49     @return lower case string: 'true' or 'false'.
     50 
     51     """
     52     return ('%s' % value).lower()
     53 
     54 
     55 def format_options(options, separator):
     56     """Format dictionary as key1=value1{separator}key2=value2{separator}..
     57 
     58     @param options: Dictionary with options.
     59     @param separator: String to be used as separator between key=value strings.
     60     @return formated string.
     61 
     62     """
     63     return separator.join(['%s=%s' % (k, v) for (k, v) in options.iteritems()])
     64 
     65 
     66 def naive_restart(host=None):
     67     """Restart Buffet without configuring it in any way.
     68 
     69     @param host: Host object if we're interested in a remote host.
     70 
     71     """
     72     run = utils.run if host is None else host.run
     73     run('stop buffet', ignore_status=True)
     74     run('start buffet')
     75 
     76 
     77 
     78 class BuffetConfig(object):
     79     """An object that knows how to restart buffet in various configurations."""
     80 
     81     def __init__(self,
     82                  log_verbosity=None,
     83                  test_definitions_dir=None,
     84                  enable_xmpp=False,
     85                  enable_ping=True,
     86                  disable_pairing_security=False,
     87                  device_whitelist=None,
     88                  options=None):
     89         self.enable_xmpp = enable_xmpp
     90         self.log_verbosity = log_verbosity
     91         self.test_definitions_dir = test_definitions_dir
     92         self.enable_ping = enable_ping
     93         self.disable_pairing_security = disable_pairing_security
     94         self.device_whitelist = device_whitelist
     95         self.options = TEST_CONFIG.copy()
     96         if options:
     97             self.options.update(options)
     98 
     99 
    100     def restart_with_config(self,
    101                             host=None,
    102                             clean_state=True):
    103         """Restart Buffet with this configuration.
    104 
    105         @param host: Host object if we're interested in a remote host.
    106         @param clean_state: boolean True to remove all existing state.
    107 
    108         """
    109         run = utils.run if host is None else host.run
    110         run('stop buffet', ignore_status=True)
    111         flags = {
    112             'BUFFET_ENABLE_XMPP': 'true' if self.enable_xmpp else 'false',
    113             'BUFFET_CONFIG_PATH': TEST_CONFIG_PATH,
    114             'BUFFET_STATE_PATH': TEST_STATE_PATH,
    115             'BUFFET_ENABLE_PING': bool_to_flag(self.enable_ping),
    116             'BUFFET_DISABLE_SECURITY':
    117                     bool_to_flag(self.disable_pairing_security),
    118         }
    119         if self.log_verbosity:
    120             flags['BUFFET_LOG_LEVEL'] = self.log_verbosity
    121 
    122         # Go through this convoluted shell magic here because we need to
    123         # create this file on both remote and local hosts (see how run() is
    124         # defined).
    125         run('cat <<EOF >%s\n%s\nEOF\n' % (TEST_CONFIG_PATH,
    126                                           format_options(self.options, '\n')))
    127 
    128         if clean_state:
    129             run('echo > %s' % TEST_STATE_PATH)
    130             run('chown buffet:buffet %s' % TEST_STATE_PATH)
    131 
    132         if self.test_definitions_dir:
    133             flags['BUFFET_TEST_DEFINITIONS_PATH'] = self.test_definitions_dir
    134 
    135         if self.device_whitelist:
    136             flags['BUFFET_DEVICE_WHITELIST'] = ','.join(self.device_whitelist)
    137 
    138         run('start buffet %s' % format_options(flags, ' '))
    139 
    140