1 /* 2 * Copyright (C) 2018 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.compatibility.common.tradefed.result.suite; 17 18 import com.android.annotations.VisibleForTesting; 19 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; 20 import com.android.compatibility.common.util.ChecksumReporter; 21 import com.android.compatibility.common.util.ResultHandler; 22 import com.android.tradefed.build.IBuildInfo; 23 import com.android.tradefed.invoker.IInvocationContext; 24 import com.android.tradefed.log.LogUtil.CLog; 25 import com.android.tradefed.result.ITestInvocationListener; 26 import com.android.tradefed.util.FileUtil; 27 28 import java.io.File; 29 import java.io.FileNotFoundException; 30 import java.io.IOException; 31 import java.util.Arrays; 32 import java.util.List; 33 34 /** 35 * Recursively copy all the files from a previous session into the current one if they don't exists 36 * already. 37 */ 38 public class PreviousSessionFileCopier implements ITestInvocationListener { 39 40 private static final List<String> NOT_RETRY_FILES = 41 Arrays.asList( 42 ChecksumReporter.NAME, 43 ChecksumReporter.PREV_NAME, 44 ResultHandler.FAILURE_REPORT_NAME, 45 CertificationSuiteResultReporter.HTLM_REPORT_NAME, 46 CertificationSuiteResultReporter.FAILURE_REPORT_NAME, 47 CertificationSuiteResultReporter.SUMMARY_FILE, 48 CertificationChecksumHelper.NAME, 49 "diffs", 50 "proto"); 51 52 private CompatibilityBuildHelper mBuildHelper; 53 private File mPreviousSessionDir = null; 54 55 /** Sets the previous session directory to copy from. */ setPreviousSessionDir(File previousSessionDir)56 public void setPreviousSessionDir(File previousSessionDir) { 57 mPreviousSessionDir = previousSessionDir; 58 } 59 60 @Override invocationStarted(IInvocationContext context)61 public void invocationStarted(IInvocationContext context) { 62 if (mBuildHelper == null) { 63 mBuildHelper = createCompatibilityHelper(context.getBuildInfos().get(0)); 64 } 65 } 66 67 @Override invocationEnded(long elapsedTime)68 public void invocationEnded(long elapsedTime) { 69 if (mPreviousSessionDir == null) { 70 CLog.e("Could not copy previous sesson files."); 71 return; 72 } 73 File resultDir = getResultDirectory(); 74 copyRetryFiles(mPreviousSessionDir, resultDir); 75 } 76 77 @VisibleForTesting createCompatibilityHelper(IBuildInfo info)78 protected CompatibilityBuildHelper createCompatibilityHelper(IBuildInfo info) { 79 return new CompatibilityBuildHelper(info); 80 } 81 82 /** 83 * Recursively copy any other files found in the previous session's result directory to the new 84 * result directory, so long as they don't already exist. For example, a "screenshots" directory 85 * generated in a previous session by a passing test will not be generated on retry unless 86 * copied from the old result directory. 87 * 88 * @param oldDir 89 * @param newDir 90 */ copyRetryFiles(File oldDir, File newDir)91 private void copyRetryFiles(File oldDir, File newDir) { 92 File[] oldChildren = oldDir.listFiles(); 93 for (File oldChild : oldChildren) { 94 if (NOT_RETRY_FILES.contains(oldChild.getName())) { 95 continue; // do not copy this file/directory or its children 96 } 97 File newChild = new File(newDir, oldChild.getName()); 98 if (!newChild.exists()) { 99 // If this old file or directory doesn't exist in new dir, simply copy it 100 try { 101 CLog.d("Copying %s to new session.", oldChild.getName()); 102 if (oldChild.isDirectory()) { 103 FileUtil.recursiveCopy(oldChild, newChild); 104 } else { 105 FileUtil.copyFile(oldChild, newChild); 106 } 107 } catch (IOException e) { 108 CLog.w("Failed to copy file \"%s\" from previous session", oldChild.getName()); 109 } 110 } else if (oldChild.isDirectory() && newChild.isDirectory()) { 111 // If both children exist as directories, make sure the children of the old child 112 // directory exist in the new child directory. 113 copyRetryFiles(oldChild, newChild); 114 } 115 } 116 } 117 getResultDirectory()118 private File getResultDirectory() { 119 File resultDir = null; 120 try { 121 resultDir = mBuildHelper.getResultDir(); 122 if (resultDir != null) { 123 resultDir.mkdirs(); 124 } 125 } catch (FileNotFoundException e) { 126 throw new RuntimeException(e); 127 } 128 if (resultDir == null) { 129 throw new RuntimeException("Result Directory was not created"); 130 } 131 if (!resultDir.exists()) { 132 throw new RuntimeException( 133 "Result Directory was not created: " + resultDir.getAbsolutePath()); 134 } 135 CLog.d("Results Directory: %s", resultDir.getAbsolutePath()); 136 return resultDir; 137 } 138 } 139