Skip to content

Commit 02ca248

Browse files
author
Jaremy J. Creechley
committed
breaking up tests some
1 parent f5628ec commit 02ca248

File tree

4 files changed

+73
-54
lines changed

4 files changed

+73
-54
lines changed

tests/common.nim

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import std/[os, logging, unittest, strutils, strformat]
2+
export os, logging, unittest, strutils, strformat
3+
4+
import threading/channels
5+
6+
const
7+
testLogLevel {.strdefine.}: string = "lvlInfo"
8+
logLevel*: Level = parseEnum[Level](testLogLevel)
9+
10+
var logger* = newConsoleLogger(logLevel, verboseFmtStr)
11+
12+
template runMultithreadInOrderTest*[T](chan: Chan[T]) =
13+
var worker1: Thread[void]
14+
15+
# Launch the first worker.
16+
createThread(worker1) do:
17+
chan.send("Hello World!")
18+
19+
# Wait for the thread to exit before moving on to the next example.
20+
worker1.joinThread()
21+
22+
var dest = ""
23+
chan.recv(dest)
24+
logger.log(lvlDebug, "Received msg: " & $dest)
25+
doAssert dest == "Hello World!"
26+
27+
28+
template runMultithreadBockTest*[T](chan: Chan[T]) =
29+
var worker2: Thread[void]
30+
# Launch the other worker.
31+
createThread(worker2) do:
32+
# This is another proc to run in a background thread. This proc takes a while
33+
# to send the message since it sleeps for 2 seconds (or 2000 milliseconds).
34+
sleep(2000)
35+
chan.send("Another message")
36+
37+
# This time, use a non-blocking approach with tryRecv.
38+
# Since the main thread is not blocked, it could be used to perform other
39+
# useful work while it waits for data to arrive on the channel.
40+
41+
var messages: seq[string]
42+
var msg = ""
43+
while true:
44+
let tried = chan.tryRecv(msg)
45+
if tried:
46+
logger.log(lvlDebug, "Receive msg: " & $msg)
47+
messages.add move(msg)
48+
break
49+
50+
messages.add "Pretend I'm doing useful work..."
51+
logger.log(lvlDebug, "add fakeMsg to messages (other work): " & $messages.len())
52+
sleep(400)
53+
54+
# Wait for the second thread to exit before cleaning up the channel.
55+
worker2.joinThread()
56+
57+
# Clean up the channel.
58+
check messages[^1] == "Another message"
59+
check messages.len >= 2

tests/tchannels_overwrite.nim

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ discard """
55

66
import threading/channels
77
import std/[os, logging, unittest]
8-
from tchannels_simple import runMultithreadTest
8+
import common
99

1010
suite "testing Chan with overwrite mode":
1111
var logger = newConsoleLogger(levelThreshold=lvlInfo)
@@ -41,7 +41,11 @@ suite "testing Chan with overwrite mode":
4141

4242
var chan = newChan[string](elements = 4, overwrite = true)
4343

44-
runMultithreadTest(chan)
44+
runMultithreadInOrderTest(chan)
45+
46+
test "basic blocking multithread":
47+
var chan = newChan[string]()
48+
runMultithreadBockTest(chan)
4549

4650

4751

tests/tchannels_simple.nim

Lines changed: 6 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,58 +5,10 @@ discard """
55

66
import threading/channels
77
import std/[os, logging, unittest]
8-
9-
template runMultithreadTest*[T](chan: Chan[T]) =
10-
var worker1: Thread[void]
11-
var worker2: Thread[void]
12-
13-
# Launch the first worker.
14-
createThread(worker1, proc () =
15-
# This proc will be run in another thread using the threads module.
16-
chan.send("Hello World!"))
17-
18-
# Block until the message arrives, then print it out.
19-
var dest = ""
20-
chan.recv(dest)
21-
doAssert dest == "Hello World!"
22-
23-
# Wait for the thread to exit before moving on to the next example.
24-
worker1.joinThread()
25-
26-
# Launch the other worker.
27-
createThread(worker2, proc () =
28-
# This is another proc to run in a background thread. This proc takes a while
29-
# to send the message since it sleeps for 2 seconds (or 2000 milliseconds).
30-
sleep(2000)
31-
chan.send("Another message"))
32-
33-
# This time, use a non-blocking approach with tryRecv.
34-
# Since the main thread is not blocked, it could be used to perform other
35-
# useful work while it waits for data to arrive on the channel.
36-
37-
var messages: seq[string]
38-
var msg = ""
39-
while true:
40-
let tried = chan.tryRecv(msg)
41-
if tried:
42-
messages.add move(msg)
43-
break
44-
45-
messages.add "Pretend I'm doing useful work..."
46-
# For this example, sleep in order not to flood stdout with the above
47-
# message.
48-
sleep(400)
49-
50-
# Wait for the second thread to exit before cleaning up the channel.
51-
worker2.joinThread()
52-
53-
# Clean up the channel.
54-
check messages[^1] == "Another message"
55-
check messages.len >= 2
8+
import common
569

5710

5811
suite "testing Chan with overwrite mode":
59-
var logger = newConsoleLogger(levelThreshold=lvlInfo)
6012

6113
setup:
6214
discard "run before each test"
@@ -71,4 +23,8 @@ suite "testing Chan with overwrite mode":
7123

7224
test "basic multithread":
7325
var chan = newChan[string]()
74-
runMultithreadTest(chan)
26+
runMultithreadInOrderTest(chan)
27+
28+
test "basic blocking multithread":
29+
var chan = newChan[string]()
30+
runMultithreadBockTest(chan)

threading/channels.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ proc isUnbuffered(chan: ChannelRaw): bool =
151151

152152
proc isClosed(chan: ChannelRaw): bool {.inline.} = load(chan.closed, moRelaxed)
153153

154-
proc peek(chan: ChannelRaw): int {.inline.} =
154+
proc peek(chan: ChannelRaw): int =
155155
(if chan.isUnbuffered: numItemsUnbuf(chan) else: numItems(chan))
156156

157157

@@ -399,7 +399,7 @@ when false:
399399
proc close*[T](c: Chan[T]) {.inline.} =
400400
store(c.d.closed, true, moRelaxed)
401401

402-
proc peek*[T](c: Chan[T]): int {.inline.} = peek(c.d)
402+
proc peek*[T](c: Chan[T]): int = peek(c.d)
403403

404404
proc newChan*[T](elements = 30, overwrite = false): Chan[T] =
405405
## create a new channel implemented using a ring buffer

0 commit comments

Comments
 (0)