package domain import ( "errors" "testing" "time" ) func TestValidateProbeRequiresOpaqueFreshNonceAndServerRTT(t *testing.T) { now := time.Unix(100000, 0) valid := ProbeEvidence{OpaqueLocation: []byte("opaque"), Nonce: []byte("nonce"), IssuedAt: now, Region: "EU", ServerRTT: 40 * time.Millisecond} if err := ValidateProbe(valid, []byte("nonce"), now); err != nil { t.Fatal(err) } for name, invalid := range map[string]ProbeEvidence{ "empty location": {Nonce: []byte("nonce"), IssuedAt: now, Region: "EU"}, "wrong nonce": {OpaqueLocation: []byte("opaque"), Nonce: []byte("other"), IssuedAt: now, Region: "EU"}, "stale": {OpaqueLocation: []byte("opaque"), Nonce: []byte("nonce"), IssuedAt: now.Add(-ProbeFreshness - time.Nanosecond), Region: "EU"}, "client chosen negative RTT": {OpaqueLocation: []byte("opaque"), Nonce: []byte("nonce"), IssuedAt: now, Region: "EU", ServerRTT: -time.Millisecond}, } { if err := ValidateProbe(invalid, []byte("nonce"), now); !errors.Is(err, ErrInvalidProbe) { t.Fatalf("%s error = %v", name, err) } } } func TestDiscrepancyQuarantineAndFiveCleanRelease(t *testing.T) { now := time.Unix(100000, 0) var tracker DiscrepancyTracker for i := 0; i < DiscrepancyLimit; i++ { tracker.RecordComparison(40*time.Millisecond, 100*time.Millisecond, now.Add(time.Duration(i)*time.Minute)) } if !tracker.Quarantined { t.Fatal("three discrepancies did not quarantine samples") } if err := tracker.PlacementAllowed(); !errors.Is(err, ErrProbeQuarantined) { t.Fatal("quarantine not enforced") } for i := 0; i < CleanSamplesToRelease; i++ { tracker.RecordComparison(40*time.Millisecond, 45*time.Millisecond, now.Add(time.Hour+time.Duration(i)*time.Minute)) } if tracker.Quarantined { t.Fatal("five clean samples did not release quarantine") } } func TestDiscrepancyThresholdUsesLargerOfAbsoluteAndRelativeLimit(t *testing.T) { now := time.Unix(100000, 0) var tracker DiscrepancyTracker tracker.RecordComparison(200*time.Millisecond, 250*time.Millisecond, now) if tracker.Quarantined { t.Fatal("50ms discrepancy should be allowed when 30%% limit is 60ms") } tracker.RecordComparison(200*time.Millisecond, 270*time.Millisecond, now.Add(time.Minute)) if len(tracker.BadSamples) != 1 { t.Fatal("70ms discrepancy should be recorded") } }