/*
 * Copyright (C) 2016 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.android.tradefed.device;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;

import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.FileListingService.FileEntry;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.IShellOutputReceiver;
import com.android.ddmlib.ShellCommandUnresponsiveException;
import com.android.ddmlib.SyncException;
import com.android.ddmlib.SyncException.SyncError;
import com.android.ddmlib.SyncService;
import com.android.ddmlib.SyncService.ISyncProgressMonitor;
import com.android.ddmlib.TimeoutException;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.command.remote.DeviceDescriptor;
import com.android.tradefed.config.ConfigurationException;
import com.android.tradefed.config.OptionSetter;
import com.android.tradefed.device.NativeDevice.RebootMode;
import com.android.tradefed.host.HostOptions;
import com.android.tradefed.host.IHostOptions;
import com.android.tradefed.log.ITestLogger;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.result.ByteArrayInputStreamSource;
import com.android.tradefed.result.FileInputStreamSource;
import com.android.tradefed.result.InputStreamSource;
import com.android.tradefed.result.LogDataType;
import com.android.tradefed.util.Bugreport;
import com.android.tradefed.util.CommandResult;
import com.android.tradefed.util.CommandStatus;
import com.android.tradefed.util.FileUtil;
import com.android.tradefed.util.IRunUtil;
import com.android.tradefed.util.ProcessInfo;
import com.android.tradefed.util.StreamUtil;

import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mockito;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.time.Clock;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/** Unit tests for {@link NativeDevice}. */
@RunWith(JUnit4.class)
public class NativeDeviceTest {

    private static final String MOCK_DEVICE_SERIAL = "serial";
    private static final String FAKE_NETWORK_SSID = "FakeNet";
    private static final String FAKE_NETWORK_PASSWORD ="FakePass";

    private IDevice mMockIDevice;
    private TestableAndroidNativeDevice mTestDevice;
    private IDeviceRecovery mMockRecovery;
    private IDeviceStateMonitor mMockStateMonitor;
    private IRunUtil mMockRunUtil;
    private IWifiHelper mMockWifi;
    private IDeviceMonitor mMockDvcMonitor;
    private IHostOptions mHostOptions;

    /**
     * A {@link TestDevice} that is suitable for running tests against
     */
    private class TestableAndroidNativeDevice extends NativeDevice {

        public boolean wasCalled = false;

        public TestableAndroidNativeDevice() {
            super(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
        }

        @Override
        public void postBootSetup() {
            // too annoying to mock out postBootSetup actions everyone, so do nothing
        }

        @Override
        protected IRunUtil getRunUtil() {
            return mMockRunUtil;
        }

        @Override
        IHostOptions getHostOptions() {
            return mHostOptions;
        }
    }

    @Before
    public void setUp() throws Exception {
        mHostOptions = new HostOptions();
        mMockIDevice = EasyMock.createMock(IDevice.class);
        EasyMock.expect(mMockIDevice.getSerialNumber()).andReturn(MOCK_DEVICE_SERIAL).anyTimes();
        mMockRecovery = EasyMock.createMock(IDeviceRecovery.class);
        mMockStateMonitor = EasyMock.createMock(IDeviceStateMonitor.class);
        mMockDvcMonitor = EasyMock.createMock(IDeviceMonitor.class);
        mMockRunUtil = EasyMock.createMock(IRunUtil.class);
        mMockWifi = EasyMock.createMock(IWifiHelper.class);
        mMockWifi.cleanUp();
        EasyMock.expectLastCall().anyTimes();

        // A TestDevice with a no-op recoverDevice() implementation
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public void recoverDevice() throws DeviceNotAvailableException {
                // ignore
            }

            @Override
            public IDevice getIDevice() {
                return mMockIDevice;
            }

            @Override
            IWifiHelper createWifiHelper() {
                return mMockWifi;
            }
        };
        mTestDevice.setRecovery(mMockRecovery);
        mTestDevice.setCommandTimeout(100);
        mTestDevice.setLogStartDelay(-1);
    }

    /**
     * Test return exception for package installation {@link NativeDevice#installPackage(File,
     * boolean, String...)}.
     */
    @Test
    public void testInstallPackages_exception() throws Exception {
        try {
            mTestDevice.installPackage(new File(""), false);
            fail("installPackage should have thrown an exception");
        } catch (UnsupportedOperationException expected) {
            // Expected
        }
    }

    /**
     * Test return exception for package installation {@link NativeDevice#uninstallPackage(String)}.
     */
    @Test
    public void testUninstallPackages_exception() throws Exception {
        try {
            mTestDevice.uninstallPackage("");
            fail("uninstallPackageForUser should have thrown an exception");
        } catch (UnsupportedOperationException expected) {
            // Expected
        }
    }

    /**
     * Test return exception for package installation {@link NativeDevice#installPackage(File,
     * boolean, boolean, String...)}.
     */
    @Test
    public void testInstallPackagesBool_exception() throws Exception {
        try {
            mTestDevice.installPackage(new File(""), false, false);
            fail("installPackage should have thrown an exception");
        } catch (UnsupportedOperationException expected) {
            // Expected
        }
    }

    /**
     * Test return exception for package installation {@link
     * NativeDevice#installPackageForUser(File, boolean, int, String...)}.
     */
    @Test
    public void testInstallPackagesForUser_exception() throws Exception {
        try {
            mTestDevice.installPackageForUser(new File(""), false, 0);
            fail("installPackageForUser should have thrown an exception");
        } catch (UnsupportedOperationException expected) {
            // Expected
        }
    }

    /**
     * Test return exception for package installation {@link
     * NativeDevice#installPackageForUser(File, boolean, boolean, int, String...)}.
     */
    @Test
    public void testInstallPackagesForUserWithPermission_exception() throws Exception {
        try {
            mTestDevice.installPackageForUser(new File(""), false, false, 0);
            fail("installPackageForUser should have thrown an exception");
        } catch (UnsupportedOperationException expected) {
            // Expected
        }
    }

    /** Unit test for {@link NativeDevice#getInstalledPackageNames()}. */
    @Test
    public void testGetInstalledPackageNames_exception() throws Exception {
        try {
            mTestDevice.getInstalledPackageNames();
            fail("getInstalledPackageNames should have thrown an exception");
        } catch (UnsupportedOperationException expected) {
            // Expected
        }
    }

    /** Unit test for {@link NativeDevice#getActiveApexes()}. */
    @Test
    public void testGetActiveApexes_exception() throws Exception {
        try {
            mTestDevice.getActiveApexes();
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("getActiveApexes should have thrown an exception");
    }

    /** Unit test for {@link NativeDevice#getMainlineModuleInfo()}. */
    @Test
    public void testGetMainlineModuleInfo_exception() throws Exception {
        try {
            mTestDevice.getMainlineModuleInfo();
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("getMainlineModuleInfo should have thrown an exception");
    }

    /** Unit test for {@link NativeDevice#getScreenshot()}. */
    @Test
    public void testGetScreenshot_exception() throws Exception {
        try {
            mTestDevice.getScreenshot();
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("getScreenshot should have thrown an exception");
    }

    /** Unit test for {@link NativeDevice#pushDir(File, String)}. */
    @Test
    public void testPushDir_notADir() throws Exception {
        assertFalse(mTestDevice.pushDir(new File(""), ""));
    }

    /** Unit test for {@link NativeDevice#pushDir(File, String)}. */
    @Test
    public void testPushDir_childFile() throws Exception {
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public boolean pushFile(File localFile, String remoteFilePath)
                    throws DeviceNotAvailableException {
                return true;
            }
        };
        File testDir = FileUtil.createTempDir("pushDirTest");
        FileUtil.createTempFile("test1", ".txt", testDir);
        assertTrue(mTestDevice.pushDir(testDir, ""));
        FileUtil.recursiveDelete(testDir);
    }

    /** Unit test for {@link NativeDevice#pushDir(File, String)}. */
    @Test
    public void testPushDir_childDir() throws Exception {
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public String executeShellCommand(String cmd) throws DeviceNotAvailableException {
                return "";
            }
            @Override
            public boolean pushFile(File localFile, String remoteFilePath)
                    throws DeviceNotAvailableException {
                return false;
            }
        };
        File testDir = FileUtil.createTempDir("pushDirTest");
        File subDir = FileUtil.createTempDir("testSubDir", testDir);
        FileUtil.createTempDir("test1", subDir);
        assertTrue(mTestDevice.pushDir(testDir, ""));
        FileUtil.recursiveDelete(testDir);
    }

    /** Unit test for {@link NativeDevice#pushDir(File, String, Set)}. */
    @Test
    public void testPushDir_childDir_filtered() throws Exception {
        File testDir = FileUtil.createTempDir("pushDirTest");
        Set<String> filter = new HashSet<>();
        try {
            File subDir = FileUtil.createTempDir("testSubDir", testDir);
            File childDir = FileUtil.createTempDir("test1", subDir);
            filter.add(childDir.getName());
            mTestDevice =
                    new TestableAndroidNativeDevice() {
                        @Override
                        public String executeShellCommand(String cmd)
                                throws DeviceNotAvailableException {
                            // Ensure we never attempt to push the excluded child.
                            assertFalse(cmd.contains(childDir.getName()));
                            return "";
                        }

                        @Override
                        public boolean pushFile(File localFile, String remoteFilePath)
                                throws DeviceNotAvailableException {
                            return false;
                        }
                    };

            assertTrue(mTestDevice.pushDir(testDir, "/", filter));
        } finally {
            FileUtil.recursiveDelete(testDir);
        }
    }

    /** Test {@link NativeDevice#pullDir(String, File)} when the remote directory is empty. */
    @Test
    public void testPullDir_nothingToDo() throws Exception {
        final IFileEntry fakeEntry = EasyMock.createMock(IFileEntry.class);
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public IFileEntry getFileEntry(FileEntry path)
                            throws DeviceNotAvailableException {
                        return fakeEntry;
                    }

                    @Override
                    public String executeShellCommand(String command)
                            throws DeviceNotAvailableException {
                        return "drwxr-xr-x root     root    somedirectory";
                    }
                };
        File dir = FileUtil.createTempDir("tf-test");
        Collection<IFileEntry> childrens = new ArrayList<>();
        EasyMock.expect(fakeEntry.getChildren(false)).andReturn(childrens);
        // Empty list of childen
        EasyMock.replay(fakeEntry);
        try {
            boolean res = mTestDevice.pullDir("/some_device_path/screenshots/", dir);
            assertTrue(res);
            assertTrue(dir.list().length == 0);
        } finally {
            FileUtil.recursiveDelete(dir);
        }
        EasyMock.verify(fakeEntry);
    }

    /**
     * Test {@link NativeDevice#pullDir(String, File)} when the remote directory has a file and a
     * directory.
     */
    @Test
    public void testPullDir() throws Exception {
        final IFileEntry fakeEntry = EasyMock.createMock(IFileEntry.class);
        final IFileEntry fakeDir = EasyMock.createMock(IFileEntry.class);
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    private boolean mFirstCall = true;

                    @Override
                    public IFileEntry getFileEntry(FileEntry path)
                            throws DeviceNotAvailableException {
                        if (mFirstCall) {
                            mFirstCall = false;
                            return fakeEntry;
                        } else {
                            return fakeDir;
                        }
                    }

                    @Override
                    public String executeShellCommand(String command)
                            throws DeviceNotAvailableException {
                        return "drwxr-xr-x root     root    somedirectory";
                    }

                    @Override
                    public boolean pullFile(String remoteFilePath, File localFile)
                            throws DeviceNotAvailableException {
                        try {
                            // Just touch the file to make it appear.
                            localFile.createNewFile();
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                        return true;
                    }
                };
        File dir = FileUtil.createTempDir("tf-test");
        Collection<IFileEntry> children = new ArrayList<>();
        IFileEntry fakeFile = EasyMock.createMock(IFileEntry.class);
        children.add(fakeFile);
        EasyMock.expect(fakeFile.isDirectory()).andReturn(false);
        EasyMock.expect(fakeFile.getName()).andReturn("fakeFile");
        EasyMock.expect(fakeFile.getFullPath()).andReturn("/some_device_path/fakeFile");

        children.add(fakeDir);
        EasyMock.expect(fakeDir.isDirectory()).andReturn(true);
        EasyMock.expect(fakeDir.getName()).andReturn("fakeDir");
        EasyMock.expect(fakeDir.getFullPath()).andReturn("/some_device_path/fakeDir");
        // #pullDir is being called on dir fakeDir to pull everything recursively.
        Collection<IFileEntry> fakeDirChildren = new ArrayList<>();
        EasyMock.expect(fakeDir.getChildren(false)).andReturn(fakeDirChildren);
        EasyMock.expect(fakeEntry.getChildren(false)).andReturn(children);

        EasyMock.replay(fakeEntry, fakeFile, fakeDir);
        try {
            boolean res = mTestDevice.pullDir("/some_device_path/", dir);
            assertTrue(res);
            assertEquals(2, dir.list().length);
            assertTrue(Arrays.asList(dir.list()).contains("fakeFile"));
            assertTrue(Arrays.asList(dir.list()).contains("fakeDir"));
        } finally {
            FileUtil.recursiveDelete(dir);
        }
        EasyMock.verify(fakeEntry, fakeFile, fakeDir);
    }

