1 /*
2  * Copyright (C) 2015 Google Inc.
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 
17 package android.location.cts;
18 
19 import junit.framework.Assert;
20 
21 import android.util.Log;
22 
23 import java.util.ArrayList;
24 import java.util.List;
25 
26 /**
27  * Custom Assertion class. This is useful for doing multiple validations together
28  * without failing the test. Tests don’t stop running even if an assertion condition fails,
29  * but the test itself is marked as a failed test to indicate the right result
30  * at the end of the test.
31  */
32 public class SoftAssert {
33 
34     List<String> mErrorList;
35     private String mTag;
36 
SoftAssert(String source)37     SoftAssert(String source) {
38         mErrorList = new ArrayList<>();
39         mTag = source;
40     }
41 
42     /**
43      * Check if condition is true
44      *
45      * @param message        test message
46      * @param eventTimeInNs  the time at which the condition occurred
47      * @param expectedResult expected value
48      * @param actualResult   actual value
49      * @param condition      condition for test
50      */
assertTrue(String message, long eventTimeInNs, String expectedResult, String actualResult, boolean condition)51     public void assertTrue(String message, long eventTimeInNs, String expectedResult,
52                            String actualResult, boolean condition) {
53         if (condition) {
54             Log.i(mTag, message + ", (Test: PASS, actual : " +
55                     actualResult + ", expected: " + expectedResult + ")");
56         } else {
57             String errorMessage = "At time = " + eventTimeInNs + " ns, " + message +
58                     " (Test: FAIL, actual :" + actualResult + ", " +
59                     "expected: " + expectedResult + ")";
60             Log.e(mTag, errorMessage);
61             mErrorList.add(errorMessage);
62         }
63     }
64 
65     /**
66      * Check if a condition is true.
67      * NOTE: A failure is downgraded to a warning.
68      *
69      * @param message        the message associated with the condition
70      * @param eventTimeInNs  the time at which the condition occurred
71      * @param expectedResult the expected result of the condition
72      * @param actualResult   the actual result of the condition
73      * @param condition      the condition status
74      */
assertTrueAsWarning( String message, long eventTimeInNs, String expectedResult, String actualResult, boolean condition)75     public void assertTrueAsWarning(
76             String message,
77             long eventTimeInNs,
78             String expectedResult,
79             String actualResult,
80             boolean condition) {
81         if (condition) {
82             String formattedMessage = String.format(
83                     "%s, (Test: PASS, actual : %s, expected : %s)",
84                     message,
85                     actualResult,
86                     expectedResult);
87             Log.i(mTag, formattedMessage);
88         } else {
89             String formattedMessage = String.format(
90                     "At time = %d ns, %s (Test: WARNING, actual : %s, expected : %s).",
91                     eventTimeInNs,
92                     message,
93                     actualResult,
94                     expectedResult);
95             failAsWarning(mTag, formattedMessage);
96         }
97     }
98 
99     /**
100      * Check if condition is true
101      *
102      * @param message   test message
103      * @param condition condition for test
104      */
assertTrue(String message, boolean condition)105     public void assertTrue(String message, boolean condition) {
106         assertOrWarnTrue(true, message, condition);
107     }
108 
109     /**
110      * Check if condition is true
111      *
112      * @param strict      if true, add this to the failure list, else, log a warning message
113      * @param message     message to describe the test - output on pass or fail
114      * @param condition   condition for test
115      */
assertOrWarnTrue(boolean strict, String message, boolean condition)116     public void assertOrWarnTrue(boolean strict, String message, boolean condition) {
117         if (condition) {
118             Log.i(mTag, "(Test: PASS) " + message);
119         } else {
120             String errorMessage = "(Test: FAIL) " + message;
121             Log.i(mTag, errorMessage);
122             if (strict) {
123                 mErrorList.add(errorMessage);
124             } else {
125                 failAsWarning(mTag, errorMessage);
126             }
127         }
128     }
129 
130     /**
131      * Assert all conditions together. This method collates all the failures and decides
132      * whether to fail the test or not at the end. This must be called at the end of the test.
133      */
assertAll()134     public void assertAll() {
135         if (mErrorList.isEmpty()) {
136             Log.i(mTag, "All test pass.");
137             // Test pass if there are no error message in errorMessageSet
138             Assert.assertTrue(true);
139         } else {
140             StringBuilder message = new StringBuilder();
141             for (String msg : mErrorList) {
142                 message.append(msg + "\n");
143             }
144             Log.e(mTag, "Failing tests are: \n" + message);
145             Assert.fail("Failing tests are: \n" + message);
146         }
147     }
148 
149     /**
150      * A hard or soft failure, depending on the setting.
151      * TODO - make this cleaner - e.g. refactor this out completely: get rid of static methods,
152      * and make a class (say TestVerification) the only entry point for verifications,
153      * so strict vs not can be abstracted away test implementations.
154      */
failOrWarning(boolean testIsStrict, String message, boolean condition)155     public static void failOrWarning(boolean testIsStrict, String message, boolean condition) {
156         if (testIsStrict) {
157             Assert.assertTrue(message, condition);
158         } else {
159             failAsWarning("", message);
160         }
161     }
162 
163     /**
164      * A soft failure. In the current state of the tests, it will only log a warning and let the
165      * test be reported as 'pass'.
166      */
failAsWarning(String tag, String message)167     public static void failAsWarning(String tag, String message) {
168         Log.w(tag, message + " [NOTE: in a future release this feature might become mandatory, and"
169                 + " this warning will fail the test].");
170     }
171 }
172