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