On 22. 5. 26 11:50, [email protected] wrote:
Author: brane
Date: Fri May 22 09:50:14 2026
New Revision: 1934497

Log:
Allow the tests to work with a non-standart Python 3 installation that
does not provide the 'venv' module.


This commit addresses some of Ivan's concerns.

1. The 'venv' module isn't available

'venv' is part of the Python standard library, so strictly speaking, it should always be available to the tests. But it's no big deal to make it conditional. If it's not present, the test driver won't attempt to create a virtual environment or download any dependencies.

2. Dependency version pinning

Done. Not doing that from the start was an omission on my part.

3. Do not download stuff / allow offline testing

This has always been possible, either by installing the optional dependencies (lxml and rnc2rng), or by telling the test runner that its --python-venv=/somewhere/that/does/not/exist. In either case, the test runner won't try to download anything.

The open question now is: what should be the default. IMO we should always do our best to validate our XML output, and if that means downloading lxml & co., then so be it. It's the preferred configuration for developer and CI testing, and there are three ways to avoid those downloads. May the mayhem discussion begin.



It has also always been the case that if those two modules aren't available, we won't validate the XML output against the schema. It turns out that we had two additional issues:

 * two of the log tests that were marked @Xfail() for other reasons
   actually succeed now, but they write invalid XML;
 * the predicate that checks if we're validating XML was not doing what
   it said on the tin.


I fixed the predicate and updated the annotations on those two tests. However, when testing over DAV, one of those two tests returns valid XML... so I'll have to tweak that XFail predicate some more.


-- Brane

* Makefile.in (check): Expose the --python-venv test runner flag through
    the PYTHON_VENV make variable.

* subversion/tests/cmdline/svntest/main.py:
    Do not require the 'venv' module to be present.
   (venv_create): The default value now depends on the presence of 'venv'.
   (SVN_TESTS_REQUIRE): Pin the dependency versions.
   (SVN_TESTS_DEPEND): New; dependency import module names. Use these
    wherever we're checking for module presence as opposed to installing them.
   (is_bad_xml_fatal): Fix a silly thinko in the predicaste.
   (create_python_venv): Require 'venv' presence.

* subversion/tests/cmdline/log_tests.py
   (log_with_merge_history_and_search,
    log_xml_with_merge_history): These tests pass the functional part and
     fail only when XML validation is enabled because they emit invalid XML.
     Update the predicates.

Modified:
    subversion/trunk/Makefile.in
    subversion/trunk/subversion/tests/cmdline/log_tests.py
    subversion/trunk/subversion/tests/cmdline/svntest/main.py

Modified: subversion/trunk/Makefile.in
==============================================================================
--- subversion/trunk/Makefile.in        Fri May 22 09:32:54 2026        
(r1934496)
+++ subversion/trunk/Makefile.in        Fri May 22 09:50:14 2026        
(r1934497)
@@ -634,6 +634,9 @@ check: bin @TRANSFORM_LIBTOOL_SCRIPTS@ $
          if test "$(SVN_BIN_DIR)" != ""; then                               \
            flags="--bin $(SVN_BIN_DIR) $$flags";                            \
          fi;                                                                \
+         if test "$(PYTHON_VENV)" != ""; then                               \
+           flags="--python-venv $(PYTHON_VENV) $$flags";                    \
+         fi;                                                                \
          if test "$(STORE_PRISTINE)" != ""; then                            \
flags="--store-pristine $(STORE_PRISTINE) $$flags"; \ fi; \ Modified: subversion/trunk/subversion/tests/cmdline/log_tests.py ============================================================================== --- subversion/trunk/subversion/tests/cmdline/log_tests.py Fri May 22 09:32:54 2026 (r1934496) +++ subversion/trunk/subversion/tests/cmdline/log_tests.py Fri May 22 09:50:14 2026 (r1934497) @@ -2778,7 +2778,7 @@ def log_on_deleted_deep(sbox): '', '-q', '-c', '1-2') -@XFail() +@XFail(svntest.main.is_bad_xml_fatal) @Issue(4711) def log_with_merge_history_and_search(sbox): "log --use-merge-history --search" @@ -2804,7 +2804,7 @@ def log_with_merge_history_and_search(sb sbox.ospath('A2')) svntest.verify.validate_xml_schema('log', output) -@XFail(svntest.main.is_ra_type_file) +@XFail(svntest.main.is_bad_xml_fatal) @Issue(4856) def log_xml_with_merge_history(sbox): "log --use-merge-history --xml" Modified: subversion/trunk/subversion/tests/cmdline/svntest/main.py ============================================================================== --- subversion/trunk/subversion/tests/cmdline/svntest/main.py Fri May 22 09:32:54 2026 (r1934496) +++ subversion/trunk/subversion/tests/cmdline/svntest/main.py Fri May 22 09:50:14 2026 (r1934497) @@ -40,7 +40,13 @@ import importlib import zipfile import codecs import queue -import venv + +# Even though 'venv' is part of the Python3 standard library, +# some environment don't provide it. The tests do not require it. +try: + import venv +except ImportError: + venv = None from urllib.parse import quote as urllib_parse_quote from urllib.parse import unquote as urllib_parse_unquote @@ -223,13 +229,15 @@ work_dir = "svn-test-work" # Directory for the Python virtual environment where we install
  # external dependencies of the test environment
+venv_create = venv is not None
  venv_base = work_dir
-venv_path = lambda: os.path.join(venv_base, "__venv__")
-venv_create = True
+def venv_path():
+  return os.path.join(venv_base, "__venv__")
# List of dependencies
  found_dependencies = set()
-SVN_TESTS_REQUIRE = ["lxml", "rnc2rng"]
+SVN_TESTS_REQUIRE = ["lxml==6.1.0", "rnc2rng==2.7.0"]  # for pip
+SVN_TESTS_DEPEND = ["lxml", "rnc2rng"]  # for install_module
# Constant for the merge info property.
  SVN_PROP_MERGEINFO ="svn:mergeinfo"
@@ -1760,7 +1768,8 @@ def is_remote_http_connection_allowed():
  def is_bad_xml_fatal():
    """Are we treating invalid XML output as a fatal error?"""
    # Only if we have all the necessary dependencies.
-  return {'lxml', 'rnc2rnd'} & found_dependencies
+  depends = {'lxml', 'rnc2rng'}
+  return depends == (depends & found_dependencies)
def wc_format(ver=None):
@@ -2462,7 +2471,7 @@ def ensure_dependencies():
    saved_sys_path = sys.path[:]
    try:
      sys.path.insert(0, package_path)
-    for package in SVN_TESTS_REQUIRE:
+    for package in SVN_TESTS_DEPEND:
        importlib.import_module(package)
        found_dependencies.add(package)
      have_required = True
@@ -2482,11 +2491,14 @@ def ensure_dependencies():
        assert python_path == package_path
        if package_path not in sys.path:
          sys.path.append(package_path)
-      found_dependencies.update(set(SVN_TESTS_REQUIRE))
+      found_dependencies.update(set(SVN_TESTS_DEPEND))
        return package_path
    return None
def create_python_venv(venv_dir, quiet=False):
+  # We should never get this far if the 'venv' module isn't available.
+  assert venv is not None
+
    try:
      # Create the virtual environment
      if not os.path.isdir(venv_dir):

Reply via email to