From 5010c2678c2d5ef9557b1eabedce9aa1f0b0e27b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= <laeubi@laeubi-soft.de>
Date: Mon, 22 Jan 2024 16:27:56 +0100
Subject: [PATCH] Add testcase for director provisioned product and
 tycho-surefire

+ fix wrong folder is used on macosx
---
 .../director/shared/DirectorRuntime.java      | 32 +++++++
 .../example-product/pom.xml                   |  8 ++
 .../META-INF/MANIFEST.MF                      |  7 ++
 .../extProductTestDirector/build.properties   |  4 +
 .../extProductTestDirector/pom.xml            | 87 +++++++++++++++++++
 .../src/testProvisioning/RootFileTest.java    | 19 ++++
 .../surefire.p2InstalledRuntime/pom.xml       |  7 ++
 .../surefire/P2InstalledTestRuntimeTest.java  | 11 +++
 .../plugins/p2/director/DirectorMojo.java     |  5 +-
 .../ProvisionedInstallationBuilder.java       | 29 +------
 10 files changed, 181 insertions(+), 28 deletions(-)
 create mode 100644 tycho-its/projects/surefire.p2InstalledRuntime/extProductTestDirector/META-INF/MANIFEST.MF
 create mode 100644 tycho-its/projects/surefire.p2InstalledRuntime/extProductTestDirector/build.properties
 create mode 100644 tycho-its/projects/surefire.p2InstalledRuntime/extProductTestDirector/pom.xml
 create mode 100644 tycho-its/projects/surefire.p2InstalledRuntime/extProductTestDirector/src/testProvisioning/RootFileTest.java

diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/director/shared/DirectorRuntime.java b/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/director/shared/DirectorRuntime.java
index 307d0b876f..a92fcf57f8 100644
--- a/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/director/shared/DirectorRuntime.java
+++ b/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/director/shared/DirectorRuntime.java
@@ -17,6 +17,7 @@
 import java.util.Map;
 
 import org.eclipse.tycho.DependencySeed;
+import org.eclipse.tycho.PlatformPropertiesUtils;
 import org.eclipse.tycho.TargetEnvironment;
 
 /**
@@ -59,4 +60,35 @@ public interface Command {
      * director runtime.
      */
     public Command newInstallCommand();
+
+    /**
+     * Computes the destination of a director install based on a target environment
+     * 
+     * @param baseLocation
+     * @param env
+     * @return
+     */
+    public static File getDestination(File baseLocation, TargetEnvironment env) {
+        if (PlatformPropertiesUtils.OS_MACOSX.equals(env.getOs()) && !hasRequiredMacLayout(baseLocation)) {
+            return new File(baseLocation, "Eclipse.app/Contents/Eclipse/");
+        }
+        return baseLocation;
+    }
+
+    private static boolean hasRequiredMacLayout(File folder) {
+        //TODO if we do not have this exact layout then director fails with:
+        //The framework persistent data location (/work/MacOS/configuration) is not the same as the framework configuration location /work/Contents/Eclipse/configuration)
+        //maybe we can simply configure the "persistent data location" to point to the expected one?
+        //or the "configuration location" must be configured and look like /work/Contents/<work>/configuration ?
+        //the actual values seem even depend on if this is an empty folder where one installs or an existing one
+        //e.g. if one installs multiple env Equinox finds the launcher and then set the location different...
+        if ("Eclipse".equals(folder.getName())) {
+            File folder2 = folder.getParentFile();
+            if (folder2 != null && "Contents".equals(folder2.getName())) {
+                File parent = folder2.getParentFile();
+                return parent != null && parent.getName().endsWith(".app");
+            }
+        }
+        return false;
+    }
 }
diff --git a/tycho-its/projects/surefire.p2InstalledRuntime/example-product/pom.xml b/tycho-its/projects/surefire.p2InstalledRuntime/example-product/pom.xml
index bac2234569..ccf91c8473 100644
--- a/tycho-its/projects/surefire.p2InstalledRuntime/example-product/pom.xml
+++ b/tycho-its/projects/surefire.p2InstalledRuntime/example-product/pom.xml
@@ -26,6 +26,14 @@
 
 	<build>
 		<plugins>
