Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions test.mk
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,12 @@ run-integration-tests-v2: ## Bring up the gnmi-gen suite env, run all suites, te
exit $$status

# Nightly / local-only fleet suite. Not wired into CI.
# SCALE_TARGETS defaults to 200; override e.g. SCALE_TARGETS=50 make integration-test-scale
SCALE_TARGETS ?= 200
# SCALE_TARGETS defaults to 200, SCALE_REPLICAS to 4.
# e.g. SCALE_TARGETS=50 SCALE_REPLICAS=2 make integration-test-scale
SCALE_TARGETS ?= 200
SCALE_REPLICAS ?= 4
.PHONY: integration-test-scale
integration-test-scale: integration-env-check ## Run 013-scale (sets RUN_SCALE=1)
RUN_SCALE=1 SCALE_TARGETS=$(SCALE_TARGETS) go test -tags=integration -count=1 -timeout 45m -v ./$(IT_SUITE_DIR)/013-scale/...
RUN_SCALE=1 SCALE_TARGETS=$(SCALE_TARGETS) SCALE_REPLICAS=$(SCALE_REPLICAS) \
go test -tags=integration -count=1 -timeout 45m -v ./$(IT_SUITE_DIR)/013-scale/...

9 changes: 6 additions & 3 deletions test/integration/harness/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ type Options struct {
GnmiGenConfigData []byte
// Baseline fixtures applied after the simulator is up, before m.Run.
Baseline []string
// BaselineVars are merged into every baseline fixture template (on top of
// the harness base vars). Used for suite-wide knobs like replica count.
BaselineVars map[string]any
// RequireTargets are simulated targets that must report "up" before tests
// start.
RequireTargets []string
Expand Down Expand Up @@ -107,7 +110,7 @@ func New(opts Options) (*Suite, error) {
}

for _, f := range opts.Baseline {
if err := s.applyBaseline(f); err != nil {
if err := s.applyBaseline(f, opts.BaselineVars); err != nil {
return s, fmt.Errorf("applying baseline %s: %w", f, err)
}
}
Expand Down Expand Up @@ -306,12 +309,12 @@ func (s *Suite) waitTargetsUp(names []string) error {
}
}

func (s *Suite) applyBaseline(path string) error {
func (s *Suite) applyBaseline(path string, vars map[string]any) error {
b, err := os.ReadFile(path)
if err != nil {
return err
}
_, err = s.K8s.applyYAML(string(b), nil)
_, err = s.K8s.applyYAML(string(b), vars)
return err
}

Expand Down
5 changes: 3 additions & 2 deletions test/integration/suite/013-scale/fixtures/baseline.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Shared props for 013-scale. The 200 Target CRs are generated in AfterBaseline.
# Shared props for 013-scale. Target CRs are generated in AfterBaseline.
# Cluster replicas come from SCALE_REPLICAS via BaselineVars.
apiVersion: v1
kind: Secret
metadata:
Expand All @@ -24,7 +25,7 @@ metadata:
name: c1
spec:
image: {{ .GnmicImage }}
replicas: 4
replicas: {{ .Replicas }}
api:
restPort: 7890
resources:
Expand Down
33 changes: 20 additions & 13 deletions test/integration/suite/013-scale/scale_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
// single-target churn cost, sustained membership change, and mass reboot.
//
// Gated behind RUN_SCALE=1 (see TestMain). Not part of the default CI lane.
// Fleet size defaults to 200 and is overridable with SCALE_TARGETS.
// Fleet size defaults to 200 (SCALE_TARGETS) and collector pods to 4
// (SCALE_REPLICAS).
package scale

import (
Expand All @@ -29,13 +30,13 @@ const (
cluster = "c1"
pipeline = "fleet"
output = "prom"
replicas = 4
)

var (
s *harness.Suite
targets []string
fleetN int
replicas int
spareSim string
sparePort int
minPerPod int
Expand All @@ -47,9 +48,14 @@ func TestMain(m *testing.M) {
fmt.Fprintln(os.Stderr, "013-scale: skipped (set RUN_SCALE=1 to enable)")
os.Exit(0)
}
fleetN = scaleTargets()
if fleetN < 4 {
fmt.Fprintf(os.Stderr, "013-scale: SCALE_TARGETS=%d too small (min 4)\n", fleetN)
fleetN = envInt("SCALE_TARGETS", 200)
replicas = envInt("SCALE_REPLICAS", 4)
if replicas < 1 {
fmt.Fprintf(os.Stderr, "013-scale: SCALE_REPLICAS=%d too small (min 1)\n", replicas)
os.Exit(1)
}
if fleetN < replicas {
fmt.Fprintf(os.Stderr, "013-scale: SCALE_TARGETS=%d < SCALE_REPLICAS=%d\n", fleetN, replicas)
os.Exit(1)
}
spareSim = fmt.Sprintf("dev-%d", fleetN+1)
Expand All @@ -59,27 +65,28 @@ func TestMain(m *testing.M) {
for i := 1; i <= fleetN; i++ {
targets[i-1] = fmt.Sprintf("dev-%d", i)
}
fmt.Fprintf(os.Stderr, "[harness] suite 013-scale: SCALE_TARGETS=%d spare=%s placement=%d..%d per pod\n",
fleetN, spareSim, minPerPod, maxPerPod)
fmt.Fprintf(os.Stderr, "[harness] suite 013-scale: SCALE_TARGETS=%d SCALE_REPLICAS=%d spare=%s placement=%d..%d per pod\n",
fleetN, replicas, spareSim, minPerPod, maxPerPod)

require := append(append([]string{}, targets...), spareSim)
os.Exit(harness.RunSuite(m, harness.Options{
Name: "013-scale",
GnmiGenConfigData: renderGnmiGenConfig(fleetN + 1),
RequireTargets: require,
Baseline: []string{"fixtures/baseline.yaml"},
BaselineVars: map[string]any{"Replicas": replicas},
AfterBaseline: applyFleetTargets,
}, &s))
}

func scaleTargets() int {
v := os.Getenv("SCALE_TARGETS")
func envInt(name string, def int) int {
v := os.Getenv(name)
if v == "" {
return 200
return def
}
n, err := strconv.Atoi(v)
if err != nil || n <= 0 {
return 200
return def
}
return n
}
Expand Down Expand Up @@ -147,12 +154,12 @@ func waitFleetReady(t *testing.T) time.Duration {
harness.WaitClusterCounts(t, s.K8s, cluster, harness.ClusterCounts{
TargetsCount: harness.I32(int32(fleetN)),
UnassignedTargets: harness.I32(0),
ReadyReplicas: harness.I32(replicas),
ReadyReplicas: harness.I32(int32(replicas)),
})
s.GnmiGen.WaitFleetStreams(t, harness.Long, 1, targets)
s.GnmiGen.WaitStreams(t, spareSim, 0)
elapsed := time.Since(start)
t.Logf("fleet converged in %s (SCALE_TARGETS=%d)", elapsed, fleetN)
t.Logf("fleet converged in %s (SCALE_TARGETS=%d SCALE_REPLICAS=%d)", elapsed, fleetN, replicas)
return elapsed
}

Expand Down