aboutsummaryrefslogtreecommitdiffstats
path: root/testing/command.py
diff options
context:
space:
mode:
Diffstat (limited to 'testing/command.py')
-rw-r--r--testing/command.py227
1 files changed, 227 insertions, 0 deletions
diff --git a/testing/command.py b/testing/command.py
new file mode 100644
index 000000000..4d9629989
--- /dev/null
+++ b/testing/command.py
@@ -0,0 +1,227 @@
+#############################################################################
+##
+## Copyright (C) 2017 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of PySide2.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from __future__ import print_function
+
+"""
+testrunner
+
+Provide an interface to the pyside tests.
+
+- find the latest build dir.
+ This is found by the build_history in setup.py,
+ near the end of pyside_build.run()
+
+- run 'make test' and record the output
+ (not ready)
+
+- compare the result list with the current blacklist
+
+- return the correct error status
+ (zero if expected includes observed, else 1)
+
+Recommended build process:
+There is no need to install the project.
+Building the project with something like
+
+ python setup.py build --build-tests --qmake=<qmakepath> --ignore-git --debug
+
+is sufficient. The tests are run by changing into the latest build dir and there
+into pyside2, then 'make test'.
+
+"""
+
+import os
+import sys
+import argparse
+
+from .helper import script_dir, decorate
+from .buildlog import builds
+from .blacklist import BlackList, learn_blacklist
+from .runner import TestRunner
+from .parser import TestParser
+
+def create_read_write(filename):
+ if os.path.isfile(filename):
+ # existing file, open for read and write
+ return open(filename, 'r+')
+ elif os.path.exists(filename):
+ # a directory?
+ raise argparse.ArgumentTypeError(None, "invalid file argument: %s" % filename)
+ else:
+ try:
+ return open(filename, 'w')
+ except IOError:
+ raise argparse.ArgumentError(None, "cannot create file: %s" % filename)
+
+def main():
+ # create the top-level command parser
+ parser = argparse.ArgumentParser()
+ subparsers = parser.add_subparsers(dest="subparser_name")
+
+ # create the parser for the "test" command
+ parser_test = subparsers.add_parser("test")
+ group = parser_test.add_mutually_exclusive_group(required=False)
+ blacklist_default = os.path.join(script_dir, 'build_history', 'blacklist.txt')
+ group.add_argument("--blacklist", "-b", type=argparse.FileType('r'),
+ default=blacklist_default,
+ help='a Qt blacklist file (default: {})'.format(blacklist_default))
+ group.add_argument("--learn", "-l", type=create_read_write,
+ help="add new entries to a blacklist file")
+ parser_test.add_argument("--skip", action='store_true',
+ help="skip the tests if they were run before")
+ parser_test.add_argument("--environ", nargs='+',
+ help="use name=value ... to set environment variables")
+ parser_test.add_argument("--buildno", default=-1, type=int,
+ help="use build number n (0-based), latest = -1 (default)")
+ all_projects = "shiboken2 pyside2 pyside2-tools".split()
+ tested_projects = "shiboken2 pyside2".split()
+ parser_test.add_argument("--projects", nargs='+', type=str,
+ default=tested_projects,
+ choices=all_projects,
+ help="use 'pyside2' (default) or other projects")
+ parser_getcwd = subparsers.add_parser("getcwd")
+ parser_getcwd.add_argument("filename", type=argparse.FileType('w'),
+ help="write the build dir name into a file")
+ parser_getcwd.add_argument("--buildno", default=-1, type=int,
+ help="use build number n (0-based), latest = -1 (default)")
+ parser_list = subparsers.add_parser("list")
+ args = parser.parse_args()
+
+ if hasattr(args, "buildno"):
+ try:
+ builds.set_buildno(args.buildno)
+ except IndexError:
+ print("history out of range. Try '%s list'" % __file__)
+ sys.exit(1)
+
+ if args.subparser_name == "getcwd":
+ print(builds.selected.build_dir, file=args.filename)
+ print(builds.selected.build_dir, "written to file", args.filename.name)
+ sys.exit(0)
+ elif args.subparser_name == "test":
+ pass # we do it afterwards
+ elif args.subparser_name == "list":
+ rp = os.path.relpath
+ print()
+ print("History")
+ print("-------")
+ for idx, build in enumerate(builds.history):
+ print(idx, rp(build.log_dir), rp(build.build_dir))
+ print()
+ print("Note: only the last history entry of a folder is valid!")
+ sys.exit(0)
+ else:
+ parser.print_help()
+ sys.exit(1)
+
+ if args.blacklist:
+ args.blacklist.close()
+ bl = BlackList(args.blacklist.name)
+ elif args.learn:
+ args.learn.close()
+ learn_blacklist(args.learn.name, result.result, builds.selected)
+ bl = BlackList(args.learn.name)
+ else:
+ bl = BlackList(None)
+ if args.environ:
+ for line in args.environ:
+ things = line.split("=")
+ if len(things) != 2:
+ raise ValueError("you need to pass one or more name=value pairs.")
+ key, value = things
+ os.environ[key] = value
+
+ print("System:\n Platform=%s\n Executable=%s\n Version=%s\n API version=%s\n\nEnvironment:" %
+ (sys.platform, sys.executable, sys.version.replace("\n", " "), sys.api_version))
+ for v in sorted(os.environ.keys()):
+ print(" %s=%s" % (v, os.environ[v]))
+ print()
+
+ q = 5 * [0]
+
+ # now loop over the projects and accumulate
+ for project in args.projects:
+ runner = TestRunner(builds.selected, project)
+ if os.path.exists(runner.logfile) and args.skip:
+ print("Parsing existing log file:", runner.logfile)
+ else:
+ runner.run(10 * 60)
+ result = TestParser(runner.logfile)
+ r = 5 * [0]
+ print("********* Start testing of %s *********" % project)
+ print("Config: Using", " ".join(builds.classifiers))
+ for test, res in result.iter_blacklist(bl):
+ print("%-6s" % res, ":", decorate(test) + "()")
+ r[0] += 1 if res == "PASS" else 0
+ r[1] += 1 if res == "FAIL" else 0
+ r[2] += 1 if res == "SKIPPED" else 0 # not yet supported
+ r[3] += 1 if res == "BFAIL" else 0
+ r[4] += 1 if res == "BPASS" else 0
+ print("Totals:", sum(r), "tests.",
+ "{} passed, {} failed, {} skipped, {} blacklisted, {} bpassed."
+ .format(*r))
+ print("********* Finished testing of %s *********" % project)
+ print()
+ q = list(map(lambda x, y: x+y, r, q))
+
+ if len(args.projects) > 1:
+ print("All above projects:", sum(q), "tests.",
+ "{} passed, {} failed, {} skipped, {} blacklisted, {} bpassed."
+ .format(*q))
+ print()
+
+ # nag us about unsupported projects
+ ap, tp = set(all_projects), set(tested_projects)
+ if ap != tp:
+ print("+++++ Note: please support", " ".join(ap-tp), "+++++")
+ print()
+
+ for project in args.projects:
+ runner = TestRunner(builds.selected, project)
+ result = TestParser(runner.logfile)
+ for test, res in result.iter_blacklist(bl):
+ if res == "FAIL":
+ raise ValueError("At least one failure was not blacklisted")
+ # the makefile does run, although it does not find any tests.
+ # We simply check if any tests were found.
+ if len(result) == 0:
+ path = builds.selected.build_dir
+ project = os.path.join(path, args.project)
+ raise ValueError("there are no tests in %s" % project)