190 lines
4.7 KiB
V
190 lines
4.7 KiB
V
|
import os
|
||
|
import time
|
||
|
import net
|
||
|
import net.http
|
||
|
|
||
|
const (
|
||
|
sport = 12380
|
||
|
exit_after_time = 1000 // milliseconds
|
||
|
vexe = os.getenv('VEXE')
|
||
|
vroot = os.dir(vexe)
|
||
|
serverexe = os.join_path(os.cache_dir(), 'vweb_test_server.exe')
|
||
|
)
|
||
|
|
||
|
// setup of vweb webserver
|
||
|
fn testsuite_begin() {
|
||
|
os.chdir(vroot)
|
||
|
if os.exists(serverexe) {
|
||
|
os.rm(serverexe)
|
||
|
}
|
||
|
// prevent failing tests when vweb_test.v is rerun quickly
|
||
|
// and the previous webserver has not yet timed out.
|
||
|
for i := 0; i < 10; i++ {
|
||
|
if client := net.dial('127.0.0.1', sport) {
|
||
|
client.close() or { }
|
||
|
eprintln('previous webserver has not yet stopped ($i); waiting...')
|
||
|
time.sleep_ms(exit_after_time / 10)
|
||
|
continue
|
||
|
} else {
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn test_a_simple_vweb_app_can_be_compiled() {
|
||
|
did_server_compile := os.system('$vexe -o $serverexe vlib/vweb/tests/vweb_test_server.v')
|
||
|
assert did_server_compile == 0
|
||
|
assert os.exists(serverexe)
|
||
|
}
|
||
|
|
||
|
fn test_a_simple_vweb_app_runs_in_the_background() {
|
||
|
server_exec_cmd := '$serverexe $sport $exit_after_time > /dev/null &'
|
||
|
$if debug_net_socket_client ? {
|
||
|
eprintln('running:\n$server_exec_cmd')
|
||
|
}
|
||
|
res := os.system(server_exec_cmd)
|
||
|
assert res == 0
|
||
|
time.sleep_ms(100)
|
||
|
}
|
||
|
|
||
|
// web client tests follow
|
||
|
fn assert_common_headers(received string) {
|
||
|
assert received.starts_with('HTTP/1.1 200 OK\r\n')
|
||
|
assert received.contains('Server: VWeb\r\n')
|
||
|
assert received.contains('Content-Length:')
|
||
|
assert received.contains('Connection: close\r\n')
|
||
|
}
|
||
|
|
||
|
fn test_a_simple_tcp_client_can_connect_to_the_vweb_server() {
|
||
|
received := simple_tcp_client({}) or {
|
||
|
assert err == ''
|
||
|
return
|
||
|
}
|
||
|
assert_common_headers(received)
|
||
|
assert received.contains('Content-Type: text/plain')
|
||
|
assert received.contains('Content-Length: 15')
|
||
|
assert received.ends_with('Welcome to VWeb')
|
||
|
}
|
||
|
|
||
|
fn test_a_simple_tcp_client_simple_route() {
|
||
|
received := simple_tcp_client({
|
||
|
path: '/simple'
|
||
|
}) or {
|
||
|
assert err == ''
|
||
|
return
|
||
|
}
|
||
|
assert_common_headers(received)
|
||
|
assert received.contains('Content-Type: text/plain')
|
||
|
assert received.contains('Content-Length: 15')
|
||
|
assert received.ends_with('A simple result')
|
||
|
}
|
||
|
|
||
|
fn test_a_simple_tcp_client_html_page() {
|
||
|
received := simple_tcp_client({
|
||
|
path: '/html_page'
|
||
|
}) or {
|
||
|
assert err == ''
|
||
|
return
|
||
|
}
|
||
|
assert_common_headers(received)
|
||
|
assert received.contains('Content-Type: text/html')
|
||
|
assert received.ends_with('<h1>ok</h1>')
|
||
|
}
|
||
|
|
||
|
// net.http client based tests follow:
|
||
|
fn assert_common_http_headers(x http.Response) {
|
||
|
assert x.status_code == 200
|
||
|
assert x.headers['Server'] == 'VWeb'
|
||
|
assert x.headers['Content-Length'].int() > 0
|
||
|
assert x.headers['Connection'] == 'close'
|
||
|
}
|
||
|
|
||
|
fn test_http_client_index() {
|
||
|
x := http.get('http://127.0.0.1:$sport/') or {
|
||
|
panic(err)
|
||
|
}
|
||
|
assert_common_http_headers(x)
|
||
|
assert x.headers['Content-Type'] == 'text/plain'
|
||
|
assert x.text == 'Welcome to VWeb'
|
||
|
}
|
||
|
|
||
|
fn test_http_client_simple() {
|
||
|
x := http.get('http://127.0.0.1:$sport/simple') or {
|
||
|
panic(err)
|
||
|
}
|
||
|
assert_common_http_headers(x)
|
||
|
assert x.headers['Content-Type'] == 'text/plain'
|
||
|
assert x.text == 'A simple result'
|
||
|
}
|
||
|
|
||
|
fn test_http_client_html_page() {
|
||
|
x := http.get('http://127.0.0.1:$sport/html_page') or {
|
||
|
panic(err)
|
||
|
}
|
||
|
assert_common_http_headers(x)
|
||
|
assert x.headers['Content-Type'] == 'text/html'
|
||
|
assert x.text == '<h1>ok</h1>'
|
||
|
}
|
||
|
|
||
|
fn test_http_client_settings_page() {
|
||
|
x := http.get('http://127.0.0.1:$sport/bilbo/settings') or {
|
||
|
panic(err)
|
||
|
}
|
||
|
assert_common_http_headers(x)
|
||
|
assert x.text == 'username: bilbo'
|
||
|
y := http.get('http://127.0.0.1:$sport/kent/settings') or {
|
||
|
panic(err)
|
||
|
}
|
||
|
assert_common_http_headers(y)
|
||
|
assert y.text == 'username: kent'
|
||
|
}
|
||
|
|
||
|
fn test_http_client_user_repo_settings_page() {
|
||
|
x := http.get('http://127.0.0.1:$sport/bilbo/gostamp/settings') or {
|
||
|
panic(err)
|
||
|
}
|
||
|
assert_common_http_headers(x)
|
||
|
assert x.text == 'username: bilbo | repository: gostamp'
|
||
|
y := http.get('http://127.0.0.1:$sport/kent/golang/settings') or {
|
||
|
panic(err)
|
||
|
}
|
||
|
assert_common_http_headers(y)
|
||
|
assert y.text == 'username: kent | repository: golang'
|
||
|
}
|
||
|
|
||
|
// utility code:
|
||
|
struct SimpleTcpClientConfig {
|
||
|
host string = 'static.dev'
|
||
|
path string = '/'
|
||
|
agent string = 'v/net.tcp.v'
|
||
|
headers string = ''
|
||
|
content string = ''
|
||
|
}
|
||
|
|
||
|
fn simple_tcp_client(config SimpleTcpClientConfig) ?string {
|
||
|
client := net.dial('127.0.0.1', sport) or {
|
||
|
return error(err)
|
||
|
}
|
||
|
defer {
|
||
|
client.close() or { }
|
||
|
}
|
||
|
message := 'GET $config.path HTTP/1.1
|
||
|
Host: $config.host
|
||
|
User-Agent: $config.agent
|
||
|
Accept: */*
|
||
|
$config.headers
|
||
|
$config.content'
|
||
|
$if debug_net_socket_client ? {
|
||
|
eprintln('sending:\n$message')
|
||
|
}
|
||
|
client.send(message.str, message.len) or {
|
||
|
return error(err)
|
||
|
}
|
||
|
bytes, blen := client.recv(4096)
|
||
|
received := unsafe {bytes.vstring_with_len(blen)}
|
||
|
$if debug_net_socket_client ? {
|
||
|
eprintln('received:\n$received')
|
||
|
}
|
||
|
return received
|
||
|
}
|