123456789module tests1011import compress.zlib12import crypto.blake313import crypto.hmac14import crypto.sha25615import net16import net.http17import os18import time1920212223fn test_built_with_the_pinned_v() {24 assert @VCURRENTHASH == 'b9a2d87'25}2627fn test_koh_refuses_a_build_without_garbage_collection() {28 output := os.join_path(os.temp_dir(), 'koh-no-gc-${os.getpid()}')29 result := os.execute('v -gc none -o "${output}" "${@VMODROOT}/src/koh.v"')30 assert result.exit_code != 031 assert result.output.contains('Koh requires garbage collection')32}3334353637fn test_blake3_vectors() {38 assert blake3.sum256(''.bytes()).hex() == 'af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262'39 assert blake3.sum256('abc'.bytes()).hex() == '6437b3ac38465133ffb63b75273a8db548c558465d79db03fd359c6cd5bd9d85'40 assert blake3.sum256('The quick brown fox jumps over the lazy dog'.bytes()).hex() == '2f1514181aadccd913abd94cfa592701a5686ab23f8df1dff1b74710febc6d4a'41}4243fn test_blake3_streaming_matches_one_shot() {44 mut d := blake3.Digest.new_hash()!45 d.write('The quick brown '.bytes())!46 d.write('fox jumps over the lazy dog'.bytes())!47 assert d.checksum(32) == blake3.sum256('The quick brown fox jumps over the lazy dog'.bytes())48}4950fn test_zlib_round_trip() {51 52 53 mut all_bytes := []u8{len: 256}54 for i in 0 .. 256 {55 all_bytes[i] = u8(i)56 }57 mut payloads := [[]u8{}, 'hello koh'.bytes()]58 payloads << all_bytes59 for payload in payloads {60 packed := zlib.compress(payload)!61 assert zlib.decompress(packed)! == payload62 }63}6465fn test_sha256_and_hmac_vectors() {66 assert sha256.sum256('abc'.bytes()).hex() == 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'67 assert sha256.hexhash('abc') == 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'68 69 mac := hmac.new('key'.bytes(), 'The quick brown fox jumps over the lazy dog'.bytes(),70 sha256.sum256, 64)71 assert mac.hex() == 'f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8'72}7374struct EtagHandler {75mut:76 seen_if_none_match string77}7879fn (mut h EtagHandler) handle(req http.Request) http.Response {80 h.seen_if_none_match = req.header.get_custom('If-None-Match', http.HeaderQueryConfig{}) or {81 ''82 }83 mut resp := http.Response{84 body: 'payload'85 }86 if h.seen_if_none_match == '*' {87 resp.status_code = 41288 resp.status_msg = 'Precondition Failed'89 } else {90 resp.status_code = 20091 resp.status_msg = 'OK'92 }93 resp.header.add_custom('ETag', '"3b1f"') or {}94 return resp95}96979899fn start_probe_server() !(int, &http.Server) {100 for port in [19301, 19302, 19303, 19304, 19305] {101 listener := net.listen_tcp(.ip, '127.0.0.1:${port}') or { continue }102 mut server := &http.Server{103 listener: listener104 handler: EtagHandler{}105 show_startup_message: false106 }107 spawn server.listen_and_serve()108 server.wait_till_running()!109 return port, server110 }111 return error('no free port for the probe server')112}113114115116117fn test_http_client_sends_headers_and_reads_status_and_etag() {118 port, mut server := start_probe_server()!119 defer {120 server.stop()121 }122 url := 'http://127.0.0.1:${port}/probe'123 mut hdr := http.new_header()124 hdr.add_custom('If-None-Match', '*')!125126 resp := http.fetch(127 url: url128 method: .get129 header: hdr130 )!131 assert resp.status_code == 412132 assert resp.header.get_custom('ETag', http.HeaderQueryConfig{}) or { '' } == '"3b1f"'133134 plain := http.fetch(url: url, method: .get)!135 assert plain.status_code == 200136 assert plain.body == 'payload'137138 139 140 if _ := http.fetch(141 url: 'http://127.0.0.1:19399/gone'142 method: .get143 read_timeout: 2 * time.second144 )145 {146 assert false, 'a request to a closed port should fail'147 }148}