package engine import ( "context" "errors" "os" "slices" "strings" "sync/atomic" "testing" "tangled.org/core/spindle/models" ) const testCloneToken = "eyJhbGciOiJFUzI1NiJ9.eyJhdWQiOiJkaWQ6cGxjOmJvbHRsZXNzIn0.Y2xvbmU" func cloneTokens(eng *echoEngine, name string) []string { eng.mu.Lock() defer eng.mu.Unlock() var tokens []string for _, step := range eng.steps[name] { tokens = append(tokens, secretValue(step, models.CloneTokenEnvVar)) } return tokens } func TestOnlyTheCloneStepGetsTheCloneToken(t *testing.T) { eng := newEchoEngine() eng.cloneFirst = true logPath := runEchoPipeline(t, eng, &models.Pipeline{ RepoDid: "did:plc:boltless", TrustedSource: true, MintCloneToken: func(context.Context) (string, error) { return testCloneToken, nil }, }, "build") if got := cloneTokens(eng, "build"); !slices.Equal(got, []string{testCloneToken, ""}) { t.Fatalf("clone token per step = %q, want it on the clone step alone", got) } logged, err := os.ReadFile(logPath) if err != nil { t.Fatal(err) } if strings.Contains(string(logged), testCloneToken) { t.Fatal("the persisted log kept the clone token in the clear") } } func TestAForkRunClonesWithoutAskingForAToken(t *testing.T) { eng := newEchoEngine() eng.cloneFirst = true var asked atomic.Bool runEchoPipeline(t, eng, &models.Pipeline{ RepoDid: "did:plc:boltless", TrustedSource: false, MintCloneToken: func(context.Context) (string, error) { asked.Store(true) return testCloneToken, nil }, }, "build") if asked.Load() { t.Fatal("a fork run asked for a token to clone the fork") } if got := cloneTokens(eng, "build"); !slices.Equal(got, []string{"", ""}) { t.Fatalf("clone token per step = %q, want none", got) } } func TestAFailedMintStillClones(t *testing.T) { eng := newEchoEngine() eng.cloneFirst = true runEchoPipeline(t, eng, &models.Pipeline{ RepoDid: "did:plc:boltless", TrustedSource: true, MintCloneToken: func(context.Context) (string, error) { return "", errors.New("mill went away") }, }, "build") if got := cloneTokens(eng, "build"); !slices.Equal(got, []string{"", ""}) { t.Fatalf("clone token per step = %q, want both steps run without one", got) } }