From 1e7dfd0e34916b716e9476dd5a9be82b63669842 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sun, 30 Jun 2024 16:23:29 -0400 Subject: [PATCH 1/2] Add more `core:net` tests - UDP send & read - DNS resolution - Nonblocking socket option --- tests/core/net/test_core_net.odin | 99 +++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/tests/core/net/test_core_net.odin b/tests/core/net/test_core_net.odin index f806463e96a..d5949fb6c6f 100644 --- a/tests/core/net/test_core_net.odin +++ b/tests/core/net/test_core_net.odin @@ -18,6 +18,7 @@ import "core:sync" import "core:time" import "core:thread" import "core:fmt" +import "core:log" @test address_parsing_test :: proc(t: ^testing.T) { @@ -216,6 +217,8 @@ IP_Address_Parsing_Test_Vectors :: []IP_Address_Parsing_Test_Vector{ ENDPOINT_TWO_SERVERS := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9991} ENDPOINT_CLOSED_PORT := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9992} ENDPOINT_SERVER_SENDS := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9993} +ENDPOINT_UDP_ECHO := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9994} +ENDPOINT_NONBLOCK := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9995} @(test) two_servers_binding_same_endpoint :: proc(t: ^testing.T) { @@ -516,6 +519,102 @@ join_url_test :: proc(t: ^testing.T) { } } +@test +test_udp_echo :: proc(t: ^testing.T) { + server, make_server_err := net.make_unbound_udp_socket(.IP4) + if !testing.expect_value(t, make_server_err, nil) { + return + } + defer net.close(server) + + bind_server_err := net.bind(server, ENDPOINT_UDP_ECHO) + if !testing.expect_value(t, bind_server_err, nil) { + return + } + + client, make_client_err := net.make_unbound_udp_socket(.IP4) + if !testing.expect_value(t, make_client_err, nil) { + return + } + defer net.close(client) + + msg := "Hellope world!" + buf: [64]u8 + + bytes_written, send_err := net.send_udp(client, transmute([]u8)msg[:], ENDPOINT_UDP_ECHO) + if !testing.expect_value(t, send_err, nil) { + return + } + if !testing.expect_value(t, bytes_written, len(msg)) { + return + } + + bytes_read, _, read_err := net.recv_udp(server, buf[:]) + if !testing.expect_value(t, read_err, nil) { + return + } + if !testing.expect_value(t, bytes_read, len(msg)) { + return + } + + testing.expect_value(t, msg, transmute(string)buf[:bytes_read]) +} + +@test +test_dns_resolve :: proc(t: ^testing.T) { + // NOTE: This test depends on external factors, so if it fails, an IP + // address may have changed or become unavailable. + + // The net API returns only one address per protocol version, and DNS + // records can store many, so we'll have to check all possibilities. + ep4, ep6, resolve_err := net.resolve("dns.quad9.net") + if !testing.expect_value(t, resolve_err, nil) { + return + } + + ip4, ip4_ok := ep4.address.(net.IP4_Address) + if !testing.expect(t, ip4_ok, "Unable to resolve IP4") { + return + } + + valid_ip4_a := net.IP4_Address{ 9, 9, 9, 9} + valid_ip4_b := net.IP4_Address{149, 112, 112, 112} + if ip4 != valid_ip4_a && ip4 != valid_ip4_b { + log.errorf("DNS resolved to invalid IP4: %v, expected %v or %v", ip4, valid_ip4_a, valid_ip4_b) + } + + ip6, ip6_ok := ep6.address.(net.IP6_Address) + if !testing.expect(t, ip6_ok, "Unable to resolve IP6") { + return + } + + valid_ip6_a := net.IP6_Address{0x2620, 0xfe, 0, 0, 0, 0, 0, 9} + valid_ip6_b := net.IP6_Address{0x2620, 0xfe, 0, 0, 0, 0, 0, 0xfe} + if ip6 != valid_ip6_a && ip6 != valid_ip6_b { + log.errorf("DNS resolved to invalid IP6: %v, expected %v or %v", ip6, valid_ip6_a, valid_ip6_b) + } +} + +@test +test_nonblocking_option :: proc(t: ^testing.T) { + server, listen_err := net.listen_tcp(ENDPOINT_NONBLOCK) + if !testing.expect_value(t, listen_err, nil) { + return + } + defer net.close(server) + + testing.set_fail_timeout(t, 2 * time.Second) + + // If the nonblocking option isn't set correctly in the operating system, + // this should block until the timeout hits. + net.set_blocking(server, false) + + _, _, accept_err := net.accept_tcp(server) + if !testing.expect_value(t, accept_err, net.Accept_Error.Would_Block) { + return + } +} + @(private) address_to_binstr :: proc(address: net.Address) -> (binstr: string) { switch t in address { From 8e64265aed03f7d3b6fec51bbbd8596f2a271c0d Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sun, 30 Jun 2024 16:27:37 -0400 Subject: [PATCH 2/2] Replace unneeded `transmute` --- tests/core/net/test_core_net.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/core/net/test_core_net.odin b/tests/core/net/test_core_net.odin index d5949fb6c6f..a8f41082aed 100644 --- a/tests/core/net/test_core_net.odin +++ b/tests/core/net/test_core_net.odin @@ -259,7 +259,7 @@ client_sends_server_data :: proc(t: ^testing.T) { } tcp_client :: proc(thread_data: rawptr) { - r := transmute(^Thread_Data)thread_data + r := cast(^Thread_Data)thread_data defer sync.wait_group_done(r.wg) @@ -274,7 +274,7 @@ client_sends_server_data :: proc(t: ^testing.T) { } tcp_server :: proc(thread_data: rawptr) { - r := transmute(^Thread_Data)thread_data + r := cast(^Thread_Data)thread_data defer sync.wait_group_done(r.wg)