+			<plugin>
+				<groupId>org.eclipse.tycho</groupId>
+				<artifactId>tycho-p2-repository-plugin</artifactId>
+				<version>${tycho-version}</version>
+				<configuration>
+					<includeAllDependencies>true</includeAllDependencies>
+				</configuration>
+			</plugin>
 			<plugin>
 				<groupId>org.eclipse.tycho</groupId>
 				<artifactId>tycho-p2-director-plugin</artifactId>
diff --git a/tycho-its/projects/surefire.p2InstalledRuntime/extProductTestDirector/META-INF/MANIFEST.MF b/tycho-its/projects/surefire.p2InstalledRuntime/extProductTestDirector/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..0a321b3440
--- /dev/null
+++ b/tycho-its/projects/surefire.p2InstalledRuntime/extProductTestDirector/META-INF/MANIFEST.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: spir.extProductTest
+Bundle-Version: 1.0.0
+Require-Bundle: org.junit,
+ org.eclipse.core.runtime
+Bundle-RequiredExecutionEnvironment: JavaSE-11
diff --git a/tycho-its/projects/surefire.p2InstalledRuntime/extProductTestDirector/build.properties b/tycho-its/projects/surefire.p2InstalledRuntime/extProductTestDirector/build.properties
new file mode 100644
index 0000000000..34d2e4d2da
--- /dev/null
+++ b/tycho-its/projects/surefire.p2InstalledRuntime/extProductTestDirector/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
diff --git a/tycho-its/projects/surefire.p2InstalledRuntime/extProductTestDirector/pom.xml b/tycho-its/projects/surefire.p2InstalledRuntime/extProductTestDirector/pom.xml
new file mode 100644
index 0000000000..ccd58ee8be
--- /dev/null
+++ b/tycho-its/projects/surefire.p2InstalledRuntime/extProductTestDirector/pom.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Copyright (c) 2013 Red Hat Inc. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ https://www.eclipse.org/legal/epl-v10.html
+
+ Contributors:
+      Mickael Istria (Red Hat JBoss) - sample product and surefire-config for 386988
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<groupId>tycho-its-project.surefire.p2InstalledRuntime</groupId>
+		<artifactId>provisionedApplicationParent</artifactId>
+		<version>1.0.0</version>
+	</parent>
+
+	<artifactId>spir.extProductTest</artifactId>
+	<packaging>eclipse-test-plugin</packaging>
+
+	<properties>
+		<!-- Default value, to override to test different OSGi versions -->
+		<other.p2.repo.url>${target-platform}</other.p2.repo.url>
+		<sdkWorkDir>${project.build.directory}/sdk-product</sdkWorkDir>
+		<sdkProfile>SDKProfile</sdkProfile>
+	</properties>
+
+	<repositories>
+		<repository>
+			<id>test-repo</id>
+			<url>${other.p2.repo.url}</url>
+			<layout>p2</layout>
+		</repository>
+	</repositories>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.eclipse.tycho</groupId>
+				<artifactId>tycho-surefire-plugin</artifactId>
+				<version>${tycho-version}</version>
+				<configuration>
+					<testRuntime>p2Installed</testRuntime>
+					<product>spir.example-product</product>
+					<work>${sdkWorkDir}</work>
+					<profileName>${sdkProfile}</profileName>
+				</configuration>
+			</plugin>
+
+			<plugin>
+				<groupId>org.eclipse.tycho</groupId>
+				<artifactId>tycho-p2-director-plugin</artifactId>
+				<version>${tycho-version}</version>
+				<configuration>
+					<destination>${sdkWorkDir}</destination>
+					<profile>${sdkProfile}</profile>
+					<installFeatures>true</installFeatures>
+				</configuration>
+				<executions>
+					<execution>
+						<id>install-sdk</id>
+						<goals>
+							<goal>director</goal>
+						</goals>
+						<phase>pre-integration-test</phase>
+						<configuration>
+							<repositories>file:${project.basedir}/../example-product/target/repository</repositories>
+							<install>
+								<iu>
+									<id>spir.example-product</id>
+								</iu>
+							</install>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+
+</project>
diff --git a/tycho-its/projects/surefire.p2InstalledRuntime/extProductTestDirector/src/testProvisioning/RootFileTest.java b/tycho-its/projects/surefire.p2InstalledRuntime/extProductTestDirector/src/testProvisioning/RootFileTest.java
new file mode 100644
index 0000000000..81bba71254
--- /dev/null
+++ b/tycho-its/projects/surefire.p2InstalledRuntime/extProductTestDirector/src/testProvisioning/RootFileTest.java
@@ -0,0 +1,19 @@
+package testProvisioning;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Platform;
+
+public class RootFileTest extends TestCase {
+
+	public void testIsProvisionedInstallation() throws Exception {
+		File eclipseInstallationRoot = new File(FileLocator.toFileURL(
+				Platform.getInstallLocation().getURL()).getPath());
+		File rootFile = new File(eclipseInstallationRoot, "README.txt");
+		assertTrue(rootFile + " does not exist - installation was not provisioned by p2", rootFile.isFile());
+	}
+
+}
diff --git a/tycho-its/projects/surefire.p2InstalledRuntime/pom.xml b/tycho-its/projects/surefire.p2InstalledRuntime/pom.xml
index b8521b747a..1d01ccbe92 100644
--- a/tycho-its/projects/surefire.p2InstalledRuntime/pom.xml
+++ b/tycho-its/projects/surefire.p2InstalledRuntime/pom.xml
@@ -60,5 +60,12 @@
 				<module>extProductTest</module>
 			</modules>
 		</profile>
