Skip to content
quarry Artifact [564e175f5a]
Login

Artifact [564e175f5a]

Artifact 564e175f5af5744cdda4efb869cb4e0b7ebcc66031a62d8af8a37fc0783dcb17:


package runner

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"testing"
)

// A RUNNER THAT STARTS AFTER ONE WAS STOPPED MID-JOB HAS EVERY JOB USER
// HAND BACK EVERY WORKSPACE AND STALE TEMP DIR (#419).
//
// The stopped runner's job left directories only its job user could
// read; the new runner ended that user's processes and nothing more, so
// every checkout into that workspace failed until someone fixed it by
// hand. sudo is a recorder here: the test reads which commands the
// runner asked for, as which user, on which directory.
func TestStartupHandsBackWorkspacesAndStaleTempDirs(t *testing.T) {
	bin, work, tmp := t.TempDir(), t.TempDir(), filepath.Join(t.TempDir(), "qr")
	rec := filepath.Join(bin, "calls")
	fake := "#!/bin/sh\necho \"$*\" >> " + rec + "\nexit 0\n"
	if err := os.WriteFile(filepath.Join(bin, "sudo"), []byte(fake), 0o755); err != nil {
		t.Fatal(err)
	}
	t.Setenv("PATH", bin+string(os.PathListSeparator)+os.Getenv("PATH"))
	for _, d := range []string{"app.job-0", "app.job-1"} {
		if err := os.MkdirAll(filepath.Join(work, "ws", d), 0o755); err != nil {
			t.Fatal(err)
		}
	}
	if err := os.WriteFile(filepath.Join(work, "ws", "not-a-dir"), nil, 0o644); err != nil {
		t.Fatal(err)
	}
	// A task dir of a runner that no longer runs: pid 1 is never this
	// test, and a pid this large is never alive.
	stale := filepath.Join(tmp, fmt.Sprintf("%s%d-123", taskPrefix, 1<<30))
	if err := os.MkdirAll(stale, 0o755); err != nil {
		t.Fatal(err)
	}
	r, err := New(Config{
		Bridge: "http://127.0.0.1:1", Token: "WT", Tasks: []string{"t"}, MaxTasks: 2,
		WorkDir: work, TempRoot: tmp, Checkout: appCheckout{}, JobUsers: []string{"qa", "qb"}, Self: "/bin/true",
		Logf: t.Logf,
	})
	if err != nil {
		t.Fatalf("FAIL: New: %v", err)
	}
	if err := r.sweepTemp(); err != nil {
		t.Fatalf("FAIL: sweepTemp: %v", err)
	}
	r.handBackWorkspaces()
	b, _ := os.ReadFile(rec)
	calls := string(b)
	for _, u := range []string{"qa", "qb"} {
		for _, d := range []string{filepath.Join(work, "ws", "app.job-0"), filepath.Join(work, "ws", "app.job-1"), stale} {
			want := "-n -u " + u + " -- chmod -R g+rwX " + d
			if !strings.Contains(calls, want+"\n") {
				t.Errorf("FAIL: user %s was not asked to hand back %s", u, d)
			}
		}
	}
	if strings.Contains(calls, "not-a-dir") {
		t.Errorf("FAIL: a plain file under ws was handed to chmod -R")
	}
	if _, err := os.Lstat(stale); !os.IsNotExist(err) {
		t.Errorf("FAIL: the stale temp dir is still there: %v", err)
	}
	t.Log("ok")
}