1 /*
2  * Copyright (C) 2023 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 
17 package android.tools.traces
18 
19 /**
20  * The utility class to wait a condition with customized options. The default retry policy is 5
21  * times with interval 1 second.
22  *
23  * @param <T> The type of the object to validate.
24  *
25  * <p>Sample:</p> <pre> // Simple case. if (Condition.waitFor("true value", () -> true)) {
26  *
27  * ```
28  *     println("Success");
29  * ```
30  *
31  * } // Wait for customized result with customized validation. String result =
32  * Condition.waitForResult(new Condition<String>("string comparison")
33  *
34  * ```
35  *         .setResultSupplier(() -> "Result string")
36  *         .setResultValidator(str -> str.equals("Expected string"))
37  *         .setRetryIntervalMs(500)
38  *         .setRetryLimit(3)
39  *         .setOnFailure(str -> println("Failed on " + str)));
40  * ```
41  *
42  * </pre>
43  *
44  * @param message The message to show what is waiting for.
45  * @param condition If it returns true, that means the condition is satisfied.
46  */
47 open class Condition<T>(
48     protected open val message: String = "",
49     protected open val condition: (T) -> Boolean
50 ) {
51     /** @return if [value] satisfies the condition */
isSatisfiednull52     fun isSatisfied(value: T): Boolean {
53         return condition.invoke(value)
54     }
55 
56     /** @return the negation of the current assertion */
<lambda>null57     fun negate(): Condition<T> = Condition(message = "!$message") { !this.condition.invoke(it) }
58 
59     /** @return a formatted message for the passing or failing condition on a state */
getMessagenull60     open fun getMessage(value: T): String = "$message(passed=${isSatisfied(value)})"
61 
62     override fun toString(): String = this.message
63 }
64