penguin/flatgit

flatgit showcase

internal/gitcmd/gitcmd_test.go

raw ยท 2136 bytes

//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)
	}
}