• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.net.urlconnection;
6 
7 import static com.google.common.truth.Truth.assertThat;
8 
9 import static org.junit.Assert.assertThrows;
10 
11 import androidx.test.ext.junit.runners.AndroidJUnit4;
12 import androidx.test.filters.SmallTest;
13 
14 import org.junit.Test;
15 import org.junit.runner.RunWith;
16 
17 import org.chromium.base.test.util.Batch;
18 
19 import java.io.InterruptedIOException;
20 import java.net.SocketTimeoutException;
21 import java.util.concurrent.ExecutorService;
22 import java.util.concurrent.Executors;
23 import java.util.concurrent.Future;
24 import java.util.concurrent.ThreadFactory;
25 
26 /** Tests the MessageLoop implementation. */
27 @Batch(Batch.UNIT_TESTS)
28 @RunWith(AndroidJUnit4.class)
29 public class MessageLoopTest {
30     private Thread mTestThread;
31     private final ExecutorService mExecutorService =
32             Executors.newSingleThreadExecutor(new ExecutorThreadFactory());
33 
34     private class ExecutorThreadFactory implements ThreadFactory {
35         @Override
newThread(Runnable r)36         public Thread newThread(Runnable r) {
37             mTestThread = new Thread(r);
38             return mTestThread;
39         }
40     }
41 
42     private boolean mFailed;
43 
44     @Test
45     @SmallTest
testInterrupt()46     public void testInterrupt() throws Exception {
47         final MessageLoop loop = new MessageLoop();
48         assertThat(loop.isRunning()).isFalse();
49         Future future =
50                 mExecutorService.submit(
51                         new Runnable() {
52                             @Override
53                             public void run() {
54                                 assertThrows(InterruptedIOException.class, loop::loop);
55                             }
56                         });
57         Thread.sleep(1000);
58         assertThat(loop.isRunning()).isTrue();
59         assertThat(loop.hasLoopFailed()).isFalse();
60         mTestThread.interrupt();
61         future.get();
62         assertThat(loop.isRunning()).isFalse();
63         assertThat(loop.hasLoopFailed()).isTrue();
64         // Re-spinning the message loop is not allowed after interrupt.
65         mExecutorService
66                 .submit(
67                         new Runnable() {
68                             @Override
69                             public void run() {
70                                 assertThrows(InterruptedIOException.class, loop::loop);
71                             }
72                         })
73                 .get();
74     }
75 
76     @Test
77     @SmallTest
testTaskFailed()78     public void testTaskFailed() throws Exception {
79         final MessageLoop loop = new MessageLoop();
80         assertThat(loop.isRunning()).isFalse();
81         Future future =
82                 mExecutorService.submit(
83                         new Runnable() {
84                             @Override
85                             public void run() {
86                                 assertThrows(NullPointerException.class, loop::loop);
87                             }
88                         });
89         Runnable failedTask =
90                 new Runnable() {
91                     @Override
92                     public void run() {
93                         throw new NullPointerException();
94                     }
95                 };
96         Thread.sleep(1000);
97         assertThat(loop.isRunning()).isTrue();
98         assertThat(loop.hasLoopFailed()).isFalse();
99         loop.execute(failedTask);
100         future.get();
101         assertThat(loop.isRunning()).isFalse();
102         assertThat(loop.hasLoopFailed()).isTrue();
103         // Re-spinning the message loop is not allowed after exception.
104         mExecutorService
105                 .submit(
106                         new Runnable() {
107                             @Override
108                             public void run() {
109                                 assertThrows(NullPointerException.class, loop::loop);
110                             }
111                         })
112                 .get();
113     }
114 
115     @Test
116     @SmallTest
testLoopWithTimeout()117     public void testLoopWithTimeout() throws Exception {
118         final MessageLoop loop = new MessageLoop();
119         assertThat(loop.isRunning()).isFalse();
120         // The MessageLoop queue is empty. Use a timeout of 100ms to check that
121         // it doesn't block forever.
122         assertThrows(SocketTimeoutException.class, () -> loop.loop(100));
123         assertThat(loop.isRunning()).isFalse();
124     }
125 }
126