Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions openedx/tests/test_bug_36305_regression.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""
Regression test for bug #36305 — xmlsec / lxml version mismatch on open-release/sumac.master.

The latest PyPI wheels for xmlsec and lxml link against a newer libxml2 than what ships
on Ubuntu 24.04 GitHub Actions runners, which raises a version-mismatch RuntimeError at
import time. The fix pins both packages in requirements/constraints.txt; this module is a
tripwire that ensures the pins stay in place on this branch.

See: https://github.com/openedx/edx-platform/issues/36305
See: https://github.com/openedx/edx-platform/issues/36695
"""

import os
import re
import unittest


REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
CONSTRAINTS_PATH = os.path.join(REPO_ROOT, "requirements", "constraints.txt")


def _read_constraints():
"""Return the contents of requirements/constraints.txt as a single string."""
with open(CONSTRAINTS_PATH, encoding="utf-8") as handle:
return handle.read()


class TestBug36305Regression(unittest.TestCase):
"""Ensure lxml and xmlsec stay pinned so CI does not pull a libxml2-incompatible wheel."""

def test_unit_bug_36305_regression_xmlsec_is_pinned(self):
"""xmlsec must be pinned to a version compatible with the system libxml2."""
contents = _read_constraints()
self.assertRegex(
contents,
r"^xmlsec==1\.3\.14\s*$",
msg="xmlsec must be pinned to 1.3.14 to avoid libxml2 mismatch (bug #36305).",
)

def test_unit_bug_36305_regression_lxml_is_pinned(self):
"""lxml must be pinned to an exact version."""
contents = _read_constraints()
match = re.search(r"^lxml==(\S+)\s*$", contents, flags=re.MULTILINE)
self.assertIsNotNone(
match,
msg="lxml must be pinned to an exact version to avoid libxml2 mismatch (bug #36305).",
)

def test_integration_bug_36305_regression_import_xmlsec_succeeds(self):
"""Importing xmlsec must not raise a version-mismatch RuntimeError."""
try:
import xmlsec # noqa: F401 pylint: disable=import-outside-toplevel,unused-import
except RuntimeError as exc: # pragma: no cover - only fires on broken wheel
self.fail(
"xmlsec import failed with RuntimeError (likely libxml2 version mismatch, "
"bug #36305): {err}".format(err=exc)
)
12 changes: 12 additions & 0 deletions requirements/constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,15 @@ social-auth-app-django<=5.4.1
# # Date: 2024-10-14
# # The edx-enterprise is currently using edx-rest-api-client==5.7.1, which needs to be updated first.
# edx-rest-api-client==5.7.1

# Date: 2025-05-09
# lxml and xmlsec need to be constrained because the latest version builds against a newer
# version of libxml2 than what we're running with. This leads to a version mismatch error
# at runtime. You can re-produce it by running any test. If lxml is unpinned in the future
# and you see this error, it may be that the system libxml2 is now shipping the correct
# version and we can un-pin this.
# Backported from master commit ef93d6b8631 to fix pylint CI on open-release/sumac.master.
# Issue: https://github.com/openedx/edx-platform/issues/36305
# Tracking: https://github.com/openedx/edx-platform/issues/36695
lxml==5.3.0
xmlsec==1.3.14