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