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 package com.android.compatibility.common.tradefed.result;
17 
18 import com.android.compatibility.common.tradefed.build.CompatibilityBuildProvider;
19 import com.android.compatibility.common.util.ChecksumReporter;
20 import com.android.compatibility.common.util.ChecksumReporter.ChecksumValidationException;
21 import com.android.compatibility.common.util.ICaseResult;
22 import com.android.compatibility.common.util.IInvocationResult;
23 import com.android.compatibility.common.util.IModuleResult;
24 import com.android.compatibility.common.util.ITestResult;
25 import com.android.compatibility.common.util.ReportLog;
26 import com.android.compatibility.common.util.TestStatus;
27 import com.android.tradefed.build.IBuildInfo;
28 import com.android.tradefed.config.OptionSetter;
29 import com.android.tradefed.invoker.IInvocationContext;
30 import com.android.tradefed.invoker.InvocationContext;
31 import com.android.tradefed.util.FileUtil;
32 
33 import junit.framework.TestCase;
34 
35 import java.io.File;
36 import java.io.FileWriter;
37 import java.io.IOException;
38 
39 /**
40  * Unit tests for {@link ChecksumReporter}
41  */
42 public class ChecksumReporterTest extends TestCase {
43 
44     private static final String ROOT_PROPERTY = "TESTS_ROOT";
45     private static final String ROOT_DIR_NAME = "root";
46     private static final String SUITE_NAME = "TESTS";
47     private static final String BUILD_NUMBER = "2";
48     private static final String SUITE_PLAN = "cts";
49     private static final String BASE_DIR_NAME = "android-tests";
50     private static final String TESTCASES = "testcases";
51 
52     private ChecksumReporter mReporter;
53     private File mRoot = null;
54     private IBuildInfo mBuildInfo;
55     private ReportLog mReportLog = null;
56     private IInvocationResult mInvocationResult;
57     private IModuleResult mModuleResult;
58     private ITestResult mFailedTest;
59 
60     @Override
setUp()61     public void setUp() throws Exception {
62         mReporter = new ChecksumReporter(100, .001, (short)1);
63         mRoot = FileUtil.createTempDir(ROOT_DIR_NAME);
64         File baseDir = new File(mRoot, BASE_DIR_NAME);
65         baseDir.mkdirs();
66         File testDir = new File(baseDir, TESTCASES);
67         testDir.mkdirs();
68         System.setProperty(ROOT_PROPERTY, mRoot.getAbsolutePath());
69 
70         ResultReporter resultReporter = new ResultReporter();
71         CompatibilityBuildProvider provider = new CompatibilityBuildProvider() {
72             @Override
73             protected String getSuiteInfoName() {
74                 return SUITE_NAME;
75             }
76             @Override
77             protected String getSuiteInfoBuildNumber() {
78                 return BUILD_NUMBER;
79             }
80             @Override
81             protected String getSuiteInfoVersion() {
82                 return BUILD_NUMBER;
83             }
84         };
85         OptionSetter setter = new OptionSetter(provider);
86         setter.setOptionValue("plan", SUITE_PLAN);
87         setter.setOptionValue("dynamic-config-url", "");
88         mBuildInfo = provider.getBuild();
89         IInvocationContext context = new InvocationContext();
90         context.addDeviceBuildInfo("fakeDevice", mBuildInfo);
91 
92         resultReporter.invocationStarted(context);
93         mInvocationResult = resultReporter.getResult();
94         mModuleResult = mInvocationResult.getOrCreateModule("Module-1");
95         mModuleResult.setDone(true);
96         ICaseResult caseResult = mModuleResult.getOrCreateResult("Case-1");
97         ITestResult test1 = caseResult.getOrCreateResult("Test1");
98         test1.passed(mReportLog);
99         mFailedTest = caseResult.getOrCreateResult("Test2");
100         mFailedTest.failed("stack-trace - error happened");
101 
102         IModuleResult moduleResult2 = mInvocationResult.getOrCreateModule("Module-2");
103         ICaseResult caseResult2 = moduleResult2.getOrCreateResult("Case-2");
104         mModuleResult.setDone(false);
105         ITestResult test3 = caseResult2.getOrCreateResult("Test3");
106         test3.passed(mReportLog);
107 
108     }
109 
110     @Override
tearDown()111     public void tearDown() throws Exception {
112         mReporter = null;
113         FileUtil.recursiveDelete(mRoot);
114     }
115 
testStoreAndRetrieveTestResults()116     public void testStoreAndRetrieveTestResults() {
117         mReporter.addInvocation(mInvocationResult);
118         VerifyInvocationResults(mInvocationResult, mReporter);
119     }
120 
121     /***
122      * By definition this test is flaky since the checksum has a false positive probability of .1%
123      */
testInvalidChecksums()124     public void testInvalidChecksums() {
125         mReporter.addInvocation(mInvocationResult);
126         IModuleResult module = mInvocationResult.getModules().get(1);
127         module.setDone(!module.isDone());
128         String fingerprint = mInvocationResult.getBuildFingerprint();
129         assertFalse("Checksum should contain module: " + module.getName(),
130                 mReporter.containsModuleResult(module, fingerprint));
131 
132         mFailedTest.setResultStatus(TestStatus.PASS);
133         assertFalse("Checksum should not contain test: " + mFailedTest.getName(),
134                 mReporter.containsTestResult(mFailedTest, mModuleResult, fingerprint));
135         assertFalse("Module checksum should verify number of tests",
136                 mReporter.containsModuleResult(mModuleResult, fingerprint));
137     }
138 
testFileSerialization()139     public void testFileSerialization() throws IOException, ChecksumValidationException {
140         mReporter.addInvocation(mInvocationResult);
141 
142         File file1 = new File(mRoot, "file1.txt");
143         try (FileWriter fileWriter = new FileWriter(file1, false)) {
144             fileWriter.append("This is a test file");
145         }
146 
147         mReporter.addDirectory(mRoot);
148         mReporter.saveToFile(mRoot);
149 
150         ChecksumReporter storedChecksum = ChecksumReporter.load(mRoot);
151         VerifyInvocationResults(mInvocationResult, storedChecksum);
152         assertTrue("Serializing checksum maintains file hash",
153                 storedChecksum.containsFile(file1, mRoot.getName()));
154     }
155 
testFileCRCOperations()156     public void testFileCRCOperations() throws IOException {
157         File subDirectory = new File(mRoot, "child");
158         subDirectory.mkdir();
159         File file1 = new File(mRoot, "file1.txt");
160         try (FileWriter fileWriter = new FileWriter(file1, false)) {
161             fileWriter.append("This is a test file");
162         }
163 
164         File file2 = new File(subDirectory, "file2.txt");
165         try (FileWriter fileWriter = new FileWriter(file2, false)) {
166             fileWriter.append("This is another test file with a different crc");
167         }
168 
169         mReporter.addDirectory(mRoot);
170         String folderName = mRoot.getName();
171         assertTrue(mReporter.containsFile(file1, folderName));
172         assertTrue(mReporter.containsFile(file2, folderName + "/child"));
173         assertFalse("Should not contain non-existent file",
174                 mReporter.containsFile(new File(mRoot, "fake.txt"), folderName));
175 
176         File file3 = new File(mRoot, "file3.txt");
177         try (FileWriter fileWriter = new FileWriter(file3, false)) {
178             fileWriter.append("This is a test file added after crc calculated");
179         }
180         assertFalse("Should not contain file created after crc calculated",
181                 mReporter.containsFile(file3, mRoot + "/"));
182 
183     }
184 
VerifyInvocationResults(IInvocationResult invocation, ChecksumReporter reporter)185     private void VerifyInvocationResults(IInvocationResult invocation, ChecksumReporter reporter) {
186         for (IModuleResult module : invocation.getModules()) {
187             String buildFingerprint = invocation.getBuildFingerprint();
188             assertTrue("Checksum should contain module: " + module.getName(),
189                     reporter.containsModuleResult(module, buildFingerprint));
190             for (ICaseResult caseResult : module.getResults()) {
191                 for (ITestResult result : caseResult.getResults()) {
192                     assertTrue("Checksum should contain test: " + result.getName(),
193                             reporter.containsTestResult(result, module, buildFingerprint));
194                 }
195             }
196         }
197     }
198 }
199