1*9c5db199SXin Li# Copyright 2016 The Chromium OS Authors. All rights reserved. 2*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 3*9c5db199SXin Li# found in the LICENSE file. 4*9c5db199SXin Li 5*9c5db199SXin Li"""Utilities used with Brillo hosts.""" 6*9c5db199SXin Li 7*9c5db199SXin Liimport contextlib 8*9c5db199SXin Liimport logging 9*9c5db199SXin Li 10*9c5db199SXin Liimport common 11*9c5db199SXin Lifrom autotest_lib.client.bin import utils 12*9c5db199SXin Li 13*9c5db199SXin Li 14*9c5db199SXin Li_RUN_BACKGROUND_TEMPLATE = '( %(cmd)s ) </dev/null >/dev/null 2>&1 & echo -n $!' 15*9c5db199SXin Li 16*9c5db199SXin Li_WAIT_CMD_TEMPLATE = """\ 17*9c5db199SXin Lito=%(timeout)d; \ 18*9c5db199SXin Liwhile test ${to} -ne 0; do \ 19*9c5db199SXin Li test $(ps %(pid)d | wc -l) -gt 1 || break; \ 20*9c5db199SXin Li sleep 1; \ 21*9c5db199SXin Li to=$((to - 1)); \ 22*9c5db199SXin Lidone; \ 23*9c5db199SXin Litest ${to} -ne 0 -o $(ps %(pid)d | wc -l) -eq 1 \ 24*9c5db199SXin Li""" 25*9c5db199SXin Li 26*9c5db199SXin Li 27*9c5db199SXin Lidef run_in_background(host, cmd): 28*9c5db199SXin Li """Runs a command in the background on the DUT. 29*9c5db199SXin Li 30*9c5db199SXin Li @param host: A host object representing the DUT. 31*9c5db199SXin Li @param cmd: The command to run. 32*9c5db199SXin Li 33*9c5db199SXin Li @return The background process ID (integer). 34*9c5db199SXin Li """ 35*9c5db199SXin Li background_cmd = _RUN_BACKGROUND_TEMPLATE % {'cmd': cmd} 36*9c5db199SXin Li return int(host.run_output(background_cmd).strip()) 37*9c5db199SXin Li 38*9c5db199SXin Li 39*9c5db199SXin Lidef wait_for_process(host, pid, timeout=-1): 40*9c5db199SXin Li """Waits for a process on the DUT to terminate. 41*9c5db199SXin Li 42*9c5db199SXin Li @param host: A host object representing the DUT. 43*9c5db199SXin Li @param pid: The process ID (integer). 44*9c5db199SXin Li @param timeout: Number of seconds to wait; default is wait forever. 45*9c5db199SXin Li 46*9c5db199SXin Li @return True if process terminated within the alotted time, False otherwise. 47*9c5db199SXin Li """ 48*9c5db199SXin Li wait_cmd = _WAIT_CMD_TEMPLATE % {'pid': pid, 'timeout': timeout} 49*9c5db199SXin Li return host.run(wait_cmd, ignore_status=True).exit_status == 0 50*9c5db199SXin Li 51*9c5db199SXin Li 52*9c5db199SXin Li@contextlib.contextmanager 53*9c5db199SXin Lidef connect_to_ssid(host, ssid, passphrase): 54*9c5db199SXin Li """Connects to a given ssid. 55*9c5db199SXin Li 56*9c5db199SXin Li @param host: A host object representing the DUT. 57*9c5db199SXin Li @param ssid: A string representing the ssid to connect to. If ssid is None, 58*9c5db199SXin Li assume that host is already connected to wifi. 59*9c5db199SXin Li @param passphrase: A string representing the passphrase to the ssid. 60*9c5db199SXin Li Defaults to None. 61*9c5db199SXin Li """ 62*9c5db199SXin Li try: 63*9c5db199SXin Li if ssid is None: 64*9c5db199SXin Li # No ssid is passed. It is assumed that the host is already 65*9c5db199SXin Li # connected to wifi. 66*9c5db199SXin Li logging.warning('This test assumes that the device is connected to ' 67*9c5db199SXin Li 'wifi. If it is not, this test will fail.') 68*9c5db199SXin Li yield 69*9c5db199SXin Li else: 70*9c5db199SXin Li logging.info('Connecting to ssid %s', ssid) 71*9c5db199SXin Li # Update the weaved init.rc to stop privet. This sets up shill in 72*9c5db199SXin Li # client mode allowing it to connect to wifi. 73*9c5db199SXin Li host.remount() 74*9c5db199SXin Li host.run('sed \'s/service weaved \/system\/bin\/weaved/' 75*9c5db199SXin Li 'service weaved \/system\/bin\/weaved --disable_privet/\' ' 76*9c5db199SXin Li '-i /system/etc/init/weaved.rc') 77*9c5db199SXin Li host.reboot() 78*9c5db199SXin Li utils.poll_for_condition( 79*9c5db199SXin Li lambda: 'running' in host.run('getprop init.svc.shill' 80*9c5db199SXin Li ).stdout, 81*9c5db199SXin Li sleep_interval=1, timeout=300, 82*9c5db199SXin Li desc='shill was not started by init') 83*9c5db199SXin Li logging.info('Connecting to wifi') 84*9c5db199SXin Li wifi_cmd = ('shill_setup_wifi --ssid=%s ' 85*9c5db199SXin Li '--wait-for-online-seconds=%i' % (ssid, 300)) 86*9c5db199SXin Li if passphrase: 87*9c5db199SXin Li wifi_cmd += ' --passphrase=%s' % passphrase 88*9c5db199SXin Li host.run(wifi_cmd) 89*9c5db199SXin Li yield 90*9c5db199SXin Li finally: 91*9c5db199SXin Li if ssid: 92*9c5db199SXin Li # If we connected to a ssid, disconnect. 93*9c5db199SXin Li host.remount() 94*9c5db199SXin Li host.run('sed \'s/service weaved \/system\/bin\/weaved ' 95*9c5db199SXin Li '--disable_privet/service weaved \/system\/bin\/weaved/\' ' 96*9c5db199SXin Li '-i /system/etc/init/weaved.rc') 97*9c5db199SXin Li host.run('stop weaved') 98*9c5db199SXin Li host.run('start weaved') 99