package calendartest import ( "fmt" "sync" "testing" calendar "amadan.net/oficina/calendar/internal/calendar" ) // TestZoneIsSafeUnderConcurrentGarbage drives Zone() the way the // public booking page will: many requests at once, most of them asking // for names nobody has ever heard of. // // Two things must hold. The cache must survive concurrent use — run // this under -race — and a name that failed to load must not be kept, // or a stranger with a ?zone= parameter grows the map without bound. func TestZoneIsSafeUnderConcurrentGarbage(t *testing.T) { var wg sync.WaitGroup for i := 0; i < 100; i++ { wg.Add(1) go func(i int) { defer wg.Done() if _, err := calendar.Zone(fmt.Sprintf("Nowhere/Town%d", i)); err == nil { t.Errorf("Nowhere/Town%d resolved", i) } if _, err := calendar.Zone("Europe/Dublin"); err != nil { t.Errorf("Europe/Dublin: %v", err) } }(i) } wg.Wait() // The bound leaves room for the handful of real zones other tests // in this package load; a hundred garbage names cannot fit inside it. if n, limit := calendar.ZoneCacheSizeForTest(), len(calendar.CommonZones)+5; n > limit { t.Errorf("zone cache holds %d entries after 100 garbage names (limit %d): failures are being cached", n, limit) } } func TestIsCommonZoneKnowsTheList(t *testing.T) { if !calendar.IsCommonZone("Europe/Dublin") { t.Error("Europe/Dublin is not common") } if calendar.IsCommonZone("Nowhere/Town1") { t.Error("Nowhere/Town1 is common") } if calendar.IsCommonZone("") { t.Error("the empty name is common") } }