mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-12 14:23:33 +00:00
248 lines
5.7 KiB
Odin
248 lines
5.7 KiB
Odin
package tests_nbio
|
|
|
|
import "core:nbio"
|
|
import "core:net"
|
|
import "core:testing"
|
|
import "core:time"
|
|
import "core:log"
|
|
|
|
// Removals are pretty complex.
|
|
|
|
@(test)
|
|
immediate_remove_of_sendfile :: proc(t: ^testing.T) {
|
|
if event_loop_guard(t) {
|
|
testing.set_fail_timeout(t, time.Minute)
|
|
|
|
sock, ep := open_next_available_local_port(t)
|
|
|
|
// Server
|
|
{
|
|
nbio.accept_poly(sock, t, on_accept)
|
|
|
|
on_accept :: proc(op: ^nbio.Operation, t: ^testing.T) {
|
|
ev(t, op.accept.err, nil)
|
|
e(t, op.accept.client != 0)
|
|
|
|
log.debugf("connection from: %v", op.accept.client_endpoint)
|
|
nbio.open_poly3(#file, t, op.accept.socket, op.accept.client, on_open)
|
|
}
|
|
|
|
on_open :: proc(op: ^nbio.Operation, t: ^testing.T, server, client: net.TCP_Socket) {
|
|
ev(t, op.open.err, nil)
|
|
e(t, op.open.handle != 0)
|
|
|
|
sendfile_op := nbio.sendfile_poly2(client, op.open.handle, t, server, on_sendfile)
|
|
|
|
// oh no changed my mind.
|
|
nbio.remove(sendfile_op)
|
|
|
|
nbio.close(op.open.handle)
|
|
nbio.close(client)
|
|
nbio.close(server)
|
|
}
|
|
|
|
on_sendfile :: proc(op: ^nbio.Operation, t: ^testing.T, server: net.TCP_Socket) {
|
|
log.error("on_sendfile shouldn't be called")
|
|
}
|
|
}
|
|
|
|
// Client
|
|
{
|
|
nbio.dial_poly(ep, t, on_dial)
|
|
|
|
on_dial :: proc(op: ^nbio.Operation, t: ^testing.T) {
|
|
ev(t, op.dial.err, nil)
|
|
|
|
buf := make([]byte, 128, context.temp_allocator)
|
|
nbio.recv_poly(op.dial.socket, {buf}, t, on_recv)
|
|
}
|
|
|
|
on_recv :: proc(op: ^nbio.Operation, t: ^testing.T) {
|
|
ev(t, op.recv.err, nil)
|
|
|
|
nbio.close(op.recv.socket.(net.TCP_Socket))
|
|
}
|
|
}
|
|
|
|
ev(t, nbio.run(), nil)
|
|
}
|
|
}
|
|
|
|
@(test)
|
|
immediate_remove_of_sendfile_without_stat :: proc(t: ^testing.T) {
|
|
if event_loop_guard(t) {
|
|
testing.set_fail_timeout(t, time.Minute)
|
|
|
|
sock, ep := open_next_available_local_port(t)
|
|
|
|
// Server
|
|
{
|
|
nbio.accept_poly(sock, t, on_accept)
|
|
|
|
on_accept :: proc(op: ^nbio.Operation, t: ^testing.T) {
|
|
ev(t, op.accept.err, nil)
|
|
e(t, op.accept.client != 0)
|
|
|
|
log.debugf("connection from: %v", op.accept.client_endpoint)
|
|
nbio.open_poly3(#file, t, op.accept.socket, op.accept.client, on_open)
|
|
}
|
|
|
|
on_open :: proc(op: ^nbio.Operation, t: ^testing.T, server, client: net.TCP_Socket) {
|
|
ev(t, op.open.err, nil)
|
|
e(t, op.open.handle != 0)
|
|
|
|
nbio.stat_poly3(op.open.handle, t, server, client, on_stat)
|
|
}
|
|
|
|
on_stat :: proc(op: ^nbio.Operation, t: ^testing.T, server, client: net.TCP_Socket) {
|
|
ev(t, op.stat.err, nil)
|
|
|
|
sendfile_op := nbio.sendfile_poly2(client, op.stat.handle, t, server, on_sendfile, nbytes=int(op.stat.size))
|
|
|
|
// oh no changed my mind.
|
|
nbio.remove(sendfile_op)
|
|
|
|
nbio.timeout_poly3(time.Millisecond * 10, op.stat.handle, client, server, proc(op: ^nbio.Operation, p1: nbio.Handle, p2, p3: net.TCP_Socket){
|
|
nbio.close(p1)
|
|
nbio.close(p2)
|
|
nbio.close(p3)
|
|
})
|
|
}
|
|
|
|
on_sendfile :: proc(op: ^nbio.Operation, t: ^testing.T, server: net.TCP_Socket) {
|
|
log.error("on_sendfile shouldn't be called")
|
|
}
|
|
}
|
|
|
|
// Client
|
|
{
|
|
nbio.dial_poly(ep, t, on_dial)
|
|
|
|
on_dial :: proc(op: ^nbio.Operation, t: ^testing.T) {
|
|
ev(t, op.dial.err, nil)
|
|
|
|
buf := make([]byte, 128, context.temp_allocator)
|
|
nbio.recv_poly(op.dial.socket, {buf}, t, on_recv)
|
|
}
|
|
|
|
on_recv :: proc(op: ^nbio.Operation, t: ^testing.T) {
|
|
ev(t, op.recv.err, nil)
|
|
|
|
nbio.close(op.recv.socket.(net.TCP_Socket))
|
|
}
|
|
}
|
|
|
|
ev(t, nbio.run(), nil)
|
|
}
|
|
}
|
|
|
|
// Open should free the temporary memory allocated for the path when removed.
|
|
// Can't really test that though, so should be checked manually that the internal callback is called but not the external.
|
|
@(test)
|
|
remove_open :: proc(t: ^testing.T) {
|
|
if event_loop_guard(t) {
|
|
testing.set_fail_timeout(t, time.Minute)
|
|
|
|
open := nbio.open(#file, on_open)
|
|
nbio.remove(open)
|
|
|
|
on_open :: proc(op: ^nbio.Operation) {
|
|
log.error("on_open shouldn't be called")
|
|
}
|
|
|
|
ev(t, nbio.run(), nil)
|
|
}
|
|
}
|
|
|
|
// Dial should close the socket when removed.
|
|
// Can't really test that though, so should be checked manually that the internal callback is called but not the external.
|
|
@(test)
|
|
remove_dial :: proc(t: ^testing.T) {
|
|
if event_loop_guard(t) {
|
|
testing.set_fail_timeout(t, time.Minute)
|
|
|
|
sock, ep := open_next_available_local_port(t)
|
|
defer nbio.close(sock)
|
|
|
|
dial := nbio.dial(ep, on_dial)
|
|
nbio.remove(dial)
|
|
|
|
on_dial :: proc(op: ^nbio.Operation) {
|
|
log.error("on_dial shouldn't be called")
|
|
}
|
|
|
|
ev(t, nbio.run(), nil)
|
|
}
|
|
}
|
|
|
|
@(test)
|
|
remove_next_tick :: proc(t: ^testing.T) {
|
|
if event_loop_guard(t) {
|
|
testing.set_fail_timeout(t, time.Minute)
|
|
|
|
nt := nbio.next_tick_poly(t, proc(op: ^nbio.Operation, t: ^testing.T) {
|
|
log.error("shouldn't be called")
|
|
})
|
|
nbio.remove(nt)
|
|
|
|
ev(t, nbio.run(), nil)
|
|
}
|
|
}
|
|
|
|
@(test)
|
|
remove_timeout :: proc(t: ^testing.T) {
|
|
if event_loop_guard(t) {
|
|
testing.set_fail_timeout(t, time.Minute)
|
|
|
|
hit: bool
|
|
timeout := nbio.timeout_poly(time.Second, &hit, proc(_: ^nbio.Operation, hit: ^bool) {
|
|
hit^ = true
|
|
})
|
|
|
|
nbio.remove(timeout)
|
|
|
|
ev(t, nbio.run(), nil)
|
|
|
|
e(t, !hit)
|
|
}
|
|
}
|
|
|
|
@(test)
|
|
remove_multiple_poll :: proc(t: ^testing.T) {
|
|
if event_loop_guard(t) {
|
|
testing.set_fail_timeout(t, time.Minute)
|
|
|
|
sock, ep := open_next_available_local_port(t)
|
|
defer nbio.close(sock)
|
|
|
|
hit: bool
|
|
|
|
first := nbio.poll(sock, .Receive, on_poll)
|
|
nbio.poll_poly2(sock, .Receive, t, &hit, on_poll2)
|
|
|
|
on_poll :: proc(op: ^nbio.Operation) {
|
|
log.error("shouldn't be called")
|
|
}
|
|
|
|
on_poll2 :: proc(op: ^nbio.Operation, t: ^testing.T, hit: ^bool) {
|
|
ev(t, op.poll.result, nbio.Poll_Result.Ready)
|
|
hit^ = true
|
|
}
|
|
|
|
ev(t, nbio.tick(0), nil)
|
|
|
|
nbio.remove(first)
|
|
|
|
ev(t, nbio.tick(0), nil)
|
|
|
|
nbio.dial_poly(ep, t, on_dial)
|
|
|
|
on_dial :: proc(op: ^nbio.Operation, t: ^testing.T) {
|
|
ev(t, op.dial.err, nil)
|
|
}
|
|
|
|
ev(t, nbio.run(), nil)
|
|
e(t, hit)
|
|
}
|
|
}
|