Hello everyone!
The filter "tests" truncates the provided value at the first closing parenthesis, which can lead to the following:
The bug appeared when we upgraded nunit.consolerunner.netcore
from version 3.18.3
to version 3.20.0
.
I suspect that the bug itself was introduced in version 3.19.0
as a result of this commit: 1af35ed.
The bug reproduces in the following cases:
If a regex with parentheses is used, the parser may truncate the regex without an explicit error.
ExampleIf I run the following command:
nunit "test.dll" -where "test =~ '(namespace1|namespace2)\\.test1'" --explore
The parser will truncate to (namespace1|namespace2)
, and I will get all tests from these namespaces instead of namespace1.test1
and namespace2.test1
.
If a regex without parentheses is used but with test arguments, the parser may truncate the regex without an explicit error.
ExampleIf I run the following command:
nunit "test.dll" -where "test =~ 'namespace\\.test1\\(1\\)|namespace\\.test2\\(2\\)'" --explore
The parser will truncate to namespace\\.test1\\(1\\)
, and I will get only one test instead of two.
If a regex with parentheses is used, it may break the regex with an error.
ExampleIf I run the following command:
nunit "test.dll" -where "test =~ '(namespace\\.test1\\(1\\)|namespace\\.test2\\(2\\))'" --explore
The parser will truncate to (namespace\\.test1\\(1\\)
, resulting in an invalid regex that will fail when creating Regex:
Unit.Engine.NUnitEngineException : An exception occurred in the driver while exploring tests.
----> System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
----> System.Text.RegularExpressions.RegexParseException : Invalid pattern '(namespace\.test1\(1\)' at offset 22. Not enough )'s.
--NUnitEngineException
An exception occurred in the driver while exploring tests.
at NUnit.Engine.Runners.DirectTestRunner.Explore(TestFilter filter) in D:\a\nunit-console\nunit-console\src\NUnitEngine\nunit.engine.core\Runners\DirectTestRunner.cs:line 81
at NUnit.Engine.Runners.MasterTestRunner.Explore(TestFilter filter) in D:\a\nunit-console\nunit-console\src\NUnitEngine\nunit.engine\Runners\MasterTestRunner.cs:line 216
at NUnit.ConsoleRunner.ConsoleRunner.ExploreTests(TestPackage package, TestFilter filter) in D:\a\nunit-console\nunit-console\src\NUnitConsole\nunit3-console\ConsoleRunner.cs:line 171
at NUnit.ConsoleRunner.ConsoleRunner.Execute() in D:\a\nunit-console\nunit-console\src\NUnitConsole\nunit3-console\ConsoleRunner.cs:line 153
at NUnit.ConsoleRunner.Program.Main(String[] args) in D:\a\nunit-console\nunit-console\src\NUnitConsole\nunit3-console\Program.cs:line 117
--
TargetInvocationException
Exception has been thrown by the target of an invocation.
at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at NUnit.Engine.Drivers.NUnitNetCore31Driver.ExecuteMethod(MethodInfo method, Object[] args) in D:\a\nunit-console\nunit-console\src\NUnitEngine\nunit.engine.core\Drivers\NUnitNetCore31Driver.cs:line 207
at NUnit.Engine.Drivers.NUnitNetCore31Driver.ExecuteMethod(String methodName, Object[] args) in D:\a\nunit-console\nunit-console\src\NUnitEngine\nunit.engine.core\Drivers\NUnitNetCore31Driver.cs:line 189
at NUnit.Engine.Drivers.NUnitNetCore31Driver.Explore(String filter) in D:\a\nunit-console\nunit-console\src\NUnitEngine\nunit.engine.core\Drivers\NUnitNetCore31Driver.cs:line 164
at NUnit.Engine.Runners.DirectTestRunner.Explore(TestFilter filter) in D:\a\nunit-console\nunit-console\src\NUnitEngine\nunit.engine.core\Runners\DirectTestRunner.cs:line 77
--
RegexParseException
Invalid pattern '(namespace\.test1\(1\)' at offset 22. Not enough )'s.
at System.Text.RegularExpressions.RegexParser.ScanRegex()
at System.Text.RegularExpressions.RegexParser.Parse(String pattern, RegexOptions options, CultureInfo culture)
at System.Text.RegularExpressions.Regex.Init(String pattern, RegexOptions options, TimeSpan matchTimeout, CultureInfo& culture)
at System.Text.RegularExpressions.Regex..ctor(String pattern, CultureInfo culture)
at System.Text.RegularExpressions.Regex..ctor(String pattern)
at NUnit.Framework.Internal.Filters.ValueMatchFilter.Match(String input)
at NUnit.Framework.Internal.Filters.FullNameFilter.Match(ITest test)
at NUnit.Framework.Internal.TestFilter.Pass(ITest test, Boolean negated)
at NUnit.Framework.Internal.TestFilter.Pass(ITest test)
at NUnit.Framework.Internal.TestSuite..ctor(TestSuite suite, ITestFilter filter)
at NUnit.Framework.Internal.TestAssembly..ctor(TestAssembly assembly, ITestFilter filter)
at NUnit.Framework.Api.NUnitTestAssemblyRunner.ExploreTests(ITestFilter filter)
at NUnit.Framework.Api.FrameworkController.ExploreTests(String filter)
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
If a TestFixture with constructor arguments is used, the parser will truncate the value to TestFixture.
ExampleIf I run the following command:
nunit "test.dll" -where "test == 'namespace.class(1).test1(1)'" --explore
The parser will truncate to namespace.class(1)
, and I will get all tests from the class instead of a specific test.
Test cases for TestSelectionParserTests.cs
to reproduce the issue:
new TestCaseData("test == namespace.class(1).test1(1)", "<test>namespace.class(1).test1(1)</test>"),
new TestCaseData("test == \"namespace.class(1).test1(1)\"", "<test>namespace.class(1).test1(1)</test>"),
new TestCaseData("test == 'namespace.class(1).test1(1)'", "<test>namespace.class(1).test1(1)</test>"),
new TestCaseData("test =~ \"(namespace\\.test1\\(1\\)|namespace\\.test2\\(2\\))\"", "<test re='1'>(namespace.test1(1)|namespace.test2(2))</test>"),
new TestCaseData("test =~ '(namespace\\.test1\\(1\\)|namespace\\.test2\\(2\\))'", "<test re='1'>(namespace.test1(1)|namespace.test2(2))</test>"),
new TestCaseData("test =~ /(namespace\\.test1\\(1\\)|namespace\\.test2\\(2\\))/", "<test re='1'>(namespace.test1(1)|namespace.test2(2))</test>"),
new TestCaseData("test =~ \"(namespace1|namespace2)\\.test1\"", "<test re='1'>(namespace1|namespace2).test1</test>"),
new TestCaseData("test =~ '(namespace1|namespace2)\\.test1'", "<test re='1'>(namespace1|namespace2).test1</test>"),
new TestCaseData("test =~ /(namespace1|namespace2)\\.test1/", "<test re='1'>(namespace1|namespace2).test1</test>"),
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4