OEQA Framework Refactor & Improvements
cover OEQA Framework Refactor & Improvements
This patchset is related to OEQA Framework for details read the RFC send to the Openembedded architecture ML.
http://lists.openembedded.org/pipermail/openembedded-architecture/2016-December/000351.html
Also adds the migration of the runtime testing leaving only selftest remains to migrate.
The testing was made using GDC Autobuilder building in different archs and running selftest.
The following changes since commit b47ecf28775830efab423fa12f0addb68671cc06:
poky.ent: Added "pip3" as an essential host installation package (2017-01-20 11:57:25 +0000)
are available in the git repository at:
git://git.yoctoproject.org/poky-contrib alimon/oeqa_runtime_migration
http://git.yoctoproject.org/cgit.cgi/poky-contrib/log/?h=alimon/oeqa_runtime_migration
Aníbal Limón (31):
oeqa/core: Add base OEQA framework
oeqa/core: Add loader, context and decorator modules oeqa/core/decorator: Add support for OETestDepends oeqa/core/decorator: Add support for OETestDataDepends and
skipIfDataVar
scripts/oe-test: Add new oe-test script
oeqa/core/context: Add support of OETestContextExecutor oeqa/core/cases: Add example test cases
oeqa/core: Add README
oe/data: Add export2json function classes/rootfs-postcommands: Add write_image_test_data classes/populate_sdk_base: Add write_sdk_test_data to postprocess
oeqa: Move common files to oeqa/files instead of runtime only oeqa/sdk: Move test cases inside cases directory oeqa/{runtime,sdk}/files: Move testsdkmakefile from runtime to sdk
module
oeqa/sdk: Add case and context modules for the SDK component classes/testsdk: Migrates testsdk.bbclass to use new OESDKTestContext oeqa/utils: Move targetbuild to buildproject module oeqa/utils: {Target,SDK,}BuildProject remove dependency of bb oeqa/sdk/cases: Migrate tests to the new OEQA framework classes/testsdk: Remove the need of TEST_LOG_DIR variable oeqa/sdkext: Move test cases inside cases directory oeqa/sdkext: Adds case and context modules. classes/testsdk: Migrate to use the new OESDKExtTestContext oeqa/sdkext/cases: Migrate test case to new OEQA framework oeqa/runtime: Fix TargetBuildProject instances
oeqa: Fix files handling on runtime tests.
oeqa/runtime: Move to runtime_cases
oeqa/runtime/context: Add runtime option group and options for target
type and server ip.
oeqa/runtime/context: Move helper functions for process args to
executor
oeqa/utils/dump: Move get_host_dumper to OERuntimeTestContextExecutor
class
oeqa/runtime/context.py: Prepare for qemu
Mariano Lopez (24):
oeqa/core: Add utils module for OEQA framework oeqa/core/decorator: Add support for OETestID and OETestTag oeqa/core/decorator: Add support for OETimeout decorator oeqa/core: Add tests for the OEQA framework oeqa/utils/__init__.py: Adds compatibility with bitbake logger oeqa/core/target Add OESSHTarget to sent commands to targets using SSH oeqa/runtime: Add case, context and loader classes for runtime testing oeqa/runtime: Add OEHasPackage decorator oeqa/core/decorator/data.py: Add skipIfNotFeature decorator oeqa/runtime/files: Move runtime files from old directory oeqa/runtime/utils/targetbuildproject.py: Don't use more than 80
characters per line
oeqa/core/decorator: Add skipIfNotDataVar and skipIfNotInDataVar oeqa/core/context: Add option to select tests to run oeqa/runtime/context.py: Add logger to getTarget core/target/qemu.py Adds qemu target
testimage.bbclass: Migrate class to use new runtime framework oeqa/runtime/cases: Migrate runtime tests. runtime/cases/smart.py: Migrate smart tests oeqa/core/utils/test.py: Add functions to get module path testimage.bbclass: Add support for package extraction testimage.bbclass: Add package install feature oeqa/runtime/context.py: Add defaults for runtime context testexport.bbclass: Migrate testexport to use new framework selftest/runtime-test.py: Adapt test to use new runtime framework
.../lib/oeqa/runtime/{ => cases}/selftest.json | 0
.../lib/oeqa/runtime/{ => cases}/selftest.py | 34 +--
meta/classes/populate_sdk_base.bbclass | 9 +-
meta/classes/rootfs-postcommands.bbclass | 18 ++
meta/classes/testexport.bbclass | 211 +++++++---------
meta/classes/testimage.bbclass | 263 ++++++++++++++++----
meta/classes/testsdk.bbclass | 167 +++++++------
meta/lib/oe/data.py | 28 +++
meta/lib/oeqa/core/README | 38 +++
meta/lib/oeqa/core/__init__.py | 0
meta/lib/oeqa/core/case.py | 46 ++++
meta/lib/oeqa/core/cases/__init__.py | 0
meta/lib/oeqa/core/cases/example/data.json | 1 +
meta/lib/oeqa/core/cases/example/test_basic.py | 20 ++
meta/lib/oeqa/core/context.py | 239 ++++++++++++++++++
meta/lib/oeqa/core/decorator/__init__.py | 71 ++++++
meta/lib/oeqa/core/decorator/data.py | 98 ++++++++
meta/lib/oeqa/core/decorator/depends.py | 94 ++++++++
meta/lib/oeqa/core/decorator/oeid.py | 23 ++
meta/lib/oeqa/core/decorator/oetag.py | 24 ++
meta/lib/oeqa/core/decorator/oetimeout.py | 25 ++
meta/lib/oeqa/core/exception.py | 14 ++
meta/lib/oeqa/core/loader.py | 235 ++++++++++++++++++
meta/lib/oeqa/core/runner.py | 76 ++++++
meta/lib/oeqa/core/target/__init__.py | 33 +++
meta/lib/oeqa/core/target/qemu.py | 45 ++++
meta/lib/oeqa/core/target/ssh.py | 266 +++++++++++++++++++++
meta/lib/oeqa/core/tests/__init__.py | 0
meta/lib/oeqa/core/tests/cases/data.py | 20 ++
meta/lib/oeqa/core/tests/cases/depends.py | 38 +++
.../oeqa/core/tests/cases/loader/invalid/oeid.py | 15 ++
.../oeqa/core/tests/cases/loader/valid/another.py | 9 +
meta/lib/oeqa/core/tests/cases/oeid.py | 18 ++
meta/lib/oeqa/core/tests/cases/oetag.py | 18 ++
meta/lib/oeqa/core/tests/cases/timeout.py | 18 ++
meta/lib/oeqa/core/tests/common.py | 35 +++
meta/lib/oeqa/core/tests/test_data.py | 51 ++++
meta/lib/oeqa/core/tests/test_decorators.py | 135 +++++++++++
meta/lib/oeqa/core/tests/test_loader.py | 86 +++++++
meta/lib/oeqa/core/tests/test_runner.py | 38 +++
meta/lib/oeqa/core/utils/__init__.py | 0
meta/lib/oeqa/core/utils/misc.py | 37 +++
meta/lib/oeqa/core/utils/path.py | 19 ++
meta/lib/oeqa/core/utils/test.py | 86 +++++++
meta/lib/oeqa/{runtime => }/files/test.c | 0
meta/lib/oeqa/{runtime => }/files/test.cpp | 0
meta/lib/oeqa/{runtime => }/files/test.pl | 0
meta/lib/oeqa/{runtime => }/files/test.py | 0
meta/lib/oeqa/oetest.py | 92 +------
meta/lib/oeqa/runtime/buildcvs.py | 31 ---
meta/lib/oeqa/runtime/buildgalculator.py | 24 --
meta/lib/oeqa/runtime/buildiptables.py | 31 ---
meta/lib/oeqa/runtime/case.py | 17 ++
meta/lib/oeqa/runtime/{ => cases}/_ptest.py | 0
meta/lib/oeqa/runtime/{ => cases}/_qemutiny.py | 0
meta/lib/oeqa/runtime/cases/buildcvs.py | 35 +++
meta/lib/oeqa/runtime/cases/buildgalculator.py | 31 +++
meta/lib/oeqa/runtime/cases/buildiptables.py | 39 +++
meta/lib/oeqa/runtime/cases/connman.py | 30 +++
meta/lib/oeqa/runtime/cases/date.py | 38 +++
meta/lib/oeqa/runtime/cases/df.py | 13 +
meta/lib/oeqa/runtime/cases/gcc.py | 76 ++++++
meta/lib/oeqa/runtime/cases/kernelmodule.py | 40 ++++
meta/lib/oeqa/runtime/cases/ldd.py | 25 ++
meta/lib/oeqa/runtime/cases/logrotate.py | 42 ++++
meta/lib/oeqa/runtime/cases/multilib.py | 41 ++++
meta/lib/oeqa/runtime/cases/pam.py | 33 +++
meta/lib/oeqa/runtime/{ => cases}/parselogs.py | 187 +++++++++------
meta/lib/oeqa/runtime/cases/perl.py | 37 +++
meta/lib/oeqa/runtime/cases/ping.py | 24 ++
meta/lib/oeqa/runtime/cases/python.py | 43 ++++
meta/lib/oeqa/runtime/cases/rpm.py | 141 +++++++++++
meta/lib/oeqa/runtime/cases/scanelf.py | 26 ++
meta/lib/oeqa/runtime/cases/scp.py | 33 +++
meta/lib/oeqa/runtime/cases/skeletoninit.py | 33 +++
meta/lib/oeqa/runtime/{ => cases}/smart.py | 172 ++++++-------
meta/lib/oeqa/runtime/cases/ssh.py | 15 ++
meta/lib/oeqa/runtime/cases/syslog.py | 57 +++++
meta/lib/oeqa/runtime/{ => cases}/systemd.py | 151 ++++++------
meta/lib/oeqa/runtime/cases/x32lib.py | 19 ++
meta/lib/oeqa/runtime/cases/xorg.py | 17 ++
meta/lib/oeqa/runtime/connman.py | 31 ---
meta/lib/oeqa/runtime/context.py | 143 +++++++++++
meta/lib/oeqa/runtime/date.py | 31 ---
meta/lib/oeqa/runtime/decorator/package.py | 53 ++++
meta/lib/oeqa/runtime/df.py | 12 -
meta/lib/oeqa/runtime/gcc.py | 47 ----
meta/lib/oeqa/runtime/kernelmodule.py | 34 ---
meta/lib/oeqa/runtime/ldd.py | 21 --
meta/lib/oeqa/runtime/loader.py | 16 ++
meta/lib/oeqa/runtime/logrotate.py | 30 ---
meta/lib/oeqa/runtime/multilib.py | 42 ----
meta/lib/oeqa/runtime/pam.py | 25 --
meta/lib/oeqa/runtime/perl.py | 30 ---
meta/lib/oeqa/runtime/ping.py | 22 --
meta/lib/oeqa/runtime/python.py | 35 ---
meta/lib/oeqa/runtime/rpm.py | 120 ----------
meta/lib/oeqa/runtime/scanelf.py | 28 ---
meta/lib/oeqa/runtime/scp.py | 22 --
meta/lib/oeqa/runtime/skeletoninit.py | 29 ---
meta/lib/oeqa/runtime/ssh.py | 19 --
meta/lib/oeqa/runtime/syslog.py | 52 ----
meta/lib/oeqa/runtime/utils/__init__.py | 0
meta/lib/oeqa/runtime/utils/targetbuildproject.py | 36 +++
meta/lib/oeqa/runtime/x32lib.py | 18 --
meta/lib/oeqa/runtime/xorg.py | 16 --
meta/lib/oeqa/sdk/__init__.py | 3 -
meta/lib/oeqa/sdk/case.py | 12 +
meta/lib/oeqa/sdk/{ => cases}/buildcvs.py | 15 +-
meta/lib/oeqa/sdk/{ => cases}/buildgalculator.py | 28 ++-
meta/lib/oeqa/sdk/{ => cases}/buildiptables.py | 16 +-
meta/lib/oeqa/sdk/cases/gcc.py | 42 ++++
meta/lib/oeqa/sdk/cases/perl.py | 27 +++
meta/lib/oeqa/sdk/{ => cases}/python.py | 25 +-
meta/lib/oeqa/sdk/context.py | 133 +++++++++++
.../oeqa/{runtime => sdk}/files/testsdkmakefile | 0
meta/lib/oeqa/sdk/gcc.py | 36 ---
meta/lib/oeqa/sdk/perl.py | 28 ---
meta/lib/oeqa/sdk/utils/__init__.py | 0
meta/lib/oeqa/sdk/utils/sdkbuildproject.py | 45 ++++
meta/lib/oeqa/sdkext/__init__.py | 3 -
meta/lib/oeqa/sdkext/case.py | 21 ++
meta/lib/oeqa/sdkext/{ => cases}/devtool.py | 49 ++--
meta/lib/oeqa/sdkext/{ => cases}/sdk_update.py | 17 +-
meta/lib/oeqa/sdkext/context.py | 21 ++
meta/lib/oeqa/selftest/runtime-test.py | 42 ++--
meta/lib/oeqa/utils/__init__.py | 30 +++
meta/lib/oeqa/utils/buildproject.py | 52 ++++
meta/lib/oeqa/utils/dump.py | 11 +-
meta/lib/oeqa/utils/package_manager.py | 181 ++++++++++++++
scripts/oe-test | 105 ++++++++
131 files changed, 4631 insertions(+), 1517 deletions(-)
rename meta-selftest/lib/oeqa/runtime/{ => cases}/selftest.json (100%)
rename meta-selftest/lib/oeqa/runtime/{ => cases}/selftest.py (53%)
create mode 100644 meta/lib/oeqa/core/README
create mode 100644 meta/lib/oeqa/core/__init__.py
create mode 100644 meta/lib/oeqa/core/case.py
create mode 100644 meta/lib/oeqa/core/cases/__init__.py
create mode 100644 meta/lib/oeqa/core/cases/example/data.json
create mode 100644 meta/lib/oeqa/core/cases/example/test_basic.py
create mode 100644 meta/lib/oeqa/core/context.py
create mode 100644 meta/lib/oeqa/core/decorator/__init__.py
create mode 100644 meta/lib/oeqa/core/decorator/data.py
create mode 100644 meta/lib/oeqa/core/decorator/depends.py
create mode 100644 meta/lib/oeqa/core/decorator/oeid.py
create mode 100644 meta/lib/oeqa/core/decorator/oetag.py
create mode 100644 meta/lib/oeqa/core/decorator/oetimeout.py
create mode 100644 meta/lib/oeqa/core/exception.py
create mode 100644 meta/lib/oeqa/core/loader.py
create mode 100644 meta/lib/oeqa/core/runner.py
create mode 100644 meta/lib/oeqa/core/target/__init__.py
create mode 100644 meta/lib/oeqa/core/target/qemu.py
create mode 100644 meta/lib/oeqa/core/target/ssh.py
create mode 100644 meta/lib/oeqa/core/tests/__init__.py
create mode 100644 meta/lib/oeqa/core/tests/cases/data.py
create mode 100644 meta/lib/oeqa/core/tests/cases/depends.py
create mode 100644 meta/lib/oeqa/core/tests/cases/loader/invalid/oeid.py
create mode 100644 meta/lib/oeqa/core/tests/cases/loader/valid/another.py
create mode 100644 meta/lib/oeqa/core/tests/cases/oeid.py
create mode 100644 meta/lib/oeqa/core/tests/cases/oetag.py
create mode 100644 meta/lib/oeqa/core/tests/cases/timeout.py
create mode 100644 meta/lib/oeqa/core/tests/common.py
create mode 100755 meta/lib/oeqa/core/tests/test_data.py
create mode 100755 meta/lib/oeqa/core/tests/test_decorators.py
create mode 100755 meta/lib/oeqa/core/tests/test_loader.py
create mode 100755 meta/lib/oeqa/core/tests/test_runner.py
create mode 100644 meta/lib/oeqa/core/utils/__init__.py
create mode 100644 meta/lib/oeqa/core/utils/misc.py
create mode 100644 meta/lib/oeqa/core/utils/path.py
create mode 100644 meta/lib/oeqa/core/utils/test.py
rename meta/lib/oeqa/{runtime => }/files/test.c (100%)
rename meta/lib/oeqa/{runtime => }/files/test.cpp (100%)
rename meta/lib/oeqa/{runtime => }/files/test.pl (100%)
rename meta/lib/oeqa/{runtime => }/files/test.py (100%)
delete mode 100644 meta/lib/oeqa/runtime/buildcvs.py
delete mode 100644 meta/lib/oeqa/runtime/buildgalculator.py
delete mode 100644 meta/lib/oeqa/runtime/buildiptables.py
create mode 100644 meta/lib/oeqa/runtime/case.py
rename meta/lib/oeqa/runtime/{ => cases}/_ptest.py (100%)
rename meta/lib/oeqa/runtime/{ => cases}/_qemutiny.py (100%)
create mode 100644 meta/lib/oeqa/runtime/cases/buildcvs.py
create mode 100644 meta/lib/oeqa/runtime/cases/buildgalculator.py
create mode 100644 meta/lib/oeqa/runtime/cases/buildiptables.py
create mode 100644 meta/lib/oeqa/runtime/cases/connman.py
create mode 100644 meta/lib/oeqa/runtime/cases/date.py
create mode 100644 meta/lib/oeqa/runtime/cases/df.py
create mode 100644 meta/lib/oeqa/runtime/cases/gcc.py
create mode 100644 meta/lib/oeqa/runtime/cases/kernelmodule.py
create mode 100644 meta/lib/oeqa/runtime/cases/ldd.py
create mode 100644 meta/lib/oeqa/runtime/cases/logrotate.py
create mode 100644 meta/lib/oeqa/runtime/cases/multilib.py
create mode 100644 meta/lib/oeqa/runtime/cases/pam.py
rename meta/lib/oeqa/runtime/{ => cases}/parselogs.py (64%)
create mode 100644 meta/lib/oeqa/runtime/cases/perl.py
create mode 100644 meta/lib/oeqa/runtime/cases/ping.py
create mode 100644 meta/lib/oeqa/runtime/cases/python.py
create mode 100644 meta/lib/oeqa/runtime/cases/rpm.py
create mode 100644 meta/lib/oeqa/runtime/cases/scanelf.py
create mode 100644 meta/lib/oeqa/runtime/cases/scp.py
create mode 100644 meta/lib/oeqa/runtime/cases/skeletoninit.py
rename meta/lib/oeqa/runtime/{ => cases}/smart.py (49%)
create mode 100644 meta/lib/oeqa/runtime/cases/ssh.py
create mode 100644 meta/lib/oeqa/runtime/cases/syslog.py
rename meta/lib/oeqa/runtime/{ => cases}/systemd.py (51%)
create mode 100644 meta/lib/oeqa/runtime/cases/x32lib.py
create mode 100644 meta/lib/oeqa/runtime/cases/xorg.py
delete mode 100644 meta/lib/oeqa/runtime/connman.py
create mode 100644 meta/lib/oeqa/runtime/context.py
delete mode 100644 meta/lib/oeqa/runtime/date.py
create mode 100644 meta/lib/oeqa/runtime/decorator/package.py
delete mode 100644 meta/lib/oeqa/runtime/df.py
delete mode 100644 meta/lib/oeqa/runtime/gcc.py
delete mode 100644 meta/lib/oeqa/runtime/kernelmodule.py
delete mode 100644 meta/lib/oeqa/runtime/ldd.py
create mode 100644 meta/lib/oeqa/runtime/loader.py
delete mode 100644 meta/lib/oeqa/runtime/logrotate.py
delete mode 100644 meta/lib/oeqa/runtime/multilib.py
delete mode 100644 meta/lib/oeqa/runtime/pam.py
delete mode 100644 meta/lib/oeqa/runtime/perl.py
delete mode 100644 meta/lib/oeqa/runtime/ping.py
delete mode 100644 meta/lib/oeqa/runtime/python.py
delete mode 100644 meta/lib/oeqa/runtime/rpm.py
delete mode 100644 meta/lib/oeqa/runtime/scanelf.py
delete mode 100644 meta/lib/oeqa/runtime/scp.py
delete mode 100644 meta/lib/oeqa/runtime/skeletoninit.py
delete mode 100644 meta/lib/oeqa/runtime/ssh.py
delete mode 100644 meta/lib/oeqa/runtime/syslog.py
create mode 100644 meta/lib/oeqa/runtime/utils/__init__.py
create mode 100644 meta/lib/oeqa/runtime/utils/targetbuildproject.py
delete mode 100644 meta/lib/oeqa/runtime/x32lib.py
delete mode 100644 meta/lib/oeqa/runtime/xorg.py
create mode 100644 meta/lib/oeqa/sdk/case.py
rename meta/lib/oeqa/sdk/{ => cases}/buildcvs.py (59%)
rename meta/lib/oeqa/sdk/{ => cases}/buildgalculator.py (45%)
rename meta/lib/oeqa/sdk/{ => cases}/buildiptables.py (58%)
create mode 100644 meta/lib/oeqa/sdk/cases/gcc.py
create mode 100644 meta/lib/oeqa/sdk/cases/perl.py
rename meta/lib/oeqa/sdk/{ => cases}/python.py (46%)
create mode 100644 meta/lib/oeqa/sdk/context.py
rename meta/lib/oeqa/{runtime => sdk}/files/testsdkmakefile (100%)
delete mode 100644 meta/lib/oeqa/sdk/gcc.py
delete mode 100644 meta/lib/oeqa/sdk/perl.py
create mode 100644 meta/lib/oeqa/sdk/utils/__init__.py
create mode 100644 meta/lib/oeqa/sdk/utils/sdkbuildproject.py
create mode 100644 meta/lib/oeqa/sdkext/case.py
rename meta/lib/oeqa/sdkext/{ => cases}/devtool.py (73%)
rename meta/lib/oeqa/sdkext/{ => cases}/sdk_update.py (63%)
create mode 100644 meta/lib/oeqa/sdkext/context.py
create mode 100644 meta/lib/oeqa/utils/buildproject.py
create mode 100755 scripts/oe-testSignature · 1 line
2.1.4
PATCH 1/55 oeqa/core: Add base OEQA framework
case: Defines OETestCase base class that provides custom
methods/attrs defined by the framework.
Every OETestCase instance contains a reference to the test data (d), the test context (tc) and the logger. Also implements _oe{SetUp,TearDown}Class for make special handling of OEQA decorators and validations.
runner: Defines OETestRunner/OETestResult with support for RAW
and XML result logs.
exception: Custom exceptions related to the OEQA framework based
on class OEQAException.
[YOCTO #10230]
[YOCTO #10233]
--- meta/lib/oeqa/core/__init__.py | 0 meta/lib/oeqa/core/case.py | 46 +++++++++++++++++++++++++ meta/lib/oeqa/core/exception.py | 14 ++++++++ meta/lib/oeqa/core/runner.py | 76 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 meta/lib/oeqa/core/__init__.py create mode 100644 meta/lib/oeqa/core/case.py create mode 100644 meta/lib/oeqa/core/exception.py create mode 100644 meta/lib/oeqa/core/runner.py
meta/lib/oeqa/core/__init__.py new file +0 -0
meta/lib/oeqa/core/case.py new file +46 -0
46 lines not on this page · raw message
meta/lib/oeqa/core/exception.py new file +14 -0
@@ -0,0 +1,14 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +class OEQAException(Exception): + pass + +class OEQATimeoutError(OEQAException): + pass + +class OEQAMissingVariable(OEQAException): + pass + +class OEQADependency(OEQAException): + pass
meta/lib/oeqa/core/runner.py new file +76 -0
76 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH 2/55 oeqa/core: Add utils module for OEQA framework
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
misc: Functions for transform object to other types.
path: Functions for path handling.
test: Functions for operations related to test cases and suites.
[YOCTO #10232]
--- meta/lib/oeqa/core/utils/__init__.py | 0 meta/lib/oeqa/core/utils/misc.py | 37 +++++++++++++++++++ meta/lib/oeqa/core/utils/path.py | 19 ++++++++++ meta/lib/oeqa/core/utils/test.py | 71 ++++++++++++++++++++++++++++++++++++ 4 files changed, 127 insertions(+) create mode 100644 meta/lib/oeqa/core/utils/__init__.py create mode 100644 meta/lib/oeqa/core/utils/misc.py create mode 100644 meta/lib/oeqa/core/utils/path.py create mode 100644 meta/lib/oeqa/core/utils/test.py
meta/lib/oeqa/core/utils/__init__.py new file +0 -0
meta/lib/oeqa/core/utils/misc.py new file +37 -0
@@ -0,0 +1,37 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +def toList(obj, obj_type, obj_name="Object"): + if isinstance(obj, obj_type): + return [obj] + elif isinstance(obj, list): + return obj + else: + raise TypeError("%s must be %s or list" % (obj_name, obj_type)) + +def toSet(obj, obj_type, obj_name="Object"): + if isinstance(obj, obj_type): + return {obj} + elif isinstance(obj, list): + return set(obj) + elif isinstance(obj, set): + return obj + else: + raise TypeError("%s must be %s or set" % (obj_name, obj_type)) + +def strToList(obj, obj_name="Object"): + return toList(obj, str, obj_name) + +def strToSet(obj, obj_name="Object"): + return toSet(obj, str, obj_name) + +def intToList(obj, obj_name="Object"): + return toList(obj, int, obj_name) + +def dataStoteToDict(d, variables): + data = {} + + for v in variables: + data[v] = d.getVar(v, True) + + return data
meta/lib/oeqa/core/utils/path.py new file +19 -0
@@ -0,0 +1,19 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +import os +import sys + +def findFile(file_name, directory): + """ + Search for a file in directory and returns its complete path. + """ + for r, d, f in os.walk(directory): + if file_name in f: + return os.path.join(r, file_name) + return None + +def remove_safe(path): + if os.path.exists(path): + os.remove(path) +
meta/lib/oeqa/core/utils/test.py new file +71 -0
71 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH 3/55 oeqa/core: Add loader, context and decorator modules
In reply to Aníbal Limónloader: Implements OETestLoader handling OETestDecorator and filtering support when load tests. The OETestLoader is responsible to set custom methods, attrs of the OEQA frameowork.
[YOCTO #10231]
[YOCTO #10317]
[YOCTO #10353]
decorator: Add base class OETestDecorator to provide a common way to define decorators to be used over OETestCase's, every decorator has a method to be called when loading tests and before test execution starts. Special decorators could be implemented for filter tests on loading phase.
context: Provides HIGH level API for loadTests and runTests of certain test component (i.e. runtime, sdk, selftest).
[YOCTO #10230]
--- meta/lib/oeqa/core/context.py | 148 +++++++++++++++++++ meta/lib/oeqa/core/decorator/__init__.py | 71 ++++++++++ meta/lib/oeqa/core/loader.py | 235 +++++++++++++++++++++++++++++++ 3 files changed, 454 insertions(+) create mode 100644 meta/lib/oeqa/core/context.py create mode 100644 meta/lib/oeqa/core/decorator/__init__.py create mode 100644 meta/lib/oeqa/core/loader.py
meta/lib/oeqa/core/context.py new file +148 -0
@@ -0,0 +1,148 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +import os +import sys +import json +import time +import logging +import collections +import re + +from oeqa.core.loader import OETestLoader +from oeqa.core.runner import OETestRunner, OEStreamLogger, xmlEnabled + +class OETestContext(object): + loaderClass = OETestLoader + runnerClass = OETestRunner + streamLoggerClass = OEStreamLogger + + files_dir = os.path.abspath(os.path.join(os.path.dirname( + os.path.abspath(__file__)), "../files")) + + def __init__(self, td=None, logger=None): + if not type(td) is dict: + raise TypeError("td isn't dictionary type") + + self.td = td + self.logger = logger + self._registry = {} + self._registry['cases'] = collections.OrderedDict() + self._results = {} + + def _read_modules_from_manifest(self, manifest): + if not os.path.exists(manifest): + raise + + modules = [] + for line in open(manifest).readlines(): + line = line.strip() + if line and not line.startswith("#"): + modules.append(line) + + return modules + + def loadTests(self, module_paths, modules=[], tests=[], + modules_manifest="", modules_required=[], filters={}): + if modules_manifest: + modules = self._read_modules_from_manifest(modules_manifest) + + self.loader = self.loaderClass(self, module_paths, modules, tests, + modules_required, filters) + self.suites = self.loader.discover() + + def runTests(self): + streamLogger = self.streamLoggerClass(self.logger) + self.runner = self.runnerClass(self, stream=streamLogger, verbosity=2) + + self._run_start_time = time.time() + result = self.runner.run(self.suites) + self._run_end_time = time.time() + + return result + + def logSummary(self, result, component, context_msg=''): + self.logger.info("SUMMARY:") + self.logger.info("%s (%s) - Ran %d test%s in %.3fs" % (component, + context_msg, result.testsRun, result.testsRun != 1 and "s" or "", + (self._run_end_time - self._run_start_time))) + + if result.wasSuccessful(): + msg = "%s - OK - All required tests passed" % component + else: + msg = "%s - FAIL - Required tests failed" % component + skipped = len(self._results['skipped']) + if skipped: + msg += " (skipped=%d)" % skipped + self.logger.info(msg) + + def _getDetailsNotPassed(self, case, type, desc): + found = False + + for (scase, msg) in self._results[type]: + # XXX: When XML reporting is enabled scase is + # xmlrunner.result._TestInfo instance instead of + # string. + if xmlEnabled: + if case.id() == scase.test_id: + found = True + break + scase_str = scase.test_id + else: + if case == scase: + found = True + break + scase_str = str(scase) + + # When fails at module or class level the class name is passed as string + # so figure out to see if match + m = re.search("^setUpModule \((?P<module_name>.*)\)$", scase_str) + if m: + if case.__class__.__module__ == m.group('module_name'): + found = True + break + + m = re.search("^setUpClass \((?P<class_name>.*)\)$", scase_str) + if m: + class_name = "%s.%s" % (case.__class__.__module__, + case.__class__.__name__) + + if class_name == m.group('class_name'): + found = True + break + + if found: + return (found, msg) + + return (found, None) + + def logDetails(self): + self.logger.info("RESULTS:") + for case_name in self._registry['cases']: + case = self._registry['cases'][case_name] + + result_types = ['failures', 'errors', 'skipped', 'expectedFailures'] + result_desc = ['FAILED', 'ERROR', 'SKIPPED', 'EXPECTEDFAIL'] + + fail = False + desc = None + for idx, name in enumerate(result_types): + (fail, msg) = self._getDetailsNotPassed(case, result_types[idx], + result_desc[idx]) + if fail: + desc = result_desc[idx] + break + + oeid = -1 + for d in case.decorators: + if hasattr(d, 'oeid'): + oeid = d.oeid + + if fail: + self.logger.info("RESULTS - %s - Testcase %s: %s" % (case.id(), + oeid, desc)) + if msg: + self.logger.info(msg) + else: + self.logger.info("RESULTS - %s - Testcase %s: %s" % (case.id(), + oeid, 'PASSED'))
meta/lib/oeqa/core/decorator/__init__.py new file +71 -0
71 lines not on this page · raw message
meta/lib/oeqa/core/loader.py new file +235 -0
235 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH 4/55 oeqa/core/decorator: Add support for OETestDepends
In reply to Aníbal LimónThe OETestDepends decorator could be used over test cases to define some dependency between them.
At loading time sorting the tests to grauntee that a test case executes before also raise an exception if found a circular dependency between test cases.
At before test case run reviews if the dependency if meet, in the case of don't it skips the test case run.
--- meta/lib/oeqa/core/decorator/depends.py | 94 +++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 meta/lib/oeqa/core/decorator/depends.py
meta/lib/oeqa/core/decorator/depends.py new file +94 -0
@@ -0,0 +1,94 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +from unittest import SkipTest + +from oeqa.core.exception import OEQADependency + +from . import OETestDiscover, registerDecorator + +def _add_depends(registry, case, depends): + module_name = case.__module__ + class_name = case.__class__.__name__ + + case_id = case.id() + + for depend in depends: + dparts = depend.split('.') + + if len(dparts) == 1: + depend_id = ".".join((module_name, class_name, dparts[0])) + elif len(dparts) == 2: + depend_id = ".".join((module_name, dparts[0], dparts[1])) + else: + depend_id = depend + + if not case_id in registry: + registry[case_id] = [] + if not depend_id in registry[case_id]: + registry[case_id].append(depend_id) + +def _validate_test_case_depends(cases, depends): + for case in depends: + if not case in cases: + continue + for dep in depends[case]: + if not dep in cases: + raise OEQADependency("TestCase %s depends on %s and isn't available"\ + ", cases available %s." % (case, dep, str(cases.keys()))) + +def _order_test_case_by_depends(cases, depends): + def _dep_resolve(graph, node, resolved, seen): + seen.append(node) + for edge in graph[node]: + if edge not in resolved: + if edge in seen: + raise OEQADependency("Test cases %s and %s have a circular" \ + " dependency." % (node, edge)) + _dep_resolve(graph, edge, resolved, seen) + resolved.append(node) + + dep_graph = {} + dep_graph['__root__'] = cases.keys() + for case in cases: + if case in depends: + dep_graph[case] = depends[case] + else: + dep_graph[case] = [] + + cases_ordered = [] + _dep_resolve(dep_graph, '__root__', cases_ordered, []) + cases_ordered.remove('__root__') + + return [cases[case_id] for case_id in cases_ordered] + +def _skipTestDependency(case, depends): + results = case.tc._results + skipReasons = ['errors', 'failures', 'skipped'] + + for reason in skipReasons: + for test, _ in results[reason]: + if test.id() in depends: + raise SkipTest("Test case %s depends on %s and was in %s." \ + % (case.id(), test.id(), reason)) + +@registerDecorator +class OETestDepends(OETestDiscover): + attrs = ('depends',) + + def bind(self, registry, case): + super(OETestDepends, self).bind(registry, case) + if not registry.get('depends'): + registry['depends'] = {} + _add_depends(registry['depends'], case, self.depends) + + @staticmethod + def discover(registry): + if registry.get('depends'): + _validate_test_case_depends(registry['cases'], registry['depends']) + return _order_test_case_by_depends(registry['cases'], registry['depends']) + else: + return [registry['cases'][case_id] for case_id in registry['cases']] + + def setUpDecorator(self): + _skipTestDependency(self.case, self.depends)
Signature · 1 line
2.1.4
PATCH 5/55 oeqa/core/decorator: Add support for OETestID and OETestTag
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
These two decorators stores certain TAG or ID for the test case also provides support for filtering in loading step.
[YOCTO #10236]
--- meta/lib/oeqa/core/decorator/oeid.py | 23 +++++++++++++++++++++++ meta/lib/oeqa/core/decorator/oetag.py | 24 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 meta/lib/oeqa/core/decorator/oeid.py create mode 100644 meta/lib/oeqa/core/decorator/oetag.py
meta/lib/oeqa/core/decorator/oeid.py new file +23 -0
@@ -0,0 +1,23 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +from . import OETestFilter, registerDecorator +from oeqa.core.utils.misc import intToList + +def _idFilter(oeid, filters): + return False if oeid in filters else True + +@registerDecorator +class OETestID(OETestFilter): + attrs = ('oeid',) + + def bind(self, registry, case): + super(OETestID, self).bind(registry, case) + + def filtrate(self, filters): + if filters.get('oeid'): + filterx = intToList(filters['oeid'], 'oeid') + del filters['oeid'] + if _idFilter(self.oeid, filterx): + return True + return False
meta/lib/oeqa/core/decorator/oetag.py new file +24 -0
@@ -0,0 +1,24 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +from . import OETestFilter, registerDecorator +from oeqa.core.utils.misc import strToList + +def _tagFilter(tags, filters): + return False if set(tags) & set(filters) else True + +@registerDecorator +class OETestTag(OETestFilter): + attrs = ('oetag',) + + def bind(self, registry, case): + super(OETestTag, self).bind(registry, case) + self.oetag = strToList(self.oetag, 'oetag') + + def filtrate(self, filters): + if filters.get('oetag'): + filterx = strToList(filters['oetag'], 'oetag') + del filters['oetag'] + if _tagFilter(self.oetag, filterx): + return True + return False
Signature · 1 line
2.1.4
PATCH 6/55 oeqa/core/decorator: Add support for OETimeout decorator
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
The OETimeout provides support for specify certain timeout in seconds for a test case, if the timeout is reach the SIGALRM is sent and an exception is raised to notify the timeout.
[YOCTO #10235]
--- meta/lib/oeqa/core/decorator/oetimeout.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 meta/lib/oeqa/core/decorator/oetimeout.py
meta/lib/oeqa/core/decorator/oetimeout.py new file +25 -0
@@ -0,0 +1,25 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +import signal +from . import OETestDecorator, registerDecorator +from oeqa.core.exception import OEQATimeoutError + +@registerDecorator +class OETimeout(OETestDecorator): + attrs = ('oetimeout',) + + def setUpDecorator(self): + timeout = self.oetimeout + def _timeoutHandler(signum, frame): + raise OEQATimeoutError("Timed out after %s " + "seconds of execution" % timeout) + + self.logger.debug("Setting up a %d second(s) timeout" % self.oetimeout) + self.alarmSignal = signal.signal(signal.SIGALRM, _timeoutHandler) + signal.alarm(self.oetimeout) + + def tearDownDecorator(self): + signal.alarm(0) + signal.signal(signal.SIGALRM, self.alarmSignal) + self.logger.debug("Removed SIGALRM handler")
Signature · 1 line
2.1.4
PATCH 7/55 oeqa/core/decorator: Add support for OETestDataDepends and skipIfDataVar
In reply to Aníbal LimónThe OETestDataDepends decorator skips a test case if a variable isn't into test data (d).
The skipIfDataVar decorator skips a test case if a variable has certain value.
--- meta/lib/oeqa/core/decorator/data.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 meta/lib/oeqa/core/decorator/data.py
meta/lib/oeqa/core/decorator/data.py new file +36 -0
@@ -0,0 +1,36 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +from oeqa.core.exception import OEQAMissingVariable + +from . import OETestDecorator, registerDecorator + +@registerDecorator +class skipIfDataVar(OETestDecorator): + """ + Skip test based on value of a data store's variable. + + It will get the info of var from the data store and will + check it against value; if are equal it will skip the test + with msg as the reason. + """ + + attrs = ('var', 'value', 'msg') + + def setUpDecorator(self): + msg = 'Checking if %r value is %r to skip test' % (self.var, self.value) + self.logger.debug(msg) + if self.case.td.get(self.var) == self.value: + self.case.skipTest(self.msg) + +@registerDecorator +class OETestDataDepends(OETestDecorator): + attrs = ('td_depends',) + + def setUpDecorator(self): + for v in self.td_depends: + try: + value = self.case.td[v] + except KeyError: + raise OEQAMissingVariable("Test case need %s variable but"\ + " isn't into td" % v)
Signature · 1 line
2.1.4
PATCH 8/55 oeqa/core: Add tests for the OEQA framework
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
This test suite covers the current functionality for the OEQA framework.
For run certain test suite,
$ cd meta/lib/oeqa/core/tests $ ./test_data.py
--- meta/lib/oeqa/core/tests/__init__.py | 0 meta/lib/oeqa/core/tests/cases/data.py | 20 +++ meta/lib/oeqa/core/tests/cases/depends.py | 38 ++++++ .../oeqa/core/tests/cases/loader/invalid/oeid.py | 15 +++ .../oeqa/core/tests/cases/loader/valid/another.py | 9 ++ meta/lib/oeqa/core/tests/cases/oeid.py | 18 +++ meta/lib/oeqa/core/tests/cases/oetag.py | 18 +++ meta/lib/oeqa/core/tests/cases/timeout.py | 18 +++ meta/lib/oeqa/core/tests/common.py | 35 ++++++ meta/lib/oeqa/core/tests/test_data.py | 51 ++++++++ meta/lib/oeqa/core/tests/test_decorators.py | 135 +++++++++++++++++++++ meta/lib/oeqa/core/tests/test_loader.py | 86 +++++++++++++ meta/lib/oeqa/core/tests/test_runner.py | 38 ++++++ 13 files changed, 481 insertions(+) create mode 100644 meta/lib/oeqa/core/tests/__init__.py create mode 100644 meta/lib/oeqa/core/tests/cases/data.py create mode 100644 meta/lib/oeqa/core/tests/cases/depends.py create mode 100644 meta/lib/oeqa/core/tests/cases/loader/invalid/oeid.py create mode 100644 meta/lib/oeqa/core/tests/cases/loader/valid/another.py create mode 100644 meta/lib/oeqa/core/tests/cases/oeid.py create mode 100644 meta/lib/oeqa/core/tests/cases/oetag.py create mode 100644 meta/lib/oeqa/core/tests/cases/timeout.py create mode 100644 meta/lib/oeqa/core/tests/common.py create mode 100755 meta/lib/oeqa/core/tests/test_data.py create mode 100755 meta/lib/oeqa/core/tests/test_decorators.py create mode 100755 meta/lib/oeqa/core/tests/test_loader.py create mode 100755 meta/lib/oeqa/core/tests/test_runner.py
meta/lib/oeqa/core/tests/__init__.py new file +0 -0
meta/lib/oeqa/core/tests/cases/data.py new file +20 -0
@@ -0,0 +1,20 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +from oeqa.core.case import OETestCase +from oeqa.core.decorator.oetag import OETestTag +from oeqa.core.decorator.data import OETestDataDepends + +class DataTest(OETestCase): + data_vars = ['IMAGE', 'ARCH'] + + @OETestDataDepends(['MACHINE',]) + @OETestTag('dataTestOk') + def testDataOk(self): + self.assertEqual(self.td.get('IMAGE'), 'core-image-minimal') + self.assertEqual(self.td.get('ARCH'), 'x86') + self.assertEqual(self.td.get('MACHINE'), 'qemuarm') + + @OETestTag('dataTestFail') + def testDataFail(self): + pass
meta/lib/oeqa/core/tests/cases/depends.py new file +38 -0
@@ -0,0 +1,38 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +from oeqa.core.case import OETestCase +from oeqa.core.decorator.depends import OETestDepends + +class DependsTest(OETestCase): + + def testDependsFirst(self): + self.assertTrue(True, msg='How is this possible?') + + @OETestDepends(['testDependsFirst']) + def testDependsSecond(self): + self.assertTrue(True, msg='How is this possible?') + + @OETestDepends(['testDependsSecond']) + def testDependsThird(self): + self.assertTrue(True, msg='How is this possible?') + + @OETestDepends(['testDependsSecond']) + def testDependsFourth(self): + self.assertTrue(True, msg='How is this possible?') + + @OETestDepends(['testDependsThird', 'testDependsFourth']) + def testDependsFifth(self): + self.assertTrue(True, msg='How is this possible?') + + @OETestDepends(['testDependsCircular3']) + def testDependsCircular1(self): + self.assertTrue(True, msg='How is this possible?') + + @OETestDepends(['testDependsCircular1']) + def testDependsCircular2(self): + self.assertTrue(True, msg='How is this possible?') + + @OETestDepends(['testDependsCircular2']) + def testDependsCircular3(self): + self.assertTrue(True, msg='How is this possible?')
meta/lib/oeqa/core/tests/cases/loader/invalid/oeid.py new file +15 -0
@@ -0,0 +1,15 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +from oeqa.core.case import OETestCase + +class AnotherIDTest(OETestCase): + + def testAnotherIdGood(self): + self.assertTrue(True, msg='How is this possible?') + + def testAnotherIdOther(self): + self.assertTrue(True, msg='How is this possible?') + + def testAnotherIdNone(self): + self.assertTrue(True, msg='How is this possible?')
meta/lib/oeqa/core/tests/cases/loader/valid/another.py new file +9 -0
@@ -0,0 +1,9 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +from oeqa.core.case import OETestCase + +class AnotherTest(OETestCase): + + def testAnother(self): + self.assertTrue(True, msg='How is this possible?')
meta/lib/oeqa/core/tests/cases/oeid.py new file +18 -0
@@ -0,0 +1,18 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +from oeqa.core.case import OETestCase +from oeqa.core.decorator.oeid import OETestID + +class IDTest(OETestCase): + + @OETestID(101) + def testIdGood(self): + self.assertTrue(True, msg='How is this possible?') + + @OETestID(102) + def testIdOther(self): + self.assertTrue(True, msg='How is this possible?') + + def testIdNone(self): + self.assertTrue(True, msg='How is this possible?')
meta/lib/oeqa/core/tests/cases/oetag.py new file +18 -0
@@ -0,0 +1,18 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +from oeqa.core.case import OETestCase +from oeqa.core.decorator.oetag import OETestTag + +class TagTest(OETestCase): + + @OETestTag('goodTag') + def testTagGood(self): + self.assertTrue(True, msg='How is this possible?') + + @OETestTag('otherTag') + def testTagOther(self): + self.assertTrue(True, msg='How is this possible?') + + def testTagNone(self): + self.assertTrue(True, msg='How is this possible?')
meta/lib/oeqa/core/tests/cases/timeout.py new file +18 -0
@@ -0,0 +1,18 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +from time import sleep + +from oeqa.core.case import OETestCase +from oeqa.core.decorator.oetimeout import OETimeout + +class TimeoutTest(OETestCase): + + @OETimeout(1) + def testTimeoutPass(self): + self.assertTrue(True, msg='How is this possible?') + + @OETimeout(1) + def testTimeoutFail(self): + sleep(2) + self.assertTrue(True, msg='How is this possible?')
meta/lib/oeqa/core/tests/common.py new file +35 -0
@@ -0,0 +1,35 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +import sys +import os + +import unittest +import logging +import os + +logger = logging.getLogger("oeqa") +logger.setLevel(logging.INFO) +consoleHandler = logging.StreamHandler() +formatter = logging.Formatter('OEQATest: %(message)s') +consoleHandler.setFormatter(formatter) +logger.addHandler(consoleHandler) + +def setup_sys_path(): + directory = os.path.dirname(os.path.abspath(__file__)) + oeqa_lib = os.path.realpath(os.path.join(directory, '../../../')) + if not oeqa_lib in sys.path: + sys.path.insert(0, oeqa_lib) + +class TestBase(unittest.TestCase): + def setUp(self): + self.logger = logger + directory = os.path.dirname(os.path.abspath(__file__)) + self.cases_path = os.path.join(directory, 'cases') + + def _testLoader(self, d={}, modules=[], tests=[], filters={}): + from oeqa.core.context import OETestContext + tc = OETestContext(d, self.logger) + tc.loadTests(self.cases_path, modules=modules, tests=tests, + filters=filters) + return tc
meta/lib/oeqa/core/tests/test_data.py new file +51 -0
51 lines not on this page · raw message
meta/lib/oeqa/core/tests/test_decorators.py new file +135 -0
135 lines not on this page · raw message
meta/lib/oeqa/core/tests/test_loader.py new file +86 -0
86 lines not on this page · raw message
meta/lib/oeqa/core/tests/test_runner.py new file +38 -0
@@ -0,0 +1,38 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +import unittest +import logging +import tempfile + +from common import setup_sys_path, TestBase +setup_sys_path() + +from oeqa.core.runner import OEStreamLogger + +class TestRunner(TestBase): + def test_stream_logger(self): + fp = tempfile.TemporaryFile(mode='w+') + + logging.basicConfig(format='%(message)s', stream=fp) + logger = logging.getLogger() + logger.setLevel(logging.INFO) + + oeSL = OEStreamLogger(logger) + + lines = ['init', 'bigline_' * 65535, 'morebigline_' * 65535 * 4, 'end'] + for line in lines: + oeSL.write(line) + + fp.seek(0) + fp_lines = fp.readlines() + for i, fp_line in enumerate(fp_lines): + fp_line = fp_line.strip() + self.assertEqual(lines[i], fp_line) + + fp.close() + +if __name__ == '__main__': + unittest.main()
Signature · 1 line
2.1.4
PATCH 9/55 scripts/oe-test: Add new oe-test script
In reply to Aníbal LimónThe new oe-test script will be use to run test components with one single script.
The oe-test script search for test components inside meta/lib/oeqa, the test components needs to implement OETestContextExecutor inside context module in order to be supported by oe-test.
[YOCTO #10230]
--- scripts/oe-test | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100755 scripts/oe-test
scripts/oe-test new file +99 -0
@@ -0,0 +1,99 @@ +#!/usr/bin/env python3 + +# OpenEmbedded test tool +# +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +import os +import sys +import argparse +import importlib +import logging + +scripts_path = os.path.dirname(os.path.realpath(__file__)) +lib_path = scripts_path + '/lib' +sys.path = sys.path + [lib_path] +import argparse_oe +import scriptutils +import scriptpath +scriptpath.add_oe_lib_path() + +from oeqa.core.context import OETestContextExecutor + +logger = scriptutils.logger_create('oe-test') + +def _load_test_components(logger): + components = {} + + for path in sys.path: + base_dir = os.path.join(path, 'oeqa') + if os.path.exists(base_dir) and os.path.isdir(base_dir): + for file in os.listdir(base_dir): + comp_name = file + comp_context = os.path.join(base_dir, file, 'context.py') + if os.path.exists(comp_context): + comp_plugin = importlib.import_module('oeqa.%s.%s' % \ + (comp_name, 'context')) + try: + if not issubclass(comp_plugin._executor_class, + OETestContextExecutor): + raise TypeError("Component %s in %s, _executor_class "\ + "isn't derived from OETestContextExecutor."\ + % (comp_name, comp_context)) + + components[comp_name] = comp_plugin._executor_class() + except AttributeError: + raise AttributeError("Component %s in %s don't have "\ + "_executor_class defined." % (comp_name, comp_context)) + + return components + +def main(): + parser = argparse_oe.ArgumentParser(description="OpenEmbedded test tool", + add_help=False, + epilog="Use %(prog)s <subcommand> --help to get help on a specific command") + parser.add_argument('-d', '--debug', help='Enable debug output', action='store_true') + parser.add_argument('-q', '--quiet', help='Print only errors', action='store_true') + global_args, unparsed_args = parser.parse_known_args() + + # Help is added here rather than via add_help=True, as we don't want it to + # be handled by parse_known_args() + parser.add_argument('-h', '--help', action='help', default=argparse.SUPPRESS, + help='show this help message and exit') + + if global_args.debug: + logger.setLevel(logging.DEBUG) + elif global_args.quiet: + logger.setLevel(logging.ERROR) + + components = _load_test_components(logger) + + subparsers = parser.add_subparsers(dest="subparser_name", title='subcommands', metavar='<subcommand>') + subparsers.add_subparser_group('components', 'Test components') + subparsers.required = True + for comp_name in sorted(components.keys()): + comp = components[comp_name] + comp.register_commands(logger, subparsers) + + try: + args = parser.parse_args(unparsed_args, namespace=global_args) + results = args.func(logger, args) + ret = 0 if results.wasSuccessful() else 1 + except SystemExit as err: + if err.code != 0: + raise err + ret = err.code + except argparse_oe.ArgumentUsageError as ae: + parser.error_subcommand(ae.message, ae.subcommand) + + return ret + +if __name__ == '__main__': + try: + ret = main() + except Exception: + ret = 1 + import traceback + traceback.print_exc() + sys.exit(ret)
Signature · 1 line
2.1.4
PATCH 10/55 oeqa/core/context: Add support of OETestContextExecutor
In reply to Aníbal LimónThe OETestContextExecutor class supports to use oe-test for run core test component also is a base class for the other test components (runtime, sdk, selftest).
Te principal functionality is to support cmdline parsing and execution of OETestContext, the test components could extend the common options to provide specific ones. The common options between test components are test data file, output log and test cases path's to scan.
Also it initializes the logger to be passed to the whole OEQA framework.
[YOCTO #10230]
--- meta/lib/oeqa/core/context.py | 85 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+)
meta/lib/oeqa/core/context.py +85 -0
@@ -146,3 +146,88 @@ class OETestContext(object): else: self.logger.info("RESULTS - %s - Testcase %s: %s" % (case.id(), oeid, 'PASSED')) + +class OETestContextExecutor(object): + _context_class = OETestContext + + name = 'core' + help = 'core test component example' + description = 'executes core test suite example' + + default_cases = [os.path.join(os.path.abspath(os.path.dirname(__file__)), + 'cases/example')] + default_test_data = os.path.join(default_cases[0], 'data.json') + + def register_commands(self, logger, subparsers): + self.parser = subparsers.add_parser(self.name, help=self.help, + description=self.description, group='components') + + self.default_output_log = '%s-results-%s.log' % (self.name, + time.strftime("%Y%m%d%H%M%S")) + self.parser.add_argument('--output-log', action='store', + default=self.default_output_log, + help="results output log, default: %s" % self.default_output_log) + + if self.default_test_data: + self.parser.add_argument('--test-data-file', action='store', + default=self.default_test_data, + help="data file to load, default: %s" % self.default_test_data) + else: + self.parser.add_argument('--test-data-file', action='store', + help="data file to load") + + if self.default_cases: + self.parser.add_argument('CASES_PATHS', action='store', + default=self.default_cases, nargs='*', + help="paths to directories with test cases, default: %s"\ + % self.default_cases) + else: + self.parser.add_argument('CASES_PATHS', action='store', + nargs='+', help="paths to directories with test cases") + + self.parser.set_defaults(func=self.run) + + def _setup_logger(self, logger, args): + formatter = logging.Formatter('%(asctime)s - ' + self.name + \ + ' - %(levelname)s - %(message)s') + sh = logger.handlers[0] + sh.setFormatter(formatter) + fh = logging.FileHandler(args.output_log) + fh.setFormatter(formatter) + logger.addHandler(fh) + + return logger + + def _process_args(self, logger, args): + self.tc_kwargs = {} + self.tc_kwargs['init'] = {} + self.tc_kwargs['load'] = {} + self.tc_kwargs['run'] = {} + + self.tc_kwargs['init']['logger'] = self._setup_logger(logger, args) + if args.test_data_file: + self.tc_kwargs['init']['td'] = json.load( + open(args.test_data_file, "r")) + else: + self.tc_kwargs['init']['td'] = {} + + self.module_paths = args.CASES_PATHS + + def run(self, logger, args): + self._process_args(logger, args) + + self.tc = self._context_class(**self.tc_kwargs['init']) + self.tc.loadTests(self.module_paths, **self.tc_kwargs['load']) + rc = self.tc.runTests(**self.tc_kwargs['run']) + self.tc.logSummary(rc, self.name) + self.tc.logDetails() + + output_link = os.path.join(os.path.dirname(args.output_log), + "%s-results.log" % self.name) + if os.path.exists(output_link): + os.remove(output_link) + os.symlink(args.output_log, output_link) + + return rc + +_executor_class = OETestContextExecutor
Signature · 1 line
2.1.4
PATCH 11/55 oeqa/core/cases: Add example test cases
In reply to Aníbal LimónServes as an first input of how to the OEQA framework works.
--- meta/lib/oeqa/core/cases/__init__.py | 0 meta/lib/oeqa/core/cases/example/data.json | 1 + meta/lib/oeqa/core/cases/example/test_basic.py | 20 ++++++++++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 meta/lib/oeqa/core/cases/__init__.py create mode 100644 meta/lib/oeqa/core/cases/example/data.json create mode 100644 meta/lib/oeqa/core/cases/example/test_basic.py
meta/lib/oeqa/core/cases/__init__.py new file +0 -0
meta/lib/oeqa/core/cases/example/data.json new file +1 -0
@@ -0,0 +1 @@ +{"ARCH": "x86", "IMAGE": "core-image-minimal"}
meta/lib/oeqa/core/cases/example/test_basic.py new file +20 -0
@@ -0,0 +1,20 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +from oeqa.core.case import OETestCase +from oeqa.core.decorator.depends import OETestDepends + +class OETestExample(OETestCase): + def test_example(self): + self.logger.info('IMAGE: %s' % self.td.get('IMAGE')) + self.assertEqual('core-image-minimal', self.td.get('IMAGE')) + self.logger.info('ARCH: %s' % self.td.get('ARCH')) + self.assertEqual('x86', self.td.get('ARCH')) + +class OETestExampleDepend(OETestCase): + @OETestDepends(['OETestExample.test_example']) + def test_example_depends(self): + pass + + def test_example_no_depends(self): + pass
Signature · 1 line
2.1.4
PATCH 12/55 oeqa/core: Add README
In reply to Aníbal LimónThe README has an introduction and explains how to run the test suite and creates a new Test component.
--- meta/lib/oeqa/core/README | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 meta/lib/oeqa/core/README
meta/lib/oeqa/core/README new file +38 -0
@@ -0,0 +1,38 @@ += OEQA Framework = + +== Introduction == + +This is the new OEQA framework the base clases of the framework +are in this module oeqa/core the subsequent components needs to +extend this classes. + +A new/unique runner was created called oe-test and is under scripts/ +oe-test, this new runner scans over oeqa module searching for test +components that supports OETestContextExecutor implemented in context +module (i.e. oeqa/core/context.py). + +For execute an example: + +$ source oe-init-build-env +$ oe-test core + +For list supported components: + +$ oe-test -h + +== Create new Test component == + +Usally for add a new Test component the developer needs to extend +OETestContext/OETestContextExecutor in context.py and OETestCase in +case.py. + +== How to run the testing of the OEQA framework == + +Run all tests: + +$ PATH=$PATH:../../ python3 -m unittest discover -s tests + +Run some test: + +$ cd tests/ +$ ./test_data.py
Signature · 1 line
2.1.4
PATCH 13/55 oe/data: Add export2json function
In reply to Aníbal LimónThe export2json function export the variables contained in the data store to JSON format, the main usage for now will be to provide test data to QA framework.
--- meta/lib/oe/data.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
meta/lib/oe/data.py +28 -0
@@ -1,3 +1,4 @@ +import json import oe.maketype def typed_value(key, d):
@@ -15,3 +16,30 @@ def typed_value(key, d): return oe.maketype.create(d.getVar(key) or '', var_type, **flags) except (TypeError, ValueError) as exc: bb.msg.fatal("Data", "%s: %s" % (key, str(exc))) + +def export2json(d, json_file, expand=True): + data2export = {} + keys2export = [] + + for key in d.keys(): + if key.startswith("_"): + continue + elif key.startswith("BB"): + continue + elif key.startswith("B_pn"): + continue + elif key.startswith("do_"): + continue + elif d.getVarFlag(key, "func", True): + continue + + keys2export.append(key) + + for key in keys2export: + try: + data2export[key] = d.getVar(key, expand) + except bb.data_smart.ExpansionError: + data2export[key] = '' + + with open(json_file, "w") as f: + json.dump(data2export, f, skipkeys=True, indent=4, sort_keys=True)
Signature · 1 line
2.1.4
PATCH 14/55 classes/rootfs-postcommands: Add write_image_test_data
In reply to Aníbal LimónThis function will generates testdata.json by image type.
[YOCTO #10231]
--- meta/classes/rootfs-postcommands.bbclass | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
meta/classes/rootfs-postcommands.bbclass +18 -0
@@ -14,6 +14,9 @@ ROOTFS_POSTPROCESS_COMMAND += "rootfs_update_timestamp ; " # Tweak the mount options for rootfs in /etc/fstab if read-only-rootfs is enabled ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs", "read_only_rootfs_hook; ", "",d)}' +# Generates test data file with data store variables expanded in json format +ROOTFS_POSTPROCESS_COMMAND += "write_image_test_data ; " + # Write manifest IMAGE_MANIFEST = "${IMGDEPLOYDIR}/${IMAGE_NAME}.rootfs.manifest" ROOTFS_POSTUNINSTALL_COMMAND =+ "write_image_manifest ; "
@@ -300,3 +303,18 @@ rootfs_check_host_user_contaminated () { rootfs_sysroot_relativelinks () { sysroot-relativelinks.py ${SDK_OUTPUT}/${SDKTARGETSYSROOT} } + +# Generated test data json file +python write_image_test_data() { + from oe.data import export2json + + testdata = "%s/%s.testdata.json" % (d.getVar('DEPLOY_DIR_IMAGE', True), d.getVar('IMAGE_NAME', True)) + testdata_link = "%s/%s.testdata.json" % (d.getVar('DEPLOY_DIR_IMAGE', True), d.getVar('IMAGE_LINK_NAME', True)) + + bb.utils.mkdirhier(os.path.dirname(testdata)) + export2json(d, testdata) + + if os.path.lexists(testdata_link): + os.remove(testdata_link) + os.symlink(os.path.basename(testdata), testdata_link) +}
Signature · 1 line
2.1.4
PATCH 15/55 classes/populate_sdk_base: Add write_sdk_test_data to postprocess
In reply to Aníbal LimónThis function will generates testdata.json per SDK type.
[YOCTO #10231]
--- meta/classes/populate_sdk_base.bbclass | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
meta/classes/populate_sdk_base.bbclass +8 -1
@@ -70,6 +70,13 @@ python write_target_sdk_manifest () { output.write(format_pkg_list(pkgs, 'ver')) } +python write_sdk_test_data() { + from oe.data import export2json + testdata = "%s/%s.testdata.json" % (d.getVar('SDKDEPLOYDIR', True), d.getVar('TOOLCHAIN_OUTPUTNAME', True)) + bb.utils.mkdirhier(os.path.dirname(testdata)) + export2json(d, testdata) +} + python write_host_sdk_manifest () { from oe.sdk import sdk_list_installed_packages from oe.utils import format_pkg_list
@@ -81,7 +88,7 @@ python write_host_sdk_manifest () { output.write(format_pkg_list(pkgs, 'ver')) } -POPULATE_SDK_POST_TARGET_COMMAND_append = " write_target_sdk_manifest ; " +POPULATE_SDK_POST_TARGET_COMMAND_append = " write_target_sdk_manifest ; write_sdk_test_data ; " POPULATE_SDK_POST_HOST_COMMAND_append = " write_host_sdk_manifest; " SDK_PACKAGING_COMMAND = "${@'${SDK_PACKAGING_FUNC};' if '${SDK_PACKAGING_FUNC}' else ''}" SDK_POSTPROCESS_COMMAND = " create_sdk_files; check_sdk_sysroots; tar_sdk; ${SDK_PACKAGING_COMMAND} "
Signature · 1 line
2.1.4
PATCH 16/55 oeqa/utils/__init__.py: Adds compatibility with bitbake logger
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
The bitbake logger changes the way debug is logged and adds different levels within debug, this is passed as argument to the function and breaks compatibility with vanilla loggers.
This implements a way to handle this adding a new function for debug, that will dispatch the correct logging method signature.
Also overrides info method to use logging.INFO + 1 in order to see plain data.
Also this commit fix the issue of not showing the test summary and results when running from bitbake.
[YOCTO #10686]
--- meta/lib/oeqa/utils/__init__.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
meta/lib/oeqa/utils/__init__.py +30 -0
@@ -36,3 +36,33 @@ def avoid_paths_in_environ(paths): new_path = new_path[:-1] return new_path + +def make_logger_bitbake_compatible(logger): + import logging + + """ + Bitbake logger redifines debug() in order to + set a level within debug, this breaks compatibility + with vainilla logging, so we neeed to redifine debug() + method again also add info() method with INFO + 1 level. + """ + def _bitbake_log_debug(*args, **kwargs): + lvl = logging.DEBUG + + if isinstance(args[0], int): + lvl = args[0] + msg = args[1] + args = args[2:] + else: + msg = args[0] + args = args[1:] + + logger.log(lvl, msg, *args, **kwargs) + + def _bitbake_log_info(msg, *args, **kwargs): + logger.log(logging.INFO + 1, msg, *args, **kwargs) + + logger.debug = _bitbake_log_debug + logger.info = _bitbake_log_info + + return logger
Signature · 1 line
2.1.4
PATCH 17/55 oeqa: Move common files to oeqa/files instead of runtime only
In reply to Aníbal LimónThose files are used by runtime and sdk test cases, so move to base directory of oeqa module.
[YOCTO #10599]
---
meta/lib/oeqa/{runtime => }/files/test.c | 0
meta/lib/oeqa/{runtime => }/files/test.cpp | 0
meta/lib/oeqa/{runtime => }/files/test.pl | 0
meta/lib/oeqa/{runtime => }/files/test.py | 0
4 files changed, 0 insertions(+), 0 deletions(-)
rename meta/lib/oeqa/{runtime => }/files/test.c (100%)
rename meta/lib/oeqa/{runtime => }/files/test.cpp (100%)
rename meta/lib/oeqa/{runtime => }/files/test.pl (100%)
rename meta/lib/oeqa/{runtime => }/files/test.py (100%)meta/lib/oeqa/files/test.c renamed from meta/lib/oeqa/runtime/files/test.c +0 -0
meta/lib/oeqa/files/test.cpp renamed from meta/lib/oeqa/runtime/files/test.cpp +0 -0
meta/lib/oeqa/files/test.pl renamed from meta/lib/oeqa/runtime/files/test.pl +0 -0
meta/lib/oeqa/files/test.py renamed from meta/lib/oeqa/runtime/files/test.py +0 -0
Signature · 1 line
2.1.4
PATCH 18/55 oeqa/sdk: Move test cases inside cases directory
In reply to Aníbal LimónFor match with the new structure of the OEQA framework.
In the new framework Test component base directory in this case sdk module will contain case and context implementations.
[YOCTO #10599]
---
meta/lib/oeqa/sdk/{ => cases}/__init__.py | 0
meta/lib/oeqa/sdk/{ => cases}/buildcvs.py | 0
meta/lib/oeqa/sdk/{ => cases}/buildgalculator.py | 0
meta/lib/oeqa/sdk/{ => cases}/buildiptables.py | 0
meta/lib/oeqa/sdk/{ => cases}/gcc.py | 0
meta/lib/oeqa/sdk/{ => cases}/perl.py | 0
meta/lib/oeqa/sdk/{ => cases}/python.py | 0
7 files changed, 0 insertions(+), 0 deletions(-)
rename meta/lib/oeqa/sdk/{ => cases}/__init__.py (100%)
rename meta/lib/oeqa/sdk/{ => cases}/buildcvs.py (100%)
rename meta/lib/oeqa/sdk/{ => cases}/buildgalculator.py (100%)
rename meta/lib/oeqa/sdk/{ => cases}/buildiptables.py (100%)
rename meta/lib/oeqa/sdk/{ => cases}/gcc.py (100%)
rename meta/lib/oeqa/sdk/{ => cases}/perl.py (100%)
rename meta/lib/oeqa/sdk/{ => cases}/python.py (100%)meta/lib/oeqa/sdk/cases/__init__.py renamed from meta/lib/oeqa/sdk/__init__.py +0 -0
meta/lib/oeqa/sdk/cases/buildcvs.py renamed from meta/lib/oeqa/sdk/buildcvs.py +0 -0
meta/lib/oeqa/sdk/cases/buildgalculator.py renamed from meta/lib/oeqa/sdk/buildgalculator.py +0 -0
meta/lib/oeqa/sdk/cases/buildiptables.py renamed from meta/lib/oeqa/sdk/buildiptables.py +0 -0
meta/lib/oeqa/sdk/cases/gcc.py renamed from meta/lib/oeqa/sdk/gcc.py +0 -0
meta/lib/oeqa/sdk/cases/perl.py renamed from meta/lib/oeqa/sdk/perl.py +0 -0
meta/lib/oeqa/sdk/cases/python.py renamed from meta/lib/oeqa/sdk/python.py +0 -0
Signature · 1 line
2.1.4
PATCH 19/55 oeqa/{runtime, sdk}/files: Move testsdkmakefile from runtime to sdk module
In reply to Aníbal LimónIt doesn't make sense to have files related to sdk module into runtime module.
[YOCTO #10599]
---
meta/lib/oeqa/{runtime => sdk}/files/testsdkmakefile | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename meta/lib/oeqa/{runtime => sdk}/files/testsdkmakefile (100%)meta/lib/oeqa/sdk/files/testsdkmakefile renamed from meta/lib/oeqa/runtime/files/testsdkmakefile +0 -0
Signature · 1 line
2.1.4
PATCH 20/55 oeqa/sdk: Add case and context modules for the SDK component
In reply to Aníbal LimónAdds case and context modules for SDK based on oetest.py old code.
Enables SDK Test component usage with oe-test, the SDK Test component adds command line options for specify sdk installed dir, sdk environment and target/hosts maniftest.
[YOCTO #10599]
--- meta/lib/oeqa/oetest.py | 51 ---------------- meta/lib/oeqa/sdk/__init__.py | 0 meta/lib/oeqa/sdk/case.py | 12 ++++ meta/lib/oeqa/sdk/context.py | 133 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 145 insertions(+), 51 deletions(-) create mode 100644 meta/lib/oeqa/sdk/__init__.py create mode 100644 meta/lib/oeqa/sdk/case.py create mode 100644 meta/lib/oeqa/sdk/context.py
meta/lib/oeqa/oetest.py +0 -51
@@ -145,20 +145,6 @@ class OETestCalledProcessError(subprocess.CalledProcessError): subprocess.CalledProcessError = OETestCalledProcessError -class oeSDKTest(oeTest): - def __init__(self, methodName='runTest'): - self.sdktestdir = oeSDKTest.tc.sdktestdir - super(oeSDKTest, self).__init__(methodName) - - @classmethod - def hasHostPackage(self, pkg): - if re.search(pkg, oeTest.tc.hostpkgmanifest): - return True - return False - - def _run(self, cmd): - return subprocess.check_output(". %s > /dev/null; %s;" % (self.tc.sdkenv, cmd), shell=True, stderr=subprocess.STDOUT).decode("utf-8") - class oeSDKExtTest(oeSDKTest): def _run(self, cmd): # extensible sdk shows a warning if found bitbake in the path
@@ -657,43 +643,6 @@ class ExportTestContext(RuntimeTestContext): pkg_dir = os.path.join(export_dir, extracted_dir) super(ExportTestContext, self).install_uninstall_packages(test_id, pkg_dir, install) -class SDKTestContext(TestContext): - def __init__(self, d, sdktestdir, sdkenv, tcname, *args): - super(SDKTestContext, self).__init__(d) - - self.sdktestdir = sdktestdir - self.sdkenv = sdkenv - self.tcname = tcname - - if not hasattr(self, 'target_manifest'): - self.target_manifest = d.getVar("SDK_TARGET_MANIFEST") - try: - self.pkgmanifest = {} - with open(self.target_manifest) as f: - for line in f: - (pkg, arch, version) = line.strip().split() - self.pkgmanifest[pkg] = (version, arch) - except IOError as e: - bb.fatal("No package manifest file found. Did you build the sdk image?\n%s" % e) - - if not hasattr(self, 'host_manifest'): - self.host_manifest = d.getVar("SDK_HOST_MANIFEST") - try: - with open(self.host_manifest) as f: - self.hostpkgmanifest = f.read() - except IOError as e: - bb.fatal("No host package manifest file found. Did you build the sdk image?\n%s" % e) - - def _get_test_namespace(self): - return "sdk" - - def _get_test_suites(self): - return (self.d.getVar("TEST_SUITES_SDK") or "auto").split() - - def _get_test_suites_required(self): - return [t for t in (self.d.getVar("TEST_SUITES_SDK") or \ - "auto").split() if t != "auto"] - class SDKExtTestContext(SDKTestContext): def __init__(self, d, sdktestdir, sdkenv, tcname, *args): self.target_manifest = d.getVar("SDK_EXT_TARGET_MANIFEST")
meta/lib/oeqa/sdk/__init__.py new file +0 -0
meta/lib/oeqa/sdk/case.py new file +12 -0
@@ -0,0 +1,12 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +import subprocess + +from oeqa.core.case import OETestCase + +class OESDKTestCase(OETestCase): + def _run(self, cmd): + return subprocess.check_output(". %s > /dev/null; %s;" % \ + (self.tc.sdk_env, cmd), shell=True, + stderr=subprocess.STDOUT).decode("utf-8")
meta/lib/oeqa/sdk/context.py new file +133 -0
133 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH 21/55 classes/testsdk: Migrates testsdk.bbclass to use new OESDKTestContext
In reply to Aníbal LimónThe functionality provided is the same with imporvements on code reuse and better interfaces.
--- meta/classes/testsdk.bbclass | 75 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 15 deletions(-)
meta/classes/testsdk.bbclass +60 -15
@@ -50,30 +50,75 @@ def run_test_context(CTestContext, d, testdir, tcname, pn, *args): def testsdk_main(d): import os - import oeqa.sdk import subprocess - from oeqa.oetest import SDKTestContext + import json + import logging - pn = d.getVar("PN") - bb.utils.mkdirhier(d.getVar("TEST_LOG_DIR")) + from bb.utils import export_proxies + from oeqa.core.runner import OEStreamLogger + from oeqa.sdk.context import OESDKTestContext, OESDKTestContextExecutor + from oeqa.utils import make_logger_bitbake_compatible + + pn = d.getVar("PN", True) + logger = make_logger_bitbake_compatible(logging.getLogger("BitBake")) + + # sdk use network for download projects for build + export_proxies(d) + + test_log_dir = d.getVar("TEST_LOG_DIR", True) + + bb.utils.mkdirhier(test_log_dir) tcname = d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.sh") if not os.path.exists(tcname): bb.fatal("The toolchain %s is not built. Build it before running the tests: 'bitbake <image> -c populate_sdk' ." % tcname) - sdktestdir = d.expand("${WORKDIR}/testimage-sdk/") - bb.utils.remove(sdktestdir, True) - bb.utils.mkdirhier(sdktestdir) + tdname = d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.testdata.json") + test_data = json.load(open(tdname, "r")) + test_data['TEST_LOG_DIR'] = test_log_dir + + target_pkg_manifest = OESDKTestContextExecutor._load_manifest( + d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.target.manifest")) + host_pkg_manifest = OESDKTestContextExecutor._load_manifest( + d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.host.manifest")) + + sdk_dir = d.expand("${WORKDIR}/testimage-sdk/") + bb.utils.remove(sdk_dir, True) + bb.utils.mkdirhier(sdk_dir) try: - subprocess.check_output("cd %s; %s <<EOF\n./tc\nY\nEOF" % (sdktestdir, tcname), shell=True) + subprocess.check_output("cd %s; %s <<EOF\n./\nY\nEOF" % (sdk_dir, tcname), shell=True) except subprocess.CalledProcessError as e: bb.fatal("Couldn't install the SDK:\n%s" % e.output.decode("utf-8")) - try: - run_test_context(SDKTestContext, d, sdktestdir, tcname, pn) - finally: - bb.utils.remove(sdktestdir, True) + fail = False + sdk_envs = OESDKTestContextExecutor._get_sdk_environs(sdk_dir) + for s in sdk_envs: + sdk_env = sdk_envs[s] + bb.plain("SDK testing environment: %s" % s) + tc = OESDKTestContext(td=test_data, logger=logger, sdk_dir=sdk_dir, + sdk_env=sdk_env, target_pkg_manifest=target_pkg_manifest, + host_pkg_manifest=host_pkg_manifest) + try: + tc.loadTests(OESDKTestContextExecutor.default_cases) + except Exception as e: + import traceback + bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) + + result = tc.runTests() + + component = "%s %s" % (pn, OESDKTestContextExecutor.name) + context_msg = "%s:%s" % (os.path.basename(tcname), os.path.basename(sdk_env)) + + tc.logSummary(result, component, context_msg) + tc.logDetails() + + if not result.wasSuccessful(): + fail = True + + if fail: + bb.fatal("%s - FAILED - check the task log and the commands log" % pn) + testsdk_main[vardepsexclude] =+ "BB_ORIGENV" python do_testsdk() {
@@ -88,13 +133,13 @@ TESTSDKEXTLOCK = "${TMPDIR}/testsdkext.lock" def testsdkext_main(d): import os - import oeqa.sdkext + import json import subprocess + import logging + from bb.utils import export_proxies - from oeqa.oetest import SDKTestContext, SDKExtTestContext from oeqa.utils import avoid_paths_in_environ - # extensible sdk use network export_proxies(d)
Signature · 1 line
2.1.4
PATCH 22/55 oeqa/utils: Move targetbuild to buildproject module
In reply to Aníbal LimónThe new buildproject module will contain only BuildProject class a helper class for build source code.
The remaining classes TargetBuildProject and SDKBuildProject was move to runtime and sdk respectively.
[YOCTO #10599]
--- meta/lib/oeqa/runtime/utils/__init__.py | 0 meta/lib/oeqa/runtime/utils/targetbuildproject.py | 33 +++++++++++ meta/lib/oeqa/sdk/utils/__init__.py | 0 meta/lib/oeqa/sdk/utils/sdkbuildproject.py | 45 +++++++++++++++ meta/lib/oeqa/utils/buildproject.py | 69 +++++++++++++++++++++++ 5 files changed, 147 insertions(+) create mode 100644 meta/lib/oeqa/runtime/utils/__init__.py create mode 100644 meta/lib/oeqa/runtime/utils/targetbuildproject.py create mode 100644 meta/lib/oeqa/sdk/utils/__init__.py create mode 100644 meta/lib/oeqa/sdk/utils/sdkbuildproject.py create mode 100644 meta/lib/oeqa/utils/buildproject.py
meta/lib/oeqa/runtime/utils/__init__.py new file +0 -0
meta/lib/oeqa/runtime/utils/targetbuildproject.py new file +33 -0
@@ -0,0 +1,33 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +from oeqa.utils.buildproject import BuildProject + +class TargetBuildProject(BuildProject): + + def __init__(self, target, d, uri, foldername=None): + self.target = target + self.targetdir = "~/" + BuildProject.__init__(self, d, uri, foldername, tmpdir="/tmp") + + def download_archive(self): + + self._download_archive() + + (status, output) = self.target.copy_to(self.localarchive, self.targetdir) + if status != 0: + raise Exception("Failed to copy archive to target, output: %s" % output) + + (status, output) = self.target.run('tar xf %s%s -C %s' % (self.targetdir, self.archive, self.targetdir)) + if status != 0: + raise Exception("Failed to extract archive, output: %s" % output) + + #Change targetdir to project folder + self.targetdir = self.targetdir + self.fname + + # The timeout parameter of target.run is set to 0 to make the ssh command + # run with no timeout. + def _run(self, cmd): + return self.target.run(cmd, 0)[0] + +
meta/lib/oeqa/sdk/utils/__init__.py new file +0 -0
meta/lib/oeqa/sdk/utils/sdkbuildproject.py new file +45 -0
45 lines not on this page · raw message
meta/lib/oeqa/utils/buildproject.py new file +69 -0
69 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH 23/55 oeqa/utils: {Target, SDK, }BuildProject remove dependency of bb
In reply to Aníbal LimónDon't use bitbake references inside utils modules, in order todo that changes getVar calls for arguments in the __init__ method like dl_dir for all the classes and testlogdir, builddatetime in SDKBUildProject.
Also don't export proxies inside _download_archive method, a good practice is to setup the proxies at init of the process instead of do it in this helper module.
[YOCTO #10231]
[YOCTO #10599]
--- meta/lib/oeqa/runtime/utils/targetbuildproject.py | 6 ++--- meta/lib/oeqa/sdk/utils/sdkbuildproject.py | 14 +++++----- meta/lib/oeqa/utils/buildproject.py | 31 +++++------------------ 3 files changed, 17 insertions(+), 34 deletions(-)
meta/lib/oeqa/runtime/utils/targetbuildproject.py +3 -3
@@ -5,13 +5,13 @@ from oeqa.utils.buildproject import BuildProject class TargetBuildProject(BuildProject): - def __init__(self, target, d, uri, foldername=None): + def __init__(self, target, uri, foldername=None, dl_dir=None): self.target = target self.targetdir = "~/" - BuildProject.__init__(self, d, uri, foldername, tmpdir="/tmp") + BuildProject.__init__(self, uri, foldername, tmpdir="/tmp", + dl_dir=dl_dir) def download_archive(self): - self._download_archive() (status, output) = self.target.copy_to(self.localarchive, self.targetdir)
meta/lib/oeqa/sdk/utils/sdkbuildproject.py +7 -7
@@ -7,17 +7,17 @@ import subprocess from oeqa.utils.buildproject import BuildProject class SDKBuildProject(BuildProject): - - def __init__(self, testpath, sdkenv, d, uri, foldername=None): + def __init__(self, testpath, sdkenv, uri, testlogdir, builddatetime, + foldername=None, dl_dir=None): self.sdkenv = sdkenv self.testdir = testpath self.targetdir = testpath - bb.utils.mkdirhier(testpath) - self.datetime = d.getVar('DATETIME') - self.testlogdir = d.getVar("TEST_LOG_DIR") - bb.utils.mkdirhier(self.testlogdir) + os.makedirs(testpath, exist_ok=True) + self.datetime = builddatetime + self.testlogdir = testlogdir + os.makedirs(self.testlogdir, exist_ok=True) self.logfile = os.path.join(self.testlogdir, "sdk_target_log.%s" % self.datetime) - BuildProject.__init__(self, d, uri, foldername, tmpdir=testpath) + BuildProject.__init__(self, uri, foldername, tmpdir=testpath, dl_dir=dl_dir) def download_archive(self):
meta/lib/oeqa/utils/buildproject.py +7 -24
@@ -6,17 +6,17 @@ import os import re -import bb.utils import subprocess +import shutil + from abc import ABCMeta, abstractmethod class BuildProject(metaclass=ABCMeta): - - def __init__(self, d, uri, foldername=None, tmpdir="/tmp/"): - self.d = d + def __init__(self, uri, foldername=None, tmpdir="/tmp/", dl_dir=None): self.uri = uri self.archive = os.path.basename(uri) self.localarchive = os.path.join(tmpdir,self.archive) + self.dl_dir = dl_dir if foldername: self.fname = foldername else:
@@ -24,27 +24,11 @@ class BuildProject(metaclass=ABCMeta): # Download self.archive to self.localarchive def _download_archive(self): - - dl_dir = self.d.getVar("DL_DIR") - if dl_dir and os.path.exists(os.path.join(dl_dir, self.archive)): - bb.utils.copyfile(os.path.join(dl_dir, self.archive), self.localarchive) + if self.dl_dir and os.path.exists(os.path.join(self.dl_dir, self.archive)): + shutil.copyfile(os.path.join(self.dl_dir, self.archive), self.localarchive) return - exportvars = ['HTTP_PROXY', 'http_proxy', - 'HTTPS_PROXY', 'https_proxy', - 'FTP_PROXY', 'ftp_proxy', - 'FTPS_PROXY', 'ftps_proxy', - 'NO_PROXY', 'no_proxy', - 'ALL_PROXY', 'all_proxy', - 'SOCKS5_USER', 'SOCKS5_PASSWD'] - - cmd = '' - for var in exportvars: - val = self.d.getVar(var) - if val: - cmd = 'export ' + var + '=\"%s\"; %s' % (val, cmd) - - cmd = cmd + "wget -O %s %s" % (self.localarchive, self.uri) + cmd = "wget -O %s %s" % (self.localarchive, self.uri) subprocess.check_call(cmd, shell=True) # This method should provide a way to run a command in the desired environment.
@@ -66,4 +50,3 @@ class BuildProject(metaclass=ABCMeta): def clean(self): self._run('rm -rf %s' % self.targetdir) subprocess.call('rm -f %s' % self.localarchive, shell=True) - pass
Signature · 1 line
2.1.4
PATCH 24/55 oeqa/sdk/cases: Migrate tests to the new OEQA framework
In reply to Aníbal LimónSummary of the changes:
- Remove auto extend_path using pkgutil at __init__, is not needed.
- Change base class to OESDKTestCase.
- Add td_vars attr to set dependencies of certain variables in test data.
- Change skips from module level to class level because Test context (tc)
now isn't at module level.
- Variable names changes to be consistent (i.e. sdktestdir -> sdk_dir).
[YOCTO #10599]
- Don't use bb.utils functions use instead remove_safe and shutil for copy files.
- SDKBuildProject pass test data variables instead of call getVar inside.
[YOCTO #10231]
--- meta/lib/oeqa/sdk/cases/__init__.py | 3 --- meta/lib/oeqa/sdk/cases/buildcvs.py | 15 ++++++----- meta/lib/oeqa/sdk/cases/buildgalculator.py | 28 ++++++++++++-------- meta/lib/oeqa/sdk/cases/buildiptables.py | 16 +++++++----- meta/lib/oeqa/sdk/cases/gcc.py | 41 +++++++++++++++++------------- meta/lib/oeqa/sdk/cases/perl.py | 25 +++++++++--------- meta/lib/oeqa/sdk/cases/python.py | 25 +++++++++--------- 7 files changed, 84 insertions(+), 69 deletions(-) delete mode 100644 meta/lib/oeqa/sdk/cases/__init__.py
meta/lib/oeqa/sdk/cases/__init__.py deleted +0 -3
@@ -1,3 +0,0 @@ -# Enable other layers to have tests in the same named directory -from pkgutil import extend_path -__path__ = extend_path(__path__, __name__)
meta/lib/oeqa/sdk/cases/buildcvs.py +9 -6
@@ -1,13 +1,16 @@ -from oeqa.oetest import oeSDKTest, skipModule -from oeqa.utils.decorators import * -from oeqa.utils.targetbuild import SDKBuildProject +from oeqa.sdk.case import OESDKTestCase +from oeqa.sdk.utils.sdkbuildproject import SDKBuildProject -class BuildCvsTest(oeSDKTest): +class BuildCvsTest(OESDKTestCase): + td_vars = ['TEST_LOG_DIR', 'DATETIME'] @classmethod def setUpClass(self): - self.project = SDKBuildProject(oeSDKTest.tc.sdktestdir + "/cvs/", oeSDKTest.tc.sdkenv, oeSDKTest.tc.d, - "http://ftp.gnu.org/non-gnu/cvs/source/feature/1.12.13/cvs-1.12.13.tar.bz2") + dl_dir = self.td.get('DL_DIR', None) + + self.project = SDKBuildProject(self.tc.sdk_dir + "/cvs/", self.tc.sdk_env, + "http://ftp.gnu.org/non-gnu/cvs/source/feature/1.12.13/cvs-1.12.13.tar.bz2", + self.td['TEST_LOG_DIR'], self.td['DATETIME'], dl_dir=dl_dir) self.project.download_archive() def test_cvs(self):
meta/lib/oeqa/sdk/cases/buildgalculator.py +18 -10
@@ -1,17 +1,25 @@ -from oeqa.oetest import oeSDKTest, skipModule -from oeqa.utils.decorators import * -from oeqa.utils.targetbuild import SDKBuildProject +import unittest -def setUpModule(): - if not (oeSDKTest.hasPackage("gtk+3") or oeSDKTest.hasPackage("libgtk-3.0")): - skipModule("Image doesn't have gtk+3 in manifest") +from oeqa.sdk.case import OESDKTestCase +from oeqa.sdk.utils.sdkbuildproject import SDKBuildProject + +class GalculatorTest(OESDKTestCase): + td_vars = ['TEST_LOG_DIR', 'DATETIME'] + + @classmethod + def setUpClass(self): + if not (self.tc.hasTargetPackage("gtk+3") or\ + self.tc.hasTargetPackage("libgtk-3.0")): + raise unittest.SkipTest("%s class: SDK don't support gtk+3" % self.__name__) -class GalculatorTest(oeSDKTest): def test_galculator(self): + dl_dir = self.td.get('DL_DIR', None) + project = None try: - project = SDKBuildProject(oeSDKTest.tc.sdktestdir + "/galculator/", - oeSDKTest.tc.sdkenv, oeSDKTest.tc.d, - "http://galculator.mnim.org/downloads/galculator-2.1.4.tar.bz2") + project = SDKBuildProject(self.tc.sdk_dir + "/galculator/", + self.tc.sdk_env, + "http://galculator.mnim.org/downloads/galculator-2.1.4.tar.bz2", + self.td['TEST_LOG_DIR'], self.td['DATETIME'], dl_dir=dl_dir) project.download_archive()
meta/lib/oeqa/sdk/cases/buildiptables.py +9 -7
@@ -1,14 +1,16 @@ -from oeqa.oetest import oeSDKTest -from oeqa.utils.decorators import * -from oeqa.utils.targetbuild import SDKBuildProject +from oeqa.sdk.case import OESDKTestCase +from oeqa.sdk.utils.sdkbuildproject import SDKBuildProject - -class BuildIptablesTest(oeSDKTest): +class BuildIptablesTest(OESDKTestCase): + td_vars = ['TEST_LOG_DIR', 'DATETIME'] @classmethod def setUpClass(self): - self.project = SDKBuildProject(oeSDKTest.tc.sdktestdir + "/iptables/", oeSDKTest.tc.sdkenv, oeSDKTest.tc.d, - "http://downloads.yoctoproject.org/mirror/sources/iptables-1.4.13.tar.bz2") + dl_dir = self.td.get('DL_DIR', None) + + self.project = SDKBuildProject(self.tc.sdk_dir + "/iptables/", self.tc.sdk_env, + "http://downloads.yoctoproject.org/mirror/sources/iptables-1.4.13.tar.bz2", + self.td['TEST_LOG_DIR'], self.td['DATETIME'], dl_dir=dl_dir) self.project.download_archive() def test_iptables(self):
meta/lib/oeqa/sdk/cases/gcc.py +24 -17
60 lines not on this page · raw message
meta/lib/oeqa/sdk/cases/perl.py +12 -13
@@ -1,28 +1,27 @@ -import unittest import os import shutil -from oeqa.oetest import oeSDKTest, skipModule -from oeqa.utils.decorators import * - -def setUpModule(): - if not oeSDKTest.hasHostPackage("nativesdk-perl"): - skipModule("No perl package in the SDK") - +import unittest -class PerlTest(oeSDKTest): +from oeqa.core.utils.path import remove_safe +from oeqa.sdk.case import OESDKTestCase +class PerlTest(OESDKTestCase): @classmethod def setUpClass(self): + if not self.tc.hasHostPackage("nativesdk-perl"): + raise unittest.SkipTest("No perl package in the SDK") + for f in ['test.pl']: - shutil.copyfile(os.path.join(self.tc.filesdir, f), self.tc.sdktestdir + f) - self.testfile = self.tc.sdktestdir + "test.pl" + shutil.copyfile(os.path.join(self.tc.files_dir, f), + os.path.join(self.tc.sdk_dir, f)) + self.testfile = os.path.join(self.tc.sdk_dir, "test.pl") def test_perl_exists(self): self._run('which perl') def test_perl_works(self): - self._run('perl %s/test.pl' % self.tc.sdktestdir) + self._run('perl %s' % self.testfile) @classmethod def tearDownClass(self): - bb.utils.remove("%s/test.pl" % self.tc.sdktestdir) + remove_safe(self.testfile)
meta/lib/oeqa/sdk/cases/python.py +12 -13
@@ -1,26 +1,25 @@ -import unittest import os import shutil -from oeqa.oetest import oeSDKTest, skipModule -from oeqa.utils.decorators import * - -def setUpModule(): - if not oeSDKTest.hasHostPackage("nativesdk-python"): - skipModule("No python package in the SDK") - +import unittest -class PythonTest(oeSDKTest): +from oeqa.core.utils.path import remove_safe +from oeqa.sdk.case import OESDKTestCase +class PythonTest(OESDKTestCase): @classmethod def setUpClass(self): + if not self.tc.hasHostPackage("nativesdk-python"): + raise unittest.SkipTest("No python package in the SDK") + for f in ['test.py']: - shutil.copyfile(os.path.join(self.tc.filesdir, f), self.tc.sdktestdir + f) + shutil.copyfile(os.path.join(self.tc.files_dir, f), + os.path.join(self.tc.sdk_dir, f)) def test_python_exists(self): self._run('which python') def test_python_stdout(self): - output = self._run('python %s/test.py' % self.tc.sdktestdir) + output = self._run('python %s/test.py' % self.tc.sdk_dir) self.assertEqual(output.strip(), "the value of a is 0.01", msg="Incorrect output: %s" % output) def test_python_testfile(self):
@@ -28,5 +27,5 @@ class PythonTest(oeSDKTest): @classmethod def tearDownClass(self): - bb.utils.remove("%s/test.py" % self.tc.sdktestdir) - bb.utils.remove("/tmp/testfile.python") + remove_safe("%s/test.py" % self.tc.sdk_dir) + remove_safe("/tmp/testfile.python")
Signature · 1 line
2.1.4
PATCH 25/55 classes/testsdk: Remove the need of TEST_LOG_DIR variable
In reply to Aníbal LimónThe TEST_LOG_DIR was used for store sdk_target_log this log contains the output of the run of build commands now that information could be found also on log.do_testsdk under WORKDIR.
The log will continue to store into SDK_DIR instead of TEST_LOG_DIR.
--- meta/classes/testsdk.bbclass | 6 ------ meta/lib/oeqa/sdk/cases/buildcvs.py | 4 ++-- meta/lib/oeqa/sdk/cases/buildgalculator.py | 4 ++-- meta/lib/oeqa/sdk/cases/buildiptables.py | 4 ++-- 4 files changed, 6 insertions(+), 12 deletions(-)
meta/classes/testsdk.bbclass +0 -6
@@ -14,7 +14,6 @@ # # where "<image-name>" is an image like core-image-sato. -TEST_LOG_DIR ?= "${WORKDIR}/testimage" TESTSDKLOCK = "${TMPDIR}/testsdk.lock" def run_test_context(CTestContext, d, testdir, tcname, pn, *args):
@@ -65,17 +64,12 @@ def testsdk_main(d): # sdk use network for download projects for build export_proxies(d) - test_log_dir = d.getVar("TEST_LOG_DIR", True) - - bb.utils.mkdirhier(test_log_dir) - tcname = d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.sh") if not os.path.exists(tcname): bb.fatal("The toolchain %s is not built. Build it before running the tests: 'bitbake <image> -c populate_sdk' ." % tcname) tdname = d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.testdata.json") test_data = json.load(open(tdname, "r")) - test_data['TEST_LOG_DIR'] = test_log_dir target_pkg_manifest = OESDKTestContextExecutor._load_manifest( d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.target.manifest"))
meta/lib/oeqa/sdk/cases/buildcvs.py +2 -2
@@ -2,7 +2,7 @@ from oeqa.sdk.case import OESDKTestCase from oeqa.sdk.utils.sdkbuildproject import SDKBuildProject class BuildCvsTest(OESDKTestCase): - td_vars = ['TEST_LOG_DIR', 'DATETIME'] + td_vars = ['DATETIME'] @classmethod def setUpClass(self):
@@ -10,7 +10,7 @@ class BuildCvsTest(OESDKTestCase): self.project = SDKBuildProject(self.tc.sdk_dir + "/cvs/", self.tc.sdk_env, "http://ftp.gnu.org/non-gnu/cvs/source/feature/1.12.13/cvs-1.12.13.tar.bz2", - self.td['TEST_LOG_DIR'], self.td['DATETIME'], dl_dir=dl_dir) + self.tc.sdk_dir, self.td['DATETIME'], dl_dir=dl_dir) self.project.download_archive() def test_cvs(self):
meta/lib/oeqa/sdk/cases/buildgalculator.py +2 -2
@@ -4,7 +4,7 @@ from oeqa.sdk.case import OESDKTestCase from oeqa.sdk.utils.sdkbuildproject import SDKBuildProject class GalculatorTest(OESDKTestCase): - td_vars = ['TEST_LOG_DIR', 'DATETIME'] + td_vars = ['DATETIME'] @classmethod def setUpClass(self):
@@ -19,7 +19,7 @@ class GalculatorTest(OESDKTestCase): project = SDKBuildProject(self.tc.sdk_dir + "/galculator/", self.tc.sdk_env, "http://galculator.mnim.org/downloads/galculator-2.1.4.tar.bz2", - self.td['TEST_LOG_DIR'], self.td['DATETIME'], dl_dir=dl_dir) + self.tc.sdk_dir, self.td['DATETIME'], dl_dir=dl_dir) project.download_archive()
meta/lib/oeqa/sdk/cases/buildiptables.py +2 -2
@@ -2,7 +2,7 @@ from oeqa.sdk.case import OESDKTestCase from oeqa.sdk.utils.sdkbuildproject import SDKBuildProject class BuildIptablesTest(OESDKTestCase): - td_vars = ['TEST_LOG_DIR', 'DATETIME'] + td_vars = ['DATETIME'] @classmethod def setUpClass(self):
@@ -10,7 +10,7 @@ class BuildIptablesTest(OESDKTestCase): self.project = SDKBuildProject(self.tc.sdk_dir + "/iptables/", self.tc.sdk_env, "http://downloads.yoctoproject.org/mirror/sources/iptables-1.4.13.tar.bz2", - self.td['TEST_LOG_DIR'], self.td['DATETIME'], dl_dir=dl_dir) + self.tc.sdk_dir, self.td['DATETIME'], dl_dir=dl_dir) self.project.download_archive() def test_iptables(self):
Signature · 1 line
2.1.4
PATCH 26/55 oeqa/sdkext: Move test cases inside cases directory
In reply to Aníbal LimónFor match with the new structure of the OEQA framework.
In the new framework Test component base directory in this case sdk module will contain case and context implementations.
[YOCTO #10599]
---
meta/lib/oeqa/sdkext/__init__.py | 3 ---
meta/lib/oeqa/sdkext/{ => cases}/devtool.py | 0
meta/lib/oeqa/sdkext/{ => cases}/sdk_update.py | 0
3 files changed, 3 deletions(-)
rename meta/lib/oeqa/sdkext/{ => cases}/devtool.py (100%)
rename meta/lib/oeqa/sdkext/{ => cases}/sdk_update.py (100%)meta/lib/oeqa/sdkext/__init__.py +0 -3
@@ -1,3 +0,0 @@ -# Enable other layers to have tests in the same named directory -from pkgutil import extend_path -__path__ = extend_path(__path__, __name__)
meta/lib/oeqa/sdkext/cases/devtool.py renamed from meta/lib/oeqa/sdkext/devtool.py +0 -0
meta/lib/oeqa/sdkext/cases/sdk_update.py renamed from meta/lib/oeqa/sdkext/sdk_update.py +0 -0
Signature · 1 line
2.1.4
PATCH 27/55 oeqa/sdkext: Adds case and context modules.
In reply to Aníbal LimónThe extensible sdk context and case modules extends the sdk ones, this means that the tests from sdk are run also the sdkext tests.
Enables support in context for use oe-test esdk command for run the test suites, the same options of sdk are required for run esdk tests.
Removes old related to case and context inside oetest.py.
[YOCTO #10599]
--- meta/lib/oeqa/oetest.py | 40 ---------------------------------------- meta/lib/oeqa/sdkext/case.py | 21 +++++++++++++++++++++ meta/lib/oeqa/sdkext/context.py | 21 +++++++++++++++++++++ 3 files changed, 42 insertions(+), 40 deletions(-) create mode 100644 meta/lib/oeqa/sdkext/case.py create mode 100644 meta/lib/oeqa/sdkext/context.py
meta/lib/oeqa/oetest.py +0 -40
@@ -27,7 +27,6 @@ try: except ImportError: pass from oeqa.utils.decorators import LogResults, gettag, getResults -from oeqa.utils import avoid_paths_in_environ logger = logging.getLogger("BitBake")
@@ -145,18 +144,6 @@ class OETestCalledProcessError(subprocess.CalledProcessError): subprocess.CalledProcessError = OETestCalledProcessError -class oeSDKExtTest(oeSDKTest): - def _run(self, cmd): - # extensible sdk shows a warning if found bitbake in the path - # because can cause contamination, i.e. use devtool from - # poky/scripts instead of eSDK one. - env = os.environ.copy() - paths_to_avoid = ['bitbake/bin', 'poky/scripts'] - env['PATH'] = avoid_paths_in_environ(paths_to_avoid) - - return subprocess.check_output(". %s > /dev/null;"\ - " %s;" % (self.tc.sdkenv, cmd), stderr=subprocess.STDOUT, shell=True, env=env).decode("utf-8") - def getmodule(pos=2): # stack returns a list of tuples containg frame information # First element of the list the is current frame, caller is 1
@@ -642,30 +629,3 @@ class ExportTestContext(RuntimeTestContext): extracted_dir = self.d.getVar("TEST_EXPORT_EXTRACTED_DIR") pkg_dir = os.path.join(export_dir, extracted_dir) super(ExportTestContext, self).install_uninstall_packages(test_id, pkg_dir, install) - -class SDKExtTestContext(SDKTestContext): - def __init__(self, d, sdktestdir, sdkenv, tcname, *args): - self.target_manifest = d.getVar("SDK_EXT_TARGET_MANIFEST") - self.host_manifest = d.getVar("SDK_EXT_HOST_MANIFEST") - if args: - self.cm = args[0] # Compatibility mode for run SDK tests - else: - self.cm = False - - super(SDKExtTestContext, self).__init__(d, sdktestdir, sdkenv, tcname) - - self.sdkextfilesdir = os.path.join(os.path.dirname(os.path.abspath( - oeqa.sdkext.__file__)), "files") - - def _get_test_namespace(self): - if self.cm: - return "sdk" - else: - return "sdkext" - - def _get_test_suites(self): - return (self.d.getVar("TEST_SUITES_SDK_EXT") or "auto").split() - - def _get_test_suites_required(self): - return [t for t in (self.d.getVar("TEST_SUITES_SDK_EXT") or \ - "auto").split() if t != "auto"]
meta/lib/oeqa/sdkext/case.py new file +21 -0
@@ -0,0 +1,21 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +import os +import subprocess + +from oeqa.utils import avoid_paths_in_environ +from oeqa.sdk.case import OESDKTestCase + +class OESDKExtTestCase(OESDKTestCase): + def _run(self, cmd): + # extensible sdk shows a warning if found bitbake in the path + # because can cause contamination, i.e. use devtool from + # poky/scripts instead of eSDK one. + env = os.environ.copy() + paths_to_avoid = ['bitbake/bin', 'poky/scripts'] + env['PATH'] = avoid_paths_in_environ(paths_to_avoid) + + return subprocess.check_output(". %s > /dev/null;"\ + " %s;" % (self.tc.sdk_env, cmd), stderr=subprocess.STDOUT, + shell=True, env=env).decode("utf-8")
meta/lib/oeqa/sdkext/context.py new file +21 -0
@@ -0,0 +1,21 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +import os +from oeqa.sdk.context import OESDKTestContext, OESDKTestContextExecutor + +class OESDKExtTestContext(OESDKTestContext): + esdk_files_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "files") + +class OESDKExtTestContextExecutor(OESDKTestContextExecutor): + _context_class = OESDKExtTestContext + + name = 'esdk' + help = 'esdk test component' + description = 'executes esdk tests' + + default_cases = [OESDKTestContextExecutor.default_cases[0], + os.path.join(os.path.abspath(os.path.dirname(__file__)), 'cases')] + default_test_data = None + +_executor_class = OESDKExtTestContextExecutor
Signature · 1 line
2.1.4
PATCH 28/55 classes/testsdk: Migrate to use the new OESDKExtTestContext
In reply to Aníbal Limón--- meta/classes/testsdk.bbclass | 98 ++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 53 deletions(-)
meta/classes/testsdk.bbclass +45 -53
@@ -16,37 +16,6 @@ TESTSDKLOCK = "${TMPDIR}/testsdk.lock" -def run_test_context(CTestContext, d, testdir, tcname, pn, *args): - import glob - import time - - targets = glob.glob(d.expand(testdir + "/tc/environment-setup-*")) - for sdkenv in targets: - bb.plain("Testing %s" % sdkenv) - tc = CTestContext(d, testdir, sdkenv, tcname, args) - - # this is a dummy load of tests - # we are doing that to find compile errors in the tests themselves - # before booting the image - try: - tc.loadTests() - except Exception as e: - import traceback - bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) - - starttime = time.time() - result = tc.runTests() - stoptime = time.time() - if result.wasSuccessful(): - bb.plain("%s SDK(%s):%s - Ran %d test%s in %.3fs" % (pn, os.path.basename(tcname), os.path.basename(sdkenv),result.testsRun, result.testsRun != 1 and "s" or "", stoptime - starttime)) - msg = "%s - OK - All required tests passed" % pn - skipped = len(result.skipped) - if skipped: - msg += " (skipped=%d)" % skipped - bb.plain(msg) - else: - bb.fatal("%s - FAILED - check the task log and the commands log" % pn) - def testsdk_main(d): import os import subprocess
@@ -122,7 +91,6 @@ addtask testsdk do_testsdk[nostamp] = "1" do_testsdk[lockfiles] += "${TESTSDKLOCK}" -TEST_LOG_SDKEXT_DIR ?= "${WORKDIR}/testsdkext" TESTSDKEXTLOCK = "${TMPDIR}/testsdkext.lock" def testsdkext_main(d):
@@ -132,7 +100,11 @@ def testsdkext_main(d): import logging from bb.utils import export_proxies - from oeqa.utils import avoid_paths_in_environ + from oeqa.utils import avoid_paths_in_environ, make_logger_bitbake_compatible + from oeqa.sdkext.context import OESDKExtTestContext, OESDKExtTestContextExecutor + + pn = d.getVar("PN", True) + logger = make_logger_bitbake_compatible(logging.getLogger("BitBake")) # extensible sdk use network export_proxies(d)
@@ -143,23 +115,27 @@ def testsdkext_main(d): d.getVar('BASE_WORKDIR')] os.environ['PATH'] = avoid_paths_in_environ(paths_to_avoid) - pn = d.getVar("PN") - bb.utils.mkdirhier(d.getVar("TEST_LOG_SDKEXT_DIR")) - tcname = d.expand("${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.sh") if not os.path.exists(tcname): bb.fatal("The toolchain ext %s is not built. Build it before running the" \ " tests: 'bitbake <image> -c populate_sdk_ext' ." % tcname) - testdir = d.expand("${WORKDIR}/testsdkext/") - bb.utils.remove(testdir, True) - bb.utils.mkdirhier(testdir) - sdkdir = os.path.join(testdir, 'tc') + tdname = d.expand("${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.testdata.json") + test_data = json.load(open(tdname, "r")) + + target_pkg_manifest = OESDKExtTestContextExecutor._load_manifest( + d.expand("${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.target.manifest")) + host_pkg_manifest = OESDKExtTestContextExecutor._load_manifest( + d.expand("${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.host.manifest")) + + sdk_dir = d.expand("${WORKDIR}/testsdkext/") + bb.utils.remove(sdk_dir, True) + bb.utils.mkdirhier(sdk_dir) try: - subprocess.check_output("%s -y -d %s" % (tcname, sdkdir), shell=True) + subprocess.check_output("%s -y -d %s" % (tcname, sdk_dir), shell=True) except subprocess.CalledProcessError as e: msg = "Couldn't install the extensible SDK:\n%s" % e.output.decode("utf-8") - logfn = os.path.join(sdkdir, 'preparing_build_system.log') + logfn = os.path.join(sdk_dir, 'preparing_build_system.log') if os.path.exists(logfn): msg += '\n\nContents of preparing_build_system.log:\n' with open(logfn, 'r') as f:
@@ -167,19 +143,35 @@ def testsdkext_main(d): msg += line bb.fatal(msg) - try: - bb.plain("Running SDK Compatibility tests ...") - run_test_context(SDKExtTestContext, d, testdir, tcname, pn, True) - finally: - pass + fail = False + sdk_envs = OESDKExtTestContextExecutor._get_sdk_environs(sdk_dir) + for s in sdk_envs: + bb.plain("Extensible SDK testing environment: %s" % s) - try: - bb.plain("Running Extensible SDK tests ...") - run_test_context(SDKExtTestContext, d, testdir, tcname, pn) - finally: - pass + sdk_env = sdk_envs[s] + tc = OESDKExtTestContext(td=test_data, logger=logger, sdk_dir=sdk_dir, + sdk_env=sdk_env, target_pkg_manifest=target_pkg_manifest, + host_pkg_manifest=host_pkg_manifest) + + try: + tc.loadTests(OESDKExtTestContextExecutor.default_cases) + except Exception as e: + import traceback + bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) + + result = tc.runTests() - bb.utils.remove(testdir, True) + component = "%s %s" % (pn, OESDKExtTestContextExecutor.name) + context_msg = "%s:%s" % (os.path.basename(tcname), os.path.basename(sdk_env)) + + tc.logSummary(result, component, context_msg) + tc.logDetails() + + if not result.wasSuccessful(): + fail = True + + if fail: + bb.fatal("%s - FAILED - check the task log and the commands log" % pn) testsdkext_main[vardepsexclude] =+ "BB_ORIGENV"
Signature · 1 line
2.1.4
PATCH 29/55 oeqa/sdkext/cases: Migrate test case to new OEQA framework
In reply to Aníbal LimónSummary,
- Changes base case class to OESDKExtTest.
- Changes decorator classes to new ones.
- Chnages variable names sdktestdir -> sdk_dir.
- Added missing license to MIT.
--- meta/lib/oeqa/sdk/cases/buildgalculator.py | 2 +- meta/lib/oeqa/sdk/cases/gcc.py | 3 +- meta/lib/oeqa/sdkext/cases/devtool.py | 49 ++++++++++++++++-------------- meta/lib/oeqa/sdkext/cases/sdk_update.py | 17 ++++++----- 4 files changed, 38 insertions(+), 33 deletions(-)
meta/lib/oeqa/sdk/cases/buildgalculator.py +1 -1
@@ -10,7 +10,7 @@ class GalculatorTest(OESDKTestCase): def setUpClass(self): if not (self.tc.hasTargetPackage("gtk+3") or\ self.tc.hasTargetPackage("libgtk-3.0")): - raise unittest.SkipTest("%s class: SDK don't support gtk+3" % self.__name__) + raise unittest.SkipTest("GalculatorTest class: SDK don't support gtk+3") def test_galculator(self): dl_dir = self.td.get('DL_DIR', None)
meta/lib/oeqa/sdk/cases/gcc.py +1 -2
@@ -19,8 +19,7 @@ class GccCompileTest(OESDKTestCase): def setUp(self): machine = self.td.get("MACHINE") if not self.tc.hasHostPackage("packagegroup-cross-canadian-%s" % machine): - raise unittest.SkipTest("%s class: SDK doesn't contain a cross-canadian toolchain", - self.__name__) + raise unittest.SkipTest("GccCompileTest class: SDK doesn't contain a cross-canadian toolchain") def test_gcc_compile(self): self._run('$CC %s/test.c -o %s/test -lm' % (self.tc.sdk_dir, self.tc.sdk_dir))
meta/lib/oeqa/sdkext/cases/devtool.py +26 -23
98 lines not on this page · raw message
meta/lib/oeqa/sdkext/cases/sdk_update.py +10 -7
@@ -1,23 +1,26 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + import os import shutil import subprocess -from oeqa.oetest import oeSDKExtTest +from oeqa.sdkext.case import OESDKExtTestCase from oeqa.utils.httpserver import HTTPService -class SdkUpdateTest(oeSDKExtTest): - +class SdkUpdateTest(OESDKExtTestCase): @classmethod def setUpClass(self): - self.publish_dir = os.path.join(self.tc.sdktestdir, 'esdk_publish') + self.publish_dir = os.path.join(self.tc.sdk_dir, 'esdk_publish') if os.path.exists(self.publish_dir): shutil.rmtree(self.publish_dir) os.mkdir(self.publish_dir) - tcname_new = self.tc.d.expand( - "${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}-new.sh") + base_tcname = "%s/%s" % (self.td.get("SDK_DEPLOY", ''), + self.td.get("TOOLCHAINEXT_OUTPUTNAME", '')) + tcname_new = "%s-new.sh" % base_tcname if not os.path.exists(tcname_new): - tcname_new = self.tc.tcname + tcname_new = "%s.sh" % base_tcname cmd = 'oe-publish-sdk %s %s' % (tcname_new, self.publish_dir) subprocess.check_output(cmd, shell=True)
Signature · 1 line
2.1.4
PATCH 30/55 oeqa/runtime: Fix TargetBuildProject instances
In reply to Aníbal LimónTargetBuildProject was refactored to avoid bitbake dependency so the instance don't allow to pass data store anymore.
classes/testimage: Export proxies before run tests
The TargetBuildProject based tests download archives from network.
--- meta/classes/testimage.bbclass | 4 ++++ meta/lib/oeqa/runtime/buildcvs.py | 9 +++++---- meta/lib/oeqa/runtime/buildgalculator.py | 8 +++++--- meta/lib/oeqa/runtime/buildiptables.py | 8 +++++--- 4 files changed, 19 insertions(+), 10 deletions(-)
meta/classes/testimage.bbclass +4 -0
@@ -129,11 +129,15 @@ def testimage_main(d): from oeqa.oetest import ImageTestContext from oeqa.targetcontrol import get_target_controller from oeqa.utils.dump import get_host_dumper + from bb.utils import export_proxies pn = d.getVar("PN") bb.utils.mkdirhier(d.getVar("TEST_LOG_DIR")) test_create_extract_dirs(d) + # runtime use network for download projects for build + export_proxies(d) + # we need the host dumper in test context host_dumper = get_host_dumper(d)
meta/lib/oeqa/runtime/buildcvs.py +5 -4
@@ -1,6 +1,6 @@ from oeqa.oetest import oeRuntimeTest, skipModule from oeqa.utils.decorators import * -from oeqa.utils.targetbuild import TargetBuildProject +from oeqa.runtime.utils.targetbuildproject import TargetBuildProject def setUpModule(): if not oeRuntimeTest.hasFeature("tools-sdk"):
@@ -10,9 +10,10 @@ class BuildCvsTest(oeRuntimeTest): @classmethod def setUpClass(self): - self.project = TargetBuildProject(oeRuntimeTest.tc.target, oeRuntimeTest.tc.d, - "http://ftp.gnu.org/non-gnu/cvs/source/feature/1.12.13/cvs-1.12.13.tar.bz2") - self.project.download_archive() + dl_dir = oeRuntimeTest.tc.d.getVar('DL_DIR', True) + self.project = TargetBuildProject(oeRuntimeTest.tc.target, + "http://ftp.gnu.org/non-gnu/cvs/source/feature/1.12.13/cvs-1.12.13.tar.bz2", + dl_dir=dl_dir) @testcase(205) @skipUnlessPassed("test_ssh")
meta/lib/oeqa/runtime/buildgalculator.py +5 -3
@@ -1,6 +1,6 @@ from oeqa.oetest import oeRuntimeTest, skipModule from oeqa.utils.decorators import * -from oeqa.utils.targetbuild import TargetBuildProject +from oeqa.runtime.utils.targetbuildproject import TargetBuildProject def setUpModule(): if not oeRuntimeTest.hasFeature("tools-sdk"):
@@ -10,9 +10,11 @@ class GalculatorTest(oeRuntimeTest): @testcase(1526) @skipUnlessPassed("test_ssh") def test_galculator(self): + dl_dir = oeRuntimeTest.tc.d.getVar('DL_DIR', True) try: - project = TargetBuildProject(oeRuntimeTest.tc.target, oeRuntimeTest.tc.d, - "http://galculator.mnim.org/downloads/galculator-2.1.4.tar.bz2") + project = TargetBuildProject(oeRuntimeTest.tc.target, + "http://galculator.mnim.org/downloads/galculator-2.1.4.tar.bz2", + dl_dir=dl_dir) project.download_archive() self.assertEqual(project.run_configure(), 0,
meta/lib/oeqa/runtime/buildiptables.py +5 -3
@@ -1,6 +1,6 @@ from oeqa.oetest import oeRuntimeTest, skipModule from oeqa.utils.decorators import * -from oeqa.utils.targetbuild import TargetBuildProject +from oeqa.runtime.utils.targetbuildproject import TargetBuildProject def setUpModule(): if not oeRuntimeTest.hasFeature("tools-sdk"):
@@ -10,8 +10,10 @@ class BuildIptablesTest(oeRuntimeTest): @classmethod def setUpClass(self): - self.project = TargetBuildProject(oeRuntimeTest.tc.target, oeRuntimeTest.tc.d, - "http://downloads.yoctoproject.org/mirror/sources/iptables-1.4.13.tar.bz2") + dl_dir = oeRuntimeTest.tc.d.getVar('DL_DIR', True) + self.project = TargetBuildProject(oeRuntimeTest.tc.target, + "http://downloads.yoctoproject.org/mirror/sources/iptables-1.4.13.tar.bz2", + dl_dir=dl_dir) self.project.download_archive() @testcase(206)
Signature · 1 line
2.1.4
PATCH 31/55 oeqa: Fix files handling on runtime tests.
In reply to Aníbal LimónCommon files was move to oeqa/files from oeqa/runtime/files because the same files are used across Runtime,SDK,eSDK tests.
--- meta/classes/testexport.bbclass | 5 +++++ meta/lib/oeqa/oetest.py | 1 + meta/lib/oeqa/runtime/gcc.py | 4 ++-- meta/lib/oeqa/runtime/perl.py | 2 +- meta/lib/oeqa/runtime/python.py | 2 +- 5 files changed, 10 insertions(+), 4 deletions(-)
meta/classes/testexport.bbclass +5 -0
@@ -87,6 +87,7 @@ def exportTests(d,tc): # - the contents of oeqa/utils and oeqa/runtime/files # - oeqa/oetest.py and oeqa/runexport.py (this will get copied to exportpath not exportpath/oeqa) # - __init__.py files + bb.utils.mkdirhier(os.path.join(exportpath, "oeqa/files")) bb.utils.mkdirhier(os.path.join(exportpath, "oeqa/runtime/files")) bb.utils.mkdirhier(os.path.join(exportpath, "oeqa/utils")) # copy test modules, this should cover tests in other layers too
@@ -124,6 +125,10 @@ def exportTests(d,tc): for f in files: if f.endswith(".py"): shutil.copy2(os.path.join(root, f), os.path.join(exportpath, "oeqa/utils")) + # copy oeqa/files/* + for root, dirs, files in os.walk(os.path.join(oeqadir, "files")): + for f in files: + shutil.copy2(os.path.join(root, f), os.path.join(exportpath, "oeqa/files")) # copy oeqa/runtime/files/* for root, dirs, files in os.walk(os.path.join(oeqadir, "runtime/files")): for f in files:
meta/lib/oeqa/oetest.py +1 -0
@@ -201,6 +201,7 @@ class TestContext(object): self.testsrequired = self._get_test_suites_required() self.filesdir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "runtime/files") + self.corefilesdir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "files") self.imagefeatures = d.getVar("IMAGE_FEATURES").split() self.distrofeatures = d.getVar("DISTRO_FEATURES").split()
meta/lib/oeqa/runtime/gcc.py +2 -2
@@ -12,9 +12,9 @@ class GccCompileTest(oeRuntimeTest): @classmethod def setUpClass(self): - oeRuntimeTest.tc.target.copy_to(os.path.join(oeRuntimeTest.tc.filesdir, "test.c"), "/tmp/test.c") + oeRuntimeTest.tc.target.copy_to(os.path.join(oeRuntimeTest.tc.corefilesdir, "test.c"), "/tmp/test.c") oeRuntimeTest.tc.target.copy_to(os.path.join(oeRuntimeTest.tc.filesdir, "testmakefile"), "/tmp/testmakefile") - oeRuntimeTest.tc.target.copy_to(os.path.join(oeRuntimeTest.tc.filesdir, "test.cpp"), "/tmp/test.cpp") + oeRuntimeTest.tc.target.copy_to(os.path.join(oeRuntimeTest.tc.corefilesdir, "test.cpp"), "/tmp/test.cpp") @testcase(203) def test_gcc_compile(self):
meta/lib/oeqa/runtime/perl.py +1 -1
@@ -12,7 +12,7 @@ class PerlTest(oeRuntimeTest): @classmethod def setUpClass(self): - oeRuntimeTest.tc.target.copy_to(os.path.join(oeRuntimeTest.tc.filesdir, "test.pl"), "/tmp/test.pl") + oeRuntimeTest.tc.target.copy_to(os.path.join(oeRuntimeTest.tc.corefilesdir, "test.pl"), "/tmp/test.pl") @testcase(1141) def test_perl_exists(self):
meta/lib/oeqa/runtime/python.py +1 -1
@@ -12,7 +12,7 @@ class PythonTest(oeRuntimeTest): @classmethod def setUpClass(self): - oeRuntimeTest.tc.target.copy_to(os.path.join(oeRuntimeTest.tc.filesdir, "test.py"), "/tmp/test.py") + oeRuntimeTest.tc.target.copy_to(os.path.join(oeRuntimeTest.tc.corefilesdir, "test.py"), "/tmp/test.py") @testcase(1145) def test_python_exists(self):
Signature · 1 line
2.1.4
PATCH 32/55 oeqa/runtime: Move to runtime_cases
In reply to Aníbal LimónThe new oeqa core framework will modify the structure of the runtime folder the new runtime folder will have python code inside to support runtime test cases.
---
meta/lib/oeqa/{runtime => runtime_cases}/_ptest.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/_qemutiny.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/buildcvs.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/buildgalculator.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/buildiptables.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/connman.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/date.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/df.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/files/hellomod.c | 0
meta/lib/oeqa/{runtime => runtime_cases}/files/hellomod_makefile | 0
meta/lib/oeqa/{runtime => runtime_cases}/files/testmakefile | 0
meta/lib/oeqa/{runtime => runtime_cases}/gcc.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/kernelmodule.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/ldd.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/logrotate.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/multilib.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/pam.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/parselogs.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/perl.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/ping.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/python.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/rpm.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/scanelf.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/scp.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/skeletoninit.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/smart.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/ssh.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/syslog.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/systemd.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/x32lib.py | 0
meta/lib/oeqa/{runtime => runtime_cases}/xorg.py | 0
31 files changed, 0 insertions(+), 0 deletions(-)
rename meta/lib/oeqa/{runtime => runtime_cases}/_ptest.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/_qemutiny.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/buildcvs.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/buildgalculator.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/buildiptables.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/connman.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/date.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/df.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/files/hellomod.c (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/files/hellomod_makefile (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/files/testmakefile (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/gcc.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/kernelmodule.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/ldd.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/logrotate.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/multilib.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/pam.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/parselogs.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/perl.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/ping.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/python.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/rpm.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/scanelf.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/scp.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/skeletoninit.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/smart.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/ssh.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/syslog.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/systemd.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/x32lib.py (100%)
rename meta/lib/oeqa/{runtime => runtime_cases}/xorg.py (100%)meta/lib/oeqa/runtime_cases/_ptest.py renamed from meta/lib/oeqa/runtime/_ptest.py +0 -0
meta/lib/oeqa/runtime_cases/_qemutiny.py renamed from meta/lib/oeqa/runtime/_qemutiny.py +0 -0
meta/lib/oeqa/runtime_cases/buildcvs.py renamed from meta/lib/oeqa/runtime/buildcvs.py +0 -0
meta/lib/oeqa/runtime_cases/buildgalculator.py renamed from meta/lib/oeqa/runtime/buildgalculator.py +0 -0
meta/lib/oeqa/runtime_cases/buildiptables.py renamed from meta/lib/oeqa/runtime/buildiptables.py +0 -0
meta/lib/oeqa/runtime_cases/connman.py renamed from meta/lib/oeqa/runtime/connman.py +0 -0
meta/lib/oeqa/runtime_cases/date.py renamed from meta/lib/oeqa/runtime/date.py +0 -0
meta/lib/oeqa/runtime_cases/df.py renamed from meta/lib/oeqa/runtime/df.py +0 -0
meta/lib/oeqa/runtime_cases/files/hellomod.c renamed from meta/lib/oeqa/runtime/files/hellomod.c +0 -0
meta/lib/oeqa/runtime_cases/files/hellomod_makefile renamed from meta/lib/oeqa/runtime/files/hellomod_makefile +0 -0
meta/lib/oeqa/runtime_cases/files/testmakefile renamed from meta/lib/oeqa/runtime/files/testmakefile +0 -0
meta/lib/oeqa/runtime_cases/gcc.py renamed from meta/lib/oeqa/runtime/gcc.py +0 -0
meta/lib/oeqa/runtime_cases/kernelmodule.py renamed from meta/lib/oeqa/runtime/kernelmodule.py +0 -0
meta/lib/oeqa/runtime_cases/ldd.py renamed from meta/lib/oeqa/runtime/ldd.py +0 -0
meta/lib/oeqa/runtime_cases/logrotate.py renamed from meta/lib/oeqa/runtime/logrotate.py +0 -0
meta/lib/oeqa/runtime_cases/multilib.py renamed from meta/lib/oeqa/runtime/multilib.py +0 -0
meta/lib/oeqa/runtime_cases/pam.py renamed from meta/lib/oeqa/runtime/pam.py +0 -0
meta/lib/oeqa/runtime_cases/parselogs.py renamed from meta/lib/oeqa/runtime/parselogs.py +0 -0
meta/lib/oeqa/runtime_cases/perl.py renamed from meta/lib/oeqa/runtime/perl.py +0 -0
meta/lib/oeqa/runtime_cases/ping.py renamed from meta/lib/oeqa/runtime/ping.py +0 -0
meta/lib/oeqa/runtime_cases/python.py renamed from meta/lib/oeqa/runtime/python.py +0 -0
meta/lib/oeqa/runtime_cases/rpm.py renamed from meta/lib/oeqa/runtime/rpm.py +0 -0
meta/lib/oeqa/runtime_cases/scanelf.py renamed from meta/lib/oeqa/runtime/scanelf.py +0 -0
meta/lib/oeqa/runtime_cases/scp.py renamed from meta/lib/oeqa/runtime/scp.py +0 -0
meta/lib/oeqa/runtime_cases/skeletoninit.py renamed from meta/lib/oeqa/runtime/skeletoninit.py +0 -0
meta/lib/oeqa/runtime_cases/smart.py renamed from meta/lib/oeqa/runtime/smart.py +0 -0
meta/lib/oeqa/runtime_cases/ssh.py renamed from meta/lib/oeqa/runtime/ssh.py +0 -0
meta/lib/oeqa/runtime_cases/syslog.py renamed from meta/lib/oeqa/runtime/syslog.py +0 -0
meta/lib/oeqa/runtime_cases/systemd.py renamed from meta/lib/oeqa/runtime/systemd.py +0 -0
meta/lib/oeqa/runtime_cases/x32lib.py renamed from meta/lib/oeqa/runtime/x32lib.py +0 -0
meta/lib/oeqa/runtime_cases/xorg.py renamed from meta/lib/oeqa/runtime/xorg.py +0 -0
Signature · 1 line
2.1.4
PATCH 33/55 oeqa/core/target Add OESSHTarget to sent commands to targets using SSH
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
With this commit now it is possible to add targets with SSH for testing. Most of it was imported for existing code, with improvements in log handling.
[YOCTO #10234]
--- meta/lib/oeqa/core/target/__init__.py | 33 +++++ meta/lib/oeqa/core/target/ssh.py | 266 ++++++++++++++++++++++++++++++++++ 2 files changed, 299 insertions(+) create mode 100644 meta/lib/oeqa/core/target/__init__.py create mode 100644 meta/lib/oeqa/core/target/ssh.py
meta/lib/oeqa/core/target/__init__.py new file +33 -0
@@ -0,0 +1,33 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +from abc import abstractmethod + +class OETarget(object): + + def __init__(self, logger, *args, **kwargs): + self.logger = logger + + @abstractmethod + def start(self): + pass + + @abstractmethod + def stop(self): + pass + + @abstractmethod + def run(self, cmd, timeout=None): + pass + + @abstractmethod + def copyTo(self, localSrc, remoteDst): + pass + + @abstractmethod + def copyFrom(self, remoteSrc, localDst): + pass + + @abstractmethod + def copyDirTo(self, localSrc, remoteDst): + pass
meta/lib/oeqa/core/target/ssh.py new file +266 -0
266 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH 34/55 oeqa/runtime: Add case, context and loader classes for runtime testing
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
This adds OERuntimeTestCase, OERuntimeTestContext, and OERuntimeTestLoader to be used for runtime testing.
As expected there are some changes in runtime context:
- Adds the target to be used for runtime testing, the default is a SSH connection to the device under test running a OE image.
- Runtime context requires image manifest because several tests are skipped if a package is missing or installed.
- Several tests require the output of the ps command and it changes its output and arguments if busybox o procps is installed, so the case must use the correct ps command.
[YOCTO #10234]
--- meta/lib/oeqa/runtime/case.py | 8 +++++ meta/lib/oeqa/runtime/context.py | 69 ++++++++++++++++++++++++++++++++++++++++ meta/lib/oeqa/runtime/loader.py | 16 ++++++++++ 3 files changed, 93 insertions(+) create mode 100644 meta/lib/oeqa/runtime/case.py create mode 100644 meta/lib/oeqa/runtime/context.py create mode 100644 meta/lib/oeqa/runtime/loader.py
meta/lib/oeqa/runtime/case.py new file +8 -0
@@ -0,0 +1,8 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +from oeqa.core.case import OETestCase + +class OERuntimeTestCase(OETestCase): + # target instance set by OERuntimeTestLoader. + target = None
meta/lib/oeqa/runtime/context.py new file +69 -0
69 lines not on this page · raw message
meta/lib/oeqa/runtime/loader.py new file +16 -0
@@ -0,0 +1,16 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +from oeqa.core.loader import OETestLoader +from oeqa.runtime.case import OERuntimeTestCase + +class OERuntimeTestLoader(OETestLoader): + caseClass = OERuntimeTestCase + + def _getTestCase(self, testCaseClass, tcName): + case = super(OERuntimeTestLoader, self)._getTestCase(testCaseClass, tcName) + + # Adds custom attributes to the OERuntimeTestCase + setattr(case, 'target', self.tc.target) + + return case
Signature · 1 line
2.1.4
PATCH 35/55 oeqa/runtime: Add OEHasPackage decorator
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
This new decorator will be used to skip the test
if the image under test doesn't have the required
packages installed.
[YOCTO #10234]
--- meta/lib/oeqa/runtime/decorator/package.py | 53 ++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 meta/lib/oeqa/runtime/decorator/package.py
meta/lib/oeqa/runtime/decorator/package.py new file +53 -0
@@ -0,0 +1,53 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +from oeqa.core.decorator import OETestDecorator, registerDecorator +from oeqa.core.utils.misc import strToSet + +@registerDecorator +class OEHasPackage(OETestDecorator): + """ + Checks if image has packages (un)installed. + + The argument must be a string, set, or list of packages that must be + installed or not present in the image. + + The way to tell a package must not be in an image is using an + exclamation point ('!') before the name of the package. + + If test depends on pkg1 or pkg2 you need to use: + @OEHasPackage({'pkg1', 'pkg2'}) + + If test depends on pkg1 and pkg2 you need to use: + @OEHasPackage('pkg1') + @OEHasPackage('pkg2') + + If test depends on pkg1 but pkg2 must not be present use: + @OEHasPackage({'pkg1', '!pkg2'}) + """ + + attrs = ('need_pkgs',) + + def setUpDecorator(self): + need_pkgs = set() + unneed_pkgs = set() + pkgs = strToSet(self.need_pkgs) + for pkg in pkgs: + if pkg.startswith('!'): + unneed_pkgs.add(pkg[1:]) + else: + need_pkgs.add(pkg) + + if unneed_pkgs: + msg = 'Checking if %s is not installed' % ', '.join(unneed_pkgs) + self.logger.debug(msg) + if not self.case.tc.image_packages.isdisjoint(unneed_pkgs): + msg = "Test can't run with %s installed" % ', or'.join(unneed_pkgs) + self.case.skipTest(msg) + + if need_pkgs: + msg = 'Checking if at least one of %s is installed' % ', '.join(need_pkgs) + self.logger.debug(msg) + if self.case.tc.image_packages.isdisjoint(need_pkgs): + msg = "Test requires %s to be installed" % ', or'.join(need_pkgs) + self.case.skipTest(msg)
Signature · 1 line
2.1.4
PATCH 36/55 oeqa/core/decorator/data.py: Add skipIfNotFeature decorator
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
This adds a new decorator to check if image under tests has certain DISTRO_FEATURE or IMAGE_FEATURE.
[YOCTO #10234]
--- meta/lib/oeqa/core/decorator/data.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
meta/lib/oeqa/core/decorator/data.py +28 -0
@@ -5,6 +5,16 @@ from oeqa.core.exception import OEQAMissingVariable from . import OETestDecorator, registerDecorator +def has_feature(td, feature): + """ + Checks for feature in DISTRO_FEATURES or IMAGE_FEATURES. + """ + + if (feature in td.get('DISTRO_FEATURES', '') or + feature in td.get('IMAGE_FEATURES', '')): + return True + return False + @registerDecorator class skipIfDataVar(OETestDecorator): """
@@ -34,3 +44,21 @@ class OETestDataDepends(OETestDecorator): except KeyError: raise OEQAMissingVariable("Test case need %s variable but"\ " isn't into td" % v) + +@registerDecorator +class skipIfNotFeature(OETestDecorator): + """ + Skip test based on DISTRO_FEATURES. + + value must be in distro features or it will skip the test + with msg as the reason. + """ + + attrs = ('value', 'msg') + + def setUpDecorator(self): + msg = ('Checking if %s is in DISTRO_FEATURES ' + 'or IMAGE_FEATURES' % (self.value)) + self.logger.debug(msg) + if not has_feature(self.case.td, self.value): + self.case.skipTest(self.msg)
Signature · 1 line
2.1.4
PATCH 37/55 oeqa/runtime/files: Move runtime files from old directory
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
As part of the refactor we require to move the files used in runtime testing to the new directory. This also adds the path to the runtime test context.
[YOCTO #10234]
---
meta/lib/oeqa/runtime/context.py | 2 ++
meta/lib/oeqa/{runtime_cases => runtime}/files/hellomod.c | 0
meta/lib/oeqa/{runtime_cases => runtime}/files/hellomod_makefile | 0
meta/lib/oeqa/{runtime_cases => runtime}/files/testmakefile | 0
4 files changed, 2 insertions(+)
rename meta/lib/oeqa/{runtime_cases => runtime}/files/hellomod.c (100%)
rename meta/lib/oeqa/{runtime_cases => runtime}/files/hellomod_makefile (100%)
rename meta/lib/oeqa/{runtime_cases => runtime}/files/testmakefile (100%)meta/lib/oeqa/runtime/context.py +2 -0
@@ -9,6 +9,8 @@ from oeqa.runtime.loader import OERuntimeTestLoader class OERuntimeTestContext(OETestContext): loaderClass = OERuntimeTestLoader + runtime_files_dir = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "files") def __init__(self, td, logger, target, packages_manifest): super(OERuntimeTestContext, self).__init__(td, logger)
meta/lib/oeqa/runtime/files/hellomod.c renamed from meta/lib/oeqa/runtime_cases/files/hellomod.c +0 -0
meta/lib/oeqa/runtime/files/hellomod_makefile renamed from meta/lib/oeqa/runtime_cases/files/hellomod_makefile +0 -0
meta/lib/oeqa/runtime/files/testmakefile renamed from meta/lib/oeqa/runtime_cases/files/testmakefile +0 -0
Signature · 1 line
2.1.4
PATCH 38/55 oeqa/runtime/utils/targetbuildproject.py: Don't use more than 80 characters per line
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
--- meta/lib/oeqa/runtime/utils/targetbuildproject.py | 29 +++++++++++++---------- 1 file changed, 16 insertions(+), 13 deletions(-)
meta/lib/oeqa/runtime/utils/targetbuildproject.py +16 -13
@@ -14,20 +14,23 @@ class TargetBuildProject(BuildProject): def download_archive(self): self._download_archive() - (status, output) = self.target.copy_to(self.localarchive, self.targetdir) - if status != 0: - raise Exception("Failed to copy archive to target, output: %s" % output) - - (status, output) = self.target.run('tar xf %s%s -C %s' % (self.targetdir, self.archive, self.targetdir)) - if status != 0: - raise Exception("Failed to extract archive, output: %s" % output) - - #Change targetdir to project folder + status, output = self.target.copyTo(self.localarchive, self.targetdir) + if status: + raise Exception('Failed to copy archive to target, ' + 'output: %s' % output) + + cmd = 'tar xf %s%s -C %s' % (self.targetdir, + self.archive, + self.targetdir) + status, output = self.target.run(cmd) + if status: + raise Exception('Failed to extract archive, ' + 'output: %s' % output) + + # Change targetdir to project folder self.targetdir = self.targetdir + self.fname - # The timeout parameter of target.run is set to 0 to make the ssh command - # run with no timeout. + # The timeout parameter of target.run is set to 0 + # to make the ssh command run with no timeout. def _run(self, cmd): return self.target.run(cmd, 0)[0] - -
Signature · 1 line
2.1.4
PATCH 39/55 oeqa/core/decorator: Add skipIfNotDataVar and skipIfNotInDataVar
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
skipIfNotDataVar will skip a test if a variable doesn't have certain value.
skipIfNotInDataVar will skip a test if a value is not in a certain variable.
--- meta/lib/oeqa/core/decorator/data.py | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-)
meta/lib/oeqa/core/decorator/data.py +35 -1
@@ -28,12 +28,46 @@ class skipIfDataVar(OETestDecorator): attrs = ('var', 'value', 'msg') def setUpDecorator(self): - msg = 'Checking if %r value is %r to skip test' % (self.var, self.value) + msg = ('Checking if %r value is %r to skip test' % + (self.var, self.value)) self.logger.debug(msg) if self.case.td.get(self.var) == self.value: self.case.skipTest(self.msg) @registerDecorator +class skipIfNotDataVar(OETestDecorator): + """ + Skip test based on value of a data store's variable. + + It will get the info of var from the data store and will + check it against value; if are not equal it will skip the + test with msg as the reason. + """ + + attrs = ('var', 'value', 'msg') + + def setUpDecorator(self): + msg = ('Checking if %r value is not %r to skip test' % + (self.var, self.value)) + self.logger.debug(msg) + if not self.case.td.get(self.var) == self.value: + self.case.skipTest(self.msg) + +@registerDecorator +class skipIfNotInDataVar(OETestDecorator): + """ + Skip test if value is not in data store's variable. + """ + + attrs = ('var', 'value', 'msg') + def setUpDecorator(self): + msg = ('Checking if %r value is in %r to run ' + 'the test' % (self.var, self.value)) + self.logger.debug(msg) + if not self.value in self.case.td.get(self.var): + self.case.skipTest(self.msg) + +@registerDecorator class OETestDataDepends(OETestDecorator): attrs = ('td_depends',)
Signature · 1 line
2.1.4
PATCH 40/55 oeqa/core/context: Add option to select tests to run
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
This add the option to select what tests to run in the <module>[.<class>[.<test>]] format.
Currently it just support modules
--- meta/lib/oeqa/core/context.py | 6 ++++++ 1 file changed, 6 insertions(+)
meta/lib/oeqa/core/context.py +6 -0
@@ -157,6 +157,7 @@ class OETestContextExecutor(object): default_cases = [os.path.join(os.path.abspath(os.path.dirname(__file__)), 'cases/example')] default_test_data = os.path.join(default_cases[0], 'data.json') + default_tests = None def register_commands(self, logger, subparsers): self.parser = subparsers.add_parser(self.name, help=self.help,
@@ -167,6 +168,9 @@ class OETestContextExecutor(object): self.parser.add_argument('--output-log', action='store', default=self.default_output_log, help="results output log, default: %s" % self.default_output_log) + self.parser.add_argument('--run-tests', action='store', + default=self.default_tests, + help="tests to run in <module>[.<class>[.<name>]] format. Just works for modules now") if self.default_test_data: self.parser.add_argument('--test-data-file', action='store',
@@ -211,6 +215,8 @@ class OETestContextExecutor(object): else: self.tc_kwargs['init']['td'] = {} + self.tc_kwargs['load']['modules'] = args.run_tests.split() + self.module_paths = args.CASES_PATHS def run(self, logger, args):
Signature · 1 line
2.1.4
PATCH 41/55 oeqa/runtime/context: Add runtime option group and options for target type and server ip.
In reply to Aníbal Limón--- meta/lib/oeqa/runtime/context.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
meta/lib/oeqa/runtime/context.py +20 -2
@@ -44,17 +44,34 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): name = 'runtime' help = 'runtime test component' description = 'executes runtime tests over targets' + default_cases = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'cases') + default_data = None + + default_target_type = 'simpleremote' + default_server_ip = '192.168.7.1' default_target_ip = '192.168.7.2' def register_commands(self, logger, subparsers): super(OERuntimeTestContextExecutor, self).register_commands(logger, subparsers) - self.parser.add_argument('--target-ip', action='store', + + runtime_group = self.parser.add_argument_group('runtime options') + + runtime_group.add_argument('--target-type', action='store', + default=self.default_target_type, choices=['simpleremote', 'qemu'], + help="Target type of device under test, default: %s" \ + % self.default_target_type) + runtime_group.add_argument('--target-ip', action='store', default=self.default_target_ip, help="IP address of device under test, default: %s" \ % self.default_target_ip) - self.parser.add_argument('--packages-manifest', action='store', + runtime_group.add_argument('--server-ip', action='store', + default=self.default_target_ip, + help="IP address of device under test, default: %s" \ + % self.default_server_ip) + + runtime_group.add_argument('--packages-manifest', action='store', help="Package manifest of the image under test") def _process_args(self, logger, args):
@@ -63,6 +80,7 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): super(OERuntimeTestContextExecutor, self)._process_args(logger, args) target = OESSHTarget(args.target_ip) + self.tc_kwargs['init']['target'] = target packages_manifest = os.path.join(os.getcwd(), args.packages_manifest)
Signature · 1 line
2.1.4
PATCH 42/55 oeqa/runtime/context: Move helper functions for process args to executor
In reply to Aníbal Limón--- meta/lib/oeqa/runtime/context.py | 56 ++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 20 deletions(-)
meta/lib/oeqa/runtime/context.py +36 -20
@@ -12,10 +12,10 @@ class OERuntimeTestContext(OETestContext): runtime_files_dir = os.path.join( os.path.dirname(os.path.abspath(__file__)), "files") - def __init__(self, td, logger, target, packages_manifest): + def __init__(self, td, logger, target, image_packages): super(OERuntimeTestContext, self).__init__(td, logger) self.target = target - self.image_packages = self.readPackagesManifest(packages_manifest) + self.image_packages = image_packages self._set_target_cmds() def _set_target_cmds(self):
@@ -25,19 +25,6 @@ class OERuntimeTestContext(OETestContext): if 'procps' in self.image_packages: self.target_cmds['ps'] = self.target_cmds['ps'] + ' -ef' - def readPackagesManifest(self, manifest): - if not os.path.exists(manifest): - raise OSError("Couldn't find manifest file: %s" % manifest) - - image_packages = set() - with open(manifest, 'r') as f: - for line in f.readlines(): - line = line.strip() - if line and not line.startswith("#"): - image_packages.add(line.split()[0]) - - return image_packages - class OERuntimeTestContextExecutor(OETestContextExecutor): _context_class = OERuntimeTestContext
@@ -74,16 +61,45 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): runtime_group.add_argument('--packages-manifest', action='store', help="Package manifest of the image under test") + + @staticmethod + def getTarget(target_type, target_ip, server_ip): + target = None + + if target_type == 'simpleremote': + target = OESSHTarget(target_ip) + elif target_type == 'qemu': + raise NotImplementedError("target_type %s isn't implemented yet" % \ + target_type) + else: + raise TypeError("target_type %s isn't supported" % target_type) + + return target + + @staticmethod + def readPackagesManifest(manifest): + if not os.path.exists(manifest): + raise OSError("Manifest file not exists: %s" % manifest) + + image_packages = set() + with open(manifest, 'r') as f: + for line in f.readlines(): + line = line.strip() + if line and not line.startswith("#"): + image_packages.add(line.split()[0]) + + return image_packages + def _process_args(self, logger, args): if not args.packages_manifest: raise TypeError('Manifest file not provided') super(OERuntimeTestContextExecutor, self)._process_args(logger, args) - target = OESSHTarget(args.target_ip) - - self.tc_kwargs['init']['target'] = target - packages_manifest = os.path.join(os.getcwd(), args.packages_manifest) - self.tc_kwargs['init']['packages_manifest'] = packages_manifest + self.tc_kwargs['init']['target'] = \ + OERuntimeTestContextExecutor.getTarget(args.target_type) + self.tc_kwargs['init']['image_packages'] = \ + OERuntimeTestContextExecutor.readPackagesManifest( + args.packages_manifest) _executor_class = OERuntimeTestContextExecutor
Signature · 1 line
2.1.4
PATCH 43/55 oeqa/utils/dump: Move get_host_dumper to OERuntimeTestContextExecutor class
In reply to Aníbal LimónTo avoid getVar calls inside a utils module, also moves get_host_dumper import inside testexport isn't needed.
[YOCTO #10231]
--- meta/classes/testexport.bbclass | 1 - meta/classes/testimage.bbclass | 5 +++-- meta/lib/oeqa/runtime/context.py | 18 +++++++++++++++++- meta/lib/oeqa/utils/dump.py | 11 ++--------- 4 files changed, 22 insertions(+), 13 deletions(-)
meta/classes/testexport.bbclass +0 -1
@@ -163,7 +163,6 @@ def exportTests(d,tc): def testexport_main(d): from oeqa.oetest import ExportTestContext from oeqa.targetcontrol import get_target_controller - from oeqa.utils.dump import get_host_dumper test_create_extract_dirs(d) export_dir = d.getVar("TEST_EXPORT_DIR")
meta/classes/testimage.bbclass +3 -2
@@ -128,8 +128,8 @@ def testimage_main(d): import signal from oeqa.oetest import ImageTestContext from oeqa.targetcontrol import get_target_controller - from oeqa.utils.dump import get_host_dumper from bb.utils import export_proxies + from oeqa.utils.dump import HostDumper pn = d.getVar("PN") bb.utils.mkdirhier(d.getVar("TEST_LOG_DIR"))
@@ -139,7 +139,8 @@ def testimage_main(d): export_proxies(d) # we need the host dumper in test context - host_dumper = get_host_dumper(d) + host_dumper = HostDumper(d.getVar("testimage_dump_host", True), + d.getVar("TESTIMAGE_DUMP_DIR", True)) # the robot dance target = get_target_controller(d)
meta/lib/oeqa/runtime/context.py +17 -1
@@ -5,6 +5,8 @@ import os from oeqa.core.context import OETestContext, OETestContextExecutor from oeqa.core.target.ssh import OESSHTarget +from oeqa.utils.dump import HostDumper + from oeqa.runtime.loader import OERuntimeTestLoader class OERuntimeTestContext(OETestContext):
@@ -12,10 +14,11 @@ class OERuntimeTestContext(OETestContext): runtime_files_dir = os.path.join( os.path.dirname(os.path.abspath(__file__)), "files") - def __init__(self, td, logger, target, image_packages): + def __init__(self, td, logger, target, host_dumper, image_packages): super(OERuntimeTestContext, self).__init__(td, logger) self.target = target self.image_packages = image_packages + self.host_dumper = host_dumper self._set_target_cmds() def _set_target_cmds(self):
@@ -39,6 +42,7 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): default_target_type = 'simpleremote' default_server_ip = '192.168.7.1' default_target_ip = '192.168.7.2' + default_host_dumper_dir = '/tmp/oe-saved-tests' def register_commands(self, logger, subparsers): super(OERuntimeTestContextExecutor, self).register_commands(logger, subparsers)
@@ -58,6 +62,11 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): help="IP address of device under test, default: %s" \ % self.default_server_ip) + runtime_group.add_argument('--host-dumper-dir', action='store', + default=self.default_host_dumper_dir, + help="Directory where host status is dumped, if tests fails, default: %s" \ + % self.default_host_dumper_dir) + runtime_group.add_argument('--packages-manifest', action='store', help="Package manifest of the image under test")
@@ -90,6 +99,10 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): return image_packages + @staticmethod + def getHostDumper(cmds, directory): + return HostDumper(cmds, directory) + def _process_args(self, logger, args): if not args.packages_manifest: raise TypeError('Manifest file not provided')
@@ -98,6 +111,9 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): self.tc_kwargs['init']['target'] = \ OERuntimeTestContextExecutor.getTarget(args.target_type) + self.tc_kwargs['init']['host_dumper'] = \ + OERuntimeTestContextExecutor.getHostDumper(None, + args.host_dumper_dir) self.tc_kwargs['init']['image_packages'] = \ OERuntimeTestContextExecutor.readPackagesManifest( args.packages_manifest)
meta/lib/oeqa/utils/dump.py +2 -9
@@ -5,12 +5,6 @@ import datetime import itertools from .commands import runCmd -def get_host_dumper(d): - cmds = d.getVar("testimage_dump_host") - parent_dir = d.getVar("TESTIMAGE_DUMP_DIR") - return HostDumper(cmds, parent_dir) - - class BaseDumper(object): """ Base class to dump commands from host/target """
@@ -77,13 +71,12 @@ class HostDumper(BaseDumper): result = runCmd(cmd, ignore_status=True) self._write_dump(cmd.split()[0], result.output) - class TargetDumper(BaseDumper): """ Class to get dumps from target, it only works with QemuRunner """ - def __init__(self, cmds, parent_dir, qemurunner): + def __init__(self, cmds, parent_dir, runner): super(TargetDumper, self).__init__(cmds, parent_dir) - self.runner = qemurunner + self.runner = runner def dump_target(self, dump_dir=""): if dump_dir:
Signature · 1 line
2.1.4
PATCH 44/55 oeqa/runtime/context.py: Prepare for qemu
In reply to Aníbal LimónThis commit will prepare context to use qemu and not just simpleremote.
--- meta/lib/oeqa/runtime/context.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
meta/lib/oeqa/runtime/context.py +13 -5
@@ -5,6 +5,7 @@ import os from oeqa.core.context import OETestContext, OETestContextExecutor from oeqa.core.target.ssh import OESSHTarget +from oeqa.core.target.qemu import OEQemuTarget from oeqa.utils.dump import HostDumper from oeqa.runtime.loader import OERuntimeTestLoader
@@ -16,6 +17,7 @@ class OERuntimeTestContext(OETestContext): def __init__(self, td, logger, target, host_dumper, image_packages): super(OERuntimeTestContext, self).__init__(td, logger) + self.target = target self.image_packages = image_packages self.host_dumper = host_dumper
@@ -70,17 +72,19 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): runtime_group.add_argument('--packages-manifest', action='store', help="Package manifest of the image under test") + runtime_group.add_argument('--qemu-boot', action='store', + help="Qemu boot configuration, only needed when target_type is QEMU.") @staticmethod - def getTarget(target_type, target_ip, server_ip): + def getTarget(target_type, target_ip, server_ip, **kwargs): target = None if target_type == 'simpleremote': - target = OESSHTarget(target_ip) + target = OESSHTarget(target_ip, server_ip, kwargs) elif target_type == 'qemu': - raise NotImplementedError("target_type %s isn't implemented yet" % \ - target_type) + target = OEQemuTarget(target_ip, server_ip, kwargs) else: + # TODO: Implement custom target module loading raise TypeError("target_type %s isn't supported" % target_type) return target
@@ -109,8 +113,12 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): super(OERuntimeTestContextExecutor, self)._process_args(logger, args) + target_kwargs = {} + target_kwargs['qemuboot'] = args.qemu_boot + self.tc_kwargs['init']['target'] = \ - OERuntimeTestContextExecutor.getTarget(args.target_type) + OERuntimeTestContextExecutor.getTarget(args.target_type, + args.target_ip, args.server_ip, **target_kwargs) self.tc_kwargs['init']['host_dumper'] = \ OERuntimeTestContextExecutor.getHostDumper(None, args.host_dumper_dir)
Signature · 1 line
2.1.4
PATCH 45/55 oeqa/runtime/context.py: Add logger to getTarget
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
Current targets (ssh and qemu) require a logger in their constructors, so in order to get a new target we need to provide the logger.
[YOCTO #10686]
--- meta/lib/oeqa/runtime/context.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
meta/lib/oeqa/runtime/context.py +3 -3
@@ -76,13 +76,13 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): help="Qemu boot configuration, only needed when target_type is QEMU.") @staticmethod - def getTarget(target_type, target_ip, server_ip, **kwargs): + def getTarget(target_type, logger, target_ip, server_ip, **kwargs): target = None if target_type == 'simpleremote': - target = OESSHTarget(target_ip, server_ip, kwargs) + target = OESSHTarget(logger, target_ip, server_ip, **kwargs) elif target_type == 'qemu': - target = OEQemuTarget(target_ip, server_ip, kwargs) + target = OEQemuTarget(logger, target_ip, server_ip, **kwargs) else: # TODO: Implement custom target module loading raise TypeError("target_type %s isn't supported" % target_type)
Signature · 1 line
2.1.4
PATCH 46/55 core/target/qemu.py Adds qemu target
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
This adds qemu target to be used in testimage.
It uses the current QemuRunner class in order
to boot and control qemu.
[YOCTO #10231]
--- meta/lib/oeqa/core/target/qemu.py | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 meta/lib/oeqa/core/target/qemu.py
meta/lib/oeqa/core/target/qemu.py new file +45 -0
@@ -0,0 +1,45 @@ +# Copyright (C) 2016 Intel Corporation +# Released under the MIT license (see COPYING.MIT) + +import os +import sys +import signal +import time + +from .ssh import OESSHTarget +from oeqa.utils.qemurunner import QemuRunner + +supported_fstypes = ['ext3', 'ext4', 'cpio.gz', 'wic'] + +class OEQemuTarget(OESSHTarget): + def __init__(self, logger, ip, server_ip, timeout=300, user='root', + port=None, machine='', rootfs='', kernel='', kvm=False, + dump_dir='', dump_host_cmds='', display='', bootlog='', + tmpdir='', dir_image='', boottime=60): + + super(OEQemuTarget, self).__init__(logger, ip, server_ip, timeout, + user, port) + + self.ip = ip + self.server_ip = server_ip + self.machine = machine + self.rootfs = rootfs + self.kernel = kernel + self.kvm = kvm + + self.runner = QemuRunner(machine=machine, rootfs=rootfs, tmpdir=tmpdir, + deploy_dir_image=dir_image, display=display, + logfile=bootlog, boottime=boottime, + use_kvm=kvm, dump_dir=dump_dir, + dump_host_cmds=dump_host_cmds) + + def start(self, params=None, extra_bootparams=None): + if self.runner.start(params, extra_bootparams=extra_bootparams): + self.ip = self.runner.ip + self.server_ip = self.runner.server_ip + else: + self.stop() + raise RuntimeError("FAILED to start qemu - check the task log and the boot log") + + def stop(self): + self.runner.stop()
Signature · 1 line
2.1.4
PATCH 47/55 testimage.bbclass: Migrate class to use new runtime framework
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
This migrates testimage class to use the new framework. Most of the code added here is to get rid off the data store dependency.
[YOCTO #10234]
--- meta/classes/testimage.bbclass | 186 +++++++++++++++++++++++++++++++---------- 1 file changed, 144 insertions(+), 42 deletions(-)
meta/classes/testimage.bbclass +144 -42
@@ -77,6 +77,7 @@ TESTIMAGEDEPENDS_qemuall += "${@bb.utils.contains('IMAGE_PKGTYPE', 'rpm', 'creat TESTIMAGEDEPENDS += "${@bb.utils.contains('IMAGE_PKGTYPE', 'rpm', 'python-smartpm-native:do_populate_sysroot', '', d)}" TESTIMAGEDEPENDS += "${@bb.utils.contains('IMAGE_PKGTYPE', 'ipk', 'opkg-utils-native:do_populate_sysroot', '', d)}" TESTIMAGEDEPENDS += "${@bb.utils.contains('IMAGE_PKGTYPE', 'deb', 'apt-native:do_populate_sysroot', '', d)}" +TESTIMAGEDEPENDS += "${@bb.utils.contains('IMAGE_PKGTYPE', 'rpm', 'python-smartpm-native:do_populate_sysroot', '', d)}" TESTIMAGELOCK = "${TMPDIR}/testimage.lock"
@@ -112,6 +113,9 @@ testimage_dump_host () { } python do_testimage() { + + testimage_sanity(d) + testimage_main(d) }
@@ -120,67 +124,165 @@ do_testimage[nostamp] = "1" do_testimage[depends] += "${TESTIMAGEDEPENDS}" do_testimage[lockfiles] += "${TESTIMAGELOCK}" +def testimage_sanity(d): + if (d.getVar('TEST_TARGET') == 'simpleremote' + and (not d.getVar('TEST_TARGET_IP') + or not d.getVar('TEST_SERVER_IP'))): + bb.fatal('When TEST_TARGET is set to "simpleremote" ' + 'TEST_TARGET_IP and TEST_SERVER_IP are needed too.') + def testimage_main(d): - import unittest import os - import oeqa.runtime - import time import signal - from oeqa.oetest import ImageTestContext - from oeqa.targetcontrol import get_target_controller - from bb.utils import export_proxies - from oeqa.utils.dump import HostDumper + import json + import sys + import logging + import time + from bb.utils import export_proxies + from oeqa.runtime.context import OERuntimeTestContext + from oeqa.runtime.context import OERuntimeTestContextExecutor + from oeqa.core.target.qemu import supported_fstypes + from oeqa.utils import make_logger_bitbake_compatible + + def sigterm_exception(signum, stackframe): + """ + Catch SIGTERM from worker in order to stop qemu. + """ + raise RuntimeError + + logger = make_logger_bitbake_compatible(logging.getLogger("BitBake")) pn = d.getVar("PN") + bb.utils.mkdirhier(d.getVar("TEST_LOG_DIR")) - test_create_extract_dirs(d) + #test_create_extract_dirs(d) + + image_name = ("%s/%s" % (d.getVar('DEPLOY_DIR_IMAGE'), + d.getVar('IMAGE_LINK_NAME'))) + + tdname = "%s.testdata.json" % image_name + td = json.load(open(tdname, "r")) + + image_manifest = "%s.manifest" % image_name + image_packages = OERuntimeTestContextExecutor.readPackagesManifest(image_manifest) + + # Get machine + machine = d.getVar("MACHINE") + + # Get rootfs + fstypes = [fs for fs in d.getVar('IMAGE_FSTYPES').split(' ') + if fs in supported_fstypes] + if not fstypes: + bb.fatal('Unsupported image type built. Add a comptible image to ' + 'IMAGE_FSTYPES. Supported types: %s' % + ', '.join(supported_fstypes)) + rootfs = '%s.%s' % (image_name, fstypes[0]) + + # Get tmpdir (not really used, just for compatibility) + tmpdir = d.getVar("TMPDIR") + + # Get deploy_dir_image (not really used, just for compatibility) + dir_image = d.getVar("DEPLOY_DIR_IMAGE") + + # Get bootlog + bootlog = os.path.join(d.getVar("TEST_LOG_DIR"), + 'qemu_boot_log.%s' % d.getVar('DATETIME')) + + # Get display + display = d.getVar("BB_ORIGENV").getVar("DISPLAY") + + # Get kernel + kernel_name = ('%s-%s.bin' % (d.getVar("KERNEL_IMAGETYPE"), machine)) + kernel = os.path.join(d.getVar("DEPLOY_DIR_IMAGE"), kernel_name) + + # Get boottime + boottime = int(d.getVar("TEST_QEMUBOOT_TIMEOUT")) + + # Get use_kvm + qemu_use_kvm = d.getVar("QEMU_USE_KVM") + if qemu_use_kvm and qemu_use_kvm == 'True' and 'x86' in machine: + kvm = True + else: + kvm = False + + # TODO: We use the current implementatin of qemu runner because of + # time constrains, qemu runner really needs a refactor too. + target_kwargs = { 'machine' : machine, + 'rootfs' : rootfs, + 'tmpdir' : tmpdir, + 'dir_image' : dir_image, + 'display' : display, + 'kernel' : kernel, + 'boottime' : boottime, + 'bootlog' : bootlog, + 'kvm' : kvm, + } # runtime use network for download projects for build export_proxies(d) # we need the host dumper in test context - host_dumper = HostDumper(d.getVar("testimage_dump_host", True), - d.getVar("TESTIMAGE_DUMP_DIR", True)) + host_dumper = OERuntimeTestContextExecutor.getHostDumper( + d.getVar("testimage_dump_host"), + d.getVar("TESTIMAGE_DUMP_DIR")) # the robot dance - target = get_target_controller(d) + target = OERuntimeTestContextExecutor.getTarget( + d.getVar("TEST_TARGET"), None, d.getVar("TEST_TARGET_IP"), + d.getVar("TEST_SERVER_IP"), **target_kwargs) # test context - tc = ImageTestContext(d, target, host_dumper) + tc = OERuntimeTestContext(td, logger, target, host_dumper, image_packages) - # this is a dummy load of tests - # we are doing that to find compile errors in the tests themselves - # before booting the image - try: - tc.loadTests() - except Exception as e: - import traceback - bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) + # Load tests before starting the target + test_paths = get_runtime_paths(d) + test_modules = d.getVar('TEST_SUITES') + tc.loadTests(test_paths, modules=test_modules) + + bootparams = None + if d.getVar('VIRTUAL-RUNTIME_init_manager', '') == 'systemd': + bootparams = 'systemd.log_level=debug systemd.log_target=console' - tc.extract_packages() - target.deploy() + results = None + orig_sigterm_handler = signal.signal(signal.SIGTERM, sigterm_exception) try: - bootparams = None - if d.getVar('VIRTUAL-RUNTIME_init_manager', '') == 'systemd': - bootparams = 'systemd.log_level=debug systemd.log_target=console' - target.start(extra_bootparams=bootparams) - starttime = time.time() - result = tc.runTests() - stoptime = time.time() - if result.wasSuccessful(): - bb.plain("%s - Ran %d test%s in %.3fs" % (pn, result.testsRun, result.testsRun != 1 and "s" or "", stoptime - starttime)) - msg = "%s - OK - All required tests passed" % pn - skipped = len(result.skipped) - if skipped: - msg += " (skipped=%d)" % skipped - bb.plain(msg) + # We need to check if runqemu ends unexpectedly + # or if the worker send us a SIGTERM + tc.target.start(extra_bootparams=bootparams) + results = tc.runTests() + except (RuntimeError, BlockingIOError) as err: + if isinstance(err, RuntimeError): + bb.error('testimage received SIGTERM, shutting down...') else: - bb.fatal("%s - FAILED - check the task log and the ssh log" % pn) - except BlockingIOError as err: - bb.error('runqemu failed, shutting down...') + bb.error('runqemu failed, shutting down...') + if results: + results.stop() + results = None finally: - signal.signal(signal.SIGTERM, tc.origsigtermhandler) - target.stop() + signal.signal(signal.SIGTERM, orig_sigterm_handler) + tc.target.stop() + + # Show results (if we have them) + if not results: + bb.fatal('%s - FAILED - tests were interrupted during execution' % pn) + tc.logSummary(results, pn) + tc.logDetails() + if not results.wasSuccessful(): + bb.fatal('%s - FAILED - check the task log and the ssh log' % pn) + +def get_runtime_paths(d): + """ + Returns a list of paths where runtime test must reside. + + Runtime tests are expected in <LAYER_DIR>/lib/oeqa/runtime/cases/ + """ + paths = [] + + for layer in d.getVar('BBLAYERS').split(): + path = os.path.join(layer, 'lib/oeqa/runtime/cases') + if os.path.isdir(path): + paths.append(path) + return paths def test_create_extract_dirs(d): install_path = d.getVar("TEST_INSTALL_TMP_DIR")
@@ -193,6 +295,6 @@ def test_create_extract_dirs(d): bb.utils.mkdirhier(extracted_path) -testimage_main[vardepsexclude] =+ "BB_ORIGENV" +testimage_main[vardepsexclude] += "BB_ORIGENV DATETIME" inherit testsdk
Signature · 1 line
2.1.4
PATCH 48/55 oeqa/runtime/cases: Migrate runtime tests.
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
This migrates current runtime test suite to be used with the new framework.
[YOCTO #10234]
---
.../{runtime_cases => runtime/cases}/_ptest.py | 0
.../{runtime_cases => runtime/cases}/_qemutiny.py | 0
meta/lib/oeqa/runtime/cases/buildcvs.py | 35 ++++
meta/lib/oeqa/runtime/cases/buildgalculator.py | 31 ++++
meta/lib/oeqa/runtime/cases/buildiptables.py | 39 +++++
meta/lib/oeqa/runtime/cases/connman.py | 30 ++++
meta/lib/oeqa/runtime/cases/date.py | 38 +++++
meta/lib/oeqa/runtime/cases/df.py | 13 ++
meta/lib/oeqa/runtime/cases/gcc.py | 76 +++++++++
meta/lib/oeqa/runtime/cases/kernelmodule.py | 40 +++++
meta/lib/oeqa/runtime/cases/ldd.py | 25 +++
meta/lib/oeqa/runtime/cases/logrotate.py | 42 +++++
meta/lib/oeqa/runtime/cases/multilib.py | 41 +++++
meta/lib/oeqa/runtime/cases/pam.py | 33 ++++
.../{runtime_cases => runtime/cases}/parselogs.py | 187 ++++++++++++---------
meta/lib/oeqa/runtime/cases/perl.py | 37 ++++
meta/lib/oeqa/runtime/cases/ping.py | 24 +++
meta/lib/oeqa/runtime/cases/python.py | 43 +++++
meta/lib/oeqa/runtime/cases/rpm.py | 141 ++++++++++++++++
meta/lib/oeqa/runtime/cases/scanelf.py | 26 +++
meta/lib/oeqa/runtime/cases/scp.py | 33 ++++
meta/lib/oeqa/runtime/cases/skeletoninit.py | 33 ++++
.../oeqa/{runtime_cases => runtime/cases}/smart.py | 0
meta/lib/oeqa/runtime/cases/ssh.py | 15 ++
meta/lib/oeqa/runtime/cases/syslog.py | 57 +++++++
.../{runtime_cases => runtime/cases}/systemd.py | 151 +++++++++--------
meta/lib/oeqa/runtime/cases/x32lib.py | 19 +++
meta/lib/oeqa/runtime/cases/xorg.py | 17 ++
meta/lib/oeqa/runtime_cases/buildcvs.py | 32 ----
meta/lib/oeqa/runtime_cases/buildgalculator.py | 26 ---
meta/lib/oeqa/runtime_cases/buildiptables.py | 33 ----
meta/lib/oeqa/runtime_cases/connman.py | 31 ----
meta/lib/oeqa/runtime_cases/date.py | 31 ----
meta/lib/oeqa/runtime_cases/df.py | 12 --
meta/lib/oeqa/runtime_cases/gcc.py | 47 ------
meta/lib/oeqa/runtime_cases/kernelmodule.py | 34 ----
meta/lib/oeqa/runtime_cases/ldd.py | 21 ---
meta/lib/oeqa/runtime_cases/logrotate.py | 30 ----
meta/lib/oeqa/runtime_cases/multilib.py | 42 -----
meta/lib/oeqa/runtime_cases/pam.py | 25 ---
meta/lib/oeqa/runtime_cases/perl.py | 30 ----
meta/lib/oeqa/runtime_cases/ping.py | 22 ---
meta/lib/oeqa/runtime_cases/python.py | 35 ----
meta/lib/oeqa/runtime_cases/rpm.py | 120 -------------
meta/lib/oeqa/runtime_cases/scanelf.py | 28 ---
meta/lib/oeqa/runtime_cases/scp.py | 22 ---
meta/lib/oeqa/runtime_cases/skeletoninit.py | 29 ----
meta/lib/oeqa/runtime_cases/ssh.py | 19 ---
meta/lib/oeqa/runtime_cases/syslog.py | 52 ------
meta/lib/oeqa/runtime_cases/x32lib.py | 18 --
meta/lib/oeqa/runtime_cases/xorg.py | 16 --
51 files changed, 1075 insertions(+), 906 deletions(-)
rename meta/lib/oeqa/{runtime_cases => runtime/cases}/_ptest.py (100%)
rename meta/lib/oeqa/{runtime_cases => runtime/cases}/_qemutiny.py (100%)
create mode 100644 meta/lib/oeqa/runtime/cases/buildcvs.py
create mode 100644 meta/lib/oeqa/runtime/cases/buildgalculator.py
create mode 100644 meta/lib/oeqa/runtime/cases/buildiptables.py
create mode 100644 meta/lib/oeqa/runtime/cases/connman.py
create mode 100644 meta/lib/oeqa/runtime/cases/date.py
create mode 100644 meta/lib/oeqa/runtime/cases/df.py
create mode 100644 meta/lib/oeqa/runtime/cases/gcc.py
create mode 100644 meta/lib/oeqa/runtime/cases/kernelmodule.py
create mode 100644 meta/lib/oeqa/runtime/cases/ldd.py
create mode 100644 meta/lib/oeqa/runtime/cases/logrotate.py
create mode 100644 meta/lib/oeqa/runtime/cases/multilib.py
create mode 100644 meta/lib/oeqa/runtime/cases/pam.py
rename meta/lib/oeqa/{runtime_cases => runtime/cases}/parselogs.py (64%)
create mode 100644 meta/lib/oeqa/runtime/cases/perl.py
create mode 100644 meta/lib/oeqa/runtime/cases/ping.py
create mode 100644 meta/lib/oeqa/runtime/cases/python.py
create mode 100644 meta/lib/oeqa/runtime/cases/rpm.py
create mode 100644 meta/lib/oeqa/runtime/cases/scanelf.py
create mode 100644 meta/lib/oeqa/runtime/cases/scp.py
create mode 100644 meta/lib/oeqa/runtime/cases/skeletoninit.py
rename meta/lib/oeqa/{runtime_cases => runtime/cases}/smart.py (100%)
create mode 100644 meta/lib/oeqa/runtime/cases/ssh.py
create mode 100644 meta/lib/oeqa/runtime/cases/syslog.py
rename meta/lib/oeqa/{runtime_cases => runtime/cases}/systemd.py (51%)
create mode 100644 meta/lib/oeqa/runtime/cases/x32lib.py
create mode 100644 meta/lib/oeqa/runtime/cases/xorg.py
delete mode 100644 meta/lib/oeqa/runtime_cases/buildcvs.py
delete mode 100644 meta/lib/oeqa/runtime_cases/buildgalculator.py
delete mode 100644 meta/lib/oeqa/runtime_cases/buildiptables.py
delete mode 100644 meta/lib/oeqa/runtime_cases/connman.py
delete mode 100644 meta/lib/oeqa/runtime_cases/date.py
delete mode 100644 meta/lib/oeqa/runtime_cases/df.py
delete mode 100644 meta/lib/oeqa/runtime_cases/gcc.py
delete mode 100644 meta/lib/oeqa/runtime_cases/kernelmodule.py
delete mode 100644 meta/lib/oeqa/runtime_cases/ldd.py
delete mode 100644 meta/lib/oeqa/runtime_cases/logrotate.py
delete mode 100644 meta/lib/oeqa/runtime_cases/multilib.py
delete mode 100644 meta/lib/oeqa/runtime_cases/pam.py
delete mode 100644 meta/lib/oeqa/runtime_cases/perl.py
delete mode 100644 meta/lib/oeqa/runtime_cases/ping.py
delete mode 100644 meta/lib/oeqa/runtime_cases/python.py
delete mode 100644 meta/lib/oeqa/runtime_cases/rpm.py
delete mode 100644 meta/lib/oeqa/runtime_cases/scanelf.py
delete mode 100644 meta/lib/oeqa/runtime_cases/scp.py
delete mode 100644 meta/lib/oeqa/runtime_cases/skeletoninit.py
delete mode 100644 meta/lib/oeqa/runtime_cases/ssh.py
delete mode 100644 meta/lib/oeqa/runtime_cases/syslog.py
delete mode 100644 meta/lib/oeqa/runtime_cases/x32lib.py
delete mode 100644 meta/lib/oeqa/runtime_cases/xorg.pymeta/lib/oeqa/runtime/cases/_ptest.py renamed from meta/lib/oeqa/runtime_cases/_ptest.py +0 -0
meta/lib/oeqa/runtime/cases/_qemutiny.py renamed from meta/lib/oeqa/runtime_cases/_qemutiny.py +0 -0
meta/lib/oeqa/runtime/cases/buildcvs.py new file +35 -0
@@ -0,0 +1,35 @@ +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.core.decorator.oeid import OETestID +from oeqa.core.decorator.data import skipIfNotFeature + +from oeqa.runtime.utils.targetbuildproject import TargetBuildProject + +class BuildCvsTest(OERuntimeTestCase): + + @classmethod + def setUpClass(cls): + uri = 'http://ftp.gnu.org/non-gnu/cvs/source/feature/1.12.13' + uri = '%s/cvs-1.12.13.tar.bz2' % uri + cls.project = TargetBuildProject(cls.tc.target, + uri, + dl_dir = cls.tc.td['DL_DIR']) + cls.project.download_archive() + + @classmethod + def tearDownClass(cls): + cls.project.clean() + + @OETestID(205) + @skipIfNotFeature('tools-sdk', + 'Test requires tools-sdk to be in IMAGE_FEATURES') + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_cvs(self): + self.assertEqual(self.project.run_configure(), 0, + msg="Running configure failed") + + self.assertEqual(self.project.run_make(), 0, + msg="Running make failed") + + self.assertEqual(self.project.run_install(), 0, + msg="Running make install failed")
meta/lib/oeqa/runtime/cases/buildgalculator.py new file +31 -0
@@ -0,0 +1,31 @@ +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.core.decorator.oeid import OETestID +from oeqa.core.decorator.data import skipIfNotFeature + +from oeqa.runtime.utils.targetbuildproject import TargetBuildProject + +class GalculatorTest(OERuntimeTestCase): + + @classmethod + def setUpClass(cls): + uri = 'http://galculator.mnim.org/downloads/galculator-2.1.4.tar.bz2' + cls.project = TargetBuildProject(cls.tc.target, + uri, + dl_dir = cls.tc.td['DL_DIR']) + cls.project.download_archive() + + @classmethod + def tearDownClass(cls): + cls.project.clean() + + @OETestID(1526) + @skipIfNotFeature('tools-sdk', + 'Test requires tools-sdk to be in IMAGE_FEATURES') + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_galculator(self): + self.assertEqual(self.project.run_configure(), 0, + msg="Running configure failed") + + self.assertEqual(self.project.run_make(), 0, + msg="Running make failed")
meta/lib/oeqa/runtime/cases/buildiptables.py new file +39 -0
@@ -0,0 +1,39 @@ +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.core.decorator.oeid import OETestID +from oeqa.core.decorator.data import skipIfNotFeature + +from oeqa.runtime.utils.targetbuildproject import TargetBuildProject + +class BuildIptablesTest(OERuntimeTestCase): + + @classmethod + def setUpClass(cls): + uri = 'http://downloads.yoctoproject.org/mirror/sources' + uri = '%s/iptables-1.4.13.tar.bz2' % uri + cls.project = TargetBuildProject(cls.tc.target, + uri, + dl_dir = cls.tc.td['DL_DIR']) + cls.project.download_archive() + + @classmethod + def tearDownClass(cls): + cls.project.clean() + + @OETestID(206) + @skipIfNotFeature('tools-sdk', + 'Test requires tools-sdk to be in IMAGE_FEATURES') + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_iptables(self): + self.assertEqual(self.project.run_configure(), 0, + msg="Running configure failed") + + self.assertEqual(self.project.run_make(), 0, + msg="Running make failed") + + self.assertEqual(self.project.run_install(), 0, + msg="Running make install failed") + + @classmethod + def tearDownClass(self): + self.project.clean()
meta/lib/oeqa/runtime/cases/connman.py new file +30 -0
@@ -0,0 +1,30 @@ +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.core.decorator.oeid import OETestID +from oeqa.runtime.decorator.package import OEHasPackage + +class ConnmanTest(OERuntimeTestCase): + + def service_status(self, service): + if oeRuntimeTest.hasFeature("systemd"): + (_, output) = self.target.run('systemctl status -l %s' % service) + return output + else: + return "Unable to get status or logs for %s" % service + + @OETestID(961) + @OETestDepends(['ssh.SSHTest.test_ssh']) + @OEHasPackage(["connman"]) + def test_connmand_help(self): + (status, output) = self.target.run('/usr/sbin/connmand --help') + msg = 'Failed to get connman help. Output: %s' % output + self.assertEqual(status, 0, msg=msg) + + @OETestID(221) + @OETestDepends(['connman.ConnmanTest.test_connmand_help']) + def test_connmand_running(self): + cmd = '%s | grep [c]onnmand' % self.tc.target_cmds['ps'] + (status, output) = self.target.run(cmd) + if status != 0: + self.logger.info(self.service_status("connman")) + self.fail("No connmand process running")
meta/lib/oeqa/runtime/cases/date.py new file +38 -0
@@ -0,0 +1,38 @@ +import re + +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.core.decorator.oeid import OETestID + +class DateTest(OERuntimeTestCase): + + def setUp(self): + if self.tc.td.get('VIRTUAL-RUNTIME_init_manager') == 'systemd': + self.logger.debug('Stopping systemd-timesyncd daemon') + self.target.run('systemctl stop systemd-timesyncd') + + def tearDown(self): + if self.tc.td.get('VIRTUAL-RUNTIME_init_manager') == 'systemd': + self.logger.debug('Starting systemd-timesyncd daemon') + self.target.run('systemctl start systemd-timesyncd') + + @OETestID(211) + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_date(self): + (status, output) = self.target.run('date +"%Y-%m-%d %T"') + msg = 'Failed to get initial date, output: %s' % output + self.assertEqual(status, 0, msg=msg) + oldDate = output + + sampleDate = '"2016-08-09 10:00:00"' + (status, output) = self.target.run("date -s %s" % sampleDate) + self.assertEqual(status, 0, msg='Date set failed, output: %s' % output) + + (status, output) = self.target.run("date -R") + p = re.match('Tue, 09 Aug 2016 10:00:.. \+0000', output) + msg = 'The date was not set correctly, output: %s' % output + self.assertTrue(p, msg=msg) + + (status, output) = self.target.run('date -s "%s"' % oldDate) + msg = 'Failed to reset date, output: %s' % output + self.assertEqual(status, 0, msg=msg)
meta/lib/oeqa/runtime/cases/df.py new file +13 -0
@@ -0,0 +1,13 @@ +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.core.decorator.oeid import OETestID + +class DfTest(OERuntimeTestCase): + + @OETestID(234) + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_df(self): + cmd = "df / | sed -n '2p' | awk '{print $4}'" + (status,output) = self.target.run(cmd) + msg = 'Not enough space on image. Current size is %s' % output + self.assertTrue(int(output)>5120, msg=msg)
meta/lib/oeqa/runtime/cases/gcc.py new file +76 -0
76 lines not on this page · raw message
meta/lib/oeqa/runtime/cases/kernelmodule.py new file +40 -0
@@ -0,0 +1,40 @@ +import os + +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.core.decorator.oeid import OETestID +from oeqa.core.decorator.data import skipIfNotFeature + +class KernelModuleTest(OERuntimeTestCase): + + @classmethod + def setUpClass(cls): + src = os.path.join(cls.tc.runtime_files_dir, 'hellomod.c') + dst = '/tmp/hellomod.c' + cls.tc.target.copyTo(src, dst) + + src = os.path.join(cls.tc.runtime_files_dir, 'hellomod_makefile') + dst = '/tmp/Makefile' + cls.tc.target.copyTo(src, dst) + + @classmethod + def tearDownClass(cls): + files = '/tmp/Makefile /tmp/hellomod.c' + cls.tc.target.run('rm %s' % files) + + @OETestID(1541) + @skipIfNotFeature('tools-sdk', + 'Test requires tools-sdk to be in IMAGE_FEATURES') + @OETestDepends(['gcc.GccCompileTest.test_gcc_compile']) + def test_kernel_module(self): + cmds = [ + 'cd /usr/src/kernel && make scripts', + 'cd /tmp && make', + 'cd /tmp && insmod hellomod.ko', + 'lsmod | grep hellomod', + 'dmesg | grep Hello', + 'rmmod hellomod', 'dmesg | grep "Cleaning up hellomod"' + ] + for cmd in cmds: + status, output = self.target.run(cmd, 900) + self.assertEqual(status, 0, msg='\n'.join([cmd, output]))
meta/lib/oeqa/runtime/cases/ldd.py new file +25 -0
@@ -0,0 +1,25 @@ +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.core.decorator.oeid import OETestID +from oeqa.core.decorator.data import skipIfNotFeature + +class LddTest(OERuntimeTestCase): + + @OETestID(962) + @skipIfNotFeature('tools-sdk', + 'Test requires tools-sdk to be in IMAGE_FEATURES') + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_ldd_exists(self): + status, output = self.target.run('which ldd') + msg = 'ldd does not exist in PATH: which ldd: %s' % output + self.assertEqual(status, 0, msg=msg) + + @OETestID(239) + @OETestDepends(['ldd.LddTest.test_ldd_exists']) + def test_ldd_rtldlist_check(self): + cmd = ('for i in $(which ldd | xargs cat | grep "^RTLDLIST"| ' + 'cut -d\'=\' -f2|tr -d \'"\'); ' + 'do test -f $i && echo $i && break; done') + status, output = self.target.run(cmd) + msg = "ldd path not correct or RTLDLIST files don't exist." + self.assertEqual(status, 0, msg=msg)
meta/lib/oeqa/runtime/cases/logrotate.py new file +42 -0
42 lines not on this page · raw message
meta/lib/oeqa/runtime/cases/multilib.py new file +41 -0
41 lines not on this page · raw message
meta/lib/oeqa/runtime/cases/pam.py new file +33 -0
@@ -0,0 +1,33 @@ +# This test should cover https://bugzilla.yoctoproject.org/tr_show_case.cgi?case_id=287 testcase +# Note that the image under test must have "pam" in DISTRO_FEATURES + +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.core.decorator.oeid import OETestID +from oeqa.core.decorator.data import skipIfNotFeature + +class PamBasicTest(OERuntimeTestCase): + + @OETestID(1543) + @skipIfNotFeature('pam', 'Test requires pam to be in DISTRO_FEATURES') + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_pam(self): + status, output = self.target.run('login --help') + msg = ('login command does not work as expected. ' + 'Status and output:%s and %s' % (status, output)) + self.assertEqual(status, 1, msg = msg) + + status, output = self.target.run('passwd --help') + msg = ('passwd command does not work as expected. ' + 'Status and output:%s and %s' % (status, output)) + self.assertEqual(status, 0, msg = msg) + + status, output = self.target.run('su --help') + msg = ('su command does not work as expected. ' + 'Status and output:%s and %s' % (status, output)) + self.assertEqual(status, 0, msg = msg) + + status, output = self.target.run('useradd --help') + msg = ('useradd command does not work as expected. ' + 'Status and output:%s and %s' % (status, output)) + self.assertEqual(status, 0, msg = msg)
meta/lib/oeqa/runtime/cases/parselogs.py renamed from meta/lib/oeqa/runtime_cases/parselogs.py +110 -77
275 lines not on this page · raw message
meta/lib/oeqa/runtime/cases/perl.py new file +37 -0
@@ -0,0 +1,37 @@ +import os + +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.core.decorator.oeid import OETestID +from oeqa.runtime.decorator.package import OEHasPackage + +class PerlTest(OERuntimeTestCase): + + @classmethod + def setUpClass(cls): + src = os.path.join(cls.tc.files_dir, 'test.pl') + dst = '/tmp/test.pl' + cls.tc.target.copyTo(src, dst) + + @classmethod + def tearDownClass(cls): + dst = '/tmp/test.pl' + cls.tc.target.run('rm %s' % dst) + + @OETestID(1141) + @OETestDepends(['ssh.SSHTest.test_ssh']) + @OEHasPackage(['perl']) + def test_perl_exists(self): + status, output = self.target.run('which perl') + msg = 'Perl binary not in PATH or not on target.' + self.assertEqual(status, 0, msg=msg) + + @OETestID(208) + @OETestDepends(['perl.PerlTest.test_perl_exists']) + def test_perl_works(self): + status, output = self.target.run('perl /tmp/test.pl') + msg = 'Exit status was not 0. Output: %s' % output + self.assertEqual(status, 0, msg=msg) + + msg = 'Incorrect output: %s' % output + self.assertEqual(output, "the value of a is 0.01", msg=msg)
meta/lib/oeqa/runtime/cases/ping.py new file +24 -0
@@ -0,0 +1,24 @@ +from subprocess import Popen, PIPE + +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.oeid import OETestID +from oeqa.core.decorator.oetimeout import OETimeout + +class PingTest(OERuntimeTestCase): + + @OETimeout(30) + @OETestID(964) + def test_ping(self): + output = '' + count = 0 + while count < 5: + cmd = 'ping -c 1 %s' % self.target.ip + proc = Popen(cmd, shell=True, stdout=PIPE) + output += proc.communicate()[0].decode('utf-8') + if proc.poll() == 0: + count += 1 + else: + count = 0 + msg = ('Expected 5 consecutive, got %d.\n' + 'ping output is:\n%s' % (count,output)) + self.assertEqual(count, 5, msg = msg)
meta/lib/oeqa/runtime/cases/python.py new file +43 -0
43 lines not on this page · raw message
meta/lib/oeqa/runtime/cases/rpm.py new file +141 -0
141 lines not on this page · raw message
meta/lib/oeqa/runtime/cases/scanelf.py new file +26 -0
@@ -0,0 +1,26 @@ +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.core.decorator.oeid import OETestID +from oeqa.runtime.decorator.package import OEHasPackage + +class ScanelfTest(OERuntimeTestCase): + scancmd = 'scanelf --quiet --recursive --mount --ldpath --path' + + @OETestID(966) + @OETestDepends(['ssh.SSHTest.test_ssh']) + @OEHasPackage(['pax-utils']) + def test_scanelf_textrel(self): + # print TEXTREL information + cmd = '%s --textrel' % self.scancmd + status, output = self.target.run(cmd) + msg = '\n'.join([cmd, output]) + self.assertEqual(output.strip(), '', msg=msg) + + @OETestID(967) + @OETestDepends(['scanelf.ScanelfTest.test_scanelf_textrel']) + def test_scanelf_rpath(self): + # print RPATH information + cmd = '%s --textrel --rpath' % self.scancmd + status, output = self.target.run(cmd) + msg = '\n'.join([cmd, output]) + self.assertEqual(output.strip(), '', msg=msg)
meta/lib/oeqa/runtime/cases/scp.py new file +33 -0
@@ -0,0 +1,33 @@ +import os +from tempfile import mkstemp + +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.core.decorator.oeid import OETestID + +class ScpTest(OERuntimeTestCase): + + @classmethod + def setUpClass(cls): + cls.tmp_fd, cls.tmp_path = mkstemp() + with os.fdopen(cls.tmp_fd, 'w') as f: + f.seek(2 ** 22 -1) + f.write(os.linesep) + + @classmethod + def tearDownClass(cls): + os.remove(cls.tmp_path) + + @OETestID(220) + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_scp_file(self): + dst = '/tmp/test_scp_file' + + (status, output) = self.target.copyTo(self.tmp_path, dst) + msg = 'File could not be copied. Output: %s' % output + self.assertEqual(status, 0, msg=msg) + + (status, output) = self.target.run('ls -la %s' % dst) + self.assertEqual(status, 0, msg = 'SCP test failed') + + self.target.run('rm %s' % dst)
meta/lib/oeqa/runtime/cases/skeletoninit.py new file +33 -0
@@ -0,0 +1,33 @@ +# This test should cover https://bugzilla.yoctoproject.org/tr_show_case.cgi?case_id=284 +# testcase. Image under test must have meta-skeleton layer in bblayers and +# IMAGE_INSTALL_append = " service" in local.conf +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.core.decorator.oeid import OETestID +from oeqa.core.decorator.data import skipIfDataVar +from oeqa.runtime.decorator.package import OEHasPackage + +class SkeletonBasicTest(OERuntimeTestCase): + + @OETestDepends(['ssh.SSHTest.test_ssh']) + @OEHasPackage(['service']) + @skipIfDataVar('VIRTUAL-RUNTIME_init_manager', 'systemd', + 'Not appropiate for systemd image') + def test_skeleton_availability(self): + status, output = self.target.run('ls /etc/init.d/skeleton') + msg = 'skeleton init script not found. Output:\n%s' % output + self.assertEqual(status, 0, msg=msg) + + status, output = self.target.run('ls /usr/sbin/skeleton-test') + msg = 'skeleton-test not found. Output:\n%s' % output + self.assertEqual(status, 0, msg=msg) + + @OETestID(284) + @OETestDepends(['skeletoninit.SkeletonBasicTest.test_skeleton_availability']) + def test_skeleton_script(self): + output1 = self.target.run("/etc/init.d/skeleton start")[1] + cmd = '%s | grep [s]keleton-test' % self.tc.target_cmds['ps'] + status, output2 = self.target.run(cmd) + cmd = ('Skeleton script could not be started:' + '\n%s\n%s' % (output1, output2)) + self.assertEqual(status, 0, msg=msg)
meta/lib/oeqa/runtime/cases/smart.py renamed from meta/lib/oeqa/runtime_cases/smart.py +0 -0
meta/lib/oeqa/runtime/cases/ssh.py new file +15 -0
@@ -0,0 +1,15 @@ +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.core.decorator.oeid import OETestID + +class SSHTest(OERuntimeTestCase): + + @OETestID(224) + @OETestDepends(['ping.PingTest.test_ping']) + def test_ssh(self): + (status, output) = self.target.run('uname -a') + self.assertEqual(status, 0, msg='SSH Test failed: %s' % output) + (status, output) = self.target.run('cat /etc/masterimage') + msg = "This isn't the right image - /etc/masterimage " \ + "shouldn't be here %s" % output + self.assertEqual(status, 1, msg=msg)
meta/lib/oeqa/runtime/cases/syslog.py new file +57 -0
57 lines not on this page · raw message
meta/lib/oeqa/runtime/cases/systemd.py renamed from meta/lib/oeqa/runtime_cases/systemd.py +77 -74
239 lines not on this page · raw message
meta/lib/oeqa/runtime/cases/x32lib.py new file +19 -0
@@ -0,0 +1,19 @@ +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.core.decorator.oeid import OETestID +from oeqa.core.decorator.data import skipIfNotInDataVar + +class X32libTest(OERuntimeTestCase): + + @skipIfNotInDataVar('DEFAULTTUNE', 'x86-64-x32', + 'DEFAULTTUNE is not set to x86-64-x32') + @OETestID(281) + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_x32_file(self): + cmd = 'readelf -h /bin/ls | grep Class | grep ELF32' + status1 = self.target.run(cmd)[0] + cmd = 'readelf -h /bin/ls | grep Machine | grep X86-64' + status2 = self.target.run(cmd)[0] + msg = ("/bin/ls isn't an X86-64 ELF32 binary. readelf says: %s" % + self.target.run("readelf -h /bin/ls")[1]) + self.assertTrue(status1 == 0 and status2 == 0, msg=msg)
meta/lib/oeqa/runtime/cases/xorg.py new file +17 -0
@@ -0,0 +1,17 @@ +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.core.decorator.oeid import OETestID +from oeqa.core.decorator.data import skipIfNotFeature + +class XorgTest(OERuntimeTestCase): + + @OETestID(1151) + @skipIfNotFeature('x11-base', + 'Test requires x11 to be in IMAGE_FEATURES') + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_xorg_running(self): + cmd ='%s | grep -v xinit | grep [X]org' % self.tc.target_cmds['ps'] + status, output = self.target.run(cmd) + msg = ('Xorg does not appear to be running %s' % + self.target.run(self.tc.target_cmds['ps'])[1]) + self.assertEqual(status, 0, msg=msg)
meta/lib/oeqa/runtime_cases/buildcvs.py deleted +0 -32
@@ -1,32 +0,0 @@ -from oeqa.oetest import oeRuntimeTest, skipModule -from oeqa.utils.decorators import * -from oeqa.runtime.utils.targetbuildproject import TargetBuildProject - -def setUpModule(): - if not oeRuntimeTest.hasFeature("tools-sdk"): - skipModule("Image doesn't have tools-sdk in IMAGE_FEATURES") - -class BuildCvsTest(oeRuntimeTest): - - @classmethod - def setUpClass(self): - dl_dir = oeRuntimeTest.tc.d.getVar('DL_DIR', True) - self.project = TargetBuildProject(oeRuntimeTest.tc.target, - "http://ftp.gnu.org/non-gnu/cvs/source/feature/1.12.13/cvs-1.12.13.tar.bz2", - dl_dir=dl_dir) - - @testcase(205) - @skipUnlessPassed("test_ssh") - def test_cvs(self): - self.assertEqual(self.project.run_configure(), 0, - msg="Running configure failed") - - self.assertEqual(self.project.run_make(), 0, - msg="Running make failed") - - self.assertEqual(self.project.run_install(), 0, - msg="Running make install failed") - - @classmethod - def tearDownClass(self): - self.project.clean()
meta/lib/oeqa/runtime_cases/buildgalculator.py deleted +0 -26
@@ -1,26 +0,0 @@ -from oeqa.oetest import oeRuntimeTest, skipModule -from oeqa.utils.decorators import * -from oeqa.runtime.utils.targetbuildproject import TargetBuildProject - -def setUpModule(): - if not oeRuntimeTest.hasFeature("tools-sdk"): - skipModule("Image doesn't have tools-sdk in IMAGE_FEATURES") - -class GalculatorTest(oeRuntimeTest): - @testcase(1526) - @skipUnlessPassed("test_ssh") - def test_galculator(self): - dl_dir = oeRuntimeTest.tc.d.getVar('DL_DIR', True) - try: - project = TargetBuildProject(oeRuntimeTest.tc.target, - "http://galculator.mnim.org/downloads/galculator-2.1.4.tar.bz2", - dl_dir=dl_dir) - project.download_archive() - - self.assertEqual(project.run_configure(), 0, - msg="Running configure failed") - - self.assertEqual(project.run_make(), 0, - msg="Running make failed") - finally: - project.clean()
meta/lib/oeqa/runtime_cases/buildiptables.py deleted +0 -33
@@ -1,33 +0,0 @@ -from oeqa.oetest import oeRuntimeTest, skipModule -from oeqa.utils.decorators import * -from oeqa.runtime.utils.targetbuildproject import TargetBuildProject - -def setUpModule(): - if not oeRuntimeTest.hasFeature("tools-sdk"): - skipModule("Image doesn't have tools-sdk in IMAGE_FEATURES") - -class BuildIptablesTest(oeRuntimeTest): - - @classmethod - def setUpClass(self): - dl_dir = oeRuntimeTest.tc.d.getVar('DL_DIR', True) - self.project = TargetBuildProject(oeRuntimeTest.tc.target, - "http://downloads.yoctoproject.org/mirror/sources/iptables-1.4.13.tar.bz2", - dl_dir=dl_dir) - self.project.download_archive() - - @testcase(206) - @skipUnlessPassed("test_ssh") - def test_iptables(self): - self.assertEqual(self.project.run_configure(), 0, - msg="Running configure failed") - - self.assertEqual(self.project.run_make(), 0, - msg="Running make failed") - - self.assertEqual(self.project.run_install(), 0, - msg="Running make install failed") - - @classmethod - def tearDownClass(self): - self.project.clean()
meta/lib/oeqa/runtime_cases/connman.py deleted +0 -31
@@ -1,31 +0,0 @@ -import unittest -from oeqa.oetest import oeRuntimeTest, skipModule -from oeqa.utils.decorators import * - -def setUpModule(): - if not oeRuntimeTest.hasPackage("connman"): - skipModule("No connman package in image") - - -class ConnmanTest(oeRuntimeTest): - - def service_status(self, service): - if oeRuntimeTest.hasFeature("systemd"): - (status, output) = self.target.run('systemctl status -l %s' % service) - return output - else: - return "Unable to get status or logs for %s" % service - - @testcase(961) - @skipUnlessPassed('test_ssh') - def test_connmand_help(self): - (status, output) = self.target.run('/usr/sbin/connmand --help') - self.assertEqual(status, 0, msg="status and output: %s and %s" % (status,output)) - - @testcase(221) - @skipUnlessPassed('test_connmand_help') - def test_connmand_running(self): - (status, output) = self.target.run(oeRuntimeTest.pscmd + ' | grep [c]onnmand') - if status != 0: - print(self.service_status("connman")) - self.fail("No connmand process running")
meta/lib/oeqa/runtime_cases/date.py deleted +0 -31
@@ -1,31 +0,0 @@ -from oeqa.oetest import oeRuntimeTest -from oeqa.utils.decorators import * -import re - -class DateTest(oeRuntimeTest): - - def setUpLocal(self): - if oeRuntimeTest.tc.d.getVar("VIRTUAL-RUNTIME_init_manager") == "systemd": - self.target.run('systemctl stop systemd-timesyncd') - - def tearDownLocal(self): - if oeRuntimeTest.tc.d.getVar("VIRTUAL-RUNTIME_init_manager") == "systemd": - self.target.run('systemctl start systemd-timesyncd') - - @testcase(211) - @skipUnlessPassed("test_ssh") - def test_date(self): - (status, output) = self.target.run('date +"%Y-%m-%d %T"') - self.assertEqual(status, 0, msg="Failed to get initial date, output: %s" % output) - oldDate = output - - sampleDate = '"2016-08-09 10:00:00"' - (status, output) = self.target.run("date -s %s" % sampleDate) - self.assertEqual(status, 0, msg="Date set failed, output: %s" % output) - - (status, output) = self.target.run("date -R") - p = re.match('Tue, 09 Aug 2016 10:00:.. \+0000', output) - self.assertTrue(p, msg="The date was not set correctly, output: %s" % output) - - (status, output) = self.target.run('date -s "%s"' % oldDate) - self.assertEqual(status, 0, msg="Failed to reset date, output: %s" % output)
meta/lib/oeqa/runtime_cases/df.py deleted +0 -12
@@ -1,12 +0,0 @@ -import unittest -from oeqa.oetest import oeRuntimeTest -from oeqa.utils.decorators import * - - -class DfTest(oeRuntimeTest): - - @testcase(234) - @skipUnlessPassed("test_ssh") - def test_df(self): - (status,output) = self.target.run("df / | sed -n '2p' | awk '{print $4}'") - self.assertTrue(int(output)>5120, msg="Not enough space on image. Current size is %s" % output)
meta/lib/oeqa/runtime_cases/gcc.py deleted +0 -47
47 lines not on this page · raw message
meta/lib/oeqa/runtime_cases/kernelmodule.py deleted +0 -34
@@ -1,34 +0,0 @@ -import unittest -import os -from oeqa.oetest import oeRuntimeTest, skipModule -from oeqa.utils.decorators import * - -def setUpModule(): - if not oeRuntimeTest.hasFeature("tools-sdk"): - skipModule("Image doesn't have tools-sdk in IMAGE_FEATURES") - - -class KernelModuleTest(oeRuntimeTest): - - def setUpLocal(self): - self.target.copy_to(os.path.join(oeRuntimeTest.tc.filesdir, "hellomod.c"), "/tmp/hellomod.c") - self.target.copy_to(os.path.join(oeRuntimeTest.tc.filesdir, "hellomod_makefile"), "/tmp/Makefile") - - @testcase('1541') - @skipUnlessPassed('test_ssh') - @skipUnlessPassed('test_gcc_compile') - def test_kernel_module(self): - cmds = [ - 'cd /usr/src/kernel && make scripts', - 'cd /tmp && make', - 'cd /tmp && insmod hellomod.ko', - 'lsmod | grep hellomod', - 'dmesg | grep Hello', - 'rmmod hellomod', 'dmesg | grep "Cleaning up hellomod"' - ] - for cmd in cmds: - (status, output) = self.target.run(cmd, 900) - self.assertEqual(status, 0, msg="\n".join([cmd, output])) - - def tearDownLocal(self): - self.target.run('rm -f /tmp/Makefile /tmp/hellomod.c')
meta/lib/oeqa/runtime_cases/ldd.py deleted +0 -21
@@ -1,21 +0,0 @@ -import unittest -from oeqa.oetest import oeRuntimeTest, skipModule -from oeqa.utils.decorators import * - -def setUpModule(): - if not oeRuntimeTest.hasFeature("tools-sdk"): - skipModule("Image doesn't have tools-sdk in IMAGE_FEATURES") - -class LddTest(oeRuntimeTest): - - @testcase(962) - @skipUnlessPassed('test_ssh') - def test_ldd_exists(self): - (status, output) = self.target.run('which ldd') - self.assertEqual(status, 0, msg = "ldd does not exist in PATH: which ldd: %s" % output) - - @testcase(239) - @skipUnlessPassed('test_ldd_exists') - def test_ldd_rtldlist_check(self): - (status, output) = self.target.run('for i in $(which ldd | xargs cat | grep "^RTLDLIST"|cut -d\'=\' -f2|tr -d \'"\'); do test -f $i && echo $i && break; done') - self.assertEqual(status, 0, msg = "ldd path not correct or RTLDLIST files don't exist. ")
meta/lib/oeqa/runtime_cases/logrotate.py deleted +0 -30
@@ -1,30 +0,0 @@ -# This test should cover https://bugzilla.yoctoproject.org/tr_show_case.cgi?case_id=289 testcase -# Note that the image under test must have logrotate installed - -import unittest -from oeqa.oetest import oeRuntimeTest, skipModule -from oeqa.utils.decorators import * - -def setUpModule(): - if not oeRuntimeTest.hasPackage("logrotate"): - skipModule("No logrotate package in image") - - -class LogrotateTest(oeRuntimeTest): - - @testcase(1544) - @skipUnlessPassed("test_ssh") - def test_1_logrotate_setup(self): - (status, output) = self.target.run('mkdir $HOME/logrotate_dir') - self.assertEqual(status, 0, msg = "Could not create logrotate_dir. Output: %s" % output) - (status, output) = self.target.run("sed -i \"s#wtmp {#wtmp {\\n olddir $HOME/logrotate_dir#\" /etc/logrotate.conf") - self.assertEqual(status, 0, msg = "Could not write to logrotate.conf file. Status and output: %s and %s)" % (status, output)) - - @testcase(1542) - @skipUnlessPassed("test_1_logrotate_setup") - def test_2_logrotate(self): - (status, output) = self.target.run('logrotate -f /etc/logrotate.conf') - self.assertEqual(status, 0, msg = "logrotate service could not be reloaded. Status and output: %s and %s" % (status, output)) - output = self.target.run('ls -la $HOME/logrotate_dir/ | wc -l')[1] - self.assertTrue(int(output)>=3, msg = "new logfile could not be created. List of files within log directory: %s" %(self.target.run('ls -la $HOME/logrotate_dir')[1])) - self.target.run('rm -rf $HOME/logrotate_dir')
meta/lib/oeqa/runtime_cases/multilib.py deleted +0 -42
42 lines not on this page · raw message
meta/lib/oeqa/runtime_cases/pam.py deleted +0 -25
@@ -1,25 +0,0 @@ -# This test should cover https://bugzilla.yoctoproject.org/tr_show_case.cgi?case_id=287 testcase -# Note that the image under test must have "pam" in DISTRO_FEATURES - -import unittest -from oeqa.oetest import oeRuntimeTest, skipModule -from oeqa.utils.decorators import * - -def setUpModule(): - if not oeRuntimeTest.hasFeature("pam"): - skipModule("target doesn't have 'pam' in DISTRO_FEATURES") - - -class PamBasicTest(oeRuntimeTest): - - @testcase(1543) - @skipUnlessPassed('test_ssh') - def test_pam(self): - (status, output) = self.target.run('login --help') - self.assertEqual(status, 1, msg = "login command does not work as expected. Status and output:%s and %s" %(status, output)) - (status, output) = self.target.run('passwd --help') - self.assertEqual(status, 0, msg = "passwd command does not work as expected. Status and output:%s and %s" %(status, output)) - (status, output) = self.target.run('su --help') - self.assertEqual(status, 0, msg = "su command does not work as expected. Status and output:%s and %s" %(status, output)) - (status, output) = self.target.run('useradd --help') - self.assertEqual(status, 0, msg = "useradd command does not work as expected. Status and output:%s and %s" %(status, output))
meta/lib/oeqa/runtime_cases/perl.py deleted +0 -30
@@ -1,30 +0,0 @@ -import unittest -import os -from oeqa.oetest import oeRuntimeTest, skipModule -from oeqa.utils.decorators import * - -def setUpModule(): - if not oeRuntimeTest.hasPackage("perl"): - skipModule("No perl package in the image") - - -class PerlTest(oeRuntimeTest): - - @classmethod - def setUpClass(self): - oeRuntimeTest.tc.target.copy_to(os.path.join(oeRuntimeTest.tc.corefilesdir, "test.pl"), "/tmp/test.pl") - - @testcase(1141) - def test_perl_exists(self): - (status, output) = self.target.run('which perl') - self.assertEqual(status, 0, msg="Perl binary not in PATH or not on target.") - - @testcase(208) - def test_perl_works(self): - (status, output) = self.target.run('perl /tmp/test.pl') - self.assertEqual(status, 0, msg="Exit status was not 0. Output: %s" % output) - self.assertEqual(output, "the value of a is 0.01", msg="Incorrect output: %s" % output) - - @classmethod - def tearDownClass(self): - oeRuntimeTest.tc.target.run("rm /tmp/test.pl")
meta/lib/oeqa/runtime_cases/ping.py deleted +0 -22
@@ -1,22 +0,0 @@ -import subprocess -import unittest -import sys -import time -from oeqa.oetest import oeRuntimeTest -from oeqa.utils.decorators import * - -class PingTest(oeRuntimeTest): - - @testcase(964) - def test_ping(self): - output = '' - count = 0 - endtime = time.time() + 60 - while count < 5 and time.time() < endtime: - proc = subprocess.Popen("ping -c 1 %s" % self.target.ip, shell=True, stdout=subprocess.PIPE) - output += proc.communicate()[0].decode("utf-8") - if proc.poll() == 0: - count += 1 - else: - count = 0 - self.assertEqual(count, 5, msg = "Expected 5 consecutive replies, got %d.\nping output is:\n%s" % (count,output))
meta/lib/oeqa/runtime_cases/python.py deleted +0 -35
@@ -1,35 +0,0 @@ -import unittest -import os -from oeqa.oetest import oeRuntimeTest, skipModule -from oeqa.utils.decorators import * - -def setUpModule(): - if not oeRuntimeTest.hasPackage("python-core"): - skipModule("No python package in the image") - - -class PythonTest(oeRuntimeTest): - - @classmethod - def setUpClass(self): - oeRuntimeTest.tc.target.copy_to(os.path.join(oeRuntimeTest.tc.corefilesdir, "test.py"), "/tmp/test.py") - - @testcase(1145) - def test_python_exists(self): - (status, output) = self.target.run('which python') - self.assertEqual(status, 0, msg="Python binary not in PATH or not on target.") - - @testcase(965) - def test_python_stdout(self): - (status, output) = self.target.run('python /tmp/test.py') - self.assertEqual(status, 0, msg="Exit status was not 0. Output: %s" % output) - self.assertEqual(output, "the value of a is 0.01", msg="Incorrect output: %s" % output) - - @testcase(1146) - def test_python_testfile(self): - (status, output) = self.target.run('ls /tmp/testfile.python') - self.assertEqual(status, 0, msg="Python test file generate failed.") - - @classmethod - def tearDownClass(self): - oeRuntimeTest.tc.target.run("rm /tmp/test.py /tmp/testfile.python")
meta/lib/oeqa/runtime_cases/rpm.py deleted +0 -120
120 lines not on this page · raw message
meta/lib/oeqa/runtime_cases/scanelf.py deleted +0 -28
@@ -1,28 +0,0 @@ -import unittest -from oeqa.oetest import oeRuntimeTest, skipModule -from oeqa.utils.decorators import * - -def setUpModule(): - if not oeRuntimeTest.hasPackage("pax-utils"): - skipModule("pax-utils package not installed") - -class ScanelfTest(oeRuntimeTest): - - def setUpLocal(self): - self.scancmd = 'scanelf --quiet --recursive --mount --ldpath --path' - - @testcase(966) - @skipUnlessPassed('test_ssh') - def test_scanelf_textrel(self): - # print TEXTREL information - self.scancmd += " --textrel" - (status, output) = self.target.run(self.scancmd) - self.assertEqual(output.strip(), "", "\n".join([self.scancmd, output])) - - @testcase(967) - @skipUnlessPassed('test_ssh') - def test_scanelf_rpath(self): - # print RPATH information - self.scancmd += " --rpath" - (status, output) = self.target.run(self.scancmd) - self.assertEqual(output.strip(), "", "\n".join([self.scancmd, output]))
meta/lib/oeqa/runtime_cases/scp.py deleted +0 -22
@@ -1,22 +0,0 @@ -import os -from oeqa.oetest import oeRuntimeTest, skipModule -from oeqa.utils.decorators import skipUnlessPassed, testcase - -def setUpModule(): - if not (oeRuntimeTest.hasPackage("dropbear") or oeRuntimeTest.hasPackage("openssh-sshd")): - skipModule("No ssh package in image") - -class ScpTest(oeRuntimeTest): - - @testcase(220) - @skipUnlessPassed('test_ssh') - def test_scp_file(self): - test_log_dir = oeRuntimeTest.tc.d.getVar("TEST_LOG_DIR") - test_file_path = os.path.join(test_log_dir, 'test_scp_file') - with open(test_file_path, 'w') as test_scp_file: - test_scp_file.seek(2 ** 22 - 1) - test_scp_file.write(os.linesep) - (status, output) = self.target.copy_to(test_file_path, '/tmp/test_scp_file') - self.assertEqual(status, 0, msg = "File could not be copied. Output: %s" % output) - (status, output) = self.target.run("ls -la /tmp/test_scp_file") - self.assertEqual(status, 0, msg = "SCP test failed")
meta/lib/oeqa/runtime_cases/skeletoninit.py deleted +0 -29
@@ -1,29 +0,0 @@ -# This test should cover https://bugzilla.yoctoproject.org/tr_show_case.cgi?case_id=284 testcase -# Note that the image under test must have meta-skeleton layer in bblayers and IMAGE_INSTALL_append = " service" in local.conf - -import unittest -from oeqa.oetest import oeRuntimeTest, skipModule -from oeqa.utils.decorators import * - -def setUpModule(): - if not oeRuntimeTest.hasPackage("service"): - skipModule("No service package in image") - - -class SkeletonBasicTest(oeRuntimeTest): - - @skipUnlessPassed('test_ssh') - @unittest.skipIf("systemd" == oeRuntimeTest.tc.d.getVar("VIRTUAL-RUNTIME_init_manager", False), "Not appropiate for systemd image") - def test_skeleton_availability(self): - (status, output) = self.target.run('ls /etc/init.d/skeleton') - self.assertEqual(status, 0, msg = "skeleton init script not found. Output:\n%s " % output) - (status, output) = self.target.run('ls /usr/sbin/skeleton-test') - self.assertEqual(status, 0, msg = "skeleton-test not found. Output:\n%s" % output) - - @testcase(284) - @skipUnlessPassed('test_skeleton_availability') - @unittest.skipIf("systemd" == oeRuntimeTest.tc.d.getVar("VIRTUAL-RUNTIME_init_manager", False), "Not appropiate for systemd image") - def test_skeleton_script(self): - output1 = self.target.run("/etc/init.d/skeleton start")[1] - (status, output2) = self.target.run(oeRuntimeTest.pscmd + ' | grep [s]keleton-test') - self.assertEqual(status, 0, msg = "Skeleton script could not be started:\n%s\n%s" % (output1, output2))
meta/lib/oeqa/runtime_cases/ssh.py deleted +0 -19
@@ -1,19 +0,0 @@ -import subprocess -import unittest -import sys -from oeqa.oetest import oeRuntimeTest, skipModule -from oeqa.utils.decorators import * - -def setUpModule(): - if not (oeRuntimeTest.hasPackage("dropbear") or oeRuntimeTest.hasPackage("openssh")): - skipModule("No ssh package in image") - -class SshTest(oeRuntimeTest): - - @testcase(224) - @skipUnlessPassed('test_ping') - def test_ssh(self): - (status, output) = self.target.run('uname -a') - self.assertEqual(status, 0, msg="SSH Test failed: %s" % output) - (status, output) = self.target.run('cat /etc/masterimage') - self.assertEqual(status, 1, msg="This isn't the right image - /etc/masterimage shouldn't be here %s" % output)
meta/lib/oeqa/runtime_cases/syslog.py deleted +0 -52
52 lines not on this page · raw message
meta/lib/oeqa/runtime_cases/x32lib.py deleted +0 -18
@@ -1,18 +0,0 @@ -import unittest -from oeqa.oetest import oeRuntimeTest, skipModule -from oeqa.utils.decorators import * - -def setUpModule(): - #check if DEFAULTTUNE is set and it's value is: x86-64-x32 - defaulttune = oeRuntimeTest.tc.d.getVar("DEFAULTTUNE") - if "x86-64-x32" not in defaulttune: - skipModule("DEFAULTTUNE is not set to x86-64-x32") - -class X32libTest(oeRuntimeTest): - - @testcase(281) - @skipUnlessPassed("test_ssh") - def test_x32_file(self): - status1 = self.target.run("readelf -h /bin/ls | grep Class | grep ELF32")[0] - status2 = self.target.run("readelf -h /bin/ls | grep Machine | grep X86-64")[0] - self.assertTrue(status1 == 0 and status2 == 0, msg="/bin/ls isn't an X86-64 ELF32 binary. readelf says: %s" % self.target.run("readelf -h /bin/ls")[1])
meta/lib/oeqa/runtime_cases/xorg.py deleted +0 -16
@@ -1,16 +0,0 @@ -import unittest -from oeqa.oetest import oeRuntimeTest, skipModule -from oeqa.utils.decorators import * - -def setUpModule(): - if not oeRuntimeTest.hasFeature("x11-base"): - skipModule("target doesn't have x11 in IMAGE_FEATURES") - - -class XorgTest(oeRuntimeTest): - - @testcase(1151) - @skipUnlessPassed('test_ssh') - def test_xorg_running(self): - (status, output) = self.target.run(oeRuntimeTest.pscmd + ' | grep -v xinit | grep [X]org') - self.assertEqual(status, 0, msg="Xorg does not appear to be running %s" % self.target.run(oeRuntimeTest.pscmd)[1])
Signature · 1 line
2.1.4
PATCH 49/55 runtime/cases/smart.py: Migrate smart tests
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
This migrates the smart test from the old framework to the new one. This has its own commit because smart test was using bb and oe libraries that are available when exporting the test cases to run in a different host.
Because of the removal of bb and oe libraries index and packages feeds creation will be managed in testimage bbclass.
[YOCTO #10234]
--- meta/classes/testimage.bbclass | 53 +++++++++++ meta/lib/oeqa/runtime/cases/smart.py | 172 +++++++++++++++-------------------- 2 files changed, 128 insertions(+), 97 deletions(-)
meta/classes/testimage.bbclass +53 -0
@@ -116,6 +116,10 @@ python do_testimage() { testimage_sanity(d) + if (d.getVar('IMAGE_PKGTYPE') == 'rpm' + and 'smart' in d.getVar('TEST_SUITES')): + create_rpm_index(d) + testimage_main(d) }
@@ -284,6 +288,55 @@ def get_runtime_paths(d): paths.append(path) return paths +def create_index(arg): + import subprocess + + index_cmd = arg + try: + bb.note("Executing '%s' ..." % index_cmd) + result = subprocess.check_output(index_cmd, + stderr=subprocess.STDOUT, + shell=True) + result = result.decode('utf-8') + except subprocess.CalledProcessError as e: + return("Index creation command '%s' failed with return code " + '%d:\n%s' % (e.cmd, e.returncode, e.output.decode("utf-8"))) + if result: + bb.note(result) + return None + +def create_rpm_index(d): + # Index RPMs + rpm_createrepo = bb.utils.which(os.getenv('PATH'), "createrepo") + index_cmds = [] + archs = (d.getVar('ALL_MULTILIB_PACKAGE_ARCHS') or '').replace('-', '_') + + for arch in archs.split(): + rpm_dir = os.path.join(d.getVar('DEPLOY_DIR_RPM'), arch) + idx_path = os.path.join(d.getVar('WORKDIR'), 'rpm', arch) + db_path = os.path.join(d.getVar('WORKDIR'), 'rpmdb', arch) + + if not os.path.isdir(rpm_dir): + continue + if os.path.exists(db_path): + bb.utils.remove(dbpath, True) + + lockfilename = os.path.join(d.getVar('DEPLOY_DIR_RPM'), 'rpm.lock') + lf = bb.utils.lockfile(lockfilename, False) + oe.path.copyhardlinktree(rpm_dir, idx_path) + # Full indexes overload a 256MB image so reduce the number of rpms + # in the feed. Filter to p* since we use the psplash packages and + # this leaves some allarch and machine arch packages too. + bb.utils.remove(idx_path + "*/[a-oq-z]*.rpm") + bb.utils.unlockfile(lf) + cmd = '%s --dbpath %s --update -q %s' % (rpm_createrepo, + db_path, idx_path) + + # Create repodata + result = create_index(cmd) + if result: + bb.fatal('%s' % ('\n'.join(result))) + def test_create_extract_dirs(d): install_path = d.getVar("TEST_INSTALL_TMP_DIR") package_path = d.getVar("TEST_PACKAGED_DIR")
meta/lib/oeqa/runtime/cases/smart.py +75 -97
275 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH 50/55 oeqa/core/utils/test.py: Add functions to get module path
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
This will add functions to get module file path from a test case or a complete suite.
[YOCTO #10234]
--- meta/lib/oeqa/core/utils/test.py | 13 +++++++++++++ 1 file changed, 13 insertions(+)
meta/lib/oeqa/core/utils/test.py +13 -0
@@ -2,6 +2,7 @@ # Released under the MIT license (see COPYING.MIT) import os +import inspect import unittest def getSuiteCases(suite):
@@ -46,6 +47,12 @@ def getSuiteCasesIDs(suite): """ return getSuiteCasesInfo(suite, getCaseID) +def getSuiteCasesFiles(suite): + """ + Returns test case files paths from suite. + """ + return getSuiteCasesInfo(suite, getCaseFile) + def getCaseModule(test_case): """ Returns test case module name.
@@ -64,6 +71,12 @@ def getCaseID(test_case): """ return test_case.id() +def getCaseFile(test_case): + """ + Returns test case file path. + """ + return inspect.getsourcefile(test_case.__class__) + def getCaseMethod(test_case): """ Returns test case method name.
Signature · 1 line
2.1.4
PATCH 51/55 testimage.bbclass: Add support for package extraction
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
testimage support the installation of packages without a package manager in the target. This adds support for package extraction required to support the installation feature.
[YOCTO #10234]
--- meta/classes/testimage.bbclass | 12 +++ meta/lib/oeqa/utils/package_manager.py | 161 +++++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+)
meta/classes/testimage.bbclass +12 -0
@@ -243,6 +243,8 @@ def testimage_main(d): test_modules = d.getVar('TEST_SUITES') tc.loadTests(test_paths, modules=test_modules) + package_extraction(d, tc.suites) + bootparams = None if d.getVar('VIRTUAL-RUNTIME_init_manager', '') == 'systemd': bootparams = 'systemd.log_level=debug systemd.log_target=console'
@@ -337,12 +339,22 @@ def create_rpm_index(d): if result: bb.fatal('%s' % ('\n'.join(result))) +def package_extraction(d, test_suites): + from oeqa.utils.package_manager import find_packages_to_extract + from oeqa.utils.package_manager import extract_packages + + test_create_extract_dirs(d) + packages = find_packages_to_extract(test_suites) + extract_packages(d, packages) + def test_create_extract_dirs(d): install_path = d.getVar("TEST_INSTALL_TMP_DIR") package_path = d.getVar("TEST_PACKAGED_DIR") extracted_path = d.getVar("TEST_EXTRACTED_DIR") bb.utils.mkdirhier(d.getVar("TEST_LOG_DIR")) + bb.utils.remove(install_path, recurse=True) bb.utils.remove(package_path, recurse=True) + bb.utils.remove(extracted_path, recurse=True) bb.utils.mkdirhier(install_path) bb.utils.mkdirhier(package_path) bb.utils.mkdirhier(extracted_path)
meta/lib/oeqa/utils/package_manager.py +161 -0
167 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH 52/55 testimage.bbclass: Add package install feature
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
This allows to use the package install feature with the new OEQA framework.
[YOCTO #10234]
--- meta/classes/testimage.bbclass | 27 ++++++++------------ meta/lib/oeqa/core/utils/test.py | 10 +++++--- meta/lib/oeqa/runtime/case.py | 9 +++++++ meta/lib/oeqa/runtime/context.py | 12 ++++++++- meta/lib/oeqa/utils/package_manager.py | 46 ++++++++++++++++++++++++---------- 5 files changed, 69 insertions(+), 35 deletions(-)
meta/classes/testimage.bbclass +10 -17
@@ -159,7 +159,6 @@ def testimage_main(d): pn = d.getVar("PN") bb.utils.mkdirhier(d.getVar("TEST_LOG_DIR")) - #test_create_extract_dirs(d) image_name = ("%s/%s" % (d.getVar('DEPLOY_DIR_IMAGE'), d.getVar('IMAGE_LINK_NAME')))
@@ -170,6 +169,8 @@ def testimage_main(d): image_manifest = "%s.manifest" % image_name image_packages = OERuntimeTestContextExecutor.readPackagesManifest(image_manifest) + extract_dir = d.getVar("TEST_EXTRACTED_DIR") + # Get machine machine = d.getVar("MACHINE")
@@ -236,7 +237,8 @@ def testimage_main(d): d.getVar("TEST_SERVER_IP"), **target_kwargs) # test context - tc = OERuntimeTestContext(td, logger, target, host_dumper, image_packages) + tc = OERuntimeTestContext(td, logger, target, host_dumper, + image_packages, extract_dir) # Load tests before starting the target test_paths = get_runtime_paths(d)
@@ -343,22 +345,13 @@ def package_extraction(d, test_suites): from oeqa.utils.package_manager import find_packages_to_extract from oeqa.utils.package_manager import extract_packages - test_create_extract_dirs(d) + bb.utils.remove(d.getVar("TEST_NEEDED_PACKAGES_DIR"), recurse=True) packages = find_packages_to_extract(test_suites) - extract_packages(d, packages) - -def test_create_extract_dirs(d): - install_path = d.getVar("TEST_INSTALL_TMP_DIR") - package_path = d.getVar("TEST_PACKAGED_DIR") - extracted_path = d.getVar("TEST_EXTRACTED_DIR") - bb.utils.mkdirhier(d.getVar("TEST_LOG_DIR")) - bb.utils.remove(install_path, recurse=True) - bb.utils.remove(package_path, recurse=True) - bb.utils.remove(extracted_path, recurse=True) - bb.utils.mkdirhier(install_path) - bb.utils.mkdirhier(package_path) - bb.utils.mkdirhier(extracted_path) - + if packages: + bb.utils.mkdirhier(d.getVar("TEST_INSTALL_TMP_DIR")) + bb.utils.mkdirhier(d.getVar("TEST_PACKAGED_DIR")) + bb.utils.mkdirhier(d.getVar("TEST_EXTRACTED_DIR")) + extract_packages(d, packages) testimage_main[vardepsexclude] += "BB_ORIGENV DATETIME"
meta/lib/oeqa/core/utils/test.py +6 -4
@@ -10,11 +10,13 @@ def getSuiteCases(suite): Returns individual test from a test suite. """ tests = [] - for item in suite: - if isinstance(item, unittest.suite.TestSuite): + + if isinstance(suite, unittest.TestCase): + tests.append(suite) + elif isinstance(suite, unittest.suite.TestSuite): + for item in suite: tests.extend(getSuiteCases(item)) - elif isinstance(item, unittest.TestCase): - tests.append(item) + return tests def getSuiteModules(suite):
meta/lib/oeqa/runtime/case.py +9 -0
@@ -2,7 +2,16 @@ # Released under the MIT license (see COPYING.MIT) from oeqa.core.case import OETestCase +from oeqa.utils.package_manager import install_package, uninstall_package class OERuntimeTestCase(OETestCase): # target instance set by OERuntimeTestLoader. target = None + + def _oeSetUp(self): + super(OERuntimeTestCase, self)._oeSetUp() + install_package(self) + + def _oeTearDown(self): + super(OERuntimeTestCase, self)._oeTearDown() + uninstall_package(self)
meta/lib/oeqa/runtime/context.py +11 -1
@@ -15,12 +15,14 @@ class OERuntimeTestContext(OETestContext): runtime_files_dir = os.path.join( os.path.dirname(os.path.abspath(__file__)), "files") - def __init__(self, td, logger, target, host_dumper, image_packages): + def __init__(self, td, logger, target, + host_dumper, image_packages, extract_dir): super(OERuntimeTestContext, self).__init__(td, logger) self.target = target self.image_packages = image_packages self.host_dumper = host_dumper + self.extract_dir = extract_dir self._set_target_cmds() def _set_target_cmds(self):
@@ -45,6 +47,7 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): default_server_ip = '192.168.7.1' default_target_ip = '192.168.7.2' default_host_dumper_dir = '/tmp/oe-saved-tests' + default_extract_dir = 'extract_dir' def register_commands(self, logger, subparsers): super(OERuntimeTestContextExecutor, self).register_commands(logger, subparsers)
@@ -72,6 +75,9 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): runtime_group.add_argument('--packages-manifest', action='store', help="Package manifest of the image under test") + runtime_group.add_argument('--extract-dir', action='store', + help='Directory where extracted packages reside') + runtime_group.add_argument('--qemu-boot', action='store', help="Qemu boot configuration, only needed when target_type is QEMU.")
@@ -126,4 +132,8 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): OERuntimeTestContextExecutor.readPackagesManifest( args.packages_manifest) + self.tc_kwargs['init']['extract_dir'] = \ + OERuntimeTestContextExecutor.readPackagesManifest( + args.extract_dir) + _executor_class = OERuntimeTestContextExecutor
meta/lib/oeqa/utils/package_manager.py +33 -13
78 lines not on this page · raw message
Signature · 1 line
2.1.4
PATCH 53/55 oeqa/runtime/context.py: Add defaults for runtime context
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
This adds default values to OERuntimeTestContextExecutor class in order to make easier the execution of exported test that were generated with testexport class.
[YOCTO #10686]
--- meta/lib/oeqa/runtime/context.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)
meta/lib/oeqa/runtime/context.py +13 -9
@@ -42,12 +42,15 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): default_cases = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'cases') default_data = None + default_test_data = 'data/testdata.json' + default_tests = '' default_target_type = 'simpleremote' + default_manifest = 'data/manifest' default_server_ip = '192.168.7.1' default_target_ip = '192.168.7.2' default_host_dumper_dir = '/tmp/oe-saved-tests' - default_extract_dir = 'extract_dir' + default_extract_dir = 'packages/extracted' def register_commands(self, logger, subparsers): super(OERuntimeTestContextExecutor, self).register_commands(logger, subparsers)
@@ -73,10 +76,14 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): % self.default_host_dumper_dir) runtime_group.add_argument('--packages-manifest', action='store', - help="Package manifest of the image under test") + default=self.default_manifest, + help="Package manifest of the image under testi, default: %s" \ + % self.default_manifest) runtime_group.add_argument('--extract-dir', action='store', - help='Directory where extracted packages reside') + default=self.default_extract_dir, + help='Directory where extracted packages reside, default: %s' \ + % self.default_extract_dir) runtime_group.add_argument('--qemu-boot', action='store', help="Qemu boot configuration, only needed when target_type is QEMU.")
@@ -97,7 +104,7 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): @staticmethod def readPackagesManifest(manifest): - if not os.path.exists(manifest): + if not manifest or not os.path.exists(manifest): raise OSError("Manifest file not exists: %s" % manifest) image_packages = set()
@@ -124,16 +131,13 @@ class OERuntimeTestContextExecutor(OETestContextExecutor): self.tc_kwargs['init']['target'] = \ OERuntimeTestContextExecutor.getTarget(args.target_type, - args.target_ip, args.server_ip, **target_kwargs) + None, args.target_ip, args.server_ip, **target_kwargs) self.tc_kwargs['init']['host_dumper'] = \ OERuntimeTestContextExecutor.getHostDumper(None, args.host_dumper_dir) self.tc_kwargs['init']['image_packages'] = \ OERuntimeTestContextExecutor.readPackagesManifest( args.packages_manifest) - - self.tc_kwargs['init']['extract_dir'] = \ - OERuntimeTestContextExecutor.readPackagesManifest( - args.extract_dir) + self.tc_kwargs['init']['extract_dir'] = args.extract_dir _executor_class = OERuntimeTestContextExecutor
Signature · 1 line
2.1.4
PATCH 54/55 testexport.bbclass: Migrate testexport to use new framework
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
This migrates current testexport implmentation to use the new OEQA framework.
[YOCTO #10686]
--- meta/classes/testexport.bbclass | 215 +++++++++++++++++----------------------- scripts/oe-test | 10 +- 2 files changed, 99 insertions(+), 126 deletions(-)
meta/classes/testexport.bbclass +91 -124
@@ -33,113 +33,111 @@ TEST_EXPORT_DEPENDS += "${@bb.utils.contains('IMAGE_PKGTYPE', 'rpm', 'cpio-nativ TEST_EXPORT_DEPENDS += "${@bb.utils.contains('TEST_EXPORT_SDK_ENABLED', '1', 'testexport-tarball:do_populate_sdk', '', d)}" TEST_EXPORT_LOCK = "${TMPDIR}/testimage.lock" -python do_testexport() { - testexport_main(d) -} - addtask testexport do_testexport[nostamp] = "1" do_testexport[depends] += "${TEST_EXPORT_DEPENDS} ${TESTIMAGEDEPENDS}" do_testexport[lockfiles] += "${TEST_EXPORT_LOCK}" -def exportTests(d,tc): +python do_testexport() { + testexport_main(d) +} + +def testexport_main(d): import json + import logging + + from oeqa.runtime.context import OERuntimeTestContext + from oeqa.runtime.context import OERuntimeTestContextExecutor + + image_name = ("%s/%s" % (d.getVar('DEPLOY_DIR_IMAGE'), + d.getVar('IMAGE_LINK_NAME'))) + + tdname = "%s.testdata.json" % image_name + td = json.load(open(tdname, "r")) + + logger = logging.getLogger("BitBake") + + target = OERuntimeTestContextExecutor.getTarget( + d.getVar("TEST_TARGET"), None, d.getVar("TEST_TARGET_IP"), + d.getVar("TEST_SERVER_IP")) + + host_dumper = OERuntimeTestContextExecutor.getHostDumper( + d.getVar("testimage_dump_host"), d.getVar("TESTIMAGE_DUMP_DIR")) + + image_manifest = "%s.manifest" % image_name + image_packages = OERuntimeTestContextExecutor.readPackagesManifest(image_manifest) + + extract_dir = d.getVar("TEST_EXTRACTED_DIR") + + tc = OERuntimeTestContext(td, logger, target, host_dumper, + image_packages, extract_dir) + + copy_needed_files(d, tc) + +def copy_needed_files(d, tc): import shutil - import pkgutil - import re import oe.path - exportpath = d.getVar("TEST_EXPORT_DIR") - - savedata = {} - savedata["d"] = {} - savedata["target"] = {} - savedata["target"]["ip"] = tc.target.ip or d.getVar("TEST_TARGET_IP") - savedata["target"]["server_ip"] = tc.target.server_ip or d.getVar("TEST_SERVER_IP") - - keys = [ key for key in d.keys() if not key.startswith("_") and not key.startswith("BB") \ - and not key.startswith("B_pn") and not key.startswith("do_") and not d.getVarFlag(key, "func")] - for key in keys: - try: - savedata["d"][key] = d.getVar(key) - except bb.data_smart.ExpansionError: - # we don't care about those anyway - pass - - json_file = os.path.join(exportpath, "testdata.json") - with open(json_file, "w") as f: - json.dump(savedata, f, skipkeys=True, indent=4, sort_keys=True) - - # Replace absolute path with relative in the file - exclude_path = os.path.join(d.getVar("COREBASE"),'meta','lib','oeqa') - f1 = open(json_file,'r').read() - f2 = open(json_file,'w') - m = f1.replace(exclude_path,'oeqa') - f2.write(m) - f2.close() - - # now start copying files - # we'll basically copy everything under meta/lib/oeqa, with these exceptions - # - oeqa/targetcontrol.py - not needed - # - oeqa/selftest - something else - # That means: - # - all tests from oeqa/runtime defined in TEST_SUITES (including from other layers) - # - the contents of oeqa/utils and oeqa/runtime/files - # - oeqa/oetest.py and oeqa/runexport.py (this will get copied to exportpath not exportpath/oeqa) - # - __init__.py files - bb.utils.mkdirhier(os.path.join(exportpath, "oeqa/files")) - bb.utils.mkdirhier(os.path.join(exportpath, "oeqa/runtime/files")) - bb.utils.mkdirhier(os.path.join(exportpath, "oeqa/utils")) - # copy test modules, this should cover tests in other layers too - bbpath = d.getVar("BBPATH").split(':') - for t in tc.testslist: - isfolder = False - if re.search("\w+\.\w+\.test_\S+", t): - t = '.'.join(t.split('.')[:3]) - mod = pkgutil.get_loader(t) - # More depth than usual? - if (t.count('.') > 2): - for p in bbpath: - foldername = os.path.join(p, 'lib', os.sep.join(t.split('.')).rsplit(os.sep, 1)[0]) - if os.path.isdir(foldername): - isfolder = True - target_folder = os.path.join(exportpath, "oeqa", "runtime", os.path.basename(foldername)) - if not os.path.exists(target_folder): - oe.path.copytree(foldername, target_folder) - if not isfolder: - shutil.copy2(mod.path, os.path.join(exportpath, "oeqa/runtime")) - json_file = "%s.json" % mod.path.rsplit(".", 1)[0] - if os.path.isfile(json_file): - shutil.copy2(json_file, os.path.join(exportpath, "oeqa/runtime")) - # Get meta layer - for layer in d.getVar("BBLAYERS").split(): - if os.path.basename(layer) == "meta": - meta_layer = layer - break - # copy oeqa/oetest.py and oeqa/runexported.py - oeqadir = os.path.join(meta_layer, "lib/oeqa") - shutil.copy2(os.path.join(oeqadir, "oetest.py"), os.path.join(exportpath, "oeqa")) - shutil.copy2(os.path.join(oeqadir, "runexported.py"), exportpath) - # copy oeqa/utils/*.py - for root, dirs, files in os.walk(os.path.join(oeqadir, "utils")): - for f in files: - if f.endswith(".py"): - shutil.copy2(os.path.join(root, f), os.path.join(exportpath, "oeqa/utils")) - # copy oeqa/files/* - for root, dirs, files in os.walk(os.path.join(oeqadir, "files")): - for f in files: - shutil.copy2(os.path.join(root, f), os.path.join(exportpath, "oeqa/files")) - # copy oeqa/runtime/files/* - for root, dirs, files in os.walk(os.path.join(oeqadir, "runtime/files")): - for f in files: - shutil.copy2(os.path.join(root, f), os.path.join(exportpath, "oeqa/runtime/files")) + from oeqa.utils.package_manager import _get_json_file + from oeqa.core.utils.test import getSuiteCasesFiles + + export_path = d.getVar('TEST_EXPORT_DIR') + corebase_path = d.getVar('COREBASE') + + # Clean everything before starting + oe.path.remove(export_path) + bb.utils.mkdirhier(os.path.join(export_path, 'lib', 'oeqa')) + + # The source of files to copy are relative to 'COREBASE' directory + # The destination is relative to 'TEST_EXPORT_DIR' + # Because we are squashing the libraries, we need to remove + # the layer/script directory + files_to_copy = [ os.path.join('meta', 'lib', 'oeqa', 'core'), + os.path.join('meta', 'lib', 'oeqa', 'runtime'), + os.path.join('meta', 'lib', 'oeqa', 'files'), + os.path.join('meta', 'lib', 'oeqa', 'utils'), + os.path.join('scripts', 'oe-test'), + os.path.join('scripts', 'lib', 'argparse_oe.py'), + os.path.join('scripts', 'lib', 'scriptutils.py'), ] + + for f in files_to_copy: + src = os.path.join(corebase_path, f) + dst = os.path.join(export_path, f.split('/', 1)[-1]) + if os.path.isdir(src): + oe.path.copytree(src, dst) + else: + shutil.copy2(src, dst) + + # Remove cases and just copy the ones specified + cases_path = os.path.join(export_path, 'lib', 'oeqa', 'runtime', 'cases') + oe.path.remove(cases_path) + bb.utils.mkdirhier(cases_path) + test_paths = get_runtime_paths(d) + test_modules = d.getVar('TEST_SUITES') + tc.loadTests(test_paths, modules=test_modules) + for f in getSuiteCasesFiles(tc.suites): + shutil.copy2(f, cases_path) + json_file = _get_json_file(f) + if json_file: + shutil.copy2(json_file, cases_path) + + # Copy test data + image_name = ("%s/%s" % (d.getVar('DEPLOY_DIR_IMAGE'), + d.getVar('IMAGE_LINK_NAME'))) + image_manifest = "%s.manifest" % image_name + tdname = "%s.testdata.json" % image_name + test_data_path = os.path.join(export_path, 'data') + bb.utils.mkdirhier(test_data_path) + shutil.copy2(image_manifest, os.path.join(test_data_path, 'manifest')) + shutil.copy2(tdname, os.path.join(test_data_path, 'testdata.json')) # Create tar file for common parts of testexport create_tarball(d, "testexport.tar.gz", d.getVar("TEST_EXPORT_DIR")) # Copy packages needed for runtime testing + package_extraction(d, tc.suites) test_pkg_dir = d.getVar("TEST_NEEDED_PACKAGES_DIR") - if os.listdir(test_pkg_dir): + if os.path.isdir(test_pkg_dir) and os.listdir(test_pkg_dir): export_pkg_dir = os.path.join(d.getVar("TEST_EXPORT_DIR"), "packages") oe.path.copytree(test_pkg_dir, export_pkg_dir) # Create tar file for packages needed by the DUT
@@ -158,35 +156,7 @@ def exportTests(d,tc): # Create tar file for the sdk create_tarball(d, "testexport_sdk_%s.tar.gz" % d.getVar("SDK_ARCH"), export_sdk_dir) - bb.plain("Exported tests to: %s" % exportpath) - -def testexport_main(d): - from oeqa.oetest import ExportTestContext - from oeqa.targetcontrol import get_target_controller - - test_create_extract_dirs(d) - export_dir = d.getVar("TEST_EXPORT_DIR") - bb.utils.mkdirhier(d.getVar("TEST_LOG_DIR")) - bb.utils.remove(export_dir, recurse=True) - bb.utils.mkdirhier(export_dir) - - # the robot dance - target = get_target_controller(d) - - # test context - tc = ExportTestContext(d, target) - - # this is a dummy load of tests - # we are doing that to find compile errors in the tests themselves - # before booting the image - try: - tc.loadTests() - except Exception as e: - import traceback - bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) - - tc.extract_packages() - exportTests(d,tc) + bb.plain("Exported tests to: %s" % export_path) def create_tarball(d, tar_name, src_dir):
@@ -204,7 +174,4 @@ def create_tarball(d, tar_name, src_dir): tar.close() os.chdir(current_dir) - -testexport_main[vardepsexclude] =+ "BB_ORIGENV" - inherit testimage
scripts/oe-test +8 -2
@@ -16,8 +16,14 @@ lib_path = scripts_path + '/lib' sys.path = sys.path + [lib_path] import argparse_oe import scriptutils -import scriptpath -scriptpath.add_oe_lib_path() + +# oe-test is used for testexport and it doesn't have oe lib +# so we just skip adding these libraries (not used in testexport) +try: + import scriptpath + scriptpath.add_oe_lib_path() +except ImportError: + pass from oeqa.core.context import OETestContextExecutor
Signature · 1 line
2.1.4
PATCH 55/55 selftest/runtime-test.py: Adapt test to use new runtime framework
In reply to Aníbal LimónFrom: Mariano Lopez <[email protected]>
This adapt the current runtime selftest to use the new runtime framework.
---
.../lib/oeqa/runtime/{ => cases}/selftest.json | 0
.../lib/oeqa/runtime/{ => cases}/selftest.py | 34 +++---------------
meta/lib/oeqa/selftest/runtime-test.py | 42 +++++++++++++---------
3 files changed, 31 insertions(+), 45 deletions(-)
rename meta-selftest/lib/oeqa/runtime/{ => cases}/selftest.json (100%)
rename meta-selftest/lib/oeqa/runtime/{ => cases}/selftest.py (53%)meta-selftest/lib/oeqa/runtime/cases/selftest.json renamed from meta-selftest/lib/oeqa/runtime/selftest.json +0 -0
meta-selftest/lib/oeqa/runtime/cases/selftest.py renamed from meta-selftest/lib/oeqa/runtime/selftest.py +5 -29
@@ -1,13 +1,9 @@ -import os +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends -from oeqa.oetest import oeRuntimeTest, skipModule -from oeqa.utils.commands import runCmd -from oeqa.utils.decorators import * +class Selftest(OERuntimeTestCase): -class Selftest(oeRuntimeTest): - - @skipUnlessPassed("test_ssh") - @tag("selftest_package_install") + @OETestDepends(['ssh.SSHTest.test_ssh']) def test_install_package(self): """ Summary: Check basic package installation functionality.
@@ -21,8 +17,7 @@ class Selftest(oeRuntimeTest): (status, output) = self.target.run("socat -V") self.assertEqual(status, 0, msg="socat is not installed") - @skipUnlessPassed("test_install_package") - @tag("selftest_package_install") + @OETestDepends(['selftest.Selftest.test_install_package']) def test_verify_unistall(self): """ Summary: Check basic package installation functionality.
@@ -34,22 +29,3 @@ class Selftest(oeRuntimeTest): (status, output) = self.target.run("socat -V") self.assertNotEqual(status, 0, msg="socat is still installed") - - @tag("selftest_sdk") - def test_sdk(self): - - result = runCmd("env -0") - sdk_path = search_sdk_path(result.output) - self.assertTrue(sdk_path, msg="Can't find SDK path") - - tar_cmd = os.path.join(sdk_path, "tar") - result = runCmd("%s --help" % tar_cmd) - -def search_sdk_path(env): - for line in env.split("\0"): - (key, _, value) = line.partition("=") - if key == "PATH": - for path in value.split(":"): - if "pokysdk" in path: - return path - return ""
meta/lib/oeqa/selftest/runtime-test.py +26 -16
75 lines not on this page · raw message
Signature · 1 line
2.1.4
✗ patchtest: failure for OEQA Framework Refactor & Improvements (rev4)
In reply to Aníbal Limón== Series Details ==
Series: OEQA Framework Refactor & Improvements (rev4)
Revision: 4
URL : https://patchwork.openembedded.org/series/4272/
State : failure
== Summary ==
Thank you for submitting this patch series to OpenEmbedded Core. This is an automated response. Several tests have been executed on the proposed series by patchtest resulting in the following failures:
* Patch [33/55] oeqa/core/target Add OESSHTarget to sent commands to targets using SSH Issue Shortlog does not follow expected format [test_shortlog_format] Suggested fix Commit shortlog (first line of commit message) should follow the format "<target>: <summary>"
* Issue Series does not apply on top of target branch [test_series_merge_on_head]
Suggested fix Rebase your series on top of targeted branch
Targeted branch master (currently at ce5c7075d5)
If you believe any of these test results are incorrect, please reply to the mailing list ([email protected]) raising your concerns. Otherwise we would appreciate you correcting the issues and submitting a new version of the patchset if applicable. Please ensure you add/increment the version number when sending the new version (i.e. [PATCH] -> [PATCH v2] -> [PATCH v3] -> ...).
---
Test framework: http://git.yoctoproject.org/cgit/cgit.cgi/patchtest Test suite: http://git.yoctoproject.org/cgit/cgit.cgi/patchtest-oe
Quoted 7 lines · Aníbal Limón
This patchset is related to OEQA Framework for details read the RFC send to the
Openembedded architecture ML.http://lists.openembedded.org/pipermail/openembedded-architecture/201
6-December/000351.html
Quoted 6 lines
Also adds the migration of the runtime testing leaving only selftest remains
to migrate.The testing was made using GDC Autobuilder building in different archs and running selftest.
Thanks, I'm testing this on the autobuilder, it seems mostly good but so far we've seen this issue:
https://autobuilder.yocto.io/builders/nightly-qa-skeleton/builds/145/st
eps/Running%20Sanity%20Tests/logs/stdio
Please send any further patches on top of this series.
Cheers,
Richard
Quoted 17 lines · Richard Purdie
Quoted 9 lines · Aníbal Limón
This patchset is related to OEQA Framework for details read the RFC send to the
Openembedded architecture ML.http://lists.openembedded.org/pipermail/openembedded-architecture/2
01
6-December/000351.htmlQuoted 7 lines
Also adds the migration of the runtime testing leaving only selftest
remains
to migrate.The testing was made using GDC Autobuilder building in different archs and running selftest.
Quoted 8 lines
Thanks, I'm testing this on the autobuilder, it seems mostly good but so far we've seen this issue:
https://autobuilder.yocto.io/builders/nightly-qa-skeleton/builds/145/
st
eps/Running%20Sanity%20Tests/logs/stdioPlease send any further patches on top of this series.
To update, the fix was trivial and the only issue uncovered by testing so I've merged a fix into the appropriate commit as I merged the series.
Cheers,
Richard