1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.tradefed.device; 17 18 import static org.mockito.Mockito.doThrow; 19 20 import com.android.ddmlib.AdbCommandRejectedException; 21 import com.android.ddmlib.FileListingService.FileEntry; 22 import com.android.ddmlib.IDevice; 23 import com.android.ddmlib.IDevice.DeviceState; 24 import com.android.ddmlib.IShellOutputReceiver; 25 import com.android.ddmlib.ShellCommandUnresponsiveException; 26 import com.android.ddmlib.SyncException; 27 import com.android.ddmlib.SyncException.SyncError; 28 import com.android.ddmlib.SyncService; 29 import com.android.ddmlib.SyncService.ISyncProgressMonitor; 30 import com.android.ddmlib.TimeoutException; 31 import com.android.tradefed.build.IBuildInfo; 32 import com.android.tradefed.command.remote.DeviceDescriptor; 33 import com.android.tradefed.config.ConfigurationException; 34 import com.android.tradefed.config.OptionSetter; 35 import com.android.tradefed.log.ITestLogger; 36 import com.android.tradefed.log.LogUtil.CLog; 37 import com.android.tradefed.result.ByteArrayInputStreamSource; 38 import com.android.tradefed.result.FileInputStreamSource; 39 import com.android.tradefed.result.InputStreamSource; 40 import com.android.tradefed.result.LogDataType; 41 import com.android.tradefed.util.Bugreport; 42 import com.android.tradefed.util.CommandResult; 43 import com.android.tradefed.util.CommandStatus; 44 import com.android.tradefed.util.FileUtil; 45 import com.android.tradefed.util.IRunUtil; 46 import com.android.tradefed.util.StreamUtil; 47 48 import com.google.common.util.concurrent.SettableFuture; 49 50 import junit.framework.TestCase; 51 52 import org.easymock.EasyMock; 53 import org.mockito.Mockito; 54 55 import java.io.File; 56 import java.io.IOException; 57 import java.time.Clock; 58 import java.util.ArrayList; 59 import java.util.Arrays; 60 import java.util.Collection; 61 import java.util.Date; 62 import java.util.HashMap; 63 import java.util.List; 64 import java.util.Map; 65 import java.util.concurrent.TimeUnit; 66 67 /** 68 * Unit tests for {@link NativeDevice}. 69 */ 70 public class NativeDeviceTest extends TestCase { 71 72 private static final String MOCK_DEVICE_SERIAL = "serial"; 73 private static final String FAKE_NETWORK_SSID = "FakeNet"; 74 private static final String FAKE_NETWORK_PASSWORD ="FakePass"; 75 76 private IDevice mMockIDevice; 77 private TestableAndroidNativeDevice mTestDevice; 78 private IDeviceRecovery mMockRecovery; 79 private IDeviceStateMonitor mMockStateMonitor; 80 private IRunUtil mMockRunUtil; 81 private IWifiHelper mMockWifi; 82 private IDeviceMonitor mMockDvcMonitor; 83 84 /** 85 * A {@link TestDevice} that is suitable for running tests against 86 */ 87 private class TestableAndroidNativeDevice extends NativeDevice { 88 89 public boolean wasCalled = false; 90 91 public TestableAndroidNativeDevice() { 92 super(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 93 } 94 95 @Override 96 public void postBootSetup() { 97 // too annoying to mock out postBootSetup actions everyone, so do nothing 98 } 99 100 @Override 101 protected IRunUtil getRunUtil() { 102 return mMockRunUtil; 103 } 104 } 105 106 /** 107 * {@inheritDoc} 108 */ 109 @Override 110 protected void setUp() throws Exception { 111 super.setUp(); 112 mMockIDevice = EasyMock.createMock(IDevice.class); 113 EasyMock.expect(mMockIDevice.getSerialNumber()).andReturn(MOCK_DEVICE_SERIAL).anyTimes(); 114 mMockRecovery = EasyMock.createMock(IDeviceRecovery.class); 115 mMockStateMonitor = EasyMock.createMock(IDeviceStateMonitor.class); 116 mMockDvcMonitor = EasyMock.createMock(IDeviceMonitor.class); 117 mMockRunUtil = EasyMock.createMock(IRunUtil.class); 118 mMockWifi = EasyMock.createMock(IWifiHelper.class); 119 mMockWifi.cleanUp(); 120 EasyMock.expectLastCall().anyTimes(); 121 122 // A TestDevice with a no-op recoverDevice() implementation 123 mTestDevice = new TestableAndroidNativeDevice() { 124 @Override 125 public void recoverDevice() throws DeviceNotAvailableException { 126 // ignore 127 } 128 129 @Override 130 public IDevice getIDevice() { 131 return mMockIDevice; 132 } 133 134 @Override 135 IWifiHelper createWifiHelper() { 136 return mMockWifi; 137 } 138 }; 139 mTestDevice.setRecovery(mMockRecovery); 140 mTestDevice.setCommandTimeout(100); 141 mTestDevice.setLogStartDelay(-1); 142 } 143 144 /** 145 * Test return exception for package installation 146 * {@link NativeDevice#installPackage(File, boolean, String...)}. 147 */ 148 public void testInstallPackages_exception() { 149 try { 150 mTestDevice.installPackage(new File(""), false); 151 } catch (UnsupportedOperationException onse) { 152 return; 153 } catch (DeviceNotAvailableException e) { 154 fail("installPackage should have thrown an Unsupported exception, not dnae"); 155 } 156 fail("installPackage should have thrown an exception"); 157 } 158 159 /** 160 * Test return exception for package installation 161 * {@link NativeDevice#uninstallPackage(String)}. 162 */ 163 public void testUninstallPackages_exception() { 164 try { 165 mTestDevice.uninstallPackage(""); 166 } catch (UnsupportedOperationException onse) { 167 return; 168 } catch (DeviceNotAvailableException e) { 169 fail("uninstallPackage should have thrown an Unsupported exception, not dnae"); 170 } 171 fail("uninstallPackageForUser should have thrown an exception"); 172 } 173 174 /** 175 * Test return exception for package installation 176 * {@link NativeDevice#installPackage(File, boolean, boolean, String...)}. 177 */ 178 public void testInstallPackagesBool_exception() { 179 try { 180 mTestDevice.installPackage(new File(""), false, false); 181 } catch (UnsupportedOperationException onse) { 182 return; 183 } catch (DeviceNotAvailableException e) { 184 fail("installPackage should have thrown an Unsupported exception, not dnae"); 185 } 186 fail("installPackage should have thrown an exception"); 187 } 188 189 /** 190 * Test return exception for package installation 191 * {@link NativeDevice#installPackageForUser(File, boolean, int, String...)}. 192 */ 193 public void testInstallPackagesForUser_exception() { 194 try { 195 mTestDevice.installPackageForUser(new File(""), false, 0); 196 } catch (UnsupportedOperationException onse) { 197 return; 198 } catch (DeviceNotAvailableException e) { 199 fail("installPackageForUser should have thrown an Unsupported exception, not dnae"); 200 } 201 fail("installPackageForUser should have thrown an exception"); 202 } 203 204 /** 205 * Test return exception for package installation 206 * {@link NativeDevice#installPackageForUser(File, boolean, boolean, int, String...)}. 207 */ 208 public void testInstallPackagesForUserWithPermission_exception() { 209 try { 210 mTestDevice.installPackageForUser(new File(""), false, false, 0); 211 } catch (UnsupportedOperationException onse) { 212 return; 213 } catch (DeviceNotAvailableException e) { 214 fail("installPackageForUser should have thrown an Unsupported exception, not dnae"); 215 } 216 fail("installPackageForUser should have thrown an exception"); 217 } 218 219 /** 220 * Unit test for {@link NativeDevice#getInstalledPackageNames()}. 221 */ 222 public void testGetInstalledPackageNames_exception() throws Exception { 223 try { 224 mTestDevice.getInstalledPackageNames(); 225 } catch (UnsupportedOperationException onse) { 226 return; 227 } 228 fail("getInstalledPackageNames should have thrown an exception"); 229 } 230 231 /** 232 * Unit test for {@link NativeDevice#getScreenshot()}. 233 */ 234 public void testGetScreenshot_exception() throws Exception { 235 try { 236 mTestDevice.getScreenshot(); 237 } catch (UnsupportedOperationException onse) { 238 return; 239 } 240 fail("getScreenshot should have thrown an exception"); 241 } 242 243 /** 244 * Unit test for {@link NativeDevice#pushDir(File, String)}. 245 */ 246 public void testPushDir_notADir() throws Exception { 247 assertFalse(mTestDevice.pushDir(new File(""), "")); 248 } 249 250 /** 251 * Unit test for {@link NativeDevice#pushDir(File, String)}. 252 */ 253 public void testPushDir_childFile() throws Exception { 254 mTestDevice = new TestableAndroidNativeDevice() { 255 @Override 256 public boolean pushFile(File localFile, String remoteFilePath) 257 throws DeviceNotAvailableException { 258 return true; 259 } 260 }; 261 File testDir = FileUtil.createTempDir("pushDirTest"); 262 FileUtil.createTempFile("test1", ".txt", testDir); 263 assertTrue(mTestDevice.pushDir(testDir, "")); 264 FileUtil.recursiveDelete(testDir); 265 } 266 267 /** 268 * Unit test for {@link NativeDevice#pushDir(File, String)}. 269 */ 270 public void testPushDir_childDir() throws Exception { 271 mTestDevice = new TestableAndroidNativeDevice() { 272 @Override 273 public String executeShellCommand(String cmd) throws DeviceNotAvailableException { 274 return ""; 275 } 276 @Override 277 public boolean pushFile(File localFile, String remoteFilePath) 278 throws DeviceNotAvailableException { 279 return false; 280 } 281 }; 282 File testDir = FileUtil.createTempDir("pushDirTest"); 283 File subDir = FileUtil.createTempDir("testSubDir", testDir); 284 FileUtil.createTempDir("test1", subDir); 285 assertTrue(mTestDevice.pushDir(testDir, "")); 286 FileUtil.recursiveDelete(testDir); 287 } 288 289 /** Test {@link NativeDevice#pullDir(String, File)} when the remote directory is empty. */ 290 public void testPullDir_nothingToDo() throws Exception { 291 final IFileEntry fakeEntry = EasyMock.createMock(IFileEntry.class); 292 mTestDevice = 293 new TestableAndroidNativeDevice() { 294 @Override 295 public IFileEntry getFileEntry(FileEntry path) 296 throws DeviceNotAvailableException { 297 return fakeEntry; 298 } 299 300 @Override 301 public String executeShellCommand(String command) 302 throws DeviceNotAvailableException { 303 return "drwxr-xr-x root root somedirectory"; 304 } 305 }; 306 File dir = FileUtil.createTempDir("tf-test"); 307 Collection<IFileEntry> childrens = new ArrayList<>(); 308 EasyMock.expect(fakeEntry.getChildren(false)).andReturn(childrens); 309 // Empty list of childen 310 EasyMock.replay(fakeEntry); 311 try { 312 boolean res = mTestDevice.pullDir("/sdcard/screenshots/", dir); 313 assertTrue(res); 314 assertTrue(dir.list().length == 0); 315 } finally { 316 FileUtil.recursiveDelete(dir); 317 } 318 EasyMock.verify(fakeEntry); 319 } 320 321 /** 322 * Test {@link NativeDevice#pullDir(String, File)} when the remote directory has a file and a 323 * directory. 324 */ 325 public void testPullDir() throws Exception { 326 final IFileEntry fakeEntry = EasyMock.createMock(IFileEntry.class); 327 final IFileEntry fakeDir = EasyMock.createMock(IFileEntry.class); 328 mTestDevice = 329 new TestableAndroidNativeDevice() { 330 private boolean mFirstCall = true; 331 332 @Override 333 public IFileEntry getFileEntry(FileEntry path) 334 throws DeviceNotAvailableException { 335 if (mFirstCall) { 336 mFirstCall = false; 337 return fakeEntry; 338 } else { 339 return fakeDir; 340 } 341 } 342 343 @Override 344 public String executeShellCommand(String command) 345 throws DeviceNotAvailableException { 346 return "drwxr-xr-x root root somedirectory"; 347 } 348 349 @Override 350 public boolean pullFile(String remoteFilePath, File localFile) 351 throws DeviceNotAvailableException { 352 try { 353 // Just touch the file to make it appear. 354 localFile.createNewFile(); 355 } catch (IOException e) { 356 throw new RuntimeException(e); 357 } 358 return true; 359 } 360 }; 361 File dir = FileUtil.createTempDir("tf-test"); 362 Collection<IFileEntry> children = new ArrayList<>(); 363 IFileEntry fakeFile = EasyMock.createMock(IFileEntry.class); 364 children.add(fakeFile); 365 EasyMock.expect(fakeFile.isDirectory()).andReturn(false); 366 EasyMock.expect(fakeFile.getName()).andReturn("fakeFile"); 367 EasyMock.expect(fakeFile.getFullPath()).andReturn("/sdcard/screenshots/fakeFile"); 368 369 children.add(fakeDir); 370 EasyMock.expect(fakeDir.isDirectory()).andReturn(true); 371 EasyMock.expect(fakeDir.getName()).andReturn("fakeDir"); 372 EasyMock.expect(fakeDir.getFullPath()).andReturn("/sdcard/screenshots/fakeDir"); 373 // #pullDir is being called on dir fakeDir to pull everything recursively. 374 Collection<IFileEntry> fakeDirChildren = new ArrayList<>(); 375 EasyMock.expect(fakeDir.getChildren(false)).andReturn(fakeDirChildren); 376 EasyMock.expect(fakeEntry.getChildren(false)).andReturn(children); 377 378 EasyMock.replay(fakeEntry, fakeFile, fakeDir); 379 try { 380 boolean res = mTestDevice.pullDir("/sdcard/screenshots/", dir); 381 assertTrue(res); 382 assertEquals(2, dir.list().length); 383 assertTrue(Arrays.asList(dir.list()).contains("fakeFile")); 384 assertTrue(Arrays.asList(dir.list()).contains("fakeDir")); 385 } finally { 386 FileUtil.recursiveDelete(dir); 387 } 388 EasyMock.verify(fakeEntry, fakeFile, fakeDir); 389 } 390 391 /** Test pulling a directory when one of the pull fails. */ 392 public void testPullDir_pullFail() throws Exception { 393 final IFileEntry fakeEntry = EasyMock.createMock(IFileEntry.class); 394 final IFileEntry fakeDir = EasyMock.createMock(IFileEntry.class); 395 mTestDevice = 396 new TestableAndroidNativeDevice() { 397 private boolean mFirstCall = true; 398 private boolean mFirstPull = true; 399 400 @Override 401 public IFileEntry getFileEntry(FileEntry path) 402 throws DeviceNotAvailableException { 403 if (mFirstCall) { 404 mFirstCall = false; 405 return fakeEntry; 406 } else { 407 return fakeDir; 408 } 409 } 410 411 @Override 412 public String executeShellCommand(String command) 413 throws DeviceNotAvailableException { 414 return "drwxr-xr-x root root somedirectory"; 415 } 416 417 @Override 418 public boolean pullFile(String remoteFilePath, File localFile) 419 throws DeviceNotAvailableException { 420 if (mFirstPull) { 421 mFirstPull = false; 422 try { 423 // Just touch the file to make it appear. 424 localFile.createNewFile(); 425 } catch (IOException e) { 426 throw new RuntimeException(e); 427 } 428 return true; 429 } else { 430 return false; 431 } 432 } 433 }; 434 File dir = FileUtil.createTempDir("tf-test"); 435 Collection<IFileEntry> children = new ArrayList<>(); 436 IFileEntry fakeFile = EasyMock.createMock(IFileEntry.class); 437 children.add(fakeFile); 438 EasyMock.expect(fakeFile.isDirectory()).andReturn(false); 439 EasyMock.expect(fakeFile.getName()).andReturn("fakeFile"); 440 EasyMock.expect(fakeFile.getFullPath()).andReturn("/sdcard/screenshots/fakeFile"); 441 442 children.add(fakeDir); 443 EasyMock.expect(fakeDir.isDirectory()).andReturn(true); 444 EasyMock.expect(fakeDir.getName()).andReturn("fakeDir"); 445 EasyMock.expect(fakeDir.getFullPath()).andReturn("/sdcard/screenshots/fakeDir"); 446 // #pullDir is being called on dir fakeDir to pull everything recursively. 447 Collection<IFileEntry> fakeDirChildren = new ArrayList<>(); 448 IFileEntry secondLevelChildren = EasyMock.createMock(IFileEntry.class); 449 fakeDirChildren.add(secondLevelChildren); 450 EasyMock.expect(fakeDir.getChildren(false)).andReturn(fakeDirChildren); 451 EasyMock.expect(fakeEntry.getChildren(false)).andReturn(children); 452 453 EasyMock.expect(secondLevelChildren.isDirectory()).andReturn(false); 454 EasyMock.expect(secondLevelChildren.getName()).andReturn("secondLevelChildren"); 455 EasyMock.expect(secondLevelChildren.getFullPath()) 456 .andReturn("/sdcard/screenshots/fakeDir/secondLevelChildren"); 457 458 EasyMock.replay(fakeEntry, fakeFile, fakeDir, secondLevelChildren); 459 try { 460 boolean res = mTestDevice.pullDir("/sdcard/screenshots/", dir); 461 // If one of the pull fails, the full command is considered failed. 462 assertFalse(res); 463 assertEquals(2, dir.list().length); 464 assertTrue(Arrays.asList(dir.list()).contains("fakeFile")); 465 // The subdir was created 466 assertTrue(Arrays.asList(dir.list()).contains("fakeDir")); 467 // The last file failed to pull, so the dir is empty. 468 assertEquals(0, new File(dir, "fakeDir").list().length); 469 } finally { 470 FileUtil.recursiveDelete(dir); 471 } 472 EasyMock.verify(fakeEntry, fakeFile, fakeDir, secondLevelChildren); 473 } 474 475 /** 476 * Test that if the requested path is not a directory on the device side, we just fail directly. 477 */ 478 public void testPullDir_invalidPath() throws Exception { 479 mTestDevice = 480 new TestableAndroidNativeDevice() { 481 @Override 482 public String executeShellCommand(String command) 483 throws DeviceNotAvailableException { 484 return "-rwxr-xr-x root root somefile"; 485 } 486 }; 487 File dir = FileUtil.createTempDir("tf-test"); 488 try { 489 assertFalse(mTestDevice.pullDir("somefile", dir)); 490 assertTrue(dir.list().length == 0); 491 } finally { 492 FileUtil.recursiveDelete(dir); 493 } 494 } 495 496 /** 497 * Unit test for {@link NativeDevice#getCurrentUser()}. 498 */ 499 public void testGetCurrentUser_exception() throws Exception { 500 try { 501 mTestDevice.getScreenshot(); 502 } catch (UnsupportedOperationException onse) { 503 return; 504 } 505 fail("getCurrentUser should have thrown an exception."); 506 } 507 508 /** 509 * Unit test for {@link NativeDevice#getUserFlags(int)}. 510 */ 511 public void testGetUserFlags_exception() throws Exception { 512 try { 513 mTestDevice.getUserFlags(0); 514 } catch (UnsupportedOperationException onse) { 515 return; 516 } 517 fail("getUserFlags should have thrown an exception."); 518 } 519 520 /** 521 * Unit test for {@link NativeDevice#getUserSerialNumber(int)}. 522 */ 523 public void testGetUserSerialNumber_exception() throws Exception { 524 try { 525 mTestDevice.getUserSerialNumber(0); 526 } catch (UnsupportedOperationException onse) { 527 return; 528 } 529 fail("getUserSerialNumber should have thrown an exception."); 530 } 531 532 /** 533 * Unit test for {@link NativeDevice#switchUser(int)}. 534 */ 535 public void testSwitchUser_exception() throws Exception { 536 try { 537 mTestDevice.switchUser(10); 538 } catch (UnsupportedOperationException onse) { 539 return; 540 } 541 fail("switchUser should have thrown an exception."); 542 } 543 544 /** 545 * Unit test for {@link NativeDevice#switchUser(int, long)}. 546 */ 547 public void testSwitchUserTimeout_exception() throws Exception { 548 try { 549 mTestDevice.switchUser(10, 5*1000); 550 } catch (UnsupportedOperationException onse) { 551 return; 552 } 553 fail("switchUser should have thrown an exception."); 554 } 555 556 /** 557 * Unit test for {@link NativeDevice#stopUser(int)}. 558 */ 559 public void testStopUser_exception() throws Exception { 560 try { 561 mTestDevice.stopUser(0); 562 } catch (UnsupportedOperationException onse) { 563 return; 564 } 565 fail("stopUser should have thrown an exception."); 566 } 567 568 /** 569 * Unit test for {@link NativeDevice#stopUser(int, boolean, boolean)}. 570 */ 571 public void testStopUserFlags_exception() throws Exception { 572 try { 573 mTestDevice.stopUser(0, true, true); 574 } catch (UnsupportedOperationException onse) { 575 return; 576 } 577 fail("stopUser should have thrown an exception."); 578 } 579 580 /** 581 * Unit test for {@link NativeDevice#isUserRunning(int)}. 582 */ 583 public void testIsUserIdRunning_exception() throws Exception { 584 try { 585 mTestDevice.isUserRunning(0); 586 } catch (UnsupportedOperationException onse) { 587 return; 588 } 589 fail("stopUser should have thrown an exception."); 590 } 591 592 /** 593 * Unit test for {@link NativeDevice#hasFeature(String)}. 594 */ 595 public void testHasFeature_exception() throws Exception { 596 try { 597 mTestDevice.hasFeature("feature:test"); 598 } catch (UnsupportedOperationException onse) { 599 return; 600 } 601 fail("hasFeature should have thrown an exception."); 602 } 603 604 /** 605 * Unit test for {@link NativeDevice#getSetting(String, String)}. 606 */ 607 public void testGetSettingSystemUser_exception() throws Exception { 608 try { 609 mTestDevice.getSetting("global", "wifi_on"); 610 } catch (UnsupportedOperationException onse) { 611 return; 612 } 613 fail("getSettings should have thrown an exception."); 614 } 615 616 /** 617 * Unit test for {@link NativeDevice#getSetting(int, String, String)}. 618 */ 619 public void testGetSetting_exception() throws Exception { 620 try { 621 mTestDevice.getSetting(0, "global", "wifi_on"); 622 } catch (UnsupportedOperationException onse) { 623 return; 624 } 625 fail("getSettings should have thrown an exception."); 626 } 627 628 /** 629 * Unit test for {@link NativeDevice#setSetting(String, String, String)}. 630 */ 631 public void testSetSettingSystemUser_exception() throws Exception { 632 try { 633 mTestDevice.setSetting("global", "wifi_on", "0"); 634 } catch (UnsupportedOperationException onse) { 635 return; 636 } 637 fail("putSettings should have thrown an exception."); 638 } 639 640 /** 641 * Unit test for {@link NativeDevice#setSetting(int, String, String, String)}. 642 */ 643 public void testSetSetting_exception() throws Exception { 644 try { 645 mTestDevice.setSetting(0, "global", "wifi_on", "0"); 646 } catch (UnsupportedOperationException onse) { 647 return; 648 } 649 fail("putSettings should have thrown an exception."); 650 } 651 652 /** 653 * Unit test for {@link NativeDevice#getAndroidId(int)}. 654 */ 655 public void testGetAndroidId_exception() throws Exception { 656 try { 657 mTestDevice.getAndroidId(0); 658 } catch (UnsupportedOperationException onse) { 659 return; 660 } 661 fail("getAndroidId should have thrown an exception."); 662 } 663 664 /** 665 * Unit test for {@link NativeDevice#getAndroidIds()}. 666 */ 667 public void testGetAndroidIds_exception() throws Exception { 668 try { 669 mTestDevice.getAndroidIds(); 670 } catch (UnsupportedOperationException onse) { 671 return; 672 } 673 fail("getAndroidIds should have thrown an exception."); 674 } 675 676 /** 677 * Unit test for {@link NativeDevice#connectToWifiNetworkIfNeeded(String, String)}. 678 */ 679 public void testConnectToWifiNetworkIfNeeded_alreadyConnected() 680 throws DeviceNotAvailableException { 681 EasyMock.expect(mMockWifi.checkConnectivity(mTestDevice.getOptions().getConnCheckUrl())) 682 .andReturn(true); 683 EasyMock.replay(mMockWifi); 684 assertTrue(mTestDevice.connectToWifiNetworkIfNeeded(FAKE_NETWORK_SSID, 685 FAKE_NETWORK_PASSWORD)); 686 EasyMock.verify(mMockWifi); 687 } 688 689 /** 690 * Unit test for {@link NativeDevice#connectToWifiNetwork(String, String)}. 691 */ 692 public void testConnectToWifiNetwork_success() throws DeviceNotAvailableException { 693 EasyMock.expect(mMockWifi.connectToNetwork(FAKE_NETWORK_SSID, FAKE_NETWORK_PASSWORD, 694 mTestDevice.getOptions().getConnCheckUrl(), false)).andReturn(true); 695 Map<String, String> fakeWifiInfo = new HashMap<String, String>(); 696 fakeWifiInfo.put("bssid", FAKE_NETWORK_SSID); 697 EasyMock.expect(mMockWifi.getWifiInfo()).andReturn(fakeWifiInfo); 698 EasyMock.replay(mMockWifi, mMockIDevice); 699 assertTrue(mTestDevice.connectToWifiNetwork(FAKE_NETWORK_SSID, 700 FAKE_NETWORK_PASSWORD)); 701 EasyMock.verify(mMockWifi, mMockIDevice); 702 } 703 704 /** 705 * Unit test for {@link NativeDevice#connectToWifiNetwork(String, String)} for a failure 706 * to connect case. 707 */ 708 public void testConnectToWifiNetwork_failure() throws DeviceNotAvailableException { 709 EasyMock.expect(mMockWifi.connectToNetwork(FAKE_NETWORK_SSID, FAKE_NETWORK_PASSWORD, 710 mTestDevice.getOptions().getConnCheckUrl(), false)).andReturn(false) 711 .times(mTestDevice.getOptions().getWifiAttempts()); 712 Map<String, String> fakeWifiInfo = new HashMap<String, String>(); 713 fakeWifiInfo.put("bssid", FAKE_NETWORK_SSID); 714 EasyMock.expect(mMockWifi.getWifiInfo()).andReturn(fakeWifiInfo) 715 .times(mTestDevice.getOptions().getWifiAttempts()); 716 mMockRunUtil.sleep(EasyMock.anyLong()); 717 EasyMock.expectLastCall().times(mTestDevice.getOptions().getWifiAttempts() - 1); 718 EasyMock.replay(mMockWifi, mMockIDevice, mMockRunUtil); 719 assertFalse(mTestDevice.connectToWifiNetwork(FAKE_NETWORK_SSID, 720 FAKE_NETWORK_PASSWORD)); 721 EasyMock.verify(mMockWifi, mMockIDevice, mMockRunUtil); 722 } 723 724 /** 725 * Unit test for {@link NativeDevice#connectToWifiNetwork(String, String)} for limiting the time 726 * trying to connect to wifi. 727 */ 728 public void testConnectToWifiNetwork_maxConnectTime() 729 throws DeviceNotAvailableException, ConfigurationException { 730 OptionSetter deviceOptionSetter = new OptionSetter(mTestDevice.getOptions()); 731 deviceOptionSetter.setOptionValue("max-wifi-connect-time", "10000"); 732 Clock mockClock = Mockito.mock(Clock.class); 733 mTestDevice.setClock(mockClock); 734 EasyMock.expect( 735 mMockWifi.connectToNetwork( 736 FAKE_NETWORK_SSID, 737 FAKE_NETWORK_PASSWORD, 738 mTestDevice.getOptions().getConnCheckUrl(), 739 false)) 740 .andReturn(false) 741 .times(2); 742 Mockito.when(mockClock.millis()) 743 .thenReturn(Long.valueOf(0), Long.valueOf(6000), Long.valueOf(12000)); 744 Map<String, String> fakeWifiInfo = new HashMap<String, String>(); 745 fakeWifiInfo.put("bssid", FAKE_NETWORK_SSID); 746 EasyMock.expect(mMockWifi.getWifiInfo()).andReturn(fakeWifiInfo).times(2); 747 748 EasyMock.replay(mMockWifi, mMockIDevice); 749 assertFalse(mTestDevice.connectToWifiNetwork(FAKE_NETWORK_SSID, FAKE_NETWORK_PASSWORD)); 750 EasyMock.verify(mMockWifi, mMockIDevice); 751 Mockito.verify(mockClock, Mockito.times(3)).millis(); 752 } 753 754 /** 755 * Unit test for {@link NativeDevice#connectToWifiNetwork(String, String, boolean)}. 756 */ 757 public void testConnectToWifiNetwork_scanSsid() throws DeviceNotAvailableException { 758 EasyMock.expect(mMockWifi.connectToNetwork(FAKE_NETWORK_SSID, FAKE_NETWORK_PASSWORD, 759 mTestDevice.getOptions().getConnCheckUrl(), true)).andReturn(true); 760 Map<String, String> fakeWifiInfo = new HashMap<String, String>(); 761 fakeWifiInfo.put("bssid", FAKE_NETWORK_SSID); 762 EasyMock.expect(mMockWifi.getWifiInfo()).andReturn(fakeWifiInfo); 763 EasyMock.replay(mMockWifi, mMockIDevice); 764 assertTrue(mTestDevice.connectToWifiNetwork(FAKE_NETWORK_SSID, 765 FAKE_NETWORK_PASSWORD, true)); 766 EasyMock.verify(mMockWifi, mMockIDevice); 767 } 768 769 /** 770 * Unit test for {@link NativeDevice#checkWifiConnection(String)}. 771 */ 772 public void testCheckWifiConnection() throws DeviceNotAvailableException { 773 EasyMock.expect(mMockWifi.isWifiEnabled()).andReturn(true); 774 EasyMock.expect(mMockWifi.getSSID()).andReturn("\"" + FAKE_NETWORK_SSID + "\""); 775 EasyMock.expect(mMockWifi.hasValidIp()).andReturn(true); 776 EasyMock.expect(mMockWifi.checkConnectivity(mTestDevice.getOptions().getConnCheckUrl())) 777 .andReturn(true); 778 EasyMock.replay(mMockWifi, mMockIDevice); 779 assertTrue(mTestDevice.checkWifiConnection(FAKE_NETWORK_SSID)); 780 EasyMock.verify(mMockWifi, mMockIDevice); 781 } 782 783 /** 784 * Unit test for {@link NativeDevice#checkWifiConnection(String)} for a failure. 785 */ 786 public void testCheckWifiConnection_failure() throws DeviceNotAvailableException { 787 EasyMock.expect(mMockWifi.isWifiEnabled()).andReturn(false); 788 EasyMock.replay(mMockWifi, mMockIDevice); 789 assertFalse(mTestDevice.checkWifiConnection(FAKE_NETWORK_SSID)); 790 EasyMock.verify(mMockWifi, mMockIDevice); 791 } 792 793 /** 794 * Unit test for {@link NativeDevice#isWifiEnabled()}. 795 */ 796 public void testIsWifiEnabled() throws DeviceNotAvailableException { 797 EasyMock.expect(mMockWifi.isWifiEnabled()).andReturn(true); 798 EasyMock.replay(mMockWifi, mMockIDevice); 799 assertTrue(mTestDevice.isWifiEnabled()); 800 EasyMock.verify(mMockWifi, mMockIDevice); 801 } 802 803 /** 804 * Unit test for {@link NativeDevice#isWifiEnabled()} with runtime exception from 805 * wifihelper. 806 */ 807 public void testIsWifiEnabled_exception() throws DeviceNotAvailableException { 808 EasyMock.expect(mMockWifi.isWifiEnabled()).andThrow(new RuntimeException()); 809 EasyMock.replay(mMockWifi, mMockIDevice); 810 assertFalse(mTestDevice.isWifiEnabled()); 811 EasyMock.verify(mMockWifi, mMockIDevice); 812 } 813 814 /** 815 * Unit test for {@link NativeDevice#disconnectFromWifi()}. 816 */ 817 public void testDisconnectFromWifi() throws DeviceNotAvailableException { 818 EasyMock.expect(mMockWifi.disconnectFromNetwork()).andReturn(true); 819 EasyMock.replay(mMockWifi, mMockIDevice); 820 assertTrue(mTestDevice.disconnectFromWifi()); 821 EasyMock.verify(mMockWifi, mMockIDevice); 822 } 823 824 /** 825 * Unit test for {@link NativeDevice#enableNetworkMonitor()}. 826 */ 827 public void testEnableNetworkMonitor() throws DeviceNotAvailableException { 828 EasyMock.expect(mMockWifi.stopMonitor()).andReturn(null); 829 EasyMock.expect(mMockWifi.startMonitor(EasyMock.anyLong(), 830 EasyMock.eq(mTestDevice.getOptions().getConnCheckUrl()))).andReturn(true); 831 EasyMock.replay(mMockWifi, mMockIDevice); 832 assertTrue(mTestDevice.enableNetworkMonitor()); 833 EasyMock.verify(mMockWifi, mMockIDevice); 834 } 835 836 /** 837 * Unit test for {@link NativeDevice#enableNetworkMonitor()} in case of failure. 838 */ 839 public void testEnableNetworkMonitor_failure() throws DeviceNotAvailableException { 840 EasyMock.expect(mMockWifi.stopMonitor()).andReturn(null); 841 EasyMock.expect(mMockWifi.startMonitor(EasyMock.anyLong(), 842 EasyMock.eq(mTestDevice.getOptions().getConnCheckUrl()))).andReturn(false); 843 EasyMock.replay(mMockWifi, mMockIDevice); 844 assertFalse(mTestDevice.enableNetworkMonitor()); 845 EasyMock.verify(mMockWifi, mMockIDevice); 846 } 847 848 /** 849 * Unit test for {@link NativeDevice#disableNetworkMonitor()}. 850 */ 851 public void testDisableNetworkMonitor() throws DeviceNotAvailableException { 852 List<Long> samples = new ArrayList<Long>(); 853 samples.add(Long.valueOf(42)); 854 samples.add(Long.valueOf(256)); 855 samples.add(Long.valueOf(-1)); // failure to connect 856 EasyMock.expect(mMockWifi.stopMonitor()).andReturn(samples); 857 EasyMock.replay(mMockWifi, mMockIDevice); 858 assertTrue(mTestDevice.disableNetworkMonitor()); 859 EasyMock.verify(mMockWifi, mMockIDevice); 860 } 861 862 /** 863 * Unit test for {@link NativeDevice#reconnectToWifiNetwork()}. 864 */ 865 public void testReconnectToWifiNetwork() throws DeviceNotAvailableException { 866 EasyMock.expect(mMockWifi.checkConnectivity(mTestDevice.getOptions().getConnCheckUrl())) 867 .andReturn(false); 868 EasyMock.expect(mMockWifi.checkConnectivity(mTestDevice.getOptions().getConnCheckUrl())) 869 .andReturn(true); 870 mMockRunUtil.sleep(EasyMock.anyLong()); 871 EasyMock.expectLastCall(); 872 EasyMock.replay(mMockWifi, mMockIDevice, mMockRunUtil); 873 try { 874 mTestDevice.reconnectToWifiNetwork(); 875 } catch (NetworkNotAvailableException nnae) { 876 fail("reconnectToWifiNetwork() should not have thrown an exception."); 877 } finally { 878 EasyMock.verify(mMockWifi, mMockIDevice, mMockRunUtil); 879 } 880 } 881 882 /** 883 * Unit test for {@link NativeDevice#isHeadless()}. 884 */ 885 public void testIsHeadless() throws DeviceNotAvailableException { 886 mTestDevice = new TestableAndroidNativeDevice() { 887 @Override 888 public String getProperty(String name) throws DeviceNotAvailableException { 889 return "1\n"; 890 } 891 }; 892 assertTrue(mTestDevice.isHeadless()); 893 } 894 895 /** 896 * Unit test for {@link NativeDevice#isHeadless()}. 897 */ 898 public void testIsHeadless_notHeadless() throws DeviceNotAvailableException { 899 mTestDevice = new TestableAndroidNativeDevice() { 900 @Override 901 public String getProperty(String name) throws DeviceNotAvailableException { 902 return null; 903 } 904 }; 905 assertFalse(mTestDevice.isHeadless()); 906 } 907 908 /** 909 * Unit test for {@link NativeDevice#getDeviceDate()}. 910 */ 911 public void testGetDeviceDate() throws DeviceNotAvailableException { 912 mTestDevice = new TestableAndroidNativeDevice() { 913 @Override 914 public String executeShellCommand(String name) throws DeviceNotAvailableException { 915 return "21692641\n"; 916 } 917 }; 918 assertEquals(21692641000L, mTestDevice.getDeviceDate()); 919 } 920 921 /** 922 * Unit test for {@link NativeDevice#logBugreport(String, ITestLogger)}. 923 */ 924 public void testTestLogBugreport() { 925 final String dataName = "test"; 926 final InputStreamSource stream = new ByteArrayInputStreamSource(null); 927 mTestDevice = 928 new TestableAndroidNativeDevice() { 929 @Override 930 public InputStreamSource getBugreportz() { 931 return stream; 932 } 933 934 @Override 935 public int getApiLevel() throws DeviceNotAvailableException { 936 return 24; 937 } 938 }; 939 ITestLogger listener = EasyMock.createMock(ITestLogger.class); 940 listener.testLog(dataName, LogDataType.BUGREPORTZ, stream); 941 EasyMock.replay(listener); 942 assertTrue(mTestDevice.logBugreport(dataName, listener)); 943 EasyMock.verify(listener); 944 } 945 946 /** 947 * Unit test for {@link NativeDevice#logBugreport(String, ITestLogger)}. 948 */ 949 public void testTestLogBugreport_oldDevice() { 950 final String dataName = "test"; 951 final InputStreamSource stream = new ByteArrayInputStreamSource(null); 952 mTestDevice = 953 new TestableAndroidNativeDevice() { 954 @Override 955 public InputStreamSource getBugreportz() { 956 // Older device do not support bugreportz and return null 957 return null; 958 } 959 960 @Override 961 public InputStreamSource getBugreportInternal() { 962 return stream; 963 } 964 965 @Override 966 public int getApiLevel() throws DeviceNotAvailableException { 967 // no bugreportz support 968 return 23; 969 } 970 }; 971 ITestLogger listener = EasyMock.createMock(ITestLogger.class); 972 listener.testLog(dataName, LogDataType.BUGREPORT, stream); 973 EasyMock.replay(listener); 974 assertTrue(mTestDevice.logBugreport(dataName, listener)); 975 EasyMock.verify(listener); 976 } 977 978 /** 979 * Unit test for {@link NativeDevice#logBugreport(String, ITestLogger)}. 980 */ 981 public void testTestLogBugreport_fail() { 982 mTestDevice = 983 new TestableAndroidNativeDevice() { 984 @Override 985 public InputStreamSource getBugreportz() { 986 return null; 987 } 988 989 @Override 990 protected InputStreamSource getBugreportInternal() { 991 return null; 992 } 993 994 @Override 995 public int getApiLevel() throws DeviceNotAvailableException { 996 return 23; 997 } 998 }; 999 ITestLogger listener = EasyMock.createMock(ITestLogger.class); 1000 EasyMock.replay(listener); 1001 assertFalse(mTestDevice.logBugreport("test", listener)); 1002 EasyMock.verify(listener); 1003 } 1004 1005 /** 1006 * Unit test for {@link NativeDevice#takeBugreport()}. 1007 */ 1008 public void testTakeBugreport_apiLevelFail() { 1009 mTestDevice = new TestableAndroidNativeDevice() { 1010 @Override 1011 public int getApiLevel() throws DeviceNotAvailableException { 1012 throw new DeviceNotAvailableException(); 1013 } 1014 }; 1015 // If we can't check API level it should return null. 1016 assertNull(mTestDevice.takeBugreport()); 1017 } 1018 1019 /** 1020 * Unit test for {@link NativeDevice#takeBugreport()}. 1021 */ 1022 public void testTakeBugreport_oldDevice() throws Exception { 1023 mTestDevice = new TestableAndroidNativeDevice() { 1024 @Override 1025 public int getApiLevel() throws DeviceNotAvailableException { 1026 return 19; 1027 } 1028 }; 1029 Bugreport report = mTestDevice.takeBugreport(); 1030 try { 1031 assertNotNull(report); 1032 // older device report a non zipped bugreport 1033 assertFalse(report.isZipped()); 1034 } finally { 1035 report.close(); 1036 } 1037 } 1038 1039 /** 1040 * Unit test for {@link NativeDevice#takeBugreport()}. 1041 */ 1042 public void testTakeBugreport() throws Exception { 1043 mTestDevice = new TestableAndroidNativeDevice() { 1044 @Override 1045 public int getApiLevel() throws DeviceNotAvailableException { 1046 return 24; 1047 } 1048 @Override 1049 protected File getBugreportzInternal() { 1050 try { 1051 return FileUtil.createTempFile("bugreportz", ".zip"); 1052 } catch (IOException e) { 1053 return null; 1054 } 1055 } 1056 }; 1057 Bugreport report = mTestDevice.takeBugreport(); 1058 try { 1059 assertNotNull(report); 1060 assertTrue(report.isZipped()); 1061 } finally { 1062 report.close(); 1063 } 1064 } 1065 1066 /** 1067 * Unit test for {@link NativeDevice#getDeviceDate()}. 1068 */ 1069 public void testGetDeviceDate_wrongformat() throws DeviceNotAvailableException { 1070 mTestDevice = new TestableAndroidNativeDevice() { 1071 @Override 1072 public String executeShellCommand(String name) throws DeviceNotAvailableException { 1073 return "WRONG\n"; 1074 } 1075 }; 1076 assertEquals(0, mTestDevice.getDeviceDate()); 1077 } 1078 1079 public void testGetBugreport_deviceUnavail() throws Exception { 1080 final String expectedOutput = "this is the output\r\n in two lines\r\n"; 1081 mTestDevice = new TestableAndroidNativeDevice() { 1082 @Override 1083 public void executeShellCommand( 1084 String command, IShellOutputReceiver receiver, 1085 long maxTimeToOutputShellResponse, TimeUnit timeUnit, int retryAttempts) 1086 throws DeviceNotAvailableException { 1087 String fakeRep = expectedOutput; 1088 receiver.addOutput(fakeRep.getBytes(), 0, fakeRep.getBytes().length); 1089 } 1090 @Override 1091 public int getApiLevel() throws DeviceNotAvailableException { 1092 return 22; 1093 } 1094 }; 1095 1096 // FIXME: this isn't actually causing a DeviceNotAvailableException to be thrown 1097 mMockRecovery.recoverDevice(EasyMock.eq(mMockStateMonitor), EasyMock.eq(false)); 1098 EasyMock.expectLastCall().andThrow(new DeviceNotAvailableException()); 1099 EasyMock.replay(mMockRecovery, mMockIDevice); 1100 assertEquals(expectedOutput, StreamUtil.getStringFromStream( 1101 mTestDevice.getBugreport().createInputStream())); 1102 } 1103 1104 public void testGetBugreport_compatibility_deviceUnavail() throws Exception { 1105 mTestDevice = new TestableAndroidNativeDevice() { 1106 @Override 1107 public void executeShellCommand( 1108 String command, IShellOutputReceiver receiver, 1109 long maxTimeToOutputShellResponse, TimeUnit timeUnit, int retryAttempts) 1110 throws DeviceNotAvailableException { 1111 throw new DeviceNotAvailableException(); 1112 } 1113 @Override 1114 public int getApiLevel() throws DeviceNotAvailableException { 1115 return 24; 1116 } 1117 @Override 1118 public IFileEntry getFileEntry(String path) throws DeviceNotAvailableException { 1119 return null; 1120 } 1121 }; 1122 EasyMock.replay(mMockRecovery, mMockIDevice); 1123 assertEquals(0, mTestDevice.getBugreport().size()); 1124 EasyMock.verify(mMockRecovery, mMockIDevice); 1125 } 1126 1127 public void testGetBugreport_deviceUnavail_fallback() throws Exception { 1128 final IFileEntry fakeEntry = EasyMock.createMock(IFileEntry.class); 1129 mTestDevice = new TestableAndroidNativeDevice() { 1130 @Override 1131 public void executeShellCommand( 1132 String command, IShellOutputReceiver receiver, 1133 long maxTimeToOutputShellResponse, TimeUnit timeUnit, int retryAttempts) 1134 throws DeviceNotAvailableException { 1135 throw new DeviceNotAvailableException(); 1136 } 1137 @Override 1138 public int getApiLevel() throws DeviceNotAvailableException { 1139 return 24; 1140 } 1141 @Override 1142 public IFileEntry getFileEntry(String path) throws DeviceNotAvailableException { 1143 return fakeEntry; 1144 } 1145 @Override 1146 public File pullFile(String remoteFilePath) throws DeviceNotAvailableException { 1147 try { 1148 return FileUtil.createTempFile("bugreport", ".txt"); 1149 } catch (IOException e) { 1150 return null; 1151 } 1152 } 1153 }; 1154 List<IFileEntry> list = new ArrayList<>(); 1155 list.add(fakeEntry); 1156 EasyMock.expect(fakeEntry.getChildren(false)).andReturn(list); 1157 EasyMock.expect(fakeEntry.getName()).andReturn("bugreport-NYC-2016-08-17-10-17-00.tmp"); 1158 EasyMock.replay(fakeEntry, mMockRecovery, mMockIDevice); 1159 InputStreamSource res = null; 1160 try { 1161 res = mTestDevice.getBugreport(); 1162 assertNotNull(res); 1163 EasyMock.verify(fakeEntry, mMockRecovery, mMockIDevice); 1164 } finally { 1165 StreamUtil.cancel(res); 1166 } 1167 } 1168 1169 /** 1170 * Unit test for {@link NativeDevice#getBugreportz()}. 1171 */ 1172 public void testGetBugreportz() throws IOException { 1173 mTestDevice = new TestableAndroidNativeDevice() { 1174 @Override 1175 public void executeShellCommand( 1176 String command, IShellOutputReceiver receiver, 1177 long maxTimeToOutputShellResponse, TimeUnit timeUnit, int retryAttempts) 1178 throws DeviceNotAvailableException { 1179 String fakeRep = "OK:/data/0/com.android.shell/bugreports/bugreport1970-10-27.zip"; 1180 receiver.addOutput(fakeRep.getBytes(), 0, fakeRep.getBytes().length); 1181 } 1182 @Override 1183 public boolean doesFileExist(String destPath) throws DeviceNotAvailableException { 1184 return true; 1185 } 1186 @Override 1187 public boolean pullFile(String remoteFilePath, File localFile) 1188 throws DeviceNotAvailableException { 1189 return true; 1190 } 1191 @Override 1192 public String executeShellCommand(String command) throws DeviceNotAvailableException { 1193 assertEquals("rm /data/0/com.android.shell/bugreports/*", command); 1194 return null; 1195 } 1196 @Override 1197 public int getApiLevel() throws DeviceNotAvailableException { 1198 return 24; 1199 } 1200 }; 1201 FileInputStreamSource f = null; 1202 try { 1203 f = (FileInputStreamSource) mTestDevice.getBugreportz(); 1204 assertNotNull(f); 1205 assertTrue(f.createInputStream().available() == 0); 1206 } finally { 1207 StreamUtil.cancel(f); 1208 if (f != null) { 1209 f.cleanFile(); 1210 } 1211 } 1212 } 1213 1214 /** 1215 * Unit test for {@link NativeDevice#getBugreportz()}. 1216 */ 1217 public void testGetBugreportz_fails() { 1218 mTestDevice = 1219 new TestableAndroidNativeDevice() { 1220 @Override 1221 public int getApiLevel() throws DeviceNotAvailableException { 1222 return 24; 1223 } 1224 1225 @Override 1226 protected File getBugreportzInternal() { 1227 return null; 1228 } 1229 1230 @Override 1231 public IFileEntry getFileEntry(String path) throws DeviceNotAvailableException { 1232 return null; 1233 } 1234 }; 1235 FileInputStreamSource f = null; 1236 try { 1237 f = (FileInputStreamSource) mTestDevice.getBugreportz(); 1238 assertNull(f); 1239 } finally { 1240 StreamUtil.cancel(f); 1241 if (f != null) { 1242 f.cleanFile(); 1243 } 1244 } 1245 } 1246 1247 /** 1248 * Test that we can distinguish a newer file even with Timezone on the device. 1249 * Seoul is GMT+9. 1250 */ 1251 public void testIsNewer() throws Exception { 1252 TestableAndroidNativeDevice testDevice = 1253 new TestableAndroidNativeDevice() { 1254 @Override 1255 public String getProperty(String name) throws DeviceNotAvailableException { 1256 return "Asia/Seoul"; 1257 } 1258 1259 @Override 1260 public long getDeviceTimeOffset(Date date) throws DeviceNotAvailableException { 1261 return 0; 1262 } 1263 }; 1264 File localFile = FileUtil.createTempFile("timezonetest", ".txt"); 1265 try { 1266 localFile.setLastModified(1470906000000l); // Thu Aug 11 09:00:00 GMT 2016 1267 IFileEntry remoteFile = EasyMock.createMock(IFileEntry.class); 1268 EasyMock.expect(remoteFile.getDate()).andReturn("2016-08-11"); 1269 EasyMock.expect(remoteFile.getTime()).andReturn("18:00"); 1270 EasyMock.replay(remoteFile); 1271 assertTrue(testDevice.isNewer(localFile, remoteFile)); 1272 EasyMock.verify(remoteFile); 1273 } finally { 1274 FileUtil.deleteFile(localFile); 1275 } 1276 } 1277 1278 /** 1279 * Test that we can distinguish a newer file even with Timezone on the device. 1280 * Seoul is GMT+9. Clock on device is inaccurate and in advance of host. 1281 */ 1282 public void testIsNewer_timeOffset() throws Exception { 1283 TestableAndroidNativeDevice testDevice = 1284 new TestableAndroidNativeDevice() { 1285 @Override 1286 public String getProperty(String name) throws DeviceNotAvailableException { 1287 return "Asia/Seoul"; 1288 } 1289 1290 @Override 1291 public long getDeviceTimeOffset(Date date) throws DeviceNotAvailableException { 1292 return -15 * 60 * 1000; // Device in advance of 15m on host. 1293 } 1294 }; 1295 File localFile = FileUtil.createTempFile("timezonetest", ".txt"); 1296 try { 1297 localFile.setLastModified(1470906000000l); // Thu, 11 Aug 2016 09:00:00 GMT 1298 IFileEntry remoteFile = EasyMock.createMock(IFileEntry.class); 1299 EasyMock.expect(remoteFile.getDate()).andReturn("2016-08-11"); 1300 EasyMock.expect(remoteFile.getTime()).andReturn("18:15"); 1301 EasyMock.replay(remoteFile); 1302 // Should sync because after time offset correction, file is older. 1303 assertTrue(testDevice.isNewer(localFile, remoteFile)); 1304 EasyMock.verify(remoteFile); 1305 } finally { 1306 FileUtil.deleteFile(localFile); 1307 } 1308 } 1309 1310 /** 1311 * Test that we can distinguish a newer file even with Timezone on the device. 1312 * Seoul is GMT+9. 1313 * Local file is set to 10min earlier than remoteFile. 1314 */ 1315 public void testIsNewer_fails() throws Exception { 1316 TestableAndroidNativeDevice testDevice = 1317 new TestableAndroidNativeDevice() { 1318 @Override 1319 public String getProperty(String name) throws DeviceNotAvailableException { 1320 return "Asia/Seoul"; 1321 } 1322 1323 @Override 1324 public long getDeviceTimeOffset(Date date) throws DeviceNotAvailableException { 1325 return 0; 1326 } 1327 }; 1328 File localFile = FileUtil.createTempFile("timezonetest", ".txt"); 1329 try { 1330 localFile.setLastModified(1470906000000l); // Thu, 11 Aug 2016 09:00:00 GMT 1331 IFileEntry remoteFile = EasyMock.createMock(IFileEntry.class); 1332 EasyMock.expect(remoteFile.getDate()).andReturn("2016-08-11"); 1333 EasyMock.expect(remoteFile.getTime()).andReturn("18:10"); 1334 EasyMock.replay(remoteFile); 1335 assertFalse(testDevice.isNewer(localFile, remoteFile)); 1336 EasyMock.verify(remoteFile); 1337 } finally { 1338 FileUtil.deleteFile(localFile); 1339 } 1340 } 1341 1342 /** 1343 * Unit test for {@link NativeDevice#getBuildAlias()}. 1344 */ 1345 public void testGetBuildAlias() throws DeviceNotAvailableException { 1346 final String alias = "alias\n"; 1347 mTestDevice = new TestableAndroidNativeDevice() { 1348 @Override 1349 public String getProperty(String name) throws DeviceNotAvailableException { 1350 return alias; 1351 } 1352 }; 1353 assertEquals(alias, mTestDevice.getBuildAlias()); 1354 } 1355 1356 /** 1357 * Unit test for {@link NativeDevice#getBuildAlias()}. 1358 */ 1359 public void testGetBuildAlias_null() throws DeviceNotAvailableException { 1360 final String alias = null; 1361 final String buildId = "alias\n"; 1362 mTestDevice = new TestableAndroidNativeDevice() { 1363 @Override 1364 public String getProperty(String name) throws DeviceNotAvailableException { 1365 return alias; 1366 } 1367 @Override 1368 public String getBuildId() throws DeviceNotAvailableException { 1369 return buildId; 1370 } 1371 }; 1372 assertEquals(buildId, mTestDevice.getBuildAlias()); 1373 } 1374 1375 /** 1376 * Unit test for {@link NativeDevice#getBuildAlias()}. 1377 */ 1378 public void testGetBuildAlias_empty() throws DeviceNotAvailableException { 1379 final String alias = ""; 1380 final String buildId = "alias\n"; 1381 mTestDevice = new TestableAndroidNativeDevice() { 1382 @Override 1383 public String getProperty(String name) throws DeviceNotAvailableException { 1384 return alias; 1385 } 1386 @Override 1387 public String getBuildId() throws DeviceNotAvailableException { 1388 return buildId; 1389 } 1390 }; 1391 assertEquals(buildId, mTestDevice.getBuildAlias()); 1392 } 1393 1394 /** 1395 * Unit test for {@link NativeDevice#getBuildId()}. 1396 */ 1397 public void testGetBuildId() throws DeviceNotAvailableException { 1398 final String buildId = "299865"; 1399 mTestDevice = new TestableAndroidNativeDevice() { 1400 @Override 1401 public String getProperty(String name) throws DeviceNotAvailableException { 1402 return buildId; 1403 } 1404 }; 1405 assertEquals(buildId, mTestDevice.getBuildId()); 1406 } 1407 1408 /** 1409 * Unit test for {@link NativeDevice#getBuildId()}. 1410 */ 1411 public void testGetBuildId_null() throws DeviceNotAvailableException { 1412 final String buildId = null; 1413 mTestDevice = new TestableAndroidNativeDevice() { 1414 @Override 1415 public String getProperty(String name) throws DeviceNotAvailableException { 1416 return buildId; 1417 } 1418 }; 1419 assertEquals(IBuildInfo.UNKNOWN_BUILD_ID, mTestDevice.getBuildId()); 1420 } 1421 1422 /** 1423 * Unit test for {@link NativeDevice#getBuildFlavor()}. 1424 */ 1425 public void testGetBuildFlavor() throws DeviceNotAvailableException { 1426 final String flavor = "ham-user"; 1427 mTestDevice = new TestableAndroidNativeDevice() { 1428 @Override 1429 public String getProperty(String name) throws DeviceNotAvailableException { 1430 return flavor; 1431 } 1432 }; 1433 assertEquals(flavor, mTestDevice.getBuildFlavor()); 1434 } 1435 1436 /** 1437 * Unit test for {@link NativeDevice#getBuildFlavor()}. 1438 */ 1439 public void testGetBuildFlavor_null_flavor() throws DeviceNotAvailableException { 1440 final String productName = "prod"; 1441 final String buildType = "buildtype"; 1442 String expected = String.format("%s-%s", productName, buildType); 1443 mTestDevice = new TestableAndroidNativeDevice() { 1444 @Override 1445 public String getProperty(String name) throws DeviceNotAvailableException { 1446 if ("ro.build.flavor".equals(name)) { 1447 return null; 1448 } else if ("ro.product.name".equals(name)) { 1449 return productName; 1450 } else if ("ro.build.type".equals(name)) { 1451 return buildType; 1452 } else { 1453 return null; 1454 } 1455 } 1456 }; 1457 assertEquals(expected, mTestDevice.getBuildFlavor()); 1458 } 1459 1460 /** 1461 * Unit test for {@link NativeDevice#getBuildFlavor()}. 1462 */ 1463 public void testGetBuildFlavor_null() throws DeviceNotAvailableException { 1464 final String productName = null; 1465 final String buildType = "buildtype"; 1466 mTestDevice = new TestableAndroidNativeDevice() { 1467 @Override 1468 public String getProperty(String name) throws DeviceNotAvailableException { 1469 if ("ro.build.flavor".equals(name)) { 1470 return ""; 1471 } else if ("ro.product.name".equals(name)) { 1472 return productName; 1473 } else if ("ro.build.type".equals(name)) { 1474 return buildType; 1475 } else { 1476 return null; 1477 } 1478 } 1479 }; 1480 assertNull(mTestDevice.getBuildFlavor()); 1481 } 1482 1483 /** 1484 * Unit test for {@link NativeDevice#doAdbReboot(String)}. 1485 */ 1486 public void testDoAdbReboot_emulator() throws Exception { 1487 final String into = "bootloader"; 1488 mMockIDevice.reboot(into); 1489 EasyMock.expectLastCall(); 1490 EasyMock.replay(mMockIDevice); 1491 mTestDevice.doAdbReboot(into); 1492 EasyMock.verify(mMockIDevice); 1493 } 1494 1495 /** 1496 * Unit test for {@link NativeDevice#doReboot()}. 1497 */ 1498 public void testDoReboot() throws Exception { 1499 NativeDevice testDevice = new NativeDevice(mMockIDevice, 1500 mMockStateMonitor, mMockDvcMonitor) { 1501 @Override 1502 public TestDeviceState getDeviceState() { 1503 return TestDeviceState.ONLINE; 1504 } 1505 }; 1506 mMockIDevice.reboot(null); 1507 EasyMock.expectLastCall(); 1508 EasyMock.expect(mMockStateMonitor.waitForDeviceNotAvailable(EasyMock.anyLong())) 1509 .andReturn(true); 1510 EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 1511 testDevice.doReboot(); 1512 EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 1513 } 1514 1515 /** 1516 * Unit test for {@link NativeDevice#doReboot()}. 1517 */ 1518 public void testDoReboot_skipped() throws Exception { 1519 NativeDevice testDevice = new NativeDevice(mMockIDevice, 1520 mMockStateMonitor, mMockDvcMonitor) { 1521 @Override 1522 public TestDeviceState getDeviceState() { 1523 mOptions = new TestDeviceOptions() { 1524 @Override 1525 public boolean shouldDisableReboot() { 1526 return true; 1527 } 1528 }; 1529 return TestDeviceState.ONLINE; 1530 } 1531 }; 1532 EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 1533 testDevice.doReboot(); 1534 EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 1535 } 1536 1537 /** 1538 * Unit test for {@link NativeDevice#doReboot()}. 1539 */ 1540 public void testDoReboot_fastboot() throws Exception { 1541 mTestDevice = new TestableAndroidNativeDevice() { 1542 @Override 1543 public TestDeviceState getDeviceState() { 1544 return TestDeviceState.FASTBOOT; 1545 } 1546 @Override 1547 public CommandResult executeFastbootCommand(String... cmdArgs) 1548 throws DeviceNotAvailableException, UnsupportedOperationException { 1549 wasCalled = true; 1550 return new CommandResult(); 1551 } 1552 }; 1553 EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 1554 mTestDevice.doReboot(); 1555 assertTrue(mTestDevice.wasCalled); 1556 EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 1557 } 1558 1559 /** 1560 * Unit test for {@link NativeDevice#unlockDevice()} already decrypted. 1561 */ 1562 public void testUnlockDevice_skipping() throws Exception { 1563 mTestDevice = new TestableAndroidNativeDevice() { 1564 @Override 1565 public boolean isEncryptionSupported() throws DeviceNotAvailableException { 1566 return true; 1567 } 1568 @Override 1569 public boolean isDeviceEncrypted() throws DeviceNotAvailableException { 1570 return false; 1571 } 1572 }; 1573 EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 1574 assertTrue(mTestDevice.unlockDevice()); 1575 EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 1576 } 1577 1578 /** 1579 * Unit test for {@link NativeDevice#unlockDevice()}. 1580 */ 1581 public void testUnlockDevice() throws Exception { 1582 mTestDevice = new TestableAndroidNativeDevice() { 1583 @Override 1584 public boolean isEncryptionSupported() throws DeviceNotAvailableException { 1585 return true; 1586 } 1587 @Override 1588 public boolean isDeviceEncrypted() throws DeviceNotAvailableException { 1589 return true; 1590 } 1591 @Override 1592 public boolean enableAdbRoot() throws DeviceNotAvailableException { 1593 return true; 1594 } 1595 @Override 1596 public String executeShellCommand(String command) throws DeviceNotAvailableException { 1597 return "200 checkpw -1"; 1598 } 1599 }; 1600 EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 1601 assertTrue(mTestDevice.unlockDevice()); 1602 EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 1603 } 1604 1605 /** 1606 * Unit test for {@link NativeDevice#unlockDevice()}. 1607 */ 1608 public void testUnlockDevice_garbageOutput() throws Exception { 1609 mTestDevice = new TestableAndroidNativeDevice() { 1610 @Override 1611 public boolean isEncryptionSupported() throws DeviceNotAvailableException { 1612 return true; 1613 } 1614 @Override 1615 public boolean isDeviceEncrypted() throws DeviceNotAvailableException { 1616 return true; 1617 } 1618 @Override 1619 public boolean enableAdbRoot() throws DeviceNotAvailableException { 1620 return true; 1621 } 1622 @Override 1623 public String executeShellCommand(String command) throws DeviceNotAvailableException { 1624 return "gdsgdgggsgdg not working"; 1625 } 1626 }; 1627 EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 1628 assertFalse(mTestDevice.unlockDevice()); 1629 EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 1630 } 1631 1632 /** 1633 * Unit test for {@link NativeDevice#unlockDevice()}. 1634 */ 1635 public void testUnlockDevice_emptyOutput() throws Exception { 1636 mTestDevice = new TestableAndroidNativeDevice() { 1637 @Override 1638 public boolean isEncryptionSupported() throws DeviceNotAvailableException { 1639 return true; 1640 } 1641 @Override 1642 public boolean isDeviceEncrypted() throws DeviceNotAvailableException { 1643 return true; 1644 } 1645 @Override 1646 public boolean enableAdbRoot() throws DeviceNotAvailableException { 1647 return true; 1648 } 1649 @Override 1650 public String executeShellCommand(String command) throws DeviceNotAvailableException { 1651 return ""; 1652 } 1653 }; 1654 EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 1655 assertFalse(mTestDevice.unlockDevice()); 1656 EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 1657 } 1658 1659 /** 1660 * Unit test for {@link NativeDevice#unlockDevice()}. 1661 */ 1662 public void testUnlockDevice_goodOutputPasswordEnteredCorrectly() throws Exception { 1663 mTestDevice = new TestableAndroidNativeDevice() { 1664 @Override 1665 public boolean isEncryptionSupported() throws DeviceNotAvailableException { 1666 return true; 1667 } 1668 @Override 1669 public boolean isDeviceEncrypted() throws DeviceNotAvailableException { 1670 return true; 1671 } 1672 @Override 1673 public boolean enableAdbRoot() throws DeviceNotAvailableException { 1674 return true; 1675 } 1676 @Override 1677 public String executeShellCommand(String command) throws DeviceNotAvailableException { 1678 return "200 encryption 0"; 1679 } 1680 }; 1681 EasyMock.expect(mMockStateMonitor.waitForDeviceAvailable()).andReturn(mMockIDevice); 1682 EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 1683 assertTrue(mTestDevice.unlockDevice()); 1684 EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 1685 } 1686 1687 /** 1688 * Test {NativeDevice#parseFreeSpaceFromModernOutput(String)} with a regular df output and 1689 * mount name of numbers. 1690 */ 1691 public void testParseDfOutput_mountWithNumber() { 1692 String dfOutput = "Filesystem 1K-blocks Used Available Use% Mounted on\n" + 1693 "/dev/fuse 31154688 100576 31054112 1% /storage/3134-3433"; 1694 Long res = mTestDevice.parseFreeSpaceFromModernOutput(dfOutput); 1695 assertNotNull(res); 1696 assertEquals(31054112L, res.longValue()); 1697 } 1698 1699 /** 1700 * Test {NativeDevice#parseFreeSpaceFromModernOutput(String)} with a regular df output and 1701 * mount name of mix of letters and numbers. 1702 */ 1703 public void testParseDfOutput() { 1704 String dfOutput = "Filesystem 1K-blocks Used Available Use% Mounted on\n" + 1705 "/dev/fuse 31154688 100576 31054112 1% /storage/sdcard58"; 1706 Long res = mTestDevice.parseFreeSpaceFromModernOutput(dfOutput); 1707 assertNotNull(res); 1708 assertEquals(31054112L, res.longValue()); 1709 } 1710 1711 /** 1712 * Test {NativeDevice#parseFreeSpaceFromModernOutput(String)} with a regular df output and 1713 * mount name with incorrect field. 1714 */ 1715 public void testParseDfOutput_wrongMount() { 1716 String dfOutput = "Filesystem 1K-blocks Used Available Use% Mounted on\n" + 1717 "/dev/fuse 31154688 100576 31054112 1% \test\\wrongpath"; 1718 Long res = mTestDevice.parseFreeSpaceFromModernOutput(dfOutput); 1719 assertNull(res); 1720 } 1721 1722 /** 1723 * Test {NativeDevice#parseFreeSpaceFromModernOutput(String)} with a regular df output and 1724 * a filesytem name with numbers in it. 1725 */ 1726 public void testParseDfOutput_filesystemWithNumber() { 1727 String dfOutput = "Filesystem 1K-blocks Used Available Use% Mounted on\n" + 1728 "/dev/dm-1 31154688 100576 31054112 1% /"; 1729 Long res = mTestDevice.parseFreeSpaceFromModernOutput(dfOutput); 1730 assertNotNull(res); 1731 assertEquals(31054112L, res.longValue()); 1732 } 1733 1734 /** 1735 * Test that {@link NativeDevice#getDeviceTimeOffset(Date)} returns the proper offset forward 1736 */ 1737 public void testGetDeviceTimeOffset() throws DeviceNotAvailableException { 1738 mTestDevice = 1739 new TestableAndroidNativeDevice() { 1740 @Override 1741 public long getDeviceDate() throws DeviceNotAvailableException { 1742 return 1476958881000L; 1743 } 1744 }; 1745 Date date = new Date(1476958891000L); 1746 assertEquals(10000L, mTestDevice.getDeviceTimeOffset(date)); 1747 } 1748 1749 /** 1750 * Test that {@link NativeDevice#getDeviceTimeOffset(Date)}} returns the proper offset when 1751 * there is delay. 1752 */ 1753 public void testGetDeviceTimeOffset_delay() throws DeviceNotAvailableException { 1754 mTestDevice = 1755 new TestableAndroidNativeDevice() { 1756 @Override 1757 public long getDeviceDate() throws DeviceNotAvailableException { 1758 // DeviceDate is in second 1759 return 1476958891000L; 1760 } 1761 }; 1762 // Date takes millisecond since Epoch 1763 Date date = new Date(1476958881000L); 1764 assertEquals(-10000L, mTestDevice.getDeviceTimeOffset(date)); 1765 } 1766 1767 /** 1768 * Test that {@link NativeDevice#setDate(Date)} returns the proper offset when 1769 * there is delay with api level above 24, posix format is used. 1770 */ 1771 public void testSetDate() throws DeviceNotAvailableException { 1772 Date date = new Date(1476958881000L); 1773 mTestDevice = 1774 new TestableAndroidNativeDevice() { 1775 @Override 1776 public int getApiLevel() throws DeviceNotAvailableException { 1777 return 24; 1778 } 1779 1780 @Override 1781 public long getDeviceTimeOffset(Date date) throws DeviceNotAvailableException { 1782 // right above set threshold 1783 return NativeDevice.MAX_HOST_DEVICE_TIME_OFFSET + 1; 1784 } 1785 1786 @Override 1787 public String executeShellCommand(String command) 1788 throws DeviceNotAvailableException { 1789 CLog.e("%s", command); 1790 assertEquals("date -u 102010212016.21", command); 1791 return command; 1792 } 1793 }; 1794 mTestDevice.setDate(date); 1795 } 1796 1797 /** 1798 * Test that {@link NativeDevice#setDate(Date)} returns the proper offset when 1799 * there is delay with api level below 23, regular second format is used. 1800 */ 1801 public void testSetDate_lowApi() throws DeviceNotAvailableException { 1802 Date date = new Date(1476958881000L); 1803 mTestDevice = 1804 new TestableAndroidNativeDevice() { 1805 @Override 1806 public int getApiLevel() throws DeviceNotAvailableException { 1807 return 22; 1808 } 1809 1810 @Override 1811 public long getDeviceTimeOffset(Date date) throws DeviceNotAvailableException { 1812 // right above set threshold 1813 return NativeDevice.MAX_HOST_DEVICE_TIME_OFFSET + 1; 1814 } 1815 1816 @Override 1817 public String executeShellCommand(String command) 1818 throws DeviceNotAvailableException { 1819 CLog.e("%s", command); 1820 assertEquals("date -u 1476958881", command); 1821 return command; 1822 } 1823 }; 1824 mTestDevice.setDate(date); 1825 } 1826 1827 /** 1828 * Test that {@link NativeDevice#setDate(Date)} does not attemp to set if bellow threshold. 1829 */ 1830 public void testSetDate_NoAction() throws DeviceNotAvailableException { 1831 Date date = new Date(1476958881000L); 1832 mTestDevice = 1833 new TestableAndroidNativeDevice() { 1834 @Override 1835 public long getDeviceTimeOffset(Date date) throws DeviceNotAvailableException { 1836 // right below set threshold 1837 return NativeDevice.MAX_HOST_DEVICE_TIME_OFFSET - 1; 1838 } 1839 1840 @Override 1841 public String executeShellCommand(String command) 1842 throws DeviceNotAvailableException { 1843 fail("Should not be called"); 1844 return command; 1845 } 1846 }; 1847 mTestDevice.setDate(date); 1848 } 1849 1850 /** 1851 * Test that {@link NativeDevice#getDeviceDescriptor()} returns the proper information. 1852 */ 1853 public void testGetDeviceDescriptor() { 1854 final String serial = "Test"; 1855 mTestDevice = new TestableAndroidNativeDevice() { 1856 @Override 1857 public IDevice getIDevice() { 1858 return new StubDevice(serial); 1859 } 1860 }; 1861 DeviceDescriptor desc = mTestDevice.getDeviceDescriptor(); 1862 assertTrue(desc.isStubDevice()); 1863 assertEquals(serial, desc.getSerial()); 1864 assertEquals("StubDevice", desc.getDeviceClass()); 1865 } 1866 1867 /** 1868 * Test that {@link NativeDevice#pullFile(String, File)} returns true when the pull is 1869 * successful. 1870 */ 1871 public void testPullFile() throws Exception { 1872 final String fakeRemotePath = "/test/"; 1873 SyncService s = Mockito.mock(SyncService.class); 1874 EasyMock.expect(mMockIDevice.getSyncService()).andReturn(s); 1875 EasyMock.replay(mMockIDevice); 1876 File tmpFile = FileUtil.createTempFile("pull", ".test"); 1877 try { 1878 boolean res = mTestDevice.pullFile(fakeRemotePath, tmpFile); 1879 EasyMock.verify(mMockIDevice); 1880 Mockito.verify(s) 1881 .pullFile( 1882 Mockito.eq(fakeRemotePath), 1883 Mockito.eq(tmpFile.getAbsolutePath()), 1884 Mockito.any(ISyncProgressMonitor.class)); 1885 Mockito.verify(s).close(); 1886 assertTrue(res); 1887 } finally { 1888 FileUtil.deleteFile(tmpFile); 1889 } 1890 } 1891 1892 /** 1893 * Test that {@link NativeDevice#pullFile(String, File)} returns false when it fails to 1894 * pull the file. 1895 */ 1896 public void testPullFile_fails() throws Exception { 1897 final String fakeRemotePath = "/test/"; 1898 SyncService s = Mockito.mock(SyncService.class); 1899 EasyMock.expect(mMockIDevice.getSyncService()).andReturn(s); 1900 EasyMock.replay(mMockIDevice); 1901 File tmpFile = FileUtil.createTempFile("pull", ".test"); 1902 doThrow(new SyncException(SyncError.CANCELED)) 1903 .when(s) 1904 .pullFile( 1905 Mockito.eq(fakeRemotePath), 1906 Mockito.eq(tmpFile.getAbsolutePath()), 1907 Mockito.any(ISyncProgressMonitor.class)); 1908 try { 1909 boolean res = mTestDevice.pullFile(fakeRemotePath, tmpFile); 1910 EasyMock.verify(mMockIDevice); 1911 Mockito.verify(s) 1912 .pullFile( 1913 Mockito.eq(fakeRemotePath), 1914 Mockito.eq(tmpFile.getAbsolutePath()), 1915 Mockito.any(ISyncProgressMonitor.class)); 1916 Mockito.verify(s).close(); 1917 assertFalse(res); 1918 } finally { 1919 FileUtil.deleteFile(tmpFile); 1920 } 1921 } 1922 1923 /** 1924 * Test that {@link NativeDevice#pullFile(String)} returns a file when succeed pulling the 1925 * file. 1926 */ 1927 public void testPullFile_returnFileSuccess() throws Exception { 1928 final String fakeRemotePath = "/test/"; 1929 mTestDevice = new TestableAndroidNativeDevice() { 1930 @Override 1931 public boolean pullFile(String remoteFilePath, File localFile) 1932 throws DeviceNotAvailableException { 1933 return true; 1934 } 1935 }; 1936 File res = mTestDevice.pullFile(fakeRemotePath); 1937 try { 1938 assertNotNull(res); 1939 } finally { 1940 FileUtil.deleteFile(res); 1941 } 1942 } 1943 1944 /** 1945 * Test that {@link NativeDevice#pullFile(String)} returns null when failed to pull the file. 1946 */ 1947 public void testPullFile_returnNull() throws Exception { 1948 final String fakeRemotePath = "/test/"; 1949 mTestDevice = new TestableAndroidNativeDevice() { 1950 @Override 1951 public boolean pullFile(String remoteFilePath, File localFile) 1952 throws DeviceNotAvailableException { 1953 return false; 1954 } 1955 }; 1956 File res = mTestDevice.pullFile(fakeRemotePath); 1957 try { 1958 assertNull(res); 1959 } finally { 1960 FileUtil.deleteFile(res); 1961 } 1962 } 1963 1964 /** 1965 * Test that {@link NativeDevice#pullFileContents(String)} returns a string when succeed pulling 1966 * the file. 1967 */ 1968 public void testPullFileContents_returnFileSuccess() throws Exception { 1969 final String fakeRemotePath = "/test/"; 1970 mTestDevice = new TestableAndroidNativeDevice() { 1971 @Override 1972 public boolean pullFile(String remoteFilePath, File localFile) 1973 throws DeviceNotAvailableException { 1974 return true; 1975 } 1976 }; 1977 String res = mTestDevice.pullFileContents(fakeRemotePath); 1978 assertNotNull(res); 1979 } 1980 1981 /** 1982 * Test that {@link NativeDevice#pullFileContents(String)} returns null when failed to pull the 1983 * file. 1984 */ 1985 public void testPullFileContents_returnNull() throws Exception { 1986 final String fakeRemotePath = "/test/"; 1987 mTestDevice = new TestableAndroidNativeDevice() { 1988 @Override 1989 public boolean pullFile(String remoteFilePath, File localFile) 1990 throws DeviceNotAvailableException { 1991 return false; 1992 } 1993 }; 1994 String res = mTestDevice.pullFileContents(fakeRemotePath); 1995 assertNull(res); 1996 } 1997 1998 /** 1999 * Test that {@link NativeDevice#pushFile(File, String)} returns true when the push is 2000 * successful. 2001 */ 2002 public void testPushFile() throws Exception { 2003 final String fakeRemotePath = "/test/"; 2004 SyncService s = Mockito.mock(SyncService.class); 2005 EasyMock.expect(mMockIDevice.getSyncService()).andReturn(s); 2006 EasyMock.replay(mMockIDevice); 2007 File tmpFile = FileUtil.createTempFile("push", ".test"); 2008 try { 2009 boolean res = mTestDevice.pushFile(tmpFile, fakeRemotePath); 2010 EasyMock.verify(mMockIDevice); 2011 Mockito.verify(s) 2012 .pushFile( 2013 Mockito.eq(tmpFile.getAbsolutePath()), 2014 Mockito.eq(fakeRemotePath), 2015 Mockito.any(ISyncProgressMonitor.class)); 2016 Mockito.verify(s).close(); 2017 assertTrue(res); 2018 } finally { 2019 FileUtil.deleteFile(tmpFile); 2020 } 2021 } 2022 2023 /** 2024 * Test that {@link NativeDevice#pushFile(File, String)} returns false when the push is 2025 * unsuccessful. 2026 */ 2027 public void testPushFile_fails() throws Exception { 2028 final String fakeRemotePath = "/test/"; 2029 SyncService s = Mockito.mock(SyncService.class); 2030 EasyMock.expect(mMockIDevice.getSyncService()).andReturn(s); 2031 EasyMock.replay(mMockIDevice); 2032 File tmpFile = FileUtil.createTempFile("push", ".test"); 2033 doThrow(new SyncException(SyncError.CANCELED)) 2034 .when(s) 2035 .pushFile( 2036 Mockito.eq(tmpFile.getAbsolutePath()), 2037 Mockito.eq(fakeRemotePath), 2038 Mockito.any(ISyncProgressMonitor.class)); 2039 try { 2040 boolean res = mTestDevice.pushFile(tmpFile, fakeRemotePath); 2041 EasyMock.verify(mMockIDevice); 2042 Mockito.verify(s) 2043 .pushFile( 2044 Mockito.eq(tmpFile.getAbsolutePath()), 2045 Mockito.eq(fakeRemotePath), 2046 Mockito.any(ISyncProgressMonitor.class)); 2047 Mockito.verify(s).close(); 2048 assertFalse(res); 2049 } finally { 2050 FileUtil.deleteFile(tmpFile); 2051 } 2052 } 2053 2054 /** 2055 * Test validating valid MAC addresses 2056 */ 2057 public void testIsMacAddress() { 2058 assertTrue(mTestDevice.isMacAddress("00:00:00:00:00:00")); 2059 assertTrue(mTestDevice.isMacAddress("00:15:E9:2B:99:3C")); 2060 assertTrue(mTestDevice.isMacAddress("FF:FF:FF:FF:FF:FF")); 2061 assertTrue(mTestDevice.isMacAddress("58:a2:b5:7d:49:24")); 2062 } 2063 2064 /** 2065 * Test validating invalid MAC addresses 2066 */ 2067 public void testIsMacAddress_invalidInput() { 2068 assertFalse(mTestDevice.isMacAddress("")); 2069 assertFalse(mTestDevice.isMacAddress("00-15-E9-2B-99-3C")); // Invalid delimiter 2070 } 2071 2072 /** 2073 * Test querying a device MAC address 2074 */ 2075 public void testGetMacAddress() throws Exception { 2076 String address = "58:a2:b5:7d:49:24"; 2077 IDevice device = new StubDevice(MOCK_DEVICE_SERIAL) { 2078 @Override 2079 public void executeShellCommand(String command, IShellOutputReceiver receiver) 2080 throws TimeoutException, AdbCommandRejectedException, 2081 ShellCommandUnresponsiveException, IOException { 2082 receiver.addOutput(address.getBytes(), 0, address.length()); 2083 } 2084 }; 2085 mMockIDevice.executeShellCommand(EasyMock.anyObject(), EasyMock.anyObject()); 2086 EasyMock.expectLastCall().andDelegateTo(device).anyTimes(); 2087 EasyMock.replay(mMockIDevice); 2088 assertEquals(address, mTestDevice.getMacAddress()); 2089 EasyMock.verify(mMockIDevice); 2090 } 2091 2092 /** 2093 * Test querying a device MAC address when the device is in fastboot 2094 */ 2095 public void testGetMacAddress_fastboot() throws Exception { 2096 mTestDevice.setDeviceState(TestDeviceState.FASTBOOT); 2097 // Will fail if executeShellCommand is called. Which it should not. 2098 assertNull(mTestDevice.getMacAddress()); 2099 } 2100 2101 /** 2102 * Test querying a device MAC address but failing to do so 2103 */ 2104 public void testGetMacAddress_failure() throws Exception { 2105 IDevice device = new StubDevice(MOCK_DEVICE_SERIAL) { 2106 @Override 2107 public void executeShellCommand(String command, IShellOutputReceiver receiver) 2108 throws TimeoutException, AdbCommandRejectedException, 2109 ShellCommandUnresponsiveException, IOException { 2110 throw new IOException(); 2111 } 2112 }; 2113 mMockIDevice.executeShellCommand(EasyMock.anyObject(), EasyMock.anyObject()); 2114 EasyMock.expectLastCall().andDelegateTo(device).anyTimes(); 2115 EasyMock.replay(mMockIDevice); 2116 assertNull(mTestDevice.getMacAddress()); 2117 EasyMock.verify(mMockIDevice); 2118 } 2119 2120 /** 2121 * Test querying a device MAC address for a stub device 2122 */ 2123 public void testGetMacAddress_stubDevice() throws Exception { 2124 String address = "58:a2:b5:7d:49:24"; 2125 IDevice device = new StubDevice(MOCK_DEVICE_SERIAL) { 2126 @Override 2127 public void executeShellCommand(String command, IShellOutputReceiver receiver) 2128 throws TimeoutException, AdbCommandRejectedException, 2129 ShellCommandUnresponsiveException, IOException { 2130 receiver.addOutput(address.getBytes(), 0, address.length()); 2131 } 2132 }; 2133 mTestDevice.setIDevice(device); 2134 assertNull(mTestDevice.getMacAddress()); 2135 } 2136 2137 /** Test that a non online device return null for sim state. */ 2138 public void testGetSimState_unavailableDevice() { 2139 mMockIDevice = EasyMock.createMock(IDevice.class); 2140 EasyMock.expect(mMockIDevice.getState()).andReturn(DeviceState.UNAUTHORIZED); 2141 EasyMock.expect(mMockIDevice.getSerialNumber()).andReturn("serial"); 2142 EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 2143 assertNull(mTestDevice.getSimState()); 2144 EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 2145 } 2146 2147 /** Test that a non online device return null for sim operator. */ 2148 public void testGetSimOperator_unavailableDevice() { 2149 mMockIDevice = EasyMock.createMock(IDevice.class); 2150 EasyMock.expect(mMockIDevice.getState()).andReturn(DeviceState.UNAUTHORIZED); 2151 EasyMock.expect(mMockIDevice.getSerialNumber()).andReturn("serial"); 2152 EasyMock.replay(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 2153 assertNull(mTestDevice.getSimOperator()); 2154 EasyMock.verify(mMockIDevice, mMockStateMonitor, mMockDvcMonitor); 2155 } 2156 2157 /** 2158 * Test that when a {@link NativeDevice#getLogcatSince(long)} is requested a matching logcat 2159 * command is generated. 2160 */ 2161 public void testGetLogcatSince() throws Exception { 2162 long date = 1512990942000L; // 2017-12-11 03:15:42.015 2163 EasyMock.expect(mMockIDevice.getState()).andReturn(DeviceState.ONLINE); 2164 SettableFuture<String> value = SettableFuture.create(); 2165 value.set("23"); 2166 EasyMock.expect(mMockIDevice.getSystemProperty("ro.build.version.sdk")).andReturn(value); 2167 mMockIDevice.executeShellCommand( 2168 EasyMock.eq("logcat -v threadtime -t '12-11 03:15:42.015'"), EasyMock.anyObject()); 2169 EasyMock.replay(mMockIDevice); 2170 mTestDevice.getLogcatSince(date); 2171 EasyMock.verify(mMockIDevice); 2172 } 2173 2174 public void testGetProductVariant() throws Exception { 2175 EasyMock.expect(mMockIDevice.getProperty(DeviceProperties.VARIANT)).andReturn("variant"); 2176 2177 EasyMock.replay(mMockIDevice); 2178 assertEquals("variant", mTestDevice.getProductVariant()); 2179 EasyMock.verify(mMockIDevice); 2180 } 2181 2182 public void testGetProductVariant_legacy() throws Exception { 2183 TestableAndroidNativeDevice testDevice = 2184 new TestableAndroidNativeDevice() { 2185 @Override 2186 protected String internalGetProperty( 2187 String propName, String fastbootVar, String description) 2188 throws DeviceNotAvailableException, UnsupportedOperationException { 2189 if (DeviceProperties.VARIANT_LEGACY.equals(propName)) { 2190 return "legacy"; 2191 } 2192 return null; 2193 } 2194 }; 2195 2196 assertEquals("legacy", testDevice.getProductVariant()); 2197 } 2198 2199 /** Test when {@link NativeDevice#executeShellV2Command(String)} returns a success. */ 2200 public void testExecuteShellV2Command() throws Exception { 2201 CommandResult res = new CommandResult(); 2202 res.setStatus(CommandStatus.SUCCESS); 2203 EasyMock.expect( 2204 mMockRunUtil.runTimedCmd( 2205 100, "adb", "-s", "serial", "shell", "some", "command")) 2206 .andReturn(res); 2207 EasyMock.replay(mMockRunUtil, mMockIDevice); 2208 assertNotNull(mTestDevice.executeShellV2Command("some command")); 2209 EasyMock.verify(mMockRunUtil, mMockIDevice); 2210 } 2211 2212 /** 2213 * Test when {@link NativeDevice#executeShellV2Command(String, long, TimeUnit, int)} fails and 2214 * repeat because of a timeout. 2215 */ 2216 public void testExecuteShellV2Command_timeout() throws Exception { 2217 CommandResult res = new CommandResult(); 2218 res.setStatus(CommandStatus.TIMED_OUT); 2219 res.setStderr("timed out"); 2220 EasyMock.expect( 2221 mMockRunUtil.runTimedCmd( 2222 200L, "adb", "-s", "serial", "shell", "some", "command")) 2223 .andReturn(res) 2224 .times(2); 2225 EasyMock.replay(mMockRunUtil, mMockIDevice); 2226 try { 2227 mTestDevice.executeShellV2Command("some command", 200L, TimeUnit.MILLISECONDS, 1); 2228 fail("Should have thrown an exception."); 2229 } catch (DeviceUnresponsiveException e) { 2230 // expected 2231 } 2232 EasyMock.verify(mMockRunUtil, mMockIDevice); 2233 } 2234 2235 /** 2236 * Test when {@link NativeDevice#executeShellV2Command(String, long, TimeUnit, int)} fails and 2237 * output. 2238 */ 2239 public void testExecuteShellV2Command_fail() throws Exception { 2240 CommandResult res = new CommandResult(); 2241 res.setStatus(CommandStatus.FAILED); 2242 res.setStderr("timed out"); 2243 EasyMock.expect( 2244 mMockRunUtil.runTimedCmd( 2245 200L, "adb", "-s", "serial", "shell", "some", "command")) 2246 .andReturn(res) 2247 .times(1); 2248 EasyMock.replay(mMockRunUtil, mMockIDevice); 2249 CommandResult result = 2250 mTestDevice.executeShellV2Command("some command", 200L, TimeUnit.MILLISECONDS, 1); 2251 assertNotNull(result); 2252 // The final result is what RunUtil returned, so it contains full status information. 2253 assertSame(res, result); 2254 EasyMock.verify(mMockRunUtil, mMockIDevice); 2255 } 2256 } 2257