98 lines
2.5 KiB
Go
98 lines
2.5 KiB
Go
//go:build integration
|
|
|
|
package dispatcher
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.ipao.vip/rogee/go-sip/contracts"
|
|
"git.ipao.vip/rogee/go-sip/internal/mq"
|
|
"git.ipao.vip/rogee/go-sip/internal/store"
|
|
)
|
|
|
|
func TestLocalDispatcherConsumesCommandIntoSQLiteAndPublishesOutbox(t *testing.T) {
|
|
url := os.Getenv("RABBITMQ_URL")
|
|
if url == "" {
|
|
t.Skip("RABBITMQ_URL is not configured")
|
|
}
|
|
broker, err := mq.OpenWithPrefetch(url, "", 1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() {
|
|
if err := broker.Close(); err != nil {
|
|
t.Error(err)
|
|
}
|
|
})
|
|
st, err := store.Open(filepath.Join(t.TempDir(), "dispatcher.db"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() {
|
|
if err := st.Close(); err != nil {
|
|
t.Error(err)
|
|
}
|
|
})
|
|
d, err := New(st, broker, time.Now)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
raw, err := contracts.Read("examples/call.execute.json")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
const tenantKey = "tenant-demo-key"
|
|
routingKey := "agent-call.tenant." + tenantKey + ".call.execute"
|
|
if _, err := broker.DeclareTenantQueue(tenantKey); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ctx, cancel := context.WithTimeout(t.Context(), 20*time.Second)
|
|
defer cancel()
|
|
consumeDone := make(chan error, 1)
|
|
go func() { consumeDone <- d.ConsumeTenant(ctx, broker, tenantKey) }()
|
|
if err := broker.Publish(ctx, mq.DefaultExchange, routingKey, raw); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
deadline := time.Now().Add(10 * time.Second)
|
|
for {
|
|
var taskCount, outboxCount int
|
|
if err := st.DB().QueryRow(`SELECT COUNT(*) FROM tasks`).Scan(&taskCount); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := st.DB().QueryRow(`SELECT COUNT(*) FROM outbox`).Scan(&outboxCount); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if taskCount == 1 && outboxCount >= 1 {
|
|
break
|
|
}
|
|
if time.Now().After(deadline) {
|
|
t.Fatalf("command was not persisted: tasks=%d outbox=%d", taskCount, outboxCount)
|
|
}
|
|
time.Sleep(50 * time.Millisecond)
|
|
}
|
|
published, err := d.FlushOutbox(ctx, 1)
|
|
if err != nil || published != 1 {
|
|
t.Fatalf("published=%d err=%v", published, err)
|
|
}
|
|
cancel()
|
|
select {
|
|
case <-consumeDone:
|
|
case <-time.After(3 * time.Second):
|
|
t.Fatal("tenant consumer did not stop")
|
|
}
|
|
var taskStatus, outboxStatus string
|
|
if err := st.DB().QueryRow(`SELECT status FROM tasks LIMIT 1`).Scan(&taskStatus); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := st.DB().QueryRow(`SELECT status FROM outbox LIMIT 1`).Scan(&outboxStatus); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if taskStatus != "accepted" || outboxStatus != "published" {
|
|
t.Fatalf("unexpected persisted statuses: task=%q outbox=%q", taskStatus, outboxStatus)
|
|
}
|
|
}
|