headless

package
v0.30.2 Latest Latest
Warning

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

Go to latest
Published: Apr 21, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package headless runs Resterm requests and workflows without the TUI.

The package exposes a library API for CI/CD, automation, and other non-interactive integrations. Choose the entrypoint based on how you run:

  • Call Run for a one-shot execution.
  • Call Build and then RunPlan when you want to prepare once and reuse the same validated plan across retries, repeated runs, or concurrent calls.

The primary workflow is:

  1. Construct Options.
  2. Call Build to prepare and validate a reusable Plan.
  3. Call RunPlan to execute the prepared plan, or call Run for a one-shot run.
  4. Inspect the returned Report, Result, and Step values.
  5. Serialize the report with Report.Encode using JSON, JUnit, or Text.

WriteJSON, WriteJUnit, and WriteText remain available as helpers over Encode. Programmatic format selection is available through the Format constants JSON, JUnit, and Text, and ParseFormat converts user-provided names into a Format value.

Invalid library inputs are reported as UsageError values. Use IsUsageError to classify them, and errors.Is to match specific sentinels such as ErrNoSourcePath or ErrTooFewTargets.

Index

Examples

Constants

View Source
const DefaultHTTPTimeout = 30 * time.Second

DefaultHTTPTimeout is the timeout applied when Options.HTTP.Timeout is zero.

Variables

View Source
var (
	// ErrNoSourcePath reports that Options.Source.Path was empty.
	ErrNoSourcePath = errors.New("headless: source path is required")

	// ErrNilContext reports that a nil context was passed to Run or RunPlan.
	ErrNilContext = errors.New("headless: nil context")

	// ErrTooFewTargets reports that compare mode was enabled without enough targets.
	ErrTooFewTargets = errors.New("headless: compare requires at least two target environments")

	// ErrInvalidPlan reports that a zero-value or otherwise invalid Plan was used.
	ErrInvalidPlan = errors.New("headless: invalid plan")

	// ErrNilReport reports an attempt to encode a nil report.
	ErrNilReport = errors.New("headless: nil report")

	// ErrNilWriter reports an attempt to write to a nil writer.
	ErrNilWriter = errors.New("headless: nil writer")
)

Functions

func IsUsageError

func IsUsageError(err error) bool

IsUsageError reports whether err contains a UsageError.

Types

type Compare

type Compare struct {
	Baseline string `json:"baseline,omitempty"`
}

Compare contains compare-run summary fields.

type CompareOptions added in v0.27.3

type CompareOptions struct {
	Targets []string `json:"targets,omitempty"`
	Base    string   `json:"base,omitempty"`
}

CompareOptions configures compare runs across multiple environments.

type EnvironmentOptions added in v0.27.3

type EnvironmentOptions struct {
	Set      EnvironmentSet `json:"set,omitempty"`
	Name     string         `json:"name,omitempty"`
	FilePath string         `json:"filePath,omitempty"`
}

EnvironmentOptions controls environment loading and selection.

type EnvironmentSet added in v0.27.3

type EnvironmentSet map[string]map[string]string

EnvironmentSet maps environment names to variable values.

type Format added in v0.28.2

type Format int
const (
	JSON Format = iota
	JUnit
	Text
)

func ParseFormat added in v0.28.2

func ParseFormat(s string) (Format, error)

func (Format) String added in v0.28.2

func (f Format) String() string

type GRPC

type GRPC struct {
	Code          string `json:"code,omitempty"`
	StatusCode    int    `json:"statusCode,omitempty"`
	StatusMessage string `json:"statusMessage,omitempty"`
}

GRPC contains gRPC response summary fields.

type GRPCOptions added in v0.27.3

type GRPCOptions struct {
	Plaintext *bool `json:"plaintext,omitempty"`
}

GRPCOptions configures default gRPC behavior.

type HTTP

type HTTP struct {
	Status     string `json:"status,omitempty"`
	StatusCode int    `json:"statusCode,omitempty"`
	Protocol   string `json:"protocol,omitempty"`
}

HTTP contains HTTP response summary fields.

type HTTPOptions added in v0.27.3

type HTTPOptions struct {
	Timeout            time.Duration `json:"timeout,omitempty"`
	FollowRedirects    *bool         `json:"followRedirects,omitempty"`
	InsecureSkipVerify bool          `json:"insecureSkipVerify,omitempty"`
	ProxyURL           string        `json:"proxyURL,omitempty"`
}

