Skip to content

Commit f45641a

Browse files
committed
rewritten all tests to unittest2; get rid of nimskull
1 parent d4badb2 commit f45641a

25 files changed

+611
-525
lines changed

.github/workflows/nim.yml

Lines changed: 6 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,11 @@
1-
name: Nim CI
2-
1+
name: CI
32
on:
43
push:
5-
branches: [ master ]
4+
branches:
5+
- master
66
pull_request:
7-
branches: [ master ]
7+
workflow_dispatch:
88

99
jobs:
10-
Test:
11-
if: |
12-
!contains(github.event.head_commit.message, '[skip ci]')
13-
strategy:
14-
fail-fast: false
15-
matrix:
16-
os: [ubuntu-latest]
17-
compiler:
18-
- name: nim
19-
version: devel
20-
21-
- name: nimskull
22-
version: "*"
23-
24-
name: "${{ matrix.os }} (${{ matrix.compiler.name }} ${{ matrix.compiler.version }})"
25-
runs-on: ${{ matrix.os }}
26-
steps:
27-
- name: Checkout
28-
uses: actions/checkout@v4
29-
with:
30-
path: project
31-
32-
- name: Compiler (nim)
33-
if: matrix.compiler.name == 'nim'
34-
uses: alaviss/setup-nim@0.1.1
35-
with:
36-
path: nim
37-
version: ${{ matrix.compiler.version }}
38-
39-
- name: Compiler (nimskull)
40-
id: nimskull
41-
if: matrix.compiler.name == 'nimskull'
42-
uses: nim-works/setup-nimskull@0.1.0
43-
with:
44-
nimskull-version: ${{ matrix.compiler.version }}
45-
46-
- if: matrix.compiler.name == 'nimskull'
47-
name: Fetch nimble's fork for nimskull
48-
uses: actions/checkout@v4
49-
with:
50-
path: nimble
51-
repository: alaviss/nimble
52-
ref: nimskull
53-
54-
- if: matrix.compiler.name == 'nimskull'
55-
name: Build nimble and add to PATH
56-
shell: bash
57-
run: |
58-
cd nimble
59-
nim c -d:release -o:nimble src/nimble.nim
60-
cp nimble "$NIMSKULL_BIN/nimble"
61-
# Add nimble binary folder to PATH too
62-
echo "$HOME/.nimble/bin" >> $GITHUB_PATH
63-
env:
64-
NIMSKULL_BIN: ${{ steps.nimskull.outputs.bin-path }}
65-
66-
- name: Dependencies
67-
shell: bash
68-
run: |
69-
cd project
70-
nimble --accept develop
71-
nimble --accept install "https://github.com/disruptek/balls"
72-
env:
73-
NIM: ${{ matrix.compiler.name }}
74-
75-
- name: Tests
76-
shell: bash
77-
run: |
78-
cd project
79-
balls --path="." --backend:c --mm:arc --mm:orc --errorMax:3
80-
env:
81-
NIM: ${{ matrix.compiler.name }}
10+
build:
11+
uses: status-im/nimbus-common-workflow/.github/workflows/common.yml@main

nimuring.nimble

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Package
22

3-
version = "0.2.0"
4-
author = "dterlyakhin"
3+
version = "0.2.1"
4+
author = "dterliakhin"
55
description = "io_uring wrapper"
66
license = "MIT"
77
srcDir = "src"
88

99
when declared(taskRequires):
10-
taskRequires "test", "https://github.com/disruptek/balls >= 3.0.0"
10+
taskRequires "test", "unittest2"

src/nimuring/barrier.nim

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,22 @@
11
from std/atomics import MemoryOrder
22

