1 /* 2 * Copyright (C) 2023 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.targetprep; 17 18 import com.android.tradefed.build.DeviceBuildInfo; 19 import com.android.tradefed.build.IDeviceBuildInfo; 20 import com.android.tradefed.config.Configuration; 21 import com.android.tradefed.config.OptionSetter; 22 import com.android.tradefed.device.ITestDevice; 23 import com.android.tradefed.invoker.IInvocationContext; 24 import com.android.tradefed.invoker.InvocationContext; 25 import com.android.tradefed.invoker.TestInformation; 26 import com.android.tradefed.util.FileUtil; 27 28 import org.junit.Assert; 29 import org.junit.Before; 30 import org.junit.Test; 31 import org.junit.runner.RunWith; 32 import org.junit.runners.JUnit4; 33 import org.mockito.Mockito; 34 35 import java.io.File; 36 import java.io.IOException; 37 38 /** Unit tests for {@link MixKernelTargetPreparer} */ 39 @RunWith(JUnit4.class) 40 public class MixKernelTargetPreparerTest { 41 private IInvocationContext mContext; 42 private TestInformation mTestInfo; 43 private IDeviceBuildInfo mBuildInfo; 44 45 @Before setUp()46 public void setUp() { 47 mContext = new InvocationContext(); 48 mBuildInfo = new DeviceBuildInfo(); 49 mBuildInfo.setBuildFlavor("flavor"); 50 mContext.addDeviceBuildInfo("device", mBuildInfo); 51 mContext.addAllocatedDevice("device", Mockito.mock(ITestDevice.class)); 52 mTestInfo = TestInformation.newBuilder().setInvocationContext(mContext).build(); 53 } 54 55 @Test testCopyDeviceImageToDir()56 public void testCopyDeviceImageToDir() throws Exception { 57 String deviceImageName = "oriole-img-9432383"; 58 File oldDir = FileUtil.createTempDir("oldDir"); 59 File newDir = FileUtil.createTempDir("newDir"); 60 File srcFile = FileUtil.createTempFile(deviceImageName + "_", ".zip", oldDir); 61 MixKernelTargetPreparer mk = new MixKernelTargetPreparer(); 62 try { 63 mk.copyDeviceImageToDir(srcFile, newDir); 64 if (FileUtil.findFile(newDir, deviceImageName + ".zip") == null) { 65 Assert.fail( 66 String.format( 67 "Copy file %s to %s/%s.zip failed. Files in newDir: %s", 68 srcFile, 69 newDir, 70 deviceImageName, 71 newDir.listFiles()[0].toString())); 72 } 73 } finally { 74 FileUtil.recursiveDelete(oldDir); 75 FileUtil.recursiveDelete(newDir); 76 } 77 } 78 79 @Test testCopyLabelFileToDir()80 public void testCopyLabelFileToDir() throws Exception { 81 File tmpDir = FileUtil.createTempDir("tmpdir"); 82 File srcFile1 = FileUtil.createTempFile("Image", ".gz", tmpDir); 83 File srcFile2 = FileUtil.createTempFile("oriole-img-9089658", ".zip", tmpDir); 84 MixKernelTargetPreparer mk = new MixKernelTargetPreparer(); 85 try { 86 mk.copyLabelFileToDir("{kernel}Image.gz", srcFile1, tmpDir); 87 mk.copyLabelFileToDir("{device}some-img-001{zip}", srcFile2, tmpDir); 88 if (FileUtil.findFile(tmpDir, "Image.gz") == null) { 89 Assert.fail(String.format("Copy file %s to %s/Imag.gz failed", srcFile1, tmpDir)); 90 } 91 if (FileUtil.findFile(tmpDir, "some-img-001.zip") == null) { 92 Assert.fail( 93 String.format("Copy file %s to %s/some-img-001 failed", srcFile1, tmpDir)); 94 } 95 } finally { 96 FileUtil.recursiveDelete(tmpDir); 97 } 98 } 99 100 @Test testFailsOnMissingDeviceImage()101 public void testFailsOnMissingDeviceImage() throws Exception { 102 MixKernelTargetPreparer mk = new MixKernelTargetPreparer(); 103 try { 104 mk.setUp(mTestInfo); 105 Assert.fail("Expected TargetSetupError"); 106 } catch (TargetSetupError e) { 107 // expected. 108 } 109 } 110 111 @Test testFailsOnMissingKernelImage()112 public void testFailsOnMissingKernelImage() throws Exception { 113 MixKernelTargetPreparer mk = new MixKernelTargetPreparer(); 114 File deviceImage = FileUtil.createTempFile("device-img-12345", "zip"); 115 mBuildInfo.setFile("device", deviceImage, "0"); 116 try { 117 mContext.addDeviceBuildInfo("device", new DeviceBuildInfo()); 118 mk.setUp(mTestInfo); 119 Assert.fail("Expected TargetSetupError"); 120 } catch (TargetSetupError e) { 121 // expected. 122 } finally { 123 FileUtil.recursiveDelete(deviceImage); 124 } 125 } 126 127 @Test testFailsOnMissingKernelMixingTool()128 public void testFailsOnMissingKernelMixingTool() throws Exception { 129 MixKernelTargetPreparer mk = new MixKernelTargetPreparer(); 130 File deviceImage = FileUtil.createTempFile("device-img-12345", "zip"); 131 mBuildInfo.setFile("device", deviceImage, "0"); 132 File kernelImage = FileUtil.createTempFile("device-img-12345", "zip"); 133 mBuildInfo.setFile("{kernel}Image.gz", kernelImage, "0"); 134 try { 135 mk.setUp(mTestInfo); 136 Assert.fail("Expected TargetSetupError"); 137 } catch (TargetSetupError e) { 138 // expected. 139 } finally { 140 FileUtil.recursiveDelete(deviceImage); 141 FileUtil.recursiveDelete(kernelImage); 142 } 143 } 144 145 @Test testFailsOnRunningKernelMixingTool()146 public void testFailsOnRunningKernelMixingTool() throws Exception { 147 MixKernelTargetPreparer mk = 148 new MixKernelTargetPreparer() { 149 @Override 150 protected void runMixKernelTool( 151 ITestDevice device, 152 File oldDeviceDir, 153 File kernelDir, 154 File gkiDir, 155 File newDeviceDir) 156 throws TargetSetupError { 157 throw new TargetSetupError("Failed to run mixing tool"); 158 } 159 }; 160 File deviceImage = FileUtil.createTempFile("device-img-12345", "zip"); 161 File kernelImage = FileUtil.createTempFile("dtbo", "img"); 162 File testsDir = FileUtil.createTempDir("testsdir"); 163 OptionSetter setter = new OptionSetter(mk); 164 setter.setOptionValue("mix-kernel-tool-name", "build_mixed_kernels_ramdisk"); 165 File mixKernelTool = FileUtil.createTempFile("build_mixed_kernels_ramdisk", null, testsDir); 166 mixKernelTool.renameTo(new File(testsDir, "build_mixed_kernels_ramdisk")); 167 mBuildInfo.setFile("device", deviceImage, "0"); 168 mBuildInfo.setFile("{kernel}Image.gz", kernelImage, "0"); 169 mBuildInfo.setTestsDir(testsDir, "0"); 170 try { 171 mk.setUp(mTestInfo); 172 Assert.fail("Expected TargetSetupError"); 173 } catch (TargetSetupError e) { 174 // expected. 175 } finally { 176 FileUtil.recursiveDelete(deviceImage); 177 FileUtil.recursiveDelete(kernelImage); 178 FileUtil.recursiveDelete(testsDir); 179 } 180 } 181 182 @Test testFailsOnNoNewDeviceImage()183 public void testFailsOnNoNewDeviceImage() throws Exception { 184 MixKernelTargetPreparer mk = 185 new MixKernelTargetPreparer() { 186 @Override 187 protected void runMixKernelTool( 188 ITestDevice device, 189 File oldDeviceDir, 190 File kernelDir, 191 File gkiDir, 192 File newDeviceDir) 193 throws TargetSetupError { 194 return; 195 } 196 }; 197 198 File deviceImage = FileUtil.createTempFile("device-img-12345", "zip"); 199 File kernelImage = FileUtil.createTempFile("dtbo", "img"); 200 OptionSetter setter = new OptionSetter(mk); 201 setter.setOptionValue("mix-kernel-tool-name", "build_mixed_kernels_ramdisk"); 202 File testsDir = FileUtil.createTempDir("testsdir"); 203 File mixKernelTool = FileUtil.createTempFile("build_mixed_kernels_ramdisk", null, testsDir); 204 mixKernelTool.renameTo(new File(testsDir, "build_mixed_kernels_ramdisk")); 205 mBuildInfo.setFile("device", deviceImage, "0"); 206 mBuildInfo.setFile("{kernel}Image.gz", kernelImage, "0"); 207 mBuildInfo.setTestsDir(testsDir, "0"); 208 try { 209 mk.setUp(mTestInfo); 210 Assert.fail("Expected TargetSetupError"); 211 } catch (TargetSetupError e) { 212 // expected. 213 } finally { 214 FileUtil.recursiveDelete(deviceImage); 215 FileUtil.recursiveDelete(kernelImage); 216 FileUtil.recursiveDelete(testsDir); 217 } 218 } 219 220 @Test testSuccessfulMixKernel()221 public void testSuccessfulMixKernel() throws Exception { 222 MixKernelTargetPreparer mk = 223 new MixKernelTargetPreparer() { 224 @Override 225 protected void runMixKernelTool( 226 ITestDevice device, 227 File oldDeviceDir, 228 File kernelDir, 229 File gkiDir, 230 File newDeviceDir) 231 throws TargetSetupError { 232 try { 233 File newFile = 234 FileUtil.createTempFile( 235 "new-device-img-12345", "zip", newDeviceDir); 236 newFile.renameTo(new File(newDeviceDir, "device-img-12345.zip")); 237 } catch (IOException e) { 238 throw new TargetSetupError( 239 "Could not create file in " + newDeviceDir.toString()); 240 } 241 } 242 }; 243 mk.setConfiguration(new Configuration("name", "desc")); 244 File deviceImage = FileUtil.createTempFile("device-img-12345", "zip"); 245 File kernelImage = FileUtil.createTempFile("dtbo", "img"); 246 File testsDir = FileUtil.createTempDir("testsdir"); 247 OptionSetter setter = new OptionSetter(mk); 248 setter.setOptionValue("mix-kernel-tool-name", "my_tool_12345"); 249 File mixKernelTool = FileUtil.createTempFile("my_tool_12345", null, testsDir); 250 mixKernelTool.renameTo(new File(testsDir, "my_tool_12345")); 251 mBuildInfo.setFile("device", deviceImage, "0"); 252 mBuildInfo.setFile("{kernel}Image.gz", kernelImage, "0"); 253 mBuildInfo.setTestsDir(testsDir, "0"); 254 try { 255 mk.setUp(mTestInfo); 256 } finally { 257 FileUtil.recursiveDelete(deviceImage); 258 FileUtil.recursiveDelete(kernelImage); 259 FileUtil.recursiveDelete(testsDir); 260 } 261 } 262 263 @Test testSuccessfulMixKernelWithLocalToolPath()264 public void testSuccessfulMixKernelWithLocalToolPath() throws Exception { 265 MixKernelTargetPreparer mk = 266 new MixKernelTargetPreparer() { 267 @Override 268 protected void runMixKernelTool( 269 ITestDevice device, 270 File oldDeviceDir, 271 File kernelDir, 272 File gkiDir, 273 File newDeviceDir) 274 throws TargetSetupError { 275 try { 276 File newFile = 277 FileUtil.createTempFile( 278 "new-device-img-12345", "zip", newDeviceDir); 279 newFile.renameTo(new File(newDeviceDir, "device-img-12345.zip")); 280 } catch (IOException e) { 281 throw new TargetSetupError( 282 "Could not create file in " + newDeviceDir.toString()); 283 } 284 } 285 }; 286 mk.setConfiguration(new Configuration("name", "desc")); 287 File deviceImage = FileUtil.createTempFile("device-img-12345", "zip"); 288 File kernelImage = FileUtil.createTempFile("dtbo", "img"); 289 File toolDir = FileUtil.createTempDir("tooldir"); 290 File mixKernelTool = FileUtil.createTempFile("my_tool_12345", null, toolDir); 291 mBuildInfo.setFile("device", deviceImage, "0"); 292 mBuildInfo.setFile("{kernel}Image.gz", kernelImage, "0"); 293 OptionSetter setter = new OptionSetter(mk); 294 setter.setOptionValue("mix-kernel-tool-path", mixKernelTool.getAbsolutePath()); 295 try { 296 mk.setUp(mTestInfo); 297 } finally { 298 FileUtil.recursiveDelete(deviceImage); 299 FileUtil.recursiveDelete(kernelImage); 300 FileUtil.recursiveDelete(toolDir); 301 } 302 } 303 304 @Test testSetNewDeviceImage()305 public void testSetNewDeviceImage() throws Exception { 306 MixKernelTargetPreparer mk = new MixKernelTargetPreparer(); 307 mk.setConfiguration(new Configuration("name", "desc")); 308 // Create a device image in lc cache 309 File deviceImageInLcCache = FileUtil.createTempFile("device-img-12345", ".zip"); 310 FileUtil.writeToFile("old_image_12345", deviceImageInLcCache); 311 // Create the device image with hardlink to device image in lc cache 312 File tmpImg = FileUtil.createTempFile("device-img-hard-link", ".zip"); 313 tmpImg.delete(); 314 FileUtil.hardlinkFile(deviceImageInLcCache, tmpImg); 315 // Add the device image with hardlink to device build info 316 mBuildInfo.setFile("device", tmpImg, "0"); 317 // Create a new device image in the device_dir 318 File newImageDir = FileUtil.createTempDir("device_dir"); 319 File deviceImage = new File(newImageDir, "device-img-12345.zip"); 320 FileUtil.writeToFile("new_image", deviceImage); 321 try { 322 if (deviceImageInLcCache.length() != mBuildInfo.getDeviceImageFile().length()) { 323 Assert.fail( 324 "Device image in lc cache is not of the same size as device image" 325 + " in device build info before calling setNewDeviceImage"); 326 } 327 mk.setNewDeviceImage(mBuildInfo, newImageDir); 328 if (mBuildInfo.getDeviceImageFile() == null 329 || !mBuildInfo.getDeviceImageFile().exists()) { 330 Assert.fail("New device image is not set"); 331 } 332 if (deviceImageInLcCache == null || !deviceImageInLcCache.exists()) { 333 Assert.fail("Device image in lc cache is gone"); 334 } 335 if (deviceImageInLcCache.length() == mBuildInfo.getDeviceImageFile().length()) { 336 Assert.fail( 337 "Device image in lc cache is of the same size as device image " 338 + "in device build info after calling setNewDeviceImage"); 339 } 340 } finally { 341 FileUtil.recursiveDelete(deviceImageInLcCache); 342 FileUtil.recursiveDelete(tmpImg); 343 FileUtil.recursiveDelete(newImageDir); 344 } 345 } 346 } 347