aboutsummaryrefslogtreecommitdiffstats
path: root/testing
diff options
context:
space:
mode:
Diffstat (limited to 'testing')
-rw-r--r--testing/__init__.py41
-rw-r--r--testing/blacklist.py50
-rw-r--r--testing/buildlog.py57
-rw-r--r--testing/command.py78
-rw-r--r--testing/helper.py41
-rw-r--r--testing/parser.py42
-rw-r--r--testing/runner.py76
-rw-r--r--testing/wheel_tester.py237
8 files changed, 210 insertions, 412 deletions
diff --git a/testing/__init__.py b/testing/__init__.py
index ca4e621ce..62614c438 100644
--- a/testing/__init__.py
+++ b/testing/__init__.py
@@ -1,41 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2017 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $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$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
"""
testing/__init__.py
@@ -46,6 +10,7 @@ testing/__init__.py
import builtins
import sys
+
from . import command
main = command.main
diff --git a/testing/blacklist.py b/testing/blacklist.py
index 09848dce4..eacb51cbb 100644
--- a/testing/blacklist.py
+++ b/testing/blacklist.py
@@ -1,41 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2017 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $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$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
"""
testing/blacklist.py
@@ -46,8 +10,9 @@ find_matching_line() adds info using classifiers.
"""
from io import StringIO
-from .helper import decorate
+
from .buildlog import builds
+from .helper import decorate
class BlackList(object):
@@ -63,7 +28,7 @@ class BlackList(object):
def filtered_line(line):
if "#" in line:
- line = line[line.index("#")]
+ line = line[:line.index("#")]
return line.split()
# now put every bracketed line in a test
@@ -77,7 +42,6 @@ class BlackList(object):
# nothing supplied
return
- self.index = {}
for idx, line in enumerate(lines):
fline = filtered_line(line)
if not fline:
@@ -92,8 +56,8 @@ class BlackList(object):
if is_test(fline):
# a new name
name = decorate(fline[0][1:-1])
- self.tests[name] = []
- self.index[name] = idx
+ # Allow for repeated sections
+ self.tests.setdefault(name, [])
elif fline:
# a known name with a new entry
self.tests[name].append(fline)
diff --git a/testing/buildlog.py b/testing/buildlog.py
index d268c1ac3..f82191f91 100644
--- a/testing/buildlog.py
+++ b/testing/buildlog.py
@@ -1,41 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2017 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python
-##
-## $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$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
"""
testing/buildlog.py
@@ -46,8 +10,9 @@ BuildLog.classifiers finds the set of classifier strings.
"""
import os
-import sys
+import platform
import shutil
+import sys
from collections import namedtuple
from textwrap import dedent
@@ -112,6 +77,7 @@ class BuildLog(object):
# we take the latest build for now.
build_history.sort()
self.history = build_history
+ self.python_version = None
self._buildno = None
if not is_ci:
# there seems to be a timing problem in RHel 7.6, so we better don't touch it
@@ -160,8 +126,8 @@ class BuildLog(object):
if not self.selected:
raise ValueError("+++ No build with the configuration found!")
# Python2 legacy: Correct 'linux2' to 'linux', recommended way.
- platform = "linux" if sys.platform.startswith("linux") else sys.platform
- res = [platform, "qt6"]
+ plat_name = "linux" if sys.platform.startswith("linux") else sys.platform
+ res = [plat_name, "qt6"]
if is_ci:
res.append("ci")
if self.selected.build_classifiers:
@@ -172,6 +138,9 @@ class BuildLog(object):
path = self.selected.build_dir
base = os.path.basename(path)
res.extend(base.split("-"))
+ # add exact Python version
+ if self.python_version:
+ res.append("py" + ".".join(map(str, self.python_version)))
# add all the python and qt subkeys
for entry in res:
parts = entry.split(".")
@@ -179,7 +148,13 @@ class BuildLog(object):
key = ".".join(parts[:idx])
if key not in res:
res.append(key)
+ # Allow to check the processor.
+ # This gives "i386" or "arm" on macOS.
+ res.append(platform.processor())
return res
+ def set_python_version(self, version_triple):
+ self.python_version = version_triple
+
builds = BuildLog()
diff --git a/testing/command.py b/testing/command.py
index 307a59761..31a48f87c 100644
--- a/testing/command.py
+++ b/testing/command.py
@@ -1,41 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2017 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $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$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
"""
testrunner
@@ -70,23 +34,24 @@ The full mode can be tested locally by setting
export COIN_RERUN_FAILED_ONLY=0
"""
+import argparse
import os
import sys
-import argparse
-from textwrap import dedent
from collections import OrderedDict
+from textwrap import dedent
from timeit import default_timer as timer
-from .helper import script_dir, decorate
-from .buildlog import builds
from .blacklist import BlackList
-from .runner import TestRunner
+from .buildlog import builds
+from .helper import decorate, script_dir
from .parser import TestParser
+from .runner import TestRunner
# Should we repeat only failed tests?
COIN_RERUN_FAILED_ONLY = True
COIN_THRESHOLD = 3 # report error if >=
COIN_TESTING = 5 # number of runs
+TIMEOUT = 20 * 60
if os.environ.get("COIN_RERUN_FAILED_ONLY", "1").lower() in "0 f false n no".split():
COIN_RERUN_FAILED_ONLY = False
@@ -95,6 +60,14 @@ if os.environ.get("COIN_RERUN_FAILED_ONLY", "1").lower() in "0 f false n no".spl
def test_project(project, args, blacklist, runs):
ret = []
+ if "pypy" in builds.classifiers:
+ # As long as PyPy has so many bugs, we use 1 test only...
+ global COIN_TESTING
+ COIN_TESTING = runs = 1
+ # ...and extend the timeout.
+ global TIMEOUT
+ TIMEOUT = 100 * 60
+
# remove files from a former run
for idx in range(runs):
index = idx + 1
@@ -106,6 +79,8 @@ def test_project(project, args, blacklist, runs):
for idx in range(runs):
index = idx + 1
runner = TestRunner(builds.selected, project, index)
+ # For the full Python version we need to ask the TestRunner.
+ builds.set_python_version(runner.get_python_version())
print()
print(f"********* Start testing of {project} *********")
print("Config: Using", " ".join(builds.classifiers))
@@ -120,7 +95,7 @@ def test_project(project, args, blacklist, runs):
break
else:
rerun = None
- runner.run(f"RUN {idx + 1}:", rerun, 10 * 60)
+ runner.run(f"RUN {idx + 1}:", rerun, TIMEOUT)
results = TestParser(runner.logfile)
r = 5 * [0]
rerun_list = []
@@ -154,7 +129,7 @@ def test_project(project, args, blacklist, runs):
print("FATAL ERROR:", fatal)
print("Repetitions cancelled!")
break
- return ret, fatal
+ return ret, fatal, runs
def main():
@@ -261,14 +236,15 @@ def main():
key, value = things
os.environ[key] = value
+ version = sys.version.replace("\n", " ")
print(
dedent(
- """\
+ f"""\
System:
- Platform={sys.__dict__["platform"]}
- Executable={sys.__dict__["executable"]}
- Version={sys.version.replace("\n", " ")}
- API version={sys.__dict__["api_version"]}
+ Platform={sys.platform}
+ Executable={sys.executable}
+ Version={version}
+ API version={sys.api_version}
Environment:"""
)
@@ -284,7 +260,7 @@ def main():
# now loop over the projects and accumulate
fatal = False
for project in args.projects:
- res, fatal = test_project(project, args, bl, runs)
+ res, fatal, runs = test_project(project, args, bl, runs)
if fatal:
runs = 1
for idx, r in enumerate(res):
diff --git a/testing/helper.py b/testing/helper.py
index a8d3a65ff..d89f0d849 100644
--- a/testing/helper.py
+++ b/testing/helper.py
@@ -1,41 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2017 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $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$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
"""
testing/helper.py
@@ -45,7 +9,6 @@ Some tools that do not fit elsewhere.
import os
-
script_dir = os.path.dirname(os.path.dirname(__file__))
diff --git a/testing/parser.py b/testing/parser.py
index 7e1e6c792..a01c4d029 100644
--- a/testing/parser.py
+++ b/testing/parser.py
@@ -1,41 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2017 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $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$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import os
import re
@@ -129,7 +93,7 @@ def _parse_tests(test_log):
match = re.match(pat, line, re.VERBOSE)
if match and line.split()[-1] != "sec":
# don't change the number of lines
- lines[idx : idx + 2] = [line.rstrip() + lines[idx + 1], ""]
+ lines[idx:idx + 2] = [line.rstrip() + lines[idx + 1], ""]
pat = _TEST_PAT
for line in lines:
diff --git a/testing/runner.py b/testing/runner.py
index 50c08d21d..b52ac4937 100644
--- a/testing/runner.py
+++ b/testing/runner.py
@@ -1,50 +1,13 @@
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the Qt for Python project.
-##
-## $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$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+import inspect
import os
-import sys
import re
import subprocess
-import inspect
-
-from textwrap import dedent
+import sys
from subprocess import TimeoutExpired
+from textwrap import dedent
# Get the dir path to the utils module
try:
@@ -53,10 +16,10 @@ except NameError:
this_file = sys.argv[0]
this_file = os.path.abspath(this_file)
this_dir = os.path.dirname(this_file)
-build_scripts_dir = os.path.abspath(os.path.join(this_dir, "../build_scripts"))
+build_scripts_dir = os.path.abspath(os.path.join(this_dir, ".."))
sys.path.append(build_scripts_dir)
-from utils import detect_clang
+from build_scripts.utils import detect_clang
class TestRunner(object):
@@ -73,6 +36,31 @@ class TestRunner(object):
self._setup_clang()
self._setup()
+ def get_python_version(self):
+ """
+ Finding the exact Python version.
+ ---------------------------------
+
+ This is done by asking the interpreter, because it cannot reliably
+ be found from any file name parsing as a triple.
+
+ Note: We need to look into the CMakeCache.txt file to find out
+ what CMake has found as the Python interpreter to use.
+ This is *not* necessarily the same Python that runs this script,
+ otherwise we could use the version info directly.
+ """
+ look_python = os.path.join(self.test_dir, "CMakeCache.txt")
+ look_for = "PYTHON_EXECUTABLE:FILEPATH="
+ with open(look_python) as f:
+ for line in f:
+ if line.startswith(look_for):
+ python_exec = line.split("=")[-1].strip()
+ res = subprocess.run([python_exec, "-c",
+ "import sys;print(sys.version_info[:3])"],
+ capture_output=True)
+ return eval(res.stdout.decode("utf-8"))
+ return None
+
def _setup_clang(self):
if sys.platform != "win32":
return
diff --git a/testing/wheel_tester.py b/testing/wheel_tester.py
index 567d2380e..b36ee55a4 100644
--- a/testing/wheel_tester.py
+++ b/testing/wheel_tester.py
@@ -1,41 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $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$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
"""
This script is used by Coin (coin_test_instructions.py specifically) to
@@ -52,11 +16,15 @@ Make sure that some generated wheels already exist in the dist/
directory (e.g. setup.py bdist_wheel was already executed).
"""
-from argparse import ArgumentParser, RawTextHelpFormatter
-from pathlib import Path
import os
+import platform
+import shutil
import sys
import tempfile
+import logging
+from argparse import ArgumentParser, RawTextHelpFormatter
+from pathlib import Path
+from configparser import ConfigParser
try:
this_file = __file__
@@ -67,14 +35,13 @@ this_dir = os.path.dirname(this_file)
setup_script_dir = os.path.abspath(os.path.join(this_dir, ".."))
sys.path.append(setup_script_dir)
-from build_scripts.utils import find_files_using_glob
-from build_scripts.utils import find_glob_in_path
-from build_scripts.utils import run_process, run_process_output
-from build_scripts.utils import rmtree
-import distutils.log as log
-import platform
+from build_scripts.utils import (find_files_using_glob, find_glob_in_path, # noqa: E402
+ remove_tree, run_process, run_process_output)
+from build_scripts.log import log # noqa: E402
+
+log.setLevel(logging.DEBUG)
-log.set_verbosity(1)
+NEW_WHEELS = False
def find_executable(executable, command_line_value):
@@ -104,8 +71,8 @@ QMAKE_PATH = None
CMAKE_PATH = None
-def get_wheels_dir():
- return os.path.join(setup_script_dir, "dist")
+def get_wheels_dir(dir_name):
+ return os.path.join(setup_script_dir, dir_name)
def get_examples_dir():
@@ -115,7 +82,11 @@ def get_examples_dir():
def package_prefix_names():
# Note: shiboken6_generator is not needed for compile_using_nuitka,
# but building modules with cmake needs it.
- return ["shiboken6", "shiboken6_generator", "PySide6"]
+ if NEW_WHEELS:
+ return ["shiboken6", "shiboken6_generator", "PySide6_Essentials", "PySide6_Addons",
+ "PySide6"]
+ else:
+ return ["shiboken6", "shiboken6_generator", "PySide6"]
def clean_egg_info():
@@ -128,7 +99,7 @@ def clean_egg_info():
paths = find_files_using_glob(setup_script_dir, "*.egg-info")
for p in paths:
log.info(f"Removing {p}")
- rmtree(p)
+ remove_tree(p)
def install_wheel(wheel_path):
@@ -167,40 +138,19 @@ def try_install_wheels(wheels_dir, py_version):
)
-def is_unix():
- if sys.platform.startswith("linux") or sys.platform == "darwin":
- return True
- return False
-
-
def generate_build_cmake():
- args = [CMAKE_PATH]
- if is_unix():
- args.extend(["-G", "Unix Makefiles"])
- else:
- args.extend(["-G", "NMake Makefiles"])
- args.append("-DCMAKE_BUILD_TYPE=Release")
- args.append(f"-Dpython_interpreter={sys.executable}")
-
- # Specify prefix path so find_package(Qt5) works.
- qmake_dir = os.path.abspath(os.path.join(os.path.dirname(QMAKE_PATH), ".."))
- args.append(f"-DCMAKE_PREFIX_PATH={qmake_dir}")
-
- args.append("..")
-
+ # Specify prefix path so find_package(Qt6) works.
+ qmake_dir = Path(QMAKE_PATH).resolve().parent.parent
+ args = [CMAKE_PATH, "-G", "Ninja", "-DCMAKE_BUILD_TYPE=Release",
+ f"-Dpython_interpreter={sys.executable}",
+ f"-DCMAKE_PREFIX_PATH={qmake_dir}",
+ ".."]
exit_code = run_process(args)
if exit_code:
raise RuntimeError("Failure while running cmake.")
log.info("")
-def generate_build_qmake():
- exit_code = run_process([QMAKE_PATH, "..", f"python_interpreter={sys.executable}"])
- if exit_code:
- raise RuntimeError("Failure while running qmake.")
- log.info("")
-
-
def raise_error_pyinstaller(msg):
print()
print(f"PYINST: {msg}")
@@ -255,32 +205,73 @@ def run_nuitka_test(example):
raise RuntimeError(f"Failure running {example} with Nuitka.")
-def run_make():
- args = []
- if is_unix():
- executable = "make"
+def _run_deploy_test(example, tmpdirname):
+ """Helper for running deployment and example."""
+ main_file = None
+ for py_file in example.glob("*.py"):
+ shutil.copy(py_file, tmpdirname)
+ if not main_file or py_file.name == "main.py":
+ main_file = py_file
+ deploy_tool = Path(sys.executable).parent / "pyside6-deploy"
+ cmd = [os.fspath(deploy_tool), "-f", main_file.name, "--init"]
+ if run_process(cmd) != 0:
+ raise RuntimeError("Error creating pysidedeploy.spec")
+
+ config_file = Path(tmpdirname) / "pysidedeploy.spec"
+ parser = ConfigParser(comment_prefixes="/", allow_no_value=True)
+ parser.read(config_file)
+ parser.set("nuitka", "extra_args", "--verbose --assume-yes-for-downloads")
+ with open(config_file, "w+") as config_file_writer:
+ parser.write(config_file_writer, space_around_delimiters=True)
+
+ cmd = [os.fspath(deploy_tool), "-f", "-c", os.fspath(config_file)]
+ if run_process(cmd) != 0:
+ raise RuntimeError("Error deploying")
+
+ suffix = "exe" if sys.platform == "win32" else "bin"
+
+ if sys.platform != "darwin":
+ binary = f"{tmpdirname}/{main_file.stem}.{suffix}"
else:
- executable = "nmake"
- args.append(executable)
+ binary = f"{tmpdirname}/pyside_app_demo.app/Contents/MacOS/{main_file.stem}"
+
+ if run_process([binary]) != 0:
+ raise RuntimeError("Error running the deployed example")
+ return True
+
+def run_deploy_test(example):
+ """Test pyside6-deploy."""
+ log.info(f"Running deploy test of {example}")
+ current_dir = Path.cwd()
+ result = False
+ with tempfile.TemporaryDirectory() as tmpdirname:
+ try:
+ os.chdir(tmpdirname)
+ result = _run_deploy_test(example, tmpdirname)
+ except RuntimeError as e:
+ log.error(str(e))
+ raise e
+ finally:
+ os.chdir(os.fspath(current_dir))
+ state = "succeeded" if result else "failed"
+ log.info(f"Deploy test {state}")
+ return result
+
+
+def run_ninja():
+ args = ["ninja"]
exit_code = run_process(args)
if exit_code:
- raise RuntimeError(f"Failure while running {executable}.")
+ raise RuntimeError(f"Failure while running {' '.join(args)}.")
log.info("")
-def run_make_install():
- args = []
- if is_unix():
- executable = "make"
- else:
- executable = "nmake"
- args.append(executable)
- args.append("install")
-
+def run_ninja_install():
+ args = ["ninja", "install"]
exit_code = run_process(args)
if exit_code:
- raise RuntimeError(f"Failed while running {executable} install.")
+ raise RuntimeError(f"Failed while running {' '.join(args)} install.")
log.info("")
@@ -307,7 +298,7 @@ def prepare_build_folder(src_path, build_folder_name):
# preparing a build folder should clean any previous existing build.
if os.path.exists(build_path):
log.info(f"Removing {build_path}")
- rmtree(build_path)
+ remove_tree(build_path)
log.info(f"Creating {build_path}")
os.makedirs(build_path)
@@ -330,30 +321,31 @@ def try_build_examples():
log.info("Attempting to build hello.py using Nuitka.")
src_path = Path(examples_dir) / "installer_test"
- # Nuitka is loaded by coin_build_instructions.py, but not when
- # testing directly this script.
- run_nuitka_test(os.fspath(src_path / "hello.py"))
+
+ # disable for windows as it Nuitka --onefile deployment in Windows
+ # requires DependencyWalker. Download and installing will slow down
+ # Coin
+ if sys.platform != "win32":
+ run_deploy_test(src_path)
+
+ if False: # pre 6.4.1, kept for reference
+ # Nuitka is loaded by coin_build_instructions.py, but not when
+ # testing directly this script.
+ run_nuitka_test(os.fspath(src_path / "hello.py"))
log.info("Attempting to build and run samplebinding using cmake.")
src_path = os.path.join(examples_dir, "samplebinding")
prepare_build_folder(src_path, "cmake")
generate_build_cmake()
- run_make()
- run_make_install()
+ run_ninja()
+ run_ninja_install()
execute_script(os.path.join(src_path, "main.py"))
- log.info("*** Defunct: build scriptableapplication using cmake.")
- # log.info("Attempting to build scriptableapplication using cmake.")
- # src_path = os.path.join(examples_dir, "scriptableapplication")
- # prepare_build_folder(src_path, "cmake")
- # generate_build_cmake()
- # run_make()
-
- log.info("Attempting to build scriptableapplication using qmake.")
+ log.info("Attempting to build scriptableapplication using cmake.")
src_path = os.path.join(examples_dir, "scriptableapplication")
- prepare_build_folder(src_path, "qmake")
- generate_build_qmake()
- run_make()
+ prepare_build_folder(src_path, "cmake")
+ generate_build_cmake()
+ run_ninja()
if sys.version_info[:2] >= (3, 7):
log.info("Checking Python Interface Files in Python 3 with all features selected")
@@ -372,11 +364,13 @@ def try_build_examples():
from PySide6 import __all__ as modules
for modname in modules:
- execute_script(src_path / f"{modname}.pyi")
+ # PYSIDE-1735: pyi files are no longer compatible with Python.
+ # XXX Maybe add a test with Mypy here?
+ pass # execute_script(src_path / f"{modname}.pyi")
-def run_wheel_tests(install_wheels):
- wheels_dir = get_wheels_dir()
+def run_wheel_tests(install_wheels, wheels_dir_name):
+ wheels_dir = get_wheels_dir(wheels_dir_name)
py_version = f"{sys.version_info.major}.{sys.version_info.minor}"
if install_wheels:
@@ -384,8 +378,13 @@ def run_wheel_tests(install_wheels):
try_install_wheels(wheels_dir, py_version)
log.info("Attempting to build examples.\n")
- try_build_examples()
+ bin_dir = os.fspath(Path(sys.executable).parent)
+ path = os.environ["PATH"]
+ if bin_dir not in path:
+ log.info(f"Adding {bin_dir} to PATH...")
+ os.environ["PATH"] = f"{bin_dir}{os.pathsep}{path}"
+ try_build_examples()
log.info("All tests passed!")
@@ -399,8 +398,12 @@ if __name__ == "__main__":
)
parser.add_argument("--qmake", type=str, help="Path to qmake")
parser.add_argument("--cmake", type=str, help="Path to cmake")
+ parser.add_argument("--wheels-dir", type=str, help="Path to where the wheels are",
+ default="dist")
+ parser.add_argument("--new", action="store_true", help="Option to test new wheels")
options = parser.parse_args()
QMAKE_PATH = find_executable("qmake", options.qmake)
CMAKE_PATH = find_executable("cmake", options.cmake)
+ NEW_WHEELS = options.new
- run_wheel_tests(not options.no_install_wheels)
+ run_wheel_tests(not options.no_install_wheels, options.wheels_dir)