108 lines
3.1 KiB
Go
108 lines
3.1 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"git.ipao.vip/rogee/creator-hub/internal/creator"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
type coverWriterStub struct {
|
|
listenerWriterStub
|
|
saved chan []creator.ListenerDelivery
|
|
err error
|
|
}
|
|
|
|
func (s *coverWriterStub) UpdateListenerEventCovers(_ context.Context, _, _ string, items []creator.ListenerDelivery) error {
|
|
s.saved <- items
|
|
return s.err
|
|
}
|
|
|
|
type coverEnricherStub struct {
|
|
listenerSessionStub
|
|
entered chan struct{}
|
|
release chan struct{}
|
|
err error
|
|
}
|
|
|
|
func (s *coverEnricherStub) enrich(ctx context.Context, items []creator.ListenerDelivery) ([]creator.ListenerDelivery, error) {
|
|
select {
|
|
case s.entered <- struct{}{}:
|
|
default:
|
|
}
|
|
select {
|
|
case <-ctx.Done():
|
|
return nil, ctx.Err()
|
|
case <-s.release:
|
|
}
|
|
for i := range items {
|
|
items[i].Notice.WorkCoverError = "cached result"
|
|
}
|
|
return items, s.err
|
|
}
|
|
func coverDelivery() []creator.ListenerDelivery {
|
|
return []creator.ListenerDelivery{{Kind: "notice", DeliveryID: "cover", Notice: &creator.ListenerNotice{EventKey: "cover", EventType: "like", WorkID: "9", WorkAuthorUID: "1", WorkCoverURL: "https://example.com/cover"}}}
|
|
}
|
|
func TestEventCoverWorkerDoesNotBlockReceptionAndReportsOverload(t *testing.T) {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
writer := &coverWriterStub{saved: make(chan []creator.ListenerDelivery, 64)}
|
|
session := &coverEnricherStub{entered: make(chan struct{}, 1), release: make(chan struct{})}
|
|
queue := startListenerCoverWorker(ctx, writer, "account", "generation", session)
|
|
original := coverDelivery()
|
|
queue(original)()
|
|
select {
|
|
case <-session.entered:
|
|
case <-time.After(time.Second):
|
|
t.Fatal("cover worker did not start")
|
|
}
|
|
for i := 0; i < 32; i++ {
|
|
queue(coverDelivery())()
|
|
}
|
|
overloaded := coverDelivery()
|
|
queue(overloaded)()
|
|
if overloaded[0].Notice.WorkCoverError != coverQueueFullReason {
|
|
t.Fatal("overload must be included in notification persistence")
|
|
}
|
|
select {
|
|
case <-writer.saved:
|
|
t.Fatal("overload performed a synchronous cover-result write")
|
|
default:
|
|
}
|
|
if original[0].Notice.WorkCoverError != "" {
|
|
t.Fatal("delivery was mutated before persistence")
|
|
}
|
|
close(session.release)
|
|
select {
|
|
case saved := <-writer.saved:
|
|
if saved[0].Notice.WorkCoverError != "cached result" {
|
|
t.Fatal("result missing")
|
|
}
|
|
case <-time.After(time.Second):
|
|
t.Fatal("cover not saved")
|
|
}
|
|
}
|
|
func TestEventCoverFailureIsRecordedAndDoesNotChangeListenerStatus(t *testing.T) {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
release := make(chan struct{})
|
|
close(release)
|
|
writer := &coverWriterStub{saved: make(chan []creator.ListenerDelivery, 4), err: creator.ErrConflict}
|
|
session := &coverEnricherStub{entered: make(chan struct{}, 1), release: release, err: errors.New("cover unavailable")}
|
|
queue := startListenerCoverWorker(ctx, writer, "account", "generation", session)
|
|
queue(nil)()
|
|
queue(coverDelivery())()
|
|
select {
|
|
case saved := <-writer.saved:
|
|
if saved[0].Notice.WorkCoverError != "cover unavailable" {
|
|
t.Fatal("error hidden")
|
|
}
|
|
case <-time.After(time.Second):
|
|
t.Fatal("error not saved")
|
|
}
|
|
if writer.batches != 0 {
|
|
t.Fatal("cover failure changed listener health")
|
|
}
|
|
}
|