diff options
author | Stas Negara <snegara@google.com> | 2015-04-15 17:15:33 -0700 |
---|---|---|
committer | Stas Negara <snegara@google.com> | 2015-04-16 12:23:49 -0700 |
commit | fb062d8a16fc1e8c0b337f71d3e9d9df135ae569 (patch) | |
tree | 687f48286efeead94474eed028d2217d8beee374 | |
parent | 8014a94e7c15d56d6cbbb023b7b04712d6118ad3 (diff) | |
download | testing-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.java | 51 | ||||
-rw-r--r-- | src/com/google/gct/testing/ui/GhostCloudDevice.java | 353 |
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; + } +} |