• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kyuupichan / bitcoinX / #2140

02 Mar 2024 07:39PM UTC coverage: 99.476% (+0.4%) from 99.074%
#2140

push

coveralls-python

neil
Remove unintentionally committed debug code

1 of 1 new or added line in 1 file covered. (100.0%)

5 existing lines in 2 files now uncovered.

12337 of 12402 relevant lines covered (99.48%)

0.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.52
/tests/test_aiolib.py
1
import sys
1✔
2
from asyncio import sleep, CancelledError, current_task, get_running_loop
1✔
3

4
import pytest
1✔
5

6
from bitcoinx.aiolib import (
1✔
7
    TimeoutCancellationError, UncaughtTimeoutError, timeout_at, timeout_after,
8
    ignore_at, ignore_after, ExceptionGroup, BaseExceptionGroup, TaskGroup
9
)
10

11

12
if sys.version_info < (3, 11):
1✔
13

14
    class TestBaseExceptionGroup:
1✔
15

16
        def test_includes_base(self):
1✔
17
            excs = [KeyboardInterrupt(), Exception()]
1✔
18
            e = BaseExceptionGroup('msg', excs)
1✔
19
            assert isinstance(e, BaseExceptionGroup)
1✔
20
            assert e.message == 'msg'
1✔
21
            assert e.exceptions == tuple(excs)
1✔
22

23
        def test_not_includes_base(self):
1✔
24
            excs = [MemoryError(), Exception()]
1✔
25
            e = BaseExceptionGroup('msg', excs)
1✔
26
            assert isinstance(e, ExceptionGroup)
1✔
27
            assert e.message == 'msg'
1✔
28
            assert e.exceptions == tuple(excs)
1✔
29

30
    class TestExceptionGroup:
1✔
31

32
        def test_includes_base(self):
1✔
33
            excs = [KeyboardInterrupt(), Exception()]
1✔
34
            with pytest.raises(TypeError):
1✔
35
                ExceptionGroup('msg', excs)
1✔
36

37
        def test_not_includes_base(self):
1✔
38
            excs = [MemoryError(), Exception()]
1✔
39
            e = ExceptionGroup('msg', excs)
1✔
40
            assert isinstance(e, ExceptionGroup)
1✔
41
            assert e.message == 'msg'
1✔
42
            assert e.exceptions == tuple(excs)
1✔
43

44

45
def assert_clean():
1✔
46
    task = current_task()
1✔
47
    if hasattr(task, '_deadlines'):
1✔
48
        assert not task._deadlines
1✔
49
        assert not task._timeout_handler
1✔
50
    if hasattr(task, 'cancelling'):
1✔
UNCOV
51
        assert not task.cancelling()
×
52

53

54
class TestTaskgroup:
1✔
55

56
    @pytest.mark.asyncio
1✔
57
    async def test_simple(self):
1✔
58
        async with TaskGroup() as group:
1✔
59
            group.create_task(sleep(0.002))
1✔
60
            group.create_task(sleep(0.001))
1✔
61
        assert group.joined
1✔
62

63
    @pytest.mark.asyncio
1✔
64
    async def test_simple_cancel_one(self):
1✔
65
        async with TaskGroup() as group:
1✔
66
            group.create_task(sleep(0.002))
1✔
67
            t = group.create_task(sleep(1))
1✔
68
            t.cancel()
1✔
69
        assert group.joined
1✔
70

71
    @pytest.mark.asyncio
1✔
72
    async def test_simple_cancel_remaining(self):
1✔
73
        async with TaskGroup() as group:
1✔
74
            group.create_task(sleep(0.002))
1✔
75
            group.create_task(sleep(1))
1✔
76
            await group.cancel_remaining()
1✔
77
        assert group.joined
1✔
78

79
    @pytest.mark.asyncio
1✔
80
    async def test_simple_group_cancelled(self):
1✔
81
        async def cancel_task(task):
1✔
82
            task.cancel()
1✔
83

84
        with pytest.raises(CancelledError):
1✔
85
            async with TaskGroup() as group:
1✔
86
                group.create_task(sleep(0.002))
1✔
87
                group.create_task(sleep(1))
1✔
88
                group.create_task(cancel_task(current_task()))
1✔
89

90
        assert group.joined
1✔
91

92
    @pytest.mark.asyncio
1✔
93
    async def test_simple_group_raises(self):
1✔
94
        v1 = ValueError(2)
1✔
95
        v2 = ValueError(3)
1✔
96

97
        async def raise_exc(secs, exc):
1✔
98
            await sleep(secs)
1✔
99
            raise exc
1✔
100

101
        with pytest.raises(ExceptionGroup) as e:
1✔
102
            async with TaskGroup() as group:
1✔
103
                group.create_task(raise_exc(0.1, v1))
1✔
104
                group.create_task(raise_exc(0.01, v2))
1✔
105

106
        assert e.value.exceptions == (v2, )
1✔
107
        assert group.joined
1✔
108

109
    @pytest.mark.asyncio
1✔
110
    async def test_simple_group_raises_2(self):
1✔
111
        v1 = ValueError(2)
1✔
112
        v2 = ValueError(3)
1✔
113

114
        async def raise_exc(secs, exc):
1✔
115
            await sleep(secs)
1✔
116
            raise exc
1✔
117

118
        with pytest.raises(ExceptionGroup) as e:
1✔
119
            async with TaskGroup() as group:
1✔
120
                group.create_task(raise_exc(0.005, v1))
1✔
121
                group.create_task(raise_exc(0.002, v2))
1✔
122
                await sleep(0.01)
1✔
123

124
        assert e.value.exceptions == (v2, v1)
1✔
125
        assert group.joined
1✔
126

127
    @pytest.mark.asyncio
1✔
128
    async def test_simple_group_timeout(self):
1✔
129
        async def raise_exc(secs, exc):
1✔
130
            await sleep(secs)
1✔
131
            raise exc
×
132

133
        async with ignore_after(0.001):
1✔
134
            async with TaskGroup() as group:
1✔
135
                group.create_task(sleep(1))
1✔
136
                group.create_task(raise_exc(0.01, ValueError()))
1✔
137

138
        assert not group._errors
1✔
139
        assert group.joined
1✔
140

141

142
class TestTimeout:
1✔
143

144
    @pytest.mark.asyncio
1✔
145
    async def test_timeout_expires(self):
1✔
146
        with pytest.raises(TimeoutError):
1✔
147
            async with timeout_after(0.01) as t:
1✔
148
                await sleep(0.1)
1✔
149
        assert t.expired
1✔
150
        assert_clean()
1✔
151

152
    @pytest.mark.asyncio
1✔
153
    async def test_timeout_doesnt_expire(self):
1✔
154
        async with timeout_after(0.01) as t:
1✔
155
            pass
1✔
156
        assert not t.expired
1✔
157
        assert_clean()
1✔
158

159
    @pytest.mark.asyncio
1✔
160
    async def test_timeout_immediate(self):
1✔
161
        body_ran = False
1✔
162
        with pytest.raises(TimeoutError):
1✔
163
            async with timeout_after(0) as t:
1✔
164
                body_ran = True
1✔
165
                await sleep(0)
1✔
166
                assert False
1✔
167
        assert body_ran
1✔
168
        assert t.expired
1✔
169
        assert_clean()
1✔
170

171
    @pytest.mark.asyncio
1✔
172
    async def test_timeout_at_immediate(self):
1✔
173
        body_ran = False
1✔
174
        with pytest.raises(TimeoutError):
1✔
175
            async with timeout_at(get_running_loop().time()) as t:
1✔
176
                body_ran = True
1✔
177
                await sleep(0)
1✔
178
                assert False
1✔
179
        assert body_ran
1✔
180
        assert t.expired
1✔
181
        assert_clean()
1✔
182

183
    @pytest.mark.asyncio
1✔
184
    async def test_nested_outer_expires_first(self):
1✔
185
        with pytest.raises(TimeoutError):
1✔
186
            async with timeout_after(0.001) as outer:
1✔
187
                with pytest.raises(TimeoutCancellationError) as e:
1✔
188
                    async with timeout_after(0.01) as inner:
1✔
189
                        await sleep(0.02)
1✔
190
                raise e.value
1✔
191
        assert outer.expired
1✔
192
        assert not inner.expired
1✔
193
        assert_clean()
1✔
194

195
    @pytest.mark.asyncio
1✔
196
    async def test_nested_inner_expires_first(self):
1✔
197
        async with timeout_after(0.05) as outer:
