Files

82 lines
3.0 KiB
Go

// Command fixtureplugin is a minimal kandev plugin backend built from
// pkg/pluginsdk, used only by internal/plugins/runtime's tests to exercise
// a real go-plugin subprocess spawn/handshake/DeliverEvent/crash-restart
// cycle end to end. It is built at test time (see
// internal/plugins/runtime/manager_test.go's TestMain) into a temp binary;
// it is never shipped.
package main
import (
"context"
"os"
"github.com/kandev/kandev/pkg/pluginsdk"
)
// fixturePlugin embeds UnimplementedPlugin (for Host injection via
// SetHost/Host) and overrides every RPC with test-observable behavior:
// - OnEvent records the last delivered event into Host state, so an
// out-of-process test can observe delivery by reading that state back
// through its own fake Host implementation.
// - HandleWebhook echoes the request body back as the response body,
// except webhook key "crash" which exits the process immediately (to
// exercise crash detection + restart), and webhook key "write" which
// drives the Host data API write RPCs (CreateTask then SendMessage to the
// returned task) so a test can observe them arrive at the Host over the
// real subprocess transport.
type fixturePlugin struct {
pluginsdk.UnimplementedPlugin
}
func (p *fixturePlugin) OnEvent(ctx context.Context, e *pluginsdk.Event) error {
host := p.Host()
if host == nil {
return nil
}
return host.SetState(ctx, "instance", "", "last_event", map[string]any{
"event_type": e.EventType,
"event_id": e.EventID,
})
}
func (p *fixturePlugin) HandleWebhook(ctx context.Context, req *pluginsdk.WebhookRequest) (*pluginsdk.WebhookResponse, error) {
if req.WebhookKey == "crash" {
os.Exit(1)
}
if req.WebhookKey == "write" {
return p.handleWrite(ctx)
}
return &pluginsdk.WebhookResponse{Status: 200, Body: req.Body}, nil
}
func (*fixturePlugin) HandleAction(_ context.Context, req *pluginsdk.PluginActionRequest) (*pluginsdk.PluginActionResponse, error) {
return &pluginsdk.PluginActionResponse{Body: req.Body}, nil
}
// handleWrite exercises the Host data API write RPCs end to end: CreateTask,
// then SendMessage to the task the Host returns. It responds "ok" on success so
// the test can assert the round-trip completed; a Host error is surfaced as a
// 500 with the error text.
func (p *fixturePlugin) handleWrite(ctx context.Context) (*pluginsdk.WebhookResponse, error) {
host := p.Host()
if host == nil {
return &pluginsdk.WebhookResponse{Status: 500, Body: []byte("no host")}, nil
}
task, err := host.Tasks().Create(ctx, pluginsdk.CreateTaskInput{
WorkspaceID: "ws-probe",
WorkflowID: "wf-probe",
Title: "fixture write probe",
})
if err != nil {
return &pluginsdk.WebhookResponse{Status: 500, Body: []byte(err.Error())}, nil
}
if _, err := host.Messages().Send(ctx, task.ID, "", "fixture probe message"); err != nil {
return &pluginsdk.WebhookResponse{Status: 500, Body: []byte(err.Error())}, nil
}
return &pluginsdk.WebhookResponse{Status: 200, Body: []byte("ok")}, nil
}
func main() {
pluginsdk.Serve(&fixturePlugin{})
}