[OE-core] [PATCH v2] testimage: Run commands in target and host when test fails
Paul Eggleton
paul.eggleton at linux.intel.com
Wed Aug 19 12:36:07 UTC 2015
On Tuesday 18 August 2015 14:52:38 mariano.lopez at linux.intel.com wrote:
> From: Mariano Lopez <mariano.lopez at linux.intel.com>
>
> This patch modify three files altought two of them
> are minimal modifications. This version includes
> the changes proposed by Paul.
>
> testimage.bbclass:
> Create new vars for easy modification of the dump
> directory and commands to be run on host and target
> when a test fails
> TESTIMAGE_DUMP_DIR: Directory to save the dumps
> testimage_dump_target: Commands to run on target
> testimage_dump_host: Commands to run on host
>
> oetest.py:
> - Allow to use the vars defined in testimage class
> - Now able to run commands in the host and dump the
> results
> - Fix an issue with the condition where to run the
> dump commands (Before it run the commands every
> test after a failure, now it runs the commands only
> in tests that failed)
> - Fix the output to stdout
>
> [YOCTO #8118]
>
> Signed-off-by: Mariano Lopez <mariano.lopez at linux.intel.com>
> ---
> meta/classes/testimage.bbclass | 24 +++++++++++++++++++++
> meta/lib/oeqa/oetest.py | 48
> +++++++++++++++++++++++++++++------------- meta/lib/oeqa/targetcontrol.py |
> 3 +++
> 3 files changed, 60 insertions(+), 15 deletions(-)
>
> diff --git a/meta/classes/testimage.bbclass b/meta/classes/testimage.bbclass
> index 140babe..1d9464f 100644
> --- a/meta/classes/testimage.bbclass
> +++ b/meta/classes/testimage.bbclass
> @@ -56,6 +56,30 @@ TESTIMAGEDEPENDS_qemuall =
> "qemu-native:do_populate_sysroot qemu-helper-native:d TESTIMAGELOCK =
> "${TMPDIR}/testimage.lock"
> TESTIMAGELOCK_qemuall = ""
>
> +TESTIMAGE_DUMP_DIR ?= "/tmp/oe-saved-tests/"
> +
> +testimage_dump_target () {
> + top -bn1
> + ps
> + free
> + df
> + _ping
> + dmesg
> + netstat -an
> + ip address
> + _logs
> +}
> +
> +testimage_dump_host () {
> + top -bn1
> + ps -ef
> + free
> + df
> + memstat
> + dmesg
> + netstat -an
> +}
> +
> python do_testimage() {
> testimage_main(d)
> }
> diff --git a/meta/lib/oeqa/oetest.py b/meta/lib/oeqa/oetest.py
> index dfed3de..e765c96 100644
> --- a/meta/lib/oeqa/oetest.py
> +++ b/meta/lib/oeqa/oetest.py
> @@ -12,8 +12,10 @@ import unittest
> import inspect
> import subprocess
> import datetime
> +import commands
> import bb
> from oeqa.utils.decorators import LogResults
> +from sys import exc_info, exc_clear
>
> def loadTests(tc, type="runtime"):
> if type == "runtime":
> @@ -120,35 +122,51 @@ class oeRuntimeTest(oeTest):
>
> def tearDown(self):
> # If a test fails or there is an exception
> - if (self._resultForDoCleanups.failures or
> - self._resultForDoCleanups.errors):
> - self.dump_target_logs()
> -
> - def dump_target_logs(self):
> - commands = ["top -bn1", "ps", "free", "df", "_ping", "dmesg",
> "netstat -a", "ifconfig -a", "_logs"] - dump_dir =
> "/tmp/oe-saved-tests"
> + if not exc_info() == (None, None, None):
> + exc_clear()
> + dump_dir = self.create_dump_dir()
> + print ("%s dump data from host and target "
> + "stored in %s" % (self._testMethodName, dump_dir))
> + self.dump_host_logs(dump_dir)
> + self.dump_target_logs(dump_dir)
> +
> + def create_dump_dir(self):
> dump_sub_dir = ("%s_%s" % (
> datetime.datetime.now().strftime('%Y%m%d%H%M'),
> self._testMethodName))
> - dump_dir = os.path.join(dump_dir, dump_sub_dir)
> + dump_dir = os.path.join(self.target.dump_dir, dump_sub_dir)
> os.makedirs(dump_dir)
> - bb.warn("%s failed: getting data from target and "
> - "saving into %s" % (self._testMethodName, dump_dir))
> - for command in commands:
> + return dump_dir
> +
> + def dump_host_logs(self, dump_dir):
> + for cmd in self.target.dump_host.split('\n'):
> + cmd = cmd.lstrip()
> + if not cmd:
> + continue
> + output = commands.getoutput(cmd)
> + filename = "host_%s" % cmd.split()[0]
> + with open(os.path.join(dump_dir, filename), 'w') as f:
> + f.write(output)
> +
> + def dump_target_logs(self, dump_dir):
> + for cmd in self.target.dump_target.split('\n'):
> + cmd = cmd.lstrip()
> + if not cmd:
> + continue
> # This will ping the host from target
> - if command == "_ping":
> + if cmd == "_ping":
> comm = "ping -c3 %s" % self.target.server_ip
> # This will get all the logs from /var/log/
> - elif command == "_logs":
> + elif cmd == "_logs":
> comm = 'find /var/log/ -type f 2>/dev/null '
> comm = '%s-exec echo "%s" \\; ' % (comm, '='*20)
> comm = '%s-exec echo {} \\; ' % comm
> comm = '%s-exec echo "%s" \\; ' % (comm, '='*20)
> comm = '%s-exec cat {} \\; -exec echo "" \\;' % comm
> else:
> - comm = command
> + comm = cmd
> (status, output) = self.target.run_serial(comm)
> - filename = command.split()[0]
> + filename = "target_%s" % cmd.split()[0]
> with open(os.path.join(dump_dir, filename), 'w') as f:
> f.write(output)
I have to say I'd be a bit happier about this if none of the commands we had
in the functions were special - i.e. instead of "_ping" we have "ping -c3
${TARGET_IP}" - if we need to substitute in values then we set those as
variables in a copy of the datastore that we then use to get the expanded
value of the function.
Perhaps we can do that as a follow-up refactoring though.
Cheers,
Paul
--
Paul Eggleton
Intel Open Source Technology Centre
More information about the Openembedded-core
mailing list