summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStas Negara <snegara@google.com>2015-04-15 17:15:33 -0700
committerStas Negara <snegara@google.com>2015-04-16 12:23:49 -0700
commitfb062d8a16fc1e8c0b337f71d3e9d9df135ae569 (patch)
tree687f48286efeead94474eed028d2217d8beee374
parent8014a94e7c15d56d6cbbb023b7b04712d6118ad3 (diff)
downloadtesting-fb062d8a16fc1e8c0b337f71d3e9d9df135ae569.tar.gz
Keep track of launching cloud devices for devices table.studio-master-release
Change-Id: I3b5ac07d76877eba85960fe3922c443a91ad27c5
-rw-r--r--src/com/google/gct/testing/CloudConfigurationProviderImpl.java51
-rw-r--r--src/com/google/gct/testing/ui/GhostCloudDevice.java353
2 files changed, 392 insertions, 12 deletions
diff --git a/src/com/google/gct/testing/CloudConfigurationProviderImpl.java b/src/com/google/gct/testing/CloudConfigurationProviderImpl.java
index e71b84e..02dc01d 100644
--- a/src/com/google/gct/testing/CloudConfigurationProviderImpl.java
+++ b/src/com/google/gct/testing/CloudConfigurationProviderImpl.java
@@ -15,10 +15,12 @@
*/
package com.google.gct.testing;
+import com.android.ddmlib.IDevice;
import com.android.tools.idea.run.CloudConfiguration;
import com.android.tools.idea.run.CloudConfiguration.Kind;
import com.android.tools.idea.run.CloudConfigurationProvider;
import com.android.tools.idea.sdk.IdeSdks;
+import com.google.api.client.util.Sets;
import com.google.api.services.storage.Storage;
import com.google.api.services.storage.model.Buckets;
import com.google.api.services.testing.model.AndroidDevice;
@@ -37,6 +39,7 @@ import com.google.gct.testing.launcher.CloudTestsLauncher;
import com.google.gct.testing.results.GoogleCloudTestListener;
import com.google.gct.testing.results.GoogleCloudTestResultsConnectionUtil;
import com.google.gct.testing.results.GoogleCloudTestingResultParser;
+import com.google.gct.testing.ui.GhostCloudDevice;
import com.intellij.execution.DefaultExecutionResult;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionResult;
@@ -89,6 +92,9 @@ public class CloudConfigurationProviderImpl extends CloudConfigurationProvider {
}
};
+
+ private final Set<GhostCloudDevice> ghostCloudDevices = Sets.newHashSet();
+
public static Map<String, List<? extends CloudTestingType>> getAllDimensionTypes() {
Map<String, List<? extends CloudTestingType>> dimensionTypes = new HashMap<String, List<? extends CloudTestingType>>();
dimensionTypes.put(DeviceDimension.DISPLAY_NAME, DeviceDimension.getFullDomain());
@@ -280,37 +286,58 @@ public class CloudConfigurationProviderImpl extends CloudConfigurationProvider {
"The returned cloud device is null\n\n");
}
+ GhostCloudDevice ghostCloudDevice = new GhostCloudDevice(createdDevice);
+ synchronized (ghostCloudDevices) {
+ ghostCloudDevices.add(ghostCloudDevice);
+ }
final long POLLING_INTERVAL = 10 * 1000; // 10 seconds
final long INITIAL_TIMEOUT = 10 * 60 * 1000; // 10 minutes
long stopTime = System.currentTimeMillis() + INITIAL_TIMEOUT;
String sdkPath = IdeSdks.getAndroidSdkPath().getAbsolutePath() + "/platform-tools";
File dir = new File(sdkPath);
- while (System.currentTimeMillis() < stopTime) {
- try {
+ try {
+ while (System.currentTimeMillis() < stopTime) {
createdDevice = getTest().projects().devices().get(cloudProjectId, createdDevice.getId()).execute();
System.out.println("Polling for device... (time: " + System.currentTimeMillis() + ", status: " + createdDevice.getState() + ")");
if (createdDevice.getState().equals("READY")) {
- //if (createdDevice.getDeviceDetails().getConnectionInfo() != null) {
+ //if (createdDevice.getDeviceDetails().getConnectionInfo() != null) {
String ipAddress = createdDevice.getDeviceDetails().getConnectionInfo().getIpAddress();
Integer adbPort = createdDevice.getDeviceDetails().getConnectionInfo().getAdbPort();
System.out.println("Device ready with IP address:port " + ipAddress + ":" + adbPort);
Runtime rt = Runtime.getRuntime();
- //Process startServer = rt.exec("./adb start-server", null, dir);
- //startServer.waitFor();
Process connect = rt.exec("./adb connect " + ipAddress + ":" + adbPort, null, dir);
connect.waitFor();
+ // Do not wait for "finally" to remove the ghost device
+ // to minimize the time both a ghost device and an actual cloud device are present in the devices table.
+ synchronized (ghostCloudDevices) {
+ ghostCloudDevices.remove(ghostCloudDevice);
+ }
return;
}
Thread.sleep(POLLING_INTERVAL);
- } catch (IOException e) {
- showCloudDevicePollingError(e, createdDevice.getId());
- } catch (InterruptedException e) {
- showCloudDevicePollingError(e, createdDevice.getId());
}
+ CloudTestingUtils.showErrorMessage(null, "Timed out connecting to a cloud device", "Timed out connecting to a cloud device!\n" +
+ "Timed out connecting to a cloud device:\n\n" +
+ createdDevice.getId());
+ } catch (IOException e) {
+ showCloudDevicePollingError(e, createdDevice.getId());
+ } catch (InterruptedException e) {
+ showCloudDevicePollingError(e, createdDevice.getId());
+ } finally {
+ synchronized (ghostCloudDevices) {
+ ghostCloudDevices.remove(ghostCloudDevice);
+ }
+ }
+ }
+
+ @NotNull
+ @Override
+ public Collection<IDevice> getLaunchingCloudDevices() {
+ synchronized (ghostCloudDevices) {
+ HashSet<IDevice> launchingCloudDevices = Sets.newHashSet();
+ launchingCloudDevices.addAll(ghostCloudDevices);
+ return launchingCloudDevices;
}
- CloudTestingUtils.showErrorMessage(null, "Timed out connecting to a cloud device", "Timed out connecting to a cloud device!\n" +
- "Timed out connecting to a cloud device:\n\n" +
- createdDevice.getId());
}
private void showCloudDevicePollingError(Exception e, String deviceId) {
diff --git a/src/com/google/gct/testing/ui/GhostCloudDevice.java b/src/com/google/gct/testing/ui/GhostCloudDevice.java
new file mode 100644
index 0000000..5f2c81d
--- /dev/null
+++ b/src/com/google/gct/testing/ui/GhostCloudDevice.java
@@ -0,0 +1,353 @@
+/*
+ * 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.ui;
+
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
+import com.android.ddmlib.*;
+import com.android.ddmlib.log.LogReceiver;
+import com.google.api.services.testing.model.AndroidDevice;
+import com.google.api.services.testing.model.Device;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+public class GhostCloudDevice implements IDevice {
+
+ private final Device device;
+
+
+ public GhostCloudDevice(Device device) {
+ this.device = device;
+ }
+
+ @NonNull
+ @Override
+ public String getSerialNumber() {
+ AndroidDevice androidDevice = device.getAndroidDevice();
+ return (androidDevice.getAndroidModelId() + "-" + androidDevice.getAndroidVersionId() + "-" +
+ androidDevice.getLocale() + "-" + androidDevice.getOrientation()).toLowerCase();
+ }
+
+ @Nullable
+ @Override
+ public String getAvdName() {
+ return null;
+ }
+
+ @Override
+ public DeviceState getState() {
+ return DeviceState.OFFLINE;
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return null;
+ }
+
+ @Override
+ public int getPropertyCount() {
+ return 0;
+ }
+
+ @Nullable
+ @Override
+ public String getProperty(@NonNull String name) {
+ if (name.equals(IDevice.PROP_BUILD_API_LEVEL)) {
+ return device.getAndroidDevice().getAndroidVersionId();
+ }
+ return null;
+ }
+
+ @Override
+ public boolean arePropertiesSet() {
+ return false;
+ }
+
+ @Override
+ public String getPropertySync(String name)
+ throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException, IOException {
+ return null;
+ }
+
+ @Override
+ public String getPropertyCacheOrSync(String name)
+ throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException, IOException {
+ return null;
+ }
+
+ @Override
+ public boolean supportsFeature(@NonNull Feature feature) {
+ return true;
+ }
+
+ @Override
+ public boolean supportsFeature(@NonNull HardwareFeature feature) {
+ if (feature != IDevice.HardwareFeature.WATCH) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public String getMountPoint(String name) {
+ return null;
+ }
+
+ @Override
+ public boolean isOnline() {
+ return false;
+ }
+
+ @Override
+ public boolean isEmulator() {
+ return false;
+ }
+
+ @Override
+ public boolean isOffline() {
+ return true;
+ }
+
+ @Override
+ public boolean isBootLoader() {
+ return false;
+ }
+
+ @Override
+ public boolean hasClients() {
+ return false;
+ }
+
+ @Override
+ public Client[] getClients() {
+ return new Client[0];
+ }
+
+ @Override
+ public Client getClient(String applicationName) {
+ return null;
+ }
+
+ @Override
+ public SyncService getSyncService() throws TimeoutException, AdbCommandRejectedException, IOException {
+ return null;
+ }
+
+ @Override
+ public FileListingService getFileListingService() {
+ return null;
+ }
+
+ @Override
+ public RawImage getScreenshot() throws TimeoutException, AdbCommandRejectedException, IOException {
+ return null;
+ }
+
+ @Override
+ public RawImage getScreenshot(long timeout, TimeUnit unit) throws TimeoutException, AdbCommandRejectedException, IOException {
+ return null;
+ }
+
+ @Override
+ public void startScreenRecorder(@NonNull String remoteFilePath,
+ @NonNull ScreenRecorderOptions options,
+ @NonNull IShellOutputReceiver receiver)
+ throws TimeoutException, AdbCommandRejectedException, IOException, ShellCommandUnresponsiveException {
+
+ }
+
+ @Override
+ public void executeShellCommand(String command, IShellOutputReceiver receiver, int maxTimeToOutputResponse)
+ throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException, IOException {
+
+ }
+
+ @Override
+ public void executeShellCommand(String command, IShellOutputReceiver receiver)
+ throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException, IOException {
+
+ }
+
+ @Override
+ public void runEventLogService(LogReceiver receiver) throws TimeoutException, AdbCommandRejectedException, IOException {
+
+ }
+
+ @Override
+ public void runLogService(String logname, LogReceiver receiver) throws TimeoutException, AdbCommandRejectedException, IOException {
+
+ }
+
+ @Override
+ public void createForward(int localPort, int remotePort) throws TimeoutException, AdbCommandRejectedException, IOException {
+
+ }
+
+ @Override
+ public void createForward(int localPort, String remoteSocketName, DeviceUnixSocketNamespace namespace)
+ throws TimeoutException, AdbCommandRejectedException, IOException {
+
+ }
+
+ @Override
+ public void removeForward(int localPort, int remotePort) throws TimeoutException, AdbCommandRejectedException, IOException {
+
+ }
+
+ @Override
+ public void removeForward(int localPort, String remoteSocketName, DeviceUnixSocketNamespace namespace)
+ throws TimeoutException, AdbCommandRejectedException, IOException {
+
+ }
+
+ @Override
+ public String getClientName(int pid) {
+ return null;
+ }
+
+ @Override
+ public void pushFile(String local, String remote) throws IOException, AdbCommandRejectedException, TimeoutException, SyncException {
+
+ }
+
+ @Override
+ public void pullFile(String remote, String local) throws IOException, AdbCommandRejectedException, TimeoutException, SyncException {
+
+ }
+
+ @Override
+ public String installPackage(String packageFilePath, boolean reinstall, String... extraArgs) throws InstallException {
+ return null;
+ }
+
+ @Override
+ public void installPackages(List<String> apkFilePaths, int timeOutInMs, boolean reinstall, String... extraArgs) throws InstallException {
+
+ }
+
+ @Override
+ public String syncPackageToDevice(String localFilePath) throws TimeoutException, AdbCommandRejectedException, IOException, SyncException {
+ return null;
+ }
+
+ @Override
+ public String installRemotePackage(String remoteFilePath, boolean reinstall, String... extraArgs) throws InstallException {
+ return null;
+ }
+
+ @Override
+ public void removeRemotePackage(String remoteFilePath) throws InstallException {
+
+ }
+
+ @Override
+ public String uninstallPackage(String packageName) throws InstallException {
+ return null;
+ }
+
+ @Override
+ public void reboot(String into) throws TimeoutException, AdbCommandRejectedException, IOException {
+
+ }
+
+ @Override
+ public Integer getBatteryLevel() throws TimeoutException, AdbCommandRejectedException, IOException, ShellCommandUnresponsiveException {
+ return null;
+ }
+
+ @Override
+ public Integer getBatteryLevel(long freshnessMs)
+ throws TimeoutException, AdbCommandRejectedException, IOException, ShellCommandUnresponsiveException {
+ return null;
+ }
+
+ @NonNull
+ @Override
+ public Future<Integer> getBattery() {
+ return null;
+ }
+
+ @NonNull
+ @Override
+ public Future<Integer> getBattery(long freshnessTime, @NonNull TimeUnit timeUnit) {
+ return null;
+ }
+
+ @NonNull
+ @Override
+ public List<String> getAbis() {
+ return null;
+ }
+
+ @Override
+ public int getDensity() {
+ return 0;
+ }
+
+ @Override
+ public String getLanguage() {
+ return null;
+ }
+
+ @Override
+ public String getRegion() {
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ return "Cloud device: " + device.getId();
+ }
+
+ @Override
+ public void executeShellCommand(String command, IShellOutputReceiver receiver, long maxTimeToOutputResponse, TimeUnit maxTimeUnits)
+ throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException, IOException {
+
+ }
+
+ @NonNull
+ @Override
+ public Future<String> getSystemProperty(@NonNull String name) {
+ return null;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ GhostCloudDevice that = (GhostCloudDevice)o;
+
+ if (device == null) {
+ return that.device == null;
+ }
+
+ if (that.device == null) {
+ return false;
+ }
+
+ return device.getId().equals(that.device.getId());
+ }
+
+ @Override
+ public int hashCode() {
+ return device != null ? device.getId().hashCode() : 0;
+ }
+}