feat(mage): add grouped pipelines and test targets

This commit is contained in:
zarazaex69
2026-05-27 12:16:00 +03:00
parent 57db32f70c
commit 3552a51be4

View File

@@ -1,5 +1,31 @@
//go:build mage
// Magefile for olcrtc.
//
// Quick reference:
//
// mage check # build + vet + lint + unit tests (pre-commit)
// mage all # full pre-merge pipeline (check + e2e smoke matrix)
// mage nightly # everything including stress matrix (~6h)
//
// mage build # native binary
// mage cross # all platforms
// mage mobile # Android AAR
//
// mage test # short unit tests
// mage testfull # all unit tests, no real providers
// mage e2e # real-provider smoke matrix
// mage stress # real-provider stress matrix (long)
// mage soak # real-provider throughput soak (long)
// mage localsoak # local in-memory soak (very long, no network)
//
// Tunables (env):
//
// E2E_CARRIERS, E2E_TRANSPORTS, E2E_TIMEOUT
// E2E_STRESS, E2E_STRESS_DURATION
// STRESS_BULK_DURATION, STRESS_ECHO_DURATION, STRESS_CASE_TIMEOUT, STRESS_TIMEOUT
// SOAK_CARRIERS, SOAK_TRANSPORTS, SOAK_DURATION, SOAK_CHAOS
package main
import (
@@ -14,11 +40,14 @@ import (
"github.com/magefile/mage/sh"
)
// Default target when invoked as `mage` with no args.
//
//nolint:gochecknoglobals // mage requires a package-level Default symbol.
var Default = Help
const (
module = "github.com/openlibrecommunity/olcrtc"
buildDir = "build"
ldflags = "-s -w"
goVersion = "1.25"
buildDir = "build"
ldflags = "-s -w"
)
var (
@@ -27,14 +56,50 @@ var (
goarch = envOr("GOARCH", runtime.GOARCH)
)
// Build builds the olcrtc CLI binary.
func Build() error {
mg.Deps(BuildCLI)
return nil
// ─────────────────────────────────────────────────────────────────────────────
// Pipelines
// ─────────────────────────────────────────────────────────────────────────────
// Help lists every target in mage's default style. This is what runs when
// you invoke `mage` with no arguments. For grouped/annotated docs see the
// magefile header.
func Help() error {
return sh.RunV("mage", "-l")
}
// BuildCLI builds the olcrtc server/client binary.
func BuildCLI() error {
// Check runs the fast pre-commit pipeline: build + vet + lint + unit tests.
// Use this before every commit.
func Check() {
mg.SerialDeps(Build, Vet, Lint, TestFull)
}
// All runs the full pre-merge pipeline: Check + the real-provider smoke
// matrix. Stress and soak are NOT included - run them explicitly when
// needed (see Nightly for everything).
func All() {
mg.SerialDeps(Check, E2e)
}
// Nightly runs everything: All + stress matrix. Expect multi-hour runtime;
// intended for the nightly CI job or manual deep validation.
func Nightly() {
mg.SerialDeps(All, Stress)
}
// Everything runs literally every test stage: Nightly + real soak + local
// soak. Expect 12+ hours; this is for "I want maximum confidence before
// shipping" runs, not regular development. Tune SOAK_DURATION etc. if you
// need a shorter window.
func Everything() {
mg.SerialDeps(Nightly, Soak, LocalSoak)
}
// ─────────────────────────────────────────────────────────────────────────────
// Build
// ─────────────────────────────────────────────────────────────────────────────
// Build builds the olcrtc CLI binary for the host platform.
func Build() error {
mg.Deps(Deps)
return buildBinary("olcrtc", "./cmd/olcrtc", goos, goarch)
}
@@ -61,20 +126,50 @@ func Cross() error {
}
}
fmt.Printf("✅ Built %d platform(s)\n", len(targets))
fmt.Printf("✅ built %d platform(s)\n", len(targets))
return nil
}
// Mobile builds the Android AAR via gomobile.
func Mobile() error {
if err := ensureTool("gomobile"); err != nil {
return fmt.Errorf("gomobile not found: run 'go install golang.org/x/mobile/cmd/gomobile@latest && gomobile init'")
}
if err := ensureBuildDir(); err != nil {
return err
}
return sh.RunV("gomobile", "bind",
"-target=android",
"-androidapi", "21",
"-ldflags", "-s -w -checklinkname=0",
"-o", filepath.Join(buildDir, "olcrtc.aar"),
"./mobile",
)
}
// ─────────────────────────────────────────────────────────────────────────────
// Container
// ─────────────────────────────────────────────────────────────────────────────
// Docker builds the image using docker.
func Docker() error {
tag := envOr("DOCKER_TAG", "olcrtc:latest")
return sh.RunV("docker", "build", "-t", tag, ".")
}
// Podman builds the image using podman.
func Podman() error {
tag := envOr("DOCKER_TAG", "olcrtc:latest")
return sh.RunV("podman", "build", "-t", tag, ".")
}
// Docker builds the image using docker.
func Docker() error {
tag := envOr("DOCKER_TAG", "olcrtc:latest")
return sh.RunV("docker", "build", "-t", tag, ".")
// ─────────────────────────────────────────────────────────────────────────────
// Quality
// ─────────────────────────────────────────────────────────────────────────────
// Vet runs go vet on the whole module.
func Vet() error {
return sh.RunV(goexe, "vet", "./...")
}
// Lint runs golangci-lint.
@@ -85,19 +180,31 @@ func Lint() error {
return sh.RunV("golangci-lint", "run", "./...")
}
// Test runs all unit tests (short mode, skips long-running chaos/throughput tests).
// Tidy runs go mod tidy and verifies modules.
func Tidy() error {
if err := sh.RunV(goexe, "mod", "tidy"); err != nil {
return err
}
return sh.RunV(goexe, "mod", "verify")
}
// ─────────────────────────────────────────────────────────────────────────────
// Tests
// ─────────────────────────────────────────────────────────────────────────────
// Test runs unit tests in -short mode (skips long-running tests).
func Test() error {
return sh.RunV(goexe, "test", "-race", "-count=1", "-short", "./...")
}
// TestFull runs all tests including chaos and throughput baselines (no real providers).
// TestFull runs all unit + fast e2e tests with race detector. No real providers.
func TestFull() error {
return sh.RunV(goexe, "test", "-race", "-count=1", "-timeout", "10m", "./...")
}
// E2E runs the real-provider e2e matrix plus stress tests.
// E2e runs the real-provider smoke matrix.
// Configure via env: E2E_CARRIERS, E2E_TRANSPORTS, E2E_TIMEOUT, E2E_STRESS.
func E2E() error {
func E2e() error {
args := []string{"test", "-race", "-count=1", "-v", "-timeout", "30m"}
args = append(args, "-olcrtc.real-e2e=true")
if carriers := os.Getenv("E2E_CARRIERS"); carriers != "" {
@@ -119,6 +226,35 @@ func E2E() error {
return sh.RunV(goexe, args...)
}
// Stress runs the real-provider stress matrix on every carrier × transport pair.
// Defaults match the long nightly profile (15m bulk + 15m echo, 35m hard cap per case).
// Override via env: STRESS_BULK_DURATION, STRESS_ECHO_DURATION, STRESS_CASE_TIMEOUT,
// STRESS_TIMEOUT, E2E_CARRIERS, E2E_TRANSPORTS.
func Stress() error {
bulk := envOr("STRESS_BULK_DURATION", "15m")
echo := envOr("STRESS_ECHO_DURATION", "15m")
caseTO := envOr("STRESS_CASE_TIMEOUT", "35m")
overall := envOr("STRESS_TIMEOUT", "6h")
args := []string{"test", "-count=1", "-v",
"-timeout", overall,
"-run", "^TestRealProviderTransportStress$",
"-olcrtc.real-e2e=true",
"-olcrtc.stress=true",
"-olcrtc.stress-bulk-duration=" + bulk,
"-olcrtc.stress-duration=" + echo,
"-olcrtc.stress-case-timeout=" + caseTO,
}
if carriers := os.Getenv("E2E_CARRIERS"); carriers != "" {
args = append(args, "-olcrtc.real-carriers="+carriers)
}
if transports := os.Getenv("E2E_TRANSPORTS"); transports != "" {
args = append(args, "-olcrtc.real-transports="+transports)
}
args = append(args, "./internal/e2e/...")
return sh.RunV(goexe, args...)
}
// Soak runs the real-provider throughput soak test.
// Configure via env: SOAK_CARRIERS, SOAK_TRANSPORTS, SOAK_DURATION.
func Soak() error {
@@ -127,13 +263,13 @@ func Soak() error {
duration := envOr("SOAK_DURATION", "10m")
args := []string{"test", "-count=1", "-v",
"-timeout", "4h",
"-timeout", "12h",
"-run", "^TestRealThroughputSoak$",
"-olcrtc.real-e2e=true",
"-olcrtc.real-soak=true",
"-olcrtc.real-soak-carrier=" + carriers,
"-olcrtc.real-soak-transport=" + transports,
"-olcrtc.real-soak-duration=" + duration,
"-run", "^TestRealThroughputSoak$",
"./internal/e2e/...",
}
return sh.RunV(goexe, args...)
@@ -147,11 +283,11 @@ func LocalSoak() error {
chaos := os.Getenv("SOAK_CHAOS")
args := []string{"test", "-count=1", "-v",
"-timeout", "4h",
"-timeout", "12h",
"-run", "^TestLocalThroughputSoak$",
"-olcrtc.local-soak=true",
"-olcrtc.local-soak-transport=" + transports,
"-olcrtc.local-soak-duration=" + duration,
"-run", "^TestLocalThroughputSoak$",
}
if chaos != "" {
args = append(args, "-olcrtc.local-soak-chaos="+chaos)
@@ -160,12 +296,13 @@ func LocalSoak() error {
return sh.RunV(goexe, args...)
}
// Deps downloads and tidies Go module dependencies.
// ─────────────────────────────────────────────────────────────────────────────
// Utility
// ─────────────────────────────────────────────────────────────────────────────
// Deps downloads Go module dependencies.
func Deps() error {
if err := sh.RunV(goexe, "mod", "download"); err != nil {
return err
}
return sh.RunV(goexe, "mod", "tidy")
return sh.RunV(goexe, "mod", "download")
}
// Clean removes build artifacts.
@@ -173,22 +310,9 @@ func Clean() error {
return os.RemoveAll(buildDir)
}
// Mobile builds the Android AAR via gomobile.
func Mobile() error {
if err := ensureTool("gomobile"); err != nil {
return fmt.Errorf("gomobile not found: run 'go install golang.org/x/mobile/cmd/gomobile@latest && gomobile init'")
}
if err := ensureBuildDir(); err != nil {
return err
}
return sh.RunV("gomobile", "bind",
"-target=android",
"-androidapi", "21",
"-ldflags", "-s -w -checklinkname=0",
"-o", filepath.Join(buildDir, "olcrtc.aar"),
"./mobile",
)
}
// ─────────────────────────────────────────────────────────────────────────────
// Helpers (unexported, not visible as targets)
// ─────────────────────────────────────────────────────────────────────────────
func buildBinary(name, pkg, os_, arch string) error {
if err := ensureBuildDir(); err != nil {
@@ -215,7 +339,6 @@ func buildBinary(name, pkg, os_, arch string) error {
}
args := []string{"build", "-trimpath", "-ldflags", flags, "-o", out, pkg}
return sh.RunWithV(env, goexe, args...)
}