1✔
198
            with pytest.raises(TimeoutError):
1✔
199
                async with timeout_after(0.001) as inner:
1✔
200
                    await sleep(0.1)
1✔
201
        assert not outer.expired
1✔
202
        assert inner.expired
1✔
203
        assert_clean()
1✔
204

205
    @pytest.mark.asyncio
1✔
206
    async def test_nested_inner_expires_first_and_uncaught(self):
1✔
207
        with pytest.raises(UncaughtTimeoutError):
1✔
208
            async with timeout_after(0.05) as outer:
1✔
209
                async with timeout_after(0.001) as inner:
1✔
210
                    await sleep(0.1)
1✔
211
        assert not outer.expired
1✔
212
        assert inner.expired
1✔
213
        assert_clean()
1✔
214

215
    @pytest.mark.asyncio
1✔
216
    async def test_no_timeout_but_raises_IndexError(self):
1✔
217
        with pytest.raises(IndexError):
1✔
218
            async with timeout_after(0.01) as t:
1✔
219
                raise IndexError
1✔
220
        assert not t.expired
1✔
221
        assert_clean()
1✔
222

223
    @pytest.mark.asyncio
1✔
224
    async def test_no_timeout_but_raises_CancelledError(self):
1✔
225
        with pytest.raises(CancelledError):
1✔
226
            async with timeout_after(0.01) as t:
1✔
227
                raise CancelledError
1✔
228
        assert not t.expired
1✔
229
        assert_clean()
1✔
230

231
    @pytest.mark.asyncio
1✔
232
    async def test_timeout_reuse_bad(self):
1✔
233
        timeout = timeout_after(0.01)
1✔
234
        async with timeout as outer:
1✔
235
            with pytest.raises(RuntimeError) as e:
1✔
236
                async with timeout:
1✔
237
                    pass
1✔
238
            assert str(e.value) == 'timeout already in use'
1✔
239
        assert not outer.expired
1✔
240
        assert_clean()
1✔
241

242
    @pytest.mark.asyncio
1✔
243
    async def test_timeout_reuse_good(self):
1✔
244
        timeout = timeout_after(0.01)
1✔
245
        assert not timeout.expired
1✔
246

247
        async with timeout:
1✔
248
            deadline = timeout._deadline
1✔
249
        assert not timeout.expired
1✔
250

251
        # Windows event loops seem to have coarse time measures
252
        await sleep(0.001)
1✔
253

254
        async with timeout:
1✔
255
            assert timeout._deadline > deadline
1✔
256
            deadline = timeout._deadline
1✔
257
        assert not timeout.expired
1✔
258

259
        # Windows event loops seem to have coarse time measures
260
        await sleep(0.001)
1✔
261

262
        with pytest.raises(TimeoutError):
1✔
263
            async with timeout:
1✔
264
                assert timeout._deadline > deadline
1✔
265
                deadline = timeout._deadline
1✔
266
                await sleep(1)
1✔
267
        assert timeout.expired
1✔
268

269
        async with timeout:
1✔
270
            assert timeout._deadline > deadline
1✔
271
            assert not timeout.expired
1✔
272
        assert not timeout.expired
1✔
273

274
        assert_clean()
1✔
275

276
    @pytest.mark.asyncio
1✔
277
    async def test_timeout_never(self):
1✔
278
        async with timeout_after(None) as t:
1✔
279
            await sleep(0.1)
1✔
280
        assert not t.expired
1✔
281
        assert_clean()
1✔
282

283
    @pytest.mark.asyncio
1✔
284
    async def test_timeout_outer_never(self):
1✔
285
        with pytest.raises(UncaughtTimeoutError):
1✔
286
            async with timeout_after(None) as outer:
1✔
287
                async with timeout_after(0.01) as inner:
1✔
288
                    await sleep(0.1)
1✔
289
        assert not outer.expired
1✔
290
        assert inner.expired
1✔
291
        assert_clean()
1✔
292

293
    @pytest.mark.asyncio
1✔
294
    async def test_timeout_inner_never(self):
1✔
295
        with pytest.raises(TimeoutError):
1✔
296
            async with timeout_after(0.01) as outer:
1✔
297
                with pytest.raises(TimeoutCancellationError) as e:
1✔
298
                    async with timeout_after(None) as inner:
