forked from eclipse-platform/eclipse.platform
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Execute before/after methods in session tests in correct instance ecl…
…ipse-platform#903 The SessionTestExtension intercepts test execution to deploy it to a remote executor starting a dedicated Eclipse application / session. In both the host and the remote-execution environment, a test runner executes the method and the interceptor decides how it is processed. Currently, the before/after methods of the test class are not properly considered, thus they are executed on both the host and the remote system, which can lead to unintended behavior This change improves consistency and comprehensibility of the session test execution. To this end, it converts the SessionTestExtension into an interface and splits it up into two realizations, one for the host and one for the remote execution, each ensuring that test methods are properly processed in their environment. It also ensures that before/after methods are, by default, only executed remotely, i.e., where the actual test method is executed, as these methods usually do some recurring preparation/cleanup work that needs to be done on the same test class instances state than on which the test is executed. In addition, the `ExecuteInHost` annotation is introduced, which can be attached to any before/after and ordinary test method to execute it in the host instance instead of the remote session. This can be used for general setup of the test instance at the host, but also for adding some reconfiguration or validation work done on the host between multiple sessions. Contributes to eclipse-platform#903
- Loading branch information
1 parent
390d8aa
commit 89e0125
Showing
11 changed files
with
268 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
....eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/session/ExecuteInHost.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2024 Vector Informatik GmbH and others. | ||
* | ||
* This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v2.0 | ||
* which accompanies this distribution, and is available at | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*******************************************************************************/ | ||
package org.eclipse.core.tests.harness.session; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* Can be attached to any test method, before method or after method in a | ||
* session test class (i.e., one using a {@link SessionTestExtension}). It | ||
* defines that the annotated method is to be executed in the host Eclipse and | ||
* not in the remote Eclipse application started to run a test in a separate | ||
* session. | ||
*/ | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.METHOD) | ||
public @interface ExecuteInHost { | ||
// Marker annotation | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
143 changes: 143 additions & 0 deletions
143
...re.tests.harness/src/org/eclipse/core/tests/harness/session/SessionTestExtensionHost.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2024 Vector Informatik GmbH and others. | ||
* | ||
* This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v2.0 | ||
* which accompanies this distribution, and is available at | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*******************************************************************************/ | ||
package org.eclipse.core.tests.harness.session; | ||
|
||
import java.lang.reflect.Method; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
import org.eclipse.core.tests.harness.session.customization.SessionCustomization; | ||
import org.eclipse.core.tests.session.Setup; | ||
import org.eclipse.core.tests.session.SetupManager; | ||
import org.eclipse.core.tests.session.SetupManager.SetupException; | ||
import org.junit.jupiter.api.extension.ExtensionContext; | ||
import org.junit.jupiter.api.extension.ReflectiveInvocationContext; | ||
|
||
/** | ||
* The implementation of the {@link SessionTestExtension} to be instantiated on | ||
* the host that is executing the session tests. It executes the test methods | ||
* remotely in a dedicated session. | ||
*/ | ||
class SessionTestExtensionHost implements SessionTestExtension { | ||
public static final String CORE_TEST_APPLICATION = "org.eclipse.pde.junit.runtime.coretestapplication"; //$NON-NLS-1$ | ||
|
||
private final RemoteTestExecutor testExecutor; | ||
|
||
private final Setup setup; | ||
|
||
private final Set<SessionCustomization> sessionCustomizations = new HashSet<>(); | ||
|
||
SessionTestExtensionHost(String pluginId, String applicationId) { | ||
try { | ||
this.setup = SetupManager.getInstance().getDefaultSetup(); | ||
setup.setSystemProperty("org.eclipse.update.reconcile", "false"); | ||
testExecutor = new RemoteTestExecutor(setup, applicationId, pluginId); | ||
} catch (SetupException e) { | ||
throw new IllegalStateException("unable to create setup", e); | ||
} | ||
} | ||
|
||
void addSessionCustomization(SessionCustomization sessionCustomization) { | ||
this.sessionCustomizations.add(sessionCustomization); | ||
} | ||
|
||
/** | ||
* Sets the given Eclipse program argument to the given value for sessions | ||
* executed with this extension. | ||
* | ||
* @param key the Eclipse argument key, must not be {@code null} | ||
* @param value the Eclipse argument value to set, may be {@code null} to remove | ||
* the key | ||
*/ | ||
@Override | ||
public void setEclipseArgument(String key, String value) { | ||
setup.setEclipseArgument(key, value); | ||
} | ||
|
||
/** | ||
* Sets the given system property to the given value for sessions executed with | ||
* this extension. | ||
* | ||
* @param key the system property key, must not be {@code null} | ||
* @param value the system property value to set, may be {@code null} to remove | ||
* the key | ||
*/ | ||
@Override | ||
public void setSystemProperty(String key, String value) { | ||
setup.setSystemProperty(key, value); | ||
} | ||
|
||
@Override | ||
public void interceptTestMethod(Invocation<Void> invocation, ReflectiveInvocationContext<Method> invocationContext, | ||
ExtensionContext extensionContext) throws Throwable { | ||
if (!skipIfNotExecuteInHost(invocation, invocationContext)) { | ||
return; | ||
} | ||
|
||
Class<?> testClass = extensionContext.getTestClass().get(); | ||
Method testMethod = extensionContext.getTestMethod().get(); | ||
|
||
boolean shouldFail = extensionContext.getTestMethod().get().getAnnotation(SessionShouldError.class) != null; | ||
try { | ||
prepareSession(); | ||
testExecutor.executeRemotely(testClass.getName(), testMethod.getName(), shouldFail); | ||
} finally { | ||
cleanupSession(); | ||
} | ||
} | ||
|
||
private boolean skipIfNotExecuteInHost(Invocation<Void> invocation, | ||
ReflectiveInvocationContext<Method> invocationContext) throws Throwable { | ||
boolean shouldExecuteInHost = invocationContext.getExecutable().getAnnotation(ExecuteInHost.class) != null; | ||
if (!shouldExecuteInHost) { | ||
invocation.skip(); | ||
return true; | ||
} | ||
invocation.proceed(); | ||
return false; | ||
} | ||
|
||
private void prepareSession() throws Exception { | ||
for (SessionCustomization customization : sessionCustomizations) { | ||
customization.prepareSession(setup); | ||
} | ||
} | ||
|
||
private void cleanupSession() throws Exception { | ||
for (SessionCustomization customization : sessionCustomizations) { | ||
customization.cleanupSession(setup); | ||
} | ||
} | ||
|
||
@Override | ||
public void interceptAfterAllMethod(Invocation<Void> invocation, | ||
ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext) throws Throwable { | ||
skipIfNotExecuteInHost(invocation, invocationContext); | ||
} | ||
|
||
@Override | ||
public void interceptAfterEachMethod(Invocation<Void> invocation, | ||
ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext) throws Throwable { | ||
skipIfNotExecuteInHost(invocation, invocationContext); | ||
} | ||
|
||
@Override | ||
public void interceptBeforeAllMethod(Invocation<Void> invocation, | ||
ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext) throws Throwable { | ||
skipIfNotExecuteInHost(invocation, invocationContext); | ||
} | ||
|
||
@Override | ||
public void interceptBeforeEachMethod(Invocation<Void> invocation, | ||
ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext) throws Throwable { | ||
skipIfNotExecuteInHost(invocation, invocationContext); | ||
} | ||
|
||
} |
Oops, something went wrong.