gates / gates (push) Successful in 46s
sent_at is stamped by Client.Report at every send, never by the collector. The hub reads it to tell a wrong box clock. Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
54 lines
1.9 KiB
Go
54 lines
1.9 KiB
Go
package hub
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// R-1384 (D79): the hub tells a wrong box clock by the time stamped at the moment of SENDING. A report whose collect
|
|
// started long ago (an old reported_at) must still leave with a fresh sent_at, and a second send of the SAME report
|
|
// struct must carry a new one — or a report that waited on the box reads as a clock that is behind.
|
|
// COMPANION RED-PROOFS (observed, felhom.eu audits/night-build-2026-11-14/B/redproof-agent-sent-at.txt).
|
|
func TestReport_StampsSentAtAtSending(t *testing.T) {
|
|
var bodies []map[string]any
|
|
c := testClient(func(r *http.Request) (*http.Response, error) {
|
|
raw, _ := io.ReadAll(r.Body)
|
|
var m map[string]any
|
|
if err := json.Unmarshal(raw, &m); err != nil {
|
|
t.Fatalf("body: %v", err)
|
|
}
|
|
bodies = append(bodies, m)
|
|
return httpResp(200, `{"status":"ok"}`), nil
|
|
})
|
|
old := time.Now().Add(-40 * time.Minute).UTC()
|
|
rep := &HostReport{HostID: "h", ReportedAt: old.Format(time.RFC3339), SentAt: old.Format(time.RFC3339Nano)}
|
|
for i := 0; i < 2; i++ {
|
|
if _, err := c.Report(context.Background(), rep); err != nil {
|
|
t.Fatalf("Report: %v", err)
|
|
}
|
|
time.Sleep(5 * time.Millisecond)
|
|
}
|
|
var sent []time.Time
|
|
for i, m := range bodies {
|
|
s, _ := m["sent_at"].(string)
|
|
at, err := time.Parse(time.RFC3339Nano, s)
|
|
if err != nil {
|
|
t.Fatalf("send %d: sent_at = %q, want an RFC3339 time", i, s)
|
|
}
|
|
if d := time.Since(at); d < 0 || d > 5*time.Second {
|
|
t.Errorf("send %d: sent_at is %s old, want the moment of sending (reported_at was 40 minutes old)", i, d)
|
|
}
|
|
if m["reported_at"] != old.Format(time.RFC3339) {
|
|
t.Errorf("send %d: reported_at changed to %v — the collect time is not the send time's to touch", i, m["reported_at"])
|
|
}
|
|
sent = append(sent, at)
|
|
}
|
|
if len(sent) == 2 && !sent[1].After(sent[0]) {
|
|
t.Errorf("the second send carries %s, not after the first %s — the stamp is not taken per send", sent[1], sent[0])
|
|
}
|
|
}
|