Browse Source

Port `tests\core\net`

Jeroen van Rijn 1 năm trước cách đây
mục cha
commit
62b7d8de97
3 tập tin đã thay đổi với 85 bổ sung195 xóa
  1. 1 1
      tests/core/Makefile
  2. 1 1
      tests/core/build.bat
  3. 83 193
      tests/core/net/test_core_net.odin

+ 1 - 1
tests/core/Makefile

@@ -81,7 +81,7 @@ noise_test:
 	$(ODIN) test math/noise $(COMMON) -out:test_noise
 
 net_test:
-	$(ODIN) run net $(COMMON) -out:test_core_net
+	$(ODIN) test net $(COMMON) -out:test_core_net
 
 os_exit_test:
 	$(ODIN) run os/test_core_os_exit.odin -file -out:test_core_os_exit && exit 1 || exit 0

+ 1 - 1
tests/core/build.bat

@@ -81,7 +81,7 @@ echo ---
 echo ---
 echo Running core:net
 echo ---
-%PATH_TO_ODIN% run net %COMMON% -out:test_core_net.exe || exit /b
+%PATH_TO_ODIN% test net %COMMON% -out:test_core_net.exe || exit /b
 
 echo ---
 echo Running core:odin tests

+ 83 - 193
tests/core/net/test_core_net.odin

@@ -11,71 +11,12 @@
 package test_core_net
 
 import "core:testing"
-import "core:mem"
-import "core:fmt"
 import "core:net"
 import "core:strconv"
 import "core:sync"
 import "core:time"
 import "core:thread"
-import "core:os"
-
-_, _ :: time, thread
-
-TEST_count := 0
-TEST_fail  := 0
-
-t := &testing.T{}
-
-when ODIN_TEST {
-    expect  :: testing.expect
-    log     :: testing.log
-} else {
-    expect  :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
-        TEST_count += 1
-        if !condition {
-            TEST_fail += 1
-            fmt.printf("[%v] %v\n", loc, message)
-            return
-        }
-    }
-    log     :: proc(t: ^testing.T, v: any, loc := #caller_location) {
-        fmt.printf("[%v] ", loc)
-        fmt.printf("log: %v\n", v)
-    }
-}
-
-_tracking_allocator := mem.Tracking_Allocator{}
-
-print_tracking_allocator_report :: proc() {
-	for _, leak in _tracking_allocator.allocation_map {
-		fmt.printf("%v leaked %v bytes\n", leak.location, leak.size)
-	}
-
-	for bf in _tracking_allocator.bad_free_array {
-		fmt.printf("%v allocation %p was freed badly\n", bf.location, bf.memory)
-	}
-}
-
-main :: proc() {
-	mem.tracking_allocator_init(&_tracking_allocator, context.allocator)
-	context.allocator = mem.tracking_allocator(&_tracking_allocator)
-
-	address_parsing_test(t)
-
-	tcp_tests(t)
-
-	split_url_test(t)
-	join_url_test(t)
-
-	fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
-
-	print_tracking_allocator_report()
-
-	if TEST_fail > 0 {
-		os.exit(1)
-	}
-}
+import "core:fmt"
 
 @test
 address_parsing_test :: proc(t: ^testing.T) {
@@ -89,127 +30,66 @@ address_parsing_test :: proc(t: ^testing.T) {
 		}
 
 		valid := len(vector.binstr) > 0
-
-		fmt.printf("%v %v\n", kind, vector.input)
-
-		msg := "-set a proper message-"
 		switch vector.family {
 		case .IP4, .IP4_Alt:
-			/*
-				Does `net.parse_ip4_address` think we parsed the address properly?
-			*/
+			// Does `net.parse_ip4_address` think we parsed the address properly?
 			non_decimal := vector.family == .IP4_Alt
+			any_addr    := net.parse_address(vector.input, non_decimal)
+			parsed_ok   := any_addr != nil
+			parsed: net.IP4_Address
 
-			any_addr  := net.parse_address(vector.input, non_decimal)
-			parsed_ok := any_addr != nil
-			parsed:   net.IP4_Address
-
-			/*
-				Ensure that `parse_address` doesn't parse IPv4 addresses into IPv6 addreses by mistake.
-			*/
+			// Ensure that `parse_address` doesn't parse IPv4 addresses into IPv6 addreses by mistake.
 			switch addr in any_addr {
 			case net.IP4_Address:
 				parsed = addr
 			case net.IP6_Address:
 				parsed_ok = false
-				msg = fmt.tprintf("parse_address mistook %v as IPv6 address %04x", vector.input, addr)
-				expect(t, false, msg)
+				testing.expectf(t, false, "parse_address mistook %v as IPv6 address %04x", vector.input, addr)
 			}
 
 			if !parsed_ok && valid {
-				msg = fmt.tprintf("parse_ip4_address failed to parse %v, expected %v", vector.input, binstr_to_address(vector.binstr))
+				testing.expectf(t, parsed_ok == valid, "parse_ip4_address failed to parse %v, expected %v", vector.input, binstr_to_address(t, vector.binstr))
 
 			} else if parsed_ok && !valid {
-				msg = fmt.tprintf("parse_ip4_address parsed %v into %v, expected failure", vector.input, parsed)
+				testing.expectf(t, parsed_ok == valid, "parse_ip4_address parsed %v into %v, expected failure", vector.input, parsed)
 			}
-			expect(t, parsed_ok == valid, msg)
 
 			if valid && parsed_ok {
 				actual_binary := address_to_binstr(parsed)
-				msg = fmt.tprintf("parse_ip4_address parsed %v into %v, expected %v", vector.input, actual_binary, vector.binstr)
-				expect(t, actual_binary == vector.binstr, msg)
+				testing.expectf(t, actual_binary == vector.binstr, "parse_ip4_address parsed %v into %v, expected %v", vector.input, actual_binary, vector.binstr)
 
-				/*
-					Do we turn an address back into the same string properly?
-					No point in testing the roundtrip if the first part failed.
-				*/
+				// Do we turn an address back into the same string properly? No point in testing the roundtrip if the first part failed.
 				if len(vector.output) > 0 && actual_binary == vector.binstr {
 					stringified := net.address_to_string(parsed)
-					msg = fmt.tprintf("address_to_string turned %v into %v, expected %v", parsed, stringified, vector.output)
-					expect(t, stringified == vector.output, msg)
+					testing.expectf(t, stringified == vector.output, "address_to_string turned %v into %v, expected %v", parsed, stringified, vector.output)
 				}
 			}
 
 		case .IP6:
-			/*
-				Do we parse the address properly?
-			*/
+			// Do we parse the address properly?
 			parsed, parsed_ok := net.parse_ip6_address(vector.input)
 
 			if !parsed_ok && valid {
-				msg = fmt.tprintf("parse_ip6_address failed to parse %v, expected %04x", vector.input, binstr_to_address(vector.binstr))
+				testing.expectf(t, parsed_ok == valid, "parse_ip6_address failed to parse %v, expected %04x", vector.input, binstr_to_address(t, vector.binstr))
 
 			} else if parsed_ok && !valid {
-				msg = fmt.tprintf("parse_ip6_address parsed %v into %04x, expected failure", vector.input, parsed)
+				testing.expectf(t, parsed_ok == valid, "parse_ip6_address parsed %v into %04x, expected failure", vector.input, parsed)
 			}
-			expect(t, parsed_ok == valid, msg)
 
 			if valid && parsed_ok {
 				actual_binary := address_to_binstr(parsed)
-				msg = fmt.tprintf("parse_ip6_address parsed %v into %v, expected %v", vector.input, actual_binary, vector.binstr)
-				expect(t, actual_binary == vector.binstr, msg)
+				testing.expectf(t, actual_binary == vector.binstr, "parse_ip6_address parsed %v into %v, expected %v", vector.input, actual_binary, vector.binstr)
 
-				/*
-					Do we turn an address back into the same string properly?
-					No point in testing the roundtrip if the first part failed.
-				*/
+				// Do we turn an address back into the same string properly? No point in testing the roundtrip if the first part failed.
 				if len(vector.output) > 0 && actual_binary == vector.binstr {
 					stringified := net.address_to_string(parsed)
-					msg = fmt.tprintf("address_to_string turned %v into %v, expected %v", parsed, stringified, vector.output)
-					expect(t, stringified == vector.output, msg)
+					testing.expectf(t, stringified == vector.output, "address_to_string turned %v into %v, expected %v", parsed, stringified, vector.output)
 				}
 			}
 		}
 	}
 }
 
