123456789module tests1011import compress.zlib12import crypto.blake313import crypto.hmac14import crypto.sha25615import net16import net.http17import time1819202122fn test_built_with_the_pinned_v() {23 assert @VCURRENTHASH == 'b9a2d87'24}2526272829fn test_blake3_vectors() {30 assert blake3.sum256(''.bytes()).hex() == 'af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262'31 assert blake3.sum256('abc'.bytes()).hex() == '6437b3ac38465133ffb63b75273a8db548c558465d79db03fd359c6cd5bd9d85'32 assert blake3.sum256('The quick brown fox jumps over the lazy dog'.bytes()).hex() == '2f1514181aadccd913abd94cfa592701a5686ab23f8df1dff1b74710febc6d4a'33}3435fn test_blake3_streaming_matches_one_shot() {36 mut d := blake3.Digest.new_hash()!37 d.write('The quick brown '.bytes())!38 d.write('fox jumps over the lazy dog'.bytes())!39 assert d.checksum(32) == blake3.sum256('The quick brown fox jumps over the lazy dog'.bytes())40}4142fn test_zlib_round_trip() {43 44 45 mut all_bytes := []u8{len: 256}46 for i in 0 .. 256 {47 all_bytes[i] = u8(i)48 }49 mut payloads := [[]u8{}, 'hello koh'.bytes()]50 payloads << all_bytes51 for payload in payloads {52 packed := zlib.compress(payload)!53 assert zlib.decompress(packed)! == payload54 }55}5657fn test_sha256_and_hmac_vectors() {58 assert sha256.sum256('abc'.bytes()).hex() == 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'59 assert sha256.hexhash('abc') == 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'60 61 mac := hmac.new('key'.bytes(), 'The quick brown fox jumps over the lazy dog'.bytes(),62 sha256.sum256, 64)63 assert mac.hex() == 'f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8'64}6566struct EtagHandler {67mut:68 seen_if_none_match string69}7071fn (mut h EtagHandler) handle(req http.Request) http.Response {72 h.seen_if_none_match = req.header.get_custom('If-None-Match', http.HeaderQueryConfig{}) or {73 ''74 }75 mut resp := http.Response{76 body: 'payload'77 }78 if h.seen_if_none_match == '*' {79 resp.status_code = 41280 resp.status_msg = 'Precondition Failed'81 } else {82 resp.status_code = 20083 resp.status_msg = 'OK'84 }85 resp.header.add_custom('ETag', '"3b1f"') or {}86 return resp87}88899091fn start_probe_server() !(int, &http.Server) {92 for port in [19301, 19302, 19303, 19304, 19305] {93 listener := net.listen_tcp(.ip, '127.0.0.1:${port}') or { continue }94 mut server := &http.Server{95 listener: listener96 handler: EtagHandler{}97 show_startup_message: false98 }99 spawn server.listen_and_serve()100 server.wait_till_running()!101 return port, server102 }103 return error('no free port for the probe server')104}105106107108109fn test_http_client_sends_headers_and_reads_status_and_etag() {110 port, mut server := start_probe_server()!111 defer {112 server.stop()113 }114 url := 'http://127.0.0.1:${port}/probe'115 mut hdr := http.new_header()116 hdr.add_custom('If-None-Match', '*')!117118 resp := http.fetch(119 url: url120 method: .get121 header: hdr122 )!123 assert resp.status_code == 412124 assert resp.header.get_custom('ETag', http.HeaderQueryConfig{}) or { '' } == '"3b1f"'125126 plain := http.fetch(url: url, method: .get)!127 assert plain.status_code == 200128 assert plain.body == 'payload'129130 131 132 if _ := http.fetch(133 url: 'http://127.0.0.1:19399/gone'134 method: .get135 read_timeout: 2 * time.second136 )137 {138 assert false, 'a request to a closed port should fail'139 }140}