3-
when defined(isNimSkull):
4-
{.push, header: "<stdatomic.h>".}
5-
proc atomic_load_explicit*[T](location: ptr T; order: MemoryOrder): T {.importc.}
6-
proc atomic_store_explicit*[T](location: ptr T; desired: T; order: MemoryOrder = moSequentiallyConsistent) {.importc.}
7-
proc atomic_thread_fence*(order: MemoryOrder) {.importc: "atomic_thread_fence".}
8-
{.pop.}
3+
{.push stackTrace:off.}
4+
when defined(cpp):
5+
{.emit: "#include <atomic>".}
6+
proc atomic_load_explicit*[T](location: ptr T; order: MemoryOrder): T {.inline.} =
7+
{.emit: ["return std::atomic_load_explicit(reinterpret_cast<const std::atomic<", T, "> *>(", location, "), ", order, ");"].}
8+
proc atomic_store_explicit*[T](location: ptr T; desired: T; order: MemoryOrder) {.inline.} =
9+
{.emit: ["std::atomic_store_explicit(reinterpret_cast<std::atomic<", T, "> *>(", location, "), ", desired, ", ", order, ");"].}
10+
proc atomic_thread_fence*(order: MemoryOrder) {.inline.} =
11+
{.emit: ["std::atomic_thread_fence(", order, ");"].}
912
else:
10-
{.push stackTrace:off.}
11-
when defined(cpp):
12-
{.emit: "#include <atomic>".}
13-
proc atomic_load_explicit*[T](location: ptr T; order: MemoryOrder): T {.inline.} =
14-
{.emit: ["return std::atomic_load_explicit(reinterpret_cast<const std::atomic<", T, "> *>(", location, "), ", order, ");"].}
15-
proc atomic_store_explicit*[T](location: ptr T; desired: T; order: MemoryOrder) {.inline.} =
16-
{.emit: ["std::atomic_store_explicit(reinterpret_cast<std::atomic<", T, "> *>(", location, "), ", desired, ", ", order, ");"].}
17-
proc atomic_thread_fence*(order: MemoryOrder) {.inline.} =
18-
{.emit: ["std::atomic_thread_fence(", order, ");"].}
19-
else:
20-
{.emit: "#include <stdatomic.h>".}
21-
proc atomic_load_explicit*[T](location: ptr T; order: MemoryOrder): T {.inline.} =
22-
{.emit: "return atomic_load_explicit((_Atomic `T` *)(`location`), `order`);".}
23-
proc atomic_store_explicit*[T](location: ptr T; desired: T; order: MemoryOrder) {.inline.} =
24-
{.emit: ["atomic_store_explicit((_Atomic ", T, " *)(", location, "), ", desired, ", ", order, ");"].}
25-
proc atomic_thread_fence*(order: MemoryOrder) {.inline.} =
26-
{.emit: ["atomic_thread_fence(", order, ");"].}
27-
{.pop.}
13+
{.emit: "#include <stdatomic.h>".}
14+
proc atomic_load_explicit*[T](location: ptr T; order: MemoryOrder): T {.inline.} =
15+
{.emit: "return atomic_load_explicit((_Atomic `T` *)(`location`), `order`);".}
16+
proc atomic_store_explicit*[T](location: ptr T; desired: T; order: MemoryOrder) {.inline.} =
17+
{.emit: ["atomic_store_explicit((_Atomic ", T, " *)(", location, "), ", desired, ", ", order, ");"].}
18+
proc atomic_thread_fence*(order: MemoryOrder) {.inline.} =
19+
{.emit: ["atomic_thread_fence(", order, ");"].}
20+
{.pop.}
2821

2922
export MemoryOrder

src/nimuring/queue.nim

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,8 @@ template destroyImpl() {.dirty.} =
112112
if queue.params != nil:
113113
deallocShared(queue.params)
114114

115-
when defined(isNimSkull):
116-
proc `=destroy`(queue: var Queue) =
117-
destroyImpl
118-
else:
119-
proc `=destroy`(queue: Queue) =
120-
destroyImpl
115+
proc `=destroy`(queue: Queue) =
116+
destroyImpl
121117

122118

123119
proc `=sink`(dest: var Queue, source: Queue) =

tests/megatest.nim

Whitespace-only changes.
Lines changed: 58 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,70 @@
1-
import balls
1+
import unittest2
22
import nimuring
33
import posix
44
import net
55

