testutil

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 1, 2026 License: Apache-2.0 Imports: 29 Imported by: 0

Documentation

Overview

Package testutil provides the shared test harness used across Astrate's verification tiers (docs/ROADMAP.md §0.2): the T2 TimescaleDB container helper and the golden-file comparison helper.

Index

Constants

View Source
const (
	// TimescaleImage is the production-parity database image (docs/DESIGN.md §5.4):
	// tests run against the exact image the docker-compose deployment ships.
	TimescaleImage = "timescale/timescaledb:latest-pg16"

	// EnvTestDSN names the env var that, when set, short-circuits container
	// startup and connects to an already-running database instead (e.g.
	// `make up` + ASTRATE_TEST_DSN=...). This is the fast local iteration
	// path; CI always boots a fresh container.
	EnvTestDSN = "ASTRATE_TEST_DSN"
)

Variables

This section is empty.

Functions

func DeflateControlList

func DeflateControlList(entries []string) []byte

DeflateControlList builds an Astarte control payload: a 4-byte big-endian uncompressed-size prefix followed by the zlib-deflated ";"-joined list (docs/DESIGN.md §3.3–3.4). It mirrors the engine's framing so test devices and the engine agree on the wire shape.

func DeviceCSR

func DeviceCSR(t testing.TB) (*ecdsa.PrivateKey, string)

