EMMA Coverage Report (generated Fri Aug 23 16:39:17 PDT 2013)
[all classes][org.chromium.base.test.util]

COVERAGE SUMMARY FOR SOURCE FILE [TestThread.java]

nameclass, %method, %block, %line, %
TestThread.java0%   (0/3)0%   (0/13)0%   (0/218)0%   (0/51)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class TestThread0%   (0/1)0%   (0/9)0%   (0/146)0%   (0/40)
<static initializer> 0%   (0/1)0%   (0/8)0%   (0/1)
TestThread (): void 0%   (0/1)0%   (0/18)0%   (0/5)
access$000 (TestThread): Object 0%   (0/1)0%   (0/3)0%   (0/1)
access$100 (TestThread): AtomicBoolean 0%   (0/1)0%   (0/3)0%   (0/1)
checkOnMainThread (): void 0%   (0/1)0%   (0/12)0%   (0/2)
run (): void 0%   (0/1)0%   (0/16)0%   (0/5)
runOnTestThreadSync (Runnable): void 0%   (0/1)0%   (0/44)0%   (0/12)
runOnTestThreadSyncAndProcessPendingTasks (Runnable): void 0%   (0/1)0%   (0/9)0%   (0/4)
startAndWaitForReadyState (): void 0%   (0/1)0%   (0/33)0%   (0/11)
     
class TestThread$10%   (0/1)0%   (0/2)0%   (0/30)0%   (0/6)
TestThread$1 (TestThread): void 0%   (0/1)0%   (0/6)0%   (0/1)
run (): void 0%   (0/1)0%   (0/24)0%   (0/5)
     
class TestThread$20%   (0/1)0%   (0/2)0%   (0/42)0%   (0/7)
TestThread$2 (TestThread, Runnable, Object, AtomicBoolean): void 0%   (0/1)0%   (0/15)0%   (0/1)
run (): void 0%   (0/1)0%   (0/27)0%   (0/6)

1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4 
5package org.chromium.base.test.util;
6 
7import android.os.Handler;
8import android.os.Looper;
9 
10import java.util.concurrent.atomic.AtomicBoolean;
11 
12/**
13 * This class is usefull when writing instrumentation tests that exercise code that posts tasks
14 * (to the same thread).
15 * Since the test code is run in a single thread, the posted tasks are never executed.
16 * The TestThread class lets you run that code on a specific thread synchronously and flush the
17 * message loop on that thread.
18 *
19 * Example of test using this:
20 *
21 * public void testMyAwesomeClass() {
22 *   TestThread testThread = new TestThread();
23 *   testThread.startAndWaitForReadyState();
24 *
25 *   testThread.runOnTestThreadSyncAndProcessPendingTasks(new Runnable() {
26 *       @Override
27 *       public void run() {
28 *           MyAwesomeClass.doStuffAsync();
29 *       }
30 *   });
31 *   // Once we get there we know doStuffAsync has been executed and all the tasks it posted.
32 *   assertTrue(MyAwesomeClass.stuffWasDone());
33 * }
34 *
35 * Notes:
36 * - this is only for tasks posted to the same thread. Anyway if you were posting to a different
37 *   thread, you'd probably need to set that other thread up.
38 * - this only supports tasks posted using Handler.post(), it won't work with postDelayed and
39 *   postAtTime.
40 * - if your test instanciates an object and that object is the one doing the posting of tasks, you
41 *   probably want to instanciate it on the test thread as it might create the Handler it posts
42 *   tasks to in the constructor.
43 */
44 
45public class TestThread extends Thread {
46    private Object mThreadReadyLock;
47    private AtomicBoolean mThreadReady;
48    private Handler mMainThreadHandler;
49    private Handler mTestThreadHandler;
50 
51    public TestThread() {
52        mMainThreadHandler = new Handler();
53        // We can't use the AtomicBoolean as the lock or findbugs will freak out...
54        mThreadReadyLock = new Object();
55        mThreadReady = new AtomicBoolean();
56    }
57 
58    @Override
59    public void run() {
60        Looper.prepare();
61        mTestThreadHandler = new Handler();
62        mTestThreadHandler.post(new Runnable() {
63            @Override
64            public void run() {
65                synchronized (mThreadReadyLock) {
66                    mThreadReady.set(true);
67                    mThreadReadyLock.notify();
68                }
69            }
70        });
71        Looper.loop();
72    }
73 
74    /**
75     * Starts this TestThread and blocks until it's ready to accept calls.
76     */
77    public void startAndWaitForReadyState() {
78        checkOnMainThread();
79        start();
80        synchronized (mThreadReadyLock) {
81            try {
82                // Note the mThreadReady and while are not really needed.
83                // There are there so findbugs don't report warnings.
84                while (!mThreadReady.get()) {
85                    mThreadReadyLock.wait();
86                }
87            } catch (InterruptedException ie) {
88                System.err.println("Error starting TestThread.");
89                ie.printStackTrace();
90            }
91        }
92    }
93 
94    /**
95     * Runs the passed Runnable synchronously on the TestThread and returns when all pending
96     * runnables have been excuted.
97     * Should be called from the main thread.
98     */
99    public void runOnTestThreadSyncAndProcessPendingTasks(Runnable r) {
100        checkOnMainThread();
101 
102        runOnTestThreadSync(r);
103 
104        // Run another task, when it's done it means all pendings tasks have executed.
105        runOnTestThreadSync(null);
106    }
107 
108    /**
109     * Runs the passed Runnable on the test thread and blocks until it has finished executing.
110     * Should be called from the main thread.
111     * @param r The runnable to be executed.
112     */
113    public void runOnTestThreadSync(final Runnable r) {
114        checkOnMainThread();
115        final Object lock = new Object();
116        // Task executed is not really needed since we are only on one thread, it is here to appease
117        // findbugs.
118        final AtomicBoolean taskExecuted = new AtomicBoolean();
119        mTestThreadHandler.post(new Runnable() {
120            @Override
121            public void run() {
122                if (r != null) r.run();
123                synchronized (lock) {
124                    taskExecuted.set(true);
125                    lock.notify();
126                }
127            }
128        });
129        synchronized (lock) {
130            try {
131                while (!taskExecuted.get()) {
132                    lock.wait();
133                }
134            } catch (InterruptedException ie) {
135                ie.printStackTrace();
136            }
137        }
138    }
139 
140    private void checkOnMainThread() {
141        assert Looper.myLooper() == mMainThreadHandler.getLooper();
142    }
143}

[all classes][org.chromium.base.test.util]
EMMA 2.0.5312 (C) Vladimir Roubtsov