| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- package service
- import (
- "encoding/binary"
- "testing"
- "time"
- "github.com/mhsanaei/3x-ui/v3/internal/xray"
- )
- func TestWeeklyRenewalSearchFailsClosed(t *testing.T) {
- // Keep a background clock reader so -race catches global timezone writes.
- started, stop, done := make(chan struct{}), make(chan struct{}), make(chan struct{})
- go func() {
- defer close(done)
- _ = time.Now()
- close(started)
- for {
- select {
- case <-stop:
- return
- default:
- _ = time.Now()
- }
- }
- }()
- <-started
- t.Cleanup(func() { close(stop); <-done })
- // Fault injection: a valid TZif with twelve absent Sundays, not a claim
- // about real IANA zones. Each following Monday repeats, so no Sunday returns.
- const transitions = 24
- data := make([]byte, 44+transitions*5+2*6+2)
- copy(data, "TZif")
- binary.BigEndian.PutUint32(data[32:36], transitions)
- binary.BigEndian.PutUint32(data[36:40], 2)
- binary.BigEndian.PutUint32(data[40:44], 2)
- from := time.Date(2026, time.March, 1, 0, 0, 0, 0, time.UTC)
- for week := range 12 {
- at := from.AddDate(0, 0, (week+1)*7).Unix()
- for day := range 2 {
- index := week*2 + day
- binary.BigEndian.PutUint32(data[44+index*4:48+index*4], uint32(at+int64(day)*86400))
- data[44+transitions*4+index] = byte(1 - day)
- }
- }
- binary.BigEndian.PutUint32(data[44+transitions*5+6:48+transitions*5+6], 86400)
- data[len(data)-2] = 'X'
- loc, err := time.LoadLocationFromTZData("Test/SkippedSundays", data)
- if err != nil {
- t.Fatal(err)
- }
- if got := nextWeeklyRenewal(from, 7, loc); !got.Equal(from) {
- t.Fatalf("exhausted weekly search advanced to %s, want unchanged %s", got.Format(time.RFC3339), from.Format(time.RFC3339))
- }
- traffic := &xray.ClientTraffic{ExpiryTime: from.UnixMilli(), ResetWeekday: 7, ResetMax: 4, ResetCount: 2, Enable: false, Up: 111, Down: 222}
- before := *traffic
- expiry, renewals := catchUpClientRenewal(traffic, from.AddDate(0, 0, 28).UnixMilli(), loc)
- if expiry != before.ExpiryTime || renewals != 0 || *traffic != before {
- t.Fatalf("exhausted search changed billing/traffic: expiry=%d renewals=%d traffic=%+v", expiry, renewals, traffic)
- }
- for _, tt := range []struct {
- name string
- now int64
- }{
- {"initial suggestion exhausted", from.UnixMilli()},
- {"catch-up exhausted with allowances left", from.AddDate(0, 3, 0).UnixMilli()},
- } {
- t.Run(tt.name, func(t *testing.T) {
- preview, err := previewClientRenewal(ClientRenewalPreviewRequest{
- ExpiryTime: before.ExpiryTime, ResetWeekday: 7, ResetMax: 4, ResetCount: 2,
- }, tt.now, loc)
- if err == nil || err.Error() != "calendar renewal could not find a future expiry\n" || preview != nil {
- t.Fatalf("failed search preview/error = %+v/%v, want nil/calendar search error", preview, err)
- }
- })
- }
- }
|