Help us shape the future of Go! Take the 2026 Go Developer Survey

testserver

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2026 License: MIT Imports: 14 Imported by: 0

README

testserver

A real Elixir + Tidewave server, booted on a unix socket, so tw's subcommands are tested against actual MCP responses instead of a mock.

server.go is the Go harness. app/ is the fixture application.

Usage

TestMain in main_test.go starts one fixture for the whole package:

srv, err := testserver.Start()
defer srv.Stop()
srv.Socket() // pass to tw via --socket

Start fetches deps and compiles on the first run (~10s), then reuses app/_build (~0.5s). It waits until the server answers a JSON-RPC ping before returning, so there is no sleep-and-hope. If mix is not on PATH, Available reports false and the integration tests skip; any other failure is returned as an error, because a silent skip is how the previous version of this fixture hid the fact that it never worked.

Fixture data

app seeds two tables before the listener starts, so data is guaranteed present once the socket is connectable:

  • users — Alice, Bob
  • posts — "Hello World", "Elixir Rocks"

TestApp.User and TestApp.Post are Ecto schemas, which is what tw schemas reports.

Constraints worth knowing

These are all load-bearing; changing them breaks tests in non-obvious ways.

  • config :test_app, ecto_repos: [TestApp.Repo] — Tidewave only registers the execute_sql_query and get_ecto_schemas tools when the host app declares :ecto_repos. Without it, tw sql and tw schemas fail with "Method not found".
  • allow_remote_access: true on the Tidewave plug — Tidewave's guard only accepts loopback IPv4/IPv6 peers, and a unix-domain peer has no address to match. Access is gated instead by filesystem permissions on the socket, which the harness puts in a private temp directory.
  • allowed_origins: ["//localhost"] — Tidewave otherwise derives allowed origins from a Phoenix endpoint, and this fixture deliberately has none. Tidewave needs only plug, so Phoenix is not a dependency.
  • The listener starts last in TestApp.Application, after the repo and seed.
  • One SQL statement per query in TestApp.Seed — the SQLite driver rejects multiple statements in a single call.
  • The socket lives under /tmp — unix socket paths are capped near 104 bytes on macOS, which the default temp directory can exceed.
  • mix is a shell wrapper that execs the VM as a child, so Stop signals the whole process group. Signalling the wrapper alone leaves the VM running.
  • Tidewave needs Mix at runtime (Mix.Project.build_path/0 and friends), hence mix run --no-halt rather than a release.

Documentation

Overview

Package testserver boots the Elixir/Tidewave fixture in testserver/app and exposes it over a unix socket, so tw's subcommands can be exercised against a real MCP server instead of a mock.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Available

func Available() bool

Available reports whether the Elixir toolchain needed by the fixture is installed. Callers should skip integration tests when it is not, rather than treating a missing toolchain as a failure.

Types

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is a running instance of the fixture app.

func Start

func Start() (*Server, error)

Start compiles the fixture if needed, boots it, and waits until it answers an MCP request. The returned Server must be stopped by the caller.

func (*Server) Output

func (s *Server) Output() string

Output returns everything the fixture has written to stdout and stderr, for use in failure messages.

func (*Server) Socket

func (s *Server) Socket() string

Socket returns the unix socket path the fixture is listening on.

func (*Server) Stop

func (s *Server) Stop()

Stop terminates the fixture and removes its temporary directory.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL