package monthlyusage import ( "context" "fmt" "github.com/gogf/gf/v2/container/gvar" "git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/fullsync/supply" "git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/model" "git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/queue/zset" "git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/testutil" "strings" "testing" "time" ) type telemetryFailRedis struct{ zset.RedisClient } func (r telemetryFailRedis) Eval(ctx context.Context, script string, n int64, keys []string, args []any) (*gvar.Var, error) { if strings.Contains(script, "'supplyObservation'") { return nil, fmt.Errorf("injected telemetry write failure") } return r.RedisClient.Eval(ctx, script, n, keys, args) } func TestSupplyFlushFailureDoesNotBlockProducerDone(t *testing.T) { client := testutil.Redis(t) store, err := zset.New(telemetryFailRedis{client}, "flow:") if err != nil { t.Fatal(err) } scanner := scannerFor([]Card{{ID: 1, ChanKey: "a"}}, 1) p := testProducer(t, scanner, store, Config{SupplyObservation: supply.NewTracker(true)}) if err = p.Produce(context.Background(), model.TrafficUsageMonthlyStartMessage{RunID: "telemetry-failure"}); err != nil { t.Fatal(err) } requireMeta(t, store, "telemetry-failure", true, 1) } func TestSupplyObservesEmptyTargetAndFinalFlush(t *testing.T) { store := testStore(t) scanner := scannerFor([]Card{{ID: 1, ChanKey: "a"}}, 2) scanner.channels = append(scanner.channels, channelMetadata{ChanKey: "empty", TempKey: "sim_yd_v5"}) tracker := supply.NewTracker(true) tracker.ConsumerActive.Store(true) scanner.hook = func(ctx context.Context, key string, last int64) error { if key == "empty" { return sleepContext(ctx, 2200*time.Millisecond) } return nil } p := testProducer(t, scanner, store, Config{SupplyObservation: tracker}) if err := p.Produce(context.Background(), model.TrafficUsageMonthlyStartMessage{RunID: "supply-end", QueryMonth: "202610"}); err != nil { t.Fatal(err) } m, err := store.GetRunMeta(context.Background(), "supply-end") if err != nil { t.Fatal(err) } if !m.ProducerDone || m.SupplyObservation == nil { t.Fatalf("missing final observation %+v", m) } snapshot := m.SupplyObservation if snapshot.Summary.Targets != 2 || snapshot.Summary.Confirmed != 0 { t.Fatalf("bad summary %+v", snapshot) } c := snapshot.Channels[1] if c.Key != "empty" || c.FirstEnqueueMS != nil || c.Termination != "empty_result" || c.Unconfirmed.TotalMS < 900 { t.Fatalf("bad empty target %+v", c) } }