Git backed by object storage because you can't stop me
git object-storage kefka
0

Configure Feed

Select the types of activity you want to include in your feed.

objgit / cmd / objgitd / daemon_test.go
3.5 kB 134 lines
1package main 2 3import ( 4 "context" 5 "net" 6 "os" 7 "os/exec" 8 "path/filepath" 9 "strings" 10 "testing" 11 "time" 12 13 "github.com/go-git/go-billy/v6/memfs" 14 "github.com/go-git/go-git/v6/plumbing/transport" 15) 16 17// TestDaemonPushCreatesRepo reproduces "git push git://host/new.git" against a 18// path that does not exist yet. The daemon must create the bare repository on 19// demand and the result must clone back cleanly. 20func TestDaemonPushCreatesRepo(t *testing.T) { 21 if _, err := exec.LookPath("git"); err != nil { 22 t.Skip("git not installed") 23 } 24 25 fs := memfs.New() 26 d := &daemon{ 27 fs: fs, 28 loader: transport.NewFilesystemLoader(fs, false), 29 allowPush: true, 30 } 31 32 ctx, cancel := context.WithCancel(context.Background()) 33 defer cancel() 34 35 ln, err := net.Listen("tcp", "127.0.0.1:0") 36 if err != nil { 37 t.Fatalf("listen: %v", err) 38 } 39 40 srvErr := make(chan error, 1) 41 go func() { srvErr <- d.Serve(ctx, ln) }() 42 43 remote := "git://" + ln.Addr().String() + "/test.git" 44 45 work := t.TempDir() 46 runGit(t, work, "init", "-b", "main") 47 runGit(t, work, "config", "user.email", "test@example.com") 48 runGit(t, work, "config", "user.name", "Test") 49 runGit(t, work, "commit", "--allow-empty", "-m", "initial") 50 51 // The repository does not exist yet; the push must create it. 52 runGit(t, work, "push", remote, "main") 53 54 if _, err := fs.Stat("/test.git/config"); err != nil { 55 t.Fatalf("expected bare repo to be created on push, but %q is missing: %v", "/test.git/config", err) 56 } 57 58 // Round-trip: a clone must recover the pushed commit. 59 dst := t.TempDir() 60 runGit(t, dst, "clone", remote, "cloned") 61 head := strings.TrimSpace(runGit(t, filepath.Join(dst, "cloned"), "rev-parse", "HEAD")) 62 if head == "" { 63 t.Fatal("cloned repository has no HEAD") 64 } 65 66 cancel() 67 _ = ln.Close() 68 select { 69 case <-srvErr: 70 case <-time.After(2 * time.Second): 71 t.Fatal("daemon did not shut down") 72 } 73} 74 75// TestDaemonPushDisabled confirms that pushes are rejected (not silently 76// creating repos) when allowPush is false. 77func TestDaemonPushDisabled(t *testing.T) { 78 if _, err := exec.LookPath("git"); err != nil { 79 t.Skip("git not installed") 80 } 81 82 fs := memfs.New() 83 d := &daemon{ 84 fs: fs, 85 loader: transport.NewFilesystemLoader(fs, false), 86 allowPush: false, 87 } 88 89 ctx, cancel := context.WithCancel(context.Background()) 90 defer cancel() 91 92 ln, err := net.Listen("tcp", "127.0.0.1:0") 93 if err != nil { 94 t.Fatalf("listen: %v", err) 95 } 96 go func() { _ = d.Serve(ctx, ln) }() 97 98 remote := "git://" + ln.Addr().String() + "/test.git" 99 100 work := t.TempDir() 101 runGit(t, work, "init", "-b", "main") 102 runGit(t, work, "config", "user.email", "test@example.com") 103 runGit(t, work, "config", "user.name", "Test") 104 runGit(t, work, "commit", "--allow-empty", "-m", "initial") 105 106 if out, err := tryGit(work, "push", remote, "main"); err == nil { 107 t.Fatalf("expected push to be rejected when allowPush is false, got success:\n%s", out) 108 } 109 110 if _, err := fs.Stat("/test.git/config"); err == nil { 111 t.Fatal("repository must not be created when push is disabled") 112 } 113} 114 115func runGit(t *testing.T, dir string, args ...string) string { 116 t.Helper() 117 out, err := tryGit(dir, args...) 118 if err != nil { 119 t.Fatalf("git %v: %v\n%s", args, err, out) 120 } 121 return out 122} 123 124func tryGit(dir string, args ...string) (string, error) { 125 cmd := exec.Command("git", args...) 126 cmd.Dir = dir 127 cmd.Env = append(os.Environ(), 128 "GIT_CONFIG_GLOBAL=/dev/null", 129 "GIT_CONFIG_SYSTEM=/dev/null", 130 "GIT_TERMINAL_PROMPT=0", 131 ) 132 out, err := cmd.CombinedOutput() 133 return string(out), err 134}