    /** Test pulling a directory when one of the pull fails. */
    @Test
    public void testPullDir_pullFail() throws Exception {
        final IFileEntry fakeEntry = EasyMock.createMock(IFileEntry.class);
        final IFileEntry fakeDir = EasyMock.createMock(IFileEntry.class);
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    private boolean mFirstCall = true;
                    private boolean mFirstPull = true;

                    @Override
                    public IFileEntry getFileEntry(FileEntry path)
                            throws DeviceNotAvailableException {
                        if (mFirstCall) {
                            mFirstCall = false;
                            return fakeEntry;
                        } else {
                            return fakeDir;
                        }
                    }

                    @Override
                    public String executeShellCommand(String command)
                            throws DeviceNotAvailableException {
                        return "drwxr-xr-x root     root    somedirectory";
                    }

                    @Override
                    public boolean pullFile(String remoteFilePath, File localFile)
                            throws DeviceNotAvailableException {
                        if (mFirstPull) {
                            mFirstPull = false;
                            try {
                                // Just touch the file to make it appear.
                                localFile.createNewFile();
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                            return true;
                        } else {
                            return false;
                        }
                    }
                };
        File dir = FileUtil.createTempDir("tf-test");
        Collection<IFileEntry> children = new ArrayList<>();
        IFileEntry fakeFile = EasyMock.createMock(IFileEntry.class);
        children.add(fakeFile);
        EasyMock.expect(fakeFile.isDirectory()).andReturn(false);
        EasyMock.expect(fakeFile.getName()).andReturn("fakeFile");
        EasyMock.expect(fakeFile.getFullPath()).andReturn("/some_device_path/fakeFile");

        children.add(fakeDir);
        EasyMock.expect(fakeDir.isDirectory()).andReturn(true);
        EasyMock.expect(fakeDir.getName()).andReturn("fakeDir");
        EasyMock.expect(fakeDir.getFullPath()).andReturn("/some_device_path/fakeDir");
        // #pullDir is being called on dir fakeDir to pull everything recursively.
        Collection<IFileEntry> fakeDirChildren = new ArrayList<>();
        IFileEntry secondLevelChildren = EasyMock.createMock(IFileEntry.class);
        fakeDirChildren.add(secondLevelChildren);
        EasyMock.expect(fakeDir.getChildren(false)).andReturn(fakeDirChildren);
        EasyMock.expect(fakeEntry.getChildren(false)).andReturn(children);

        EasyMock.expect(secondLevelChildren.isDirectory()).andReturn(false);
        EasyMock.expect(secondLevelChildren.getName()).andReturn("secondLevelChildren");
        EasyMock.expect(secondLevelChildren.getFullPath())
                .andReturn("/some_device_path/fakeDir/secondLevelChildren");

        EasyMock.replay(fakeEntry, fakeFile, fakeDir, secondLevelChildren);
        try {
            boolean res = mTestDevice.pullDir("/some_device_path/", dir);
            // If one of the pull fails, the full command is considered failed.
            assertFalse(res);
            assertEquals(2, dir.list().length);
            assertTrue(Arrays.asList(dir.list()).contains("fakeFile"));
            // The subdir was created
            assertTrue(Arrays.asList(dir.list()).contains("fakeDir"));
            // The last file failed to pull, so the dir is empty.
            assertEquals(0, new File(dir, "fakeDir").list().length);
        } finally {
            FileUtil.recursiveDelete(dir);
        }
        EasyMock.verify(fakeEntry, fakeFile, fakeDir, secondLevelChildren);
    }

