package oltp
import (
"testing"
"time"
)
// A chat file's ticket that expires unspent is the sweep's to take, with
// its bytes: the read path's expiry leaves chat's rows alone, an expired
// chat ticket no longer answers, and ExpireChatUploads hands back each
// one whose bytes no live ticket still waits on (#380).
func TestExpiredChatUploadsAreTheSweeps(t *testing.T) {
db := testDB(t)
put := func(family, sha string, age time.Duration) string {
t.Helper()
id, err := db.PutUploadTicket(UploadTicket{Repo: "r", Family: family, Name: sha + ".png", Size: 1, Type: "image/png", SHA256: sha, Who: "ann"})
if err != nil {
t.Fatal(err)
}
if _, err := db.w.Exec(`UPDATE upload_ticket SET created = ? WHERE id = ?`,
time.Now().UTC().Add(-age).Format(time.RFC3339), id); err != nil {
t.Fatal(err)
}
return id
}
gone := put("chat", "aaaa", 2*time.Hour)
shared := put("chat", "bbbb", 2*time.Hour)
put("chat", "bbbb", time.Minute) // the same bytes, pasted again just now
live := put("chat", "cccc", time.Minute)
put("forum", "dddd", 2*time.Hour)
if _, ok, _ := db.UploadTicket(gone); ok {
t.Error("FAIL: an expired chat ticket still answers")
}
if _, ok, _ := db.UploadTicket(live); !ok {
t.Error("FAIL: a live chat ticket does not answer")
}
var n int
db.db.QueryRow(`SELECT count(*) FROM upload_ticket WHERE family = 'chat'`).Scan(&n)
if n != 4 {
t.Fatalf("FAIL: the read path's expiry took chat rows: %d left of 4", n)
}
out, err := db.ExpireChatUploads()
if err != nil {
t.Fatal(err)
}
if len(out) != 1 || out[0].ID != gone || out[0].SHA256 != "aaaa" {
t.Fatalf("FAIL: expired for the sweep: %+v, want only %s (bbbb has a live ticket)", out, gone)
}
if _, ok, _ := db.UploadTicket(shared); ok {
t.Error("FAIL: the expired ticket for shared bytes was kept")
}
if _, ok, _ := db.UploadTicket(live); !ok {
t.Error("FAIL: the sweep took a live ticket")
}
t.Log("ok: expired chat tickets go to the sweep, live bytes stay")
}