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

conform

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Nov 1, 2026 License: GPL-3.0 Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const (
	KindMissing      = "missing"
	KindExtra        = "extra"
	KindType         = "type"
	KindValue        = "value"
	KindStatus       = "status"
	KindHeader       = "header"
	KindParse        = "parse"
	KindRequestError = "request_error"
)

Difference kinds. Missing, extra, type, status, header, parse and request_error differences are blocking. Value differences stay informational here so Jellyfin/Emby/Silo are not gated on the Plex load-bearing list. plex.Compare promotes those values (and hub #order).

Variables

View Source
var KeyShapeFields = []string{"key", "ratingKey"}

KeyShapeFields compare by identifier shape (path template or {id}), not the numeric IDs inside them. A shape mismatch is load-bearing.

View Source
var LoadBearingFields = []string{
	"viewMode",
	"viewGroup",
	"leafCount",
	"viewedLeafCount",
	"childCount",
	"size",
	"totalSize",
	"type",
	"nocache",
	"allowSync",
	"librarySectionID",
	"hubIdentifier",
	"context",
	"style",
	"more",
	"generalDecisionCode",
	"directPlayDecisionCode",
	"transcodeDecisionCode",
	"mdeDecisionCode",
	"generalDecisionText",
	"directPlayDecisionText",
	"transcodeDecisionText",
	"mdeDecisionText",
}

LoadBearingFields are Plex protocol-shape values clients branch on. Shared Compare reports mismatches; plex.Compare makes them blocking so Jellyfin/Emby/Silo gates are not affected. Catalog contents still differ between servers; those names stay listed here because a wrong type, count, or hub identity is a wire bug even when titles differ.

View Source
var VolatileFields = []string{}/* 147 elements not displayed */

VolatileFields are per-server values compared by type (and URL shape) only. A leading or trailing * is a wildcard. Load-bearing names win even when a pattern here would also match.

Functions

func FixtureName

func FixtureName(profile, path string, jsonMode bool) string

FixtureName is the file name (without ".json") of the fixture for a request made with a client profile in XML or JSON.

func IdentifierShape

func IdentifierShape(s string) string

IdentifierShape reduces a key or ratingKey to the shape clients match on.

func LoadBearing

func LoadBearing(path string) bool

LoadBearing reports whether a schema path's leaf is a load-bearing field or a key/ratingKey shape. Image/Rating/Setting @type and Part @key are catalog decoration, not protocol branches.

func Redact

func Redact(body []byte) []byte

Redact removes common account and host identifiers from captured XML/JSON/text.

func SaveFixture

func SaveFixture(dir, name string, r Response) error

SaveFixture stores one redacted response as a JSON fixture.

func SaveFixtureTrimmed

func SaveFixtureTrimmed(dir, name string, r Response) (int, error)

SaveFixtureTrimmed redacts and limits each repeated container child list to 50 items. It returns the number of response bodies whose listings were shortened.

func TrimBody

func TrimBody(body []byte) ([]byte, bool)

TrimBody truncates XML repeated sibling elements and JSON arrays to their first 50 entries.

func ValidateBinary

func ValidateBinary(r Response) error

ValidateBinary checks a live response against strict byte-range semantics.

func WriteSummary

func WriteSummary(w io.Writer, r Report, values bool)

WriteSummary prints, per endpoint, the missing and extra attributes or elements and the type mismatches (and, with values, the informational value differences), followed by a count table.

func WriteTable

func WriteTable(w io.Writer, sums []EndpointSummary)

WriteTable prints a Markdown table of per-endpoint difference counts (distinct schema paths across clients).

func WriteText

func WriteText(w io.Writer, r Report, values bool)

WriteText prints every difference grouped by request (client, format, endpoint).

Types

type Client

type Client struct {
	Name    string
	Headers http.Header
}

Client describes a Plex application header profile.

type Difference

type Difference struct {
	// Client, Format and Endpoint identify the request (filled by the
	// caller that ran it; Compare leaves them empty).
	Client   string `json:"client,omitempty"`
	Format   string `json:"format,omitempty"`
	Endpoint string `json:"endpoint,omitempty"`

	Path      string `json:"path"`
	Kind      string `json:"kind"`
	Reference any    `json:"reference,omitempty"`
	Target    any    `json:"target,omitempty"`
	// Count is how many times the path occurs on the side that has it (the
	// reference for missing/type/value, the target for extra).
	Count int `json:"count,omitempty"`
	// Nested is how many descendant paths of a missing or extra element
	// were folded into this difference.
	Nested   int    `json:"nested,omitempty"`
	Blocking bool   `json:"blocking"`
	Reason   string `json:"reason,omitempty"`
}

Difference describes one structural or protocol mismatch at one schema path. Array indices are collapsed, so a path stands for every element of a repeated list ("/MediaContainer/Video/@title", "$/MediaContainer/Metadata[]/title").

type DiscoveredIDs

type DiscoveredIDs struct {
	Values   map[string]string `json:"values"`
	Warnings []string          `json:"warnings,omitempty"`
}

DiscoveredIDs holds per-server identifiers used to make templated probes target real items.

type EndpointSummary

type EndpointSummary struct {
	Endpoint string        `json:"endpoint"`
	Missing  []PathSummary `json:"missing,omitempty"`
	Extra    []PathSummary `json:"extra,omitempty"`
	Type     []PathSummary `json:"type,omitempty"`
	Value    []PathSummary `json:"value,omitempty"`
	// Other holds status, header, parse and request errors.
	Other []PathSummary `json:"other,omitempty"`
}

EndpointSummary groups the differences of one endpoint (all clients and formats).

func Summarize

func Summarize(r Report) []EndpointSummary

Summarize groups a report by endpoint, then by (format, kind, path), so a gap that every client shows is listed once.

func (EndpointSummary) Blocking

func (e EndpointSummary) Blocking() int

Blocking counts the endpoint's blocking path differences.

type PathSummary

type PathSummary struct {
	Format    string   `json:"format"`
	Path      string   `json:"path"`
	Kind      string   `json:"kind"`
	Reference string   `json:"reference,omitempty"`
	Target    string   `json:"target,omitempty"`
	Clients   []string `json:"clients"`
	Count     int      `json:"count,omitempty"`
	Nested    int      `json:"nested,omitempty"`
	Blocking  bool     `json:"blocking,omitempty"`
}

PathSummary is one schema difference aggregated across the clients that showed it.

type Protocol

type Protocol interface {
	Clients() map[string]Client
	Corpus(profile string) []Request
	Formats() []bool // false is XML, true is JSON
	Discover(context.Context, *http.Client, string, string, string, *DiscoveredIDs) DiscoveredIDs
	Fetch(context.Context, *http.Client, string, string, Request, string, map[string]string, bool) (Response, error)
	FixtureName(profile string, request Request, jsonMode bool) string
	// IgnorePaths supplies regular expressions for protocol-specific differences.
	IgnorePaths() []string
	Redact(response Response) Response
	Compare(reference, target Response) Report
}

Protocol supplies the wire-specific parts of a conformance run. Implementations must not retain credentials or use shared mutable state between runs.

type ReferenceDefect

type ReferenceDefect struct {
	ID       string `json:"id"`
	Detail   string `json:"detail"`
	Observed string `json:"observed"`
}

ReferenceDefect records a known behavior of a reference, never an Ether requirement.

type Report

type Report struct {
	Differences      []Difference      `json:"differences"`
	Discovery        []string          `json:"discovery,omitempty"`
	ReferenceDefects []ReferenceDefect `json:"reference_defects,omitempty"`
	// Endpoints lists every endpoint compared, so summaries can show
	// endpoints without differences too.
	Endpoints []string `json:"endpoints,omitempty"`
}

Report is the result of comparing responses.

func Compare

func Compare(a, b Response) Report

Compare checks status, selected headers and the response schema. Bodies are reduced to schemas (paths with array indices collapsed, the set of value types and distinct values seen at each path, and child element order), so two listings of different titles compare by shape: an attribute that PMS emits on some items but the target never emits is "missing", the reverse is "extra", and a JSON number where PMS sends a string is a "type" mismatch. VolatileFields (titles, timestamps, versions, redacted fields) are compared by type only. LoadBearingFields still emit value diffs (including multi-value sets); plex.Compare promotes those to blocking.

func CompareBinary

func CompareBinary(a, b Response) Report

CompareBinary compares range semantics, not media bytes or cross-server hashes.

func CompareHeaders

func CompareHeaders(a, b Response, headers []string) Report

CompareHeaders compares responses using protocol-supplied headers.

func ComparePlaylist

func ComparePlaylist(a, b Response) Report

ComparePlaylist compares HLS structure without comparing signed URLs, segment counts, timestamps or media-specific values across servers.

func (Report) Blocking

func (r Report) Blocking() int

Blocking counts the blocking differences.

func (Report) WithRequest

func (r Report) WithRequest(client, format, endpoint string) Report

WithRequest stamps every difference with the request it came from.

type Request

type Request struct {
	Name, Method, Path string
	Headers            map[string]http.Header
	Body               []byte
	RangeKind          string
	FixtureOnly        bool
	ExpectedStatus     int
}

Request is one logical request in the PMS probe corpus.

type RequestComparer

type RequestComparer interface {
	CompareRequest(Request, Response, Response) Report
}

RequestComparer permits narrowly scoped protocol rules that depend on the request being compared. Protocols without it retain the ordinary comparer.

type Response

type Response struct {
	Status          int              `json:"status"`
	Headers         http.Header      `json:"headers"`
	Body            []byte           `json:"body"`
	Kind            string           `json:"kind,omitempty"`
	RangeKind       string           `json:"rangeKind,omitempty"`
	BodyLength      int64            `json:"bodyLength,omitempty"`
	SHA256          string           `json:"sha256,omitempty"`
	Truncated       bool             `json:"truncated,omitempty"`
	ReferenceDefect *ReferenceDefect `json:"reference_defect,omitempty"`
	RequestRange    string           `json:"requestRange,omitempty"`
}

Response is a captured HTTP response.

func LoadFixture

func LoadFixture(path string) (Response, error)

LoadFixture reads a response fixture.

func RedactSecrets

func RedactSecrets(r Response, secrets ...string) Response

RedactSecrets removes known run-specific credentials and identifiers from a response before it can reach disk or reports, without altering JSON keys.

type ResponseObserver

type ResponseObserver interface {
	Observe(Request, Response, map[string]string)
}

ResponseObserver is an optional protocol extension for stateful ordered flows. Implementations may update only the caller-owned run variables.

type Route

type Route struct {
	Method  string `json:"method"`
	Pattern string `json:"pattern"`
}

Route describes one registered protocol endpoint.

type RouteInventory

type RouteInventory struct {
	Available bool    `json:"available"`
	Routes    []Route `json:"routes"`
}

RouteInventory distinguishes an unavailable front end from an available one with no routes.

Directories

Path Synopsis
Package capture records sanitized HTTP traffic while proxying client requests.
Package capture records sanitized HTTP traffic while proxying client requests.
Package mediabrowser implements profile-driven Jellyfin and Emby probes.
Package mediabrowser implements profile-driven Jellyfin and Emby probes.
Package openapi validates JSON responses against OpenAPI 3 and Swagger 2 documents.
Package openapi validates JSON responses against OpenAPI 3 and Swagger 2 documents.
Package silo provides Silo's native profile-driven conformance protocol.
Package silo provides Silo's native profile-driven conformance protocol.
Package specs exposes the pinned conformance manifest to offline tools.
Package specs exposes the pinned conformance manifest to offline tools.

Jump to

Keyboard shortcuts

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