1e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller/* 2e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Copyright (C) 2014 Square, Inc. 3e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * 4e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Licensed under the Apache License, Version 2.0 (the "License"); 5e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * you may not use this file except in compliance with the License. 6e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * You may obtain a copy of the License at 7e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * 8e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * http://www.apache.org/licenses/LICENSE-2.0 9e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * 10e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * Unless required by applicable law or agreed to in writing, software 11e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * distributed under the License is distributed on an "AS IS" BASIS, 12e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * See the License for the specific language governing permissions and 14e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * limitations under the License. 15e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */ 16e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerpackage okio; 17e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 18e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.io.IOException; 19e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.io.InterruptedIOException; 20e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.util.Arrays; 21e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.util.List; 22e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.util.concurrent.CopyOnWriteArrayList; 23e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport java.util.concurrent.TimeUnit; 24e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport org.junit.Before; 25e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport org.junit.Test; 26e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 27e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static org.junit.Assert.assertEquals; 28e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static org.junit.Assert.assertFalse; 29e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static org.junit.Assert.assertTrue; 30e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerimport static org.junit.Assert.fail; 31e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 32e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller/** 33e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * This test uses four timeouts of varying durations: 250ms, 500ms, 750ms and 34e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * 1000ms, named 'a', 'b', 'c' and 'd'. 35e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller */ 36e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fullerpublic class AsyncTimeoutTest { 37e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private final List<Timeout> timedOut = new CopyOnWriteArrayList<Timeout>(); 38e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private final AsyncTimeout a = new RecordingAsyncTimeout(); 39e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private final AsyncTimeout b = new RecordingAsyncTimeout(); 40e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private final AsyncTimeout c = new RecordingAsyncTimeout(); 41e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private final AsyncTimeout d = new RecordingAsyncTimeout(); 42e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 43e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Before public void setUp() throws Exception { 44e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller a.timeout( 250, TimeUnit.MILLISECONDS); 45e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller b.timeout( 500, TimeUnit.MILLISECONDS); 46e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller c.timeout( 750, TimeUnit.MILLISECONDS); 47e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller d.timeout(1000, TimeUnit.MILLISECONDS); 48e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 49e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 50e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Test public void zeroTimeoutIsNoTimeout() throws Exception { 51e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller AsyncTimeout timeout = new RecordingAsyncTimeout(); 52e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.timeout(0, TimeUnit.MILLISECONDS); 53e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.enter(); 54e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Thread.sleep(250); 55e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertFalse(timeout.exit()); 56e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTimedOut(); 57e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 58e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 59e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Test public void singleInstanceTimedOut() throws Exception { 60e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller a.enter(); 61e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Thread.sleep(500); 62e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTrue(a.exit()); 63e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTimedOut(a); 64e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 65e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 66e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Test public void singleInstanceNotTimedOut() throws Exception { 67e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller b.enter(); 68e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Thread.sleep(250); 69e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller b.exit(); 70e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertFalse(b.exit()); 71e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTimedOut(); 72e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 73e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 74e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Test public void instancesAddedAtEnd() throws Exception { 75e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller a.enter(); 76e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller b.enter(); 77e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller c.enter(); 78e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller d.enter(); 79e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Thread.sleep(1250); 80e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTrue(a.exit()); 81e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTrue(b.exit()); 82e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTrue(c.exit()); 83e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTrue(d.exit()); 84e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTimedOut(a, b, c, d); 85e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 86e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 87e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Test public void instancesAddedAtFront() throws Exception { 88e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller d.enter(); 89e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller c.enter(); 90e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller b.enter(); 91e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller a.enter(); 92e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Thread.sleep(1250); 93e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTrue(d.exit()); 94e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTrue(c.exit()); 95e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTrue(b.exit()); 96e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTrue(a.exit()); 97e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTimedOut(a, b, c, d); 98e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 99e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 100e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Test public void instancesRemovedAtFront() throws Exception { 101e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller a.enter(); 102e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller b.enter(); 103e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller c.enter(); 104e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller d.enter(); 105e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertFalse(a.exit()); 106e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertFalse(b.exit()); 107e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertFalse(c.exit()); 108e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertFalse(d.exit()); 109e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTimedOut(); 110e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 111e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 112e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Test public void instancesRemovedAtEnd() throws Exception { 113e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller a.enter(); 114e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller b.enter(); 115e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller c.enter(); 116e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller d.enter(); 117e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertFalse(d.exit()); 118e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertFalse(c.exit()); 119e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertFalse(b.exit()); 120e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertFalse(a.exit()); 121e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTimedOut(); 122e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 123e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 124e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller /** Detecting double-enters is not guaranteed. */ 125e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Test public void doubleEnter() throws Exception { 126e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller a.enter(); 127e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller try { 128e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller a.enter(); 129e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller fail(); 130e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } catch (IllegalStateException expected) { 131e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 132e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 133e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 134e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Test public void deadlineOnly() throws Exception { 135e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller RecordingAsyncTimeout timeout = new RecordingAsyncTimeout(); 136e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.deadline(250, TimeUnit.MILLISECONDS); 137e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.enter(); 138e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Thread.sleep(500); 139e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTrue(timeout.exit()); 140e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTimedOut(timeout); 141e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 142e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 143e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Test public void deadlineBeforeTimeout() throws Exception { 144e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller RecordingAsyncTimeout timeout = new RecordingAsyncTimeout(); 145e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.deadline(250, TimeUnit.MILLISECONDS); 146e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.timeout(750, TimeUnit.MILLISECONDS); 147e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.enter(); 148e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Thread.sleep(500); 149e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTrue(timeout.exit()); 150e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTimedOut(timeout); 151e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 152e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 153e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Test public void deadlineAfterTimeout() throws Exception { 154e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller RecordingAsyncTimeout timeout = new RecordingAsyncTimeout(); 155e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.timeout(250, TimeUnit.MILLISECONDS); 156e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.deadline(750, TimeUnit.MILLISECONDS); 157e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.enter(); 158e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Thread.sleep(500); 159e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTrue(timeout.exit()); 160e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTimedOut(timeout); 161e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 162e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 163e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Test public void deadlineStartsBeforeEnter() throws Exception { 164e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller RecordingAsyncTimeout timeout = new RecordingAsyncTimeout(); 165e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.deadline(500, TimeUnit.MILLISECONDS); 166e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Thread.sleep(500); 167e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.enter(); 168e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Thread.sleep(250); 169e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTrue(timeout.exit()); 170e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTimedOut(timeout); 171e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 172e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 173e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Test public void deadlineInThePast() throws Exception { 174e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller RecordingAsyncTimeout timeout = new RecordingAsyncTimeout(); 175e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.deadlineNanoTime(System.nanoTime() - 1); 176e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.enter(); 177e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Thread.sleep(250); 178e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTrue(timeout.exit()); 179e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertTimedOut(timeout); 180e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 181e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 182e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Test public void wrappedSinkTimesOut() throws Exception { 183e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Sink sink = new ForwardingSink(new Buffer()) { 184e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Override public void write(Buffer source, long byteCount) throws IOException { 185e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller try { 186e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Thread.sleep(500); 187e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } catch (InterruptedException e) { 188e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller throw new AssertionError(); 189e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 190e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 191e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller }; 192e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller AsyncTimeout timeout = new AsyncTimeout(); 193e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.timeout(250, TimeUnit.MILLISECONDS); 194e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Sink timeoutSink = timeout.sink(sink); 195e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller try { 196e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeoutSink.write(null, 0); 197e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller fail(); 198e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } catch (InterruptedIOException expected) { 199e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 200e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 201e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 202e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Test public void wrappedSourceTimesOut() throws Exception { 203e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Source source = new ForwardingSource(new Buffer()) { 204e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Override public long read(Buffer sink, long byteCount) throws IOException { 205e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller try { 206e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Thread.sleep(500); 207e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller return -1; 208e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } catch (InterruptedException e) { 209e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller throw new AssertionError(); 210e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 211e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 212e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller }; 213e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller AsyncTimeout timeout = new AsyncTimeout(); 214e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.timeout(250, TimeUnit.MILLISECONDS); 215e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Source timeoutSource = timeout.source(source); 216e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller try { 217e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeoutSource.read(null, 0); 218e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller fail(); 219e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } catch (InterruptedIOException expected) { 220e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 221e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 222e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 223e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Test public void wrappedThrowsWithTimeout() throws Exception { 224e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Sink sink = new ForwardingSink(new Buffer()) { 225e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Override public void write(Buffer source, long byteCount) throws IOException { 226e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller try { 227e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Thread.sleep(500); 228e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller throw new IOException("exception and timeout"); 229e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } catch (InterruptedException e) { 230e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller throw new AssertionError(); 231e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 232e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 233e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller }; 234e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller AsyncTimeout timeout = new AsyncTimeout(); 235e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.timeout(250, TimeUnit.MILLISECONDS); 236e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Sink timeoutSink = timeout.sink(sink); 237e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller try { 238e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeoutSink.write(null, 0); 239e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller fail(); 240e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } catch (InterruptedIOException expected) { 241e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertEquals("timeout", expected.getMessage()); 242e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertEquals("exception and timeout", expected.getCause().getMessage()); 243e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 244e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 245e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 246e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Test public void wrappedThrowsWithoutTimeout() throws Exception { 247e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Sink sink = new ForwardingSink(new Buffer()) { 248e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Override public void write(Buffer source, long byteCount) throws IOException { 249e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller throw new IOException("no timeout occurred"); 250e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 251e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller }; 252e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller AsyncTimeout timeout = new AsyncTimeout(); 253e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeout.timeout(250, TimeUnit.MILLISECONDS); 254e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller Sink timeoutSink = timeout.sink(sink); 255e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller try { 256e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timeoutSink.write(null, 0); 257e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller fail(); 258e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } catch (IOException expected) { 259e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertEquals("no timeout occurred", expected.getMessage()); 260e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 261e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 262e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 263e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller /** Asserts which timeouts fired, and in which order. */ 264e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller private void assertTimedOut(Timeout... expected) { 265e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller assertEquals(Arrays.asList(expected), timedOut); 266e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 267e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller 268e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller class RecordingAsyncTimeout extends AsyncTimeout { 269e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller @Override protected void timedOut() { 270e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller timedOut.add(this); 271e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 272e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller } 273e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller} 274