Skip to content

Commit

Permalink
Enable the huge_tree option for the lxml parser (#3365)
Browse files Browse the repository at this point in the history
  • Loading branch information
seberm authored Nov 28, 2024
1 parent 36362a1 commit dfb5761
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 22 deletions.
20 changes: 20 additions & 0 deletions tests/report/junit/data/custom-deep-tree.xml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" ?>

{#
Test that very deep trees are correctly handled by junit plugin.
Refs.:
- [PR#3365](https://github.com/teemtee/tmt/pull/3365)
- [`huge_tree` option](https://lxml.de/api/lxml.etree.XMLParser-class.html)
#}

{% set DEPTH = 257 %}
<root>
{% for i in range(1, DEPTH + 1) %}
{{ " " * i }}<tag{{ i }}>
{% endfor %}

{% for i in range(DEPTH, 0, -1) %}
{{ " " * i }}</tag{{ i }}>
{% endfor %}
</root>
8 changes: 8 additions & 0 deletions tests/report/junit/data/main.fmf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@
/escape"<speci&l>_chars:
test: ./special_chars.sh

/big-output:
summary: Generate huge text data into <system-out> JUnit tag
link:
- verifies: https://github.com/teemtee/tmt/issues/3363
require:
- python
test: python -c "print((('a' * 1023) + '\n') * 1024 * 10)"

/subresults/pass:
summary: Basic pass test of shell subresults
test: |
Expand Down
46 changes: 28 additions & 18 deletions tests/report/junit/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,62 +5,71 @@ rlJournalStart
rlPhaseStartSetup
rlRun "pushd data"
rlRun "set -o pipefail"
rlRun "tmp=\$(mktemp -d)" 0 "Creating tmp directory"
rlRun "run_dir=$tmp/run-subresults"
rlPhaseEnd

for method in tmt; do
rlPhaseStartTest "[$method] Basic format checks"
rlRun "tmt run -avr execute -h $method report -h junit --file junit.xml 2>&1 >/dev/null | tee output" 2
rlAssertGrep "5 tests passed, 5 tests failed and 2 errors" "output"
rlAssertGrep '00:00:00 pass /test/shell/escape"<speci&l>_chars (on default-0)' "output"
rlAssertGrep '<testsuite name="/plan" disabled="0" errors="2" failures="5" skipped="0" tests="12"' "junit.xml"
rlRun -s "tmt run -av --id $run_dir execute -h $method report -h junit --file junit.xml 2>&1 >/dev/null" 2
rlAssertGrep "6 tests passed, 5 tests failed and 2 errors" "$rlRun_LOG"
rlAssertGrep '00:00:00 pass /test/shell/escape"<speci&l>_chars (on default-0)' "$rlRun_LOG"
rlAssertGrep '<testsuite name="/plan" disabled="0" errors="2" failures="5" skipped="0" tests="13"' "junit.xml"
rlAssertGrep 'fail</failure>' "junit.xml"

# Test the escape of special characters
rlAssertGrep '<testcase name="/test/shell/escape&quot;&lt;speci&amp;l&gt;_chars">' "junit.xml"
rlAssertGrep '<system-out>&lt;speci&amp;l&gt;"chars and control chars</system-out>' "junit.xml"

# Check there is no schema problem reported
rlAssertNotGrep 'The generated XML output is not a valid XML file or it is not valid against the XSD schema\.' "output"
rlAssertNotGrep 'The generated XML output is not a valid XML file or it is not valid against the XSD schema\.' "$rlRun_LOG"
rlPhaseEnd

rlPhaseStartTest "[$method] Check the flavor argument is working"
rlRun "tmt run -avr execute -h $method report -h junit --file junit.xml --flavor default 2>&1 >/dev/null | tee output" 2
rlAssertGrep "5 tests passed, 5 tests failed and 2 errors" "output"
rlRun -s "tmt run --last -v --id $run_dir execute -h $method report -h junit --file junit.xml --flavor default --force 2>&1 >/dev/null" 2
rlAssertGrep "6 tests passed, 5 tests failed and 2 errors" "$rlRun_LOG"

# Check there is no schema problem reported
rlAssertNotGrep 'The generated XML output is not a valid XML file or it is not valid against the XSD schema\.' "output"
rlAssertNotGrep 'The generated XML output is not a valid XML file or it is not valid against the XSD schema\.' "$rlRun_LOG"
rlPhaseEnd

rlPhaseStartTest "[$method] Check the mutually exclusive arguments"
rlRun "tmt run -avr execute -h $method report -h junit --file junit.xml --flavor custom 2>&1 >/dev/null | tee output" 2
rlAssertGrep "The 'custom' flavor requires the '--template-path' argument." "output"
rlRun -s "tmt run --last -v --id $run_dir execute -h $method report -h junit --file junit.xml --flavor custom --force 2>&1 >/dev/null" 2
rlAssertGrep "The 'custom' flavor requires the '--template-path' argument." "$rlRun_LOG"

rlRun "tmt run -avr execute -h $method report -h junit --file junit.xml --template-path custom.xml.j2 2>&1 >/dev/null | tee output" 2
rlAssertGrep "The '--template-path' can be used only with '--flavor=custom'." "output"
rlRun -s "tmt run --last -v execute -h $method report -h junit --file junit.xml --template-path custom.xml.j2 --force 2>&1 >/dev/null" 2
rlAssertGrep "The '--template-path' can be used only with '--flavor=custom'." "$rlRun_LOG"

rlPhaseEnd

rlPhaseStartTest "[$method] Check the 'custom' flavor with a custom XML template"
rlRun "tmt run -avr execute -h $method report -h junit --file custom-template-out.xml --template-path custom.xml.j2 --flavor custom 2>&1 >/dev/null | tee output" 2
rlRun -s "tmt run --last -v --id $run_dir execute -h $method report -h junit --file custom-template-out.xml --template-path custom.xml.j2 --flavor custom --force 2>&1 >/dev/null" 2

# There must not be a schema check when using a custom flavor
rlAssertGrep "The 'custom' JUnit flavor is used, you are solely responsible for the validity of the XML schema\." "output"
rlAssertGrep "The 'custom' JUnit flavor is used, you are solely responsible for the validity of the XML schema\." "$rlRun_LOG"

rlAssertGrep '<test name="/test/beakerlib/fail" value="fail"/>' "custom-template-out.xml"
rlAssertGrep '<test name="/test/beakerlib/pass" value="pass"/>' "custom-template-out.xml"
rlAssertGrep '<test name="/test/shell/pass" value="pass"/>' "custom-template-out.xml"
rlAssertGrep '<test name="/test/shell/timeout" value="error"/>' "custom-template-out.xml"
rlAssertGrep '<test name="/test/shell/escape&quot;&lt;speci&amp;l&gt;_chars" value="pass"/>' "custom-template-out.xml"
rlAssertGrep '<test name="/test/shell/big-output" value="pass"/>' "custom-template-out.xml"
rlPhaseEnd

rlPhaseStartTest "[$method] Check the 'custom' flavor with very deep XML trees"
rlRun -s "tmt run --last -v --id $run_dir execute -h $method report -h junit --file custom-deep-tree-template-out.xml --template-path custom-deep-tree.xml.j2 --flavor custom --force 2>&1 >/dev/null" 2

rlAssertNotGrep 'Excessive depth in document' "$rlRun_LOG"
rlPhaseEnd

rlPhaseStartTest "[$method] The 'custom' flavor with a custom **non-XML** template must not work"
rlRun "tmt run -avr execute -h $method report -h junit --file custom-template-out.xml --template-path non-xml-custom.j2 --flavor custom 2>&1 >/dev/null | tee output" 2
rlRun -s "tmt run --last -v execute -h $method report -h junit --file custom-template-out.xml --template-path non-xml-custom.j2 --flavor custom --force 2>&1 >/dev/null" 2

rlAssertGrep 'The generated XML output is not a valid XML file.' "output"
rlAssertGrep 'The generated XML output is not a valid XML file.' "$rlRun_LOG"
rlPhaseEnd

rlPhaseStartTest "[$method] Check the 'custom' flavor and context for subresults"
rlRun "tmt run -avr execute -h $method report -h junit --file custom-subresults-template-out.xml --template-path custom-subresults.xml.j2 --flavor custom 2>&1 >/dev/null | tee output" 2
rlRun "tmt run --last -v execute -h $method report -h junit --file custom-subresults-template-out.xml --template-path custom-subresults.xml.j2 --flavor custom --force 2>&1 >/dev/null" 2

# Beakerlib subresults
rlAssertGrep '<subresult name="/Test" outcome="fail"/>' "custom-subresults-template-out.xml"
Expand All @@ -85,7 +94,8 @@ rlJournalStart
done

rlPhaseStartCleanup
rlRun "rm output junit.xml custom-template-out.xml custom-subresults-template-out.xml"
rlRun "rm *.xml"
rlRun "popd"
rlRun "rm -rf $tmp"
rlPhaseEnd
rlJournalEnd
7 changes: 3 additions & 4 deletions tmt/steps/report/junit.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,8 @@ def _read_log_filter(log: Path) -> str:

xml_parser_kwargs: dict[str, Any] = {
'remove_blank_text': prettify,
'schema': None,
}
'huge_tree': True,
'schema': None}

# The schema check must be done only for a non-custom JUnit flavors
if flavor != CUSTOM_FLAVOR_NAME:
Expand All @@ -334,8 +334,7 @@ def _read_log_filter(log: Path) -> str:

xml_parser = etree.XMLParser(**xml_parser_kwargs)
try:
# S320: Parsing of untrusted data is known to be vulnerable to XML
# attacks.
# S320: Parsing of untrusted data is known to be vulnerable to XML attacks.
tree_root: XMLElement = etree.fromstring(xml_data, xml_parser) # noqa: S320

except etree.XMLSyntaxError as e:
Expand Down

0 comments on commit dfb5761

Please sign in to comment.