1✔
299
                        await sleep(0.1)
1✔
300
                raise e.value
1✔
301
        assert outer.expired
1✔
302
        assert not inner.expired
1✔
303
        assert_clean()
1✔
304

305
    @pytest.mark.asyncio
1✔
306
    async def test_timeout_at(self):
1✔
307
        with pytest.raises(TimeoutError):
1✔
308
            clock = get_running_loop().time()
1✔
309
            async with timeout_at(clock + 0.01) as t:
1✔
310
                await sleep(0.1)
1✔
311
        assert t.expired
1✔
312
        assert_clean()
1✔
313

314

315
class TestIgnore:
1✔
316

317
    @pytest.mark.asyncio
1✔
318
    async def test_timeout_expires(self):
1✔
319
        async with ignore_after(0.01) as t:
1✔
320
            await sleep(0.1)
1✔
321
        assert t.expired
1✔
322
        assert_clean()
1✔
323

324
    @pytest.mark.asyncio
1✔
325
    async def test_timeout_doesnt_expire(self):
1✔
326
        async with ignore_after(0.01) as t:
1✔
327
            pass
1✔
328
        assert not t.expired
1✔
329
        assert_clean()
1✔
330

331
    @pytest.mark.asyncio
1✔
332
    async def test_timeout_immediate(self):
1✔
333
        body_ran = False
1✔
334
        async with ignore_after(0) as t:
1✔
335
            body_ran = True
1✔
336
            await sleep(0)
1✔
337
            assert False
1✔
338
        assert body_ran
1✔
339
        assert t.expired
1✔
340
        assert_clean()
1✔
341

342
    @pytest.mark.asyncio
1✔
343
    async def test_timeout_at_immediate(self):
1✔
344
        body_ran = False
1✔
345
        async with ignore_at(get_running_loop().time()) as t:
1✔
346
            body_ran = True
1✔
347
            await sleep(0)
1✔
348
            assert False
1✔
349
        assert body_ran
1✔
350
        assert t.expired
1✔
351
        assert_clean()
1✔
352

353
    @pytest.mark.asyncio
1✔
354
    async def test_nested_outer_expires_first(self):
1✔
355
        async with ignore_after(0.001) as outer:
1✔
356
            with pytest.raises(TimeoutCancellationError) as e:
1✔
357
                async with ignore_after(0.01) as inner:
1✔
358
                    await sleep(0.02)
1✔
359
            raise e.value
1✔
360
        assert outer.expired
1✔
361
        assert not inner.expired
1✔
362
        assert_clean()
1✔
363

364
    @pytest.mark.asyncio
1✔
365
    async def test_nested_inner_expires_first(self):
1✔
366
        async with ignore_after(0.05) as outer:
1✔
367
            async with ignore_after(0.001) as inner:
1✔
368
                await sleep(0.1)
1✔
369
        assert not outer.expired
1✔
370
        assert inner.expired
1✔
371
        assert_clean()
1✔
372

373
    @pytest.mark.asyncio
1✔
374
    async def test_no_timeout_but_raises_IndexError(self):
1✔
375
        with pytest.raises(IndexError):
1✔
376
            async with ignore_after(0.01) as t:
1✔
377
                raise IndexError
1✔
378
        assert not t.expired
1✔
379
        assert_clean()
1✔
380

381
    @pytest.mark.asyncio
1✔
382
    async def test_no_timeout_but_raises_CancelledError(self):
1✔
383
        with pytest.raises(CancelledError):
1✔
384
            async with ignore_after(0.01) as t:
1✔
385
                raise CancelledError
1✔
386
        assert not t.expired
1✔
387
        assert_clean()
1✔
388

389
    @pytest.mark.asyncio
1✔
390
    async def test_timeout_reuse_bad(self):
1✔
391
        timeout = ignore_after(0.01)
1✔
392
        async with timeout as outer:
1✔
393
            with pytest.raises(RuntimeError) as e:
1✔
394
                async with timeout:
1✔
395
                    pass
1✔
396
            assert str(e.value) == 'timeout already in use'
1✔
397
        assert not outer.expired
1✔
398
        assert_clean()
1✔
399

400
    @pytest.mark.asyncio
1✔
401
    async def test_timeout_reuse_good(self):
1✔
402
        timeout = ignore_after(0.01)
