Skip to content

Commit

Permalink
Ensure JVM flags are propagated in LocalAppEngineServerLaunchConfigur…
Browse files Browse the repository at this point in the history
…ationDelegate (#3485)

Test that JDWP is connected by looking for running threads.
  • Loading branch information
briandealwis authored Jun 24, 2019
1 parent 8abe2ad commit 4ec70c5
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,8 @@ public void launch(ILaunchConfiguration configuration, String mode, final ILaunc
generateServerRunConfiguration(configuration, server, mode, runnables);
if (ILaunchManager.DEBUG_MODE.equals(mode)) {
int debugPort = getDebugPort();
setupDebugTarget(devServerRunConfiguration, launch, debugPort, monitor);
devServerRunConfiguration =
setupDebugTarget(devServerRunConfiguration, launch, debugPort, monitor);
}

IJavaProject javaProject = JavaCore.create(modules[0].getProject());
Expand Down Expand Up @@ -492,8 +493,13 @@ protected void openBrowserPage(final IServer server) {
server.getName());
}

private void setupDebugTarget(RunConfiguration devServerRunConfiguration, ILaunch launch,
int debugPort, IProgressMonitor monitor) throws CoreException {
/** Set up the debug target to connect to the remote JVM. Returns the updated RunConfiguration. */
private RunConfiguration setupDebugTarget(
RunConfiguration devServerRunConfiguration,
ILaunch launch,
int debugPort,
IProgressMonitor monitor)
throws CoreException {
if (debugPort <= 0 || debugPort > 65535) {
throw new IllegalArgumentException("Debug port is set to " + debugPort //$NON-NLS-1$
+ ", should be between 1-65535"); //$NON-NLS-1$
Expand All @@ -511,7 +517,8 @@ private void setupDebugTarget(RunConfiguration devServerRunConfiguration, ILaunc
JavaRuntime.getVMConnector(IJavaLaunchConfigurationConstants.ID_SOCKET_LISTEN_VM_CONNECTOR);
if (connector == null) {
abort("Cannot find Socket Listening connector", null, 0); //$NON-NLS-1$
return; // keep JDT null analysis happy
// NOTREACHED
return null; // keep JDT null analysis happy
}

// Set JVM debugger connection parameters
Expand All @@ -523,6 +530,7 @@ private void setupDebugTarget(RunConfiguration devServerRunConfiguration, ILaunc
connectionParameters.put("timeout", Integer.toString(timeout)); //$NON-NLS-1$
connectionParameters.put("connectionLimit", "0"); //$NON-NLS-1$ //$NON-NLS-2$
connector.connect(connectionParameters, monitor, launch);
return devServerRunConfiguration;
}

private int getDebugPort() throws CoreException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory.widgetOfType;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
Expand All @@ -35,6 +36,7 @@
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.swt.custom.StyledText;
Expand All @@ -59,15 +61,15 @@ public class DebugNativeAppEngineStandardProjectTest extends BaseProjectTest {

private static final long TERMINATE_SERVER_TIMEOUT = 10000L;

@Rule
public ThreadDumpingWatchdog timer = new ThreadDumpingWatchdog(2, TimeUnit.MINUTES);
@Rule public ThreadDumpingWatchdog timer = new ThreadDumpingWatchdog(2, TimeUnit.MINUTES);

/**
* Launch a native application in debug mode and verify that:
*
* <ol>
* <li>it started,</li>
* <li>it can be terminated and removed from the launch list, and</li>
* <li>the process is actually terminated.</li>
* <li>it started,
* <li>it can be terminated and removed from the launch list, and
* <li>the process is actually terminated.
* </ol>
*/
@Test
Expand All @@ -80,8 +82,9 @@ public void testDebugLaunch() throws Exception {

assertNoService(new URL("http://localhost:8080/hello"));

project = SwtBotAppEngineActions.createNativeWebAppProject(bot, "testapp_java8", null,
"app.engine.test", null /* runtime */);
project =
SwtBotAppEngineActions.createNativeWebAppProject(
bot, "testapp_java8", null, "app.engine.test", null /* runtime */);
assertTrue(project.exists());

SWTBotTreeItem testProject = SwtBotProjectActions.selectProject(bot, "testapp_java8");
Expand All @@ -96,8 +99,10 @@ public void testDebugLaunch() throws Exception {

SwtBotTestingUtilities.clickButtonAndWaitForWindowClose(bot, bot.button("Finish"));

bot.perspectiveById("org.eclipse.debug.ui.DebugPerspective").activate(); // IDebugUIConstants.ID_DEBUG_PERSPECTIVE
SWTBotView debugView = bot.viewById("org.eclipse.debug.ui.DebugView"); // IDebugUIConstants.ID_DEBUG_VIEW
bot.perspectiveById("org.eclipse.debug.ui.DebugPerspective")
.activate(); // IDebugUIConstants.ID_DEBUG_PERSPECTIVE
SWTBotView debugView =
bot.viewById("org.eclipse.debug.ui.DebugView"); // IDebugUIConstants.ID_DEBUG_VIEW
debugView.show();

SWTBotTree launchTree =
Expand All @@ -111,22 +116,30 @@ public void testDebugLaunch() throws Exception {

SwtBotTreeUtilities.waitUntilTreeHasItems(bot, launchTree);
SWTBotTreeItem[] allItems = launchTree.getAllItems();
SwtBotTreeUtilities.waitUntilTreeContainsText(bot, allItems[0],
"App Engine Standard at localhost");
SwtBotTreeUtilities.waitUntilTreeContainsText(
bot, allItems[0], "App Engine Standard at localhost");

SWTBotView consoleView = bot.viewById("org.eclipse.ui.console.ConsoleView"); // IConsoleConstants.ID_CONSOLE_VIEW
SWTBotView consoleView =
bot.viewById("org.eclipse.ui.console.ConsoleView"); // IConsoleConstants.ID_CONSOLE_VIEW
consoleView.show();
SwtBotTestingUtilities.waitUntilViewContentDescription(
bot, consoleView, Matchers.containsString("App Engine Standard at localhost"));
SWTBotStyledText consoleContents =
new SWTBotStyledText(bot.widget(widgetOfType(StyledText.class), consoleView.getWidget()));
SwtBotTestingUtilities.waitUntilStyledTextContains(bot,
"Module instance default is running at http://localhost:8080", consoleContents);
SwtBotTestingUtilities.waitUntilStyledTextContains(
bot, "Module instance default is running at http://localhost:8080", consoleContents);

// Server is now running
assertEquals("Hello App Engine!",
assertEquals(
"Hello App Engine!",
getUrlContents(new URL("http://localhost:8080/hello"), (int) SWTBotPreferences.TIMEOUT));

// Ensure debugger has connected by looking for well-known thread
debugView.show();
assertTrue(
SwtBotTreeUtilities.hasChild(
bot, launchTree, stringContainsInOrder(Arrays.asList("Thread", "(Running)"))));

{
SWTBotView serversView = bot.viewById("org.eclipse.wst.server.ui.ServersView");
serversView.show();
Expand All @@ -149,21 +162,21 @@ public void testDebugLaunch() throws Exception {
SwtBotTreeUtilities.waitUntilTreeTextMatches(
bot, allItems[0], containsString("<terminated>"), TERMINATE_SERVER_TIMEOUT);
assertNoService(new URL("http://localhost:8080/hello"));
assertTrue("App Engine console should mark as stopped",
assertTrue(
"App Engine console should mark as stopped",
consoleView.getViewReference().getContentDescription().startsWith("<stopped>"));
assertFalse("Stop Server button should be disabled", stopServerButton.isEnabled());

// should also cause console to be discarded
launchTree.contextMenu("Remove All Terminated").click();
SwtBotTreeUtilities.waitUntilTreeHasNoItems(bot, launchTree);
assertThat("App Engine console should be removed",
assertThat(
"App Engine console should be removed",
consoleView.getViewReference().getContentDescription(),
Matchers.is("No consoles to display at this time."));
}

/**
* Check that there is no remote service for the URL.
*/
/** Check that there is no remote service for the URL. */
private void assertNoService(URL url) {
try {
getUrlContents(url, 10);
Expand Down Expand Up @@ -193,5 +206,4 @@ private static String getUrlContents(URL url, int timeoutInMilliseconds) throws
}
return content.toString().trim();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,18 @@

package com.google.cloud.tools.eclipse.swtbot;

import static org.junit.Assert.assertFalse;

import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
import org.eclipse.swtbot.swt.finder.results.Result;
import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
Expand All @@ -31,9 +38,7 @@
import org.hamcrest.Matchers;
import org.hamcrest.StringDescription;

/**
* Utilities for manipulating trees.
*/
/** Utilities for manipulating trees. */
public class SwtBotTreeUtilities {

/**
Expand All @@ -42,17 +47,18 @@ public class SwtBotTreeUtilities {
* @throws TimeoutException if no items appear within the default timeout
*/
public static SWTBotTreeItem waitUntilTreeHasItems(SWTWorkbenchBot bot, SWTBotTree tree) {
bot.waitUntil(new DefaultCondition() {
@Override
public String getFailureMessage() {
return "Tree items never appeared";
}
bot.waitUntil(
new DefaultCondition() {
@Override
public String getFailureMessage() {
return "Tree items never appeared";
}

@Override
public boolean test() throws Exception {
return tree.hasItems();
}
});
@Override
public boolean test() throws Exception {
return tree.hasItems();
}
});
return tree.getAllItems()[0];
}

Expand Down Expand Up @@ -122,21 +128,22 @@ public boolean test() throws Exception {

/**
* Wait until the given tree has not items.
*
*
* @throws TimeoutException if no items appear within the default timeout
*/
public static void waitUntilTreeHasNoItems(SWTWorkbenchBot bot, final SWTBotTree tree) {
bot.waitUntil(new DefaultCondition() {
@Override
public String getFailureMessage() {
return "Tree items never disappeared";
}
bot.waitUntil(
new DefaultCondition() {
@Override
public String getFailureMessage() {
return "Tree items never disappeared";
}

@Override
public boolean test() throws Exception {
return !tree.hasItems();
}
});
@Override
public boolean test() throws Exception {
return !tree.hasItems();
}
});
}

/**
Expand Down Expand Up @@ -227,4 +234,39 @@ public static SWTBotTreeItem select(SWTWorkbenchBot bot, SWTBotTree tree, String
}
return item.getNode(nodeNames[leafIndex]).select(); // throws WNFE
}

/** Expand the tree as necessary to find a child matching the given condition. */
public static boolean hasChild(SWTWorkbenchBot bot, SWTBotTree tree, Matcher<String> textMatcher) {
waitUntilTreeHasItems(bot, tree);
// perform breadth-first search; execute directly in SWT thread as the tree may otherwise
// be affected by thread changes
Result<Boolean> query =
() -> {
TreeItem[] items = tree.widget.getItems();
for (TreeItem item : items) {
if (textMatcher.matches(item.getText())) {
return true;
}
}
LinkedList<TreeItem> stack = new LinkedList<>();
Collections.addAll(stack, items);
while (!stack.isEmpty()) {
TreeItem parent = stack.removeFirst();
items = parent.getItems();
// If this assertion fails, it may be due to
// https://github.com/GoogleCloudPlatform/google-cloud-eclipse/issues/2569
// and may require applying the workaround to collapse and re-expand the node
assertFalse(
"workaround may be required", items.length == 1 && "".equals(items[0].getText()));
for (TreeItem item : items) {
if (textMatcher.matches(item.getText())) {
return true;
}
}
Collections.addAll(stack, items);
}
return false;
};
return UIThreadRunnable.syncExec(query);
}
}
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@
<configuration>
<runOrder>hourly</runOrder>
<forkedProcessTimeoutInSeconds>600</forkedProcessTimeoutInSeconds>
<trimStackTrace>false</trimStackTrace>
<!--
- maven.artifact.threads=1 to workaround repository corruption seen in
https://github.com/GoogleCloudPlatform/google-cloud-eclipse/issues/2284
Expand Down

0 comments on commit 4ec70c5

Please sign in to comment.