@@ -11,6 +11,8 @@ import ./helpers/certificate
1111import lsquic/ certificateverifier
1212import lsquic/ stream
1313import lsquic/ lsquic_ffi
14+ import stew/ endians2
15+ import sequtils
1416
1517proc logging (ctx: pointer , buf: cstring , len: csize_t ): cint {.cdecl .} =
1618 echo $ buf
@@ -21,10 +23,111 @@ proc certificateCb(
2123): bool {.gcsafe .} =
2224 return derCertificates.len > 0
2325
24- suite " connections" :
25- setup:
26- let address = initTAddress (" 127.0.0.1:12345" )
26+ let address = initTAddress (" 127.0.0.1:12345" )
27+
28+ const
29+ runs = 1
30+ uploadSize = 100000 # 100KB
31+ downloadSize = 100000000 # 100MB
32+ chunkSize = 65536 # 64KB chunks like perf
33+
34+ proc runPerf (): Future [Duration ] {.async .} =
35+ let customCertVerif: CertificateVerifier =
36+ CustomCertificateVerifier .init (certificateCb)
37+ let clientTLSConfig = TLSConfig .new (
38+ testCertificate (),
39+ testPrivateKey (),
40+ @ [" test" ].toHashSet (),
41+ Opt .some (customCertVerif),
42+ )
43+ let serverTLSConfig = TLSConfig .new (
44+ testCertificate (),
45+ testPrivateKey (),
46+ @ [" test" ].toHashSet (),
47+ Opt .some (customCertVerif),
48+ )
49+ let client = QuicClient .new (clientTLSConfig)
50+ let server = QuicServer .new (serverTLSConfig)
51+ let listener = server.listen (address)
52+ let accepting = listener.accept ()
53+ let dialing = client.dial (address)
54+
55+ let outgoingConn = await dialing
56+ let incomingConn = await accepting
57+
58+ let serverHandler = proc () {.async .} =
59+ let stream = await incomingConn.incomingStream ()
60+
61+ # Step 1: Read download size (8 bytes)
62+ let clientDownloadSize = await stream.read ()
63+
64+ # Step 2: Read upload data until EOF
65+ var totalBytesRead = 0
66+ while true :
67+ let chunk = await stream.read ()
68+ if chunk.len == 0 :
69+ break
70+ totalBytesRead += chunk.len
71+
72+ # Step 3: Send download data back
73+ var remainingToSend = uint64 .fromBytesBE (clientDownloadSize)
74+ while remainingToSend > 0 :
75+ let toSend = min (remainingToSend, chunkSize)
76+ try :
77+ await stream.write (newSeq [byte ](toSend))
78+ except StreamError :
79+ echo " STREAM ERROR 1"
80+ quit (1 )
81+ remainingToSend -= toSend
82+
83+ stream.close ()
84+
85+ # Start server handler
86+ asyncSpawn serverHandler ()
87+
88+ let startTime = Moment .now ()
89+
90+ # Step 1: Send download size, activate stream first
91+ let clientStream = await outgoingConn.openStream ()
92+ try :
93+ await clientStream.write (toSeq (downloadSize.uint64 .toBytesBE ()))
94+ except StreamError :
95+ echo " STREAM ERROR 1"
96+ quit (1 )
97+ # Step 2: Send upload data in chunks
98+ var remainingToSend = uploadSize
99+ while remainingToSend > 0 :
100+ let toSend = min (remainingToSend, chunkSize)
101+ await clientStream.write (newSeq [byte ](toSend))
102+ remainingToSend -= toSend
103+
104+ # Step 3: Close write side
105+ clientStream.close ()
106+
107+ # Step 4: Start reading download data
108+ var totalDownloaded = 0
109+ while totalDownloaded < downloadSize:
110+ let chunk = await clientStream.read ()
111+ totalDownloaded += chunk.len
27112
113+ let duration = Moment .now () - startTime
114+
115+ await listener.stop ()
116+ await client.stop ()
117+
118+ return duration
119+
120+ suite " perf protocol simulation" :
121+ asyncTest " test" :
122+ var total: Duration
123+ for i in 0 ..< runs:
124+ let duration = await runPerf ()
125+ total += duration
126+ echo " \t run #" & $ (i + 1 ) & " duration: " & $ duration
127+
128+ echo " \t avrg duration: " & $ (total div runs)
129+
130+ suite " tests" :
28131 asyncTest " test" :
29132 let logger = struct_lsquic_logger_if (log_buf: logging)
30133 discard lsquic_set_log_level (" debug" )
@@ -76,7 +179,6 @@ suite "connections":
76179
77180 let incomingBehaviour = proc () {.async .} =
78181 try :
79- echo " HERE"
80182 let stream = await incomingConn.incomingStream ()
81183 echo " Received stream in server"
82184
@@ -107,12 +209,15 @@ suite "connections":
107209 outgoingConn.close ()
108210 incomingConn.close ()
109211
212+ # Cannot create a stream once closed
213+ expect ConnectionError :
214+ discard await outgoingConn.openStream ()
215+
110216 await sleepAsync (1 .seconds)
111217
112218 await client.stop ()
113219 await listener.stop ()
114220
115- # TODO : perf example
116221 # TODO : destructors: (nice to have:)
117222 # - lsquic_global_cleanup() to free global resources.
118223 # - lsquic_engine_destroy(engine)
0 commit comments