1 /* 2 * Copyright (C) 2015 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 17 package com.android.compatibility.common.tradefed.targetprep; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertTrue; 22 import static org.junit.Assert.fail; 23 import static org.mockito.Mockito.never; 24 import static org.mockito.Mockito.verify; 25 import static org.mockito.Mockito.when; 26 27 import com.android.ddmlib.IDevice; 28 import com.android.tradefed.build.DeviceBuildInfo; 29 import com.android.tradefed.config.Configuration; 30 import com.android.tradefed.config.OptionSetter; 31 import com.android.tradefed.device.DeviceNotAvailableException; 32 import com.android.tradefed.device.ITestDevice; 33 import com.android.tradefed.invoker.IInvocationContext; 34 import com.android.tradefed.invoker.InvocationContext; 35 import com.android.tradefed.invoker.TestInformation; 36 import com.android.tradefed.targetprep.ITargetPreparer; 37 import com.android.tradefed.targetprep.TargetSetupError; 38 import com.android.tradefed.util.FileUtil; 39 40 import org.junit.After; 41 import org.junit.Before; 42 import org.junit.Test; 43 import org.junit.runner.RunWith; 44 import org.junit.runners.JUnit4; 45 import org.mockito.Mockito; 46 47 import java.io.File; 48 import java.util.ArrayList; 49 import java.util.List; 50 51 /** Unit tests for {@link MediaPreparer}. */ 52 @RunWith(JUnit4.class) 53 public class MediaPreparerTest { 54 55 private static final String RUN_TESTS_AS_USER_KEY = "RUN_TESTS_AS_USER"; 56 private static final int TEST_USER_ID = 99; 57 58 private MediaPreparer mMediaPreparer; 59 private DeviceBuildInfo mMockBuildInfo; 60 private ITestDevice mMockDevice; 61 private OptionSetter mOptionSetter; 62 private TestInformation mTestInfo; 63 private File mTestsDir; 64 65 @Before setUp()66 public void setUp() throws Exception { 67 mMediaPreparer = 68 new MediaPreparer() { 69 @Override 70 protected void setMaxRes(TestInformation testInfo) 71 throws DeviceNotAvailableException, TargetSetupError { 72 if (mMaxRes != null) return; 73 super.setMaxRes(testInfo); 74 } 75 }; 76 mMediaPreparer.setUserId(TEST_USER_ID); 77 mMockDevice = Mockito.mock(ITestDevice.class); 78 mMockBuildInfo = new DeviceBuildInfo("0", ""); 79 mTestsDir = FileUtil.createTempDir("media-unit-tests"); 80 mMockBuildInfo.setTestsDir(mTestsDir, "1"); 81 new File(mTestsDir, "CtsMediaPreparerApp.apk").createNewFile(); 82 mOptionSetter = new OptionSetter(mMediaPreparer); 83 IInvocationContext context = new InvocationContext(); 84 context.addDeviceBuildInfo("device", mMockBuildInfo); 85 context.addAllocatedDevice("device", mMockDevice); 86 mTestInfo = TestInformation.newBuilder().setInvocationContext(context).build(); 87 } 88 89 @After tearDown()90 public void tearDown() throws Exception { 91 FileUtil.recursiveDelete(mTestsDir); 92 } 93 94 @Test testLegacySetMountPoint()95 public void testLegacySetMountPoint() throws Exception { 96 when(mMockDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE)).thenReturn( 97 "/sdcard"); 98 99 mMediaPreparer.setMountPoint(mMockDevice); 100 assertEquals(mMediaPreparer.mBaseDeviceShortDir, "/sdcard/test/bbb_short/"); 101 assertEquals(mMediaPreparer.mBaseDeviceFullDir, "/sdcard/test/bbb_full/"); 102 } 103 104 @Test testSetMountPoint()105 public void testSetMountPoint() throws Exception { 106 String mediaFolderName = "unittest"; 107 mOptionSetter.setOptionValue("media-folder-name", mediaFolderName); 108 mOptionSetter.setOptionValue("use-legacy-folder-structure", "false"); 109 when(mMockDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE)).thenReturn("/sdcard"); 110 111 mMediaPreparer.setMountPoint(mMockDevice); 112 String baseDir = "/sdcard/test/" + mediaFolderName; 113 assertEquals(mMediaPreparer.mBaseDeviceShortDir, baseDir + "/bbb_short/"); 114 assertEquals(mMediaPreparer.mBaseDeviceFullDir, baseDir + "/bbb_full/"); 115 } 116 117 @Test testDefaultModuleDirMountPoint()118 public void testDefaultModuleDirMountPoint() throws Exception { 119 when(mMockDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE)).thenReturn( 120 "/sdcard"); 121 122 mMediaPreparer.setMountPoint(mMockDevice); 123 assertEquals(mMediaPreparer.mBaseDeviceModuleDir, "/sdcard/test/android-cts-media/"); 124 assertEquals(mMediaPreparer.getMediaDir().getName(), "android-cts-media"); 125 } 126 127 @Test testSetModuleDirMountPoint()128 public void testSetModuleDirMountPoint() throws Exception { 129 mOptionSetter.setOptionValue("media-folder-name", "unittest"); 130 when(mMockDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE)).thenReturn( 131 "/sdcard"); 132 133 mMediaPreparer.setMountPoint(mMockDevice); 134 assertEquals(mMediaPreparer.mBaseDeviceModuleDir, "/sdcard/test/unittest/"); 135 assertEquals(mMediaPreparer.getMediaDir().getName(), "unittest"); 136 } 137 138 @Test testCopyMediaFiles()139 public void testCopyMediaFiles() throws Exception { 140 mMediaPreparer.mMaxRes = MediaPreparer.RESOLUTIONS[1]; 141 mMediaPreparer.mBaseDeviceShortDir = "/sdcard/test/bbb_short/"; 142 mMediaPreparer.mBaseDeviceFullDir = "/sdcard/test/bbb_full/"; 143 mMediaPreparer.mBaseDeviceModuleDir = "/sdcard/test/android-cts-media/"; 144 for (MediaPreparer.Resolution resolution : MediaPreparer.RESOLUTIONS) { 145 if (resolution.getWidth() > MediaPreparer.RESOLUTIONS[1].getWidth()) { 146 // Stop when we reach the default max resolution 147 continue; 148 } 149 String shortFile = String.format("%s%s", mMediaPreparer.mBaseDeviceShortDir, 150 resolution.toString()); 151 String fullFile = String.format("%s%s", mMediaPreparer.mBaseDeviceFullDir, 152 resolution.toString()); 153 when(mMockDevice.doesFileExist(shortFile, TEST_USER_ID)).thenReturn(true); 154 when(mMockDevice.doesFileExist(fullFile, TEST_USER_ID)).thenReturn(true); 155 } 156 when(mMockDevice.doesFileExist(mMediaPreparer.mBaseDeviceModuleDir, TEST_USER_ID)) 157 .thenReturn(false); 158 159 mMediaPreparer.copyMediaFiles(mMockDevice); 160 } 161 162 @Test testMediaFilesExistOnDeviceTrue()163 public void testMediaFilesExistOnDeviceTrue() throws Exception { 164 mMediaPreparer.mMaxRes = MediaPreparer.RESOLUTIONS[1]; 165 mMediaPreparer.mBaseDeviceShortDir = "/sdcard/test/bbb_short/"; 166 mMediaPreparer.mBaseDeviceFullDir = "/sdcard/test/bbb_full/"; 167 for (MediaPreparer.Resolution resolution : MediaPreparer.RESOLUTIONS) { 168 String shortFile = String.format("%s%s", mMediaPreparer.mBaseDeviceShortDir, 169 resolution.toString()); 170 String fullFile = String.format("%s%s", mMediaPreparer.mBaseDeviceFullDir, 171 resolution.toString()); 172 when(mMockDevice.doesFileExist(shortFile, TEST_USER_ID)).thenReturn(true); 173 when(mMockDevice.doesFileExist(fullFile, TEST_USER_ID)).thenReturn(true); 174 } 175 assertTrue(mMediaPreparer.mediaFilesExistOnDevice(mMockDevice)); 176 } 177 178 @Test testMediaFilesExistOnDeviceTrueWithPushAll()179 public void testMediaFilesExistOnDeviceTrueWithPushAll() throws Exception { 180 mOptionSetter.setOptionValue("push-all", "true"); 181 mMediaPreparer.mBaseDeviceModuleDir = "/sdcard/test/android-cts-media/"; 182 when(mMockDevice.doesFileExist(mMediaPreparer.mBaseDeviceModuleDir, TEST_USER_ID)) 183 .thenReturn(true); 184 185 assertTrue(mMediaPreparer.mediaFilesExistOnDevice(mMockDevice)); 186 } 187 188 @Test testMediaFilesExistOnDeviceFalse()189 public void testMediaFilesExistOnDeviceFalse() throws Exception { 190 mMediaPreparer.mMaxRes = MediaPreparer.RESOLUTIONS[1]; 191 mMediaPreparer.mBaseDeviceShortDir = "/sdcard/test/bbb_short/"; 192 String firstFileChecked = "/sdcard/test/bbb_short/176x144"; 193 when(mMockDevice.doesFileExist(firstFileChecked, TEST_USER_ID)).thenReturn(false); 194 195 assertFalse(mMediaPreparer.mediaFilesExistOnDevice(mMockDevice)); 196 } 197 198 @Test testMediaFilesExistOnDevice_differentUserId()199 public void testMediaFilesExistOnDevice_differentUserId() throws Exception { 200 mOptionSetter.setOptionValue("push-all", "true"); 201 mMediaPreparer.mBaseDeviceModuleDir = "/sdcard/test/android-cts-media/"; 202 when(mMockDevice.doesFileExist(mMediaPreparer.mBaseDeviceModuleDir, TEST_USER_ID)) 203 .thenReturn(true); 204 205 assertTrue(mMediaPreparer.mediaFilesExistOnDevice(mMockDevice)); 206 207 // The file exists for TEST_USER_ID, but not for other users. 208 mMediaPreparer.setUserId(TEST_USER_ID + 1); 209 assertFalse(mMediaPreparer.mediaFilesExistOnDevice(mMockDevice)); 210 } 211 212 @Test testSetUp_setsUserIdFromProperty()213 public void testSetUp_setsUserIdFromProperty() throws Exception { 214 mOptionSetter.setOptionValue("skip-media-download", "true"); 215 mOptionSetter.setOptionValue("push-all", "true"); 216 mMediaPreparer.mBaseDeviceModuleDir = "/sdcard/test/android-cts-media/"; 217 int newTestUserId = TEST_USER_ID + 1; 218 when(mMockDevice.doesFileExist(mMediaPreparer.mBaseDeviceModuleDir, newTestUserId)) 219 .thenReturn(true); 220 221 // The file exists for newTestUserId, not for TEST_USER_ID. 222 assertFalse(mMediaPreparer.mediaFilesExistOnDevice(mMockDevice)); 223 224 mTestInfo.properties().put(RUN_TESTS_AS_USER_KEY, String.valueOf(newTestUserId)); 225 // userId is set to newTestUser by setUp(). 226 mMediaPreparer.setUp(mTestInfo); 227 228 assertTrue(mMediaPreparer.mediaFilesExistOnDevice(mMockDevice)); 229 } 230 231 @Test testSkipMediaDownload()232 public void testSkipMediaDownload() throws Exception { 233 mOptionSetter.setOptionValue("skip-media-download", "true"); 234 235 mMediaPreparer.setUp(mTestInfo); 236 } 237 238 @Test testPushAll()239 public void testPushAll() throws Exception { 240 mOptionSetter.setOptionValue("push-all", "true"); 241 mOptionSetter.setOptionValue("media-folder-name", "unittest"); 242 mMediaPreparer.mBaseDeviceModuleDir = "/sdcard/test/unittest/"; 243 mMediaPreparer.mBaseDeviceShortDir = "/sdcard/test/bbb_short/"; 244 mMediaPreparer.mBaseDeviceFullDir = "/sdcard/test/bbb_full/"; 245 when(mMockDevice.doesFileExist(mMediaPreparer.mBaseDeviceModuleDir, TEST_USER_ID)) 246 .thenReturn(true); 247 when(mMockDevice.doesFileExist(mMediaPreparer.mBaseDeviceShortDir, TEST_USER_ID)) 248 .thenReturn(false); 249 when(mMockDevice.doesFileExist(mMediaPreparer.mBaseDeviceFullDir, TEST_USER_ID)) 250 .thenReturn(false); 251 252 mMediaPreparer.copyMediaFiles(mMockDevice); 253 } 254 255 /** Test that if we decide to run and files are on the device, we don't download again. */ 256 @Test testMediaDownloadOnly_existsOnDevice()257 public void testMediaDownloadOnly_existsOnDevice() throws Exception { 258 mMediaPreparer.mMaxRes = MediaPreparer.RESOLUTIONS[3]; 259 mOptionSetter.setOptionValue("local-media-path", "/fake/media/dir"); 260 mMediaPreparer.mBaseDeviceShortDir = "/sdcard/test/bbb_short/"; 261 mMediaPreparer.mBaseDeviceFullDir = "/sdcard/test/bbb_full/"; 262 263 when(mMockDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE)) 264 .thenReturn("/sdcard"); 265 for (MediaPreparer.Resolution resolution : MediaPreparer.RESOLUTIONS) { 266 if (resolution.getWidth() > MediaPreparer.RESOLUTIONS[1].getWidth()) { 267 // Stop when we reach the default max resolution 268 continue; 269 } 270 String shortFile = 271 String.format( 272 "%s%s", mMediaPreparer.mBaseDeviceShortDir, resolution.toString()); 273 String fullFile = 274 String.format("%s%s", mMediaPreparer.mBaseDeviceFullDir, resolution.toString()); 275 when(mMockDevice.doesFileExist(shortFile, TEST_USER_ID)).thenReturn(true); 276 when(mMockDevice.doesFileExist(fullFile, TEST_USER_ID)).thenReturn(true); 277 } 278 279 mMediaPreparer.setUp(mTestInfo); 280 } 281 setUpTocTests()282 private void setUpTocTests() throws Exception { 283 mOptionSetter.setOptionValue("push-all", "true"); 284 mOptionSetter.setOptionValue("media-folder-name", "toc"); 285 mOptionSetter.setOptionValue("simple-caching-semantics", "false"); 286 mMediaPreparer.mBaseDeviceModuleDir = "/sdcard/test/toc/"; 287 288 when(mMockDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE)) 289 .thenReturn("/sdcard"); 290 when(mMockDevice.doesFileExist(Mockito.any(), Mockito.anyInt())).thenReturn(false); 291 when(mMockDevice.getDeviceDescriptor()).thenReturn(null); 292 when(mMockDevice.pushDir(Mockito.any(), Mockito.any(), Mockito.anyInt())).thenReturn(true); 293 when(mMockDevice.executeShellCommand(Mockito.any())) 294 .thenReturn(""); 295 } 296 297 /** Test that if TOC doesn't exist, we download again */ 298 @Test testMissingTOC()299 public void testMissingTOC() throws Exception { 300 setUpTocTests(); 301 302 File mediaFolder = mMediaPreparer.getMediaDir(); 303 mediaFolder.mkdirs(); 304 305 // In order to test non-existent TOC triggers a download, need to ensure there is at 306 // least a file in the folder, otherwise empty folder triggers a download */ 307 File file = new File(mediaFolder, "file"); 308 file.createNewFile(); 309 310 try { 311 mMediaPreparer.setUp(mTestInfo); 312 fail("TargetSetupError expected"); 313 } catch (TargetSetupError e) { 314 // Expected 315 } finally { 316 FileUtil.recursiveDelete(mediaFolder); 317 } 318 } 319 320 /** Test that if TOC has a non-existent file, we download again */ 321 @Test testNonExistentFileInTOC()322 public void testNonExistentFileInTOC() throws Exception { 323 setUpTocTests(); 324 File mediaFolder = mMediaPreparer.getMediaDir(); 325 mediaFolder.mkdirs(); 326 327 File file = new File(mediaFolder, "file"); 328 file.createNewFile(); 329 330 File tocFile = new File(mediaFolder, MediaPreparer.TOC_NAME); 331 String content = "file\n" + "non-existent-file"; 332 FileUtil.writeToFile(content, tocFile); 333 334 try { 335 mMediaPreparer.setUp(mTestInfo); 336 fail("TargetSetupError expected"); 337 } catch (TargetSetupError e) { 338 // Expected 339 } finally { 340 FileUtil.recursiveDelete(mediaFolder); 341 } 342 } 343 344 /** Test that if TOC is valid, we don't download again */ 345 @Test testValidTOC()346 public void testValidTOC() throws Exception { 347 setUpTocTests(); 348 349 File mediaFolder = mMediaPreparer.getMediaDir(); 350 mediaFolder.mkdirs(); 351 File file = new File(mediaFolder, "file"); 352 file.createNewFile(); 353 354 File tocFile = new File(mediaFolder, MediaPreparer.TOC_NAME); 355 String content = "file\n"; 356 FileUtil.writeToFile(content, tocFile); 357 358 try { 359 mMediaPreparer.setUp(mTestInfo); 360 } finally { 361 FileUtil.recursiveDelete(mediaFolder); 362 } 363 } 364 365 @Test testGetDynamicConfig()366 public void testGetDynamicConfig() throws Exception { 367 Configuration config = new Configuration("name", "test"); 368 mMediaPreparer.setConfiguration(config); 369 List<ITargetPreparer> preparers = new ArrayList<>(); 370 DynamicConfigPusher pusher = new DynamicConfigPusher(); 371 pusher.setModuleName("CtsModuleName"); 372 preparers.add(pusher); 373 preparers.add(mMediaPreparer); 374 config.setTargetPreparers(preparers); 375 assertEquals("CtsModuleName", mMediaPreparer.getDynamicModuleName()); 376 } 377 378 @Test testGetDynamicConfig_outOfOrder()379 public void testGetDynamicConfig_outOfOrder() throws Exception { 380 Configuration config = new Configuration("name", "test"); 381 mMediaPreparer.setConfiguration(config); 382 List<ITargetPreparer> preparers = new ArrayList<>(); 383 preparers.add(mMediaPreparer); 384 DynamicConfigPusher pusher = new DynamicConfigPusher(); 385 pusher.setModuleName("CtsModuleName"); 386 preparers.add(pusher); 387 config.setTargetPreparers(preparers); 388 try { 389 mMediaPreparer.getDynamicModuleName(); 390 fail("Should have thrown an exception."); 391 } catch (TargetSetupError expected) { 392 // Expected 393 } 394 } 395 396 @Test testDownloadOnly()397 public void testDownloadOnly() throws Exception { 398 mOptionSetter.setOptionValue("media-download-only", "true"); 399 mOptionSetter.setOptionValue("local-media-path", "/fake/media/dir"); 400 mMediaPreparer.setUp(mTestInfo); 401 402 verify(mMockDevice, never()).getMountPoint(Mockito.any()); 403 verify(mMockDevice, never()).doesFileExist(Mockito.any(), Mockito.anyInt()); 404 } 405 } 406 407