Documentation
¶
Overview ¶
Package plugintest provides the hostile plugin doubles and the build/dial harness they are exercised through. The doubles are REAL plugin binaries (separate processes over the OSCTF go-plugin handshake) that misbehave in specific, named ways — crash on launch, hang, crash after serving, return malformed responses, ignore shutdown, respond correctly-but-slowly, and stall on shutdown past the drain window. They are the fixtures the loader (P3-c) and failure isolation (P3-d) are built against, so a plugin outage is tested against a plugin that actually outages, not a mock.
This file is the PLUGIN side (used by the double main packages). harness.go is the HOST side (build + dial), used by the tests.
Index ¶
- func Build(t *testing.T, name string) string
- func Dial(t *testing.T, bin string) (*goplugin.Client, pluginpb.ScoringClient)
- func DialCaptureStderr(t *testing.T, bin string, w io.Writer) (*goplugin.Client, pluginpb.ScoringClient)
- func DialWithConfig(t *testing.T, bin string, cfg map[string]string) (*goplugin.Client, pluginpb.ScoringClient)
- func ServeScoring(impl pluginpb.ScoringServer)
- func ServeScoringHandshake(impl pluginpb.ScoringServer, hs goplugin.HandshakeConfig)
- func TryDial(bin string) (*goplugin.Client, pluginpb.ScoringClient, error)
- type OKScoring
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Build ¶
Build compiles a double (its directory name under doubles/) to a temp binary and returns the path. The doubles are real processes, so the loader (P3-c) and failure isolation (P3-d) are exercised against plugins that actually misbehave, not mocks.
func Dial ¶
Dial launches a built double and returns the go-plugin client (for Kill/lifecycle) plus a Scoring client. Fails the test if the handshake/dispense fails. The caller defers c.Kill().
func DialCaptureStderr ¶
func DialCaptureStderr(t *testing.T, bin string, w io.Writer) (*goplugin.Client, pluginpb.ScoringClient)
DialCaptureStderr is Dial with the plugin's STDERR streamed to w. go-plugin redirects the plugin's os.Stderr over a gRPC stdio stream to the client's SyncStderr — that (not the Logger) is the plugin→host log path, and it is what sdk.Log() output travels on.
func DialWithConfig ¶
func DialWithConfig(t *testing.T, bin string, cfg map[string]string) (*goplugin.Client, pluginpb.ScoringClient)
DialWithConfig is Dial, but launches the plugin with a resolved config in the shared OSCTF_PLUGIN_CONFIG env var (plugin.PluginConfigEnv — the SAME const the host writes and the SDK reads), so a double that calls sdk.Config() receives it. This exercises the host→plugin config path end to end, and the shared const means the read side and write side cannot drift.
func ServeScoring ¶
func ServeScoring(impl pluginpb.ScoringServer)
ServeScoring runs a Scoring plugin over the OSCTF handshake. Blocks until the host disconnects (or the process is killed). The doubles call this from main.
func ServeScoringHandshake ¶
func ServeScoringHandshake(impl pluginpb.ScoringServer, hs goplugin.HandshakeConfig)
ServeScoringHandshake is ServeScoring with an explicit handshake — used by the wrong-ABI double, which serves a different ProtocolVersion so the host must refuse it pre-call.
Types ¶
type OKScoring ¶
type OKScoring struct {
pluginpb.UnimplementedScoringServer
Name string // defaults to "double" via Info if empty
}
OKScoring is a well-behaved, deterministic Scoring impl the doubles embed and selectively override. Value returns a linear curve; Info advertises the current ABI.
func (OKScoring) Info ¶
func (s OKScoring) Info(context.Context, *pluginpb.InfoRequest) (*pluginpb.InfoResponse, error)
func (OKScoring) Value ¶
func (OKScoring) Value(_ context.Context, req *pluginpb.ScoreRequest) (*pluginpb.ScoreResponse, error)
Directories
¶
| Path | Synopsis |
|---|---|
|
doubles
|
|
|
configecho
command
Double: reads its config through the PUBLIC sdk.Config() and reflects it in Value — so the host→plugin config path (OSCTF_PLUGIN_CONFIG env → sdk.Config) can be asserted end to end.
|
Double: reads its config through the PUBLIC sdk.Config() and reflects it in Value — so the host→plugin config path (OSCTF_PLUGIN_CONFIG env → sdk.Config) can be asserted end to end. |
|
crashafter
command
Double: CRASHES AFTER SERVING — handshakes and answers Info, then exits non-zero on the first Value call.
|
Double: CRASHES AFTER SERVING — handshakes and answers Info, then exits non-zero on the first Value call. |
|
crashlaunch
command
Double: CRASH ON LAUNCH — exits non-zero before serving, every time.
|
Double: CRASH ON LAUNCH — exits non-zero before serving, every time. |
|
goodscore
command
Double: well-behaved baseline.
|
Double: well-behaved baseline. |
|
hang
command
Double: HANG — Value never returns (and ignores the context).
|
Double: HANG — Value never returns (and ignores the context). |
|
ignoreshutdown
command
Double: IGNORES SHUTDOWN — serves correctly but traps and ignores SIGINT/SIGTERM, so a graceful stop does not make it exit.
|
Double: IGNORES SHUTDOWN — serves correctly but traps and ignores SIGINT/SIGTERM, so a graceful stop does not make it exit. |
|
logecho
command
Double: logs via the PUBLIC sdk.Log() on each call, so the plugin→host log path (over go-plugin's stderr channel into the host Logger) can be asserted end to end.
|
Double: logs via the PUBLIC sdk.Log() on each call, so the plugin→host log path (over go-plugin's stderr channel into the host Logger) can be asserted end to end. |
|
malformed
command
Double: MALFORMED — serves Info fine but returns a gRPC error status on Value (and an out-of-contract Info name mismatch is available via NAME).
|
Double: MALFORMED — serves Info fine but returns a gRPC error status on Value (and an out-of-contract Info name mismatch is available via NAME). |
|
nohandshake
command
Double: NEVER HANDSHAKES — a valid executable that starts and then blocks forever without calling plugin.Serve, so the go-plugin handshake never completes and the loader's launch is stuck until its StartTimeout.
|
Double: NEVER HANDSHAKES — a valid executable that starts and then blocks forever without calling plugin.Serve, so the go-plugin handshake never completes and the loader's launch is stuck until its StartTimeout. |
|
slow
command
Double: SLOW — responds correctly, every time, in 4 seconds, and deliberately IGNORES the request context.
|
Double: SLOW — responds correctly, every time, in 4 seconds, and deliberately IGNORES the request context. |
|
slowcoop
command
Double: SLOW BUT COOPERATIVE — a long call like `slow`, except it HONORS ctx cancellation: on cancel it returns promptly with codes.Canceled instead of running to completion.
|
Double: SLOW BUT COOPERATIVE — a long call like `slow`, except it HONORS ctx cancellation: on cancel it returns promptly with codes.Canceled instead of running to completion. |
|
slowshutdown
command
Double: SLOW ONLY ON SHUTDOWN — responds normally, but on a stop signal takes far longer than the 30s drain window to exit.
|
Double: SLOW ONLY ON SHUTDOWN — responds normally, but on a stop signal takes far longer than the 30s drain window to exit. |
|
wrongabi
command
Double: WRONG ABI MAJOR — serves correctly but with a go-plugin ProtocolVersion the host does not speak.
|
Double: WRONG ABI MAJOR — serves correctly but with a go-plugin ProtocolVersion the host does not speak. |