diff options
Diffstat (limited to 'tests/async')
-rw-r--r-- | tests/async/nim.cfg | 1 | ||||
-rw-r--r-- | tests/async/t11558.nim | 13 | ||||
-rw-r--r-- | tests/async/t17045.nim | 28 | ||||
-rw-r--r-- | tests/async/t20111.nim | 19 | ||||
-rw-r--r-- | tests/async/t21447.nim | 6 | ||||
-rw-r--r-- | tests/async/t21893.nim | 13 | ||||
-rw-r--r-- | tests/async/t22210.nim | 41 | ||||
-rw-r--r-- | tests/async/t22210_2.nim | 73 | ||||
-rw-r--r-- | tests/async/tasync_gcunsafe.nim | 2 | ||||
-rw-r--r-- | tests/async/tasync_noasync.nim | 35 | ||||
-rw-r--r-- | tests/async/tasync_traceback.nim | 103 | ||||
-rw-r--r-- | tests/async/tasyncawait.nim | 2 | ||||
-rw-r--r-- | tests/async/tasyncdial.nim | 1 | ||||
-rw-r--r-- | tests/async/tasyncintemplate.nim | 62 | ||||
-rw-r--r-- | tests/async/tasyncnetudp.nim | 2 | ||||
-rw-r--r-- | tests/async/tasyncssl.nim | 3 | ||||
-rw-r--r-- | tests/async/tioselectors.nim | 27 | ||||
-rw-r--r-- | tests/async/tnewasyncudp.nim | 6 | ||||
-rw-r--r-- | tests/async/twinasyncrw.nim | 14 |
19 files changed, 364 insertions, 87 deletions
diff --git a/tests/async/nim.cfg b/tests/async/nim.cfg new file mode 100644 index 000000000..be50f572c --- /dev/null +++ b/tests/async/nim.cfg @@ -0,0 +1 @@ +--experimental:strictEffects diff --git a/tests/async/t11558.nim b/tests/async/t11558.nim new file mode 100644 index 000000000..99961e7b6 --- /dev/null +++ b/tests/async/t11558.nim @@ -0,0 +1,13 @@ +discard """ +output: "Hello\n9" +""" +import std/asyncdispatch + +proc foo(): Future[string] {.async.} = + "Hello" + +proc bar(): Future[int] {.async.} = + result = 9 + +echo waitFor foo() +echo waitFor bar() diff --git a/tests/async/t17045.nim b/tests/async/t17045.nim new file mode 100644 index 000000000..2b5acf48a --- /dev/null +++ b/tests/async/t17045.nim @@ -0,0 +1,28 @@ +discard """ + targets: "c cpp" + matrix: "--mm:refc; --mm:arc" +""" + +type Future = ref object + +iterator paths: string = + # without "when nimvm" everything works + when nimvm: + yield "test.md" + else: + yield "test.md" + +template await(f: Future): string = + # need this yield, also the template has to return something + yield f + "hello world" + +proc generatePostContextsAsync() = + iterator generatePostContextsAsyncIter(): Future {.closure.} = + for filePath in paths(): + var temp = await Future() + + # need this line + var nameIterVar = generatePostContextsAsyncIter + +generatePostContextsAsync() \ No newline at end of file diff --git a/tests/async/t20111.nim b/tests/async/t20111.nim new file mode 100644 index 000000000..0aaa7d886 --- /dev/null +++ b/tests/async/t20111.nim @@ -0,0 +1,19 @@ +discard """ + action: "run" +""" +import asyncdispatch +type + Sync = object + Async = object + SyncRes = (Sync, string) + AsyncRes = (Async, string) + +proc foo(val: Sync | Async): Future[(Async, string) | (Sync, string)] {.multisync.} = + return (val, "hello") + +let + myAsync = Async() + mySync = Sync() + +doAssert typeof(waitFor foo(myAsync)) is AsyncRes +doAssert typeof(foo(mySync)) is SyncRes diff --git a/tests/async/t21447.nim b/tests/async/t21447.nim new file mode 100644 index 000000000..e4f7ae31f --- /dev/null +++ b/tests/async/t21447.nim @@ -0,0 +1,6 @@ +discard """ + action: "compile" + cmd: "nim c -d:release -d:futureLogging $file" +""" + +import std/asyncdispatch diff --git a/tests/async/t21893.nim b/tests/async/t21893.nim new file mode 100644 index 000000000..658cb02eb --- /dev/null +++ b/tests/async/t21893.nim @@ -0,0 +1,13 @@ +discard """ +output: "@[97]\ntrue" +""" + +import asyncdispatch + +proc test(): Future[bool] {.async.} = + const S4 = @[byte('a')] + echo S4 + return true + +echo waitFor test() + diff --git a/tests/async/t22210.nim b/tests/async/t22210.nim new file mode 100644 index 000000000..fcf939472 --- /dev/null +++ b/tests/async/t22210.nim @@ -0,0 +1,41 @@ +discard """ +output: ''' +stage 1 +stage 2 +stage 3 +(status: 200, data: "SOMEDATA") +''' +""" + +import std/asyncdispatch + + +# bug #22210 +type + ClientResponse = object + status*: int + data*: string + +proc subFoo1(): Future[int] {.async.} = + await sleepAsync(100) + return 200 + +proc subFoo2(): Future[string] {.async.} = + await sleepAsync(100) + return "SOMEDATA" + +proc testFoo(): Future[ClientResponse] {.async.} = + try: + let status = await subFoo1() + doAssert(status == 200) + let data = await subFoo2() + return ClientResponse(status: status, data: data) + finally: + echo "stage 1" + await sleepAsync(100) + echo "stage 2" + await sleepAsync(200) + echo "stage 3" + +when isMainModule: + echo waitFor testFoo() \ No newline at end of file diff --git a/tests/async/t22210_2.nim b/tests/async/t22210_2.nim new file mode 100644 index 000000000..9db664a32 --- /dev/null +++ b/tests/async/t22210_2.nim @@ -0,0 +1,73 @@ +import std/asyncdispatch + + +# bug #22210 +type + ClientResponse = object + status*: int + data*: string + +proc subFoo1(): Future[int] {.async.} = + await sleepAsync(100) + return 200 + +proc subFoo2(): Future[string] {.async.} = + await sleepAsync(100) + return "SOMEDATA" + + +proc testFoo2(): Future[ClientResponse] {.async.} = + var flag = 0 + try: + let status = await subFoo1() + doAssert(status == 200) + let data = await subFoo2() + result = ClientResponse(status: status, data: data) + finally: + inc flag + await sleepAsync(100) + inc flag + await sleepAsync(200) + inc flag + doAssert flag == 3 + +discard waitFor testFoo2() + +proc testFoo3(): Future[ClientResponse] {.async.} = + var flag = 0 + try: + let status = await subFoo1() + doAssert(status == 200) + let data = await subFoo2() + if false: + return ClientResponse(status: status, data: data) + finally: + inc flag + await sleepAsync(100) + inc flag + await sleepAsync(200) + inc flag + doAssert flag == 3 + +discard waitFor testFoo3() + + +proc testFoo4(): Future[ClientResponse] {.async.} = + var flag = 0 + try: + let status = await subFoo1() + doAssert(status == 200) + let data = await subFoo2() + if status == 200: + return ClientResponse(status: status, data: data) + else: + return ClientResponse() + finally: + inc flag + await sleepAsync(100) + inc flag + await sleepAsync(200) + inc flag + doAssert flag == 3 + +discard waitFor testFoo4() diff --git a/tests/async/tasync_gcunsafe.nim b/tests/async/tasync_gcunsafe.nim index 00c92b109..f3e6bc691 100644 --- a/tests/async/tasync_gcunsafe.nim +++ b/tests/async/tasync_gcunsafe.nim @@ -1,5 +1,5 @@ discard """ - errormsg: "'anotherGCSafeAsyncProcIter' is not GC-safe as it calls 'asyncGCUnsafeProc'" + errormsg: "'anotherGCSafeAsyncProc (Async)' is not GC-safe as it calls 'asyncGCUnsafeProc'" cmd: "nim c --threads:on $file" file: "asyncmacro.nim" """ diff --git a/tests/async/tasync_noasync.nim b/tests/async/tasync_noasync.nim index 54f4f597f..0927148bf 100644 --- a/tests/async/tasync_noasync.nim +++ b/tests/async/tasync_noasync.nim @@ -1,13 +1,42 @@ discard """ - errormsg: "'yield' only allowed in an iterator" - cmd: "nim c $file" - file: "asyncmacro.nim" + cmd: "nim check --hints:off --warnings:off $file" + action: "reject" + nimout: ''' +tasync_noasync.nim(21, 10) Error: Can only 'await' inside a proc marked as 'async'. Use 'waitFor' when calling an 'async' proc in a non-async scope instead +tasync_noasync.nim(25, 12) Error: Can only 'await' inside a proc marked as 'async'. Use 'waitFor' when calling an 'async' proc in a non-async scope instead +tasync_noasync.nim(28, 10) Error: Can only 'await' inside a proc marked as 'async'. Use 'waitFor' when calling an 'async' proc in a non-async scope instead +tasync_noasync.nim(31, 10) Error: Can only 'await' inside a proc marked as 'async'. Use 'waitFor' when calling an 'async' proc in a non-async scope instead +tasync_noasync.nim(35, 10) Error: Can only 'await' inside a proc marked as 'async'. Use 'waitFor' when calling an 'async' proc in a non-async scope instead +tasync_noasync.nim(38, 10) Error: Can only 'await' inside a proc marked as 'async'. Use 'waitFor' when calling an 'async' proc in a non-async scope instead +tasync_noasync.nim(40, 8) Error: Can only 'await' inside a proc marked as 'async'. Use 'waitFor' when calling an 'async' proc in a non-async scope instead +''' """ import async proc a {.async.} = discard +# Bad await usage +proc nonAsyncProc = + await a() + +proc nestedNonAsyncProc {.async.} = + proc nested = + await a() + +iterator customIterator: int = + await a() + +macro awaitInMacro = + await a() + +type DummyRef = ref object of RootObj +method awaitInMethod(_: DummyRef) {.base.} = + await a() + +proc improperMultisync {.multisync.} = + await a() + await a() # if we overload a fallback handler to get diff --git a/tests/async/tasync_traceback.nim b/tests/async/tasync_traceback.nim index 9f787929b..98f71b192 100644 --- a/tests/async/tasync_traceback.nim +++ b/tests/async/tasync_traceback.nim @@ -1,6 +1,5 @@ discard """ exitcode: 0 - disabled: "windows" output: "Matched" """ import asyncdispatch, strutils @@ -68,53 +67,24 @@ import re const expected = """ b failure Async traceback: - tasync_traceback\.nim\(\d+?\)\s+?tasync_traceback - asyncmacro\.nim\(\d+?\)\s+?a - asyncmacro\.nim\(\d+?\)\s+?aNimAsyncContinue - ## Resumes an async procedure - tasync_traceback\.nim\(\d+?\)\s+?aIter - asyncmacro\.nim\(\d+?\)\s+?b - asyncmacro\.nim\(\d+?\)\s+?bNimAsyncContinue - ## Resumes an async procedure - tasync_traceback\.nim\(\d+?\)\s+?bIter - #\[ - tasync_traceback\.nim\(\d+?\)\s+?tasync_traceback - asyncmacro\.nim\(\d+?\)\s+?a - asyncmacro\.nim\(\d+?\)\s+?aNimAsyncContinue - ## Resumes an async procedure - asyncmacro\.nim\(\d+?\)\s+?aIter - asyncfutures\.nim\(\d+?\)\s+?read - \]# + tasync_traceback\.nim\(\d+?\) tasync_traceback + tasync_traceback\.nim\(\d+?\) a \(Async\) + tasync_traceback\.nim\(\d+?\) b \(Async\) Exception message: b failure -Exception type: + bar failure Async traceback: - tasync_traceback\.nim\(\d+?\)\s+?tasync_traceback - asyncdispatch\.nim\(\d+?\)\s+?waitFor - asyncdispatch\.nim\(\d+?\)\s+?poll + tasync_traceback\.nim\(\d+?\) tasync_traceback + asyncdispatch\.nim\(\d+?\) waitFor + asyncdispatch\.nim\(\d+?\) poll ## Processes asynchronous completion events - asyncdispatch\.nim\(\d+?\)\s+?runOnce - asyncdispatch\.nim\(\d+?\)\s+?processPendingCallbacks + asyncdispatch\.nim\(\d+?\) runOnce + asyncdispatch\.nim\(\d+?\) processPendingCallbacks ## Executes pending callbacks - asyncmacro\.nim\(\d+?\)\s+?barNimAsyncContinue - ## Resumes an async procedure - tasync_traceback\.nim\(\d+?\)\s+?barIter - #\[ - tasync_traceback\.nim\(\d+?\)\s+?tasync_traceback - asyncdispatch\.nim\(\d+?\)\s+?waitFor - asyncdispatch\.nim\(\d+?\)\s+?poll - ## Processes asynchronous completion events - asyncdispatch\.nim\(\d+?\)\s+?runOnce - asyncdispatch\.nim\(\d+?\)\s+?processPendingCallbacks - ## Executes pending callbacks - asyncmacro\.nim\(\d+?\)\s+?fooNimAsyncContinue - ## Resumes an async procedure - asyncmacro\.nim\(\d+?\)\s+?fooIter - asyncfutures\.nim\(\d+?\)\s+?read - \]# + tasync_traceback\.nim\(\d+?\) bar \(Async\) Exception message: bar failure -Exception type: + """ # TODO: is asyncmacro good enough location for fooIter traceback/debugging? just put the callsite info for all? @@ -122,28 +92,31 @@ Exception type: let resLines = splitLines(result.strip) let expLines = splitLines(expected.strip) -if resLines.len != expLines.len: - echo("Not matched! Wrong number of lines!") - echo expLines.len - echo resLines.len - echo("Expected: -----------") - echo expected - echo("Gotten: -------------") - echo result - echo("---------------------") - quit(QuitFailure) - -var ok = true -for i in 0 ..< resLines.len: - if not resLines[i].match(re(expLines[i])): - echo "Not matched! Line ", i + 1 - echo "Expected:" - echo expLines[i] - echo "Actual:" - echo resLines[i] - ok = false - -if ok: - echo("Matched") +when not defined(cpp): # todo fixme + if resLines.len != expLines.len: + echo("Not matched! Wrong number of lines!") + echo expLines.len + echo resLines.len + echo("Expected: -----------") + echo expected + echo("Gotten: -------------") + echo result + echo("---------------------") + quit(QuitFailure) + + var ok = true + for i in 0 ..< resLines.len: + if not resLines[i].match(re(expLines[i])): + echo "Not matched! Line ", i + 1 + echo "Expected:" + echo expLines[i] + echo "Actual:" + echo resLines[i] + ok = false + + if ok: + echo("Matched") + else: + quit(QuitFailure) else: - quit(QuitFailure) + echo("Matched") diff --git a/tests/async/tasyncawait.nim b/tests/async/tasyncawait.nim index f658a15ed..e86542b2d 100644 --- a/tests/async/tasyncawait.nim +++ b/tests/async/tasyncawait.nim @@ -34,7 +34,7 @@ proc readMessages(client: AsyncFD) {.async.} = clientCount.inc break else: - if line.startswith("Message "): + if line.startsWith("Message "): msgCount.inc else: doAssert false diff --git a/tests/async/tasyncdial.nim b/tests/async/tasyncdial.nim index a755de74e..f0377dfd5 100644 --- a/tests/async/tasyncdial.nim +++ b/tests/async/tasyncdial.nim @@ -3,7 +3,6 @@ discard """ OK AF_INET OK AF_INET6 ''' - disabled: "travis" """ import diff --git a/tests/async/tasyncintemplate.nim b/tests/async/tasyncintemplate.nim new file mode 100644 index 000000000..4bddb1d18 --- /dev/null +++ b/tests/async/tasyncintemplate.nim @@ -0,0 +1,62 @@ +discard """ + output: ''' +42 +43 +43 +1 +2 +3 +4 +''' +""" + +# xxx move to tests/async/tasyncintemplate.nim +import asyncdispatch + +block: # bug #16159 + template foo() = + proc temp(): Future[int] {.async.} = return 42 + proc tempVoid(): Future[void] {.async.} = echo await temp() + foo() + waitFor tempVoid() + +block: # aliasing `void` + template foo() = + type Foo = void + proc temp(): Future[int] {.async.} = return 43 + proc tempVoid(): Future[Foo] {.async.} = echo await temp() + proc tempVoid2() {.async.} = echo await temp() + foo() + waitFor tempVoid() + waitFor tempVoid2() + +block: # sanity check + template foo() = + proc bad(): int {.async.} = discard + doAssert not compiles(bad()) + +block: # bug #16786 + block: + proc main(a: int|string)= + proc bar(b: int|string) = echo b + bar(a) + main(1) + + block: + proc main(a: int) : Future[void] {.async.} = + proc bar(b: int): Future[void] {.async.} = echo b + await bar(a) + waitFor main(2) + + block: + proc main(a: int) : Future[void] {.async.} = + proc bar(b: int | string): Future[void] {.async.} = echo b + await bar(a) + waitFor main(3) + + block: + # bug + proc main(a: int|string) = + proc bar(b: int): Future[void] {.async.} = echo b + waitFor bar(a) + main(4) diff --git a/tests/async/tasyncnetudp.nim b/tests/async/tasyncnetudp.nim index ef6dfc5e1..dade96fb2 100644 --- a/tests/async/tasyncnetudp.nim +++ b/tests/async/tasyncnetudp.nim @@ -59,7 +59,7 @@ proc readMessages(server: AsyncSocket) {.async.} = while i < maxResponses: let (data, fromIp, fromPort) = await recvFrom(server, 16384) - if data.startswith("Message ") and fromIp == "127.0.0.1": + if data.startsWith("Message ") and fromIp == "127.0.0.1": await sendTo(server, fromIp, fromPort, data) inc(msgCount) diff --git a/tests/async/tasyncssl.nim b/tests/async/tasyncssl.nim index a582818eb..57de3271d 100644 --- a/tests/async/tasyncssl.nim +++ b/tests/async/tasyncssl.nim @@ -1,5 +1,6 @@ discard """ cmd: "nim $target --hints:on --define:ssl $options $file" + disabled: osx """ import asyncdispatch, asyncnet, net, strutils @@ -36,7 +37,7 @@ when defined(ssl): inc(clientCount) break else: - if line.startswith("Message "): + if line.startsWith("Message "): inc(msgCount) else: doAssert false diff --git a/tests/async/tioselectors.nim b/tests/async/tioselectors.nim index f7487525a..f53767408 100644 --- a/tests/async/tioselectors.nim +++ b/tests/async/tioselectors.nim @@ -58,7 +58,11 @@ when not defined(windows): registerHandle(selector, client_socket, {Event.Write}, 0) freeAddrInfo(aiList) - discard selector.select(100) + + # make sure both sockets are selected + var nevs = 0 + while nevs < 2: + nevs += selector.select(100).len var sockAddress: SockAddr var addrLen = sizeof(sockAddress).Socklen @@ -234,7 +238,7 @@ when not defined(windows): if fd == -1: raiseOsError(osLastError()) let length = len(data).cint - if posix.write(fd, cast[pointer](unsafeAddr data[0]), + if posix.write(fd, cast[pointer](addr data[0]), len(data).cint) != length: raiseOsError(osLastError()) if posix.close(fd) == -1: @@ -288,8 +292,8 @@ when not defined(windows): events: set[Event] proc vnode_test(): bool = - proc validate(test: openarray[ReadyKey], - check: openarray[valType]): bool = + proc validate(test: openArray[ReadyKey], + check: openArray[valType]): bool = result = false if len(test) == len(check): for checkItem in check: @@ -427,6 +431,20 @@ when not defined(windows): doAssert(res[0].fd == dirfd and {Event.Vnode, Event.VnodeDelete} <= res[0].events) + proc pipe_test(): bool = + # closing the read end of a pipe will result in it automatically + # being removed from the kqueue; make sure no exception is raised + var s = newSelector[int]() + var fds: array[2, cint] + discard pipe(fds) + s.registerHandle(fds[1], {Write}, 0) + discard close(fds[0]) + let res = s.select(-1) + doAssert(res.len == 1) + s.unregister(fds[1]) + discard close(fds[1]) + return true + when hasThreadSupport: var counter = 0 @@ -468,6 +486,7 @@ when not defined(windows): when defined(macosx) or defined(freebsd) or defined(openbsd) or defined(netbsd): processTest("File notification test...", vnode_test()) + processTest("Pipe test...", pipe_test()) echo("All tests passed!") else: import nativesockets, winlean, os, osproc diff --git a/tests/async/tnewasyncudp.nim b/tests/async/tnewasyncudp.nim index 76462c21d..68de796a0 100644 --- a/tests/async/tnewasyncudp.nim +++ b/tests/async/tnewasyncudp.nim @@ -58,7 +58,7 @@ proc launchSwarm(name: ptr SockAddr) {.async.} = 16384, cast[ptr SockAddr](addr saddr), addr slen) size = 0 - var grammString = $cstring(addr buffer) + var grammString = $cast[cstring](addr buffer) if grammString == message: saveSendingPort(sockport) inc(recvCount) @@ -80,8 +80,8 @@ proc readMessages(server: AsyncFD) {.async.} = 16384, cast[ptr SockAddr](addr(saddr)), addr(slen)) size = 0 - var grammString = $cstring(addr buffer) - if grammString.startswith("Message ") and + var grammString = $cast[cstring](addr buffer) + if grammString.startsWith("Message ") and saddr.sin_addr.s_addr == nativesockets.ntohl(INADDR_LOOPBACK.uint32): await sendTo(server, addr grammString[0], len(grammString), cast[ptr SockAddr](addr saddr), slen) diff --git a/tests/async/twinasyncrw.nim b/tests/async/twinasyncrw.nim index 69b092607..f0a8f6a62 100644 --- a/tests/async/twinasyncrw.nim +++ b/tests/async/twinasyncrw.nim @@ -19,7 +19,7 @@ when defined(windows): retFuture.complete() return true else: - retFuture.fail(newException(OSError, osErrorMsg(OSErrorCode(ret)))) + retFuture.fail(newOSError(OSErrorCode(ret))) return true var aiList = getAddrInfo(address, port, domain) @@ -45,7 +45,7 @@ when defined(windows): freeAddrInfo(aiList) if not success: - retFuture.fail(newException(OSError, osErrorMsg(lastError))) + retFuture.fail(newOSError(lastError)) return retFuture proc winRecv*(socket: AsyncFD, size: int, @@ -63,7 +63,7 @@ when defined(windows): if flags.isDisconnectionError(lastError): retFuture.complete("") else: - retFuture.fail(newException(OSError, osErrorMsg(lastError))) + retFuture.fail(newOSError(lastError)) elif res == 0: # Disconnected retFuture.complete("") @@ -88,7 +88,7 @@ when defined(windows): if flags.isDisconnectionError(lastError): retFuture.complete(0) else: - retFuture.fail(newException(OSError, osErrorMsg(lastError))) + retFuture.fail(newOSError(lastError)) else: retFuture.complete(res) # TODO: The following causes a massive slowdown. @@ -112,7 +112,7 @@ when defined(windows): if flags.isDisconnectionError(lastError): retFuture.complete() else: - retFuture.fail(newException(OSError, osErrorMsg(lastError))) + retFuture.fail(newOSError(lastError)) else: written.inc(res) if res != netSize: @@ -136,7 +136,7 @@ when defined(windows): var client = nativesockets.accept(sock.SocketHandle, cast[ptr SockAddr](addr(sockAddress)), addr(addrLen)) if client == osInvalidSocket: - retFuture.fail(newException(OSError, osErrorMsg(osLastError()))) + retFuture.fail(newOSError(osLastError())) else: retFuture.complete((getAddrString(cast[ptr SockAddr](addr sockAddress)), client.AsyncFD)) @@ -220,7 +220,7 @@ when defined(windows): clientCount.inc break else: - if line.startswith("Message "): + if line.startsWith("Message "): msgCount.inc else: doAssert false |