Files
rvbox/internal/client/spool/quota_test.go
T

70 lines
3.0 KiB
Go

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)
}
}