Repository: frankframework/frankframework
Pull request #9009: Larva - Fix Comparisons that include path of testdata.dir
Author: login: tnleeuw
Labels: name: Larva
name: Technical Debt
Created: 2025-05-19T17:37:33Z | Merged: 2025-05-20T14:19:49Z



Diff:
diff --git a/larva/src/main/java/org/frankframework/larva/LarvaTool.java b/larva/src/main/java/org/frankframework/larva/LarvaTool.java
index d28d09f1b74..db989a7dc43 100644
--- a/larva/src/main/java/org/frankframework/larva/LarvaTool.java
+++ b/larva/src/main/java/org/frankframework/larva/LarvaTool.java
@@ -508,6 +508,19 @@ private int reportFailedCompare(TestExecutionObserver testExecutionObserver, Sce
 
 	public String prepareResultForCompare(String input, Properties properties, Map<String, Map<String, Map<String, String>>> ignoreMap) {
 		String result = input;
+
+		// TESTDATA-dir based file paths in results can often not be compared properly because of location differences, and complicated by system-dependent file paths.
+		// Changing Windows backslashes to Unix forward slashes in the rest of file paths is done with regexes configured in global.properties
+		String testDataDirPropertyValue = AppConstants.getInstance().getProperty("testdata.dir");
+		if (testDataDirPropertyValue != null) {
+			String testDataDirNative = new File(testDataDirPropertyValue).getAbsolutePath();
+			String testDataDirWindows = FilenameUtils.normalize(testDataDirPropertyValue, false);
+			String testDataDirUnix = FilenameUtils.normalize(testDataDirPropertyValue, true);
+			result = result.replace(testDataDirNative, "TESTDATA_DIR")
+					.replace(testDataDirWindows, "TESTDATA_DIR")
+					.replace(testDataDirUnix, "TESTDATA_DIR");
+		}
+
 		result = doActionBetweenKeys("decodeUnzipContentBetweenKeys", result, properties, ignoreMap, (value, pp, key1, key2)-> {
 			boolean replaceNewlines = !"true".equals(pp.apply("replaceNewlines"));
 			return decodeUnzipContentBetweenKeys(value, key1, key2, replaceNewlines);
@@ -548,7 +561,7 @@ public interface SingleKeyAction {
 		String format(String value, Function<String, String> propertyProvider, String key1);
 	}
 
-	public String doActionBetweenKeys(String key, String value, Properties properties, Map<String, Map<String, Map<String, String>>> ignoreMap, BetweenKeysAction action) {
+	public static String doActionBetweenKeys(String key, String value, Properties properties, Map<String, Map<String, Map<String, String>>> ignoreMap, BetweenKeysAction action) {
 		String result = value;
 		log.debug("Check [{}] properties", key);
 		boolean lastKeyIndexProcessed = false;
@@ -588,7 +601,7 @@ public String doActionBetweenKeys(String key, String value, Properties propertie
 		return result;
 	}
 
-	public String doActionWithSingleKey(String keyName, String value, Properties properties, Map<String, Map<String, Map<String, String>>> ignoreMap, SingleKeyAction action) {
+	public static String doActionWithSingleKey(String keyName, String value, Properties properties, Map<String, Map<String, Map<String, String>>> ignoreMap, SingleKeyAction action) {
 		String result = value;
 		log.debug("Check [{}] properties", keyName);
 		boolean lastKeyIndexProcessed = false;
diff --git a/larva/src/test/java/org/frankframework/larva/LarvaToolTest.java b/larva/src/test/java/org/frankframework/larva/LarvaToolTest.java
index 8a40a167e7b..c81648b0b1e 100644
--- a/larva/src/test/java/org/frankframework/larva/LarvaToolTest.java
+++ b/larva/src/test/java/org/frankframework/larva/LarvaToolTest.java
@@ -8,6 +8,8 @@
 import java.io.File;
 import java.io.StringWriter;
 import java.util.List;
+import java.util.Map;
+import java.util.Properties;
 
 import jakarta.servlet.ServletContext;
 
@@ -28,6 +30,7 @@
 import org.frankframework.testutil.TestConfiguration;
 import org.frankframework.util.AppConstants;
 import org.frankframework.util.CloseUtils;
+import org.frankframework.util.PropertyLoader;
 
 @Log4j2
 class LarvaToolTest {
@@ -38,6 +41,8 @@ class LarvaToolTest {
 	private static AppConstants appConstants;
 	private static File scenarioRoot;
 
+	private Properties properties;
+
 	@BeforeAll
 	public static void beforeAll() {
 		configuration = new TestConfiguration();
@@ -50,12 +55,15 @@ public static void beforeAll() {
 	public void setUp() {
 		appConstants.setProperty("scenariosroot1.directory", scenarioRoot.getAbsolutePath());
 		appConstants.setProperty("scenariosroot1.description", "Test Scenarios Root Directory");
+
+		properties = new PropertyLoader("scenario-testdata.properties");
 	}
 
 	@AfterEach
 	public void tearDown() {
 		appConstants.remove("scenariosroot1.directory");
 		appConstants.remove("scenariosroot1.description");
+		appConstants.remove("testdata.dir");
 	}
 
 	@AfterAll
@@ -63,6 +71,70 @@ public static void afterAll() {
 		CloseUtils.closeSilently(configuration);
 	}
 
+	@Test
+	public void testPrepareForCompareWithTestDataDirNotSet() {
+		// Arrange
+		LarvaTool larvaTool = LarvaTool.createInstance(configuration);
+		Map<String, Map<String, Map<String, String>>> ignoresMap = LarvaTool.mapPropertiesToIgnores(properties);
+
+		String input = """
+				<test>C:\\TestData\\SomePath\\MyFile.txt</test>
+				""";
+
+		String expected = """
+				<test>C:\\TestData\\SomePath\\MyFile.txt</test>
+				""";
+
+		// Act
+		String actual = larvaTool.prepareResultForCompare(input, properties, ignoresMap);
+
+		// Assert
+		assertEquals(expected, actual);
+	}
+	@Test
+	public void testPrepareForCompareWithTestDataDirUnixPathInput() {
+		// Arrange
+		LarvaTool larvaTool = LarvaTool.createInstance(configuration);
+		appConstants.setProperty("testdata.dir", "/var/testdata");
+		Map<String, Map<String, Map<String, String>>> ignoresMap = LarvaTool.mapPropertiesToIgnores(properties);
+
+		String input = """
+				<test>/var/testdata/SomePath/MyFile.txt</test>
+				""";
+
+		String expected = """
+				<test>TESTDATA_DIR/SomePath/MyFile.txt</test>
+				""";
+
+		// Act
+		String actual = larvaTool.prepareResultForCompare(input, properties, ignoresMap);
+
+		// Assert
+		assertEquals(expected, actual);
+	}
+
+	@Test
+	public void testPrepareForCompareWithTestDataDirWindowsPathInput() {
+		// Arrange
+		LarvaTool larvaTool = LarvaTool.createInstance(configuration);
+		appConstants.setProperty("testdata.dir", "C:\\TestData");
+		Map<String, Map<String, Map<String, String>>> ignoresMap = LarvaTool.mapPropertiesToIgnores(properties);
+
+		String input = """
+				<test>C:\\TestData\\SomePath\\MyFile.txt</test>
+				""";
+
+		String expected = """
+				<test>TESTDATA_DIR/SomePath/MyFile.txt</test>
+				""";
+
+		// Act
+		String actual = larvaTool.prepareResultForCompare(input, properties, ignoresMap);
+
+		// Assert
+		assertEquals(expected, actual);
+	}
+
 	@Test
 	void testRunScenariosFromServletRequest () {
 		// Arrange
diff --git a/larva/src/test/resources/scenario-testdata.properties b/larva/src/test/resources/scenario-testdata.properties
new file mode 100644
index 00000000000..c9e6fb9f51a
--- /dev/null
+++ b/larva/src/test/resources/scenario-testdata.properties
@@ -0,0 +1,11 @@
+replaceRegularExpressionKeys.testdatadir-separator1.key1=(TESTDATA_DIR)\\\\
+replaceRegularExpressionKeys.testdatadir-separator1.key2=$1/
+
+replaceRegularExpressionKeys.testdatadir-separator2.key1=((?:TESTDATA_DIR)[\\\\/][a-zA-Z0-9\-_ ]*)[\\\\/]
+replaceRegularExpressionKeys.testdatadir-separator2.key2=$1/
+
+replaceRegularExpressionKeys.testdatadir-separator3.key1=((?:TESTDATA_DIR)[\\\\/][a-zA-Z0-9\-_ ]*[\\\\/][a-zA-Z0-9\-_ ]*)[\\\\/]
+replaceRegularExpressionKeys.testdatadir-separator3.key2=$1/
+
+replaceRegularExpressionKeys.testdatadir-separator4.key1=((?:TESTDATA_DIR)[\\\\/][a-zA-Z0-9\-_ ]*[\\\\/][a-zA-Z0-9\-_ ]*[\\\\/][a-zA-Z0-9\-_ ]*)[\\\\/]
+replaceRegularExpressionKeys.testdatadir-separator4.key2=$1/
diff --git a/test/src/main/resources/DeploymentSpecifics.properties b/test/src/main/resources/DeploymentSpecifics.properties
index 2fe50cffd68..63cd0912ba7 100644
--- a/test/src/main/resources/DeploymentSpecifics.properties
+++ b/test/src/main/resources/DeploymentSpecifics.properties
@@ -118,10 +118,6 @@ tt.dir=${log.dir}/testtool
 testdata.dir=${log.dir}/testdata
 fxf.dir=${testdata.dir}/fxf
 
-# Please mark that the backslashes below are double escaped: first for the value of the property, second time for use in regular expression
-log.dir.match=(?i)([cd]:[\\\\/]temp)|(${log.dir})
-testdata.dir.match=((${log.dir.match})[\\\\/]testdata)|(${testdata.dir})
-
 warnings.suppress.unsafeAttribute=true
 
 
diff --git a/test/src/main/resources/StageSpecifics_LOC.properties b/test/src/main/resources/StageSpecifics_LOC.properties
index de8b6aca074..bbc3ac4a4b0 100644
--- a/test/src/main/resources/StageSpecifics_LOC.properties
+++ b/test/src/main/resources/StageSpecifics_LOC.properties
@@ -59,13 +59,3 @@ larva.adapter.execute=IbisConsole
 
 # dtap.stage=LOC
 # log.dir=c:/temp
-#
-# The directory represented by ${log.dir} can appear in different ways under Windows.
-# Supply this regex to match every possible way.
-#
-# Comment on the value chosen for Windows. This expression matches:
-#   c:/temp
-#   c:\temp
-#   C:/temp
-#   C:\temp
-# log.dir.match=(?i)c:[\\\\/]temp
diff --git a/test/src/test/java/org/frankframework/runner/RunCypressE2eTest.java b/test/src/test/java/org/frankframework/runner/RunCypressE2eTest.java
index dd5fccf84ad..58547894e3e 100644
--- a/test/src/test/java/org/frankframework/runner/RunCypressE2eTest.java
+++ b/test/src/test/java/org/frankframework/runner/RunCypressE2eTest.java
@@ -17,6 +17,7 @@
 package org.frankframework.runner;
 
 import static org.awaitility.Awaitility.await;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
@@ -29,7 +30,6 @@
 
 import org.apache.logging.log4j.Logger;
 import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.DynamicContainer;
 import org.junit.jupiter.api.DynamicTest;
@@ -69,7 +69,7 @@
 public class RunCypressE2eTest {
 	private static CypressContainer container;
 	private static ConfigurableApplicationContext run;
-	private static final Logger LOGGER = LogUtil.getLogger("cypress");
+	private static final Logger CYPRESS_LOG = LogUtil.getLogger("cypress");
 
 	@BeforeAll
 	public static void setUp() throws IOException {
@@ -94,7 +94,7 @@ private static boolean verifyAppIsHealthy(OutboundGateway gateway) {
 			Message<Object> response = gateway.sendSyncMessage(RequestMessageBuilder.create(BusTopic.HEALTH).build(null));
 			return "200".equals(response.getHeaders().get(BusMessageUtils.HEADER_PREFIX+MessageBase.STATUS_KEY));
 		} catch (Exception e) {
-			LOGGER.error("error while checking health of application", e);
+			CYPRESS_LOG.error("error while checking health of application", e);
 			return false;
 		}
 	}
@@ -104,7 +104,7 @@ public static void startTestContainer() {
 
 		container = new CypressContainer();
 		container.withBaseUrl("http://host.testcontainers.internal:8080/iaf-test/iaf/gui");
-		container.withLogConsumer(frame -> LOGGER.info(frame.getUtf8StringWithoutLineEnding()));
+		container.withLogConsumer(frame -> CYPRESS_LOG.info(frame.getUtf8StringWithoutLineEnding()));
 
 		container.start();
 
@@ -116,8 +116,10 @@ public static void tearDown() {
 		run.stop();
 		container.stop();
 
-		Assertions.assertFalse(run.isRunning());
-		Assertions.assertFalse(container.isRunning());
+		assertFalse(run.isRunning());
+		assertFalse(container.isRunning());
+
+		run.close();
 	}
 
 	@TestFactory
diff --git a/test/src/test/java/org/frankframework/runner/RunLarvaTests.java b/test/src/test/java/org/frankframework/runner/RunLarvaTests.java
index 0332ecdedc7..3ce21614710 100644
--- a/test/src/test/java/org/frankframework/runner/RunLarvaTests.java
+++ b/test/src/test/java/org/frankframework/runner/RunLarvaTests.java
@@ -1,5 +1,6 @@
 package org.frankframework.runner;
 
+import static org.awaitility.Awaitility.await;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -8,9 +9,11 @@
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Paths;
+import java.time.Duration;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Stream;
 
 import jakarta.annotation.Nonnull;
@@ -29,8 +32,12 @@
 import org.junit.jupiter.api.TestFactory;
 import org.springframework.boot.SpringApplication;
 import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.messaging.Message;
+
+import lombok.extern.log4j.Log4j2;
 
 import org.frankframework.configuration.IbisContext;
+import org.frankframework.console.util.RequestMessageBuilder;
 import org.frankframework.larva.LarvaConfig;
 import org.frankframework.larva.LarvaLogLevel;
 import org.frankframework.larva.LarvaTool;
@@ -41,7 +48,13 @@
 import org.frankframework.larva.output.PlainTextScenarioOutputRenderer;
 import org.frankframework.larva.output.TestExecutionObserver;
 import org.frankframework.lifecycle.FrankApplicationInitializer;
+import org.frankframework.management.bus.BusMessageUtils;
+import org.frankframework.management.bus.BusTopic;
+import org.frankframework.management.bus.LocalGateway;
+import org.frankframework.management.bus.OutboundGateway;
+import org.frankframework.management.bus.message.MessageBase;
 import org.frankframework.util.CloseUtils;
+import org.frankframework.util.SpringUtils;
 
 /**
  * Attempt to run Larva tests in the Maven build.
@@ -53,50 +66,18 @@
  *
  */
 @Tag("integration")
+@Log4j2
 public class RunLarvaTests {
 
 	public static final LarvaLogLevel LARVA_LOG_LEVEL = LarvaLogLevel.WRONG_PIPELINE_MESSAGES_PREPARED_FOR_DIFF;
 	public static final Set<String> IGNORED_SCENARIOS = Set.of(
-			"ApiListener/scenario01",
-			"ApiListener/scenario02",
-			"ApiListener/scenario03",
-			"ApiListener/scenario04",
-			"ApiListener/scenario05",
-			"ApiListener/scenario06",
-			"ApiListener/scenario07",
-			"ApiListener/scenario08",
 			"Authentication/scenario03",
 			"Authentication/scenario04",
 			"Base64Pipe/scenario01",
 			"Base64Pipe/scenario02",
-			"CorrelationMessageId/scenario04",
-			"CorrelationMessageId/scenario05",
-			"Exits/api/scenario01",
-			"Exits/api/scenario01b",
-			"Exits/api/scenario03",
-			"Exits/soap/scenario01",
-			"Exits/soap/scenario02",
-			"JSON/DataSonnet/scenario01",
-			"JSON/JsonPipe/scenario01",
 			"FileSender/scenario01",
-			"ForwardNameProvidingSenders/scenario10",
-			"ForwardNameProvidingSenders/scenario11",
-			"ForwardNameProvidingSenders/scenario12",
-			"ForwardNameProvidingSenders/scenario13",
-			"FrankSender/scenario05",
 			"ManagedFileHandler/scenario01",
 			"ManagedFileHandler/scenario02",
-			"LocalFileSystemPipe/scenario07",
-			"LocalFileSystemPipe/scenario08",
-			"MoveFiles/scenario01",
-			"MoveFiles/scenario04",
-			"MoveFiles/scenario09",
-			"Receivers/NonTransacted/NoInProcess/scenario01",
-			"Receivers/NonTransacted/NoInProcess/scenario05",
-			"Receivers/NonTransacted/NoInProcess/scenario06",
-			"Receivers/Transacted/WithInProcess/scenario03",
-			"RestListener/scenario01",
-			"RestListener/scenario02",
 			"Validators/SoapValidator/scenario07",
 			"WebServiceListenerSender/scenario11b",
 			"WebServiceListenerSender/scenario11c",
@@ -104,9 +85,7 @@ public class RunLarvaTests {
 			"WsdlGeneratorPipe/scenario01",
 			"WsdlGeneratorPipe/scenario02",
 			"WsdlGeneratorPipe/scenario03",
-			"XsltProviderListener/scenario04",
-			"Zip/ZipWriter/scenario 01",
-			"Zip/ZipWriter/scenario 02"
+			"XsltProviderListener/scenario04"
 	);
 
 	private static ConfigurableApplicationContext parentContext;
@@ -132,6 +111,22 @@ static void setupBeforeAll() throws IOException {
 		// We need to get the IbisContext from the ServletContext, since from this one we can get the ApplicationContext that has the database.
 		ibisContext = FrankApplicationInitializer.getIbisContext(servletContext);
 		applicationContext = ibisContext.getApplicationContext();
+
+		OutboundGateway gateway = SpringUtils.createBean(parentContext, LocalGateway.class);
+		assertTrue(parentContext.isRunning());
+		await().pollInterval(5, TimeUnit.SECONDS)
+				.atMost(Duration.ofMinutes(5))
+				.until(() -> verifyAppIsHealthy(gateway));
+	}
+
+	private static boolean verifyAppIsHealthy(OutboundGateway gateway) {
+		try {
+			Message<Object> response = gateway.sendSyncMessage(RequestMessageBuilder.create(BusTopic.HEALTH).build(null));
+			return "200".equals(response.getHeaders().get(BusMessageUtils.HEADER_PREFIX+ MessageBase.STATUS_KEY));
+		} catch (Exception e) {
+			log.error("error while checking health of application", e);
+			return false;
+		}
 	}
 
 	@BeforeEach
diff --git a/test/src/test/testtool/global.properties b/test/src/test/testtool/global.properties
index 2129e61d3c3..ba36e98ae52 100644
--- a/test/src/test/testtool/global.properties
+++ b/test/src/test/testtool/global.properties
@@ -46,19 +46,16 @@ replaceEverywhereKey15.key2=jms/i4testiaf_in
 replaceEverywhereKey16.key1=${jms.destination.i4testiaf_ff}
 replaceEverywhereKey16.key2=jms/i4testiaf_ff
 
-replaceRegularExpressionKeys.testdatadir.key1=${testdata.dir.match}
-replaceRegularExpressionKeys.testdatadir.key2=TESTDATA_DIR
-
-replaceRegularExpressionKeys.testdatadir-separator1.key1=(${testdata.dir.match}|TESTDATA_DIR)\\\\
+replaceRegularExpressionKeys.testdatadir-separator1.key1=(TESTDATA_DIR)\\\\
 replaceRegularExpressionKeys.testdatadir-separator1.key2=$1/
 
-replaceRegularExpressionKeys.testdatadir-separator2.key1=((?:${testdata.dir.match}|TESTDATA_DIR)[\\\\/][a-zA-Z0-9\-_ ]*)[\\\\/]
+replaceRegularExpressionKeys.testdatadir-separator2.key1=((?:TESTDATA_DIR)[\\\\/][a-zA-Z0-9\-_ ]*)[\\\\/]
 replaceRegularExpressionKeys.testdatadir-separator2.key2=$1/
 
-replaceRegularExpressionKeys.testdatadir-separator3.key1=((?:${testdata.dir.match}|TESTDATA_DIR)[\\\\/][a-zA-Z0-9\-_ ]*[\\\\/][a-zA-Z0-9\-_ ]*)[\\\\/]
+replaceRegularExpressionKeys.testdatadir-separator3.key1=((?:TESTDATA_DIR)[\\\\/][a-zA-Z0-9\-_ ]*[\\\\/][a-zA-Z0-9\-_ ]*)[\\\\/]
 replaceRegularExpressionKeys.testdatadir-separator3.key2=$1/
 
-replaceRegularExpressionKeys.testdatadir-separator4.key1=((?:${testdata.dir.match}|TESTDATA_DIR)[\\\\/][a-zA-Z0-9\-_ ]*[\\\\/][a-zA-Z0-9\-_ ]*[\\\\/][a-zA-Z0-9\-_ ]*)[\\\\/]
+replaceRegularExpressionKeys.testdatadir-separator4.key1=((?:TESTDATA_DIR)[\\\\/][a-zA-Z0-9\-_ ]*[\\\\/][a-zA-Z0-9\-_ ]*[\\\\/][a-zA-Z0-9\-_ ]*)[\\\\/]
 replaceRegularExpressionKeys.testdatadir-separator4.key2=$1/
 
 ignoreContentBetweenKeys.messageId.key1=messageId="


Reviews:
user: login: evandongen
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T09:42:35Z
user: login: nielsm5
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-05-20T10:19:49Z
user: login: tnleeuw
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T10:28:22Z
user: login: nielsm5
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-20T10:29:36Z
user: login: nielsm5
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-20T14:19:36Z

Review comments:
diff_hunk: @@ -1,7 +1,7 @@
 scenario.description = Test the XSLT provider listener with xslt parameters with xslt file in configuration folder
 
 java.XsltProviderListener.className = org.frankframework.larva.XsltProviderListener
-java.XsltProviderListener.filename = configurations/UTIL/Larva/xsltProviderListener/ApplyValueOverrides.xslt
path: test/src/test/testtool/XsltProviderListener/scenario04.properties
user: login: nielsm5
body: Deze moet wel echt as is blijven. Dat is het hele punt van deze test. (lees ook de description)
created_at: 2025-05-20T10:19:10Z
author_association: MEMBER
diff_hunk: @@ -508,6 +508,19 @@ private int reportFailedCompare(TestExecutionObserver testExecutionObserver, Sce
 
 	public String prepareResultForCompare(String input, Properties properties, Map<String, Map<String, Map<String, String>>> ignoreMap) {
 		String result = input;
+
+		// TESTDATA-dir based file paths in results can often not be compared properly because of location differences, and complicated by system-dependent file paths.
+		// Changing Windows backslashes to Unix forward slashes in the rest of file paths is done with regexes configured in global.properties
+		String testDataDirPropertyValue = AppConstants.getInstance().getProperty("testdata.dir");
path: larva/src/main/java/org/frankframework/larva/LarvaTool.java
user: login: nielsm5
body: Dit is wel een iaf-test specifiek piefje hoor... Misschien dat elke directory standaard genormalizeerd moet worden?
created_at: 2025-05-20T10:19:46Z
author_association: MEMBER
diff_hunk: @@ -508,6 +508,19 @@ private int reportFailedCompare(TestExecutionObserver testExecutionObserver, Sce
 
 	public String prepareResultForCompare(String input, Properties properties, Map<String, Map<String, Map<String, String>>> ignoreMap) {
 		String result = input;
+
+		// TESTDATA-dir based file paths in results can often not be compared properly because of location differences, and complicated by system-dependent file paths.
+		// Changing Windows backslashes to Unix forward slashes in the rest of file paths is done with regexes configured in global.properties
+		String testDataDirPropertyValue = AppConstants.getInstance().getProperty("testdata.dir");
path: larva/src/main/java/org/frankframework/larva/LarvaTool.java
user: login: tnleeuw
body: Maar hoe vind je die directories / paden in de output? Op een gegarandeerde manier?
De regex die we hadden, die werkt in ieder geval niet goed omdat er teveel variatie is in hoe paden gespecifeerd kunnen worden, en teveel verschillende plaatsen waar een pad ergens in de config komt, uit de config wordt gehaald, of in een Message kan komen.

Ik zie voorlopig nog geen goede manier om paden altijd gestandaardiseerd te krijgen.
created_at: 2025-05-20T10:28:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -508,6 +508,19 @@ private int reportFailedCompare(TestExecutionObserver testExecutionObserver, Sce
 
 	public String prepareResultForCompare(String input, Properties properties, Map<String, Map<String, Map<String, String>>> ignoreMap) {
 		String result = input;
+
+		// TESTDATA-dir based file paths in results can often not be compared properly because of location differences, and complicated by system-dependent file paths.
+		// Changing Windows backslashes to Unix forward slashes in the rest of file paths is done with regexes configured in global.properties
+		String testDataDirPropertyValue = AppConstants.getInstance().getProperty("testdata.dir");
path: larva/src/main/java/org/frankframework/larva/LarvaTool.java
user: login: nielsm5
body: alles wat een absolute path (rare property methode) krijgt normaliseren?
created_at: 2025-05-20T10:29:36Z
author_association: MEMBER

PR comments:
user: login: sonarqubecloud[bot]
created_at: 2025-05-20T11:14:19Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=ibissource_iaf&pullRequest=9009) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=ibissource_iaf&pullRequest=9009&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=ibissource_iaf&pullRequest=9009&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=ibissource_iaf&pullRequest=9009&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [100.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=ibissource_iaf&pullRequest=9009&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=ibissource_iaf&pullRequest=9009&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=ibissource_iaf&pullRequest=9009)


author_association: NONE