summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStas Negara <snegara@google.com>2015-05-01 15:57:10 -0700
committerStas Negara <snegara@google.com>2015-05-05 15:55:32 -0700
commitd15ea558d770bd733f2b9b8431199f5ef862bafa (patch)
tree3f9784cb071bd919aa9e8a2412c14b50cbd17ab2
parentbe9df783298c3d80fe31aaebe25f34862cc014d2 (diff)
downloadtesting-d15ea558d770bd733f2b9b8431199f5ef862bafa.tar.gz
Cancel cloud matrix tests if user terminates the execution.
Change-Id: I7952f93e033520fa701b197cd0dbd1aac9c2280c
-rw-r--r--src/com/google/gct/testing/CloudConfigurationProviderImpl.java32
-rw-r--r--src/com/google/gct/testing/CloudMatrixExecutionCancellator.java64
-rw-r--r--src/com/google/gct/testing/CloudResultsAdapter.java15
-rw-r--r--src/com/google/gct/testing/results/GoogleCloudTestResultsConnectionUtil.java43
4 files changed, 129 insertions, 25 deletions
diff --git a/src/com/google/gct/testing/CloudConfigurationProviderImpl.java b/src/com/google/gct/testing/CloudConfigurationProviderImpl.java
index 5b0f92d..c935e53 100644
--- a/src/com/google/gct/testing/CloudConfigurationProviderImpl.java
+++ b/src/com/google/gct/testing/CloudConfigurationProviderImpl.java
@@ -427,10 +427,10 @@ public class CloudConfigurationProviderImpl extends CloudConfigurationProvider {
lastCloudProjectId = cloudProjectId;
AndroidTestRunConfiguration testRunConfiguration = (AndroidTestRunConfiguration) runningState.getConfiguration();
- AndroidTestConsoleProperties properties =
- new AndroidTestConsoleProperties(testRunConfiguration, executor);
- ConsoleView console = GoogleCloudTestResultsConnectionUtil
- .createAndAttachConsole("Cloud Testing", runningState.getProcessHandler(), properties, runningState.getEnvironment());
+ AndroidTestConsoleProperties properties = new AndroidTestConsoleProperties(testRunConfiguration, executor);
+ CloudMatrixExecutionCancellator matrixExecutionCancellator = new CloudMatrixExecutionCancellator();
+ ConsoleView console = GoogleCloudTestResultsConnectionUtil.createAndAttachConsole(
+ "Cloud Testing", runningState.getProcessHandler(), properties, runningState.getEnvironment(), matrixExecutionCancellator);
Disposer.register(project, console);
GoogleCloudTestingResultParser
@@ -444,13 +444,13 @@ public class CloudConfigurationProviderImpl extends CloudConfigurationProvider {
GoogleCloudTestingDeveloperConfigurable.GoogleCloudTestingDeveloperState googleCloudTestingDeveloperState =
GoogleCloudTestingDeveloperSettings.getInstance(project).getState();
if (!googleCloudTestingDeveloperState.shouldUseFakeBucket) {
- performTestsInCloud(cloudConfiguration, cloudProjectId, runningState, cloudResultParser);
+ performTestsInCloud(cloudConfiguration, cloudProjectId, runningState, cloudResultParser, matrixExecutionCancellator);
}
else {
String testRunId = TEST_RUN_ID_PREFIX + googleCloudTestingDeveloperState.fakeBucketName + System.currentTimeMillis();
CloudResultsAdapter cloudResultsAdapter =
new CloudResultsAdapter(cloudProjectId, googleCloudTestingDeveloperState.fakeBucketName, cloudResultParser,
- expectedConfigurationInstances, testRunId, null);
+ expectedConfigurationInstances, testRunId, null, null);
addCloudConfiguration(testRunId, cloudConfiguration);
addCloudResultsAdapter(testRunId, cloudResultsAdapter);
cloudResultsAdapter.startPolling();
@@ -459,7 +459,8 @@ public class CloudConfigurationProviderImpl extends CloudConfigurationProvider {
}
private void performTestsInCloud(final CloudConfigurationImpl cloudTestingConfiguration, final String cloudProjectId,
- final AndroidRunningState runningState, final GoogleCloudTestingResultParser cloudResultParser) {
+ final AndroidRunningState runningState, final GoogleCloudTestingResultParser cloudResultParser,
+ final CloudMatrixExecutionCancellator matrixExecutionCancellator) {
if (cloudTestingConfiguration != null && cloudTestingConfiguration.getDeviceConfigurationCount() > 0) {
final List<String> expectedConfigurationInstances =
cloudTestingConfiguration.computeConfigurationInstances(ConfigurationInstance.DISPLAY_NAME_DELIMITER);
@@ -472,10 +473,16 @@ public class CloudConfigurationProviderImpl extends CloudConfigurationProvider {
String appPackage = runningState.getFacet().getAndroidModuleInfo().getPackage();
String testPackage = appPackage + ".test";
+ if (matrixExecutionCancellator.isCancelled()) {
+ return;
+ }
runningState.getProcessHandler().notifyTextAvailable(
prepareProgressString("Creating Cloud Storage bucket " + bucketName + "...", ""), ProcessOutputTypes.STDOUT);
CloudTestsLauncher.createBucket(cloudProjectId, bucketName);
+ if (matrixExecutionCancellator.isCancelled()) {
+ return;
+ }
List<String> apkPaths = getApkPaths(runningState);
runningState.getProcessHandler().notifyTextAvailable(prepareProgressString("Uploading app APK...", ""),
ProcessOutputTypes.STDOUT);
@@ -488,6 +495,9 @@ public class CloudConfigurationProviderImpl extends CloudConfigurationProvider {
}
String appApkName = CloudTestsLauncher.uploadFile(bucketName, appApk).getName();
+ if (matrixExecutionCancellator.isCancelled()) {
+ return;
+ }
runningState.getProcessHandler().notifyTextAvailable(prepareProgressString("Uploading test APK...", ""),
ProcessOutputTypes.STDOUT);
File testApk = findAppropriateApk(apkPaths, true);
@@ -499,6 +509,9 @@ public class CloudConfigurationProviderImpl extends CloudConfigurationProvider {
}
String testApkName = CloudTestsLauncher.uploadFile(bucketName, testApk).getName();
+ if (matrixExecutionCancellator.isCancelled()) {
+ return;
+ }
runningState.getProcessHandler().notifyTextAvailable(prepareProgressString("Invoking cloud test API...", "\n"),
ProcessOutputTypes.STDOUT);
String testSpecification = CloudTestingUtils.prepareTestSpecification(testRunConfiguration);
@@ -509,9 +522,12 @@ public class CloudConfigurationProviderImpl extends CloudConfigurationProvider {
cloudTestingConfiguration, appPackage, testPackage);
if (testMatrix != null) {
+ matrixExecutionCancellator.setCloudProjectId(cloudProjectId);
+ matrixExecutionCancellator.setTestMatrixId(testMatrix.getTestMatrixId());
String testRunId = TEST_RUN_ID_PREFIX + bucketName;
CloudResultsAdapter cloudResultsAdapter =
- new CloudResultsAdapter(cloudProjectId, bucketName, cloudResultParser, expectedConfigurationInstances, testRunId, testMatrix);
+ new CloudResultsAdapter(cloudProjectId, bucketName, cloudResultParser, expectedConfigurationInstances, testRunId, testMatrix,
+ matrixExecutionCancellator);
addCloudConfiguration(testRunId, cloudTestingConfiguration);
addCloudResultsAdapter(testRunId, cloudResultsAdapter);
cloudResultsAdapter.startPolling();
diff --git a/src/com/google/gct/testing/CloudMatrixExecutionCancellator.java b/src/com/google/gct/testing/CloudMatrixExecutionCancellator.java
new file mode 100644
index 0000000..c59bfcc
--- /dev/null
+++ b/src/com/google/gct/testing/CloudMatrixExecutionCancellator.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.gct.testing;
+
+import java.io.IOException;
+
+import static com.google.gct.testing.launcher.CloudAuthenticator.getTest;
+
+public class CloudMatrixExecutionCancellator {
+
+ private volatile boolean isCancelled = false;
+ private volatile String cloudProjectId = null;
+ private volatile String testMatrixId = null;
+
+
+ public synchronized void cancel() {
+ if (isCancelled) {
+ return;
+ }
+
+ if (cloudProjectId != null && testMatrixId != null) {
+ try {
+ doCancel();
+ } catch (Exception e1) {
+ // Retry
+ try {
+ doCancel();
+ } catch (Exception e2) {
+ // Give up
+ }
+ }
+ }
+ isCancelled = true;
+ }
+
+ private void doCancel() throws IOException {
+ getTest().projects().testMatrices().cancel(cloudProjectId, testMatrixId);
+ }
+
+ public synchronized boolean isCancelled() {
+ return isCancelled;
+ }
+
+ public synchronized void setCloudProjectId(String cloudProjectId) {
+ this.cloudProjectId = cloudProjectId;
+ }
+
+ public synchronized void setTestMatrixId(String testMatrixId) {
+ this.testMatrixId = testMatrixId;
+ }
+}
diff --git a/src/com/google/gct/testing/CloudResultsAdapter.java b/src/com/google/gct/testing/CloudResultsAdapter.java
index 8b804fd..99b27c3 100644
--- a/src/com/google/gct/testing/CloudResultsAdapter.java
+++ b/src/com/google/gct/testing/CloudResultsAdapter.java
@@ -20,6 +20,7 @@ import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.gct.testing.results.GoogleCloudTestingResultParser;
+import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -39,15 +40,17 @@ public class CloudResultsAdapter {
private final Set<ConfigurationResult> markedAsPendingConfigurations = new HashSet<ConfigurationResult>();
// The set of configurations that were marked as finished in the test results tree.
private final Set<ConfigurationResult> markedAsFinishedConfigurations = new HashSet<ConfigurationResult>();
- private final PollingTicker pollingTicker = new PollingTicker();
+ private final PollingTicker pollingTicker;
public CloudResultsAdapter(String cloudProjectId, String bucketName, GoogleCloudTestingResultParser resultParser,
- List<String> expectedConfigurationInstances, String testRunId, TestMatrix testMatrix) {
+ List<String> expectedConfigurationInstances, String testRunId, @Nullable TestMatrix testMatrix,
+ @Nullable CloudMatrixExecutionCancellator matrixExecutionCancellator) {
this.cloudProjectId = cloudProjectId;
loader = new CloudResultsLoader(cloudProjectId, resultParser.getTestRunListener(), bucketName, testMatrix);
this.resultParser = resultParser;
this.expectedConfigurationInstances = expectedConfigurationInstances;
+ pollingTicker = new PollingTicker(matrixExecutionCancellator);
// Update the tree's root node with the index of the adapter that communicates with the tree through this parser.
resultParser.getTestRunListener().setTestRunId(testRunId);
}
@@ -153,6 +156,11 @@ public class CloudResultsAdapter {
private static final int POLLING_INTERVAL = 3 * 1000; // 3 seconds
private long stopTime;
+ private final CloudMatrixExecutionCancellator matrixExecutionCancellator;
+
+ public PollingTicker(@Nullable CloudMatrixExecutionCancellator matrixExecutionCancellator) {
+ this.matrixExecutionCancellator = matrixExecutionCancellator;
+ }
public void resetTimeout() {
long newStopTime = System.currentTimeMillis() + DYNAMIC_TIMEOUT;
@@ -166,6 +174,9 @@ public class CloudResultsAdapter {
boolean allResultsArrived = false;
stopTime = System.currentTimeMillis() + INITIAL_TIMEOUT;
while (System.currentTimeMillis() < stopTime) {
+ if (matrixExecutionCancellator != null && matrixExecutionCancellator.isCancelled()) {
+ break;
+ }
allResultsArrived = poll();
if (allResultsArrived) {
break;
diff --git a/src/com/google/gct/testing/results/GoogleCloudTestResultsConnectionUtil.java b/src/com/google/gct/testing/results/GoogleCloudTestResultsConnectionUtil.java
index 495b207..7924a46 100644
--- a/src/com/google/gct/testing/results/GoogleCloudTestResultsConnectionUtil.java
+++ b/src/com/google/gct/testing/results/GoogleCloudTestResultsConnectionUtil.java
@@ -15,6 +15,7 @@
*/
package com.google.gct.testing.results;
+import com.google.gct.testing.CloudMatrixExecutionCancellator;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.CommandLineState;
@@ -67,9 +68,10 @@ public class GoogleCloudTestResultsConnectionUtil {
public static BaseTestsOutputConsoleView createAndAttachConsole(@NotNull final String testFrameworkName,
@NotNull final ProcessHandler processHandler,
@NotNull final TestConsoleProperties consoleProperties,
- ExecutionEnvironment environment
+ ExecutionEnvironment environment,
+ @NotNull final CloudMatrixExecutionCancellator matrixExecutionCancellator
) throws ExecutionException {
- BaseTestsOutputConsoleView console = createConsole(testFrameworkName, consoleProperties, environment);
+ BaseTestsOutputConsoleView console = createConsole(testFrameworkName, consoleProperties, environment, matrixExecutionCancellator);
console.attachToProcess(processHandler);
return console;
}
@@ -77,13 +79,15 @@ public class GoogleCloudTestResultsConnectionUtil {
public static BaseTestsOutputConsoleView createConsoleWithCustomLocator(@NotNull final String testFrameworkName,
@NotNull final TestConsoleProperties consoleProperties,
ExecutionEnvironment environment,
- @Nullable final TestLocationProvider locator) {
+ @Nullable final TestLocationProvider locator,
+ @NotNull final CloudMatrixExecutionCancellator matrixExecutionCancellator) {
return createConsoleWithCustomLocator(testFrameworkName,
consoleProperties,
environment,
new CompositeTestLocationProvider(locator),
false,
- null);
+ null,
+ matrixExecutionCancellator);
}
public static GoogleCloudTestingConsoleView createConsoleWithCustomLocator(@NotNull final String testFrameworkName,
@@ -91,12 +95,13 @@ public class GoogleCloudTestResultsConnectionUtil {
ExecutionEnvironment environment,
@Nullable final TestLocationProvider locator,
final boolean idBasedTreeConstruction,
- @Nullable final TestProxyFilterProvider filterProvider) {
+ @Nullable final TestProxyFilterProvider filterProvider,
+ @NotNull final CloudMatrixExecutionCancellator matrixExecutionCancellator) {
String splitterPropertyName = getSplitterPropertyName(testFrameworkName);
GoogleCloudTestingConsoleView consoleView = new GoogleCloudTestingConsoleView(consoleProperties,
environment,
splitterPropertyName);
- initConsoleView(consoleView, testFrameworkName, locator, idBasedTreeConstruction, filterProvider);
+ initConsoleView(consoleView, testFrameworkName, locator, idBasedTreeConstruction, filterProvider, matrixExecutionCancellator);
return consoleView;
}
@@ -109,7 +114,8 @@ public class GoogleCloudTestResultsConnectionUtil {
@NotNull final String testFrameworkName,
@Nullable final TestLocationProvider locator,
final boolean idBasedTreeConstruction,
- @Nullable final TestProxyFilterProvider filterProvider) {
+ @Nullable final TestProxyFilterProvider filterProvider,
+ @NotNull final CloudMatrixExecutionCancellator matrixExecutionCancellator) {
consoleView.addAttachToProcessListener(new AttachToProcessListener() {
@Override
public void onAttachToProcess(@NotNull ProcessHandler processHandler) {
@@ -125,7 +131,8 @@ public class GoogleCloudTestResultsConnectionUtil {
testFrameworkName,
locator,
idBasedTreeConstruction,
- printerProvider);
+ printerProvider,
+ matrixExecutionCancellator);
}
});
consoleView.setHelpId("reference.runToolWindow.testResultsTab");
@@ -134,9 +141,10 @@ public class GoogleCloudTestResultsConnectionUtil {
public static BaseTestsOutputConsoleView createConsole(@NotNull final String testFrameworkName,
@NotNull final TestConsoleProperties consoleProperties,
- ExecutionEnvironment environment) {
+ ExecutionEnvironment environment,
+ @NotNull final CloudMatrixExecutionCancellator matrixExecutionCancellator) {
- return createConsoleWithCustomLocator(testFrameworkName, consoleProperties, environment, null);
+ return createConsoleWithCustomLocator(testFrameworkName, consoleProperties, environment, null, matrixExecutionCancellator);
}
/**
@@ -188,26 +196,29 @@ public class GoogleCloudTestResultsConnectionUtil {
public static ConsoleView createAndAttachConsole(@NotNull final String testFrameworkName, @NotNull final ProcessHandler processHandler,
@NotNull final CommandLineState commandLineState,
@NotNull final ModuleRunConfiguration config,
- @NotNull final Executor executor
+ @NotNull final Executor executor,
+ @NotNull final CloudMatrixExecutionCancellator matrixExecutionCancellator
) throws ExecutionException {
// final String testFrameworkName
final TestConsoleProperties consoleProperties = new SMTRunnerConsoleProperties(config, testFrameworkName, executor);
return createAndAttachConsole(testFrameworkName, processHandler, consoleProperties,
- commandLineState.getEnvironment());
+ commandLineState.getEnvironment(), matrixExecutionCancellator);
}
public static ConsoleView createConsole(@NotNull final String testFrameworkName,
@NotNull final CommandLineState commandLineState,
@NotNull final ModuleRunConfiguration config,
- @NotNull final Executor executor
+ @NotNull final Executor executor,
+ @NotNull final CloudMatrixExecutionCancellator matrixExecutionCancellator
) throws ExecutionException {
// final String testFrameworkName
final TestConsoleProperties consoleProperties = new SMTRunnerConsoleProperties(config, testFrameworkName, executor);
return createConsole(testFrameworkName,
consoleProperties,
- commandLineState.getEnvironment());
+ commandLineState.getEnvironment(),
+ matrixExecutionCancellator);
}
/**
@@ -227,7 +238,8 @@ public class GoogleCloudTestResultsConnectionUtil {
@NotNull final String testFrameworkName,
@Nullable final TestLocationProvider locator,
boolean idBasedTreeConstruction,
- @Nullable TestProxyPrinterProvider printerProvider) {
+ @Nullable TestProxyPrinterProvider printerProvider,
+ @NotNull final CloudMatrixExecutionCancellator matrixExecutionCancellator) {
//build messages consumer
final OutputToGoogleCloudTestEventsConverter
outputConsumer = new OutputToGoogleCloudTestEventsConverter(testFrameworkName, consoleProperties);
@@ -268,6 +280,7 @@ public class GoogleCloudTestResultsConnectionUtil {
processHandler.addProcessListener(new ProcessAdapter() {
@Override
public void processTerminated(final ProcessEvent event) {
+ matrixExecutionCancellator.cancel();
outputConsumer.flushBufferBeforeTerminating();
eventsProcessor.onFinishTesting();