=== renamed file 'doc/examples/jobs/lava-android-test-leb-panda.json' => 'doc/examples/jobs/lava-android-test.json'
@@ -1,5 +1,5 @@
{
- "job_name": "android_monkey_test2",
+ "job_name": "lava_android_test",
"target": "panda01",
"timeout": 18000,
"actions": [
@@ -7,9 +7,9 @@
"command": "deploy_linaro_android_image",
"parameters":
{
- "boot": "http://releases.linaro.org/11.10/android/leb-panda/boot.tar.bz2",
- "system": "http://releases.linaro.org/11.10/android/leb-panda/system.tar.bz2",
- "data": "http://releases.linaro.org/11.10/android/leb-panda/userdata.tar.bz2"
+ "boot": "http://snapshots.linaro.org/android/~linaro-android/panda-ics-gcc46-kwg-upstream-open/540/target/product/pandaboard/boot.tar.bz2",
+ "system": "http://snapshots.linaro.org/android/~linaro-android/panda-ics-gcc46-kwg-upstream-open/540/target/product/pandaboard/system.tar.bz2",
+ "data": "http://snapshots.linaro.org/android/~linaro-android/panda-ics-gcc46-kwg-upstream-open/540/target/product/pandaboard/userdata.tar.bz2"
},
"metadata":
{
@@ -42,6 +42,22 @@
}
},
{
+ "command": "lava_android_test_run_custom",
+ "parameters":
+ {
+ "command_file": "http://bazaar.launchpad.net/~linaro-validation/lava-android-test/trunk/download/head:/busybox_test.sh-20110927085925-2fxzf7wrrtq4gci0-3/busybox_test.sh",
+ "parser": "^\\s*(?P<test_case_id>\\w+)=(?P<result>\\w+)\\s*$"
+ }
+ },
+ {
+ "command": "lava_android_test_run_custom",
+ "parameters":
+ {
+ "commands": ["tjunittest"],
+ "parser": "^\\s*(?P<test_case_id>.+)\\s+\\.\\.\\.\\s+(?P<result>\\w+)\\.\\s+(?P<measurement>[\\d\\.]+)\\s+(?P<units>\\w+)\\s*$"
+ }
+ },
+ {
"command": "lava_android_test_run",
"parameters":
{
=== modified file 'lava_dispatcher/actions/lava-android-test.py'
@@ -1,6 +1,6 @@
#!/usr/bin/python
-# Copyright (C) 2011 Linaro Limited
+# Copyright (C) 2011-2012 Linaro Limited
#
# Author: Linaro Validation Team <linaro-dev@lists.linaro.org>
#
@@ -20,10 +20,12 @@
# along with this program; if not, see <http://www.gnu.org/licenses>.
import os
+import subprocess
import logging
from datetime import datetime
from lava_dispatcher.actions import BaseAction
from lava_dispatcher.client.base import OperationFailed
+from lava_dispatcher.utils import generate_bundle_file_name
class AndroidTestAction(BaseAction):
@@ -40,6 +42,7 @@
'type': 'object',
'properties': {
'test_name': {'type': 'string'},
+ 'option': {'type': 'string', 'optional': True},
'timeout': {'type': 'integer', 'optional': True},
},
'additionalProperties': False,
@@ -49,23 +52,80 @@
return super(cmd_lava_android_test_run, self).test_name() + \
' (%s)' % test_name
- def run(self, test_name, timeout=-1):
+ def run(self, test_name, option=None, timeout=-1):
#Make sure in test image now
self.check_lava_android_test_installed()
with self.client.android_tester_session() as session:
- bundle_name = test_name + "-" + datetime.now().strftime("%H%M%S")
- cmd = 'lava-android-test run %s -s %s -o %s/%s.bundle' % (
- test_name, session.dev_name, self.context.host_result_dir,
- bundle_name)
-
- logging.info("Execute command on host: %s" % cmd)
- rc = os.system(cmd)
+ bundle_name = generate_bundle_file_name(test_name)
+ cmds = ["lava-android-test", 'run', test_name,
+ '-s', session.dev_name,
+ '-o', '%s/%s.bundle' % (self.context.host_result_dir,
+ bundle_name)]
+ if option is not None:
+ cmds.extend(['-O', option])
+ logging.info("Execute command on host: %s" % (' '.join(cmds)))
+ rc = subprocess.call(cmds)
if rc != 0:
raise OperationFailed(
"Failed to run test case(%s) on device(%s) with return "
"value: %s" % (test_name, session.dev_name, rc))
+class cmd_lava_android_test_run_custom(AndroidTestAction):
+
+ parameters_schema = {
+ 'type': 'object',
+ 'properties': {
+ 'commands': {'type': 'array', 'items': {'type': 'string'},
+ 'optional': True},
+ 'command_file': {'type': 'string', 'optional': True},
+ 'parser': {'type': 'string', 'optional': True},
+ 'timeout': {'type': 'integer', 'optional': True},
+ },
+ 'additionalProperties': False,
+ }
+
+ def test_name(self, commands=[], command_file=None, parser=None,
+ timeout=-1):
+ if commands:
+ return '%s (commands=[%s])' % (
+ super(cmd_lava_android_test_run_custom, self).test_name(),
+ ','.join(commands))
+ elif command_file:
+ return '%s (command-file=%s)' % (
+ super(cmd_lava_android_test_run_custom, self).test_name(),
+ command_file)
+
+ def run(self, commands=[], command_file=None, parser=None, timeout=-1):
+ #Make sure in test image now
+ self.check_lava_android_test_installed()
+ if commands or command_file:
+ with self.client.android_tester_session() as session:
+ bundle_name = generate_bundle_file_name('custom')
+ cmds = ["lava-android-test", 'run-custom']
+ if commands:
+ for command in commands:
+ cmds.extend(['-c', command])
+ elif command_file:
+ cmds.extend(['-f', command_file])
+ else:
+ raise OperationFailed(
+ "Only one of the -c and -f option can be specified"
+ " for lava_android_test_run_custom action")
+ cmds.extend(['-s', session.dev_name, '-o',
+ '%s/%s.bundle' % (self.context.host_result_dir,
+ bundle_name)])
+ if parser is not None:
+ cmds.extend(['-p', parser])
+ logging.info("Execute command on host: %s" % (' '.join(cmds)))
+ rc = subprocess.call(cmds)
+ if rc != 0:
+ raise OperationFailed(
+ "Failed to run test custom case[%s] on device(%s)"
+ " with return value: %s" % (' '.join(cmds),
+ session.dev_name, rc))
+
+
class cmd_lava_android_test_install(AndroidTestAction):
"""
lava-test deployment to test image rootfs by chroot
@@ -85,12 +145,13 @@
self.check_lava_android_test_installed()
with self.client.android_tester_session() as session:
for test in tests:
- cmd = 'lava-android-test install %s -s %s' % (
- test, session.dev_name)
+ cmds = ["lava-android-test", 'install',
+ test,
+ '-s', session.dev_name]
if option is not None:
- cmd += ' -o ' + option
- logging.info("Execute command on host: %s" % cmd)
- rc = os.system(cmd)
+ cmds.extend(['-o', option])
+ logging.info("Execute command on host: %s" % (' '.join(cmds)))
+ rc = subprocess.call(cmds)
if rc != 0:
raise OperationFailed(
"Failed to install test case(%s) on device(%s) with "
=== modified file 'lava_dispatcher/actions/lava-test.py'
@@ -1,6 +1,6 @@
#!/usr/bin/python
-# Copyright (C) 2011 Linaro Limited
+# Copyright (C) 2011-2012 Linaro Limited
#
# Author: Paul Larson <paul.larson@linaro.org>
#
@@ -25,6 +25,7 @@
from lava_dispatcher.actions import BaseAction
from lava_dispatcher.client.base import OperationFailed, CriticalError
+from lava_dispatcher.utils import generate_bundle_file_name
def _install_lava_test(client, session):
@@ -32,7 +33,8 @@
session.run('apt-get update')
#Install necessary packages for build lava-test
cmd = ('apt-get -y --force-yes install '
- 'bzr usbutils python-apt python-setuptools python-simplejson lsb-release')
+ 'bzr usbutils python-apt python-setuptools '
+ 'python-simplejson lsb-release')
session.run(cmd, timeout=2400)
session.run("apt-get -y --force-yes install python-pip")
@@ -47,6 +49,7 @@
# cleanup the lava-test - old results, cached files...
session.run('lava-test reset', timeout=60)
+
class cmd_lava_test_run(BaseAction):
parameters_schema = {
@@ -59,21 +62,21 @@
'additionalProperties': False,
}
- def test_name(self, test_name, test_options = "", timeout=-1):
+ def test_name(self, test_name, test_options="", timeout=-1):
return super(cmd_lava_test_run, self).test_name() + ' (%s)' % test_name
- def run(self, test_name, test_options = "", timeout=-1):
+ def run(self, test_name, test_options="", timeout=-1):
logging.info("Executing lava_test_run %s command" % test_name)
with self.client.tester_session() as session:
session.run('mkdir -p %s' % self.context.lava_result_dir)
session.export_display()
- bundle_name = test_name + "-" + datetime.now().strftime("%H%M%S")
-
+ bundle_name = generate_bundle_file_name(test_name)
if test_options != "":
test_options = "-t '%s'" % test_options
cmd = ('lava-test run %s %s -o %s/%s.bundle' % (
- test_name, test_options, self.context.lava_result_dir, bundle_name))
+ test_name, test_options, self.context.lava_result_dir,
+ bundle_name))
try:
rc = session.run(cmd, timeout=timeout)
except:
@@ -89,7 +92,9 @@
if rc is None:
raise OperationFailed("test case getting return value failed")
elif rc != 0:
- raise OperationFailed("test case failed with return value: %s" % rc)
+ raise OperationFailed(
+ "test case failed with return value: %s" % rc)
+
class cmd_lava_test_install(BaseAction):
"""
@@ -111,8 +116,9 @@
'additionalProperties': False,
}
- def run(self, tests, install_python = None, register = None, timeout=2400):
- logging.info("Executing lava_test_install (%s) command" % ",".join(tests))
+ def run(self, tests, install_python=None, register=None, timeout=2400):
+ logging.info(
+ "Executing lava_test_install (%s) command" % ",".join(tests))
with self.client.reliable_session() as session:
@@ -136,7 +142,8 @@
class cmd_add_apt_repository(BaseAction):
"""
add apt repository to test image rootfs by chroot
- arg could be 'deb uri distribution [component1] [component2][...]' or ppa:<ppa_name>
+ arg could be 'deb uri distribution [component1] [component2][...]'
+ or ppa:<ppa_name>
"""
parameters_schema = {
=== modified file 'lava_dispatcher/utils.py'
@@ -1,4 +1,4 @@
-# Copyright (C) 2011 Linaro Limited
+# Copyright (C) 2011-2012 Linaro Limited
#
# Author: Paul Larson <paul.larson@linaro.org>
#
@@ -18,6 +18,7 @@
# along
# with this program; if not, see <http://www.gnu.org/licenses>.
+import datetime
import errno
import logging
import os
@@ -33,12 +34,12 @@
urlpath = urlparse.urlsplit(url).path
filename = os.path.basename(urlpath)
if path:
- filename = os.path.join(path,filename)
+ filename = os.path.join(path, filename)
fd = open(filename, "w")
try:
response = urllib2.urlopen(urllib2.quote(url, safe=":/"), timeout=30)
fd = open(filename, 'wb')
- shutil.copyfileobj(response,fd,0x10000)
+ shutil.copyfileobj(response, fd, 0x10000)
fd.close()
response.close()
except:
@@ -47,6 +48,7 @@
raise RuntimeError("Could not retrieve %s" % url)
return filename
+
def download_with_cache(url, path="", cachedir=""):
cache_loc = url_to_cache(url, cachedir)
if os.path.exists(cache_loc):
@@ -60,7 +62,8 @@
if err.errno == errno.EEXIST:
logging.debug("Cached copy of %s already exists" % url)
else:
- logging.exception("os.link '%s' with '%s' failed"%(cache_loc,file_location))
+ logging.exception("os.link '%s' with '%s' failed" % (cache_loc,
+ file_location))
else:
file_location = download(url, path)
try:
@@ -78,12 +81,14 @@
logging.exception("os.link failed")
return file_location
+
def url_to_cache(url, cachedir):
url_parts = urlparse.urlsplit(url)
path = os.path.join(cachedir, url_parts.netloc,
url_parts.path.lstrip(os.sep))
return path
+
def string_to_list(string):
splitter = shlex(string, posix=True)
splitter.whitespace = ","
@@ -92,35 +97,43 @@
strip_newlines = lambda x: newlines_to_spaces(x).strip(' ')
return map(strip_newlines, list(splitter))
+
def logging_system(cmd):
- logging.debug("Executing on host : '%r'"%cmd)
+ logging.debug("Executing on host : '%r'" % cmd)
return os.system(cmd)
class logging_spawn(pexpect.spawn):
def sendline(self, *args, **kw):
- logging.debug("sendline : %s" %args[0])
+ logging.debug("sendline : %s" % args[0])
return super(logging_spawn, self).sendline(*args, **kw)
def send(self, *args, **kw):
- logging.debug("send : %s" %args[0])
+ logging.debug("send : %s" % args[0])
return super(logging_spawn, self).send(*args, **kw)
def expect(self, *args, **kw):
# some expect should not be logged because it is so much noise.
- if kw.has_key('lava_no_logging'):
+ if 'lava_no_logging' in kw:
del kw['lava_no_logging']
return self.expect(*args, **kw)
- if (kw.has_key('timeout')):
+ if 'timeout' in kw:
timeout = kw['timeout']
else:
timeout = self.timeout
if len(args) == 1:
- logging.debug("expect (%d): '%s'" %(timeout, args[0]))
+ logging.debug("expect (%d): '%s'" % (timeout, args[0]))
else:
- logging.debug("expect (%d): '%s'" %(timeout, str(args)))
+ logging.debug("expect (%d): '%s'" % (timeout, str(args)))
return super(logging_spawn, self).expect(*args, **kw)
+
+
+def generate_bundle_file_name(test_name):
+ return ("{test_id}.{time.tm_year:04}-{time.tm_mon:02}-{time.tm_mday:02}T"
+ "{time.tm_hour:02}:{time.tm_min:02}:{time.tm_sec:02}Z").format(
+ test_id=test_name,
+ time=datetime.datetime.utcnow().timetuple())