mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-03-28 14:56:28 +01:00
Support Context tags in Boost test runs
Boost a while ago added Context tags, this commit makes those context tags supported in the testsrunner code of CDT See also https://www.boost.org/doc/libs/1_82_0/libs/test/doc/html/boost_test/test_output/test_tools_support_for_logging/contexts.html Fixes 459
This commit is contained in:
parent
60948feda8
commit
02035b02cf
4 changed files with 199 additions and 10 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011, 2012 Anton Gorenkov.
|
||||
* Copyright (c) 2011, 2023 Anton Gorenkov and others.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
|
@ -21,6 +21,10 @@ public class BoostTestsRunnerMessages extends NLS {
|
|||
public static String BoostTestsRunner_io_error_prefix;
|
||||
public static String BoostTestsRunner_wrong_tests_paths_count;
|
||||
public static String BoostTestsRunner_xml_error_prefix;
|
||||
public static String BoostXmlLogHandler_ContextHeader;
|
||||
public static String BoostXmlLogHandler_ContextOverflow;
|
||||
public static String BoostXmlLogHandler_ContextPrefix;
|
||||
public static String BoostXmlLogHandler_ContextSuffix;
|
||||
public static String BoostXmlLogHandler_exception_suffix;
|
||||
public static String BoostXmlLogHandler_wrong_tag_name;
|
||||
static {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
###############################################################################
|
||||
# Copyright (c) 2011 Anton Gorenkov
|
||||
# Copyright (c) 2011, 2023 Anton Gorenkov and others.
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License 2.0
|
||||
|
@ -15,5 +15,9 @@ BoostTestsRunner_error_format={0}: {1}
|
|||
BoostTestsRunner_io_error_prefix=I/O Error
|
||||
BoostTestsRunner_wrong_tests_paths_count=Only on test suite or test case should be specified to rerun
|
||||
BoostTestsRunner_xml_error_prefix=XML parse error
|
||||
BoostXmlLogHandler_ContextHeader=\nContext:\u0020
|
||||
BoostXmlLogHandler_ContextOverflow=...
|
||||
BoostXmlLogHandler_ContextPrefix=\u0020[
|
||||
BoostXmlLogHandler_ContextSuffix=]
|
||||
BoostXmlLogHandler_exception_suffix=\nLast check point was here.
|
||||
BoostXmlLogHandler_wrong_tag_name=Invalid XML format: Element "{0}" is not accepted\!
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011, 2013 Anton Gorenkov and others.
|
||||
* Copyright (c) 2011, 2023 Anton Gorenkov and others.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
|
@ -46,6 +46,8 @@ public class BoostXmlLogHandler extends DefaultHandler {
|
|||
private static final String XML_NODE_ERROR = "Error"; //$NON-NLS-1$
|
||||
private static final String XML_NODE_FATAL_ERROR = "FatalError"; //$NON-NLS-1$
|
||||
private static final String XML_NODE_EXCEPTION = "Exception"; //$NON-NLS-1$
|
||||
private static final String XML_NODE_CONTEXT = "Context"; //$NON-NLS-1$
|
||||
private static final String XML_NODE_FRAME = "Frame"; //$NON-NLS-1$
|
||||
|
||||
// Boost.Test XML log attributes
|
||||
private static final String XML_ATTR_TEST_SUITE_NAME = "name"; //$NON-NLS-1$
|
||||
|
@ -53,6 +55,13 @@ public class BoostXmlLogHandler extends DefaultHandler {
|
|||
private static final String XML_ATTR_MESSAGE_FILE = "file"; //$NON-NLS-1$
|
||||
private static final String XML_ATTR_MESSAGE_LINE = "line"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* The context can be of arbitrary length, to prevent excessively long strings
|
||||
* in the tree limit the context to this length in the tree. The full context
|
||||
* is available in the details tab.
|
||||
*/
|
||||
private static final int MAX_CONTEXT_LENGTH_IN_TREE = 50;
|
||||
|
||||
/** The default file name for test message location. */
|
||||
private static final String DEFAULT_LOCATION_FILE = null;
|
||||
|
||||
|
@ -81,6 +90,10 @@ public class BoostXmlLogHandler extends DefaultHandler {
|
|||
private String lastTestCaseName = ""; //$NON-NLS-1$
|
||||
private static final int SAME_TEST_CASE_NAME_COUNT_START = 2;
|
||||
private int sameTestCaseNameCount = SAME_TEST_CASE_NAME_COUNT_START;
|
||||
private StringBuilder context = new StringBuilder();
|
||||
|
||||
private boolean testCaseEnterDeferred = false;
|
||||
private StringBuilder testCaseName = new StringBuilder();
|
||||
|
||||
BoostXmlLogHandler(ITestModelUpdater modelUpdater) {
|
||||
this.modelUpdater = modelUpdater;
|
||||
|
@ -102,17 +115,18 @@ public class BoostXmlLogHandler extends DefaultHandler {
|
|||
break;
|
||||
|
||||
case XML_NODE_TEST_CASE:
|
||||
String testCaseName = attrs.getValue(XML_ATTR_TEST_CASE_NAME);
|
||||
testCaseName.setLength(0);
|
||||
testCaseName.append(attrs.getValue(XML_ATTR_TEST_CASE_NAME));
|
||||
|
||||
if (lastTestCaseName.equals(testCaseName)) {
|
||||
testCaseName += " (" + sameTestCaseNameCount + ")"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
if (lastTestCaseName.equals(testCaseName.toString())) {
|
||||
testCaseName.append(" (" + sameTestCaseNameCount + ")"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
++sameTestCaseNameCount;
|
||||
} else {
|
||||
lastTestCaseName = testCaseName;
|
||||
lastTestCaseName = testCaseName.toString();
|
||||
sameTestCaseNameCount = SAME_TEST_CASE_NAME_COUNT_START;
|
||||
}
|
||||
|
||||
modelUpdater.enterTestCase(testCaseName);
|
||||
testCaseEnterDeferred = true;
|
||||
testStatus = Status.Passed;
|
||||
break;
|
||||
|
||||
|
@ -132,6 +146,11 @@ public class BoostXmlLogHandler extends DefaultHandler {
|
|||
lineNumber = DEFAULT_LOCATION_LINE;
|
||||
break;
|
||||
|
||||
case XML_NODE_CONTEXT:
|
||||
case XML_NODE_FRAME:
|
||||
/* handle in endElement */
|
||||
break;
|
||||
|
||||
case XML_NODE_TESTING_TIME:
|
||||
case XML_NODE_TEST_LOG:
|
||||
/* just skip, do nothing */
|
||||
|
@ -149,7 +168,26 @@ public class BoostXmlLogHandler extends DefaultHandler {
|
|||
* @param level test message level
|
||||
*/
|
||||
private void addCurrentMessage(ITestMessage.Level level) {
|
||||
modelUpdater.addTestMessage(fileName, lineNumber, level, elementDataStack.peek().toString().trim());
|
||||
String text = elementDataStack.peek().toString().trim();
|
||||
if (testCaseEnterDeferred) {
|
||||
if (!context.isEmpty()) {
|
||||
testCaseName.append(BoostTestsRunnerMessages.BoostXmlLogHandler_ContextPrefix);
|
||||
if (context.length() > MAX_CONTEXT_LENGTH_IN_TREE) {
|
||||
testCaseName.append(context.subSequence(0, MAX_CONTEXT_LENGTH_IN_TREE));
|
||||
testCaseName.append(BoostTestsRunnerMessages.BoostXmlLogHandler_ContextOverflow);
|
||||
} else {
|
||||
testCaseName.append(context);
|
||||
}
|
||||
testCaseName.append(BoostTestsRunnerMessages.BoostXmlLogHandler_ContextSuffix);
|
||||
}
|
||||
modelUpdater.enterTestCase(testCaseName.toString());
|
||||
testCaseEnterDeferred = false;
|
||||
}
|
||||
if (!context.isEmpty()) {
|
||||
text += BoostTestsRunnerMessages.BoostXmlLogHandler_ContextHeader + context.toString().trim();
|
||||
context.setLength(0);
|
||||
}
|
||||
modelUpdater.addTestMessage(fileName, lineNumber, level, text.trim());
|
||||
fileName = DEFAULT_LOCATION_FILE;
|
||||
lineNumber = DEFAULT_LOCATION_LINE;
|
||||
if (level == ITestMessage.Level.Error || level == ITestMessage.Level.FatalError) {
|
||||
|
@ -174,6 +212,10 @@ public class BoostXmlLogHandler extends DefaultHandler {
|
|||
break;
|
||||
|
||||
case XML_NODE_TEST_CASE:
|
||||
if (testCaseEnterDeferred) {
|
||||
modelUpdater.enterTestCase(testCaseName.toString());
|
||||
testCaseEnterDeferred = false;
|
||||
}
|
||||
modelUpdater.setTestStatus(testStatus);
|
||||
modelUpdater.exitTestCase();
|
||||
break;
|
||||
|
@ -209,6 +251,13 @@ public class BoostXmlLogHandler extends DefaultHandler {
|
|||
addCurrentMessage(ITestMessage.Level.Exception);
|
||||
break;
|
||||
|
||||
case XML_NODE_CONTEXT:
|
||||
context.insert(0, elementDataStack.peek().toString().trim());
|
||||
break;
|
||||
case XML_NODE_FRAME:
|
||||
context.append(elementDataStack.peek().toString().trim());
|
||||
break;
|
||||
|
||||
case XML_NODE_TEST_LOG:
|
||||
case XML_NODE_LAST_CHECKPOINT:
|
||||
/* just skip, do nothing */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011, 2013 Anton Gorenkov and others.
|
||||
* Copyright (c) 2011, 2023 Anton Gorenkov and others.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
|
@ -507,4 +507,136 @@ public class BoostTestCase extends BaseTestCase {
|
|||
mockModelUpdater.exitTestCase();
|
||||
mockModelUpdater.exitTestSuite();
|
||||
}
|
||||
|
||||
//<TestLog>
|
||||
// <TestSuite name="MainTS">
|
||||
// <TestCase name="single-context">
|
||||
// <Info file="file1.cpp" line="1">
|
||||
// <Context>
|
||||
// <Frame>
|
||||
// <![CDATA[context 1 message here]]>
|
||||
// </Frame>
|
||||
// </Context>
|
||||
// </Info>
|
||||
// </TestCase>
|
||||
// <TestCase name="single-context-and-info-message">
|
||||
// <Info file="file2.cpp" line="2">
|
||||
// <![CDATA[info 2 message here]]>
|
||||
// <Context>
|
||||
// <Frame>
|
||||
// <![CDATA[context 2 message here]]>
|
||||
// </Frame>
|
||||
// </Context>
|
||||
// </Info>
|
||||
// </TestCase>
|
||||
// <TestCase name="multi-context">
|
||||
// <Info file="file3.cpp" line="1">
|
||||
// <Context>
|
||||
// <Frame>
|
||||
// <![CDATA[context 3a message here]]>
|
||||
// </Frame>
|
||||
// </Context>
|
||||
// </Info>
|
||||
// <Info file="file3.cpp" line="2">
|
||||
// <Context>
|
||||
// <Frame>
|
||||
// <![CDATA[context 3b message here]]>
|
||||
// </Frame>
|
||||
// </Context>
|
||||
// </Info>
|
||||
// </TestCase>
|
||||
// <TestCase name="error-message">
|
||||
// <Error file="file4.cpp" line="1">
|
||||
// <![CDATA[error 4 message here]]>
|
||||
// <Context>
|
||||
// <Frame>
|
||||
// <![CDATA[context 4 message here]]>
|
||||
// </Frame>
|
||||
// </Context>
|
||||
// </Error>
|
||||
// </TestCase>
|
||||
// <TestCase name="off-by-one-check-a">
|
||||
// <Error file="off-by-one.cpp" line="1">
|
||||
// <Context>
|
||||
// <Frame>
|
||||
// <![CDATA[very very very long context off-by-one-check 01234567890]]>
|
||||
// </Frame>
|
||||
// </Context>
|
||||
// </Error>
|
||||
// </TestCase>
|
||||
// <TestCase name="off-by-one-check-b">
|
||||
// <Error file="off-by-one.cpp" line="1">
|
||||
// <Context>
|
||||
// <Frame>
|
||||
// <![CDATA[very very very long context off-by-one-check 012345]]>
|
||||
// </Frame>
|
||||
// </Context>
|
||||
// </Error>
|
||||
// </TestCase>
|
||||
// <TestCase name="off-by-one-check-c">
|
||||
// <Error file="off-by-one.cpp" line="1">
|
||||
// <Context>
|
||||
// <Frame>
|
||||
// <![CDATA[very very very long context off-by-one-check 01234]]>
|
||||
// </Frame>
|
||||
// </Context>
|
||||
// </Error>
|
||||
// </TestCase>
|
||||
// <TestCase name="off-by-one-check-d">
|
||||
// <Error file="off-by-one.cpp" line="1">
|
||||
// <Context>
|
||||
// <Frame>
|
||||
// <![CDATA[very very very long context off-by-one-check 0123]]>
|
||||
// </Frame>
|
||||
// </Context>
|
||||
// </Error>
|
||||
// </TestCase>
|
||||
// </TestSuite>
|
||||
//</TestLog>
|
||||
public void testWithContextTests() {
|
||||
mockModelUpdater.skipCalls("setTestStatus");
|
||||
|
||||
mockModelUpdater.enterTestSuite("MainTS");
|
||||
mockModelUpdater.enterTestCase("single-context [context 1 message here]");
|
||||
mockModelUpdater.addTestMessage("file1.cpp", 1, ITestMessage.Level.Info, "Context: context 1 message here");
|
||||
mockModelUpdater.exitTestCase();
|
||||
mockModelUpdater.enterTestCase("single-context-and-info-message [context 2 message here]");
|
||||
mockModelUpdater.addTestMessage("file2.cpp", 2, ITestMessage.Level.Info,
|
||||
"info 2 message here\nContext: context 2 message here");
|
||||
mockModelUpdater.exitTestCase();
|
||||
|
||||
// I am not convinced the handling of this is correct, there is an assumption in the code that the first
|
||||
// context seen in an info (or error/warning/etc) message is the one to display next to the test case
|
||||
// name. This works if all the info messages have the same context, but is that an oversimplification?
|
||||
// See https://github.com/eclipse-cdt/cdt/issues/459#issuecomment-1677589998
|
||||
mockModelUpdater.enterTestCase("multi-context [context 3a message here]");
|
||||
mockModelUpdater.addTestMessage("file3.cpp", 1, ITestMessage.Level.Info, "Context: context 3a message here");
|
||||
mockModelUpdater.addTestMessage("file3.cpp", 2, ITestMessage.Level.Info, "Context: context 3b message here");
|
||||
mockModelUpdater.exitTestCase();
|
||||
|
||||
mockModelUpdater.enterTestCase("error-message [context 4 message here]");
|
||||
mockModelUpdater.addTestMessage("file4.cpp", 1, ITestMessage.Level.Error,
|
||||
"error 4 message here\nContext: context 4 message here");
|
||||
mockModelUpdater.exitTestCase();
|
||||
|
||||
// These tests make sure there is no off-by-one error when shortening context strings
|
||||
mockModelUpdater.enterTestCase("off-by-one-check-a [very very very long context off-by-one-check 01234...]");
|
||||
mockModelUpdater.addTestMessage("off-by-one.cpp", 1, ITestMessage.Level.Error,
|
||||
"Context: very very very long context off-by-one-check 01234567890");
|
||||
mockModelUpdater.exitTestCase();
|
||||
mockModelUpdater.enterTestCase("off-by-one-check-b [very very very long context off-by-one-check 01234...]");
|
||||
mockModelUpdater.addTestMessage("off-by-one.cpp", 1, ITestMessage.Level.Error,
|
||||
"Context: very very very long context off-by-one-check 012345");
|
||||
mockModelUpdater.exitTestCase();
|
||||
mockModelUpdater.enterTestCase("off-by-one-check-c [very very very long context off-by-one-check 01234]");
|
||||
mockModelUpdater.addTestMessage("off-by-one.cpp", 1, ITestMessage.Level.Error,
|
||||
"Context: very very very long context off-by-one-check 01234");
|
||||
mockModelUpdater.exitTestCase();
|
||||
mockModelUpdater.enterTestCase("off-by-one-check-d [very very very long context off-by-one-check 0123]");
|
||||
mockModelUpdater.addTestMessage("off-by-one.cpp", 1, ITestMessage.Level.Error,
|
||||
"Context: very very very long context off-by-one-check 0123");
|
||||
mockModelUpdater.exitTestCase();
|
||||
|
||||
mockModelUpdater.exitTestSuite();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue