=== added file 'doc/lava-android-test-leb-panda.json'
@@ -0,0 +1,54 @@
+{
+ "job_name": "android_monkey_test2",
+ "image_type": "android",
+ "target": "panda01",
+ "timeout": 18000,
+ "actions": [
+ {
+ "command": "deploy_linaro_android_image",
+ "parameters":
+ {
+ "boot": "https://android-build.linaro.org/jenkins/job/linaro-android_leb-panda/246/artifact/build/out/target/product/pandaboard/boot.tar.bz2",
+ "system": "https://android-build.linaro.org/jenkins/job/linaro-android_leb-panda/246/artifact/build/out/target/product/pandaboard/system.tar.bz2",
+ "data": "https://android-build.linaro.org/jenkins/job/linaro-android_leb-panda/246/artifact/build/out/target/product/pandaboard/userdata.tar.bz2"
+ },
+ "metadata":
+ {
+ "rootfs.type": "android",
+ "rootfs.build": "246"
+ }
+ },
+ {
+ "command": "boot_linaro_android_image"
+ },
+ {
+ "command": "lava_android_test_install",
+ "parameters":
+ {
+ "tests": ["monkey", "0xbench"]
+ }
+ },
+ {
+ "command": "lava_android_test_run",
+ "parameters":
+ {
+ "test_name": "monkey"
+ }
+ },
+ {
+ "command": "lava_android_test_run",
+ "parameters":
+ {
+ "test_name": "0xbench"
+ }
+ },
+ {
+ "command": "submit_results_on_host",
+ "parameters":
+ {
+ "server": "http://validation.linaro.org/lava-server/RPC2/",
+ "stream": "/anonymous/lava-android-leb-panda/"
+ }
+ }
+ ]
+}
=== added file 'lava_dispatcher/actions/lava-android-test.py'
@@ -0,0 +1,86 @@
+#!/usr/bin/python
+
+# Copyright (C) 2011 Linaro Limited
+#
+# Author: Linaro Validation Team <linaro-dev@lists.linaro.org>
+#
+# This file is part of LAVA Dispatcher.
+#
+# LAVA Dispatcher is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# LAVA Dispatcher is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses>.
+import sys
+import pexpect
+import time
+from datetime import datetime
+from lava_dispatcher.actions import BaseAction
+from lava_dispatcher.client import OperationFailed, NetworkError
+
+class AndroidTestAction(BaseAction):
+
+ def wait_devices_attached(self, dev_name):
+ for count in range(3):
+ if self.check_device_state(dev_name):
+ return
+ time.sleep(1)
+
+ raise NetworkError("The android device(%s) isn't attached" % self.client.hostname)
+
+ def check_device_state(self, dev_name):
+ (output, rc) = pexpect.run('adb devices', timeout=None, logfile=sys.stdout, withexitstatus=True)
+ if rc != 0:
+ return False
+ expect_line = '%s\tdevice' % dev_name
+ for line in output.splitlines():
+ if line.strip() == expect_line:
+ return True
+ return False
+
+ def check_lava_android_test_installed(self):
+ rc = pexpect.run('which lava-android-test', timeout=None, logfile=sys.stdout, withexitstatus=True)[1]
+ if rc != 0:
+ raise OperationFailed('lava-android-test has not been installed')
+
+ def is_ready_for_test(self):
+ self.check_lava_android_test_installed()
+ dev_name = self.client.android_adb_connect_over_default_nic_ip()
+ if dev_name is None:
+ raise NetworkError("The android device(%s) isn't attached over tcpip" % self.client.hostname)
+
+ self.wait_devices_attached(dev_name)
+ self.client.wait_home_screen()
+ return dev_name
+
+class cmd_lava_android_test_run(AndroidTestAction):
+ def run(self, test_name, timeout= -1):
+ #Make sure in test image now
+ dev_name = self.is_ready_for_test()
+ bundle_name = test_name + "-" + datetime.now().strftime("%H%M%S")
+ cmd = 'lava-android-test run %s -s %s -o /tmp/%s/%s.bundle' % (
+ test_name, dev_name, self.context.lava_result_dir, bundle_name)
+
+ rc = pexpect.run(cmd, timeout=None, logfile=sys.stdout, withexitstatus=True)[1]
+ if rc != 0:
+ raise OperationFailed("Failed to run test case(%s) on device(%s) with return value: %s" % (test_name, dev_name, rc))
+
+class cmd_lava_android_test_install(AndroidTestAction):
+ """
+ lava-test deployment to test image rootfs by chroot
+ """
+ def run(self, tests, timeout=2400):
+ dev_name = self.is_ready_for_test()
+ for test in tests:
+ cmd = 'lava-android-test install %s -s %s' % (test, dev_name)
+ rc = pexpect.run(cmd, timeout=None, logfile=sys.stdout, withexitstatus=True)[1]
+ if rc != 0:
+ raise OperationFailed("Failed to install test case(%s) on device(%s) with return value: %s" % (test, dev_name, rc))
+
=== modified file 'lava_dispatcher/android_client.py'
@@ -19,17 +19,19 @@
import pexpect
import sys
-from lava_dispatcher.client import LavaClient, OperationFailed
+import time
+from lava_dispatcher.client import LavaClient, OperationFailed, NetworkError, GeneralError
+
from utils import string_to_list
class LavaAndroidClient(LavaClient):
- def run_adb_shell_command(self, dev_id, cmd, response, timeout=-1):
+ def run_adb_shell_command(self, dev_id, cmd, response, timeout= -1):
adb_cmd = "adb -s %s shell %s" % (dev_id, cmd)
try:
adb_proc = pexpect.spawn(adb_cmd, logfile=sys.stdout)
- id = adb_proc.expect([response, pexpect.EOF], timeout=timeout)
- if id == 0:
+ match_id = adb_proc.expect([response, pexpect.EOF], timeout=timeout)
+ if match_id == 0:
return True
except pexpect.TIMEOUT:
pass
@@ -39,8 +41,8 @@
""" Check that we are in a shell on the test image
"""
self.proc.sendline("")
- id = self.proc.expect([self.tester_str , pexpect.TIMEOUT])
- if id == 1:
+ match_id = self.proc.expect([self.tester_str , pexpect.TIMEOUT])
+ if match_id == 1:
raise OperationFailed
def boot_linaro_android_image(self):
@@ -60,6 +62,9 @@
self.in_test_shell()
self.proc.sendline("export PS1=\"root@linaro: \"")
+ self.enable_adb_over_tcpip()
+ self.android_adb_disconnect_over_default_nic_ip()
+
def android_logcat_clear(self):
cmd = "logcat -c"
self.proc.sendline(cmd)
@@ -68,12 +73,12 @@
cmd = "logcat"
self.proc.sendline(cmd)
- def android_logcat_monitor(self, pattern, timeout=-1):
+ def android_logcat_monitor(self, pattern, timeout= -1):
self.android_logcat_stop()
cmd = 'logcat'
self.proc.sendline(cmd)
- id = self.proc.expect(pattern, timeout=timeout)
- if id == 0:
+ match_id = self.proc.expect(pattern, timeout=timeout)
+ if match_id == 0:
return True
else:
return False
@@ -90,45 +95,90 @@
cmd = "adb connect %s" % dev_ip
adb_proc = pexpect.spawn(cmd, timeout=300, logfile=sys.stdout)
- id = adb_proc.expect([pattern1, pattern2, pattern3, pexpect.EOF])
- if id == 0:
+ match_id = adb_proc.expect([pattern1, pattern2, pattern3, pexpect.EOF])
+ if match_id == 0 or match_id == 1:
dev_name = adb_proc.match.groups()[0]
- return True, dev_name
+ return dev_name
else:
- return False, None
+ return None
def android_adb_disconnect(self, dev_ip):
cmd = "adb disconnect %s" % dev_ip
adb_proc = pexpect.run(cmd, timeout=300, logfile=sys.stdout)
def check_adb_status(self):
+ device_ip = self.get_default_nic_ip()
+ if device_ip is not None:
+ dev_name = self.android_adb_connect(device_ip)
+ if dev_name is not None:
+ print "dev_name = " + dev_name
+ result = self.run_adb_shell_command(dev_name, "echo 1", "1")
+ self.android_adb_disconnect(device_ip)
+ return result
+ return False
+
+ def get_default_nic_ip(self):
# XXX: IP could be assigned in other way in the validation farm
network_interface = self.default_network_interface
+ ip = None
try:
- self.run_cmd_tester(
- 'netcfg %s dhcp' % network_interface, timeout=60)
+ ip = self._get_default_nic_ip_by_ifconfig(network_interface)
except:
- print "netcfg %s dhcp exception" % network_interface
- return False
-
+ pass
+
+ if ip is None:
+ self.get_ip_via_dhcp(network_interface)
+ ip = self._get_default_nic_ip_by_ifconfig(network_interface)
+ return ip
+
+ def _get_default_nic_ip_by_ifconfig(self, nic_name):
# Check network ip and setup adb connection
- ip_pattern = "(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"
- cmd = "ifconfig %s" % network_interface
+ ip_pattern = "%s: ip (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) mask" % nic_name
+ cmd = "ifconfig %s" % nic_name
self.proc.sendline('')
self.proc.sendline(cmd)
+ match_id = 0
try:
- id = self.proc.expect([ip_pattern, pexpect.EOF], timeout=60)
- except:
- print "ifconfig can not match ip pattern"
- return False
- if id == 0:
+ match_id = self.proc.expect([ip_pattern, pexpect.EOF], timeout=60)
+ except Exception as e:
+ raise NetworkError("ifconfig can not match ip pattern for %s:%s" % (nic_name, e))
+
+ if match_id == 0:
match_group = self.proc.match.groups()
if len(match_group) > 0:
- device_ip = match_group[0]
- adb_status, dev_name = self.android_adb_connect(device_ip)
- if adb_status == True:
- print "dev_name = " + dev_name
- result = self.run_adb_shell_command(dev_name, "echo 1", "1")
- self.android_adb_disconnect(device_ip)
- return result
- return False
+ return match_group[0]
+ return None
+
+ def get_ip_via_dhcp(self, nic):
+ try:
+ self.run_cmd_tester('netcfg %s dhcp' % nic, timeout=60)
+ except:
+ raise NetworkError("netcfg %s dhcp exception" % nic)
+
+
+ def android_adb_connect_over_default_nic_ip(self):
+ dev_ip = self.get_default_nic_ip()
+ if dev_ip is not None:
+ return self.android_adb_connect(dev_ip)
+
+ def android_adb_disconnect_over_default_nic_ip(self):
+ dev_ip = self.get_default_nic_ip()
+ if dev_ip is not None:
+ self.android_adb_disconnect(dev_ip)
+
+ def enable_adb_over_tcpip(self):
+ self.proc.sendline('echo 0>/sys/class/android_usb/android0/enable')
+ self.proc.sendline('setprop service.adb.tcp.port 5555')
+ self.proc.sendline('stop adbd')
+ self.proc.sendline('start adbd')
+
+ def wait_home_screen(self):
+ cmd = 'getprop init.svc.bootanim'
+ for count in range(100):
+ self.proc.sendline(cmd)
+ match_id = self.proc.expect('stopped')
+ if match_id == 0:
+ return True
+ time.sleep(1)
+ raise GeneralError('The home screen does not displayed')
+