Ctrl K
ComunidadGuías…

scripts/nightly_due_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package scripts_test

import (
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
	"time"
)

type nightlyRun struct {
	id        string
	finished  time.Time
	succeeded string
}

func ranTheNightly(id string, ago time.Duration) nightlyRun {
	return nightlyRun{id: id, finished: time.Now().UTC().Add(-ago), succeeded: "97"}
}

func stoppedAtTheGuard(id string, ago time.Duration) nightlyRun {
	return nightlyRun{id: id, finished: time.Now().UTC().Add(-ago), succeeded: "0"}
}

func runNightlyDue(t *testing.T, event string, runs ...nightlyRun) (string, []string) {
	t.Helper()
	if runtime.GOOS == "windows" {
		t.Skip("the nightly guard runs in Linux CI jobs")
	}
	dir := t.TempDir()
	bin := filepath.Join(dir, "bin")
	if err := os.Mkdir(bin, 0o700); err != nil {
		t.Fatalf("create fake binary directory: %v", err)
	}
	gh := `#!/usr/bin/env bash
set -euo pipefail
printf '%s\n' "$*" >> "$GH_CALLS"
if [ "$1 $2" = "run list" ]; then
    printf '%s' "$GH_RUNS"
    exit 0
fi
succeeded="GH_SUCCEEDED_$3"
printf '%s\n' "${!succeeded}"
`
	if err := os.WriteFile(filepath.Join(bin, "gh"), []byte(gh), 0o700); err != nil {
		t.Fatalf("write fake gh: %v", err)
	}
	calls := filepath.Join(dir, "calls")
	if err := os.WriteFile(calls, nil, 0o600); err != nil {
		t.Fatalf("seed call log: %v", err)
	}
	var listed strings.Builder
	env := append(
		os.Environ(),
		"PATH="+bin+string(os.PathListSeparator)+os.Getenv("PATH"),
		"GH_CALLS="+calls,
		"GITHUB_EVENT_NAME="+event,
		"NIGHTLY_WINDOW_HOURS=20",
	)
	for _, run := range runs {
		listed.WriteString(run.id + " " + run.finished.Format("2006-01-02T15:04:05Z") + "\n")
		env = append(env, "GH_SUCCEEDED_"+run.id+"="+run.succeeded)
	}
	env = append(env, "GH_RUNS="+listed.String())
	command := exec.Command("bash", "nightly-due.sh")
	command.Env = env
	out, err := command.Output()
	if err != nil {
		t.Fatalf("run nightly-due.sh: %v", err)
	}
	raw, readErr := os.ReadFile(calls)
	if readErr != nil {
		t.Fatalf("read gh calls: %v", readErr)
	}
	logged := strings.Split(strings.TrimSpace(string(raw)), "\n")
	if len(logged) == 1 && logged[0] == "" {
		logged = nil
	}
	return strings.TrimSpace(string(out)), logged
}

func TestNightlyIsDueWhenNoRunHasEverSucceeded(t *testing.T) {
	verdict, calls := runNightlyDue(t, "push")
	if verdict != "true" {
		t.Fatalf("verdict = %q, want true", verdict)
	}
	if len(calls) != 1 {
		t.Fatalf("gh calls = %q, want one lookup", calls)
	}
}

func TestNightlyIsDueWhenTheLastRunAgedOutOfTheWindow(t *testing.T) {
	verdict, _ := runNightlyDue(t, "push", ranTheNightly("40845046601", 21*time.Hour))
	if verdict != "true" {
		t.Fatalf("verdict = %q, want true for a run 21h ago", verdict)
	}
}

func TestNightlyIsNotDueInsideTheWindow(t *testing.T) {
	verdict, _ := runNightlyDue(t, "push", ranTheNightly("40845046601", 3*time.Hour))
	if verdict != "false" {
		t.Fatalf("verdict = %q, want false for a run 3h ago", verdict)
	}
}

func TestNightlyIsNotDueOnTheHourItLastSucceeded(t *testing.T) {
	verdict, _ := runNightlyDue(t, "schedule", ranTheNightly("40845046601", 19*time.Hour+59*time.Minute))
	if verdict != "false" {
		t.Fatalf("verdict = %q, want false just inside the window", verdict)
	}
}

func TestAnExplicitDispatchSkipsTheWindowAndAsksGitHubNothing(t *testing.T) {
	for _, event := range []string{"workflow_dispatch", "repository_dispatch"} {
		verdict, calls := runNightlyDue(t, event, ranTheNightly("40845046601", 0))
		if verdict != "true" {
			t.Fatalf("%s verdict = %q, want true", event, verdict)
		}
		if calls != nil {
			t.Fatalf("%s made gh calls %q, want none", event, calls)
		}
	}
}

func TestTheScheduleIsSubjectToTheSameWindowAsAPush(t *testing.T) {
	verdict, calls := runNightlyDue(t, "schedule", ranTheNightly("40845046601", 21*time.Hour))
	if verdict != "true" {
		t.Fatalf("verdict = %q, want true", verdict)
	}
	if len(calls) != 2 {
		t.Fatalf("gh calls = %q, want the list and one look at its newest run", calls)
	}
}

func TestARunTheGuardStoppedDoesNotRestartTheWindow(t *testing.T) {
	verdict, calls := runNightlyDue(
		t,
		"schedule",
		stoppedAtTheGuard("38885394510", 2*time.Hour),
		ranTheNightly("38881002417", 21*time.Hour),
	)
	if verdict != "true" {
		t.Fatalf("verdict = %q, want true: the nightly last ran 21h ago, only its guard ran 2h ago", verdict)
	}
	if len(calls) != 3 {
		t.Fatalf("gh calls = %q, want the list and both runs looked at", calls)
	}
	want := []string{"run view 38885394510", "run view 38881002417"}
	for index, prefix := range want {
		if !strings.HasPrefix(calls[index+1], prefix) {
			t.Fatalf("gh call %d = %q, want it to start with %q", index+1, calls[index+1], prefix)
		}
	}
}

func TestTheNewestRunThatGotPastTheGuardDecides(t *testing.T) {
	verdict, calls := runNightlyDue(
		t,
		"push",
		stoppedAtTheGuard("38885394510", time.Hour),
		ranTheNightly("38881002417", 3*time.Hour),
		ranTheNightly("38750118803", 27*time.Hour),
	)
	if verdict != "false" {
		t.Fatalf("verdict = %q, want false: the nightly ran 3h ago", verdict)
	}
	if len(calls) != 3 {
		t.Fatalf("gh calls = %q, want the list and two runs looked at, stopping at the first that ran", calls)
	}
}

func TestOnlyRunsTheGuardStoppedLeaveNothingToAgeOut(t *testing.T) {
	verdict, calls := runNightlyDue(
		t,
		"push",
		stoppedAtTheGuard("38885394510", time.Hour),
		stoppedAtTheGuard("38870021954", 5*time.Hour),
	)
	if verdict != "true" {
		t.Fatalf("verdict = %q, want true when no listed run got past the guard", verdict)
	}
	if len(calls) != 3 {
		t.Fatalf("gh calls = %q, want the list and both runs looked at", calls)
	}
}