HTTPOptions configures default HTTP client behavior.

type HistBin

type HistBin struct {
	From  time.Duration `json:"from,omitempty"`
	To    time.Duration `json:"to,omitempty"`
	Count int           `json:"count,omitempty"`
}

HistBin contains one profile histogram bin.

type Kind

type Kind string

Kind identifies the executed result type.

const (
	KindRequest  Kind = "request"
	KindWorkflow Kind = "workflow"
	KindForEach  Kind = "for-each"
	KindCompare  Kind = "compare"
	KindProfile  Kind = "profile"
)

func (Kind) IsValid added in v0.28.2

func (k Kind) IsValid() bool

IsValid reports whether k is a known result kind.

func (Kind) String added in v0.28.2

func (k Kind) String() string

String implements fmt.Stringer.

type Latency

type Latency struct {
	Count  int           `json:"count,omitempty"`
	Min    time.Duration `json:"min,omitempty"`
	Max    time.Duration `json:"max,omitempty"`
	Mean   time.Duration `json:"mean,omitempty"`
	Median time.Duration `json:"median,omitempty"`
	StdDev time.Duration `json:"stdDev,omitempty"`
}

Latency contains aggregate profile latency statistics.

type Options added in v0.27.3

type Options struct {
	Version       string             `json:"version,omitempty"`
	Source        Source             `json:"source,omitempty"`
	WorkspaceRoot string             `json:"workspaceRoot,omitempty"`
	Recursive     bool               `json:"recursive,omitempty"`
	State         StateOptions       `json:"state,omitempty"`
	Environment   EnvironmentOptions `json:"environment,omitempty"`
	Compare       CompareOptions     `json:"compare,omitempty"`
	Profile       ProfileOptions     `json:"profile,omitempty"`
	HTTP          HTTPOptions        `json:"http,omitempty"`
	GRPC          GRPCOptions        `json:"grpc,omitempty"`
	Selection     Selection          `json:"selection,omitempty"`
}

Options configures a headless run.

type Percentile

type Percentile struct {
	Percentile int           `json:"percentile"`
	Value      time.Duration `json:"value,omitempty"`
}

Percentile contains one profile percentile.

type Plan added in v0.29.1

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

Plan stores a prepared run configuration. A Plan can be reused across multiple RunPlan calls, including concurrently. The zero value is invalid.

func Build added in v0.29.1

func Build(o Options) (Plan, error)

Build prepares o for execution and returns a reusable plan. Use Build with RunPlan when you want to validate once and reuse the same source and selection across multiple runs.

type Profile

type Profile struct {
	Count          int              `json:"count,omitempty"`
	Warmup         int              `json:"warmup,omitempty"`
	Delay          time.Duration    `json:"delay,omitempty"`
	TotalRuns      int              `json:"totalRuns,omitempty"`
	WarmupRuns     int              `json:"warmupRuns,omitempty"`
	SuccessfulRuns int              `json:"successfulRuns,omitempty"`
	FailedRuns     int              `json:"failedRuns,omitempty"`
	Latency        *Latency         `json:"latency,omitempty"`
	Percentiles    []Percentile     `json:"percentiles,omitempty"`
	Histogram      []HistBin        `json:"histogram,omitempty"`
	Failures       []ProfileFailure `json:"failures,omitempty"`
}

Profile contains profile-run summary fields.

type ProfileFailure added in v0.27.3

type ProfileFailure struct {
	Iteration  int           `json:"iteration,omitempty"`
	Warmup     bool          `json:"warmup,omitempty"`
	Reason     string        `json:"reason,omitempty"`
	Status     string        `json:"status,omitempty"`
	StatusCode int           `json:"statusCode,omitempty"`
	Duration   time.Duration `json:"duration,omitempty"`
}

ProfileFailure contains one failed profile iteration.

type ProfileOptions added in v0.28.2

type ProfileOptions struct {
	Enabled bool `json:"enabled,omitempty"`
}

ProfileOptions configures profile runs.

type Report

type Report struct {
	Version   string
	FilePath  string
	EnvName   string
	StartedAt time.Time
	EndedAt   time.Time
	Duration  time.Duration
	Results   []Result
	Total     int
	Passed    int
	Failed    int
	Skipped   int
}

