Author: ivan
Date: Tue Jun 23 13:33:58 2026
New Revision: 1935586

Log:
On 'xml-schema-validation-improvements' branch:

Always use installed lxml and rnc2rng Python packages to validate XML output
of `svn --xml` in tests.

This change also makes these package mandatory for running tests unless new
option `--disable-xml-schema-validation` is specified.

* build/run_tests.py
  (_init_py_tests): Remove `--python-venv`. Add
   `--disable-xml-schema-validation`. Do not download Python packages and
   do not update PYTHONPATH environment variable.
  (create_parser): Remove `--python-venv`. Add
   `--disable-xml-schema-validation`.

* Makefile.in
  (check): Remove PYTHON_VENV argument handling. Add
   DISABLE_XML_SCHEMA_VALIDATION.

* subversion/tests/cmdline/log_tests.py
  (is_ra_local_and_is_bad_xml_fatal): Remove.
  (log_with_merge_history_and_search, log_xml_with_merge_history): Use
   is_xml_schema_validation_enabled() instead of is_bad_xml_fatal().

* subversion/tests/cmdline/prop_tests.py
  (xml_unsafe_author2): Use is_xml_schema_validation_enabled() instead of
   is_bad_xml_fatal().
   
* subversion/tests/cmdline/svntest/main.py
  (): Do not import venv package.
  (venv_create, venv_base, found_dependencies, SVN_TESTS_REQUIRE,
   SVN_TESTS_DEPEND): Remove.
  (is_bad_xml_fatal): Remove.
  (is_xml_schema_validation_enabled): New.
  (TestSpawningThread.run_one): Remove options.venv_base handling. Handle
   options.disable_xml_schema_validation.
  (_create_parser): Remove `--python-venv`. Add
   `--disable-xml-schema-validation`.
  (parse_options): Remove options.venv_base handling.
  (_get_purelib_dir, ensure_dependencies, create_python_venv): Remove.
  (execute_tests): Do not call ensure_dependencies().

* subversion/tests/cmdline/svntest/verify.py
  (validate_xml_schema): Do not nothing if XML schema validation is disabled.
   Consider XML schema validation errors as test failure.

Modified:
   subversion/branches/xml-schema-validation-improvements/Makefile.in
   subversion/branches/xml-schema-validation-improvements/build/run_tests.py
   
subversion/branches/xml-schema-validation-improvements/subversion/tests/cmdline/log_tests.py
   
subversion/branches/xml-schema-validation-improvements/subversion/tests/cmdline/prop_tests.py
   
subversion/branches/xml-schema-validation-improvements/subversion/tests/cmdline/svntest/main.py
   
subversion/branches/xml-schema-validation-improvements/subversion/tests/cmdline/svntest/verify.py

Modified: subversion/branches/xml-schema-validation-improvements/Makefile.in
==============================================================================
--- subversion/branches/xml-schema-validation-improvements/Makefile.in  Tue Jun 
23 12:54:08 2026        (r1935585)
+++ subversion/branches/xml-schema-validation-improvements/Makefile.in  Tue Jun 
23 13:33:58 2026        (r1935586)
@@ -642,9 +642,6 @@ 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;                                                                \
@@ -654,6 +651,9 @@ check: bin @TRANSFORM_LIBTOOL_SCRIPTS@ $
          if test "$(VALGRIND_OPTS)" != ""; then                             \
            flags="--valgrind-opts $(VALGRIND_OPTS) $$flags";                \
          fi;                                                                \
+         if test "$(DISABLE_XML_SCHEMA_VALIDATION)" != ""; then             \
+           flags="--disable-xml-schema-validation $$flags";                 \
+         fi;                                                                \
          LD_LIBRARY_PATH='$(auth_plugin_dirs):$(LD_LIBRARY_PATH)'           \
          $(PYTHON) $(top_srcdir)/build/run_tests.py                         \
                    --config-file $(top_srcdir)/subversion/tests/tests.conf  \

Modified: 
subversion/branches/xml-schema-validation-improvements/build/run_tests.py
==============================================================================
--- subversion/branches/xml-schema-validation-improvements/build/run_tests.py   
Tue Jun 23 12:54:08 2026        (r1935585)
+++ subversion/branches/xml-schema-validation-improvements/build/run_tests.py   
Tue Jun 23 13:33:58 2026        (r1935586)
@@ -259,8 +259,6 @@ class TestHarness:
       cmdline.append('--tools-bin=%s' % self.opts.tools_bin)
     if self.opts.svn_bin is not None:
       cmdline.append('--bin=%s' % self.opts.svn_bin)
