package spawntest
import "bazil.org/fuse/fs/fstestutil/spawntest"
Package spawntest helps write tests that use subprocesses.
The subprocess runs a HTTP server on a UNIX domain socket, and the test can make HTTP requests to control the behavior of the helper subprocess.
Helpers are identified by names they pass to Registry.Register. This call should be placed in an init function. The test spawns the subprocess by executing the same test binary in a subprocess, passing it a special flag that is recognized by TestMain.
This might get extracted to a standalone repository, if it proves
useful enough.
Code:play
Example¶
package main
import (
"context"
"errors"
"flag"
"os"
"testing"
"bazil.org/fuse/fs/fstestutil/spawntest"
"bazil.org/fuse/fs/fstestutil/spawntest/httpjson"
)
var helpers spawntest.Registry
type addRequest struct {
A uint64
B uint64
}
type addResult struct {
X uint64
}
func add(ctx context.Context, req addRequest) (*addResult, error) {
// In real tests, you'd instruct the helper to interact with the
// system-under-test on behalf of the unit test process. For
// brevity, we'll just do the action directly in this example.
x := req.A + req.B
if x < req.A {
return nil, errors.New("overflow")
}
r := &addResult{
X: x,
}
return r, nil
}
// The second argument to Register can be any http.Handler. To keep
// state in the helper between calls, you can create a custom type and
// delegate to methods based on http.Request.URL.Path.
var addHelper = helpers.Register("add", httpjson.ServePOST(add))
func name_me_TestAdd(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
control := addHelper.Spawn(ctx, t)
defer control.Close()
var got addResult
if err := control.JSON("/").Call(ctx, addRequest{A: 42, B: 13}, &got); err != nil {
t.Fatalf("calling helper: %v", err)
}
if g, e := got.X, uint64(55); g != e {
t.Errorf("wrong add result: %v != %v", g, e)
}
}
func name_me_TestMain(m *testing.M) {
helpers.AddFlag(flag.CommandLine)
flag.Parse()
helpers.RunIfNeeded()
os.Exit(m.Run())
}
func main() {}
// Quiet linters. See https://github.com/dominikh/go-tools/issues/675
var _ = name_me_TestAdd
var _ = name_me_TestMain
Index ¶
- type Control
- func (c *Control) Close()
- func (c *Control) HTTP() *http.Client
- func (c *Control) JSON(path string) *httpjson.Resource
- func (c *Control) Signal(sig os.Signal) error
- type Helper
- type Registry
Examples ¶
Types ¶
type Control ¶
type Control struct {
// contains filtered or unexported fields
}
Control an instance of a helper running as a subprocess.
func (*Control) Close ¶
func (c *Control) Close()
Close kills the helper and frees resources.
func (*Control) HTTP ¶
HTTP returns a HTTP client that can be used to communicate with the helper. URLs passed to this helper should not include scheme or host.
func (*Control) JSON ¶
JSON returns a helper to make HTTP requests that pass data as JSON to the resource identified by path. Path should not include scheme or host. Path can be empty to communicate with the root resource.
func (*Control) Signal ¶
Signal send a signal to the helper process.
type Helper ¶
type Helper struct {
// contains filtered or unexported fields
}
Helper is the result of registering a helper. It can be used by tests to spawn the helper.
func (*Helper) Spawn ¶
Spawn the helper. All errors will be reported via t.Logf and fatal errors result in t.FailNow. The helper is killed after context cancels.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry keeps track of helpers.
The zero value is ready to use.
func (*Registry) AddFlag ¶
AddFlag adds the command-line flag used to communicate between Control and the helper to the flag set. Typically flag.CommandLine is used, and this should be called from TestMain before flag.Parse.
func (*Registry) Register ¶
Register a helper in the registry.
This should be called from a top-level variable assignment.
Register will panic if the name is already registered.
func (*Registry) RunIfNeeded ¶
func (r *Registry) RunIfNeeded()
RunIfNeeded passes execution to the helper if the right command-line flag was seen. This should be called from TestMain after flag.Parse. If running as the helper, the call will not return.
Source Files ¶
spawntest.go
Directories ¶
Path | Synopsis |
---|---|
fs/fstestutil/spawntest/httpjson | Package httpjson helps transporting JSON over HTTP. |
- Version
- v0.0.0-20230120002735-62a210ff1fd5 (latest)
- Published
- Jan 20, 2023
- Platform
- linux/amd64
- Imports
- 14 packages
- Last checked
- 4 days ago –
Tools for package owners.