DeviceCSR generates a fresh P-256 device key and a PEM CSR for it (the CSR's subject is irrelevant: the pairing CA overrides everything).

func DeviceTLSConfig

func DeviceTLSConfig(t testing.TB, clientCertPEM string, key *ecdsa.PrivateKey, roots *x509.CertPool) *tls.Config

DeviceTLSConfig assembles the client-side mTLS configuration from an issued certificate PEM, its private key, and the pool trusting the broker's server certificate.

func Golden

func Golden(t testing.TB, name string, got []byte)

Golden compares got against the golden file testdata/<name> (relative to the calling package). With -update the file is (re)written instead and the comparison always passes. Golden fixtures are wire-frozen bytes (envelopes, payload vectors), so the comparison is exact — byte for byte.

func InflateControlList

func InflateControlList(t testing.TB, frame []byte) []string

InflateControlList parses an Astarte control payload (the inverse of DeflateControlList), returning the ";"-separated entry list. An empty list yields nil. It is used by tests to assert consumer/properties payloads.

func Introspection

func Introspection(entries map[string][2]int) string

Introspection renders a "name:major:minor;..." string with deterministic (sorted) ordering.

func MQTTConnect

func MQTTConnect(t testing.TB, brokerURL, clientID string, cleanSession bool, tlsCfg *tls.Config, tweaks ...func(*paho.ClientOptions)) (paho.Client, bool)

MQTTConnect is MQTTTryConnect that fails the test on connection errors.

func MQTTTryConnect

func MQTTTryConnect(t testing.TB, brokerURL, clientID string, cleanSession bool, tlsCfg *tls.Config, tweaks ...func(*paho.ClientOptions)) (paho.Client, bool, error)

MQTTTryConnect dials the broker and waits for the CONNACK. It returns the connected client and the CONNACK's session-present flag, or an error when the broker refuses (or drops) the connection. brokerURL uses paho schemes: "ssl://host:port" (TLS) or "tcp://host:port". Extra option tweaks (e.g. SetDefaultPublishHandler) apply before connecting. On success, disconnect is registered on t.Cleanup.

func ServerTLSCert

func ServerTLSCert(t testing.TB) (tls.Certificate, *x509.CertPool)

ServerTLSCert generates a self-signed server certificate for the broker's TLS listener (valid for localhost/127.0.0.1/::1) and returns it together with a root pool that trusts it, for client-side verification.

func StartTimescale

func StartTimescale(t testing.TB) *pgxpool.Pool

StartTimescale returns a pgxpool.Pool connected to a ready TimescaleDB instance. If EnvTestDSN is set it reuses that database; otherwise it boots a fresh TimescaleImage container. Teardown (pool close, container termination) is registered on t.Cleanup, so callers just use the pool.

func WaitToken

func WaitToken(t testing.TB, token paho.Token, timeout time.Duration)

WaitToken waits for a paho token with a timeout and fails the test on token errors.

Types

type AstarteDevice

type AstarteDevice struct {
	// Realm is the device's realm name.
	Realm string
	// ID is the device identifier.
	ID deviceid.ID
	// Client is the underlying paho client (for advanced cases — most tests
	// use the helpers below).
	Client paho.Client
	// contains filtered or unexported fields
}

AstarteDevice is a test client that speaks the Astarte MQTT v1 protocol (docs/ROADMAP.md §7.2 file 6.15): a paho MQTT client over the broker's mTLS listener whose client ID is the certificate CN "<realm>/<device_id>", with helpers for introspection, BSON / JSON-profile data publishes, control-channel payloads (emptyCache, producer/properties), and capture of server-owned messages pushed back to the device. It is reused by the engine T3 suite and the M7/M9 conformance harnesses, so it deliberately does not import internal/broker (which imports this package in its tests).

func ConnectAstarteDevice

func ConnectAstarteDevice(t testing.TB, brokerURL, realm string, id deviceid.ID, tlsCfg *tls.Config, cleanSession bool) *AstarteDevice

ConnectAstarteDevice connects a test device over the broker's TLS listener. brokerURL is an "ssl://host:port" address; tlsCfg must carry the device's realm-CA-issued client certificate (testutil.DeviceTLSConfig). The device subscribes to "<realm>/<id>/#" — the tolerated superset filter (docs/DESIGN.md §3.2) — so every server-owned and control message is captured.

func (*AstarteDevice) Base

func (d *AstarteDevice) Base() string

Base returns the device's base topic "<realm>/<id>".

func (*AstarteDevice) DataTopic

func (d *AstarteDevice) DataTopic(iface, path string) string

DataTopic builds the publish topic for an interface path ("<realm>/<id>/<iface><path>"); path includes its leading slash, or is empty for an object-aggregated interface whose root is the interface itself.

func (*AstarteDevice) Disconnect

func (d *AstarteDevice) Disconnect()

Disconnect closes the MQTT connection.

func (*AstarteDevice) EmptyCache

func (d *AstarteDevice) EmptyCache(t testing.TB)

EmptyCache publishes the control/emptyCache signal (docs/DESIGN.md §3.3), telling Astrate to re-send every server-owned property.

func (*AstarteDevice) Messages

func (d *AstarteDevice) Messages() []ServerMessage

Messages returns a snapshot of every server message captured so far.

func (*AstarteDevice) PublishIntrospection

func (d *AstarteDevice) PublishIntrospection(t testing.TB, introspection string)

PublishIntrospection publishes the introspection string on the bare base topic (docs/DESIGN.md §3.3) at QoS 2 and waits for the PUBACK/PUBCOMP.

func (*AstarteDevice) PublishRaw

func (d *AstarteDevice) PublishRaw(t testing.TB, iface, path string, body []byte, qos byte)

PublishRaw publishes a pre-encoded body on the interface path. An empty body is a property unset (docs/DESIGN.md §3.3).

func (*AstarteDevice) PublishValue

func (d *AstarteDevice) PublishValue(t testing.TB, iface, path string, v payload.Value, ts *time.Time, format payload.Format, qos byte)

PublishValue encodes a value in the given wire format and publishes it on the interface path, waiting for the acknowledgment.

func (*AstarteDevice) SendProducerProperties

func (d *AstarteDevice) SendProducerProperties(t testing.TB, entries []string)

SendProducerProperties publishes the control/producer/properties payload: the zlib-framed exhaustive list of "<iface>/<path>" entries the device still holds (docs/DESIGN.md §3.3). Astrate purges every device-owned property not listed.

func (*AstarteDevice) WaitForMessage

func (d *AstarteDevice) WaitForMessage(t testing.TB, timeout time.Duration, what string, pred func(ServerMessage) bool) ServerMessage

WaitForMessage polls until a captured message satisfies pred, returning it. It fails the test on timeout.

func (*AstarteDevice) WaitForTopic

func (d *AstarteDevice) WaitForTopic(t testing.TB, timeout time.Duration, topic string) ServerMessage

WaitForTopic waits for a (non-empty) message delivered on an exact topic.

type ServerMessage

type ServerMessage struct {
	// Topic is the full publish topic.
	Topic string
	// Payload is the message body (empty for a property-unset retained clear).
	Payload []byte
}

ServerMessage is one message the broker delivered to the device.

Jump to

Keyboard shortcuts

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