Files
mesh-controller/internal/link/report_retry_test.go
T

62 lines
1.9 KiB
Go

package link
import (
"context"
"encoding/json"
"errors"
"io"
"log"
"testing"
amqp "github.com/rabbitmq/amqp091-go"
)
type saidTo struct{ acked, nacked, requeued bool }
func (a *saidTo) Ack(uint64, bool) error { a.acked = true; return nil }
func (a *saidTo) Nack(_ uint64, _ bool, requeue bool) error {
a.nacked, a.requeued = true, requeue
return nil
}
func (a *saidTo) Reject(uint64, bool) error { return nil }
type heardWith struct{ err error }
func (h heardWith) Heard(context.Context, Report) error { return h.err }
func aReport(t *testing.T, to *saidTo) amqp.Delivery {
t.Helper()
body, err := json.Marshal(Report{Node: "anchor", Applied: []string{"store"}})
if err != nil {
t.Fatal(err)
}
return amqp.Delivery{Acknowledger: to, RoutingKey: KeyReport, Body: body}
}
// A report the store could not take right now goes back to the broker to be asked again; one the
// store answered no to is acknowledged, or it would come back for ever (novox/hq issue 082).
func TestAReportTheStoreCouldNotTakeIsKeptAndOneItRefusedIsNot(t *testing.T) {
quiet := log.New(io.Discard, "", 0)
notNow := &saidTo{}
s := &Server{listener: heardWith{err: errors.Join(ErrTryAgain, errors.New("starting up"))}, log: quiet, again: 1}
s.handleReport(aReport(t, notNow))
if notNow.acked || !notNow.nacked || !notNow.requeued {
t.Fatalf("a report the store could not take yet was not handed back to be asked again: %+v", notNow)
}
refused := &saidTo{}
s = &Server{listener: heardWith{err: errors.New("a report named no node")}, log: quiet, again: 1}
s.handleReport(aReport(t, refused))
if !refused.acked || refused.nacked {
t.Fatalf("a report the store answered no to was not acknowledged, so it would spin: %+v", refused)
}
recorded := &saidTo{}
s = &Server{listener: heardWith{}, log: quiet}
s.handleReport(aReport(t, recorded))
if !recorded.acked || recorded.nacked {
t.Fatalf("a recorded report was not acknowledged: %+v", recorded)
}
}