nim-libp2p-experimental/tests/testsemaphore.nim
Dmitriy Ryajov b2ea5a3c77
Concurrent upgrades (#489)
* adding an upgraded event to conn

* set stopped flag asap

* trigger upgradded event on conn

* set concurrency limit for accepts

* backporting semaphore from tcp-limits2

* export unittests module

* make params explicit

* tone down debug logs

* adding semaphore tests

* use semaphore to throttle concurent upgrades

* add libp2p scope

* trigger upgraded event before any other events

* add event handler for connection upgrade

* cleanup upgraded event on conn close

* make upgrades slot release rebust

* dont forget to release slot on nil connection

* misc

* make sure semaphore is always released

* minor improvements and a nil check

* removing unneeded comment

* make upgradeMonitor a non-closure proc

* make sure the `upgraded` event is initialized

* handle exceptions in accepts when stopping

* don't leak exceptions when stopping accept loops
2021-01-04 12:59:05 -06:00

104 lines
2.2 KiB
Nim

import random
import chronos
import ../libp2p/utils/semaphore
import ./helpers
randomize()
suite "AsyncSemaphore":
asyncTest "should acquire":
let sema = AsyncSemaphore.init(3)
await sema.acquire()
await sema.acquire()
await sema.acquire()
check sema.count == 0
asyncTest "should release":
let sema = AsyncSemaphore.init(3)
await sema.acquire()
await sema.acquire()
await sema.acquire()
check sema.count == 0
sema.release()
sema.release()
sema.release()
check sema.count == 3
asyncTest "should queue acquire":
let sema = AsyncSemaphore.init(1)
await sema.acquire()
let fut = sema.acquire()
check sema.count == -1
check sema.queue.len == 1
sema.release()
sema.release()
check sema.count == 1
await sleepAsync(10.millis)
check fut.finished()
asyncTest "should keep count == size":
let sema = AsyncSemaphore.init(1)
sema.release()
sema.release()
sema.release()
check sema.count == 1
asyncTest "should tryAcquire":
let sema = AsyncSemaphore.init(1)
await sema.acquire()
check sema.tryAcquire() == false
asyncTest "should tryAcquire and acquire":
let sema = AsyncSemaphore.init(4)
check sema.tryAcquire() == true
check sema.tryAcquire() == true
check sema.tryAcquire() == true
check sema.tryAcquire() == true
check sema.count == 0
let fut = sema.acquire()
check fut.finished == false
check sema.count == -1
# queue is only used when count is < 0
check sema.queue.len == 1
sema.release()
sema.release()
sema.release()
sema.release()
sema.release()
check fut.finished == true
check sema.count == 4
check sema.queue.len == 0
asyncTest "should restrict resource access":
let sema = AsyncSemaphore.init(3)
var resource = 0
proc task() {.async.} =
try:
await sema.acquire()
resource.inc()
check resource > 0 and resource <= 3
let sleep = rand(0..10).millis
# echo sleep
await sleepAsync(sleep)
finally:
resource.dec()
sema.release()
var tasks: seq[Future[void]]
for i in 0..<10:
tasks.add(task())
await allFutures(tasks)