blob: f0404f4b277e07c85559c5a38a8ec44dcb4d196d [file] [log] [blame]
# Copyright 2019 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""
Test which updates chameleond on the Bluetooth Peer device
This is not a test per se. This 'test' checks if the chameleond version on the
Bluetooth peer device and updates it if it below the expected value.
"""
import logging
import os
import sys
import time
from datetime import datetime
from autotest_lib.client.common_lib import error
from autotest_lib.server import test
# The current chameleond version
CUR_BT_PKG_VERSION='0.0.1'
# The following needs to be kept in sync with values chameleond code
BUNDLE='chameleond-0.0.2.tar.gz' # Name of the chamleond package
BUNDLE_DIR = 'chameleond-0.0.2'
BUNDLE_VERSION = '9999'
CHAMELEON_BOARD = 'fpga_tio'
def run_cmd(peer, cmd):
"""A wrapper around host.run()."""
try:
logging.info("executing command %s on peer",cmd)
result = peer.host.run(cmd)
logging.info("exit_status is %s", result.exit_status)
logging.info("stdout is %s stderr is %s", result.stdout, result.stderr)
output = result.stderr if result.stderr else result.stdout
if result.exit_status == 0:
return True, output
else:
return False, output
except error.AutoservRunError as e:
logging.error("Error while running cmd %s %s", cmd, e)
return False, None
def cmp_version(v1,v2):
""" Compare versions.
Return -1,0,1 depending on whether v1 is less than, equal to or greater
than v2
"""
p1 = [int(i) for i in v1.split('.')]
p2 = [int(i) for i in v2.split('.')]
for i1,i2 in zip(p1,p2):
if i1 < i2:
return -1
elif i1 > i2:
return 1
else:
continue
return 0
def check_version_format(v):
""" Check whether version is in proper format"""
try:
parts = v.split('.')
if len(parts) != 3:
logging.error('version should be in format x.x.x')
return False
return all([i.isdigit() for i in parts])
except Exception as e:
logging.error('exception in check_version_format %s', str(e))
return False
def is_update_needed(peer):
""" Check if update is required
Get the version of chameleond on the peer and compare to
expected version
@returns: True/False
"""
try:
version = peer.get_bt_pkg_version()
except:
logging.error("Getting the version failed %s",sys.exc_info())
raise error.TestFail("Unable to get version")
logging.info("version on chameleond on the peer device is %s", version)
logging.info("current chameleond version is %s", CUR_BT_PKG_VERSION)
if not check_version_format(version):
logging.error("Version not in proper format")
raise error.TestFail("Version not in proper format")
if cmp_version(version, CUR_BT_PKG_VERSION) == -1:
logging.debug("Current version is lower. Update required")
return True
elif cmp_version(version, CUR_BT_PKG_VERSION) == 0:
logging.debug("Current version is equal. Update not required")
return False
else:
# A lab peer with a higher version should be highlighted
raise error.TestFail("Peer has a higher version")
def is_tmp_noexec(peer):
"""Check if /tmp partition is not excutable."""
try:
cmd = 'cat /proc/mounts |grep "/tmp"'
status, output = run_cmd(peer, cmd)
return status and 'noexec' in output
except Exception as e:
logging.error('Exception %s while checking status of /tmp', str(e))
return True
def remount_tmp_exec(peer):
"""Remount /tmp partition with exec flag."""
try:
cmd = 'mount -o remount,exec "/tmp"'
status, output = run_cmd(peer, cmd)
return status
except Exception as e:
logging.error('Exception %s while remounting /tmp', str(e))
return False
def perform_update(peer, arch):
""" Update the chameleond on the peer"""
if arch == 'CHROMEOS':
logging.info("Check if /tmp partition is executable")
if is_tmp_noexec(peer):
if not remount_tmp_exec(peer):
logging.error("unable to remount /tmp as exec")
return False
if is_tmp_noexec(peer):
logging.error("/tmp partition is still noexec")
return False
logging.info("/tmp partition is executable")
logging.info("copy the file over to the peer")
try:
current_dir = os.path.dirname(os.path.realpath(__file__))
bundle_path = os.path.join(current_dir, BUNDLE)
logging.debug("package location is %s", bundle_path)
peer.host.send_file(bundle_path, '/tmp/')
except:
logging.error("copying the file failed %s ", sys.exc_info())
return False
HOST_NOW = datetime.strftime(datetime.now(), '%Y-%m-%d %H:%M:%S')
logging.info("running make on peer")
cmd = ('cd /tmp && rm -rf %s && tar zxf %s &&'
'cd %s && find -exec touch -c {} \; &&'
'make install REMOTE_INSTALL=TRUE '
'HOST_NOW="%s" BUNDLE_VERSION=%s '
'CHAMELEON_BOARD=%s') % (BUNDLE_DIR, BUNDLE, BUNDLE_DIR,
HOST_NOW, BUNDLE_VERSION,
CHAMELEON_BOARD)
status, _ = run_cmd(peer, cmd)
if not status:
logging.info("make failed")
return False
logging.info("chameleond installed on peer")
return True
def restart_check_chameleond(peer, arch):
"""restart chamleond and make sure it is running."""
def _check_output(output, arch):
logging.info("checking output '%s' on %s", output, arch)
if arch == 'CHROMEOS':
expected_output = 'chameleond start/running'
else:
expected_output = 'chameleond is running'
return expected_output in output
if arch == 'CHROMEOS':
restart_cmd = 'restart chameleond'
start_cmd = 'start chameleond'
status_cmd = 'status chameleond'
else:
restart_cmd = 'sudo /etc/init.d/chameleond restart'
start_cmd = 'sudo /etc/init.d/chameleond start'
status_cmd = 'sudo /etc/init.d/chameleond status'
status, _ = run_cmd(peer, restart_cmd)
if not status:
status, _ = run_cmd(peer, start_cmd)
if not status:
logging.error("restarting/starting chamleond failed")
# Wait till chameleond initialization is complete
time.sleep(5)
status, output = run_cmd(peer, status_cmd)
return status and _check_output(output, arch)
def update_peer(host):
"""Update the chameleond on peer device if requried"""
if host.chameleon is None:
raise error.TestError('Bluetooth Peer not present')
peer = host.chameleon
arch = host.chameleon.get_platform()
if arch not in ['CHROMEOS', 'RASPI']:
raise error.TestNAError("%s architecture not supported" % arch)
if not is_update_needed(peer):
raise error.TestNAError("Update not needed")
if not perform_update(peer, arch):
raise error.TestFail("Update failed")
if not restart_check_chameleond(peer, arch):
raise error.TestFail("Unable to start chameleond")
if is_update_needed(peer):
raise error.TestFail("Version not updated after upgrade")
logging.info("updating chameleond succeded")
class bluetooth_PeerUpdate(test.test):
"""
This test updates chameleond on Bluetooth peer devices
"""
version = 1
def run_once(self, host):
""" Update Bluetooth peer device
@param host: the DUT, usually a chromebook
"""
self.host = host
update_peer(self.host)