1✔
403
        assert not timeout.expired
1✔
404

405
        async with timeout:
1✔
406
            deadline = timeout._deadline
1✔
407
        assert not timeout.expired
1✔
408

409
        # Windows event loops seem to have coarse time measures
410
        await sleep(0.001)
1✔
411

412
        async with timeout:
1✔
413
            assert timeout._deadline > deadline
1✔
414
            deadline = timeout._deadline
1✔
415
        assert not timeout.expired
1✔
416

417
        # Windows event loops seem to have coarse time measures
418
        await sleep(0.001)
1✔
419

420
        async with timeout:
1✔
421
            assert timeout._deadline > deadline
1✔
422
            deadline = timeout._deadline
1✔
423
            await sleep(1)
1✔
424
        assert timeout.expired
1✔
425

426
        async with timeout:
1✔
427
            assert timeout._deadline > deadline
1✔
428
            assert not timeout.expired
1✔
429
        assert not timeout.expired
1✔
430

431
        assert_clean()
1✔
432

433
    @pytest.mark.asyncio
1✔
434
    async def test_timeout_outer_never(self):
1✔
435
        with pytest.raises(ValueError):
1✔
436
            async with ignore_after(None) as outer:
1✔
437
                async with ignore_after(0.01) as inner:
1✔
438
                    await sleep(0.1)
1✔
439
                raise ValueError
1✔
440
        assert not outer.expired
1✔
441
        assert inner.expired
1✔
442
        assert_clean()
1✔
443

444
    @pytest.mark.asyncio
1✔
445
    async def test_timeout_inner_never(self):
1✔
446
        async with ignore_after(0.01) as outer:
1✔
447
            with pytest.raises(TimeoutCancellationError) as e:
1✔
448
                async with ignore_after(None) as inner:
1✔
449
                    await sleep(0.1)
1✔
450
            raise e.value
1✔
451
        assert outer.expired
1✔
452
        assert not inner.expired
1✔
453
        assert_clean()
1✔
454

455
    @pytest.mark.asyncio
1✔
456
    async def test_ignore_at(self):
1✔
457
        clock = get_running_loop().time()
1✔
458
        async with ignore_at(clock + 0.01) as t:
1✔
459
            await sleep(0.1)
1✔
460
        assert t.expired
1✔
461
        assert_clean()
1✔
462

463

464
class TestMixedNested:
1✔
465

466
    @pytest.mark.asyncio
1✔
467
    async def test_nested_outer_expires_first(self):
1✔
468
        async with ignore_after(0.001) as outer:
1✔
469
            with pytest.raises(TimeoutCancellationError) as e:
1✔
470
                async with timeout_after(0.01) as inner:
1✔
471
                    await sleep(0.02)
1✔
472
            raise e.value
1✔
473
        assert outer.expired
1✔
474
        assert not inner.expired
1✔
475
        assert_clean()
1✔
476

477
    @pytest.mark.asyncio
1✔
478
    async def test_nested_outer_expires_first_reversed(self):
1✔
479
        with pytest.raises(TimeoutError):
1✔
480
            async with timeout_after(0.001) as outer:
1✔
481
                with pytest.raises(TimeoutCancellationError) as e:
1✔
482
                    async with ignore_after(0.01) as inner:
1✔
483
                        await sleep(0.02)
1✔
484
                raise e.value
1✔
485
        assert outer.expired
1✔
486
        assert not inner.expired
1✔
487
        assert_clean()
1✔
488

489
    @pytest.mark.asyncio
1✔
490
    async def test_nested_inner_expires_first(self):
1✔
491
        async with timeout_after(0.05) as outer:
1✔
492
            async with ignore_after(0.001) as inner:
1✔
493
                await sleep(0.1)
1✔
494
        assert not outer.expired
1✔
495
        assert inner.expired
1✔
496
        assert_clean()
1✔
497

498
    @pytest.mark.asyncio
1✔
499
    async def test_nested_inner_expires_first_reversed(self):
1✔
500
        async with ignore_after(0.05) as outer:
1✔
501
            with pytest.raises(TimeoutError):
1✔
502
                async with timeout_after(0.001) as inner:
1✔
503
                    await sleep(0.1)
1✔
504
        assert not outer.expired
1✔
505
        assert inner.expired
1✔
506
        assert_clean()
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc