120225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki/* 220225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki * Copyright (C) 2010 The Android Open Source Project 320225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki * 420225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki * Licensed under the Apache License, Version 2.0 (the "License"); 520225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki * you may not use this file except in compliance with the License. 620225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki * You may obtain a copy of the License at 720225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki * 820225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki * http://www.apache.org/licenses/LICENSE-2.0 920225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki * 1020225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki * Unless required by applicable law or agreed to in writing, software 1120225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki * distributed under the License is distributed on an "AS IS" BASIS, 1220225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki * See the License for the specific language governing permissions and 1420225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki * limitations under the License. 1520225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki */ 1620225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki 1720225d57609d6a5e482c088fdad60c29212d31a0Makoto Onukipackage com.android.email; 1820225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki 19e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onukiimport android.app.KeyguardManager; 20e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onukiimport android.content.Context; 21e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onukiimport android.os.PowerManager; 22fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onukiimport android.test.MoreAsserts; 2357f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onukiimport android.test.suitebuilder.annotation.LargeTest; 247c1fa2c16195098453b3f3bd9c44a1f7a058e356Makoto Onukiimport android.view.View; 257c1fa2c16195098453b3f3bd9c44a1f7a058e356Makoto Onukiimport android.view.ViewParent; 2620225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki 2717d3a29c9d8f7a27c463239f190bdcc4e0804527Jerry Xieimport com.android.emailcommon.Logging; 2817d3a29c9d8f7a27c463239f190bdcc4e0804527Jerry Xieimport com.android.mail.utils.LogUtils; 2917d3a29c9d8f7a27c463239f190bdcc4e0804527Jerry Xie 3057f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onukiimport junit.framework.AssertionFailedError; 3120225d57609d6a5e482c088fdad60c29212d31a0Makoto Onukiimport junit.framework.TestCase; 3220225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki 3320225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki/** 3420225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki * Utility methods used only by tests. 3520225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki */ 3657f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki@LargeTest 3720225d57609d6a5e482c088fdad60c29212d31a0Makoto Onukipublic class TestUtils extends TestCase /* It tests itself */ { 3857f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki public interface Condition { 3957f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki public boolean isMet(); 4057f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 4157f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki 4220225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki /** Shortcut to create byte array */ 4320225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki public static byte[] b(int... array) { 4420225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki if (array == null) { 4520225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki return null; 4620225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki } 4720225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki byte[] ret = new byte[array.length]; 4820225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki for (int i = 0; i < ret.length; i++) { 4920225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki ret[i] = (byte) array[i]; 5020225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki } 5120225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki return ret; 5220225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki } 5320225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki 54fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki public void testB() { 55fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki assertNull(b(null)); 56fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki MoreAsserts.assertEquals(new byte[] {}, b()); 57fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki MoreAsserts.assertEquals(new byte[] {1, 2, (byte) 0xff}, b(1, 2, 0xff)); 5820225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki } 5957f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki 6057f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki /** 6157f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki * Run {@code runnable} and fails if it doesn't throw a {@code expectedThrowable} or a subclass 6257f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki * of it. 6357f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki */ 6457f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki public static void expectThrowable(Runnable runnable, 6557f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki Class<? extends Throwable> expectedThrowable) { 6657f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki try { 6757f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki runnable.run(); 6857f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki fail("Expected throwable not thrown."); 6957f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } catch (Throwable th) { 7057f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki if (expectedThrowable.isAssignableFrom(th.getClass())) { 7157f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki return; // Expcted. OK 7257f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 7357f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki fail("Cought unexpected throwable " + th.getClass().getName()); 7457f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 7557f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 7657f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki 7757f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki public void testExpectThrowable() { 7857f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki try { 7957f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki expectThrowable(new Runnable() { 8057f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki @Override public void run() { 8157f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki // Throwing no exception 8257f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 8357f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki }, Throwable.class); 8457f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki fail(); 8557f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } catch (AssertionFailedError ok) { 8657f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 8757f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki 8857f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki try { 8957f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki expectThrowable(new Runnable() { 9057f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki @Override public void run() { 9157f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki // Throw RuntimeException, which is not a subclass of Error. 9257f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki throw new RuntimeException(); 9357f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 9457f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki }, Error.class); 9557f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki fail(); 9657f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } catch (AssertionFailedError ok) { 9757f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 9857f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki 9957f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki expectThrowable(new Runnable() { 10057f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki @Override public void run() { 10157f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki throw new RuntimeException(); 10257f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 10357f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki }, Exception.class); 10457f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 10557f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki 10657f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki /** 10757f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki * Wait until a {@code Condition} is met. 10857f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki */ 109206d4e842d287a7a4e6bedf4963fb7f0f58e113fMakoto Onuki public static void waitUntil(Condition condition, int timeoutSeconds) { 110206d4e842d287a7a4e6bedf4963fb7f0f58e113fMakoto Onuki waitUntil("", condition, timeoutSeconds); 111206d4e842d287a7a4e6bedf4963fb7f0f58e113fMakoto Onuki } 112206d4e842d287a7a4e6bedf4963fb7f0f58e113fMakoto Onuki 113206d4e842d287a7a4e6bedf4963fb7f0f58e113fMakoto Onuki /** 114206d4e842d287a7a4e6bedf4963fb7f0f58e113fMakoto Onuki * Wait until a {@code Condition} is met. 115206d4e842d287a7a4e6bedf4963fb7f0f58e113fMakoto Onuki */ 11657f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki public static void waitUntil(String message, Condition condition, int timeoutSeconds) { 117560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.d(Logging.LOG_TAG, message + ": Waiting..."); 11857f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki final long timeout = System.currentTimeMillis() + timeoutSeconds * 1000; 11957f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki while (System.currentTimeMillis() < timeout) { 12057f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki if (condition.isMet()) { 12157f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki return; 12257f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 12357f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki try { 12457f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki Thread.sleep(500); 12557f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } catch (InterruptedException ignore) { 12657f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 12757f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 12857f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki fail(message + ": Timeout"); 12957f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 13057f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki 13157f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki public void testWaitUntil() { 13257f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki // Shouldn't fail. 13357f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki waitUntil("message", new Condition() { 13457f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki @Override public boolean isMet() { 13557f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki return true; 13657f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 13757f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki }, 1000000); 13857f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki 13957f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki expectThrowable(new Runnable() { 14057f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki @Override public void run() { 14157f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki // Condition never meets, should fail. 14257f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki waitUntil("message", new Condition() { 14357f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki @Override public boolean isMet() { 14457f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki return false; 14557f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 14657f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki }, 0); 14757f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 14857f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki }, AssertionFailedError.class); 14957f4d0222b0a5647793d7ea14acda055223ea11dMakoto Onuki } 150e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onuki 151e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onuki /** 152e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onuki * @return true if the screen is on and not locked; false otherwise, in which case tests that 153e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onuki * send key events will fail. 154e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onuki */ 155e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onuki public static boolean isScreenOnAndNotLocked(Context context) { 156e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onuki PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 157e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onuki if (!pm.isScreenOn()) { 158e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onuki return false; 159e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onuki } 160e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onuki KeyguardManager km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE); 161e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onuki if (km.inKeyguardRestrictedInputMode()) { 162e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onuki return false; 163e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onuki } 164e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onuki return true; 165e9919377ee02958da4f2d2dde3b65c93505b4343Makoto Onuki } 1667c1fa2c16195098453b3f3bd9c44a1f7a058e356Makoto Onuki 1677c1fa2c16195098453b3f3bd9c44a1f7a058e356Makoto Onuki public static void assertViewVisible(View v) { 1687c1fa2c16195098453b3f3bd9c44a1f7a058e356Makoto Onuki if (v == null) { 1697c1fa2c16195098453b3f3bd9c44a1f7a058e356Makoto Onuki throw new NullPointerException(); 1707c1fa2c16195098453b3f3bd9c44a1f7a058e356Makoto Onuki } 1717c1fa2c16195098453b3f3bd9c44a1f7a058e356Makoto Onuki for (;;) { 1727c1fa2c16195098453b3f3bd9c44a1f7a058e356Makoto Onuki assertTrue("visibility for " + v, View.VISIBLE == v.getVisibility()); 1737c1fa2c16195098453b3f3bd9c44a1f7a058e356Makoto Onuki ViewParent parent = v.getParent(); 1747c1fa2c16195098453b3f3bd9c44a1f7a058e356Makoto Onuki if (parent == null || !(parent instanceof View)) { 1757c1fa2c16195098453b3f3bd9c44a1f7a058e356Makoto Onuki break; 1767c1fa2c16195098453b3f3bd9c44a1f7a058e356Makoto Onuki } 1777c1fa2c16195098453b3f3bd9c44a1f7a058e356Makoto Onuki v = (View) parent; 1787c1fa2c16195098453b3f3bd9c44a1f7a058e356Makoto Onuki } 1797c1fa2c16195098453b3f3bd9c44a1f7a058e356Makoto Onuki } 18020225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki} 181