-    if self.opts.venv_base is not None:
-      cmdline.append('--python-venv=%s' % self.opts.venv_base)
     if self.opts.url is not None:
       cmdline.append('--url=%s' % self.opts.url)
     if self.opts.fs_type is not None:
@@ -317,6 +315,8 @@ class TestHarness:
       cmdline.append('--valgrind=%s' % self.opts.valgrind)
     if self.opts.valgrind_opts is not None:
       cmdline.append('--valgrind-opts=%s' % self.opts.valgrind_opts)
+    if self.opts.disable_xml_schema_validation is not None:
+      cmdline.append('--disable-xml-schema-validation')
 
     self.py_test_cmdline = cmdline
 
@@ -330,15 +330,6 @@ class TestHarness:
       svntest = importlib.import_module('svntest')
       svntest.main.parse_options(cmdline, optparse.SUPPRESS_USAGE)
       svntest.testcase.TextColors.disable()
-      dependency_path = svntest.main.ensure_dependencies()
-
-      # We have to update PYTHONPATH, otherwise the whole setting up of a
-      # virtualenv and installing dependencies will happen for every test case.
-      if dependency_path:
-        python_path = os.environ.get("PYTHONPATH")
-        python_path = (dependency_path if not python_path
-                       else "%s:%s" % (dependency_path, python_path))
-        os.environ["PYTHONPATH"] = python_path
     finally:
       os.chdir(old_cwd)
 
@@ -1041,9 +1032,6 @@ def create_parser():
                     help='Use the svn binaries installed in this path')
   parser.add_option('--tools-bin', action='store', dest='tools_bin',
                     help='Use the svn tools installed in this path')
-  parser.add_option('--python-venv', action='store', dest='venv_base',
-                    help=('Use the virtual environment inside this path to'
-                          ' find the dependencies used by the test suite.'))
   parser.add_option('--fsfs-sharding', action='store', type='int',
                     help='Default shard size (for fsfs)')
   parser.add_option('--fsfs-packing', action='store_true',
@@ -1103,6 +1091,8 @@ def create_parser():
                     help='programs to run under valgrind')
   parser.add_option('--valgrind-opts', action='store',
                     help='options to pass valgrind')
+  parser.add_option('--disable-xml-schema-validation', action='store_true',
+                    help='Disable extended XML schema validation')
 
   parser.set_defaults(set_log_level=None)
   return parser

Modified: 
subversion/branches/xml-schema-validation-improvements/subversion/tests/cmdline/log_tests.py
==============================================================================
--- 
subversion/branches/xml-schema-validation-improvements/subversion/tests/cmdline/log_tests.py
        Tue Jun 23 12:54:08 2026        (r1935585)
+++ 
subversion/branches/xml-schema-validation-improvements/subversion/tests/cmdline/log_tests.py
        Tue Jun 23 13:33:58 2026        (r1935586)
@@ -2778,7 +2778,7 @@ def log_on_deleted_deep(sbox):
                                      '',
                                      '-q', '-c', '1-2')
 
-@XFail(svntest.main.is_bad_xml_fatal)
+@XFail(svntest.main.is_xml_schema_validation_enabled)
 @Issue(4711)
 def log_with_merge_history_and_search(sbox):
   "log --use-merge-history --search"
@@ -2805,10 +2805,8 @@ def log_with_merge_history_and_search(sb
   svntest.verify.validate_xml_schema('log', output)
 
 
-def is_ra_local_and_is_bad_xml_fatal():
-  return svntest.main.is_ra_type_file() and svntest.main.is_bad_xml_fatal()
-
-@XFail(is_ra_local_and_is_bad_xml_fatal)
+@XFail(lambda: (svntest.main.is_xml_schema_validation_enabled()
+                and svntest.main.is_ra_type_file()))
 @Issue(4856)
 def log_xml_with_merge_history(sbox):
   "log --use-merge-history --xml"

Modified: 
subversion/branches/xml-schema-validation-improvements/subversion/tests/cmdline/prop_tests.py
==============================================================================
--- 
subversion/branches/xml-schema-validation-improvements/subversion/tests/cmdline/prop_tests.py
       Tue Jun 23 12:54:08 2026        (r1935585)
+++ 
subversion/branches/xml-schema-validation-improvements/subversion/tests/cmdline/prop_tests.py
       Tue Jun 23 13:33:58 2026        (r1935586)
@@ -2641,7 +2641,7 @@ def xml_unsafe_author(sbox):
 
 @Issue(4415)
 @Issue(4919)
-@XFail(lambda: (svntest.main.is_bad_xml_fatal()
+@XFail(lambda: (svntest.main.is_xml_schema_validation_enabled()
                 and not svntest.main.is_ra_type_dav()))
 def xml_unsafe_author2(sbox):
   "svn:author with XML unsafe chars 2"

Modified: 
subversion/branches/xml-schema-validation-improvements/subversion/tests/cmdline/svntest/main.py
==============================================================================
--- 
subversion/branches/xml-schema-validation-improvements/subversion/tests/cmdline/svntest/main.py
     Tue Jun 23 12:54:08 2026        (r1935585)
+++ 
subversion/branches/xml-schema-validation-improvements/subversion/tests/cmdline/svntest/main.py
     Tue Jun 23 13:33:58 2026        (r1935586)
@@ -41,13 +41,6 @@ import zipfile
 import codecs
 import queue
 
-# 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
 from urllib.parse import urlparse
@@ -127,13 +120,11 @@ class SVNRepositoryCreateFailure(Failure
 if sys.platform == 'win32':
   windows = True
   file_scheme_prefix = 'file:///'
-  venv_bin = 'Scripts'
   _exe = '.exe'
   _bat = '.bat'
   os.environ['SVN_DBG_STACKTRACES_TO_STDERR'] = 'y'
 else:
   windows = False
-  venv_bin = 'bin'
   file_scheme_prefix = 'file://'
   _exe = ''
   _bat = ''
@@ -227,18 +218,6 @@ options = None
 # this dir, so there's one point at which to mount, e.g., a ramdisk.
 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
-def venv_path():
-  return os.path.join(venv_base, "__venv__")
-
-# List of dependencies
-found_dependencies = set()
-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"
 
@@ -1764,12 +1743,8 @@ def is_httpd_authz_provider_enabled():
 def is_remote_http_connection_allowed():
   return options.allow_remote_http_connection
 
-# XML schema validation
-def is_bad_xml_fatal():
-  """Are we treating invalid XML output as a fatal error?"""
-  # Only if we have all the necessary dependencies.
-  depends = {'lxml', 'rnc2rng'}
-  return depends == (depends & found_dependencies)
+def is_xml_schema_validation_enabled():
+  return not options.disable_xml_schema_validation
 
 
 def wc_format(ver=None):
@@ -1875,14 +1850,14 @@ class TestSpawningThread(threading.Threa
       args.append('--allow-remote-http-connection')
     if options.svn_bin:
       args.append('--bin=' + options.svn_bin)
-    if options.venv_base:
-      args.append('--python-venv=' + options.venv_base)
     if options.store_pristine:
       args.append('--store-pristine=' + options.store_pristine)
     if options.valgrind:
       args.append('--valgrind=' + options.valgrind)
     if options.valgrind_opts:
       args.append('--valgrind-opts=' + options.valgrind_opts)
+    if options.disable_xml_schema_validation:
+      args.append('--disable-xml-schema-validation')
 
     result, stdout_lines, stderr_lines = spawn_process(command, 0, False, None,
                                                        *args)
@@ -2251,9 +2226,6 @@ def _create_parser(usage=None):
                     help='Whether to clean up')
   parser.add_option('--enable-sasl', action='store_true',
                     help='Whether to enable SASL authentication')
-  parser.add_option('--python-venv', action='store', dest='venv_base',
-                    help=('Use the virtual environment inside this path to'
-                          ' find the dependencies used by the test suite.'))
   parser.add_option('--bin', action='store', dest='svn_bin',
                     help='Use the svn binaries installed in this path')
   parser.add_option('--use-jsvn', action='store_true',
@@ -2330,6 +2302,8 @@ def _create_parser(usage=None):
                     help='programs to run under valgrind')
   parser.add_option('--valgrind-opts', action='store',
                     help='options to pass to valgrind')
+  parser.add_option('--disable-xml-schema-validation', action='store_true',
+                    help='Disable extended XML schema validation')
 
   # most of the defaults are None, but some are other values, set them here
   parser.set_defaults(
@@ -2360,8 +2334,6 @@ def parse_options(arglist=sys.argv[1:],
   """Parse the arguments in arg_list, and set the global options object with
      the results"""
 
-  global venv_base
-  global venv_create
   global options
 
   parser = _create_parser(usage)
@@ -2411,10 +2383,6 @@ def parse_options(arglist=sys.argv[1:],
                     svn_wc__max_supported_format_version(),
                     options.wc_format_version))
 
-  if options.venv_base:
-    venv_base = options.venv_base
-    venv_create = False
-
   return (parser, args)
 
 def tweak_options_for_precooked_repos():
@@ -2447,80 +2415,6 @@ def run_tests(test_list, serial_only = F
 
   sys.exit(execute_tests(test_list, serial_only))
 
-def _get_purelib_dir(venv_dir):
-  if sys.platform == 'win32':
-    return os.path.join(venv_dir, "Lib", "site-packages")
-  else:
-    return os.path.join(venv_dir, "lib", "python%d.%d" % sys.version_info[:2],
-                        "site-packages")
-
-def ensure_dependencies():
-  """Install the dependencies we need for running the tests.
-
-  NOTE: this function des not handle the case where the Python
-        version has changed. In theory, we could automagically
-        upgrade the venv in that case. In practice, we won't.
-  """
-
-  venv_dir = os.path.abspath(venv_path())
-  package_path = _get_purelib_dir(venv_dir)
-
-  # Check if all our dependencies are installed. It doesn't matter if
-  # they're installed in our venv, as long as they're available.
-  found_dependencies.clear()
-  saved_sys_path = sys.path[:]
-  try:
-    sys.path.insert(0, package_path)
-    for package in SVN_TESTS_DEPEND:
-      importlib.import_module(package)
-      found_dependencies.add(package)
-    have_required = True
-  except ImportError:
-    have_required = False
-  finally:
-    sys.path[:] = saved_sys_path
-
-  if have_required:
-    if package_path not in sys.path:
-      sys.path.append(package_path)
-    return package_path
-
-  if venv_create:
-    python_prog, python_path = create_python_venv(venv_dir)
-    if python_prog is not None:
-      assert python_path == package_path
-      if package_path not in sys.path:
-        sys.path.append(package_path)
-      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):
-      if os.path.exists(venv_dir):
-        safe_rmtree(venv_dir)
-      venv.create(venv_dir, with_pip=True)
-
-    # Install the dependencies
-    pip = os.path.join(venv_dir, venv_bin, "pip" + _exe)
-    pip_options = ("--disable-pip-version-check", "--require-virtualenv")
-    subprocess.run([pip, *pip_options, "install", *SVN_TESTS_REQUIRE],
-                   check=True, stdout=subprocess.PIPE if quiet else None)
-    importlib.invalidate_caches()
-
-    python_prog = os.path.join(venv_dir, venv_bin, "python" + _exe)
-    python_path = _get_purelib_dir(venv_dir)
-    return python_prog, python_path
-  except Exception:
-    if logger:
-      logger.warning('Could not install test dependencies', exc_info=True)
-    return None, None
-
 def get_issue_details(issue_numbers):
   """For each issue number in ISSUE_NUMBERS query the issue
      tracker and determine what the target milestone is and
@@ -2719,10 +2613,6 @@ def execute_tests(test_list, serial_only
     wc_incomplete_tester_binary = os.path.join(options.tools_bin,
                                                'wc-incomplete-tester' + _exe)
 
-  assert options.venv_base is None or venv_base == options.venv_base, \
-    'venv_base=%s options.venv_base=%s' % (venv_base, options.venv_base)
-  ensure_dependencies()
-
   ######################################################################
 
   # Cleanup: if a previous run crashed or interrupted the python

Modified: 
subversion/branches/xml-schema-validation-improvements/subversion/tests/cmdline/svntest/verify.py
==============================================================================
--- 
subversion/branches/xml-schema-validation-improvements/subversion/tests/cmdline/svntest/verify.py
   Tue Jun 23 12:54:08 2026        (r1935585)
+++ 
subversion/branches/xml-schema-validation-improvements/subversion/tests/cmdline/svntest/verify.py
   Tue Jun 23 13:33:58 2026        (r1935586)
@@ -1053,9 +1053,12 @@ __schema_dir = os.path.join(
           os.path.abspath(__file__))))),
   "svn", "schema")
 def validate_xml_schema(name: str, lines: Iterable[str]) -> None:
+  if not svntest.main.is_xml_schema_validation_enabled():
+    logger.debug("XML schema validation is disabled.")
+    return
+
   schema_name = name + ".rnc"
   try:
-    # Imported in this scope because sys.path may not have been updated yet.
     from lxml import etree #type:ignore
     schema_file = os.path.join(__schema_dir, schema_name)
     schema = etree.RelaxNG(file=schema_file)
@@ -1065,11 +1068,8 @@ def validate_xml_schema(name: str, lines
       raise SVNXMLSchemaValidationError(schema.error_log)
   except ImportError:
     logger.error("XML: Module lxml.etree not found")
-    return
+    raise svntest.Failure
   except Exception as ex:
     logger.error("XML: " + str(ex))
     logger.warning("XML:\n" + "\n".join(repr(line) for line in lines))
-    if svntest.main.is_bad_xml_fatal():
-      raise
-    else:
-      logger.warning("XML:", exc_info=True)
+    raise

Reply via email to