Report contains the results of a headless run.

func Run

func Run(ctx context.Context, opt Options) (*Report, error)

Run executes a request or workflow file and returns a stable public report. Use Run for one-shot execution when you do not need to reuse a prepared plan.

Example
package main

import (
	"bytes"
	"context"
	"fmt"
	"net/http"
	"net/http/httptest"
	"os"
	"path/filepath"

	"github.com/unkn0wn-root/resterm/headless"
)

func main() {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		_, _ = fmt.Fprint(w, `{"ok":true}`)
	}))
	defer srv.Close()

	dir, err := os.MkdirTemp("", "headless-example-*")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer func() { _ = os.RemoveAll(dir) }()

	path := filepath.Join(dir, "api.http")
	src := fmt.Sprintf("# @name ok\nGET %s\n", srv.URL)
	err = os.WriteFile(path, []byte(src), 0o600)
	if err != nil {
		fmt.Println(err)
		return
	}

	// Run is the simplest entrypoint when you only need a single execution.
	rep, err := headless.Run(context.Background(), headless.Options{
		Source: headless.Source{Path: path},
	})
	if err != nil {
		fmt.Println(err)
		return
	}

	var out bytes.Buffer
	if err := rep.Encode(&out, headless.Text); err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(rep.Passed, rep.Failed)
}
Output:
1 0

func RunPlan added in v0.29.1

func RunPlan(ctx context.Context, pl Plan) (*Report, error)

RunPlan executes a prepared plan and returns a stable public report. Use RunPlan with Build when you want to prepare once and execute the same validated plan multiple times.

Example
package main

import (
	"context"
	"fmt"
	"net/http"
	"net/http/httptest"
	"os"
	"path/filepath"

	"github.com/unkn0wn-root/resterm/headless"
)

func main() {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		_, _ = fmt.Fprint(w, `{"ok":true}`)
	}))
	defer srv.Close()

	dir, err := os.MkdirTemp("", "headless-example-*")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer func() { _ = os.RemoveAll(dir) }()

	path := filepath.Join(dir, "api.http")
	src := fmt.Sprintf("# @name ok\nGET %s\n", srv.URL)
	err = os.WriteFile(path, []byte(src), 0o600)
	if err != nil {
		fmt.Println(err)
		return
	}

	// Build once when you want to reuse the same validated input across
	// repeated runs, retries, or concurrent callers.
	pl, err := headless.Build(headless.Options{
		Source: headless.Source{Path: path},
	})
	if err != nil {
		fmt.Println(err)
		return
	}

	rep1, err := headless.RunPlan(context.Background(), pl)
	if err != nil {
		fmt.Println(err)
		return
	}
	rep2, err := headless.RunPlan(context.Background(), pl)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(rep1.Passed, rep2.Passed)
}
Output:
1 1

func (*Report) Encode added in v0.28.2

func (r *Report) Encode(w io.Writer, f Format) error

Encode writes the report in the given format.

func (*Report) HasFailures

func (r *Report) HasFailures() bool

HasFailures reports whether the report contains any failed results.

func (Report) MarshalJSON added in v0.27.3

func (r Report) MarshalJSON() ([]byte, error)

MarshalJSON writes the canonical report JSON format.

func (*Report) WriteJSON

func (r *Report) WriteJSON(w io.Writer) error

WriteJSON writes r as indented JSON.

func (*Report) WriteJUnit

func (r *Report) WriteJUnit(w io.Writer) error

WriteJUnit writes r as JUnit XML.

func (*Report) WriteText

func (r *Report) WriteText(w io.Writer) error

WriteText writes r as a text report.

type Result

type Result struct {
	Kind        Kind
	Name        string
	Method      string
	Target      string
	Environment string
	Status      Status
	Summary     string
	Duration    time.Duration
	Canceled    bool
	SkipReason  string
	Error       string
	ScriptError string
	HTTP        *HTTP
	GRPC        *GRPC
	Stream      *Stream
	Trace       *Trace
	Tests       []Test
	Compare     *Compare
	Profile     *Profile
	Steps       []Step
}

Result contains one executed request, workflow, compare run, or profile run.

func (Result) Failed

func (r Result) Failed() bool

