Initial project import

This commit is contained in:
Agila Forge Importer committed 2026-07-13 15:20:32 +00:00
commit 23f2d29e32
11957 files changed
+1754577

No files matched your search

+28
View File
@@ -0,0 +1,28 @@
# x.async integration tests
This folder contains module-oriented integration tests for `x.async`.
Tests are validation-first programs. Unlike the examples, they are written to
assert edge cases, error propagation, cancellation behavior, backpressure, and
module integration boundaries. They should fail when a regression is introduced.
The tests are deliberately local and synthetic. They verify that `x.async`
composes cleanly with selected V modules without modifying those modules and
without depending on public network services, fixed ports, filesystem paths, or
fragile server shutdown behavior.
Current subfolders:
- `net_http/`: in-memory `net.http` request/response work through `Pool`.
- `net_websocket/`: in-memory `websocket.Message` processing and callback-style
error propagation through `Task` and `Group`.
- `mcp/`: in-memory MCP JSON-RPC request/response dispatch through `Task`.
- `veb/`: in-memory `veb.Context` response lifecycle through `with_timeout()`.
Run through the guarded validation path:
```sh
sh vlib/x/async/tools/validate.sh
```
The validation script uses isolated `VTMP` and `VCACHE` and runs serially.
+11
View File
@@ -0,0 +1,11 @@
# mcp integration tests
These tests keep MCP traffic in memory. They do not start stdio, HTTP, a child
process, or any external MCP service.
The coverage target is the `x.async` boundary around MCP-shaped work:
- build an MCP request;
- decode and validate it inside a `Task`;
- produce an MCP response;
- decode the result after `Task.wait()`.
@@ -0,0 +1,28 @@
import context
import mcp
import x.async as xasync
struct TestEchoArgs {
pub:
text string
}
fn test_mcp_task_dispatches_in_memory_request() {
request := mcp.new_request(1, 'tools/call', TestEchoArgs{
text: 'hello'
})
mut task := xasync.run[mcp.Response](fn [request] (mut ctx context.Context) !mcp.Response {
_ = ctx
req := mcp.decode_request(request.encode())!
if req.method != 'tools/call' {
return error('unexpected MCP method')
}
args := req.decode_params[TestEchoArgs]()!
result := mcp.tool_text_result(args.text)
return mcp.new_response(1, result, mcp.ResponseError{})
})!
response := task.wait()!
result := response.decode_result[mcp.ToolResult]()!
assert result.content.contains('hello')
}
@@ -0,0 +1,11 @@
# net.http integration tests
These tests use `net.http` request and response values in memory. They do not
open a listener, bind a port, or call an external service.
The coverage target is the `x.async` boundary around HTTP-shaped work:
- bounded pool submission;
- explicit queue-full backpressure;
- draining accepted request handlers through `Pool.close()`;
- preserving response data produced by accepted jobs.
@@ -0,0 +1,73 @@
import context
import net.http
import time
import x.async as xasync
fn test_net_http_pool_handles_synthetic_requests_with_backpressure() {
mut pool := xasync.new_pool(workers: 1, queue_size: 1)!
started := chan bool{cap: 1}
release := chan bool{cap: 2}
responses := chan int{cap: 2}
first_req := http.new_request(.get, '/first', '')
second_req := http.new_request(.get, '/second', '')
third_req := http.new_request(.get, '/third', '')
pool.try_submit(fn [first_req, started, release, responses] (mut ctx context.Context) ! {
_ = ctx
started <- true
_ := <-release
resp := synthetic_http_response(first_req)!
responses <- resp.status_code
})!
wait_for_http_signal(started, 'first synthetic HTTP job did not start')
pool.try_submit(fn [second_req, release, responses] (mut ctx context.Context) ! {
_ = ctx
_ := <-release
resp := synthetic_http_response(second_req)!
responses <- resp.status_code
})!
pool.try_submit(fn [third_req] (mut ctx context.Context) ! {
_ = ctx
_ = third_req
}) or {
assert err.msg() == 'async: pool queue is full'
release <- true
release <- true
pool.close()!
assert read_http_status(responses) == 200
assert read_http_status(responses) == 200
return
}
assert false
}
fn synthetic_http_response(req http.Request) !http.Response {
if req.url == '' {
return error('empty synthetic HTTP URL')
}
return http.new_response(status: .ok, body: req.url)
}
fn wait_for_http_signal(signal chan bool, message string) {
select {
ok := <-signal {
assert ok
}
1 * time.second {
assert false, message
}
}
}
fn read_http_status(responses chan int) int {
select {
status := <-responses {
return status
}
1 * time.second {
assert false, 'synthetic HTTP response was not produced'
}
}
return 0
}
@@ -0,0 +1,11 @@
# net.websocket integration tests
These tests are intentionally in-memory and synthetic. They exercise
`websocket.Message` processing and callback-shaped control flow with `x.async`,
but they do not start a websocket server or claim end-to-end websocket server
coverage.
That limitation is important: in this V snapshot, `websocket.Server.close()` is
not a complete, stable shutdown primitive for a fragile validation test. The
tests therefore avoid binding ports and focus on the part `x.async` can safely
compose: message work, cancellation, and error propagation around callbacks.
@@ -0,0 +1,44 @@
import context
import net.websocket
import x.async as xasync
fn test_net_websocket_task_processes_message_in_memory() {
msg := websocket.Message{
opcode: .text_frame
payload: 'hello'.bytes()
}
mut task := xasync.run[string](fn [msg] (mut ctx context.Context) !string {
_ = ctx
return websocket_message_text(msg)!
})!
assert task.wait()! == 'hello'
}
fn test_net_websocket_callback_error_propagates_through_group() {
mut group := xasync.new_group(context.background())
observed := chan string{cap: 1}
group.go(fn [observed] (mut ctx context.Context) ! {
_ = ctx
msg := websocket.Message{
opcode: .close
}
text := websocket_message_text(msg) or {
observed <- err.msg()
return err
}
observed <- text
})!
group.wait() or {
assert err.msg() == 'unsupported websocket opcode'
assert <-observed == 'unsupported websocket opcode'
return
}
assert false
}
fn websocket_message_text(msg websocket.Message) !string {
if msg.opcode != .text_frame {
return error('unsupported websocket opcode')
}
return msg.payload.bytestr()
}
+8
View File
@@ -0,0 +1,8 @@
# veb integration tests
These tests use `veb.Context` in memory. They do not start a `veb` server, bind
a port, or depend on HTTP client/server timing.
The coverage target is narrow: `x.async` can bound and propagate errors for a
synthetic veb handler step without becoming part of `veb`'s runtime or server
lifecycle.
@@ -0,0 +1,18 @@
import context
import time
import veb
import x.async as xasync
fn test_veb_context_response_inside_timeout() {
xasync.with_timeout(1 * time.second, fn (mut ctx context.Context) ! {
_ = ctx
mut web_ctx := veb.Context{}
_ := web_ctx.text('hello from veb')
if web_ctx.res.status_code != 200 {
return error('unexpected veb status')
}
if web_ctx.res.body != 'hello from veb' {
return error('unexpected veb body')
}
})!
}