1package server
2
3import (
4 "fmt"
5 "os"
6 "path/filepath"
7 "testing"
8
9 "github.com/charmbracelet/keygen"
10 "github.com/charmbracelet/soft-serve/config"
11 "github.com/gliderlabs/ssh"
12 "github.com/go-git/go-git/v5"
13 gconfig "github.com/go-git/go-git/v5/config"
14 "github.com/go-git/go-git/v5/plumbing/object"
15 gssh "github.com/go-git/go-git/v5/plumbing/transport/ssh"
16 "github.com/matryer/is"
17 cssh "golang.org/x/crypto/ssh"
18)
19
20var (
21 testdata = "testdata"
22 cfg = &config.Config{
23 BindAddr: "",
24 Host: "localhost",
25 Port: 22222,
26 RepoPath: fmt.Sprintf("%s/repos", testdata),
27 KeyPath: fmt.Sprintf("%s/key", testdata),
28 }
29 pkPath = ""
30)
31
32func TestServer(t *testing.T) {
33 t.Cleanup(func() {
34 os.RemoveAll(testdata)
35 })
36 is := is.New(t)
37 _, pkPath = createKeyPair(t)
38 s := setupServer(t)
39 err := s.Reload()
40 is.NoErr(err)
41 t.Run("TestPushRepo", testPushRepo)
42 t.Run("TestCloneRepo", testCloneRepo)
43}
44
45func testPushRepo(t *testing.T) {
46 is := is.New(t)
47 rp := t.TempDir()
48 r, err := git.PlainInit(rp, false)
49 is.NoErr(err)
50 wt, err := r.Worktree()
51 is.NoErr(err)
52 _, err = wt.Filesystem.Create("testfile")
53 is.NoErr(err)
54 _, err = wt.Add("testfile")
55 is.NoErr(err)
56 author := &object.Signature{
57 Name: "test",
58 Email: "",
59 }
60 _, err = wt.Commit("test commit", &git.CommitOptions{
61 All: true,
62 Author: author,
63 Committer: author,
64 })
65 is.NoErr(err)
66 _, err = r.CreateRemote(&gconfig.RemoteConfig{
67 Name: "origin",
68 URLs: []string{fmt.Sprintf("ssh://%s:%d/%s", cfg.Host, cfg.Port, "testrepo")},
69 })
70 auth, err := gssh.NewPublicKeysFromFile("git", pkPath, "")
71 is.NoErr(err)
72 auth.HostKeyCallbackHelper = gssh.HostKeyCallbackHelper{
73 HostKeyCallback: cssh.InsecureIgnoreHostKey(),
74 }
75 err = r.Push(&git.PushOptions{
76 RemoteName: "origin",
77 Auth: auth,
78 })
79 is.NoErr(err)
80}
81
82func testCloneRepo(t *testing.T) {
83 is := is.New(t)
84 auth, err := gssh.NewPublicKeysFromFile("git", pkPath, "")
85 is.NoErr(err)
86 auth.HostKeyCallbackHelper = gssh.HostKeyCallbackHelper{
87 HostKeyCallback: cssh.InsecureIgnoreHostKey(),
88 }
89 dst := t.TempDir()
90 _, err = git.PlainClone(dst, false, &git.CloneOptions{
91 URL: fmt.Sprintf("ssh://%s:%d/config", cfg.Host, cfg.Port),
92 Auth: auth,
93 })
94 is.NoErr(err)
95}
96
97func setupServer(t *testing.T) *Server {
98 s := NewServer(cfg)
99 go func() {
100 s.Start()
101 }()
102 defer s.Close()
103 return s
104}
105
106func createKeyPair(t *testing.T) (ssh.PublicKey, string) {
107 is := is.New(t)
108 t.Helper()
109 keyDir := t.TempDir()
110 kp, err := keygen.NewWithWrite(keyDir, "id", nil, keygen.Ed25519)
111 is.NoErr(err)
112 pubkey, _, _, _, err := ssh.ParseAuthorizedKey(kp.PublicKey)
113 is.NoErr(err)
114 return pubkey, filepath.Join(keyDir, "id_ed25519")
115}