6-
var q = newQueue(4)
7-
8-
proc findCqe(cqes: var seq[Cqe]; userData: UserData): Cqe =
9-
for cqe in cqes:
10-
if cqe.userData == userData.uint64:
11-
return cqe
12-
13-
const
14-
ACCEPT = 1
15-
CONNECT = 2
16-
SEND = 3
17-
RECV = 4
18-
19-
20-
let server = newSocket()
21-
let client = newSocket()
22-
23-
var listener: Socket
24-
try:
25-
server.bindAddr(Port(1234))
26-
server.listen()
6+
template withSockets(body: untyped) =
7+
let server {.inject.} = newSocket()
8+
let client {.inject.} = newSocket()
9+
var listener {.inject.}: Socket = nil
10+
try:
11+
`body`
12+
finally:
13+
server.close()
14+
client.close()
15+
if listener != nil:
16+
listener.close()
2717

28-
var accept_addr: SockAddr
29-
var accept_addr_len: SockLen
30-
check accept_addr_len.int == 0
31-
q.accept(userData=ACCEPT, server.getFd, addr accept_addr, addr accept_addr_len, 0)
18+
template setupServer(server: Socket, port: Port, accept_addr: var SockAddr, accept_addr_len: var SockLen, q: var Queue) =
19+
server.bindAddr(port)
20+
server.listen()
21+
accept_addr_len = 0.SockLen
22+
q.accept(userData=1, server.getFd, addr accept_addr, addr accept_addr_len, 0)
3223

33-
var sa: Sockaddr_storage
34-
var sl: SockLen
35-
toSockAddr("127.0.0.1".parseIpAddress, Port(1234), sa, sl)
24+
template setupClientConnect(client: Socket, port: Port, q: var Queue) =
25+
var sa: Sockaddr_storage = default(Sockaddr_storage)
26+
var sl: SockLen = 0
27+
toSockAddr("127.0.0.1".parseIpAddress, port, sa, sl)
28+
q.connect(userData=2, client.getFd, cast[ptr SockAddr](sa.addr), sl)
3629

37-
q.connect(userData=CONNECT, client.getFd, cast[ptr SockAddr](sa.addr), sl)
30+
proc findCqe(cqes: var seq[Cqe]; userData: UserData): Cqe =
31+
result = default(Cqe)
32+
for cqe in cqes:
33+
if cqe.userData == userData.uint64:
34+
return cqe
3835

39-
q.submit()
40-
var cqes = q.copyCqes(1)
41-
let acceptCqe = cqes.findCqe(ACCEPT)
42-
listener = newSocket(cast[SocketHandle](acceptCqe.res))
36+
suite "accept, connect, send, recv":
37+
test "accept/connect":
38+
withSockets:
39+
var q = newQueue(4)
40+
var accept_addr: SockAddr
41+
var accept_addr_len: SockLen
42+
setupServer(server, Port(1234), accept_addr, accept_addr_len, q)
43+
setupClientConnect(client, Port(1234), q)
44+
q.submit()
45+
var cqes = q.copyCqes(1)
46+
let acceptCqe = cqes.findCqe(1)
47+
listener = newSocket(cast[SocketHandle](acceptCqe.res))
48+
check accept_addr_len.int == 16
4349

44-
check accept_addr_len.int == 16
50+
test "send/recv":
51+
withSockets:
52+
var q = newQueue(4)
53+
var accept_addr: SockAddr
54+
var accept_addr_len: SockLen
55+
setupServer(server, Port(1234), accept_addr, accept_addr_len, q)
56+
setupClientConnect(client, Port(1234), q)
57+
q.submit()
58+
var cqes = q.copyCqes(1)
59+
let acceptCqe = cqes.findCqe(1)
60+
listener = newSocket(cast[SocketHandle](acceptCqe.res))
4561

46-
var bufferSend = ['\x01', '\x00', '\x01', '\x00', '\x01', '\x00', '\x01', '\x00', '\x01', '\x00']
47-
var bufferRecv: array[6, char]
62+
var bufferSend = ['\x01', '\x00', '\x01', '\x00', '\x01', '\x00', '\x01', '\x00', '\x01', '\x00']
63+
var bufferRecv: array[6, char] = ['\0', '\0', '\0', '\0', '\0', '\0']
4864

49-
q.send(SEND, client.getFd, bufferSend.addr, bufferSend.len).linkNext()
50-
q.recv(RECV, listener.getFd, bufferRecv.addr, bufferRecv.len)
51-
q.submit(2)
65+
q.send(3, client.getFd, bufferSend.addr, bufferSend.len).linkNext()
66+
q.recv(4, listener.getFd, bufferRecv.addr, bufferRecv.len)
67+
q.submit(2)
5268

