Files
handler-base/messages/bench_test.go
Billy D. f1dd96a42b
All checks were successful
CI / Test (push) Successful in 3m2s
CI / Lint (push) Successful in 3m7s
CI / Release (push) Successful in 1m55s
CI / Notify Downstream (stt-module) (push) Successful in 1s
CI / Notify Downstream (voice-assistant) (push) Successful in 1s
CI / Notify (push) Successful in 2s
CI / Notify Downstream (chat-handler) (push) Successful in 1s
CI / Notify Downstream (pipeline-bridge) (push) Successful in 1s
CI / Notify Downstream (tts-module) (push) Successful in 1s
style: gofmt + fix errcheck lint warning
2026-02-21 15:35:37 -05:00

313 lines
10 KiB
Go

// Package messages benchmarks protobuf encoding/decoding of all message types.
//
// Run with:
//
// go test -bench=. -benchmem -count=5 ./messages/... | tee bench.txt
// # optional: go install golang.org/x/perf/cmd/benchstat@latest && benchstat bench.txt
package messages
import (
"testing"
"time"
"google.golang.org/protobuf/proto"
pb "git.daviestechlabs.io/daviestechlabs/handler-base/gen/messagespb"
)
// ────────────────────────────────────────────────────────────────────────────
// Test fixtures — proto message constructors
// ────────────────────────────────────────────────────────────────────────────
func chatRequestProto() *pb.ChatRequest {
return &pb.ChatRequest{
RequestId: "req-abc-123",
UserId: "user-42",
Message: "What is the capital of France?",
Premium: true,
EnableRag: true,
EnableReranker: true,
TopK: 10,
Collection: "documents",
SystemPrompt: "You are a helpful assistant.",
ResponseSubject: "ai.chat.response.req-abc-123",
}
}
func voiceResponseProto() *pb.VoiceResponse {
return &pb.VoiceResponse{
RequestId: "vr-001",
Response: "The capital of France is Paris.",
Audio: make([]byte, 16384),
Transcription: "What is the capital of France?",
}
}
func ttsChunkProto() *pb.TTSAudioChunk {
return &pb.TTSAudioChunk{
SessionId: "tts-sess-99",
ChunkIndex: 3,
TotalChunks: 12,
Audio: make([]byte, 32768),
IsLast: false,
Timestamp: time.Now().Unix(),
SampleRate: 24000,
}
}
// ────────────────────────────────────────────────────────────────────────────
// Wire-size comparison (run once, printed by TestWireSize)
// ────────────────────────────────────────────────────────────────────────────
func TestWireSize(t *testing.T) {
tests := []struct {
name string
protoMsg proto.Message
}{
{"ChatRequest", chatRequestProto()},
{"VoiceResponse", voiceResponseProto()},
{"TTSAudioChunk", ttsChunkProto()},
}
for _, tt := range tests {
protoBytes, _ := proto.Marshal(tt.protoMsg)
t.Logf("%-16s proto=%5d B", tt.name, len(protoBytes))
}
}
// ────────────────────────────────────────────────────────────────────────────
// Encode benchmarks
// ────────────────────────────────────────────────────────────────────────────
func BenchmarkEncode_ChatRequest(b *testing.B) {
data := chatRequestProto()
b.ResetTimer()
for b.Loop() {
_, _ = proto.Marshal(data)
}
}
func BenchmarkEncode_VoiceResponse(b *testing.B) {
data := voiceResponseProto()
b.ResetTimer()
for b.Loop() {
_, _ = proto.Marshal(data)
}
}
func BenchmarkEncode_TTSChunk(b *testing.B) {
data := ttsChunkProto()
b.ResetTimer()
for b.Loop() {
_, _ = proto.Marshal(data)
}
}
// ────────────────────────────────────────────────────────────────────────────
// Decode benchmarks
// ────────────────────────────────────────────────────────────────────────────
func BenchmarkDecode_ChatRequest(b *testing.B) {
encoded, _ := proto.Marshal(chatRequestProto())
b.ResetTimer()
for b.Loop() {
var m pb.ChatRequest
_ = proto.Unmarshal(encoded, &m)
}
}
func BenchmarkDecode_VoiceResponse(b *testing.B) {
encoded, _ := proto.Marshal(voiceResponseProto())
b.ResetTimer()
for b.Loop() {
var m pb.VoiceResponse
_ = proto.Unmarshal(encoded, &m)
}
}
func BenchmarkDecode_TTSChunk(b *testing.B) {
encoded, _ := proto.Marshal(ttsChunkProto())
b.ResetTimer()
for b.Loop() {
var m pb.TTSAudioChunk
_ = proto.Unmarshal(encoded, &m)
}
}
// ────────────────────────────────────────────────────────────────────────────
// Roundtrip benchmarks (encode + decode)
// ────────────────────────────────────────────────────────────────────────────
func BenchmarkRoundtrip_ChatRequest(b *testing.B) {
data := chatRequestProto()
b.ResetTimer()
for b.Loop() {
enc, _ := proto.Marshal(data)
var dec pb.ChatRequest
_ = proto.Unmarshal(enc, &dec)
}
}
// ────────────────────────────────────────────────────────────────────────────
// Correctness tests — verify proto roundtrip
// ────────────────────────────────────────────────────────────────────────────
func TestRoundtrip_ChatRequest(t *testing.T) {
orig := chatRequestProto()
data, err := proto.Marshal(orig)
if err != nil {
t.Fatal(err)
}
var dec pb.ChatRequest
if err := proto.Unmarshal(data, &dec); err != nil {
t.Fatal(err)
}
if dec.GetRequestId() != orig.GetRequestId() {
t.Errorf("RequestId = %q, want %q", dec.GetRequestId(), orig.GetRequestId())
}
if dec.GetMessage() != orig.GetMessage() {
t.Errorf("Message = %q, want %q", dec.GetMessage(), orig.GetMessage())
}
if dec.GetTopK() != orig.GetTopK() {
t.Errorf("TopK = %d, want %d", dec.GetTopK(), orig.GetTopK())
}
if dec.GetPremium() != orig.GetPremium() {
t.Errorf("Premium = %v, want %v", dec.GetPremium(), orig.GetPremium())
}
if EffectiveQuery(&dec) != orig.GetMessage() {
t.Errorf("EffectiveQuery() = %q, want %q", EffectiveQuery(&dec), orig.GetMessage())
}
}
func TestRoundtrip_VoiceResponse(t *testing.T) {
orig := voiceResponseProto()
data, err := proto.Marshal(orig)
if err != nil {
t.Fatal(err)
}
var dec pb.VoiceResponse
if err := proto.Unmarshal(data, &dec); err != nil {
t.Fatal(err)
}
if dec.GetRequestId() != orig.GetRequestId() {
t.Errorf("RequestId mismatch")
}
if len(dec.GetAudio()) != len(orig.GetAudio()) {
t.Errorf("Audio len = %d, want %d", len(dec.GetAudio()), len(orig.GetAudio()))
}
if dec.GetTranscription() != orig.GetTranscription() {
t.Errorf("Transcription mismatch")
}
}
func TestRoundtrip_TTSAudioChunk(t *testing.T) {
orig := ttsChunkProto()
data, err := proto.Marshal(orig)
if err != nil {
t.Fatal(err)
}
var dec pb.TTSAudioChunk
if err := proto.Unmarshal(data, &dec); err != nil {
t.Fatal(err)
}
if dec.GetSessionId() != orig.GetSessionId() {
t.Errorf("SessionId mismatch")
}
if dec.GetChunkIndex() != orig.GetChunkIndex() {
t.Errorf("ChunkIndex = %d, want %d", dec.GetChunkIndex(), orig.GetChunkIndex())
}
if len(dec.GetAudio()) != len(orig.GetAudio()) {
t.Errorf("Audio len = %d, want %d", len(dec.GetAudio()), len(orig.GetAudio()))
}
if dec.GetSampleRate() != orig.GetSampleRate() {
t.Errorf("SampleRate = %d, want %d", dec.GetSampleRate(), orig.GetSampleRate())
}
}
func TestRoundtrip_PipelineTrigger(t *testing.T) {
orig := &pb.PipelineTrigger{
RequestId: "pip-001",
Pipeline: "document-ingestion",
Parameters: map[string]string{"source": "s3://bucket/data"},
}
data, err := proto.Marshal(orig)
if err != nil {
t.Fatal(err)
}
var dec pb.PipelineTrigger
if err := proto.Unmarshal(data, &dec); err != nil {
t.Fatal(err)
}
if dec.GetPipeline() != orig.GetPipeline() {
t.Errorf("Pipeline = %q, want %q", dec.GetPipeline(), orig.GetPipeline())
}
if dec.GetParameters()["source"] != orig.GetParameters()["source"] {
t.Errorf("Parameters[source] mismatch")
}
}
func TestRoundtrip_STTTranscription(t *testing.T) {
orig := &pb.STTTranscription{
SessionId: "stt-001",
Transcript: "hello world",
Sequence: 5,
IsPartial: false,
IsFinal: true,
Timestamp: time.Now().Unix(),
SpeakerId: "speaker-1",
HasVoiceActivity: true,
State: "listening",
}
data, err := proto.Marshal(orig)
if err != nil {
t.Fatal(err)
}
var dec pb.STTTranscription
if err := proto.Unmarshal(data, &dec); err != nil {
t.Fatal(err)
}
if dec.GetTranscript() != orig.GetTranscript() {
t.Errorf("Transcript = %q, want %q", dec.GetTranscript(), orig.GetTranscript())
}
if dec.GetIsFinal() != orig.GetIsFinal() {
t.Error("IsFinal mismatch")
}
}
func TestRoundtrip_ErrorResponse(t *testing.T) {
orig := &pb.ErrorResponse{Error: true, Message: "something broke", Type: "InternalError"}
data, err := proto.Marshal(orig)
if err != nil {
t.Fatal(err)
}
var dec pb.ErrorResponse
if err := proto.Unmarshal(data, &dec); err != nil {
t.Fatal(err)
}
if !dec.GetError() || dec.GetMessage() != "something broke" || dec.GetType() != "InternalError" {
t.Errorf("ErrorResponse roundtrip mismatch: %+v", &dec)
}
}
func TestEffectiveQuery_MessageSet(t *testing.T) {
req := &pb.ChatRequest{Message: "hello", Query: "world"}
if got := EffectiveQuery(req); got != "hello" {
t.Errorf("EffectiveQuery() = %q, want %q", got, "hello")
}
}
func TestEffectiveQuery_FallbackToQuery(t *testing.T) {
req := &pb.ChatRequest{Query: "world"}
if got := EffectiveQuery(req); got != "world" {
t.Errorf("EffectiveQuery() = %q, want %q", got, "world")
}
}
func TestTimestamp(t *testing.T) {
ts := Timestamp()
now := time.Now().Unix()
if ts < now-1 || ts > now+1 {
t.Errorf("Timestamp() = %d, expected ~%d", ts, now)
}
}