1914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal/*
2914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * Copyright (C) 2017 The Android Open Source Project
3914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal *
4914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * Licensed under the Apache License, Version 2.0 (the "License");
5914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * you may not use this file except in compliance with the License.
6914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * You may obtain a copy of the License at
7914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal *
8914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal *      http://www.apache.org/licenses/LICENSE-2.0
9914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal *
10914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * Unless required by applicable law or agreed to in writing, software
11914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * distributed under the License is distributed on an "AS IS" BASIS,
12914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * See the License for the specific language governing permissions and
14914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * limitations under the License.
15914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal */
16914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
176d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikaspackage android.support.testutils;
18914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
196d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikasimport org.junit.Assert;
20914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
216d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas/**
226d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas * Utility used for testing that allows to poll for a certain condition to happen within a timeout.
236d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas */
24914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalpublic abstract class PollingCheck {
256d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas    private static final long DEFAULT_TIMEOUT = 3000;
26914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    private static final long TIME_SLICE = 50;
276d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas    private final long mTimeout;
28914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
296d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas    /**
306d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas     * The condition that the PollingCheck should use to proceed successfully.
316d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas     */
32914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    public interface PollingCheckCondition {
336d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas        /**
346d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas         * @return Whether the polling condition has been met.
356d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas         */
36914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        boolean canProceed();
37914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    }
38914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
39914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    public PollingCheck(long timeout) {
40914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        mTimeout = timeout;
41914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    }
42914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
43914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    protected abstract boolean check();
44914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
456d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas    /**
466d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas     * Start running the polling check.
476d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas     */
48914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    public void run() {
49914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        if (check()) {
50914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            return;
51914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        }
52914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
53914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        long timeout = mTimeout;
54914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        while (timeout > 0) {
55914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            try {
56914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                Thread.sleep(TIME_SLICE);
57914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            } catch (InterruptedException e) {
58914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                Assert.fail("unexpected InterruptedException");
59914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            }
60914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
61914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            if (check()) {
62914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                return;
63914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            }
64914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
65914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            timeout -= TIME_SLICE;
66914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        }
67914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
68914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        Assert.fail("unexpected timeout");
69914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    }
70914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
716d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas    /**
726d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas     * Instantiate and start polling for a given condition with a default 3000ms timeout.
736d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas     * @param condition The condition to check for success.
746d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas     */
75914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    public static void waitFor(final PollingCheckCondition condition) {
766d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas        new PollingCheck(DEFAULT_TIMEOUT) {
77914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            @Override
78914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            protected boolean check() {
79914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                return condition.canProceed();
80914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            }
81914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        }.run();
82914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    }
83914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
846d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas    /**
856d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas     * Instantiate and start polling for a given condition.
866d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas     * @param timeout Time out in ms
876d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas     * @param condition The condition to check for success.
886d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikas     */
89914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    public static void waitFor(long timeout, final PollingCheckCondition condition) {
90914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        new PollingCheck(timeout) {
91914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            @Override
92914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            protected boolean check() {
93914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                return condition.canProceed();
94914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            }
95914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        }.run();
96914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    }
97914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal}
98