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.compatibility.common.tradefed.build.CompatibilityBuildHelper;
19 import com.android.tradefed.config.Option;
20 import com.android.tradefed.invoker.IInvocationContext;
21 import com.android.tradefed.invoker.InvocationContext;
22 import com.android.tradefed.log.LogUtil.CLog;
23 import com.android.tradefed.result.proto.FileProtoResultReporter;
24 import com.android.tradefed.result.proto.ProtoResultParser;
25 import com.android.tradefed.result.proto.TestRecordProto.TestRecord;
26 import com.android.tradefed.util.FileUtil;
27 
28 import java.io.File;
29 import java.io.FileNotFoundException;
30 import java.io.IOException;
31 
32 /** Proto reporter that will drop a {@link TestRecord} protobuf in the result directory. */
33 public class CompatibilityProtoResultReporter extends FileProtoResultReporter {
34 
35     public static final String PROTO_FILE_NAME = "test-record.pb";
36     public static final String PROTO_DIR = "proto";
37 
38     @Option(
39             name = "skip-proto-compacting",
40             description = "Option to disable compacting the protos at the end")
41     private boolean mSkipProtoCompacting = false;
42 
43     private CompatibilityBuildHelper mBuildHelper;
44 
45     /** The directory containing the proto results */
46     private File mResultDir = null;
47 
48     private File mBaseProtoFile = null;
49 
50     @Override
processStartInvocation( TestRecord invocationStartRecord, IInvocationContext invocationContext)51     public void processStartInvocation(
52             TestRecord invocationStartRecord, IInvocationContext invocationContext) {
53         if (mBuildHelper == null) {
54             mBuildHelper = new CompatibilityBuildHelper(invocationContext.getBuildInfos().get(0));
55             mResultDir = getProtoResultDirectory();
56             mBaseProtoFile = new File(mResultDir, PROTO_FILE_NAME);
57             setFileOutput(mBaseProtoFile);
58         }
59         super.processStartInvocation(invocationStartRecord, invocationContext);
60     }
61 
62     @Override
processFinalProto(TestRecord invocationEndedProto)63     public void processFinalProto(TestRecord invocationEndedProto) {
64         super.processFinalProto(invocationEndedProto);
65 
66         if (!isPeriodicWriting()) {
67             return;
68         }
69         if (mSkipProtoCompacting) {
70             return;
71         }
72         // Compact all the protos
73         try {
74             compactAllProtos();
75         } catch (RuntimeException e) {
76             CLog.e("Failed to compact the protos");
77             CLog.e(e);
78             FileUtil.deleteFile(mBaseProtoFile);
79             return;
80         }
81         // Delete all the protos we compacted
82         int index = 0;
83         while (new File(mBaseProtoFile.getAbsolutePath() + index).exists()) {
84             FileUtil.deleteFile(new File(mBaseProtoFile.getAbsolutePath() + index));
85             index++;
86         }
87     }
88 
getProtoResultDirectory()89     private File getProtoResultDirectory() {
90         File protoDir = null;
91         try {
92             File resultDir = mBuildHelper.getResultDir();
93             if (resultDir != null) {
94                 resultDir.mkdirs();
95             }
96             protoDir = new File(resultDir, PROTO_DIR);
97             protoDir.mkdir();
98         } catch (FileNotFoundException e) {
99             throw new RuntimeException(e);
100         }
101         if (!protoDir.exists()) {
102             throw new RuntimeException(
103                     "Result Directory was not created: " + protoDir.getAbsolutePath());
104         }
105         CLog.d("Proto Results Directory: %s", protoDir.getAbsolutePath());
106         return protoDir;
107     }
108 
compactAllProtos()109     private void compactAllProtos() {
110         FileProtoResultReporter fprr = new FileProtoResultReporter();
111         fprr.setFileOutput(mBaseProtoFile);
112         ProtoResultParser parser = new ProtoResultParser(fprr, new InvocationContext(), true);
113         int index = 0;
114         while (new File(mBaseProtoFile.getAbsolutePath() + index).exists()) {
115             try {
116                 parser.processFileProto(new File(mBaseProtoFile.getAbsolutePath() + index));
117             } catch (IOException e) {
118                 throw new RuntimeException(e);
119             }
120             index++;
121         }
122     }
123 }