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(filepath.Join(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}