test(19.3-06): wait for the queued site-cache purge before asserting (WR-01)

- every read of the purge receiver first drains the app's purger through
  cooler.SiteCachePurger.Wait, since cooler now queues purges after commit
This commit is contained in:
Jakub Zych
2026-10-15 22:39:18 +02:00
parent fa90e836bc
commit e52b28621b

View File

@@ -1,6 +1,7 @@
package faq_test package faq_test
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@@ -9,8 +10,10 @@ import (
"strings" "strings"
"sync" "sync"
"testing" "testing"
"time"
"git.golem15.com/golem15/sm-faq-plugin/models" "git.golem15.com/golem15/sm-faq-plugin/models"
"git.golem15.com/golem15/summercms/modules/backpack"
"git.golem15.com/golem15/summercms/modules/cooler" "git.golem15.com/golem15/summercms/modules/cooler"
) )
@@ -37,6 +40,9 @@ type purgeReceiver struct {
got []purgeRequest got []purgeRequest
status int status int
probe func() string probe func() string
// drain waits for the queued purges of the app under test; see
// drainFrom.
drain func()
} }
func newPurgeReceiver(t *testing.T) *purgeReceiver { func newPurgeReceiver(t *testing.T) *purgeReceiver {
@@ -67,6 +73,12 @@ func newPurgeReceiver(t *testing.T) *purgeReceiver {
} }
func (r *purgeReceiver) take() []purgeRequest { func (r *purgeReceiver) take() []purgeRequest {
r.mu.Lock()
drain := r.drain
r.mu.Unlock()
if drain != nil {
drain()
}
r.mu.Lock() r.mu.Lock()
defer r.mu.Unlock() defer r.mu.Unlock()
got := r.got got := r.got
@@ -74,6 +86,21 @@ func (r *purgeReceiver) take() []purgeRequest {
return got return got
} }
// drainFrom makes every read of r first wait for the purges queued on app's
// site-cache purger: cooler queues them after commit and sends them in the
// background, so a save's purge is asserted only once it was sent.
func (r *purgeReceiver) drainFrom(t *testing.T, app *backpack.App) {
r.mu.Lock()
defer r.mu.Unlock()
r.drain = func() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := cooler.SiteCacheFromApp(app).Wait(ctx); err != nil {
t.Errorf("waiting for the queued site-cache purge: %v", err)
}
}
}
func (r *purgeReceiver) setStatus(status int) { func (r *purgeReceiver) setStatus(status int) {
r.mu.Lock() r.mu.Lock()
r.status = status r.status = status
@@ -114,6 +141,7 @@ func (r *purgeReceiver) expectOnePurge(t *testing.T, stage, slug string) purgeRe
func TestFaqAdminPurgesSiteCache(t *testing.T) { func TestFaqAdminPurgesSiteCache(t *testing.T) {
recv := newPurgeReceiver(t) recv := newPurgeReceiver(t)
e := bootFAQ(t) e := bootFAQ(t)
recv.drainFrom(t, e.app)
// SiteCacheFromApp reads the keys on the first save, so they can be set // SiteCacheFromApp reads the keys on the first save, so they can be set
// after boot. // after boot.
if err := e.app.Config.Set(cooler.SiteCachePurgeURLKey, recv.srv.URL+purgeTestPath); err != nil { if err := e.app.Config.Set(cooler.SiteCachePurgeURLKey, recv.srv.URL+purgeTestPath); err != nil {