-address_to_binstr :: proc(address: net.Address) -> (binstr: string) {
-	switch t in address {
-	case net.IP4_Address:
-		b := transmute(u32be)t
-		return fmt.tprintf("%08x", b)
-	case net.IP6_Address:
-		b := transmute(u128be)t
-		return fmt.tprintf("%32x", b)
-	case:
-		return ""
-	}
-	unreachable()
-}
-
-binstr_to_address :: proc(binstr: string) -> (address: net.Address) {
-	switch len(binstr) {
-	case 8:  // IPv4
-		a, ok := strconv.parse_u64_of_base(binstr, 16)
-		expect(t, ok, "failed to parse test case bin string")
-
-		ipv4 := u32be(a)
-		return net.IP4_Address(transmute([4]u8)ipv4)
-
-
-	case 32: // IPv6
-		a, ok := strconv.parse_u128_of_base(binstr, 16)
-		expect(t, ok, "failed to parse test case bin string")
-
-		ipv4 := u128be(a)
-		return net.IP6_Address(transmute([8]u16be)ipv4)
-
-	case 0:
-		return nil
-	}
-	panic("Invalid test case")
-}
-
 Kind :: enum {
 	IP4,     // Decimal IPv4
 	IP4_Alt, // Non-decimal address
@@ -223,10 +103,7 @@ IP_Address_Parsing_Test_Vector :: struct {
 	// Input address to try and parse.
 	input:            string,
 
-	/*
-		Hexadecimal representation of the expected numeric value of the address.
-		Zero length means input is invalid and the parser should report failure.
-	*/
+	// Hexadecimal representation of the expected numeric value of the address. Zero length means input is invalid and the parser should report failure.
 	binstr:           string,
 
 	// Expected `address_to_string` output, if a valid input and this string is non-empty.
@@ -335,38 +212,30 @@ IP_Address_Parsing_Test_Vectors :: []IP_Address_Parsing_Test_Vector{
 	{ .IP6, "c0a8",                    "", ""},
 }
 
-tcp_tests :: proc(t: ^testing.T) {
-	fmt.println("Testing two servers trying to bind to the same endpoint...")
-	two_servers_binding_same_endpoint(t)
-	fmt.println("Testing client connecting to a closed port...")
-	client_connects_to_closed_port(t)
-	fmt.println("Testing client sending server data...")
-	client_sends_server_data(t)
-}
-
-ENDPOINT := net.Endpoint{
-	net.IP4_Address{127, 0, 0, 1},
-	9999,
-}
+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}
 
 @(test)
 two_servers_binding_same_endpoint :: proc(t: ^testing.T) {
-	skt1, err1 := net.listen_tcp(ENDPOINT)
+	skt1, err1 := net.listen_tcp(ENDPOINT_TWO_SERVERS)
 	defer net.close(skt1)
-	skt2, err2 := net.listen_tcp(ENDPOINT)
+	skt2, err2 := net.listen_tcp(ENDPOINT_TWO_SERVERS)
 	defer net.close(skt2)
 
-	expect(t, err1 == nil, "expected first server binding to endpoint to do so without error")
-	expect(t, err2 == net.Bind_Error.Address_In_Use, "expected second server to bind to an endpoint to return .Address_In_Use")
+	testing.expect(t, err1 == nil, "expected first server binding to endpoint to do so without error")
+	testing.expect(t, err2 == net.Bind_Error.Address_In_Use, "expected second server to bind to an endpoint to return .Address_In_Use")
 }
 
 @(test)
 client_connects_to_closed_port :: proc(t: ^testing.T) {
-	skt, err := net.dial_tcp(ENDPOINT)
+
+	skt, err := net.dial_tcp(ENDPOINT_CLOSED_PORT)
 	defer net.close(skt)
-	expect(t, err == net.Dial_Error.Refused, "expected dial of a closed endpoint to return .Refused")
+	testing.expect(t, err == net.Dial_Error.Refused, "expected dial of a closed endpoint to return .Refused")
 }
 
+
 @(test)
 client_sends_server_data :: proc(t: ^testing.T) {
 	CONTENT: string: "Hellope!"
@@ -390,8 +259,8 @@ client_sends_server_data :: proc(t: ^testing.T) {
 
 		defer sync.wait_group_done(r.wg)
 
-		if r.skt, r.err = net.dial_tcp(ENDPOINT); r.err != nil {
-			log(r.t, r.err)
+		if r.skt, r.err = net.dial_tcp(ENDPOINT_SERVER_SENDS); r.err != nil {
+			testing.expectf(r.t, false, "[tcp_client:dial_tcp] %v", r.err)
 			return
 		}
 
@@ -405,19 +274,17 @@ client_sends_server_data :: proc(t: ^testing.T) {
 
 		defer sync.wait_group_done(r.wg)
 
-		log(r.t, "tcp_server listen")
-		if r.skt, r.err = net.listen_tcp(ENDPOINT); r.err != nil {
+		if r.skt, r.err = net.listen_tcp(ENDPOINT_SERVER_SENDS); r.err != nil {
 			sync.wait_group_done(r.wg)
-			log(r.t, r.err)
+			testing.expectf(r.t, false, "[tcp_server:listen_tcp] %v", r.err)
 			return
 		}
 
 		sync.wait_group_done(r.wg)
 
-		log(r.t, "tcp_server accept")
 		client: net.TCP_Socket
 		if client, _, r.err = net.accept_tcp(r.skt.(net.TCP_Socket)); r.err != nil {
-			log(r.t, r.err)
+			testing.expectf(r.t, false, "[tcp_server:accept_tcp] %v", r.err)
 			return
 		}
 		defer net.close(client)
@@ -437,10 +304,7 @@ client_sends_server_data :: proc(t: ^testing.T) {
 	thread_data[0].wg = &wg
 	thread_data[0].tid = thread.create_and_start_with_data(&thread_data[0], tcp_server, context)
 	
-	log(t, "waiting for server to start listening")
 	sync.wait_group_wait(&wg)
-	log(t, "starting up client")
-
 	sync.wait_group_add(&wg, 2)
 
 	thread_data[1].t = t
@@ -454,20 +318,15 @@ client_sends_server_data :: proc(t: ^testing.T) {
 		net.close(thread_data[1].skt)
 		thread.destroy(thread_data[1].tid)
 	}
-
-	log(t, "waiting for threads to finish")
 	sync.wait_group_wait(&wg)
-	log(t, "threads finished")
 
 	okay := thread_data[0].err == nil && thread_data[1].err == nil
-	msg  := fmt.tprintf("Expected client and server to return `nil`, got %v and %v", thread_data[0].err, thread_data[1].err)
-	expect(t, okay, msg)
+	testing.expectf(t, okay, "Expected client and server to return `nil`, got %v and %v", thread_data[0].err, thread_data[1].err)
 
 	received := string(thread_data[0].data[:thread_data[0].length])
 
 	okay  = received == CONTENT
-	msg   = fmt.tprintf("Expected client to send \"{}\", got \"{}\"", CONTENT, received)
-	expect(t, okay, msg)
+	testing.expectf(t, okay, "Expected client to send \"{}\", got \"{}\"", CONTENT, received)
 }
 
 URL_Test :: struct {
@@ -559,22 +418,15 @@ split_url_test :: proc(t: ^testing.T) {
 			delete(test.queries)
 		}
 
-		msg := fmt.tprintf("Expected `net.split_url` to return %s, got %s", test.scheme, scheme)
-		expect(t, scheme == test.scheme, msg)
-		msg = fmt.tprintf("Expected `net.split_url` to return %s, got %s", test.host, host)
-		expect(t, host == test.host, msg)
-		msg = fmt.tprintf("Expected `net.split_url` to return %s, got %s", test.path, path)
-		expect(t, path == test.path, msg)
-		msg = fmt.tprintf("Expected `net.split_url` to return %d queries, got %d queries", len(test.queries), len(queries))
-		expect(t, len(queries) == len(test.queries), msg)
+		testing.expectf(t, scheme       == test.scheme,       "Expected `net.split_url` to return %s, got %s", test.scheme, scheme)
+		testing.expectf(t, host         == test.host,         "Expected `net.split_url` to return %s, got %s", test.host, host)
+		testing.expectf(t, path         == test.path,         "Expected `net.split_url` to return %s, got %s", test.path, path)
+		testing.expectf(t, len(queries) == len(test.queries), "Expected `net.split_url` to return %d queries, got %d queries", len(test.queries), len(queries))
 		for k, v in queries {
 			expected := test.queries[k]
-			msg = fmt.tprintf("Expected `net.split_url` to return %s, got %s", expected, v)
-			expect(t, v == expected, msg)
+			testing.expectf(t, v == expected, "Expected `net.split_url` to return %s, got %s", expected, v)
 		}
-		msg = fmt.tprintf("Expected `net.split_url` to return %s, got %s", test.fragment, fragment)
-		expect(t, fragment == test.fragment, msg)
-
+		testing.expectf(t, fragment == test.fragment, "Expected `net.split_url` to return %s, got %s", test.fragment, fragment)
 	}
 }
 
@@ -659,7 +511,45 @@ join_url_test :: proc(t: ^testing.T) {
 		for test_url in test.url {
 			pass |= url == test_url
 		}
-		msg := fmt.tprintf("Expected `net.join_url` to return one of %s, got %s", test.url, url)
-		expect(t, pass, msg)
+		testing.expectf(t, pass, "Expected `net.join_url` to return one of %s, got %s", test.url, url)
+	}
+}
+
+@(private)
+address_to_binstr :: proc(address: net.Address) -> (binstr: string) {
+	switch t in address {
+	case net.IP4_Address:
+		b := transmute(u32be)t
+		return fmt.tprintf("%08x", b)
+	case net.IP6_Address:
+		b := transmute(u128be)t
+		return fmt.tprintf("%32x", b)
+	case:
+		return ""
 	}
+	unreachable()
 }
+
+@(private)
+binstr_to_address :: proc(t: ^testing.T, binstr: string) -> (address: net.Address) {
+	switch len(binstr) {
+	case 8:  // IPv4
+		a, ok := strconv.parse_u64_of_base(binstr, 16)
+		testing.expect(t, ok, "failed to parse test case bin string")
+
+		ipv4 := u32be(a)
+		return net.IP4_Address(transmute([4]u8)ipv4)
+
+
+	case 32: // IPv6
+		a, ok := strconv.parse_u128_of_base(binstr, 16)
+		testing.expect(t, ok, "failed to parse test case bin string")
+
+		ipv4 := u128be(a)
+		return net.IP6_Address(transmute([8]u16be)ipv4)
+
+	case 0:
+		return nil
+	}
+	panic("Invalid test case")
+}