//go:build unix package gitcmd import ( "context" "errors" "os" "path/filepath" "strings" "testing" "time" ) func fakeGit(t *testing.T, script string) *Runner { t.Helper() path := filepath.Join(t.TempDir(), "git") if err := os.WriteFile(path, []byte("#!/bin/sh\n"+script), 0o755); err != nil { t.Fatal(err) } return New(path, nil) } func TestRemoteProbeRetriesThenSucceeds(t *testing.T) { count := filepath.Join(t.TempDir(), "attempts") t.Setenv("FLATGIT_TEST_ATTEMPTS", count) r := fakeGit(t, `echo attempt >> "$FLATGIT_TEST_ATTEMPTS" if [ "$(wc -l < "$FLATGIT_TEST_ATTEMPTS")" -lt 2 ]; then exit 1; fi `) ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() if err := r.waitRemoteLive(ctx, "test", time.Second); err != nil { t.Fatal(err) } b, err := os.ReadFile(count) if err != nil || strings.Count(string(b), "attempt") != 2 { t.Fatalf("attempts = %q, error = %v", b, err) } } func TestOutputTimeoutKillsTransportHelper(t *testing.T) { // The child inherits stdout/stderr, like git-remote-https. Killing only // the shell would leave cmd.Run waiting for the child's pipes to close. r := fakeGit(t, "sleep 30 &\nwait\n") ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() start := time.Now() _, err := r.Output(ctx, "", "ls-remote") if !errors.Is(err, context.DeadlineExceeded) { t.Fatalf("error = %v", err) } if elapsed := time.Since(start); elapsed > 2*time.Second { t.Fatalf("timeout took %s", elapsed) } } func TestRemoteProbeCancellationStopsRetries(t *testing.T) { count := filepath.Join(t.TempDir(), "attempts") t.Setenv("FLATGIT_TEST_ATTEMPTS", count) r := fakeGit(t, "echo attempt >> \"$FLATGIT_TEST_ATTEMPTS\"\nexit 1\n") ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() if err := r.waitRemoteLive(ctx, "test", time.Second); !errors.Is(err, context.DeadlineExceeded) { t.Fatalf("error = %v", err) } b, err := os.ReadFile(count) if err != nil || strings.Count(string(b), "attempt") != 1 { t.Fatalf("attempts = %q, error = %v", b, err) } }