tinyrelayfile
tinyrelay/internal/daemon/git_push_test.go/

internal/daemon/git_push_test.go raw
1package daemon
2
3import (
4 "context"
5 "io"
6 "net/http"
7 "os"
8 "os/exec"
9 "path/filepath"
10 "strconv"
11 "strings"
12 "testing"
13 "time"
14
15 "net/http/httptest"
16
17 "github.com/FelineStateMachine/tinyrelay/internal/event"
18 "github.com/FelineStateMachine/tinyrelay/internal/relay"
19)
20
21func TestImmediateMultiRefPushAfterSignedState(t *testing.T) {
22 ctx := context.Background()
23 secret := strings.Repeat("0", 63) + "1"
24 owner, err := event.PublicKey(secret)
25 if err != nil {
26 t.Fatal(err)
27 }
28 app, tenant := testTenant(t)
29 p := tenant.Policy()
30 p.Features.Grasp = true
31 if err := tenant.applyPolicy(ctx, p); err != nil {
32 t.Fatal(err)
33 }
34
35 announcement := event.Event{Kind: event.KIND_REPO, CreatedAt: time.Now().Unix(), Tags: [][]string{{"d", "many"}, {"clone", "http://relay.test/" + "npub10xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqpkge6d/many.git"}, {"relays", "ws://relay.test"}}}
36 if err := event.Sign(&announcement, secret); err != nil {
37 t.Fatal(err)
38 }
39 if _, err := tenant.router.Publish(ctx, announcement, relay.Session{PubKeys: []string{owner}}); err != nil {
40 t.Fatal(err)
41 }
42
43 source := filepath.Join(t.TempDir(), "source.git")
44 gitTest(t, "init", "--bare", source)
45 work := filepath.Join(t.TempDir(), "work")
46 gitTest(t, "clone", source, work)
47 gitTest(t, "-C", work, "config", "user.email", "test@example.com")
48 gitTest(t, "-C", work, "config", "user.name", "Test")
49 if err := osWrite(filepath.Join(work, "README"), []byte("multi\n")); err != nil {
50 t.Fatal(err)
51 }
52 gitTest(t, "-C", work, "add", "README")
53 gitTest(t, "-C", work, "commit", "-m", "multi")
54 gitTest(t, "-C", work, "branch", "-M", "main")
55 sha := strings.TrimSpace(gitOutput(t, "-C", work, "rev-parse", "HEAD"))
56 refs := [][]string{{"HEAD", "ref: refs/heads/main"}}
57 for i := 0; i < 30; i++ {
58 name := "refs/heads/branch-" + strconv.Itoa(i)
59 if i == 0 {
60 name = "refs/heads/main"
61 }
62 gitTest(t, "-C", work, "update-ref", name, sha)
63 refs = append(refs, []string{name, sha})
64 }
65 state := event.Event{Kind: event.KIND_REPO_STATE, CreatedAt: time.Now().Unix(), Tags: append([][]string{{"d", "many"}}, refs...)}
66 if err := event.Sign(&state, secret); err != nil {
67 t.Fatal(err)
68 }
69 if _, err := tenant.router.Publish(ctx, state, relay.Session{PubKeys: []string{owner}}); err != nil {
70 t.Fatal(err)
71 }
72
73 server := httptest.NewServer(app)
74 defer server.Close()
75 const ownerNPub = "npub10xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqpkge6d"
76 url := server.URL + "/r/main/" + ownerNPub + "/many.git"
77 gitTest(t, "-C", work, "push", url, "refs/heads/*:refs/heads/*")
78 // Existing repositories must obey live hosting/read policy changes too.
79 checkAdvertisement := func(want int) {
80 t.Helper()
81 res, err := server.Client().Get(url + "/info/refs?service=git-upload-pack")
82 if err != nil {
83 t.Fatal(err)
84 }
85 defer res.Body.Close()
86 _, _ = io.Copy(io.Discard, res.Body)
87 if res.StatusCode != want {
88 t.Fatalf("Git policy response = %d, want %d", res.StatusCode, want)
89 }
90 }
91 p = tenant.Policy()
92 p.Reads = "members"
93 if err := tenant.applyPolicy(ctx, p); err != nil {
94 t.Fatal(err)
95 }
96 checkAdvertisement(http.StatusForbidden)
97 p.Reads = "open"
98 p.Features.Grasp = false
99 if err := tenant.applyPolicy(ctx, p); err != nil {
100 t.Fatal(err)
101 }
102 checkAdvertisement(http.StatusNotFound)
103 p.Features.Grasp = true
104 if err := tenant.applyPolicy(ctx, p); err != nil {
105 t.Fatal(err)
106 }
107 checkAdvertisement(http.StatusOK)
108}
109
110func gitTest(t *testing.T, args ...string) {
111 t.Helper()
112 if out, err := exec.Command("git", args...).CombinedOutput(); err != nil {
113 t.Fatalf("git %v: %v: %s", args, err, out)
114 }
115}
116
117func gitOutput(t *testing.T, args ...string) string {
118 t.Helper()
119 out, err := exec.Command("git", args...).Output()
120 if err != nil {
121 t.Fatal(err)
122 }
123 return string(out)
124}
125
126func osWrite(path string, data []byte) error {
127 return os.WriteFile(path, data, 0600)
128}

About

ownerc01503e8035f
visibilitypublic
headd730679639bf

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

  • https://012.run/npub1cq2s86qrtadf36eqq3epm38wmhdynrrcwxf84eldk3f94dkv7ttsrulrz5/tinyrelay.git

Refs