+		<profile>
+			<!-- scenario 3: run tests on top of a previously provisioned product using director -->
+			<id>useProvisionedProductDirector</id>
+			<modules>
+				<module>extProductTestDirector</module>
+			</modules>
+		</profile>
 	</profiles>
 </project>
diff --git a/tycho-its/src/test/java/org/eclipse/tycho/test/surefire/P2InstalledTestRuntimeTest.java b/tycho-its/src/test/java/org/eclipse/tycho/test/surefire/P2InstalledTestRuntimeTest.java
index dc73417158..7511feced6 100644
--- a/tycho-its/src/test/java/org/eclipse/tycho/test/surefire/P2InstalledTestRuntimeTest.java
+++ b/tycho-its/src/test/java/org/eclipse/tycho/test/surefire/P2InstalledTestRuntimeTest.java
@@ -41,6 +41,17 @@ public void testRunTestOnProvisionedApp() throws Exception {
 		verifier.verifyErrorFreeLog();
 	}
 
+	@Test
+	public void testRunTestOnProvisionedDirector() throws Exception {
+		Verifier verifier = getVerifier("surefire.p2InstalledRuntime");
+		verifier.addCliOption("-Dp2.repo.url=" + ResourceUtil.P2Repositories.ECLIPSE_LATEST.toString());
+		verifier.addCliOption("-PuseProvisionedProductDirector");
+		verifier.addCliOption("-DproductClassifier=" + getProductClassifier());
+		verifier.executeGoals(List.of("clean", "integration-test"));
+		verifier.verifyErrorFreeLog();
+		verifier.verifyTextInLog("Tests run: 1");
+	}
+
 	@Test
 	public void testDifferentHarnessVersions() throws Exception {
 		Verifier verifier = getVerifier("surefire.p2InstalledRuntime", false);
diff --git a/tycho-p2-director-plugin/src/main/java/org/eclipse/tycho/plugins/p2/director/DirectorMojo.java b/tycho-p2-director-plugin/src/main/java/org/eclipse/tycho/plugins/p2/director/DirectorMojo.java
index 71a2cb459a..1104f5b457 100644
--- a/tycho-p2-director-plugin/src/main/java/org/eclipse/tycho/plugins/p2/director/DirectorMojo.java
+++ b/tycho-p2-director-plugin/src/main/java/org/eclipse/tycho/plugins/p2/director/DirectorMojo.java
@@ -37,9 +37,11 @@
 import org.eclipse.equinox.p2.core.IProvisioningAgent;
 import org.eclipse.equinox.p2.core.IProvisioningAgentProvider;
 import org.eclipse.equinox.p2.core.ProvisionException;
+import org.eclipse.tycho.TargetEnvironment;
 import org.eclipse.tycho.TychoConstants;
 import org.eclipse.tycho.p2.CommandLineArguments;
 import org.eclipse.tycho.p2.resolver.BundlePublisher;
+import org.eclipse.tycho.p2.tools.director.shared.DirectorRuntime;
 import org.eclipse.tycho.p2tools.TychoDirectorApplication;
 
 /**
@@ -349,7 +351,8 @@ public class DirectorMojo extends AbstractMojo {
     @Override
     public void execute() throws MojoExecutionException, MojoFailureException {
         CommandLineArguments args = new CommandLineArguments();
-        args.addNonNull("-destination", destination);
+        args.addNonNull("-destination",
+                DirectorRuntime.getDestination(destination, TargetEnvironment.getRunningEnvironment()));
         args.addNonNull("-metadatarepository", metadatarepositories);
         args.addNonNull("-artifactrepository", artifactrepositories);
         args.addNonNull("-repository", getRepositories());
diff --git a/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/provisioning/ProvisionedInstallationBuilder.java b/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/provisioning/ProvisionedInstallationBuilder.java
index 63958d18aa..448556f714 100644
--- a/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/provisioning/ProvisionedInstallationBuilder.java
+++ b/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/provisioning/ProvisionedInstallationBuilder.java
@@ -23,7 +23,6 @@
 import org.codehaus.plexus.util.FileUtils;
 import org.eclipse.sisu.equinox.launching.EquinoxInstallation;
 import org.eclipse.sisu.equinox.launching.ProvisionedEquinoxInstallation;
-import org.eclipse.tycho.PlatformPropertiesUtils;
 import org.eclipse.tycho.TargetEnvironment;
 import org.eclipse.tycho.p2.tools.director.shared.DirectorCommandException;
 import org.eclipse.tycho.p2.tools.director.shared.DirectorRuntime;
@@ -100,7 +99,7 @@ public EquinoxInstallation install(TargetEnvironment main) throws Exception {
         validate();
         publishPlainBundleJars();
         executeDirector(main);
-        return new ProvisionedEquinoxInstallation(getFinalDestination(main));
+        return new ProvisionedEquinoxInstallation(DirectorRuntime.getDestination(effectiveDestination, main));
     }
 
     private void publishPlainBundleJars() throws Exception {
@@ -127,7 +126,7 @@ private void executeDirector(TargetEnvironment env) throws MojoFailureException
         for (String iu : ius) {
             command.addUnitToInstall(iu);
         }
-        command.setDestination(getFinalDestination(env));
+        command.setDestination(DirectorRuntime.getDestination(effectiveDestination, env));
         command.setProfileName(profileName);
         command.setInstallFeatures(installFeatures);
         command.setEnvironment(env);
@@ -139,30 +138,6 @@ private void executeDirector(TargetEnvironment env) throws MojoFailureException
         }
     }
 
-    private File getFinalDestination(TargetEnvironment env) {
-        if (PlatformPropertiesUtils.OS_MACOSX.equals(env.getOs()) && !hasRequiredMacLayout(effectiveDestination)) {
-            return new File(effectiveDestination, "Eclipse.app/Contents/Eclipse/");
-        }
-        return effectiveDestination;
-    }
-
-    private static boolean hasRequiredMacLayout(File folder) {
-        //TODO if we do not have this exact layout then director fails with:
-        //The framework persistent data location (/work/MacOS/configuration) is not the same as the framework configuration location /work/Contents/Eclipse/configuration)
-        //maybe we can simply configure the "persistent data location" to point to the expected one?
-        //or the "configuration location" must be configured and look like /work/Contents/<work>/configuration ?
-        //the actual values seem even depend on if this is an empty folder where one installs or an existing one
-        //e.g. if one installs multiple env Equinox finds the launcher and then set the location different...
-        if ("Eclipse".equals(folder.getName())) {
-            File folder2 = folder.getParentFile();
-            if (folder2 != null && "Contents".equals(folder2.getName())) {
-                File parent = folder2.getParentFile();
-                return parent != null && parent.getName().endsWith(".app");
-            }
-        }
-        return false;
-    }
-
     private void validate() {
         assertNotNull(workingDir, "workingDir");
         assertNotNull(effectiveDestination, "destination");