Failed reports whether the result represents a failure.

func (Result) MarshalJSON added in v0.27.3

func (r Result) MarshalJSON() ([]byte, error)

MarshalJSON writes the canonical result JSON format.

type Selection added in v0.27.3

type Selection struct {
	Request  string `json:"request,omitempty"`
	Workflow string `json:"workflow,omitempty"`
	Tag      string `json:"tag,omitempty"`
	All      bool   `json:"all,omitempty"`
}

Selection narrows which request or workflow to run.

type Source added in v0.29.1

type Source struct {
	Path    string `json:"path,omitempty"`
	Content []byte `json:"-"`
}

Source identifies the request document to execute. Path is required and provides the logical file identity and relative-resolution anchor. Path may be synthetic when Content is provided. Content overrides the bytes loaded from Path when provided.

type StateOptions added in v0.27.3

type StateOptions struct {
	ArtifactDir    string `json:"artifactDir,omitempty"`
	StateDir       string `json:"stateDir,omitempty"`
	PersistGlobals bool   `json:"persistGlobals,omitempty"`
	PersistAuth    bool   `json:"persistAuth,omitempty"`
	History        bool   `json:"history,omitempty"`
}

StateOptions controls artifacts and persisted runtime state.

type Status

type Status string

Status reports whether a result passed, failed, or was skipped.

const (
	StatusPass Status = "pass"
	StatusFail Status = "fail"
	StatusSkip Status = "skip"
)

func (Status) IsValid added in v0.28.2

func (s Status) IsValid() bool

IsValid reports whether s is a known result status.

func (Status) String added in v0.28.2

func (s Status) String() string

String implements fmt.Stringer.

type Step

type Step struct {
	Name        string
	Method      string
	Target      string
	Environment string
	Branch      string
	Iteration   int
	Total       int
	Status      Status
	Summary     string
	Duration    time.Duration
	Canceled    bool
	SkipReason  string
	Error       string
	ScriptError string
	HTTP        *HTTP
	GRPC        *GRPC
	Stream      *Stream
	Trace       *Trace
	Tests       []Test
}

Step contains one workflow or compare step result.

func (Step) Failed

func (s Step) Failed() bool

Failed reports whether the step represents a failure.

func (Step) MarshalJSON added in v0.27.3

func (s Step) MarshalJSON() ([]byte, error)

MarshalJSON writes the canonical step JSON format.

type Stream

type Stream struct {
	Kind           string         `json:"kind,omitempty"`
	EventCount     int            `json:"eventCount,omitempty"`
	Summary        map[string]any `json:"summary,omitempty"`
	TranscriptPath string         `json:"transcriptPath,omitempty"`
}

Stream contains streaming response metadata.

type Test

type Test struct {
	Name    string        `json:"name,omitempty"`
	Message string        `json:"message,omitempty"`
	Passed  bool          `json:"passed"`
	Elapsed time.Duration `json:"elapsed,omitempty"`
}

Test contains one assertion result.

type Trace

type Trace struct {
	Duration     time.Duration `json:"duration,omitempty"`
	Error        string        `json:"error,omitempty"`
	Budget       *TraceBudget  `json:"budget,omitempty"`
	Breaches     []TraceBreach `json:"breaches,omitempty"`
	ArtifactPath string        `json:"artifactPath,omitempty"`
}

Trace contains trace summary metadata.

type TraceBreach

type TraceBreach struct {
	Kind   string        `json:"kind,omitempty"`
	Limit  time.Duration `json:"limit,omitempty"`
	Actual time.Duration `json:"actual,omitempty"`
	Over   time.Duration `json:"over,omitempty"`
}

TraceBreach contains one trace budget breach.

type TraceBudget

type TraceBudget struct {
	Total     time.Duration            `json:"total,omitempty"`
	Tolerance time.Duration            `json:"tolerance,omitempty"`
	Phases    map[string]time.Duration `json:"phases,omitempty"`
}

TraceBudget contains trace budget limits.

type UsageError added in v0.27.3

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

UsageError reports invalid input or options passed to the headless API.

func (UsageError) Error added in v0.27.3

func (e UsageError) Error() string

func (UsageError) Unwrap added in v0.27.3

func (e UsageError) Unwrap() error

Jump to

Keyboard shortcuts

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