diff options
author | Hongguang Chen <hgchen@google.com> | 2020-08-31 01:22:12 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-08-31 01:22:12 +0000 |
commit | a19f55ed67fe37805e86dcaedf66284ad11867a7 (patch) | |
tree | 2135c292472a4f7a2083e03d490b598dd0bef0f3 | |
parent | 141506868ab1ce9ef4e62e0f459598e11b7ebe10 (diff) | |
parent | 2ec2b8e9b1c6fad3b9fc1facba2d266ec8222f5e (diff) | |
download | tradefederation-a19f55ed67fe37805e86dcaedf66284ad11867a7.tar.gz |
Allow IPv6 link-local address to be fastboot serial number. am: 2ec2b8e9b1
Original change: https://googleplex-android-review.googlesource.com/c/platform/tools/tradefederation/+/12335092
Change-Id: If21c146bd4add1a602c459a7065839bbe0ecebcf
14 files changed, 455 insertions, 10 deletions
diff --git a/device_build_interfaces/com/android/tradefed/device/IDeviceStateMonitor.java b/device_build_interfaces/com/android/tradefed/device/IDeviceStateMonitor.java index 0e6c86ed2..8f432fcb6 100644 --- a/device_build_interfaces/com/android/tradefed/device/IDeviceStateMonitor.java +++ b/device_build_interfaces/com/android/tradefed/device/IDeviceStateMonitor.java @@ -196,4 +196,9 @@ public interface IDeviceStateMonitor { */ public void setDefaultAvailableTimeout(long timeoutMs); + /** Sets the fastboot mode serial number. */ + public void setFastbootSerialNumber(String serial); + + /** Gets the fastboot mode serial number. */ + public String getFastbootSerialNumber(); } diff --git a/device_build_interfaces/com/android/tradefed/device/INativeDevice.java b/device_build_interfaces/com/android/tradefed/device/INativeDevice.java index 3ceb9448f..b3fdbbb79 100644 --- a/device_build_interfaces/com/android/tradefed/device/INativeDevice.java +++ b/device_build_interfaces/com/android/tradefed/device/INativeDevice.java @@ -82,6 +82,9 @@ public interface INativeDevice { */ public String getSerialNumber(); + /** Returns the fastboot mode serial number. */ + public String getFastbootSerialNumber(); + /** * Retrieve the given property value from the device. * diff --git a/global_configuration/com/android/tradefed/host/HostOptions.java b/global_configuration/com/android/tradefed/host/HostOptions.java index 68aa51f08..f280130d4 100644 --- a/global_configuration/com/android/tradefed/host/HostOptions.java +++ b/global_configuration/com/android/tradefed/host/HostOptions.java @@ -19,9 +19,14 @@ package com.android.tradefed.host; import com.android.tradefed.config.ConfigurationException; import com.android.tradefed.config.Option; import com.android.tradefed.config.OptionClass; +import com.android.tradefed.log.LogUtil.CLog; import java.io.File; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; import java.util.ArrayList; +import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -96,6 +101,11 @@ public class HostOptions implements IHostOptions { description = "Whether to use zip64 format in partial download.") private boolean mUseZip64InPartialDownload = false; + @Option( + name = "use-network-interface", + description = "The network interface used to connect to test devices.") + private String mNetworkInterface = null; + /** {@inheritDoc} */ @Override public Integer getConcurrentFlasherLimit() { @@ -167,4 +177,37 @@ public class HostOptions implements IHostOptions { public boolean getUseZip64InPartialDownload() { return mUseZip64InPartialDownload; } + + /** {@inheritDoc} */ + @Override + public String getNetworkInterface() { + if (mNetworkInterface != null) { + return mNetworkInterface; + } + + try { + for (Enumeration<NetworkInterface> enNetI = NetworkInterface.getNetworkInterfaces(); + enNetI.hasMoreElements(); ) { + NetworkInterface netI = enNetI.nextElement(); + if (!netI.isUp()) { + continue; + } + for (Enumeration<InetAddress> enumIpAddr = netI.getInetAddresses(); + enumIpAddr.hasMoreElements(); ) { + InetAddress inetAddress = enumIpAddr.nextElement(); + if (!inetAddress.isAnyLocalAddress() + && !inetAddress.isLinkLocalAddress() + && !inetAddress.isLoopbackAddress() + && !inetAddress.isMulticastAddress()) { + mNetworkInterface = netI.getName(); + return mNetworkInterface; + } + } + } + } catch (SocketException e) { + CLog.w("Failed to get host's active interface"); + CLog.w(e); + } + return null; + } } diff --git a/global_configuration/com/android/tradefed/host/IHostOptions.java b/global_configuration/com/android/tradefed/host/IHostOptions.java index 32b8a044d..342658795 100644 --- a/global_configuration/com/android/tradefed/host/IHostOptions.java +++ b/global_configuration/com/android/tradefed/host/IHostOptions.java @@ -73,4 +73,7 @@ public interface IHostOptions { /** Check if it should use the zip64 format in partial download or not. */ boolean getUseZip64InPartialDownload(); + + /** Returns the network interface used to connect to remote test devices. */ + String getNetworkInterface(); } diff --git a/src/com/android/tradefed/device/DeviceManager.java b/src/com/android/tradefed/device/DeviceManager.java index 669496072..c43fd75cc 100644 --- a/src/com/android/tradefed/device/DeviceManager.java +++ b/src/com/android/tradefed/device/DeviceManager.java @@ -195,6 +195,8 @@ public class DeviceManager implements IDeviceManager { /** Flag to remember if adb bridge has been disconnected and needs to be reset * */ private boolean mAdbBridgeNeedRestart = false; + private Map<String, String> mMonitoringTcpFastbootDevices = new HashMap<>(); + /** * The DeviceManager should be retrieved from the {@link GlobalConfiguration} */ @@ -1352,6 +1354,11 @@ public class DeviceManager implements IDeviceManager { final FastbootHelper fastboot = new FastbootHelper(getRunUtil(), getFastbootPath()); while (!mQuit) { Map<String, Boolean> serialAndMode = fastboot.getBootloaderAndFastbootdDevices(); + + serialAndMode.putAll( + fastboot.getBootloaderAndFastbootdTcpDevices( + mMonitoringTcpFastbootDevices)); + if (serialAndMode != null) { // Update known bootloader devices state Set<String> bootloader = new HashSet<>(); @@ -1591,4 +1598,10 @@ public class DeviceManager implements IDeviceManager { public String getAdbVersion() { return mAdbBridge.getAdbVersion(mAdbPath); } + + /** {@inheritDoc} */ + @Override + public void addMonitoringTcpFastbootDevice(String serial, String fastboot_serial) { + mMonitoringTcpFastbootDevices.put(serial, fastboot_serial); + } } diff --git a/src/com/android/tradefed/device/FastbootHelper.java b/src/com/android/tradefed/device/FastbootHelper.java index 276207521..fe251fd03 100644 --- a/src/com/android/tradefed/device/FastbootHelper.java +++ b/src/com/android/tradefed/device/FastbootHelper.java @@ -25,6 +25,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -125,6 +126,38 @@ public class FastbootHelper { } /** + * Returns a map of device serials and whether they are in fastbootd mode or not. + * + * @param serials a map of devices serial number and fastboot mode serial number. + * @return a Map of serial in bootloader or fastbootd, the boolean is true if in fastbootd + */ + public Map<String, Boolean> getBootloaderAndFastbootdTcpDevices(Map<String, String> serials) { + HashMap<String, Boolean> devices = new LinkedHashMap<>(); + long TIMEOUT = 1500; + + for (Entry<String, String> entry : serials.entrySet()) { + CLog.v("Run 'fastboot -s %s getvar is-userspace' command", entry.getValue()); + CommandResult fastbootResult = + mRunUtil.runTimedCmdSilently( + TIMEOUT, + mFastbootPath, + "-s", + entry.getValue(), + "getvar", + "is-userspace"); + if (fastbootResult.getStatus().equals(CommandStatus.SUCCESS)) { + if (fastbootResult.getStderr().contains("yes")) { + devices.put(entry.getKey(), true); + } else { + devices.put(entry.getKey(), false); + } + } + } + + return devices; + } + + /** * Parses the output of "fastboot devices" command. Exposed for unit testing. * * @param fastbootOutput the output of fastboot command. diff --git a/src/com/android/tradefed/device/IDeviceManager.java b/src/com/android/tradefed/device/IDeviceManager.java index c1c3ff153..d5bf57369 100644 --- a/src/com/android/tradefed/device/IDeviceManager.java +++ b/src/com/android/tradefed/device/IDeviceManager.java @@ -286,4 +286,13 @@ public interface IDeviceManager { /** Get the adb version currently in use by the device manager. */ public String getAdbVersion(); + + /** + * Add a device to fastboot monitor. The fastboot monitor will use 'fastboot_serial' to + * communicate with the device. + * + * @param serial the device's serial number. + * @param fastboot_serial the device's fastboot mode serial number. + */ + public void addMonitoringTcpFastbootDevice(String serial, String fastboot_serial); } diff --git a/src/com/android/tradefed/device/NativeDevice.java b/src/com/android/tradefed/device/NativeDevice.java index 2f90ad037..8c9616264 100644 --- a/src/com/android/tradefed/device/NativeDevice.java +++ b/src/com/android/tradefed/device/NativeDevice.java @@ -76,6 +76,8 @@ import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.io.OutputStream; +import java.net.Inet6Address; +import java.net.UnknownHostException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Clock; @@ -168,6 +170,9 @@ public class NativeDevice implements IManagedTestDevice { static final String MAC_ADDRESS_PATTERN = "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}"; static final String MAC_ADDRESS_COMMAND = "su root cat /sys/class/net/wlan0/address"; + static final String ETHERNET_MAC_ADDRESS_COMMAND = "cat /sys/class/net/eth0/address"; + + static final int ETHER_ADDR_LEN = 6; /** The network monitoring interval in ms. */ private static final int NETWORK_MONITOR_INTERVAL = 10 * 1000; @@ -225,6 +230,8 @@ public class NativeDevice implements IManagedTestDevice { private DeviceDescriptor mCachedDeviceDescriptor = null; private final Object mCacheLock = new Object(); + private String mFastbootSerialNumber = null; + /** * Interface for a generic device communication attempt. */ @@ -337,6 +344,11 @@ public class NativeDevice implements IManagedTestDevice { mReason = reason; } + public boolean isFastbootOrBootloader() { + return mRebootMode == RebootMode.REBOOT_INTO_BOOTLOADER + || mRebootMode == RebootMode.REBOOT_INTO_FASTBOOTD; + } + @Override public boolean run() throws TimeoutException, IOException, AdbCommandRejectedException { getIDevice().reboot(mRebootMode.formatRebootCommand(mReason)); @@ -2050,8 +2062,8 @@ public class NativeDevice implements IManagedTestDevice { * Builds the OS command for the given fastboot command and args */ private String[] buildFastbootCommand(String... commandArgs) { - return ArrayUtil.buildArray(new String[] {getFastbootPath(), "-s", getSerialNumber()}, - commandArgs); + return ArrayUtil.buildArray( + new String[] {getFastbootPath(), "-s", getFastbootSerialNumber()}, commandArgs); } /** @@ -2089,6 +2101,15 @@ public class NativeDevice implements IManagedTestDevice { return false; } } catch (AdbCommandRejectedException e) { + // Workaround to not recover device if TCP adb is used. + if (isAdbTcp() + && (action instanceof RebootDeviceAction) + && ((RebootDeviceAction) action).isFastbootOrBootloader()) { + CLog.d( + "Ignore AdbCommandRejectedException when TCP device is rebooted into" + + " fastboot."); + return true; + } logDeviceActionException(actionDescription, e); } catch (ShellCommandUnresponsiveException e) { CLog.w("Device %s stopped responding when attempting %s", getSerialNumber(), @@ -2968,6 +2989,10 @@ public class NativeDevice implements IManagedTestDevice { throw new UnsupportedOperationException( String.format("Fastboot is not available and cannot reboot into %s", mode)); } + + // Update fastboot serial number before entering fastboot mode + mStateMonitor.setFastbootSerialNumber(getFastbootSerialNumber()); + // If we go to bootloader, it's probably for flashing so ensure we re-check the provider mShouldSkipContentProviderSetup = false; CLog.i( @@ -3747,6 +3772,78 @@ public class NativeDevice implements IManagedTestDevice { return null; } + /** {@inheritDoc} */ + @Override + public String getFastbootSerialNumber() { + if (mFastbootSerialNumber != null) { + return mFastbootSerialNumber; + } + + // Only devices which use TCP adb have different fastboot serial number because IPv6 + // link-local address will be used in fastboot mode. + if (!isAdbTcp()) { + mFastbootSerialNumber = getSerialNumber(); + CLog.i( + "Device %s's fastboot serial number is %s", + getSerialNumber(), mFastbootSerialNumber); + return mFastbootSerialNumber; + } + + mFastbootSerialNumber = getSerialNumber(); + byte[] macEui48Bytes; + + try { + boolean adbRoot = isAdbRoot(); + if (!adbRoot) { + enableAdbRoot(); + } + macEui48Bytes = getEUI48MacAddressInBytes(ETHERNET_MAC_ADDRESS_COMMAND); + if (!adbRoot) { + disableAdbRoot(); + } + } catch (DeviceNotAvailableException e) { + CLog.e("Device %s isn't available when get fastboot serial number", getSerialNumber()); + CLog.e(e); + return getSerialNumber(); + } + + String net_interface = getHostOptions().getNetworkInterface(); + if (net_interface == null || macEui48Bytes == null) { + CLog.i( + "Device %s's fastboot serial number is %s", + getSerialNumber(), mFastbootSerialNumber); + return mFastbootSerialNumber; + } + + // Create a link-local Inet6Address from the MAC address. The EUI-48 MAC address + // is converted to an EUI-64 MAC address per RFC 4291. The resulting EUI-64 is + // used to construct a link-local IPv6 address per RFC 4862. + byte[] addr = new byte[16]; + addr[0] = (byte) 0xfe; + addr[1] = (byte) 0x80; + addr[8] = (byte) (macEui48Bytes[0] ^ (byte) 0x02); // flip the link-local bit + addr[9] = macEui48Bytes[1]; + addr[10] = macEui48Bytes[2]; + addr[11] = (byte) 0xff; + addr[12] = (byte) 0xfe; + addr[13] = macEui48Bytes[3]; + addr[14] = macEui48Bytes[4]; + addr[15] = macEui48Bytes[5]; + + try { + String host_addr = Inet6Address.getByAddress(null, addr, 0).getHostAddress(); + mFastbootSerialNumber = "tcp:" + host_addr.split("%")[0] + "%" + net_interface; + } catch (UnknownHostException e) { + CLog.w("Failed to get %s's IPv6 link-local address", getSerialNumber()); + CLog.w(e); + } + + CLog.i( + "Device %s's fastboot serial number is %s", + getSerialNumber(), mFastbootSerialNumber); + return mFastbootSerialNumber; + } + /** * {@inheritDoc} */ @@ -4785,10 +4882,12 @@ public class NativeDevice implements IManagedTestDevice { } /** - * {@inheritDoc} + * Query Mac address from the device + * + * @param command the query command + * @return the MAC address of the device, null if it fails to query from the device */ - @Override - public String getMacAddress() { + private String getMacAddress(String command) { if (getIDevice() instanceof StubDevice) { // Do not query MAC addresses from stub devices. return null; @@ -4799,20 +4898,81 @@ public class NativeDevice implements IManagedTestDevice { } CollectingOutputReceiver receiver = new CollectingOutputReceiver(); try { - mIDevice.executeShellCommand(MAC_ADDRESS_COMMAND, receiver); + mIDevice.executeShellCommand(command, receiver); } catch (IOException | TimeoutException | AdbCommandRejectedException | ShellCommandUnresponsiveException e) { - CLog.w("Failed to query MAC address for %s", mIDevice.getSerialNumber()); + CLog.w( + "Failed to query MAC address for %s by '%s'", + mIDevice.getSerialNumber(), command); CLog.w(e); } String output = receiver.getOutput().trim(); if (isMacAddress(output)) { return output; } - CLog.d("No valid MAC address queried from device %s", mIDevice.getSerialNumber()); + CLog.d( + "No valid MAC address queried from device %s by '%s'", + mIDevice.getSerialNumber(), command); return null; } + /** + * Query EUI-48 MAC address from the device + * + * @param command the query command + * @return the EUI-48 MAC address in long, 0 if it fails to query from the device + * @throws IllegalArgumentException + */ + long getEUI48MacAddressInLong(String command) { + String addr = getMacAddress(command); + if (addr == null) { + return 0; + } + + String[] parts = addr.split(":"); + if (parts.length != ETHER_ADDR_LEN) { + throw new IllegalArgumentException(addr + " was not a valid MAC address"); + } + long longAddr = 0; + for (int i = 0; i < parts.length; i++) { + int x = Integer.valueOf(parts[i], 16); + if (x < 0 || 0xff < x) { + throw new IllegalArgumentException(addr + "was not a valid MAC address"); + } + longAddr = x + (longAddr << 8); + } + + return longAddr; + } + + /** + * Query EUI-48 MAC address from the device + * + * @param command the query command + * @return the EUI-48 MAC address in byte[], null if it fails to query from the device + * @throws IllegalArgumentException + */ + byte[] getEUI48MacAddressInBytes(String command) { + long addr = getEUI48MacAddressInLong(command); + if (addr == 0) { + return null; + } + + byte[] bytes = new byte[ETHER_ADDR_LEN]; + int index = ETHER_ADDR_LEN; + while (index-- > 0) { + bytes[index] = (byte) addr; + addr = addr >> 8; + } + return bytes; + } + + /** {@inheritDoc} */ + @Override + public String getMacAddress() { + return getMacAddress(MAC_ADDRESS_COMMAND); + } + /** {@inheritDoc} */ @Override public String getSimState() { diff --git a/src/com/android/tradefed/device/NativeDeviceStateMonitor.java b/src/com/android/tradefed/device/NativeDeviceStateMonitor.java index ebe4526e0..dcd2da7f2 100644 --- a/src/com/android/tradefed/device/NativeDeviceStateMonitor.java +++ b/src/com/android/tradefed/device/NativeDeviceStateMonitor.java @@ -55,6 +55,9 @@ public class NativeDeviceStateMonitor implements IDeviceStateMonitor { /** The time in ms to wait for a device to available. */ private long mDefaultAvailableTimeout = 6 * 60 * 1000; + /** The fastboot mode serial number */ + private String mFastbootSerialNumber = null; + private List<DeviceStateListener> mStateListeners; private IDeviceManager mMgr; private final boolean mFastbootEnabled; @@ -95,6 +98,17 @@ public class NativeDeviceStateMonitor implements IDeviceStateMonitor { mDefaultAvailableTimeout = timeoutMs; } + /** Set the fastboot mode serial number. */ + @Override + public void setFastbootSerialNumber(String serial) { + mFastbootSerialNumber = serial; + + if (mFastbootSerialNumber != null && !mFastbootSerialNumber.equals(getSerialNumber())) { + // Add to IDeviceManager to monitor it + mMgr.addMonitoringTcpFastbootDevice(getSerialNumber(), mFastbootSerialNumber); + } + } + /** * {@inheritDoc} */ @@ -131,6 +145,15 @@ public class NativeDeviceStateMonitor implements IDeviceStateMonitor { return getIDevice().getSerialNumber(); } + /** {@inheritDoc} */ + @Override + public String getFastbootSerialNumber() { + if (mFastbootSerialNumber == null) { + mFastbootSerialNumber = getSerialNumber(); + } + return mFastbootSerialNumber; + } + /** * {@inheritDoc} */ diff --git a/src/com/android/tradefed/device/WaitDeviceRecovery.java b/src/com/android/tradefed/device/WaitDeviceRecovery.java index 80a8f7d52..d71fb0637 100644 --- a/src/com/android/tradefed/device/WaitDeviceRecovery.java +++ b/src/com/android/tradefed/device/WaitDeviceRecovery.java @@ -137,8 +137,13 @@ public class WaitDeviceRecovery implements IDeviceRecovery { "Found device %s in %s but expected online. Rebooting...", monitor.getSerialNumber(), state)); // TODO: retry if failed - getRunUtil().runTimedCmd(mFastbootWaitTime, mFastbootPath, "-s", - monitor.getSerialNumber(), "reboot"); + getRunUtil() + .runTimedCmd( + mFastbootWaitTime, + mFastbootPath, + "-s", + monitor.getFastbootSerialNumber(), + "reboot"); } // wait for device online diff --git a/tests/src/com/android/tradefed/device/MockDeviceManager.java b/tests/src/com/android/tradefed/device/MockDeviceManager.java index 86b58f9d1..997b972ab 100644 --- a/tests/src/com/android/tradefed/device/MockDeviceManager.java +++ b/tests/src/com/android/tradefed/device/MockDeviceManager.java @@ -454,4 +454,9 @@ public class MockDeviceManager implements IDeviceManager { public String getAdbVersion() { return null; } + + @Override + public void addMonitoringTcpFastbootDevice(String serial, String fastboot_serial) { + // ignore + } } diff --git a/tests/src/com/android/tradefed/device/NativeDeviceTest.java b/tests/src/com/android/tradefed/device/NativeDeviceTest.java index c77f3ab52..2a3974d6e 100644 --- a/tests/src/com/android/tradefed/device/NativeDeviceTest.java +++ b/tests/src/com/android/tradefed/device/NativeDeviceTest.java @@ -1686,10 +1686,16 @@ public class NativeDeviceTest { public TestDeviceState getDeviceState() { return TestDeviceState.ONLINE; } + + @Override + public String getFastbootSerialNumber() { + return MOCK_DEVICE_SERIAL; + } }; String into = "bootloader"; mMockIDevice.reboot(into); EasyMock.expectLastCall(); + mMockStateMonitor.setFastbootSerialNumber(MOCK_DEVICE_SERIAL); EasyMock.expect(mMockStateMonitor.waitForDeviceBootloader(EasyMock.anyLong())) .andReturn(true); EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); @@ -1718,7 +1724,13 @@ public class NativeDeviceTest { } return new CommandResult(); } + + @Override + public String getFastbootSerialNumber() { + return MOCK_DEVICE_SERIAL; + } }; + mMockStateMonitor.setFastbootSerialNumber(MOCK_DEVICE_SERIAL); EasyMock.expect(mMockStateMonitor.waitForDeviceBootloader(EasyMock.anyLong())) .andReturn(true); EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); @@ -1736,10 +1748,16 @@ public class NativeDeviceTest { public TestDeviceState getDeviceState() { return TestDeviceState.ONLINE; } + + @Override + public String getFastbootSerialNumber() { + return MOCK_DEVICE_SERIAL; + } }; String into = "fastboot"; mMockIDevice.reboot(into); EasyMock.expectLastCall(); + mMockStateMonitor.setFastbootSerialNumber(MOCK_DEVICE_SERIAL); EasyMock.expect(mMockStateMonitor.waitForDeviceBootloader(EasyMock.anyLong())) .andReturn(true); EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); @@ -1768,7 +1786,13 @@ public class NativeDeviceTest { } return new CommandResult(); } + + @Override + public String getFastbootSerialNumber() { + return MOCK_DEVICE_SERIAL; + } }; + mMockStateMonitor.setFastbootSerialNumber(MOCK_DEVICE_SERIAL); EasyMock.expect(mMockStateMonitor.waitForDeviceBootloader(EasyMock.anyLong())) .andReturn(true); EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); @@ -3235,4 +3259,116 @@ public class NativeDeviceTest { .andReturn(stubResult); EasyMock.replay(mMockRunUtil); } + + /** Test {@link NativeDevice#getFastbootSerialNumber()} with USB adb. */ + @Test + public void testGetFastbootSerialNumber_usb_adb() { + mTestDevice = + new TestableAndroidNativeDevice() { + @Override + public boolean isAdbTcp() { + return false; + } + }; + EasyMock.replay(mMockIDevice); + assertEquals(MOCK_DEVICE_SERIAL, mTestDevice.getFastbootSerialNumber()); + EasyMock.verify(mMockIDevice); + } + + /** Test {@link NativeDevice#getFastbootSerialNumber()} with non-root TCP adb. */ + @Test + public void testGetFastbootSerialNumber_non_root_tcp_adb() throws Exception { + String address = "00:30:1b:ba:81:28"; + IDevice device = + new StubDevice(MOCK_DEVICE_SERIAL) { + @Override + public void executeShellCommand(String command, IShellOutputReceiver receiver) + throws TimeoutException, AdbCommandRejectedException, + ShellCommandUnresponsiveException, IOException { + receiver.addOutput(address.getBytes(), 0, address.length()); + } + }; + mTestDevice = + new TestableAndroidNativeDevice() { + @Override + IHostOptions getHostOptions() { + return new HostOptions() { + @Override + public String getNetworkInterface() { + return "en0"; + } + }; + } + + @Override + public boolean isAdbTcp() { + return true; + } + + @Override + public boolean isAdbRoot() throws DeviceNotAvailableException { + return false; + } + + @Override + public boolean enableAdbRoot() throws DeviceNotAvailableException { + return true; + } + + @Override + public boolean disableAdbRoot() throws DeviceNotAvailableException { + return true; + } + }; + mMockIDevice.executeShellCommand(EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall().andDelegateTo(device).anyTimes(); + EasyMock.replay(mMockIDevice); + assertEquals( + "tcp:fe80:0:0:0:230:1bff:feba:8128%en0", mTestDevice.getFastbootSerialNumber()); + EasyMock.verify(mMockIDevice); + } + + /** Test {@link NativeDevice#getFastbootSerialNumber()} with root TCP adb. */ + @Test + public void testGetFastbootSerialNumber_root_tcp_adb() throws Exception { + String address = "00:30:1b:ba:81:28"; + IDevice device = + new StubDevice(MOCK_DEVICE_SERIAL) { + @Override + public void executeShellCommand(String command, IShellOutputReceiver receiver) + throws TimeoutException, AdbCommandRejectedException, + ShellCommandUnresponsiveException, IOException { + receiver.addOutput(address.getBytes(), 0, address.length()); + } + }; + mTestDevice = + new TestableAndroidNativeDevice() { + @Override + IHostOptions getHostOptions() { + return new HostOptions() { + @Override + public String getNetworkInterface() { + return "en0"; + } + }; + } + + @Override + public boolean isAdbTcp() { + return true; + } + + @Override + public boolean isAdbRoot() throws DeviceNotAvailableException { + return true; + } + }; + + mMockIDevice.executeShellCommand(EasyMock.anyObject(), EasyMock.anyObject()); + EasyMock.expectLastCall().andDelegateTo(device).anyTimes(); + EasyMock.replay(mMockIDevice); + assertEquals( + "tcp:fe80:0:0:0:230:1bff:feba:8128%en0", mTestDevice.getFastbootSerialNumber()); + EasyMock.verify(mMockIDevice); + } } diff --git a/tests/src/com/android/tradefed/device/TestDeviceTest.java b/tests/src/com/android/tradefed/device/TestDeviceTest.java index 5de87725b..e6007fd6f 100644 --- a/tests/src/com/android/tradefed/device/TestDeviceTest.java +++ b/tests/src/com/android/tradefed/device/TestDeviceTest.java @@ -129,6 +129,11 @@ public class TestDeviceTest extends TestCase { // Avoid issue with GlobalConfiguration return new HostOptions(); } + + @Override + public boolean isAdbTcp() { + return false; + } } /** diff --git a/tests/src/com/android/tradefed/device/WaitDeviceRecoveryTest.java b/tests/src/com/android/tradefed/device/WaitDeviceRecoveryTest.java index 3b5cb688d..855403a2a 100644 --- a/tests/src/com/android/tradefed/device/WaitDeviceRecoveryTest.java +++ b/tests/src/com/android/tradefed/device/WaitDeviceRecoveryTest.java @@ -197,6 +197,7 @@ public class WaitDeviceRecoveryTest { EasyMock.eq("reboot"))) .andReturn(result); + EasyMock.expect(mMockMonitor.getFastbootSerialNumber()).andReturn("serial"); EasyMock.expect(mMockMonitor.waitForDeviceOnline(EasyMock.anyLong())).andReturn(null); replayMocks(); try { @@ -247,6 +248,7 @@ public class WaitDeviceRecoveryTest { CommandResult result = new CommandResult(); result.setStatus(CommandStatus.SUCCESS); // expect reboot + EasyMock.expect(mMockMonitor.getFastbootSerialNumber()).andReturn("serial"); EasyMock.expect(mMockRunUtil.runTimedCmd(EasyMock.anyLong(), EasyMock.eq("fastboot"), EasyMock.eq("-s"), EasyMock.eq("serial"), EasyMock.eq("reboot"))). andReturn(result); |