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
- func DeflateControlList(entries []string) []byte
- func DeviceCSR(t testing.TB) (*ecdsa.PrivateKey, string)
- func DeviceTLSConfig(t testing.TB, clientCertPEM string, key *ecdsa.PrivateKey, ...) *tls.Config
- func Golden(t testing.TB, name string, got []byte)
- func InflateControlList(t testing.TB, frame []byte) []string
- func Introspection(entries map[string][2]int) string
- func MQTTConnect(t testing.TB, brokerURL, clientID string, cleanSession bool, ...) (paho.Client, bool)
- func MQTTTryConnect(t testing.TB, brokerURL, clientID string, cleanSession bool, ...) (paho.Client, bool, error)
- func ServerTLSCert(t testing.TB) (tls.Certificate, *x509.CertPool)
- func StartTimescale(t testing.TB) *pgxpool.Pool
- func WaitToken(t testing.TB, token paho.Token, timeout time.Duration)
- type AstarteDevice
- func (d *AstarteDevice) Base() string
- func (d *AstarteDevice) DataTopic(iface, path string) string
- func (d *AstarteDevice) Disconnect()
- func (d *AstarteDevice) EmptyCache(t testing.TB)
- func (d *AstarteDevice) Messages() []ServerMessage
- func (d *AstarteDevice) PublishIntrospection(t testing.TB, introspection string)
- func (d *AstarteDevice) PublishRaw(t testing.TB, iface, path string, body []byte, qos byte)
- func (d *AstarteDevice) PublishValue(t testing.TB, iface, path string, v payload.Value, ts *time.Time, ...)
- func (d *AstarteDevice) SendProducerProperties(t testing.TB, entries []string)
- func (d *AstarteDevice) WaitForMessage(t testing.TB, timeout time.Duration, what string, ...) ServerMessage
- func (d *AstarteDevice) WaitForTopic(t testing.TB, timeout time.Duration, topic string) ServerMessage
- type ServerMessage
Constants ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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.
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 ¶
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.