1 2 /* 3 * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 4 */ 5 6 @file:Suppress("NAMED_ARGUMENTS_NOT_ALLOWED") // KT-21913 7 8 package kotlinx.coroutines 9 10 import kotlinx.coroutines.channels.* 11 import kotlin.test.* 12 13 class WithTimeoutOrNullTest : TestBase() { 14 /** 15 * Tests a case of no timeout and no suspension inside. 16 */ 17 @Test <lambda>null18 fun testBasicNoSuspend() = runTest { 19 expect(1) 20 val result = withTimeoutOrNull(10_000) { 21 expect(2) 22 "OK" 23 } 24 assertEquals("OK", result) 25 finish(3) 26 } 27 28 /** 29 * Tests a case of no timeout and one suspension inside. 30 */ 31 @Test <lambda>null32 fun testBasicSuspend() = runTest { 33 expect(1) 34 val result = withTimeoutOrNull(10_000) { 35 expect(2) 36 yield() 37 expect(3) 38 "OK" 39 } 40 assertEquals("OK", result) 41 finish(4) 42 } 43 44 /** 45 * Tests property dispatching of `withTimeoutOrNull` blocks 46 */ 47 @Test <lambda>null48 fun testDispatch() = runTest { 49 expect(1) 50 launch { 51 expect(4) 52 yield() // back to main 53 expect(7) 54 } 55 expect(2) 56 // test that it does not yield to the above job when started 57 val result = withTimeoutOrNull(1000) { 58 expect(3) 59 yield() // yield only now 60 expect(5) 61 "OK" 62 } 63 assertEquals("OK", result) 64 expect(6) 65 yield() // back to launch 66 finish(8) 67 } 68 69 /** 70 * Tests that a 100% CPU-consuming loop will react on timeout if it has yields. 71 */ 72 @Test <lambda>null73 fun testYieldBlockingWithTimeout() = runTest { 74 expect(1) 75 val result = withTimeoutOrNull(100) { 76 while (true) { 77 yield() 78 } 79 } 80 assertNull(result) 81 finish(2) 82 } 83 84 @Test testSmallTimeoutnull85 fun testSmallTimeout() = runTest { 86 val channel = Channel<Int>(1) 87 val value = withTimeoutOrNull(1) { 88 channel.receive() 89 } 90 assertNull(value) 91 } 92 93 @Test <lambda>null94 fun testThrowException() = runTest(expected = {it is AssertionError}) { <lambda>null95 withTimeoutOrNull<Unit>(Long.MAX_VALUE) { 96 throw AssertionError() 97 } 98 } 99 100 @Test testInnerTimeoutnull101 fun testInnerTimeout() = runTest( 102 expected = { it is CancellationException } <lambda>null103 ) { 104 withTimeoutOrNull(1000) { 105 withTimeout(10) { 106 while (true) { 107 yield() 108 } 109 } 110 @Suppress("UNREACHABLE_CODE") 111 expectUnreached() // will timeout 112 } 113 expectUnreached() // will timeout 114 } 115 116 @Test testNestedTimeoutnull117 fun testNestedTimeout() = runTest(expected = { it is TimeoutCancellationException }) { <lambda>null118 withTimeoutOrNull(Long.MAX_VALUE) { 119 // Exception from this withTimeout is not suppressed by withTimeoutOrNull 120 withTimeout(10) { 121 delay(Long.MAX_VALUE) 122 1 123 } 124 } 125 126 expectUnreached() 127 } 128 129 @Test <lambda>null130 fun testOuterTimeout() = runTest { 131 if (isJavaAndWindows) return@runTest 132 var counter = 0 133 val result = withTimeoutOrNull(320) { 134 while (true) { 135 val inner = withTimeoutOrNull(150) { 136 while (true) { 137 yield() 138 } 139 } 140 assertNull(inner) 141 counter++ 142 } 143 } 144 assertNull(result) 145 check(counter in 1..2) {"Executed: $counter times"} 146 } 147 148 @Test <lambda>null149 fun testBadClass() = runTest { 150 val bad = BadClass() 151 val result = withTimeoutOrNull(100) { 152 bad 153 } 154 assertSame(bad, result) 155 } 156 157 @Test <lambda>null158 fun testNullOnTimeout() = runTest { 159 expect(1) 160 val result = withTimeoutOrNull(100) { 161 expect(2) 162 delay(1000) 163 expectUnreached() 164 "OK" 165 } 166 assertNull(result) 167 finish(3) 168 } 169 170 @Test <lambda>null171 fun testSuppressExceptionWithResult() = runTest { 172 expect(1) 173 val result = withTimeoutOrNull(100) { 174 expect(2) 175 try { 176 delay(1000) 177 } catch (e: CancellationException) { 178 expect(3) 179 } 180 "OK" 181 } 182 assertNull(result) 183 finish(4) 184 } 185 186 @Test <lambda>null187 fun testSuppressExceptionWithAnotherException() = runTest { 188 expect(1) 189 try { 190 withTimeoutOrNull(100) { 191 expect(2) 192 try { 193 delay(1000) 194 } catch (e: CancellationException) { 195 expect(3) 196 throw TestException() 197 } 198 expectUnreached() 199 "OK" 200 } 201 expectUnreached() 202 } catch (e: TestException) { 203 // catches TestException 204 finish(4) 205 206 } 207 } 208 209 @Test <lambda>null210 fun testNegativeTimeout() = runTest { 211 expect(1) 212 var result = withTimeoutOrNull(-1) { 213 expectUnreached() 214 } 215 assertNull(result) 216 result = withTimeoutOrNull(0) { 217 expectUnreached() 218 } 219 assertNull(result) 220 finish(2) 221 } 222 223 @Test <lambda>null224 fun testExceptionFromWithinTimeout() = runTest { 225 expect(1) 226 try { 227 expect(2) 228 withTimeoutOrNull(1000) { 229 expect(3) 230 throw TestException() 231 } 232 expectUnreached() 233 } catch (e: TestException) { 234 finish(4) 235 } 236 } 237 } 238