package spool import ( "context" "errors" "path/filepath" "testing" "time" ) func TestCheckReservationQuotaTiers_BH_RET_01(t *testing.T) { t.Parallel() limits := QuotaLimits{HardAllocationBytes: 1_000, CommandOutputBytes: 1_200, CommandTotalBytes: 2_000, ClientTotalBytes: 3_000, CloseoutReserveBytes: 400} cases := []struct { name string state ReservationState request ReservationRequest tier CapacityTier }{ {name: "hard allocation", request: ReservationRequest{ChargedBytes: 1_001}, tier: CapacityTierHardMaximum}, {name: "output", state: ReservationState{CommandOutputCharged: 1_100}, request: ReservationRequest{ChargedBytes: 101, Output: true}, tier: CapacityTierCommandOut}, {name: "normal preserves closeout", state: ReservationState{CommandTotalCharged: 1_500, CloseoutRemaining: 400}, request: ReservationRequest{ChargedBytes: 101}, tier: CapacityTierCommand}, {name: "client", state: ReservationState{ClientTotalCharged: 2_900, CloseoutRemaining: 400}, request: ReservationRequest{ChargedBytes: 101}, tier: CapacityTierClient}, } for _, test := range cases { t.Run(test.name, func(t *testing.T) { _, err := CheckReservation(limits, test.state, test.request) var capacity *CapacityError if !errors.As(err, &capacity) || capacity.Tier != test.tier { t.Fatalf("CheckReservation error = %v, want tier %q", err, test.tier) } }) } decision, err := CheckReservation(limits, ReservationState{CommandTotalCharged: 1_500, CloseoutRemaining: 400}, ReservationRequest{ChargedBytes: 400, UseCloseout: true}) if err != nil || decision.CloseoutRemaining != 0 || decision.CommandTotalCharged != 1_900 { t.Fatalf("closeout reservation = %#v, %v", decision, err) } } func TestSpoolAcknowledgementReleasesQuota_HP_CLIENT_08(t *testing.T) { t.Parallel() ctx := context.Background() limits := QuotaLimits{HardAllocationBytes: 1_000, CommandOutputBytes: 800, CommandTotalBytes: 2_000, ClientTotalBytes: 3_000, CloseoutReserveBytes: 400} store, err := Open(ctx, Options{DataDir: filepath.Join(t.TempDir(), "spool"), BusyTimeout: time.Second, QuotaLimits: limits}) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = store.Close() }) issue := testUUID(t, "019c46f1-1d02-7000-8000-000000000021") if _, err := store.AcceptCommand(ctx, testCommand(issue, []byte("quota")), time.Now().UTC()); err != nil { t.Fatal(err) } input := EventInput{Kind: 1, Compression: 1, RawBytes: 200, Payload: make([]byte, 200), Output: true, CreatedAt: time.Now().UTC()} if _, err := store.AppendEvent(ctx, issue, input); err != nil { t.Fatal(err) } if _, err := store.AppendEvent(ctx, issue, input); !errors.Is(err, ErrCapacityExhausted) { t.Fatalf("second output append error = %v, want ErrCapacityExhausted", err) } if _, err := store.AssignSendWindow(ctx, issue, 1, 1<<20); err != nil { t.Fatal(err) } if err := store.Ack(ctx, issue, 1); err != nil { t.Fatal(err) } if _, err := store.AppendEvent(ctx, issue, input); err != nil { t.Fatalf("append after acknowledgement did not release quota: %v", err) } }