package mill
import (
"context"
"errors"
"strings"
"testing"
"tangled.org/core/spindle/models"
"tangled.org/core/spindle/quota"
)
var bigWorkflowRefusal = quota.Reservation{
Reason: quota.ReasonRepoLimit,
Resource: quota.ResourceWorkflowVCPUs,
Scope: quota.ScopeRepo,
Requested: 6,
Limit: 2,
}
func placeBigWorkflow(t *testing.T, verdicts ...quota.Reservation) (*quotaCandidate, error) {
t.Helper()
m, _ := quotaMill(t, &scriptedStore{verdicts: verdicts})
cand := addQuotaCandidate(t, m, "node-a", fixedReport(6, 2048))
wid := models.WorkflowId{PipelineId: models.PipelineId("rkey1"), Name: "build"}
slot, err := m.place(context.Background(), "dummy", wid, testWorkflow("build"))
if err == nil {
slot.Release()
}
if !errors.Is(err, quota.ErrDenied) {
t.Fatalf("place error = %v, want a refusal", err)
}
// a prefix added to the refusal would show up in front of it in the workflow status
if msg := err.Error(); strings.Contains(msg, ": ") || !strings.Contains(msg, "6 vCPUs") || !strings.Contains(msg, "2 vCPUs") {
t.Fatalf("place error = %q, want just the refusal with both amounts", msg)
}
return cand, err
}
func TestPlaceRefusesWorkflowOverItsLimit(t *testing.T) {
cand, _ := placeBigWorkflow(t, bigWorkflowRefusal)
if _, released := cand.counts(); released != 1 {
t.Errorf("executor seat releases = %d, want 1", released)
}
}
func TestPlaceRefusesWorkflowOverItsLimitBehindAQueue(t *testing.T) {
placeBigWorkflow(t, quota.Reservation{Temporary: true, Reason: quota.ReasonRepoLimit}, bigWorkflowRefusal)
}