53-
for i in 0..<bufferRecv.len:
54-
check bufferSend[i] == bufferRecv[i]
55-
56-
finally:
57-
# Socket has no graceful =destroy
58-
server.close()
59-
client.close()
69+
for i in 0..<bufferRecv.len:
70+
check bufferSend[i] == bufferRecv[i]

tests/ops/test_nop.nim

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,40 @@
1-
import balls
1+
import unittest2
22
import nimuring
33

4-
var q = newQueue(1, {})
5-
q.nop(cast[pointer](0xaaaaaaaa))
6-
check q.sqReady() == 1
7-
check q.cqReady() == 0
8-
check q.submit() == 1
9-
check q.sqReady() == 0
10-
check q.cqReady() == 1
4+
suite "nop operation":
5+
test "basic nop submit and completion":
6+
var q = newQueue(1, {})
7+
q.nop(cast[pointer](0xaaaaaaaa))
8+
check q.sqReady() == 1
9+
check q.cqReady() == 0
10+
check q.submit() == 1
11+
check q.sqReady() == 0
12+
check q.cqReady() == 1
1113

12-
var cqes = q.copyCqes(1)
13-
check cqes.len == 1
14-
check cqes[0].userData == 0xaaaaaaaa.uint64
15-
check q.sqReady() == 0
16-
check q.cqReady() == 0
14+
var cqes = q.copyCqes(1)
15+
check cqes.len == 1
16+
check cqes[0].userData == 0xaaaaaaaa.uint64
17+
check q.sqReady() == 0
18+
check q.cqReady() == 0
1719

20+
test "drainPrevious and second nop":
21+
var q = newQueue(1, {})
22+
q.nop(cast[pointer](0xaaaaaaaa))
23+
discard q.submit()
24+
discard q.copyCqes(1)
1825

19-
let sqe = q.nop(cast[pointer](0xbbbbbbbb))
20-
# check that io_using correctly processed the previous request,
21-
# so that the new one that is waiting for the previous one will also be processed
22-
sqe.drainPrevious()
26+
let sqe = q.nop(cast[pointer](0xbbbbbbbb))
27+
sqe.drainPrevious()
2328

24-
check q.sqReady() == 1
25-
check q.cqReady() == 0
29+
check q.sqReady() == 1
30+
check q.cqReady() == 0
2631

27-
check q.submit() == 1
28-
check q.sqReady() == 0
29-
check q.cqReady() == 1
32+
check q.submit() == 1
33+
check q.sqReady() == 0
34+
check q.cqReady() == 1
3035

31-
cqes = q.copyCqes(1)
32-
check cqes.len == 1
33-
check cqes[0].userData == 0xbbbbbbbb.uint64
34-
check q.sqReady() == 0
35-
check q.cqReady() == 0
36+
let cqes = q.copyCqes(1)
37+
check cqes.len == 1
38+
check cqes[0].userData == 0xbbbbbbbb.uint64
39+
check q.sqReady() == 0
40+
check q.cqReady() == 0

tests/ops/test_openat.nim

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1-
import balls
1+
import unittest2
22
import nimuring
33
import posix
44
import os
55

6-
var q = newQueue(1, {})
6+
template withTempFile(body: untyped) =
7+
let path {.inject.} = getTempDir() / "test_io_uring_openat"
8+
try:
9+
body
10+
finally:
11+
if fileExists(path):
12+
removeFile(path)
713

8-
const path = getTempDir() / "test_io_uring_openat";
9-
10-
q.openat(0, 0, path, O_CLOEXEC or O_RDWR or O_CREAT)
11-
q.submit(1)
12-
13-
check fileExists(path)
14-
removeFile(path)
14+
suite "openat operation":
15+
test "openat creates file":
16+
withTempFile:
17+
var q = newQueue(1, {})
18+
q.openat(0, 0, path, O_CLOEXEC or O_RDWR or O_CREAT)
19+
q.submit(1)
20+
check fileExists(path)

0 commit comments

Comments
 (0)