New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for NUnit files #289
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import os | ||
import pathlib | ||
from typing import Iterable, Callable | ||
|
||
from lxml import etree | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. opt.semgrep.python.lang.security.use-defused-xml.use-defused-xml: Found use of the native Python XML libraries, which is vulnerable to XML external entity (XXE) (at-me in a reply with Was this a good recommendation? |
||
|
||
from publish.junit import JUnitTreeOrException, ParsedJUnitFile | ||
|
||
with (pathlib.Path(__file__).parent / 'xslt' / 'nunit3-to-junit.xslt').open('r', encoding='utf-8') as r: | ||
transform_nunit_to_junit = etree.XSLT(etree.parse(r)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blacklist: Using lxml.etree.parse to parse untrusted XML data is known to be vulnerable to XML attacks. Replace lxml.etree.parse with its defusedxml equivalent function. (at-me in a reply with Was this a good recommendation? |
||
|
||
|
||
def parse_nunit_files(files: Iterable[str], | ||
progress: Callable[[ParsedJUnitFile], ParsedJUnitFile] = lambda x: x) -> Iterable[ParsedJUnitFile]: | ||
"""Parses nunit files.""" | ||
def parse(path: str) -> JUnitTreeOrException: | ||
"""Parses an nunit file and returns either a JUnitTree or an Exception.""" | ||
if not os.path.exists(path): | ||
return FileNotFoundError(f'File does not exist.') | ||
if os.stat(path).st_size == 0: | ||
return Exception(f'File is empty.') | ||
|
||
try: | ||
nunit = etree.parse(path) | ||
return transform_nunit_to_junit(nunit) | ||
except BaseException as e: | ||
return e | ||
|
||
return [progress((result_file, parse(result_file))) for result_file in files] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- based on https://github.com/syl20bnr/nunit-plugin/blob/be8193421b60c45366e9f6c9d0ff91b3aa852244/src/main/resources/hudson/plugins/nunit/nunit-to-junit.xsl --> | ||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> | ||
<xsl:output method="xml" indent="yes" /> | ||
|
||
<xsl:template match="/test-results"> | ||
<testsuites> | ||
<xsl:for-each select="test-suite//results//test-case[1]"> | ||
|
||
<xsl:for-each select="../.."> | ||
<xsl:variable name="firstTestName" | ||
select="results//test-case[1]//@name" /> | ||
|
||
<xsl:variable name="assembly"> | ||
<xsl:choose> | ||
<xsl:when test="substring($firstTestName, string-length($firstTestName)) = ')'"> | ||
<xsl:value-of select="substring-before($firstTestName, concat('.', @name))"></xsl:value-of> | ||
</xsl:when> | ||
<xsl:otherwise> | ||
<xsl:value-of select="concat(substring-before($firstTestName, @name), @name)" /> | ||
</xsl:otherwise> | ||
</xsl:choose> | ||
</xsl:variable> | ||
<!-- | ||
<xsl:variable name="assembly" | ||
select="concat(substring-before($firstTestName, @name), @name)" /> | ||
--> | ||
|
||
<!-- <redirect:write file="{$outputpath}/TEST-{$assembly}.xml">--> | ||
|
||
<testsuite name="{$assembly}" | ||
tests="{count(*/test-case)}" time="{@time}" | ||
failures="{count(*/test-case/failure)}" errors="0" | ||
skipped="{count(*/test-case[@executed='False'])}"> | ||
<xsl:for-each select="*/test-case"> | ||
<xsl:variable name="testcaseName"> | ||
<xsl:choose> | ||
<xsl:when test="contains(./@name, concat($assembly,'.'))"> | ||
<xsl:value-of select="substring-after(./@name, concat($assembly,'.'))"/><!-- We either instantiate a "15" --> | ||
</xsl:when> | ||
<xsl:otherwise> | ||
<xsl:value-of select="./@name"/><!-- ...or a "20" --> | ||
</xsl:otherwise> | ||
</xsl:choose> | ||
</xsl:variable> | ||
|
||
<testcase classname="{$assembly}" | ||
name="{$testcaseName}"> | ||
<xsl:if test="@time!=''"> | ||
<xsl:attribute name="time"><xsl:value-of select="@time" /></xsl:attribute> | ||
</xsl:if> | ||
|
||
<xsl:variable name="generalfailure" | ||
select="./failure" /> | ||
|
||
<xsl:if test="./failure"> | ||
<xsl:variable name="failstack" | ||
select="count(./failure/stack-trace/*) + count(./failure/stack-trace/text())" /> | ||
<failure> | ||
<xsl:choose> | ||
<xsl:when test="$failstack > 0 or not($generalfailure)"> | ||
MESSAGE: | ||
<xsl:value-of select="./failure/message" /> | ||
+++++++++++++++++++ | ||
STACK TRACE: | ||
<xsl:value-of select="./failure/stack-trace" /> | ||
</xsl:when> | ||
<xsl:otherwise> | ||
MESSAGE: | ||
<xsl:value-of select="$generalfailure/message" /> | ||
+++++++++++++++++++ | ||
STACK TRACE: | ||
<xsl:value-of select="$generalfailure/stack-trace" /> | ||
</xsl:otherwise> | ||
</xsl:choose> | ||
</failure> | ||
</xsl:if> | ||
<xsl:if test="@executed='False'"> | ||
<skipped> | ||
<xsl:attribute name="message"><xsl:value-of select="./reason/message"/></xsl:attribute> | ||
</skipped> | ||
</xsl:if> | ||
</testcase> | ||
</xsl:for-each> | ||
</testsuite> | ||
<!-- </redirect:write>--> | ||
</xsl:for-each> | ||
</xsl:for-each> | ||
</testsuites> | ||
</xsl:template> | ||
</xsl:stylesheet> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
blacklist: Using etree to parse untrusted XML data is known to be vulnerable to XML attacks. Replace etree with the equivalent defusedxml package.
(at-me in a reply with
help
orignore
)Was this a good recommendation?
[ 🙁 Not relevant ] - [ 😕 Won't fix ] - [ 😑 Not critical, will fix ] - [ 🙂 Critical, will fix ] - [ 😊 Critical, fixing now ]