Documentation
¶
Overview ¶
Package packagecompat compares a route's legacy kernel handler with its package-native implementation on identical seeded data. Extraction PRs use it to prove that a native route answers byte-compatibly (after v2compat.NormalizeForCompare) before its mode moves past shadow.
Every run seeds two independent databases: the legacy handler reads the kernel's global database, the native handler gets its own connection. They are SQLite files by default; with ANIX_TEST_POSTGRES_DSN set, RunRead and RunWrite also run on two PostgreSQL schemas. Each case starts from empty databases with the route's Models migrated; the cases a test runs share the migrated databases, emptied between cases (shared.go).
Index ¶
- Constants
- func CompareAnswers(legacy, native Result) error
- func FinalizeNodeSplit(t testing.TB, db *gorm.DB, tables ...string)
- func ForEachKernelDatabase(t *testing.T, models []any, body func(t *testing.T, db *gorm.DB))
- func KernelSettings(t testing.TB, db *gorm.DB, grants SettingsGrants) kernelsettingsv1.KernelSettingsClient
- func Lease(db *gorm.DB, packageID string) func(ctx context.Context, name string) bool
- func NodeSplitModels() []any
- func OpenSQLite(t *testing.T, models ...any) *gorm.DB
- func RequireSame(t *testing.T, c Case, legacy, native Result)
- func RunKernelRead(t *testing.T, route KernelRoute, c Case)
- func RunKernelWrite(t *testing.T, route KernelRoute, c Case)
- func RunRead(t *testing.T, route Route, c Case)
- func RunWrite(t *testing.T, route Route, c Case)
- type Case
- type Kernel
- func (k *Kernel) Do(t testing.TB, method, path string, body []byte, headers map[string]string) Result
- func (k *Kernel) LegacyCalls(routeID string) int
- func (k *Kernel) PendingHandles() int
- func (k *Kernel) Received(routeID string) []pluginhostsdk.NativeRequest
- func (k *Kernel) Serve(t *testing.T, method, pattern string, c Case) Result
- type KernelHostRoute
- type KernelOptions
- type KernelRoute
- type Result
- type Route
- type SettingsGrants
Constants ¶
const PostgresDSNEnvironment = "ANIX_TEST_POSTGRES_DSN"
PostgresDSNEnvironment enables the PostgreSQL runs.
Variables ¶
This section is empty.
Functions ¶
func CompareAnswers ¶
CompareAnswers reports how two answers differ: status code, or body after v2compat.NormalizeForCompare. A sealed handle in the native answer matches the secret the legacy answer shows there, as in the router's shadow comparison (v2compat.EqualForCompare).
func FinalizeNodeSplit ¶ added in v4.2.0
FinalizeNodeSplit takes tables (all split tables when none are named) through the split as an operator does (docs/UPGRADE.md): the state rows, a backfill, a matching verification, dual_read, then finalize. Their legacy secret columns then hold tombstones and redacted documents, and the kernel creates the views that wait for finalize (packagestore.EnsureKernelAPIViews). Seed functions call it after the rows are written, on both sides.
func ForEachKernelDatabase ¶ added in v4.2.0
ForEachKernelDatabase runs body on a fresh kernel database with models migrated, on SQLite and, with ANIX_TEST_POSTGRES_DSN set, on a throwaway PostgreSQL schema; the database is also the kernel's global one, which the legacy handlers and the kernel's services read. A test whose legacy and native sides must share live state (agent sessions the kernel holds in memory) runs both on it.
func KernelSettings ¶
func KernelSettings(t testing.TB, db *gorm.DB, grants SettingsGrants) kernelsettingsv1.KernelSettingsClient
KernelSettings serves the kernel's KernelSettings (internal/kernelsettings) on db in process over gRPC, to grants' host, and returns a client for it, as the package host gets one over its bridge connection.
func Lease ¶ added in v4.2.0
Lease answers what the kernel's storage lease grants the package whose manifest template is packages/<packageID>/manifest.template.json on db, as the kernel decides it when a host asks (service.EffectiveStorageGrants): an adoption of v2_node, v2_node_protocol or v2_forward_node, and a view of the split's remainder, only once finalized. The answer is computed when asked, so it sees what the case's seed did. It is a native service's Leased.
func NodeSplitModels ¶ added in v4.2.0
func NodeSplitModels() []any
NodeSplitModels are the node credential split's tables, and the operation log its phase changes are audited in. A route on a table or view of the split's remainder (docs/architecture/node-ops-service.md section 4.6) lists them in Route.Models, so the shared databases keep them between cases.
func OpenSQLite ¶ added in v4.2.0
OpenSQLite is a fresh SQLite kernel database with models migrated, for a test that calls a native handler directly.
func RequireSame ¶ added in v4.2.0
RequireSame requires two answers to be the same, as RunRead does: the headers c lists sent by both, the status and the normalized body equal once c's masked paths are masked.
func RunKernelRead ¶ added in v4.2.0
func RunKernelRead(t *testing.T, route KernelRoute, c Case)
RunKernelRead is RunRead for a KernelRoute. Unless the case expects the route to fall back (Case.Fallback), the native handler must answer itself: an answer the host relayed to the kernel's legacy handler would match by construction.
func RunKernelWrite ¶ added in v4.2.0
func RunKernelWrite(t *testing.T, route KernelRoute, c Case)
RunKernelWrite is RunWrite for a KernelRoute.
Types ¶
type Case ¶
type Case struct {
Name string
// Path is the concrete request path, with query string if any.
Path string
Body []byte
Principal pluginhostsdk.Principal
// Seed writes the same data into each database.
Seed func(t testing.TB, db *gorm.DB)
// Snapshot returns the database state RunWrite compares after the
// request; any JSON-encodable value.
Snapshot func(t testing.TB, db *gorm.DB) any
// Mask lists dotted JSON paths (for example "data.token") whose values
// differ by design, such as tokens and secrets: they must exist on both
// sides and are replaced before comparing.
Mask []string
// Headers lists response headers both sides must send.
Headers []string
// RequestHeaders are sent with the request: the legacy handler reads
// them from it, the native one from the metadata the kernel forwards.
RequestHeaders map[string]string
// Host is the request's Host (default example.com) and TLS whether it
// arrived over TLS: the legacy handler reads them from the request, the
// native one from the request scheme and host the kernel sends.
Host string
TLS bool
// Warmup bodies are sent, in order, before the compared request.
Warmup [][]byte
// Fallback is set when the native side must answer from the legacy
// handler (RunKernelRead, RunKernelWrite): the route cannot serve the
// request natively, for example before the node credential split is
// finalized.
Fallback bool
}
Case is one request.
type Kernel ¶ added in v4.2.0
type Kernel struct {
// contains filtered or unexported fields
}
Kernel is the native side of a KernelRoute: the gateway, one package host and the KernelNodeOps engine.
func StartKernel ¶ added in v4.2.0
func StartKernel(t testing.TB, opts KernelOptions) *Kernel
StartKernel starts the kernel's side of a package: a KernelNodeOps engine on opts.DB with the executors a kernel registers (agent ones on opts.Agents), the gateway with the kernel's node secret fields, and the package host on a real bridge session, every route native.
func (*Kernel) Do ¶ added in v4.2.0
func (k *Kernel) Do(t testing.TB, method, path string, body []byte, headers map[string]string) Result
Do sends one request through the gateway, without a Case: method, path, body and request headers, as the administrator (actor 1).
func (*Kernel) LegacyCalls ¶ added in v4.2.0
LegacyCalls counts the requests of a route the host relayed to the kernel's legacy handler.
func (*Kernel) PendingHandles ¶ added in v4.2.0
PendingHandles counts the sealed handles still held: none once every request ended.
func (*Kernel) Received ¶ added in v4.2.0
func (k *Kernel) Received(routeID string) []pluginhostsdk.NativeRequest
Received returns what the package's native handler of a route was sent.
type KernelHostRoute ¶ added in v4.2.0
type KernelHostRoute struct {
Method, Pattern, RouteID string
// Legacy is the kernel's handler, which the host relays to.
Legacy gin.HandlerFunc
// Native builds the package's handler with the host's KernelNodeOps
// client.
Native func(nodeOps kernelnodeopsv1.KernelNodeOpsClient) pluginhostsdk.NativeHandler
}
KernelHostRoute is one route of a KernelOptions host.
type KernelOptions ¶ added in v4.2.0
type KernelOptions struct {
// DB is the kernel database the engine records in.
DB *gorm.DB
PackageID string
// Capabilities are the KernelNodeOps capabilities the package holds.
Capabilities []string
// Agents are the agent sessions the executors and session RPCs read.
Agents kernelnodeops.SourcesFunc
// Routes are the package's routes, each in native mode.
Routes []KernelHostRoute
}
KernelOptions configure StartKernel.
type KernelRoute ¶ added in v4.2.0
type KernelRoute struct {
Route
// PackageID is the route's package.
PackageID string
// Capabilities are the KernelNodeOps capabilities the package's signed
// release declares (kernel.nodeops.<family>.v1).
Capabilities []string
// NativeService builds the package's native handler on the native
// database, with the host's KernelNodeOps client.
NativeService func(db *gorm.DB, nodeOps kernelnodeopsv1.KernelNodeOpsClient) pluginhostsdk.NativeHandler
// Agents are the agent sessions the kernel's executors and session RPCs
// read; nil reads none.
Agents kernelnodeops.SourcesFunc
}
KernelRoute is a route whose native side runs the whole path a deployment runs: the kernel's v2 gateway (which seals the node secrets of the routes in config/node-secret-fields.json into handles and expands the handles an answer shows), a real package bridge session serving KernelNodeOps, the SDK router with the route in native mode, and the kernel's KernelNodeOps engine with its executors on the native database (docs/architecture/node-ops-service.md). The package host never sees a node secret, as in a deployment.
type Result ¶
Result is one side's answer.
func ServeLegacy ¶ added in v4.2.0
ServeLegacy sends c to the kernel's legacy handler, as the principal of c, for a test that runs both sides on one database (ForEachKernelDatabase).
type Route ¶
type Route struct {
// Method and Pattern are the gin registration, for example GET and
// "/api/v2/user/knowledge/:id".
Method string
Pattern string
RouteID string
// Legacy is the kernel's gin handler. It reads database.GetDB().
Legacy gin.HandlerFunc
// Native builds the package implementation on a database connection.
Native func(db *gorm.DB) pluginhostsdk.NativeHandler
// Models are migrated into both databases before Seed runs.
Models []any
}
Route is one v2 route with both implementations.
type SettingsGrants ¶
type SettingsGrants struct {
Host packagebridge.HostIdentity
Capabilities []string
}
SettingsGrants authorizes the capabilities a package's signed release declares, for that package's host only.
func (SettingsGrants) AuthorizeCapability ¶
func (g SettingsGrants) AuthorizeCapability(_ context.Context, host packagebridge.HostIdentity, capability string) error
AuthorizeCapability implements kernelsettings.Authorizer.