    /**
     * Test that if the requested path is not a directory on the device side, we just fail directly.
     */
    @Test
    public void testPullDir_invalidPath() throws Exception {
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public String executeShellCommand(String command)
                            throws DeviceNotAvailableException {
                        return "-rwxr-xr-x root     root    somefile";
                    }
                };
        File dir = FileUtil.createTempDir("tf-test");
        try {
            assertFalse(mTestDevice.pullDir("somefile", dir));
            assertTrue(dir.list().length == 0);
        } finally {
            FileUtil.recursiveDelete(dir);
        }
    }

    /** Unit test for {@link NativeDevice#getCurrentUser()}. */
    @Test
    public void testGetCurrentUser_exception() throws Exception {
        try {
            mTestDevice.getScreenshot();
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("getCurrentUser should have thrown an exception.");
    }

    /** Unit test for {@link NativeDevice#getUserFlags(int)}. */
    @Test
    public void testGetUserFlags_exception() throws Exception {
        try {
            mTestDevice.getUserFlags(0);
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("getUserFlags should have thrown an exception.");
    }

    /** Unit test for {@link NativeDevice#getUserSerialNumber(int)}. */
    @Test
    public void testGetUserSerialNumber_exception() throws Exception {
        try {
            mTestDevice.getUserSerialNumber(0);
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("getUserSerialNumber should have thrown an exception.");
    }

    /** Unit test for {@link NativeDevice#switchUser(int)}. */
    @Test
    public void testSwitchUser_exception() throws Exception {
        try {
            mTestDevice.switchUser(10);
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("switchUser should have thrown an exception.");
    }

    /** Unit test for {@link NativeDevice#switchUser(int, long)}. */
    @Test
    public void testSwitchUserTimeout_exception() throws Exception {
        try {
            mTestDevice.switchUser(10, 5*1000);
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("switchUser should have thrown an exception.");
    }

    /** Unit test for {@link NativeDevice#stopUser(int)}. */
    @Test
    public void testStopUser_exception() throws Exception {
        try {
            mTestDevice.stopUser(0);
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("stopUser should have thrown an exception.");
    }

    /** Unit test for {@link NativeDevice#stopUser(int, boolean, boolean)}. */
    @Test
    public void testStopUserFlags_exception() throws Exception {
        try {
            mTestDevice.stopUser(0, true, true);
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("stopUser should have thrown an exception.");
    }

    /** Unit test for {@link NativeDevice#startUser(int, boolean)}. */
    @Test
    public void testStartUserFlags_exception() throws Exception {
        try {
            mTestDevice.startUser(0, true);
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("startUser should have thrown an exception.");
    }

    /** Unit test for {@link NativeDevice#isUserRunning(int)}. */
    @Test
    public void testIsUserIdRunning_exception() throws Exception {
        try {
            mTestDevice.isUserRunning(0);
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("stopUser should have thrown an exception.");
    }

    /** Unit test for {@link NativeDevice#hasFeature(String)}. */
    @Test
    public void testHasFeature_exception() throws Exception {
        try {
            mTestDevice.hasFeature("feature:test");
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("hasFeature should have thrown an exception.");
    }

    /** Unit test for {@link NativeDevice#getSetting(String, String)}. */
    @Test
    public void testGetSettingSystemUser_exception() throws Exception {
        try {
            mTestDevice.getSetting("global", "wifi_on");
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("getSettings should have thrown an exception.");
    }

    /** Unit test for {@link NativeDevice#getSetting(int, String, String)}. */
    @Test
    public void testGetSetting_exception() throws Exception {
        try {
            mTestDevice.getSetting(0, "global", "wifi_on");
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("getSettings should have thrown an exception.");
    }

    /** Unit test for {@link NativeDevice#getAllSettings(String)}. */
    @Test
    public void testGetAllSettingsSystemUser_exception() throws Exception {
        try {
            mTestDevice.getAllSettings("global");
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("getAllSettings should have thrown an exception");
    }

    /** Unit test for {@link NativeDevice#setSetting(String, String, String)}. */
    @Test
    public void testSetSettingSystemUser_exception() throws Exception {
        try {
            mTestDevice.setSetting("global", "wifi_on", "0");
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("putSettings should have thrown an exception.");
    }

    /** Unit test for {@link NativeDevice#setSetting(int, String, String, String)}. */
    @Test
    public void testSetSetting_exception() throws Exception {
        try {
            mTestDevice.setSetting(0, "global", "wifi_on", "0");
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("putSettings should have thrown an exception.");
    }

    /** Unit test for {@link NativeDevice#getAndroidId(int)}. */
    @Test
    public void testGetAndroidId_exception() throws Exception {
        try {
            mTestDevice.getAndroidId(0);
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("getAndroidId should have thrown an exception.");
    }

    /** Unit test for {@link NativeDevice#getAndroidIds()}. */
    @Test
    public void testGetAndroidIds_exception() throws Exception {
        try {
            mTestDevice.getAndroidIds();
        } catch (UnsupportedOperationException onse) {
            return;
        }
        fail("getAndroidIds should have thrown an exception.");
    }

    /** Unit test for {@link NativeDevice#connectToWifiNetworkIfNeeded(String, String)}. */
    @Test
    public void testConnectToWifiNetworkIfNeeded_alreadyConnected()
            throws DeviceNotAvailableException {
        EasyMock.expect(mMockWifi.checkConnectivity(mTestDevice.getOptions().getConnCheckUrl()))
                .andReturn(true);
        EasyMock.replay(mMockWifi);
        assertTrue(mTestDevice.connectToWifiNetworkIfNeeded(FAKE_NETWORK_SSID,
                FAKE_NETWORK_PASSWORD));
        EasyMock.verify(mMockWifi);
    }

    /** Unit test for {@link NativeDevice#connectToWifiNetwork(String, String)}. */
    @Test
    public void testConnectToWifiNetwork_success() throws DeviceNotAvailableException {
        EasyMock.expect(mMockWifi.connectToNetwork(FAKE_NETWORK_SSID, FAKE_NETWORK_PASSWORD,
                mTestDevice.getOptions().getConnCheckUrl(), false)).andReturn(true);
        Map<String, String> fakeWifiInfo = new HashMap<String, String>();
        fakeWifiInfo.put("bssid", FAKE_NETWORK_SSID);
        EasyMock.expect(mMockWifi.getWifiInfo()).andReturn(fakeWifiInfo);
        EasyMock.replay(mMockWifi, mMockIDevice);
        assertTrue(mTestDevice.connectToWifiNetwork(FAKE_NETWORK_SSID,
                FAKE_NETWORK_PASSWORD));
        EasyMock.verify(mMockWifi, mMockIDevice);
    }

    /**
     * Unit test for {@link NativeDevice#connectToWifiNetwork(String, String)} for a failure to
     * connect case.
     */
    @Test
    public void testConnectToWifiNetwork_failure() throws DeviceNotAvailableException {
        EasyMock.expect(mMockWifi.connectToNetwork(FAKE_NETWORK_SSID, FAKE_NETWORK_PASSWORD,
                mTestDevice.getOptions().getConnCheckUrl(), false)).andReturn(false)
                .times(mTestDevice.getOptions().getWifiAttempts());
        Map<String, String> fakeWifiInfo = new HashMap<String, String>();
        fakeWifiInfo.put("bssid", FAKE_NETWORK_SSID);
        EasyMock.expect(mMockWifi.getWifiInfo()).andReturn(fakeWifiInfo)
                .times(mTestDevice.getOptions().getWifiAttempts());
        mMockRunUtil.sleep(EasyMock.anyLong());
        EasyMock.expectLastCall().times(mTestDevice.getOptions().getWifiAttempts() - 1);
        EasyMock.replay(mMockWifi, mMockIDevice, mMockRunUtil);
        assertFalse(mTestDevice.connectToWifiNetwork(FAKE_NETWORK_SSID,
                FAKE_NETWORK_PASSWORD));
        EasyMock.verify(mMockWifi, mMockIDevice, mMockRunUtil);
    }

    /**
     * Unit test for {@link NativeDevice#connectToWifiNetwork(String, String)} for limiting the time
     * trying to connect to wifi.
     */
    @Test
    public void testConnectToWifiNetwork_maxConnectTime()
            throws DeviceNotAvailableException, ConfigurationException {
        OptionSetter deviceOptionSetter = new OptionSetter(mTestDevice.getOptions());
        deviceOptionSetter.setOptionValue("max-wifi-connect-time", "10000");
        Clock mockClock = Mockito.mock(Clock.class);
        mTestDevice.setClock(mockClock);
        EasyMock.expect(
                        mMockWifi.connectToNetwork(
                                FAKE_NETWORK_SSID,
                                FAKE_NETWORK_PASSWORD,
                                mTestDevice.getOptions().getConnCheckUrl(),
                                false))
                .andReturn(false)
                .times(2);
        Mockito.when(mockClock.millis())
                .thenReturn(Long.valueOf(0), Long.valueOf(6000), Long.valueOf(12000));
        Map<String, String> fakeWifiInfo = new HashMap<String, String>();
        fakeWifiInfo.put("bssid", FAKE_NETWORK_SSID);
        EasyMock.expect(mMockWifi.getWifiInfo()).andReturn(fakeWifiInfo).times(2);

        EasyMock.replay(mMockWifi, mMockIDevice);
        assertFalse(mTestDevice.connectToWifiNetwork(FAKE_NETWORK_SSID, FAKE_NETWORK_PASSWORD));
        EasyMock.verify(mMockWifi, mMockIDevice);
        Mockito.verify(mockClock, Mockito.times(3)).millis();
    }

    /** Unit test for {@link NativeDevice#connectToWifiNetwork(String, String, boolean)}. */
    @Test
    public void testConnectToWifiNetwork_scanSsid() throws DeviceNotAvailableException {
        EasyMock.expect(mMockWifi.connectToNetwork(FAKE_NETWORK_SSID, FAKE_NETWORK_PASSWORD,
                mTestDevice.getOptions().getConnCheckUrl(), true)).andReturn(true);
        Map<String, String> fakeWifiInfo = new HashMap<String, String>();
        fakeWifiInfo.put("bssid", FAKE_NETWORK_SSID);
        EasyMock.expect(mMockWifi.getWifiInfo()).andReturn(fakeWifiInfo);
        EasyMock.replay(mMockWifi, mMockIDevice);
        assertTrue(mTestDevice.connectToWifiNetwork(FAKE_NETWORK_SSID,
                FAKE_NETWORK_PASSWORD, true));
        EasyMock.verify(mMockWifi, mMockIDevice);
    }

    /** Unit test for {@link NativeDevice#checkWifiConnection(String)}. */
    @Test
    public void testCheckWifiConnection() throws DeviceNotAvailableException {
        EasyMock.expect(mMockWifi.isWifiEnabled()).andReturn(true);
        EasyMock.expect(mMockWifi.getSSID()).andReturn("\"" + FAKE_NETWORK_SSID + "\"");
        EasyMock.expect(mMockWifi.hasValidIp()).andReturn(true);
        EasyMock.expect(mMockWifi.checkConnectivity(mTestDevice.getOptions().getConnCheckUrl()))
                .andReturn(true);
        EasyMock.replay(mMockWifi, mMockIDevice);
        assertTrue(mTestDevice.checkWifiConnection(FAKE_NETWORK_SSID));
        EasyMock.verify(mMockWifi, mMockIDevice);
    }

    /** Unit test for {@link NativeDevice#checkWifiConnection(String)} for a failure. */
    @Test
    public void testCheckWifiConnection_failure() throws DeviceNotAvailableException {
        EasyMock.expect(mMockWifi.isWifiEnabled()).andReturn(false);
        EasyMock.replay(mMockWifi, mMockIDevice);
        assertFalse(mTestDevice.checkWifiConnection(FAKE_NETWORK_SSID));
        EasyMock.verify(mMockWifi, mMockIDevice);
    }

    /** Unit test for {@link NativeDevice#isWifiEnabled()}. */
    @Test
    public void testIsWifiEnabled() throws DeviceNotAvailableException {
        EasyMock.expect(mMockWifi.isWifiEnabled()).andReturn(true);
        EasyMock.replay(mMockWifi, mMockIDevice);
        assertTrue(mTestDevice.isWifiEnabled());
        EasyMock.verify(mMockWifi, mMockIDevice);
    }

    /**
     * Unit test for {@link NativeDevice#isWifiEnabled()} with runtime exception from wifihelper.
     */
    @Test
    public void testIsWifiEnabled_exception() throws DeviceNotAvailableException {
        EasyMock.expect(mMockWifi.isWifiEnabled()).andThrow(new RuntimeException());
        EasyMock.replay(mMockWifi, mMockIDevice);
        assertFalse(mTestDevice.isWifiEnabled());
        EasyMock.verify(mMockWifi, mMockIDevice);
    }

    /** Unit test for {@link NativeDevice#disconnectFromWifi()}. */
    @Test
    public void testDisconnectFromWifi() throws DeviceNotAvailableException {
        EasyMock.expect(mMockWifi.disconnectFromNetwork()).andReturn(true);
        EasyMock.replay(mMockWifi, mMockIDevice);
        assertTrue(mTestDevice.disconnectFromWifi());
        EasyMock.verify(mMockWifi, mMockIDevice);
    }

    /** Unit test for {@link NativeDevice#enableNetworkMonitor()}. */
    @Test
    public void testEnableNetworkMonitor() throws DeviceNotAvailableException {
        EasyMock.expect(mMockWifi.stopMonitor()).andReturn(null);
        EasyMock.expect(mMockWifi.startMonitor(EasyMock.anyLong(),
                EasyMock.eq(mTestDevice.getOptions().getConnCheckUrl()))).andReturn(true);
        EasyMock.replay(mMockWifi, mMockIDevice);
        assertTrue(mTestDevice.enableNetworkMonitor());
        EasyMock.verify(mMockWifi, mMockIDevice);
    }

    /** Unit test for {@link NativeDevice#enableNetworkMonitor()} in case of failure. */
    @Test
    public void testEnableNetworkMonitor_failure() throws DeviceNotAvailableException {
        EasyMock.expect(mMockWifi.stopMonitor()).andReturn(null);
        EasyMock.expect(mMockWifi.startMonitor(EasyMock.anyLong(),
                EasyMock.eq(mTestDevice.getOptions().getConnCheckUrl()))).andReturn(false);
        EasyMock.replay(mMockWifi, mMockIDevice);
        assertFalse(mTestDevice.enableNetworkMonitor());
        EasyMock.verify(mMockWifi, mMockIDevice);
    }

    /** Unit test for {@link NativeDevice#disableNetworkMonitor()}. */
    @Test
    public void testDisableNetworkMonitor() throws DeviceNotAvailableException {
        List<Long> samples = new ArrayList<Long>();
        samples.add(Long.valueOf(42));
        samples.add(Long.valueOf(256));
        samples.add(Long.valueOf(-1)); // failure to connect
        EasyMock.expect(mMockWifi.stopMonitor()).andReturn(samples);
        EasyMock.replay(mMockWifi, mMockIDevice);
        assertTrue(mTestDevice.disableNetworkMonitor());
        EasyMock.verify(mMockWifi, mMockIDevice);
    }

    /** Unit test for {@link NativeDevice#reconnectToWifiNetwork()}. */
    @Test
    public void testReconnectToWifiNetwork() throws DeviceNotAvailableException {
        EasyMock.expect(mMockWifi.checkConnectivity(mTestDevice.getOptions().getConnCheckUrl()))
                .andReturn(false);
        EasyMock.expect(mMockWifi.checkConnectivity(mTestDevice.getOptions().getConnCheckUrl()))
                .andReturn(true);
        mMockRunUtil.sleep(EasyMock.anyLong());
        EasyMock.expectLastCall();
        EasyMock.replay(mMockWifi, mMockIDevice, mMockRunUtil);
        try {
            mTestDevice.reconnectToWifiNetwork();
        } finally {
            EasyMock.verify(mMockWifi, mMockIDevice, mMockRunUtil);
        }
    }

    /** Unit test for {@link NativeDevice#isHeadless()}. */
    @Test
    public void testIsHeadless() throws DeviceNotAvailableException {
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public String getProperty(String name) throws DeviceNotAvailableException {
                return "1\n";
            }
        };
        assertTrue(mTestDevice.isHeadless());
    }

    /** Unit test for {@link NativeDevice#isHeadless()}. */
    @Test
    public void testIsHeadless_notHeadless() throws DeviceNotAvailableException {
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public String getProperty(String name) throws DeviceNotAvailableException {
                return null;
            }
        };
        assertFalse(mTestDevice.isHeadless());
    }

    /** Unit test for {@link NativeDevice#getDeviceDate()}. */
    @Test
    public void testGetDeviceDate() throws DeviceNotAvailableException {
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public String executeShellCommand(String name) throws DeviceNotAvailableException {
                return "21692641\n";
            }
        };
        assertEquals(21692641000L, mTestDevice.getDeviceDate());
    }

    /** Unit test for {@link NativeDevice#logBugreport(String, ITestLogger)}. */
    @Test
    public void testTestLogBugreport() {
        final String dataName = "test";
        final InputStreamSource stream = new ByteArrayInputStreamSource("bugreportz".getBytes());
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public InputStreamSource getBugreportz() {
                        return stream;
                    }

                    @Override
                    public int getApiLevel() throws DeviceNotAvailableException {
                        return 24;
                    }
                };
        ITestLogger listener = EasyMock.createMock(ITestLogger.class);
        listener.testLog(dataName, LogDataType.BUGREPORTZ, stream);
        EasyMock.replay(listener);
        assertTrue(mTestDevice.logBugreport(dataName, listener));
        EasyMock.verify(listener);
    }

    /** Unit test for {@link NativeDevice#logBugreport(String, ITestLogger)}. */
    @Test
    public void testTestLogBugreport_oldDevice() {
        final String dataName = "test";
        final InputStreamSource stream = new ByteArrayInputStreamSource("bugreport".getBytes());
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public InputStreamSource getBugreportz() {
                        // Older device do not support bugreportz and return null
                        return null;
                    }

                    @Override
                    public InputStreamSource getBugreportInternal() {
                        return stream;
                    }

                    @Override
                    public int getApiLevel() throws DeviceNotAvailableException {
                        // no bugreportz support
                        return 23;
                    }
                };
        ITestLogger listener = EasyMock.createMock(ITestLogger.class);
        listener.testLog(dataName, LogDataType.BUGREPORT, stream);
        EasyMock.replay(listener);
        assertTrue(mTestDevice.logBugreport(dataName, listener));
        EasyMock.verify(listener);
    }

    /** Unit test for {@link NativeDevice#logBugreport(String, ITestLogger)}. */
    @Test
    public void testTestLogBugreport_fail() {
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public InputStreamSource getBugreportz() {
                        return null;
                    }

                    @Override
                    protected InputStreamSource getBugreportInternal() {
                        return null;
                    }

                    @Override
                    public int getApiLevel() throws DeviceNotAvailableException {
                        return 23;
                    }
                };
        ITestLogger listener = EasyMock.createMock(ITestLogger.class);
        EasyMock.replay(listener);
        assertFalse(mTestDevice.logBugreport("test", listener));
        EasyMock.verify(listener);
    }

    /** Unit test for {@link NativeDevice#takeBugreport()}. */
    @Test
    public void testTakeBugreport_apiLevelFail() {
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public int getApiLevel() throws DeviceNotAvailableException {
                        throw new DeviceNotAvailableException("test", "serial");
                    }
                };
        // If we can't check API level it should return null.
        assertNull(mTestDevice.takeBugreport());
    }

    /** Unit test for {@link NativeDevice#takeBugreport()}. */
    @Test
    public void testTakeBugreport_oldDevice() throws Exception {
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public int getApiLevel() throws DeviceNotAvailableException {
                return 19;
            }
        };
        Bugreport report = mTestDevice.takeBugreport();
        try {
            assertNotNull(report);
            // older device report a non zipped bugreport
            assertFalse(report.isZipped());
        } finally {
            report.close();
        }
    }

    /** Unit test for {@link NativeDevice#takeBugreport()}. */
    @Test
    public void testTakeBugreport() throws Exception {
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public int getApiLevel() throws DeviceNotAvailableException {
                return 24;
            }
            @Override
            protected File getBugreportzInternal() {
                try {
                    return FileUtil.createTempFile("bugreportz", ".zip");
                } catch (IOException e) {
                    return null;
                }
            }
        };
        Bugreport report = mTestDevice.takeBugreport();
        try {
            assertNotNull(report);
            assertTrue(report.isZipped());
        } finally {
            report.close();
        }
    }

    /** Unit test for {@link NativeDevice#getDeviceDate()}. */
    @Test
    public void testGetDeviceDate_wrongformat() throws DeviceNotAvailableException {
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public String executeShellCommand(String name) throws DeviceNotAvailableException {
                return "WRONG\n";
            }
        };
        assertEquals(0, mTestDevice.getDeviceDate());
    }

    @Test
    public void testGetBugreport_deviceUnavail() throws Exception {
        final String expectedOutput = "this is the output\r\n in two lines\r\n";
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public void executeShellCommand(
                    String command, IShellOutputReceiver receiver,
                    long maxTimeToOutputShellResponse, TimeUnit timeUnit, int retryAttempts)
                            throws DeviceNotAvailableException {
                String fakeRep = expectedOutput;
                receiver.addOutput(fakeRep.getBytes(), 0, fakeRep.getBytes().length);
            }
            @Override
            public int getApiLevel() throws DeviceNotAvailableException {
                return 22;
            }
        };

        // FIXME: this isn't actually causing a DeviceNotAvailableException to be thrown
        mMockRecovery.recoverDevice(EasyMock.eq(mMockStateMonitor), EasyMock.eq(false));
        EasyMock.expectLastCall().andThrow(new DeviceNotAvailableException("test", "serial"));
        EasyMock.replay(mMockRecovery, mMockIDevice);
        assertEquals(expectedOutput, StreamUtil.getStringFromStream(
                mTestDevice.getBugreport().createInputStream()));
    }

    @Test
    public void testGetBugreport_compatibility_deviceUnavail() throws Exception {
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public void executeShellCommand(
                            String command,
                            IShellOutputReceiver receiver,
                            long maxTimeToOutputShellResponse,
                            TimeUnit timeUnit,
                            int retryAttempts)
                            throws DeviceNotAvailableException {
                        throw new DeviceNotAvailableException("test", "serial");
                    }

                    @Override
                    public int getApiLevel() throws DeviceNotAvailableException {
                        return 24;
                    }

                    @Override
                    public IFileEntry getFileEntry(String path) throws DeviceNotAvailableException {
                        return null;
                    }
                };
        EasyMock.replay(mMockRecovery, mMockIDevice);
        assertEquals(0, mTestDevice.getBugreport().size());
        EasyMock.verify(mMockRecovery, mMockIDevice);
    }

    @Test
    public void testGetBugreport_deviceUnavail_fallback() throws Exception {
        final IFileEntry fakeEntry = EasyMock.createMock(IFileEntry.class);
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public void executeShellCommand(
                            String command,
                            IShellOutputReceiver receiver,
                            long maxTimeToOutputShellResponse,
                            TimeUnit timeUnit,
                            int retryAttempts)
                            throws DeviceNotAvailableException {
                        throw new DeviceNotAvailableException("test", "serial");
                    }

                    @Override
                    public int getApiLevel() throws DeviceNotAvailableException {
                        return 24;
                    }

                    @Override
                    public IFileEntry getFileEntry(String path) throws DeviceNotAvailableException {
                        return fakeEntry;
                    }

                    @Override
                    public File pullFile(String remoteFilePath) throws DeviceNotAvailableException {
                        try {
                            return FileUtil.createTempFile("bugreport", ".txt");
                        } catch (IOException e) {
                            return null;
                        }
                    }
                };
        List<IFileEntry> list = new ArrayList<>();
        list.add(fakeEntry);
        EasyMock.expect(fakeEntry.getChildren(false)).andReturn(list);
        EasyMock.expect(fakeEntry.getName()).andReturn("bugreport-NYC-2016-08-17-10-17-00.tmp");
        EasyMock.replay(fakeEntry, mMockRecovery, mMockIDevice);
        InputStreamSource res = null;
        try {
            res = mTestDevice.getBugreport();
            assertNotNull(res);
            EasyMock.verify(fakeEntry, mMockRecovery, mMockIDevice);
        } finally {
            StreamUtil.cancel(res);
        }
    }

    /** Unit test for {@link NativeDevice#getBugreportz()}. */
    @Test
    public void testGetBugreportz() throws IOException {
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public void executeShellCommand(
                            String command,
                            IShellOutputReceiver receiver,
                            long maxTimeToOutputShellResponse,
                            TimeUnit timeUnit,
                            int retryAttempts)
                            throws DeviceNotAvailableException {
                        String fakeRep =
                                "OK:/data/0/com.android.shell/bugreports/bugreport1970-10-27.zip";
                        receiver.addOutput(fakeRep.getBytes(), 0, fakeRep.getBytes().length);
                    }

                    @Override
                    public boolean doesFileExist(String destPath)
                            throws DeviceNotAvailableException {
                        return true;
                    }

                    @Override
                    public boolean pullFile(String remoteFilePath, File localFile)
                            throws DeviceNotAvailableException {
                        return true;
                    }

                    @Override
                    public void deleteFile(String deviceFilePath)
                            throws DeviceNotAvailableException {
                        assertEquals("/data/0/com.android.shell/bugreports/*", deviceFilePath);
                    }

                    @Override
                    public int getApiLevel() throws DeviceNotAvailableException {
                        return 24;
                    }
                };
        FileInputStreamSource f = null;
        try {
            f = (FileInputStreamSource) mTestDevice.getBugreportz();
            assertNotNull(f);
            assertTrue(f.createInputStream().available() == 0);
        } finally {
            StreamUtil.cancel(f);
            if (f != null) {
                f.cleanFile();
            }
        }
    }

    /** Unit test for {@link NativeDevice#getBugreportz()}. */
    @Test
    public void testGetBugreportz_fails() {
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public int getApiLevel() throws DeviceNotAvailableException {
                        return 24;
                    }

                    @Override
                    protected File getBugreportzInternal() {
                        return null;
                    }

                    @Override
                    public IFileEntry getFileEntry(String path) throws DeviceNotAvailableException {
                        return null;
                    }
                };
        FileInputStreamSource f = null;
        try {
            f = (FileInputStreamSource) mTestDevice.getBugreportz();
            assertNull(f);
        } finally {
            StreamUtil.cancel(f);
            if (f != null) {
                f.cleanFile();
            }
        }
    }

    @Test
    public void testGetBugreportz_fallBack_validation() throws Exception {
        IFileEntry entryMock = EasyMock.createMock(IFileEntry.class);
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public int getApiLevel() throws DeviceNotAvailableException {
                        return 24;
                    }

                    @Override
                    protected File getBugreportzInternal() {
                        return null;
                    }

                    @Override
                    public IFileEntry getFileEntry(String path) throws DeviceNotAvailableException {
                        return entryMock;
                    }

                    @Override
                    public File pullFile(String remoteFilePath) throws DeviceNotAvailableException {
                        try {
                            // Return an empty zip file for the partial bugreportz
                            return FileUtil.createTempFile("bugreportz-test", ".zip");
                        } catch (IOException e) {
                            throw new RuntimeException();
                        }
                    }
                };
        IFileEntry childNode = EasyMock.createMock(IFileEntry.class);
        EasyMock.expect(entryMock.getChildren(false)).andReturn(Arrays.asList(childNode));
        EasyMock.expect(childNode.getName()).andReturn("bugreport-test-partial.zip");
        FileInputStreamSource f = null;
        EasyMock.replay(entryMock, childNode);
        try {
            f = (FileInputStreamSource) mTestDevice.getBugreportz();
            assertNull(f);
        } finally {
            StreamUtil.cancel(f);
            if (f != null) {
                f.cleanFile();
            }
        }
        EasyMock.verify(entryMock, childNode);
    }

    /**
     * Test that we can distinguish a newer file even with Timezone on the device. Seoul is GMT+9.
     */
    @Test
    public void testIsNewer() throws Exception {
        TestableAndroidNativeDevice testDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public String getProperty(String name) throws DeviceNotAvailableException {
                        return "Asia/Seoul";
                    }

                    @Override
                    public long getDeviceTimeOffset(Date date) throws DeviceNotAvailableException {
                        return 0;
                    }
                };
        File localFile = FileUtil.createTempFile("timezonetest", ".txt");
        try {
            localFile.setLastModified(1470906000000L); // Thu Aug 11 09:00:00 GMT 2016
            IFileEntry remoteFile = EasyMock.createMock(IFileEntry.class);
            EasyMock.expect(remoteFile.getDate()).andReturn("2016-08-11");
            EasyMock.expect(remoteFile.getTime()).andReturn("18:00");
            EasyMock.replay(remoteFile);
            assertTrue(testDevice.isNewer(localFile, remoteFile));
            EasyMock.verify(remoteFile);
        } finally {
            FileUtil.deleteFile(localFile);
        }
    }

    /**
     * Test that we can distinguish a newer file even with Timezone on the device. Seoul is GMT+9.
     * Clock on device is inaccurate and in advance of host.
     */
    @Test
    public void testIsNewer_timeOffset() throws Exception {
        TestableAndroidNativeDevice testDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public String getProperty(String name) throws DeviceNotAvailableException {
                        return "Asia/Seoul";
                    }

                    @Override
                    public long getDeviceTimeOffset(Date date) throws DeviceNotAvailableException {
                        return -15 * 60 * 1000; // Device in advance of 15m on host.
                    }
                };
        File localFile = FileUtil.createTempFile("timezonetest", ".txt");
        try {
            localFile.setLastModified(1470906000000L); // Thu, 11 Aug 2016 09:00:00 GMT
            IFileEntry remoteFile = EasyMock.createMock(IFileEntry.class);
            EasyMock.expect(remoteFile.getDate()).andReturn("2016-08-11");
            EasyMock.expect(remoteFile.getTime()).andReturn("18:15");
            EasyMock.replay(remoteFile);
            // Should sync because after time offset correction, file is older.
            assertTrue(testDevice.isNewer(localFile, remoteFile));
            EasyMock.verify(remoteFile);
        } finally {
            FileUtil.deleteFile(localFile);
        }
    }

    /**
     * Test that we can distinguish a newer file even with Timezone on the device. Seoul is GMT+9.
     * Local file is set to 10min earlier than remoteFile.
     */
    @Test
    public void testIsNewer_fails() throws Exception {
        TestableAndroidNativeDevice testDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public String getProperty(String name) throws DeviceNotAvailableException {
                        return "Asia/Seoul";
                    }

                    @Override
                    public long getDeviceTimeOffset(Date date) throws DeviceNotAvailableException {
                        return 0;
                    }
                };
        File localFile = FileUtil.createTempFile("timezonetest", ".txt");
        try {
            localFile.setLastModified(1470906000000L); // Thu, 11 Aug 2016 09:00:00 GMT
            IFileEntry remoteFile = EasyMock.createMock(IFileEntry.class);
            EasyMock.expect(remoteFile.getDate()).andReturn("2016-08-11");
            EasyMock.expect(remoteFile.getTime()).andReturn("18:10");
            EasyMock.replay(remoteFile);
            assertFalse(testDevice.isNewer(localFile, remoteFile));
            EasyMock.verify(remoteFile);
        } finally {
            FileUtil.deleteFile(localFile);
        }
    }

    /** Unit test for {@link NativeDevice#getBuildAlias()}. */
    @Test
    public void testGetBuildAlias() throws DeviceNotAvailableException {
        final String alias = "alias\n";
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public String getProperty(String name) throws DeviceNotAvailableException {
                return alias;
            }
        };
        assertEquals(alias, mTestDevice.getBuildAlias());
    }

    /** Unit test for {@link NativeDevice#getBuildAlias()}. */
    @Test
    public void testGetBuildAlias_null() throws DeviceNotAvailableException {
        final String alias = null;
        final String buildId = "alias\n";
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public String getProperty(String name) throws DeviceNotAvailableException {
                return alias;
            }
            @Override
            public String getBuildId() throws DeviceNotAvailableException {
                return buildId;
            }
        };
        assertEquals(buildId, mTestDevice.getBuildAlias());
    }

    /** Unit test for {@link NativeDevice#getBuildAlias()}. */
    @Test
    public void testGetBuildAlias_empty() throws DeviceNotAvailableException {
        final String alias = "";
        final String buildId = "alias\n";
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public String getProperty(String name) throws DeviceNotAvailableException {
                return alias;
            }
            @Override
            public String getBuildId() throws DeviceNotAvailableException {
                return buildId;
            }
        };
        assertEquals(buildId, mTestDevice.getBuildAlias());
    }

    /** Unit test for {@link NativeDevice#getBuildId()}. */
    @Test
    public void testGetBuildId() throws DeviceNotAvailableException {
        final String buildId = "299865";
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public String getProperty(String name) throws DeviceNotAvailableException {
                return buildId;
            }
        };
        assertEquals(buildId, mTestDevice.getBuildId());
    }

    /** Unit test for {@link NativeDevice#getBuildId()}. */
    @Test
    public void testGetBuildId_null() throws DeviceNotAvailableException {
        final String buildId = null;
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public String getProperty(String name) throws DeviceNotAvailableException {
                return buildId;
            }
        };
        assertEquals(IBuildInfo.UNKNOWN_BUILD_ID, mTestDevice.getBuildId());
    }

    /** Unit test for {@link NativeDevice#getBuildFlavor()}. */
    @Test
    public void testGetBuildFlavor() throws DeviceNotAvailableException {
        final String flavor = "ham-user";
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public String getProperty(String name) throws DeviceNotAvailableException {
                return flavor;
            }
        };
        assertEquals(flavor, mTestDevice.getBuildFlavor());
    }

    /** Unit test for {@link NativeDevice#getBuildFlavor()}. */
    @Test
    public void testGetBuildFlavor_null_flavor() throws DeviceNotAvailableException {
        final String productName = "prod";
        final String buildType = "buildtype";
        String expected = String.format("%s-%s", productName, buildType);
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public String getProperty(String name) throws DeviceNotAvailableException {
                if ("ro.build.flavor".equals(name)) {
                    return null;
                } else if ("ro.product.name".equals(name)) {
                    return productName;
                } else if ("ro.build.type".equals(name)) {
                    return buildType;
                } else {
                    return null;
                }
            }
        };
        assertEquals(expected, mTestDevice.getBuildFlavor());
    }

    /** Unit test for {@link NativeDevice#getBuildFlavor()}. */
    @Test
    public void testGetBuildFlavor_null() throws DeviceNotAvailableException {
        final String productName = null;
        final String buildType = "buildtype";
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public String getProperty(String name) throws DeviceNotAvailableException {
                if ("ro.build.flavor".equals(name)) {
                    return "";
                } else if ("ro.product.name".equals(name)) {
                    return productName;
                } else if ("ro.build.type".equals(name)) {
                    return buildType;
                } else {
                    return null;
                }
            }
        };
        assertNull(mTestDevice.getBuildFlavor());
    }

    /** Unit test for {@link NativeDevice#doAdbReboot(RebootMode, String)} )}. */
    @Test
    public void testDoAdbReboot_emulator() throws Exception {
        final String into = "bootloader";
        mMockIDevice.reboot(into);
        EasyMock.expectLastCall();
        EasyMock.replay(mMockIDevice);
        mTestDevice.doAdbReboot(RebootMode.REBOOT_INTO_BOOTLOADER, "");
        EasyMock.verify(mMockIDevice);
    }

    /** Unit test for {@link NativeDevice#doReboot(RebootMode, String)} ()}. */
    @Test
    public void testDoReboot() throws Exception {
        NativeDevice testDevice = new NativeDevice(mMockIDevice,
                mMockStateMonitor, mMockDvcMonitor) {
            @Override
            public TestDeviceState getDeviceState() {
                return TestDeviceState.ONLINE;
            }
        };
        mMockIDevice.reboot(null);
        EasyMock.expectLastCall();
        EasyMock.expect(mMockStateMonitor.waitForDeviceNotAvailable(EasyMock.anyLong()))
                .andReturn(true);
        EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
        testDevice.doReboot(RebootMode.REBOOT_FULL, null);
        EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
    }

    /** Unit test for {@link NativeDevice#doReboot(RebootMode, String)} ()}. */
    @Test
    public void testDoReboot_skipped() throws Exception {
        NativeDevice testDevice = new NativeDevice(mMockIDevice,
                mMockStateMonitor, mMockDvcMonitor) {
            @Override
            public TestDeviceState getDeviceState() {
                mOptions = new TestDeviceOptions() {
                    @Override
                    public boolean shouldDisableReboot() {
                        return true;
                    }
                };
                return TestDeviceState.ONLINE;
            }
        };
        EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
        testDevice.doReboot(RebootMode.REBOOT_FULL, null);
        EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
    }

    /** Unit test for {@link NativeDevice#doReboot(RebootMode, String)} ()}. */
    @Test
    public void testDoReboot_fastboot() throws Exception {
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public TestDeviceState getDeviceState() {
                return TestDeviceState.FASTBOOT;
            }
            @Override
            public CommandResult executeFastbootCommand(String... cmdArgs)
                    throws DeviceNotAvailableException, UnsupportedOperationException {
                wasCalled = true;
                return new CommandResult();
            }
        };
        EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
        mTestDevice.doReboot(RebootMode.REBOOT_FULL, null);
        assertTrue(mTestDevice.wasCalled);
        EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
    }

    /** Unit test for {@link NativeDevice#rebootIntoSideload()}}. */
    @Test
    public void testRebootIntoSideload() throws Exception {
        NativeDevice testDevice =
                new NativeDevice(mMockIDevice, mMockStateMonitor, mMockDvcMonitor) {
                    @Override
                    public TestDeviceState getDeviceState() {
                        return TestDeviceState.ONLINE;
                    }
                };
        String into = "sideload";
        mMockIDevice.reboot(into);
        EasyMock.expectLastCall();
        EasyMock.expect(mMockStateMonitor.waitForDeviceInSideload(EasyMock.anyLong()))
                .andReturn(true);
        EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
        testDevice.rebootIntoSideload();
        EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
    }

    /** Unit test for {@link NativeDevice#rebootIntoBootloader()}}. */
    @Test
    public void testRebootIntoBootloader() throws Exception {
        NativeDevice testDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    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);
        testDevice.rebootIntoBootloader();
        EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
    }

    /**
     * Unit test for {@link NativeDevice#rebootIntoBootloader()}} when device is already in fastboot
     * mode.
     */
    @Test
    public void testRebootIntoBootloader_forceFastboot() throws Exception {
        TestableAndroidNativeDevice testDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public TestDeviceState getDeviceState() {
                        return TestDeviceState.FASTBOOT;
                    }

                    @Override
                    public CommandResult executeFastbootCommand(String... cmdArgs)
                            throws DeviceNotAvailableException, UnsupportedOperationException {
                        if (cmdArgs[0].equals("reboot-bootloader")) {
                            wasCalled = true;
                        }
                        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);
        testDevice.rebootIntoBootloader();
        assertTrue(testDevice.wasCalled);
        EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
    }

    /** Unit test for {@link NativeDevice#rebootIntoFastbootd()}}. */
    @Test
    public void testRebootIntoFastbootd() throws Exception {
        NativeDevice testDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    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);
        testDevice.rebootIntoFastbootd();
        EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
    }

    /**
     * Unit test for {@link NativeDevice#rebootIntoFastbootd()}} when device is already in fastboot
     * mode.
     */
    @Test
    public void testRebootIntoFastbootd_forceFastboot() throws Exception {
        TestableAndroidNativeDevice testDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public TestDeviceState getDeviceState() {
                        return TestDeviceState.FASTBOOT;
                    }

                    @Override
                    public CommandResult executeFastbootCommand(String... cmdArgs)
                            throws DeviceNotAvailableException, UnsupportedOperationException {
                        if (cmdArgs[0].equals("reboot-fastboot")) {
                            wasCalled = true;
                        }
                        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);
        testDevice.rebootIntoFastbootd();
        assertTrue(testDevice.wasCalled);
        EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
    }

    /** Unit test for {@link NativeDevice#unlockDevice()} already decrypted. */
    @Test
    public void testUnlockDevice_skipping() throws Exception {
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public boolean isEncryptionSupported() throws DeviceNotAvailableException {
                return true;
            }
            @Override
            public boolean isDeviceEncrypted() throws DeviceNotAvailableException {
                return false;
            }
        };
        EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
        assertTrue(mTestDevice.unlockDevice());
        EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
    }

    /** Unit test for {@link NativeDevice#unlockDevice()}. */
    @Test
    public void testUnlockDevice() throws Exception {
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public boolean isEncryptionSupported() throws DeviceNotAvailableException {
                return true;
            }
            @Override
            public boolean isDeviceEncrypted() throws DeviceNotAvailableException {
                return true;
            }
            @Override
            public boolean enableAdbRoot() throws DeviceNotAvailableException {
                return true;
            }
            @Override
            public String executeShellCommand(String command) throws DeviceNotAvailableException {
                return "200 checkpw -1";
            }
        };
        EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
        assertTrue(mTestDevice.unlockDevice());
        EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
    }

    /** Unit test for {@link NativeDevice#unlockDevice()}. */
    @Test
    public void testUnlockDevice_garbageOutput() throws Exception {
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public boolean isEncryptionSupported() throws DeviceNotAvailableException {
                return true;
            }
            @Override
            public boolean isDeviceEncrypted() throws DeviceNotAvailableException {
                return true;
            }
            @Override
            public boolean enableAdbRoot() throws DeviceNotAvailableException {
                return true;
            }
            @Override
            public String executeShellCommand(String command) throws DeviceNotAvailableException {
                return "gdsgdgggsgdg not working";
            }
        };
        EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
        assertFalse(mTestDevice.unlockDevice());
        EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
    }

    /** Unit test for {@link NativeDevice#unlockDevice()}. */
    @Test
    public void testUnlockDevice_emptyOutput() throws Exception {
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public boolean isEncryptionSupported() throws DeviceNotAvailableException {
                return true;
            }
            @Override
            public boolean isDeviceEncrypted() throws DeviceNotAvailableException {
                return true;
            }
            @Override
            public boolean enableAdbRoot() throws DeviceNotAvailableException {
                return true;
            }
            @Override
            public String executeShellCommand(String command) throws DeviceNotAvailableException {
                return "";
            }
        };
        EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
        assertFalse(mTestDevice.unlockDevice());
        EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
    }

    /** Unit test for {@link NativeDevice#unlockDevice()}. */
    @Test
    public void testUnlockDevice_goodOutputPasswordEnteredCorrectly() throws Exception {
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public boolean isEncryptionSupported() throws DeviceNotAvailableException {
                return true;
            }
            @Override
            public boolean isDeviceEncrypted() throws DeviceNotAvailableException {
                return true;
            }
            @Override
            public boolean enableAdbRoot() throws DeviceNotAvailableException {
                return true;
            }
            @Override
            public String executeShellCommand(String command) throws DeviceNotAvailableException {
                return "200 encryption 0";
            }
        };
        EasyMock.expect(mMockStateMonitor.waitForDeviceAvailable()).andReturn(mMockIDevice);
        EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
        assertTrue(mTestDevice.unlockDevice());
        EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor);
    }

    /**
     * Test {NativeDevice#parseFreeSpaceFromModernOutput(String)} with a regular df output and mount
     * name of numbers.
     */
    @Test
    public void testParseDfOutput_mountWithNumber() {
        String dfOutput = "Filesystem     1K-blocks   Used Available Use% Mounted on\n" +
                "/dev/fuse       31154688 100576  31054112   1% /storage/3134-3433";
        Long res = mTestDevice.parseFreeSpaceFromModernOutput(dfOutput);
        assertNotNull(res);
        assertEquals(31054112L, res.longValue());
    }

    /**
     * Test {NativeDevice#parseFreeSpaceFromModernOutput(String)} with a regular df output and mount
     * name of mix of letters and numbers.
     */
    @Test
    public void testParseDfOutput() {
        String dfOutput = "Filesystem     1K-blocks   Used Available Use% Mounted on\n" +
                "/dev/fuse       31154688 100576  31054112   1% /storage/sdcard58";
        Long res = mTestDevice.parseFreeSpaceFromModernOutput(dfOutput);
        assertNotNull(res);
        assertEquals(31054112L, res.longValue());
    }

    /**
     * Test {NativeDevice#parseFreeSpaceFromModernOutput(String)} with a regular df output and mount
     * name with incorrect field.
     */
    @Test
    public void testParseDfOutput_wrongMount() {
        String dfOutput = "Filesystem     1K-blocks   Used Available Use% Mounted on\n" +
                "/dev/fuse       31154688 100576  31054112   1% \test\\wrongpath";
        Long res = mTestDevice.parseFreeSpaceFromModernOutput(dfOutput);
        assertNull(res);
    }

    /**
     * Test {NativeDevice#parseFreeSpaceFromModernOutput(String)} with a regular df output and a
     * filesytem name with numbers in it.
     */
    @Test
    public void testParseDfOutput_filesystemWithNumber() {
        String dfOutput = "Filesystem     1K-blocks   Used Available Use% Mounted on\n" +
                "/dev/dm-1       31154688 100576  31054112   1% /";
        Long res = mTestDevice.parseFreeSpaceFromModernOutput(dfOutput);
        assertNotNull(res);
        assertEquals(31054112L, res.longValue());
    }

    /**
     * Test that {@link NativeDevice#getDeviceTimeOffset(Date)} returns the proper offset forward
     */
    @Test
    public void testGetDeviceTimeOffset() throws DeviceNotAvailableException {
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public long getDeviceDate() throws DeviceNotAvailableException {
                        return 1476958881000L;
                    }
                };
        Date date = new Date(1476958891000L);
        assertEquals(10000L, mTestDevice.getDeviceTimeOffset(date));
    }

    /**
     * Test that {@link NativeDevice#getDeviceTimeOffset(Date)}} returns the proper offset when
     * there is delay.
     */
    @Test
    public void testGetDeviceTimeOffset_delay() throws DeviceNotAvailableException {
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public long getDeviceDate() throws DeviceNotAvailableException {
                        // DeviceDate is in second
                        return 1476958891000L;
                    }
                };
        // Date takes millisecond since Epoch
        Date date = new Date(1476958881000L);
        assertEquals(-10000L, mTestDevice.getDeviceTimeOffset(date));
    }

    /**
     * Test that {@link NativeDevice#setDate(Date)} returns the proper offset when there is delay
     * with api level above 24, posix format is used.
     */
    @Test
    public void testSetDate() throws DeviceNotAvailableException {
        Date date = new Date(1476958881000L);
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public int getApiLevel() throws DeviceNotAvailableException {
                        return 24;
                    }

                    @Override
                    public long getDeviceTimeOffset(Date date) throws DeviceNotAvailableException {
                        // right above set threshold
                        return NativeDevice.MAX_HOST_DEVICE_TIME_OFFSET + 1;
                    }

                    @Override
                    public String executeShellCommand(String command)
                            throws DeviceNotAvailableException {
                        CLog.e("%s", command);
                        assertEquals("TZ=UTC date -u 102010212016.21", command);
                        return command;
                    }
                };
        mTestDevice.setDate(date);
    }

    /**
     * Test that {@link NativeDevice#setDate(Date)} returns the proper offset when there is delay
     * with api level below 23, regular second format is used.
     */
    @Test
    public void testSetDate_lowApi() throws DeviceNotAvailableException {
        Date date = new Date(1476958881000L);
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public int getApiLevel() throws DeviceNotAvailableException {
                        return 22;
                    }

                    @Override
                    public long getDeviceTimeOffset(Date date) throws DeviceNotAvailableException {
                        // right above set threshold
                        return NativeDevice.MAX_HOST_DEVICE_TIME_OFFSET + 1;
                    }

                    @Override
                    public String executeShellCommand(String command)
                            throws DeviceNotAvailableException {
                        CLog.e("%s", command);
                        assertEquals("TZ=UTC date -u 1476958881", command);
                        return command;
                    }
                };
        mTestDevice.setDate(date);
    }

    /** Test that {@link NativeDevice#setDate(Date)} does not attemp to set if bellow threshold. */
    @Test
    public void testSetDate_NoAction() throws DeviceNotAvailableException {
        Date date = new Date(1476958881000L);
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public long getDeviceTimeOffset(Date date) throws DeviceNotAvailableException {
                        // right below set threshold
                        return NativeDevice.MAX_HOST_DEVICE_TIME_OFFSET - 1;
                    }

                    @Override
                    public String executeShellCommand(String command)
                            throws DeviceNotAvailableException {
                        fail("Should not be called");
                        return command;
                    }
                };
        mTestDevice.setDate(date);
    }

    /** Test that {@link NativeDevice#getDeviceDescriptor()} returns the proper information. */
    @Test
    public void testGetDeviceDescriptor() {
        final String serial = "Test";
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public IDevice getIDevice() {
                return new StubDevice(serial);
            }
        };
        DeviceDescriptor desc = mTestDevice.getDeviceDescriptor();
        assertTrue(desc.isStubDevice());
        assertEquals(serial, desc.getSerial());
        assertEquals("StubDevice", desc.getDeviceClass());
    }

    /**
     * Test that {@link NativeDevice#pullFile(String, File)} returns true when the pull is
     * successful.
     */
    @Test
    public void testPullFile() throws Exception {
        final String fakeRemotePath = "/test/";
        SyncService s = Mockito.mock(SyncService.class);
        EasyMock.expect(mMockIDevice.getSyncService()).andReturn(s);
        EasyMock.replay(mMockIDevice);
        File tmpFile = FileUtil.createTempFile("pull", ".test");
        try {
            boolean res = mTestDevice.pullFile(fakeRemotePath, tmpFile);
            EasyMock.verify(mMockIDevice);
            Mockito.verify(s)
                    .pullFile(
                            Mockito.eq(fakeRemotePath),
                            Mockito.eq(tmpFile.getAbsolutePath()),
                            Mockito.any(ISyncProgressMonitor.class));
            Mockito.verify(s).close();
            assertTrue(res);
        } finally {
            FileUtil.deleteFile(tmpFile);
        }
    }

    /**
     * Test that {@link NativeDevice#pullFile(String, File)} returns false when it fails to pull the
     * file.
     */
    @Test
    public void testPullFile_fails() throws Exception {
        final String fakeRemotePath = "/test/";
        SyncService s = Mockito.mock(SyncService.class);
        EasyMock.expect(mMockIDevice.getSyncService()).andReturn(s);
        EasyMock.replay(mMockIDevice);
        File tmpFile = FileUtil.createTempFile("pull", ".test");
        doThrow(new SyncException(SyncError.CANCELED))
                .when(s)
                .pullFile(
                        Mockito.eq(fakeRemotePath),
                        Mockito.eq(tmpFile.getAbsolutePath()),
                        Mockito.any(ISyncProgressMonitor.class));
        try {
            boolean res = mTestDevice.pullFile(fakeRemotePath, tmpFile);
            EasyMock.verify(mMockIDevice);
            Mockito.verify(s)
                    .pullFile(
                            Mockito.eq(fakeRemotePath),
                            Mockito.eq(tmpFile.getAbsolutePath()),
                            Mockito.any(ISyncProgressMonitor.class));
            Mockito.verify(s).close();
            assertFalse(res);
        } finally {
            FileUtil.deleteFile(tmpFile);
        }
    }

    /**
     * Test that {@link NativeDevice#pullFile(String)} returns a file when succeed pulling the file.
     */
    @Test
    public void testPullFile_returnFileSuccess() throws Exception {
        final String fakeRemotePath = "/test/";
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public boolean pullFile(String remoteFilePath, File localFile)
                    throws DeviceNotAvailableException {
                return true;
            }
        };
        File res = mTestDevice.pullFile(fakeRemotePath);
        try {
            assertNotNull(res);
        } finally {
            FileUtil.deleteFile(res);
        }
    }

    /**
     * Test that {@link NativeDevice#pullFile(String)} returns null when failed to pull the file.
     */
    @Test
    public void testPullFile_returnNull() throws Exception {
        final String fakeRemotePath = "/test/";
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public boolean pullFile(String remoteFilePath, File localFile)
                    throws DeviceNotAvailableException {
                return false;
            }
        };
        File res = mTestDevice.pullFile(fakeRemotePath);
        try {
            assertNull(res);
        } finally {
            FileUtil.deleteFile(res);
        }
    }

    /**
     * Test that {@link NativeDevice#pullFileContents(String)} returns a string when succeed pulling
     * the file.
     */
    @Test
    public void testPullFileContents_returnFileSuccess() throws Exception {
        final String fakeRemotePath = "/test/";
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public boolean pullFile(String remoteFilePath, File localFile)
                    throws DeviceNotAvailableException {
                return true;
            }
        };
        String res = mTestDevice.pullFileContents(fakeRemotePath);
        assertNotNull(res);
    }

    /**
     * Test that {@link NativeDevice#pullFileContents(String)} returns null when failed to pull the
     * file.
     */
    @Test
    public void testPullFileContents_returnNull() throws Exception {
        final String fakeRemotePath = "/test/";
        mTestDevice = new TestableAndroidNativeDevice() {
            @Override
            public boolean pullFile(String remoteFilePath, File localFile)
                    throws DeviceNotAvailableException {
                return false;
            }
        };
        String res = mTestDevice.pullFileContents(fakeRemotePath);
        assertNull(res);
    }

    /**
     * Test that {@link NativeDevice#pushFile(File, String)} returns true when the push is
     * successful.
     */
    @Test
    public void testPushFile() throws Exception {
        final String fakeRemotePath = "/test/";
        SyncService s = Mockito.mock(SyncService.class);
        EasyMock.expect(mMockIDevice.getSyncService()).andReturn(s);
        EasyMock.replay(mMockIDevice);
        File tmpFile = FileUtil.createTempFile("push", ".test");
        try {
            boolean res = mTestDevice.pushFile(tmpFile, fakeRemotePath);
            EasyMock.verify(mMockIDevice);
            Mockito.verify(s)
                    .pushFile(
                            Mockito.eq(tmpFile.getAbsolutePath()),
                            Mockito.eq(fakeRemotePath),
                            Mockito.any(ISyncProgressMonitor.class));
            Mockito.verify(s).close();
            assertTrue(res);
        } finally {
            FileUtil.deleteFile(tmpFile);
        }
    }

    /**
     * Test that {@link NativeDevice#pushFile(File, String)} returns false when the push is
     * unsuccessful.
     */
    @Test
    public void testPushFile_fails() throws Exception {
        final String fakeRemotePath = "/test/";
        SyncService s = Mockito.mock(SyncService.class);
        EasyMock.expect(mMockIDevice.getSyncService()).andReturn(s);
        EasyMock.replay(mMockIDevice);
        File tmpFile = FileUtil.createTempFile("push", ".test");
        doThrow(new SyncException(SyncError.CANCELED))
                .when(s)
                .pushFile(
                        Mockito.eq(tmpFile.getAbsolutePath()),
                        Mockito.eq(fakeRemotePath),
                        Mockito.any(ISyncProgressMonitor.class));
        try {
            boolean res = mTestDevice.pushFile(tmpFile, fakeRemotePath);
            EasyMock.verify(mMockIDevice);
            Mockito.verify(s)
                    .pushFile(
                            Mockito.eq(tmpFile.getAbsolutePath()),
                            Mockito.eq(fakeRemotePath),
                            Mockito.any(ISyncProgressMonitor.class));
            Mockito.verify(s).close();
            assertFalse(res);
        } finally {
            FileUtil.deleteFile(tmpFile);
        }
    }

    /** Test get Process pid by process name */
    @Test
    public void testGetProcessPid() throws Exception {
        final String fakePid = "914";
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn(fakePid).when(spy).executeShellCommand("pidof system_server");
        EasyMock.replay(mMockIDevice);
        assertEquals(fakePid, spy.getProcessPid("system_server"));
        EasyMock.verify(mMockIDevice);
    }

    /** Test get Process pid by process name with adb shell return of extra new line */
    @Test
    public void testGetProcessPidWithNewLine() throws Exception {
        final String fakePid = "914";
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn(fakePid + "\n").when(spy).executeShellCommand("pidof system_server");
        EasyMock.replay(mMockIDevice);
        assertEquals(fakePid, spy.getProcessPid("system_server"));
        EasyMock.verify(mMockIDevice);
    }

    /** Test get Process pid return null with invalid shell command output */
    @Test
    public void testGetProcessPidInvalidOutput() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("invalid output").when(spy).executeShellCommand("pidof system_server");
        EasyMock.replay(mMockIDevice);
        assertNull(spy.getProcessPid("system_server"));
        EasyMock.verify(mMockIDevice);
    }

    /** Test get Process pid return null with shell command empty output */
    @Test
    public void testGetProcessPidEmptyOutput() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("").when(spy).executeShellCommand("pidof system_server");
        EasyMock.replay(mMockIDevice);
        assertNull(spy.getProcessPid("system_server"));
        EasyMock.verify(mMockIDevice);
    }

    /** Test get ProcessInfo by process name */
    @Test
    public void testGetProcessByName() throws Exception {
        final String fakePid = "914";
        final String fakeCreationTime = "1559091922";
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn(fakePid).when(spy).executeShellCommand("pidof system_server");
        doReturn("12:07:32").when(spy).executeShellCommand("ps -p " + fakePid + " -o stime=");
        doReturn(fakeCreationTime).when(spy).executeShellCommand("date -d\"12:07:32\" +%s");
        doReturn("system").when(spy).executeShellCommand("stat -c%U /proc/" + fakePid);
        EasyMock.replay(mMockIDevice);
        assertEquals(Integer.parseInt(fakePid), spy.getProcessByName("system_server").getPid());
        assertEquals(
                Long.parseLong(fakeCreationTime),
                spy.getProcessByName("system_server").getStartTime());
        EasyMock.verify(mMockIDevice);
    }

    /** Test get ProcessInfo by process name return null for invalid process */
    @Test
    public void testGetProcessByNameInvalidProcess() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("").when(spy).executeShellCommand("pidof system_server");
        EasyMock.replay(mMockIDevice);
        assertNull(spy.getProcessByName("system_server"));
        EasyMock.verify(mMockIDevice);
    }

    /** Test get ProcessInfo by process name return null for invalid process */
    @Test
    public void testGetProcessByNameInvalidStartTime() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("120").when(spy).executeShellCommand("pidof system_server");
        doReturn("").when(spy).executeShellCommand("ps -p 120 -o stime=");
        EasyMock.replay(mMockIDevice);
        assertNull(spy.getProcessByName("system_server"));
        EasyMock.verify(mMockIDevice);
    }

    @Test
    public void testGetIntProperty() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("123").when(spy).getProperty("ro.test.prop");
        EasyMock.replay(mMockIDevice);
        assertEquals(123, spy.getIntProperty("ro.test.prop", -1));
        EasyMock.verify(mMockIDevice);
    }

    @Test
    public void testGetIntPropertyNotAnIntegerPropertyReturnsDefaultValue() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("not-an-int").when(spy).getProperty("ro.test.prop");
        EasyMock.replay(mMockIDevice);
        assertEquals(-1, spy.getIntProperty("ro.test.prop", -1));
        EasyMock.verify(mMockIDevice);
    }

    @Test
    public void testGetIntPropertyUnknownPropertyReturnsDefaultValue() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn(null).when(spy).getProperty("ro.test.prop");
        EasyMock.replay(mMockIDevice);
        assertEquals(-1, spy.getIntProperty("ro.test.prop", -1));
        EasyMock.verify(mMockIDevice);
    }

    @Test
    public void testGetBooleanPropertyReturnsTrue() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("true").when(spy).getProperty("ro.test.prop");
        EasyMock.replay(mMockIDevice);
        assertTrue(spy.getBooleanProperty("ro.test.prop", false));
        EasyMock.verify(mMockIDevice);
    }

    @Test
    public void testGetBooleanPropertyReturnsFalse() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("no").when(spy).getProperty("ro.test.prop");
        EasyMock.replay(mMockIDevice);
        assertFalse(spy.getBooleanProperty("ro.test.prop", true));
        EasyMock.verify(mMockIDevice);
    }

    @Test
    public void testGetBooleanPropertyUnknownPropertyReturnsDefaultValue() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn(null).when(spy).getProperty("ro.test.prop");
        EasyMock.replay(mMockIDevice);
        assertTrue(spy.getBooleanProperty("ro.test.prop", true));
        EasyMock.verify(mMockIDevice);
    }

    @Test
    public void testGetBooleanPropertyInvalidValueReturnsDefaultValue() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("123").when(spy).getProperty("ro.test.prop");
        EasyMock.replay(mMockIDevice);
        assertTrue(spy.getBooleanProperty("ro.test.prop", true));
        EasyMock.verify(mMockIDevice);
    }

    @Test
    public void testGetProperty_noOutput() throws Exception {
        CommandResult res = new CommandResult(CommandStatus.SUCCESS);
        res.setStdout("\n");
        EasyMock.expect(
                        mMockRunUtil.runTimedCmd(
                                100,
                                (OutputStream) null,
                                null,
                                "adb",
                                "-s",
                                "serial",
                                "shell",
                                "getprop",
                                "test"))
                .andReturn(res);
        EasyMock.replay(mMockRunUtil, mMockIDevice);
        assertNull(mTestDevice.getProperty("test"));
        EasyMock.verify(mMockRunUtil, mMockIDevice);
    }

    /** Test get boot history */
    @Test
    public void testGetBootHistory() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn(
                        "kernel_panic,1556587278\n"
                                + "        reboot,,1556238008\n"
                                + "        reboot,,1556237796\n"
                                + "        reboot,,1556237725\n")
                .when(spy)
                .getProperty(DeviceProperties.BOOT_REASON_HISTORY);
        Map<Long, String> history = new LinkedHashMap<Long, String>();
        history.put(1556587278L, "kernel_panic");
        history.put(1556238008L, "reboot");
        history.put(1556237796L, "reboot");
        history.put(1556237725L, "reboot");
        EasyMock.replay(mMockIDevice);
        assertEquals(history, spy.getBootHistory());
        EasyMock.verify(mMockIDevice);
    }

    /** Test get empty boot history */
    @Test
    public void testGetBootHistoryEmpty() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("").when(spy).getProperty(DeviceProperties.BOOT_REASON_HISTORY);
        EasyMock.replay(mMockIDevice);
        assertTrue(spy.getBootHistory().isEmpty());
        EasyMock.verify(mMockIDevice);
    }

    /** Test get invalid boot history */
    @Test
    public void testGetBootHistoryInvalid() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("invalid output").when(spy).getProperty(DeviceProperties.BOOT_REASON_HISTORY);
        EasyMock.replay(mMockIDevice);
        assertTrue(spy.getBootHistory().isEmpty());
        EasyMock.verify(mMockIDevice);
    }

    /** Test get boot history since */
    @Test
    public void testGetBootHistorySince() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn(
                        "kernel_panic,1556587278\n"
                                + "        reboot,,1556238008\n"
                                + "        reboot,,1556237796\n"
                                + "        reboot,,1556237725\n")
                .when(spy)
                .getProperty(DeviceProperties.BOOT_REASON_HISTORY);
        Map<Long, String> history = new LinkedHashMap<Long, String>();
        history.put(1556587278L, "kernel_panic");
        EasyMock.replay(mMockIDevice);
        assertEquals(history, spy.getBootHistorySince(1556238009L, TimeUnit.SECONDS));
        EasyMock.verify(mMockIDevice);
    }

    /** Test {@link NativeDevice#getBootHistorySince(long, TimeUnit)} on an edge condition. */
    @Test
    public void testGetBootHistorySince_limit() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("reboot,1579678463\n" + "        reboot,,1579678339\n")
                .when(spy)
                .getProperty(DeviceProperties.BOOT_REASON_HISTORY);
        Map<Long, String> history = new LinkedHashMap<Long, String>();
        history.put(1579678463L, "reboot");
        EasyMock.replay(mMockIDevice);
        // For the same value we should expect it to be part of the reboot.
        assertEquals(history, spy.getBootHistorySince(1579678463, TimeUnit.SECONDS));
        EasyMock.verify(mMockIDevice);
    }

    /** Test get boot history since */
    @Test
    public void testGetBootHistorySinceInMillisecond() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn(
                        "kernel_panic,1556587278\n"
                                + "        reboot,,1556238008\n"
                                + "        reboot,,1556237796\n"
                                + "        reboot,,1556237725\n")
                .when(spy)
                .getProperty(DeviceProperties.BOOT_REASON_HISTORY);
        Map<Long, String> history = new LinkedHashMap<Long, String>();
        history.put(1556587278L, "kernel_panic");
        EasyMock.replay(mMockIDevice);
        assertEquals(history, spy.getBootHistorySince(1556238009000L, TimeUnit.MILLISECONDS));
        EasyMock.verify(mMockIDevice);
    }

    /** Test deviceSoftRestartedSince */
    @Test
    public void testDeviceSoftRestartedSince() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("914").when(spy).executeShellCommand("pidof system_server");
        doReturn("12:07:32").when(spy).executeShellCommand("ps -p 914 -o stime=");
        doReturn("1559091922").when(spy).executeShellCommand("date -d\"12:07:32\" +%s");
        doReturn("system").when(spy).executeShellCommand("stat -c%U /proc/914");
        doReturn(
                        "kernel_panic,1556587278\n"
                                + "        reboot,,1556238008\n"
                                + "        reboot,,1556237796\n"
                                + "        reboot,,1556237725\n")
                .when(spy)
                .getProperty(DeviceProperties.BOOT_REASON_HISTORY);
        EasyMock.replay(mMockIDevice);
        assertFalse(spy.deviceSoftRestartedSince(1559091923L, TimeUnit.SECONDS));
        assertFalse(spy.deviceSoftRestartedSince(1559091923000L, TimeUnit.MILLISECONDS));
        assertFalse(spy.deviceSoftRestartedSince(1559091922L, TimeUnit.SECONDS));
        assertFalse(spy.deviceSoftRestartedSince(1559091922000L, TimeUnit.MILLISECONDS));
        assertTrue(spy.deviceSoftRestartedSince(1559091920L, TimeUnit.SECONDS));
        assertTrue(spy.deviceSoftRestartedSince(1559091920000L, TimeUnit.MILLISECONDS));
        EasyMock.verify(mMockIDevice);
    }

    /** Test deviceSoftRestartedSince return true with system_server stopped */
    @Test
    public void testDeviceSoftRestartedSinceWithSystemServerStopped() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("").when(spy).executeShellCommand("pidof system_server");
        assertTrue(spy.deviceSoftRestartedSince(1559091922L, TimeUnit.SECONDS));
    }

    /** Test deviceSoftRestartedSince throw RuntimeException with abnormal reboot */
    @Test
    public void testDeviceSoftRestartedSinceWithAbnormalReboot() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("914").when(spy).executeShellCommand("pidof system_server");
        doReturn("12:07:32").when(spy).executeShellCommand("ps -p 914 -o stime=");
        doReturn("1559091999").when(spy).executeShellCommand("date -d\"12:07:32\" +%s");
        doReturn("system").when(spy).executeShellCommand("stat -c%U /proc/914");
        doReturn(
                        "kernel_panic,1559091933\n"
                                + "        reboot,,1556238008\n"
                                + "        reboot,,1556237796\n"
                                + "        reboot,,1556237725\n")
                .when(spy)
                .getProperty(DeviceProperties.BOOT_REASON_HISTORY);
        EasyMock.replay(mMockIDevice);
        try {
            spy.deviceSoftRestartedSince(1559091922L, TimeUnit.SECONDS);
        } catch (RuntimeException e) {
            //expected
            return;
        }
        fail("RuntimeException is expected");
    }

    /** Test deviceSoftRestartedSince return false with normal reboot */
    @Test
    public void testDeviceSoftRestartedSinceNotAfterNormalReboot() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("914").when(spy).executeShellCommand("pidof system_server");
        doReturn("12:07:32").when(spy).executeShellCommand("ps -p 914 -o stime=");
        doReturn("1559091939").when(spy).executeShellCommand("date -d\"12:07:32\" +%s");
        doReturn("system").when(spy).executeShellCommand("stat -c%U /proc/914");
        doReturn(
                        "reboot,1559091933\n"
                                + "        reboot,,1556238008\n"
                                + "        reboot,,1556237796\n"
                                + "        reboot,,1556237725\n")
                .when(spy)
                .getProperty(DeviceProperties.BOOT_REASON_HISTORY);
        EasyMock.replay(mMockIDevice);
        assertFalse(spy.deviceSoftRestartedSince(1559091921L, TimeUnit.SECONDS));
        EasyMock.verify(mMockIDevice);
    }

    /** Test deviceSoftRestartedSince return false with normal reboot */
    @Test
    public void testDeviceSoftRestartedSinceAfterNormalReboot() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("914").when(spy).executeShellCommand("pidof system_server");
        doReturn("12:07:32").when(spy).executeShellCommand("ps -p 914 -o stime=");
        doReturn("1559091992").when(spy).executeShellCommand("date -d\"12:07:32\" +%s");
        doReturn("system").when(spy).executeShellCommand("stat -c%U /proc/914");
        doReturn(
                        "reboot,1559091933\n"
                                + "        reboot,,1556238008\n"
                                + "        reboot,,1556237796\n"
                                + "        reboot,,1556237725\n")
                .when(spy)
                .getProperty(DeviceProperties.BOOT_REASON_HISTORY);
        EasyMock.replay(mMockIDevice);
        assertTrue(spy.deviceSoftRestartedSince(1559091921L, TimeUnit.SECONDS));
        EasyMock.verify(mMockIDevice);
    }

    /** Test deviceSoftRestarted given the previous system_server {@link ProcessInfo} */
    @Test
    public void testDeviceSoftRestarted() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        ProcessInfo prev1 = new ProcessInfo("system", 123, "system_server", 1559000000L);
        ProcessInfo prev2 = new ProcessInfo("system", 914, "system_server", 1559091922L);
        doReturn("914").when(spy).executeShellCommand("pidof system_server");
        doReturn("12:07:32").when(spy).executeShellCommand("ps -p 914 -o stime=");
        doReturn("1559091922").when(spy).executeShellCommand("date -d\"12:07:32\" +%s");
        doReturn("system").when(spy).executeShellCommand("stat -c%U /proc/914");
        doReturn(
                        "kernel_panic,1556587278\n"
                                + "        reboot,,1556238008\n"
                                + "        reboot,,1556237796\n"
                                + "        reboot,,1556237725\n")
                .when(spy)
                .getProperty(DeviceProperties.BOOT_REASON_HISTORY);
        EasyMock.replay(mMockIDevice);
        assertTrue(spy.deviceSoftRestarted(prev1));
        assertFalse(spy.deviceSoftRestarted(prev2));
        EasyMock.verify(mMockIDevice);
    }

    /** Test deviceSoftRestarted return true with system_server stopped */
    @Test
    public void testDeviceSoftRestartedWithSystemServerStopped() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("").when(spy).executeShellCommand("pidof system_server");
        assertTrue(
                spy.deviceSoftRestarted(
                        new ProcessInfo("system", 123, "system_server", 1559000000L)));
    }

    /** Test deviceSoftRestarted throw RuntimeException with abnormal reboot */
    @Test
    public void testDeviceSoftRestartedWithAbnormalReboot() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("914").when(spy).executeShellCommand("pidof system_server");
        doReturn("12:07:32").when(spy).executeShellCommand("ps -p 914 -o stime=");
        doReturn("1559091999").when(spy).executeShellCommand("date -d\"12:07:32\" +%s");
        doReturn("system").when(spy).executeShellCommand("stat -c%U /proc/914");
        doReturn(
                        "kernel_panic,1559091933\n"
                                + "        reboot,,1556238008\n"
                                + "        reboot,,1556237796\n"
                                + "        reboot,,1556237725\n")
                .when(spy)
                .getProperty(DeviceProperties.BOOT_REASON_HISTORY);
        EasyMock.replay(mMockIDevice);
        try {
            spy.deviceSoftRestarted(new ProcessInfo("system", 123, "system_server", 1559000000L));
        } catch (RuntimeException e) {
            //expected
            return;
        }
        fail("Abnormal reboot is detected, RuntimeException is expected");
    }

    /** Test ddeviceSoftRestarted return false with normal reboot */
    @Test
    public void testDeviceSoftRestartedNotAfterNormalReboot() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("914").doReturn("914").when(spy).executeShellCommand("pidof system_server");
        doReturn("12:07:32").when(spy).executeShellCommand("ps -p 914 -o stime=");
        doReturn("1559091935").when(spy).executeShellCommand("date -d\"12:07:32\" +%s");
        doReturn("system").when(spy).executeShellCommand("stat -c%U /proc/914");
        doReturn(
                        "reboot,,1559091933\n"
                                + "        reboot,,1556238008\n"
                                + "        reboot,,1556237796\n"
                                + "        reboot,,1556237725\n")
                .when(spy)
                .getProperty(DeviceProperties.BOOT_REASON_HISTORY);
        EasyMock.replay(mMockIDevice);
        assertFalse(
                spy.deviceSoftRestarted(
                        new ProcessInfo("system", 123, "system_server", 1559000000L)));
        EasyMock.verify(mMockIDevice);
    }

    /** Test deviceSoftRestarted return true if system_server restarted after normal reboot */
    @Test
    public void testDeviceSoftRestartedAfterNormalReboot() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn("914").doReturn("914").when(spy).executeShellCommand("pidof system_server");
        doReturn("12:07:32").when(spy).executeShellCommand("ps -p 914 -o stime=");
        doReturn("1559091995").when(spy).executeShellCommand("date -d\"12:07:32\" +%s");
        doReturn("system").when(spy).executeShellCommand("stat -c%U /proc/914");
        doReturn(
                        "reboot,,1559091933\n"
                                + "        reboot,,1556238008\n"
                                + "        reboot,,1556237796\n"
                                + "        reboot,,1556237725\n")
                .when(spy)
                .getProperty(DeviceProperties.BOOT_REASON_HISTORY);
        EasyMock.replay(mMockIDevice);
        assertTrue(
                spy.deviceSoftRestarted(
                        new ProcessInfo("system", 123, "system_server", 1559000000L)));
        EasyMock.verify(mMockIDevice);
    }

    /** Test validating valid MAC addresses */
    @Test
    public void testIsMacAddress() {
        assertTrue(mTestDevice.isMacAddress("00:00:00:00:00:00"));
        assertTrue(mTestDevice.isMacAddress("00:15:E9:2B:99:3C"));
        assertTrue(mTestDevice.isMacAddress("FF:FF:FF:FF:FF:FF"));
        assertTrue(mTestDevice.isMacAddress("58:a2:b5:7d:49:24"));
    }

    /** Test validating invalid MAC addresses */
    @Test
    public void testIsMacAddress_invalidInput() {
        assertFalse(mTestDevice.isMacAddress(""));
        assertFalse(mTestDevice.isMacAddress("00-15-E9-2B-99-3C")); // Invalid delimiter
    }

    /** Test querying a device MAC address */
    @Test
    public void testGetMacAddress() throws Exception {
        String address = "58:a2:b5:7d:49:24";
        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());
            }
        };
        mMockIDevice.executeShellCommand(EasyMock.anyObject(), EasyMock.anyObject());
        EasyMock.expectLastCall().andDelegateTo(device).anyTimes();
        EasyMock.replay(mMockIDevice);
        assertEquals(address, mTestDevice.getMacAddress());
        EasyMock.verify(mMockIDevice);
    }

    /** Test querying a device MAC address when the device is in fastboot */
    @Test
    public void testGetMacAddress_fastboot() throws Exception {
        mTestDevice.setDeviceState(TestDeviceState.FASTBOOT);
        // Will fail if executeShellCommand is called. Which it should not.
        assertNull(mTestDevice.getMacAddress());
    }

    /** Test querying a device MAC address but failing to do so */
    @Test
    public void testGetMacAddress_failure() throws Exception {
        IDevice device = new StubDevice(MOCK_DEVICE_SERIAL) {
            @Override
            public void executeShellCommand(String command, IShellOutputReceiver receiver)
                    throws TimeoutException, AdbCommandRejectedException,
                    ShellCommandUnresponsiveException, IOException {
                throw new IOException();
            }
        };
        mMockIDevice.executeShellCommand(EasyMock.anyObject(), EasyMock.anyObject());
        EasyMock.expectLastCall().andDelegateTo(device).anyTimes();
        EasyMock.replay(mMockIDevice);
        assertNull(mTestDevice.getMacAddress());
        EasyMock.verify(mMockIDevice);
    }

    /** Test querying a device MAC address for a stub device */
    @Test
    public void testGetMacAddress_stubDevice() throws Exception {
        String address = "58:a2:b5:7d:49:24";
        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
                    public void recoverDevice() throws DeviceNotAvailableException {
                        // ignore
                    }

                    @Override
                    public IDevice getIDevice() {
                        return device;
                    }

                    @Override
                    IWifiHelper createWifiHelper() {
                        return mMockWifi;
                    }
                };
        mTestDevice.setIDevice(device);
        assertNull(mTestDevice.getMacAddress());
    }

    /** Test if valid shell output returns correct memory size. */
    @Test
    public void testGetTotalMemory() {
        final long expectSize = 1902936064;
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public String executeShellCommand(String command)
                            throws DeviceNotAvailableException {
                        return "MemTotal:        1858336 kB";
                    }
                };
        assertEquals(expectSize, mTestDevice.getTotalMemory());
    }

    /** Test if empty shell output returns -1. */
    @Test
    public void testGetTotalMemory_emptyString() {
        final long expectSize = -1;
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public String executeShellCommand(String command)
                            throws DeviceNotAvailableException {
                        return "";
                    }
                };
        assertEquals(expectSize, mTestDevice.getTotalMemory());
    }

    /** Test if unexpected shell output returns -1. */
    @Test
    public void testGetTotalMemory_unexpectedFormat() {
        final long expectSize = -1;
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public String executeShellCommand(String command)
                            throws DeviceNotAvailableException {
                        return "1858336 kB";
                    }
                };
        assertEquals(expectSize, mTestDevice.getTotalMemory());
    }

    /** Test if catching exception returns -1. */
    @Test
    public void testGetTotalMemory_exception() {
        final long expectSize = -1;
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public String executeShellCommand(String command)
                            throws DeviceNotAvailableException {
                        throw new DeviceNotAvailableException("test", "serial");
                    }
                };
        assertEquals(expectSize, mTestDevice.getTotalMemory());
    }

    /**
     * Test that when a {@link NativeDevice#getLogcatSince(long)} is requested a matching logcat
     * command is generated.
     */
    @Test
    public void testGetLogcatSince() throws Exception {
        long date = 1512990942000L; // 2017-12-11 03:15:42.015
        setGetPropertyExpectation("ro.build.version.sdk", "23");

        SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss.mmm");
        String dateFormatted = format.format(new Date(date));

        mMockIDevice.executeShellCommand(
                EasyMock.eq(String.format("logcat -v threadtime -t '%s'", dateFormatted)),
                EasyMock.anyObject());
        EasyMock.replay(mMockIDevice);
        InputStreamSource res = mTestDevice.getLogcatSince(date);
        StreamUtil.close(res);
        EasyMock.verify(mMockIDevice);
    }

    @Test
    public void testGetProductVariant() throws Exception {
        setGetPropertyExpectation(DeviceProperties.VARIANT, "variant");
        EasyMock.replay(mMockIDevice);
        assertEquals("variant", mTestDevice.getProductVariant());
        EasyMock.verify(mMockIDevice);
    }

    @Test
    public void testGetProductVariant_legacyOmr1() throws Exception {
        TestableAndroidNativeDevice testDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    protected String internalGetProperty(
                            String propName, String fastbootVar, String description)
                            throws DeviceNotAvailableException, UnsupportedOperationException {
                        if (DeviceProperties.VARIANT_LEGACY_O_MR1.equals(propName)) {
                            return "legacy_omr1";
                        }
                        return null;
                    }
                };

        assertEquals("legacy_omr1", testDevice.getProductVariant());
    }

    @Test
    public void testGetProductVariant_legacy() throws Exception {
        TestableAndroidNativeDevice testDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    protected String internalGetProperty(
                            String propName, String fastbootVar, String description)
                            throws DeviceNotAvailableException, UnsupportedOperationException {
                        if (DeviceProperties.VARIANT_LEGACY_LESS_EQUAL_O.equals(propName)) {
                            return "legacy";
                        }
                        return null;
                    }
                };

        assertEquals("legacy", testDevice.getProductVariant());
    }

    /** Test when {@link NativeDevice#executeShellV2Command(String)} returns a success. */
    @Test
    public void testExecuteShellV2Command() throws Exception {
        OutputStream stdout = null, stderr = null;
        CommandResult res = new CommandResult();
        res.setStatus(CommandStatus.SUCCESS);
        EasyMock.expect(
                        mMockRunUtil.runTimedCmd(
                                100, stdout, stderr, "adb", "-s", "serial", "shell", "some",
                                "command"))
                .andReturn(res);
        EasyMock.replay(mMockRunUtil, mMockIDevice);
        assertNotNull(mTestDevice.executeShellV2Command("some command"));
        EasyMock.verify(mMockRunUtil, mMockIDevice);
    }

    /**
     * Test when {@link NativeDevice#executeShellV2Command(String, long, TimeUnit, int)} fails and
     * repeat because of a timeout.
     */
    @Test
    public void testExecuteShellV2Command_timeout() throws Exception {
        OutputStream stdout = null, stderr = null;
        CommandResult res = new CommandResult();
        res.setStatus(CommandStatus.TIMED_OUT);
        res.setStderr("timed out");
        EasyMock.expect(
                        mMockRunUtil.runTimedCmd(
                                200L, stdout, stderr, "adb", "-s", "serial", "shell", "some",
                                "command"))
                .andReturn(res)
                .times(2);
        EasyMock.replay(mMockRunUtil, mMockIDevice);
        try {
            mTestDevice.executeShellV2Command("some command", 200L, TimeUnit.MILLISECONDS, 1);
            fail("Should have thrown an exception.");
        } catch (DeviceUnresponsiveException e) {
            // expected
        }
        EasyMock.verify(mMockRunUtil, mMockIDevice);
    }

    /**
     * Test when {@link NativeDevice#executeShellV2Command(String, long, TimeUnit, int)} fails and
     * output.
     */
    @Test
    public void testExecuteShellV2Command_fail() throws Exception {
        OutputStream stdout = null, stderr = null;
        CommandResult res = new CommandResult();
        res.setStatus(CommandStatus.FAILED);
        res.setStderr("timed out");
        EasyMock.expect(
                        mMockRunUtil.runTimedCmd(
                                200L, stdout, stderr, "adb", "-s", "serial", "shell", "some",
                                "command"))
                .andReturn(res)
                .times(1);
        EasyMock.replay(mMockRunUtil, mMockIDevice);
        CommandResult result =
                mTestDevice.executeShellV2Command("some command", 200L, TimeUnit.MILLISECONDS, 1);
        assertNotNull(result);
        // The final result is what RunUtil returned, so it contains full status information.
        assertSame(res, result);
        EasyMock.verify(mMockRunUtil, mMockIDevice);
    }

    /** Unit test for {@link INativeDevice#setProperty(String, String)}. */
    @Test
    public void testSetProperty() throws DeviceNotAvailableException {
        OutputStream stdout = null, stderr = null;
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public boolean isAdbRoot() throws DeviceNotAvailableException {
                        return true;
                    }
                };
        CommandResult res = new CommandResult();
        res.setStatus(CommandStatus.SUCCESS);
        EasyMock.expect(
                        mMockRunUtil.runTimedCmd(
                                120000,
                                stdout,
                                stderr,
                                "adb",
                                "-s",
                                "serial",
                                "shell",
                                "setprop test 'value'"))
                .andReturn(res);
        EasyMock.replay(mMockRunUtil, mMockIDevice);
        assertTrue(mTestDevice.setProperty("test", "value"));
        EasyMock.verify(mMockRunUtil, mMockIDevice);
    }

    /**
     * Verifies that {@link INativeDevice#isExecutable(String)} recognizes regular executable file
     *
     * @throws Exception
     */
    @Test
    public void testIsDeviceFileExecutable_executable_rwx() throws Exception {
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public String executeShellCommand(String command)
                            throws DeviceNotAvailableException {
                        return "-rwxr-xr-x 1 root shell 42824 2009-01-01 00:00 /system/bin/ping";
                    }
                };
        assertTrue(mTestDevice.isExecutable("/system/bin/ping"));
    }

    /**
     * Verifies that {@link INativeDevice#isExecutable(String)} recognizes symlink'd executable file
     *
     * @throws Exception
     */
    @Test
    public void testIsDeviceFileExecutable_executable_lrwx() throws Exception {
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public String executeShellCommand(String command)
                            throws DeviceNotAvailableException {
                        return "lrwxr-xr-x 1 root shell 7 2009-01-01 00:00 /system/bin/start ->"
                                + " toolbox";
                    }
                };
        assertTrue(mTestDevice.isExecutable("/system/bin/start"));
    }

    /**
     * Verifies that {@link INativeDevice#isExecutable(String)} recognizes non-executable file
     *
     * @throws Exception
     */
    @Test
    public void testIsDeviceFileExecutable_notExecutable() throws Exception {
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public String executeShellCommand(String command)
                            throws DeviceNotAvailableException {
                        return "-rw-r--r-- 1 root root 5020 2009-01-01 00:00 /system/build.prop";
                    }
                };
        assertFalse(mTestDevice.isExecutable("/system/build.prop"));
    }

    /**
     * Verifies that {@link INativeDevice#isExecutable(String)} recognizes a directory listing
     *
     * @throws Exception
     */
    @Test
    public void testIsDeviceFileExecutable_directory() throws Exception {
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public String executeShellCommand(String command)
                            throws DeviceNotAvailableException {
                        return "total 416\n"
                                + "drwxr-xr-x 74 root root    4096 2009-01-01 00:00 app\n"
                                + "drwxr-xr-x  3 root shell   8192 2009-01-01 00:00 bin\n"
                                + "-rw-r--r--  1 root root    5020 2009-01-01 00:00"
                                + " build.prop\n"
                                + "drwxr-xr-x 15 root root    4096 2009-01-01 00:00 etc\n"
                                + "drwxr-xr-x  2 root root    4096 2009-01-01 00:00 fake-libs\n"
                                + "drwxr-xr-x  2 root root    8192 2009-01-01 00:00 fonts\n"
                                + "drwxr-xr-x  4 root root    4096 2009-01-01 00:00 framework\n"
                                + "drwxr-xr-x  6 root root    8192 2009-01-01 00:00 lib\n"
                                + "drwx------  2 root root    4096 1970-01-01 00:00"
                                + " lost+found\n"
                                + "drwxr-xr-x  3 root root    4096 2009-01-01 00:00 media\n"
                                + "drwxr-xr-x 68 root root    4096 2009-01-01 00:00 priv-app\n"
                                + "-rw-r--r--  1 root root  137093 2009-01-01 00:00"
                                + " recovery-from-boot.p\n"
                                + "drwxr-xr-x  9 root root    4096 2009-01-01 00:00 usr\n"
                                + "drwxr-xr-x  8 root shell   4096 2009-01-01 00:00 vendor\n"
                                + "drwxr-xr-x  2 root shell   4096 2009-01-01 00:00 xbin\n";
                    }
                };
        assertFalse(mTestDevice.isExecutable("/system"));
    }

    /** Test {@link NativeDevice#getTombstones()}. */
    @Test
    public void testGetTombstones_notRoot() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn(false).when(spy).isAdbRoot();

        EasyMock.replay(mMockIDevice);
        List<File> result = spy.getTombstones();
        assertEquals(0, result.size());
        EasyMock.verify(mMockIDevice);
    }

    /** Test {@link NativeDevice#getTombstones()}. */
    @Test
    public void testGetTombstones() throws Exception {
        TestableAndroidNativeDevice spy = Mockito.spy(mTestDevice);
        doReturn(true).when(spy).isAdbRoot();

        String[] tombs = new String[] {"tomb1", "tomb2"};
        doReturn(tombs).when(spy).getChildren("/data/tombstones/");

        doReturn(new File("tomb1_test")).when(spy).pullFile("/data/tombstones/tomb1");
        doReturn(new File("tomb2_test")).when(spy).pullFile("/data/tombstones/tomb2");

        EasyMock.replay(mMockIDevice);
        List<File> result = spy.getTombstones();
        assertEquals(2, result.size());
        EasyMock.verify(mMockIDevice);
    }

    /** Test {@link NativeDevice#getLaunchApiLevel()} with ro.product.first_api_level being set. */
    @Test
    public void testGetLaunchApiLevel_w_first_api() throws DeviceNotAvailableException {
        setGetPropertyExpectation(DeviceProperties.FIRST_API_LEVEL, "23");
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public int getApiLevel() throws DeviceNotAvailableException {
                        return 29;
                    }
                };
        EasyMock.replay(mMockIDevice);
        assertEquals(23, mTestDevice.getLaunchApiLevel());
        EasyMock.verify(mMockIDevice);
    }

    /**
     * Test {@link NativeDevice#getLaunchApiLevel()} without ro.product.first_api_level being set.
     */
    @Test
    public void testGetLaunchApiLevel_wo_first_api() throws DeviceNotAvailableException {
        setGetPropertyExpectation(DeviceProperties.FIRST_API_LEVEL, null);
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public int getApiLevel() throws DeviceNotAvailableException {
                        return 29;
                    }
                };
        EasyMock.replay(mMockIDevice);
        assertEquals(29, mTestDevice.getLaunchApiLevel());
        EasyMock.verify(mMockIDevice);
    }

    /** Test {@link NativeDevice#getLaunchApiLevel()} with NumberFormatException be asserted. */
    @Test
    public void testGetLaunchApiLevel_w_exception() throws DeviceNotAvailableException {
        setGetPropertyExpectation(DeviceProperties.FIRST_API_LEVEL, "R");
        mTestDevice =
                new TestableAndroidNativeDevice() {
                    @Override
                    public int getApiLevel() throws DeviceNotAvailableException {
                        return 29;
                    }
                };
        EasyMock.replay(mMockIDevice);
        assertEquals(29, mTestDevice.getLaunchApiLevel());
        EasyMock.verify(mMockIDevice);
    }

    private void setGetPropertyExpectation(String property, String value) {
        CommandResult stubResult = new CommandResult(CommandStatus.SUCCESS);
        stubResult.setStdout(value);
        EasyMock.expect(
                        mMockRunUtil.runTimedCmd(
                                EasyMock.anyLong(),
                                (OutputStream) EasyMock.isNull(),
                                EasyMock.isNull(),
                                EasyMock.eq("adb"),
                                EasyMock.eq("-s"),
                                EasyMock.eq("serial"),
                                EasyMock.eq("shell"),
                                EasyMock.eq("getprop"),
                                EasyMock.eq(property)))
                .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);
    }
}
