server_test.go

  1package server
  2
  3import (
  4	"fmt"
  5	"path/filepath"
  6	"testing"
  7
  8	"github.com/charmbracelet/keygen"
  9	ggit "github.com/charmbracelet/soft-serve/git"
 10	"github.com/charmbracelet/soft-serve/server/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	cfg = &config.Config{
 22		BindAddr: "",
 23		Host:     "localhost",
 24		Port:     22222,
 25	}
 26)
 27
 28func TestPushRepo(t *testing.T) {
 29	is := is.New(t)
 30	_, pkPath := createKeyPair(t)
 31	s := setupServer(t)
 32	defer s.Close()
 33	err := s.Reload()
 34	is.NoErr(err)
 35
 36	rp := t.TempDir()
 37	r, err := git.PlainInit(rp, false)
 38	is.NoErr(err)
 39	wt, err := r.Worktree()
 40	is.NoErr(err)
 41	_, err = wt.Filesystem.Create("testfile")
 42	is.NoErr(err)
 43	_, err = wt.Add("testfile")
 44	is.NoErr(err)
 45	author := &object.Signature{
 46		Name:  "test",
 47		Email: "",
 48	}
 49	_, err = wt.Commit("test commit", &git.CommitOptions{
 50		All:       true,
 51		Author:    author,
 52		Committer: author,
 53	})
 54	is.NoErr(err)
 55	_, err = r.CreateRemote(&gconfig.RemoteConfig{
 56		Name: "origin",
 57		URLs: []string{fmt.Sprintf("ssh://%s:%d/%s", cfg.Host, cfg.Port, "testrepo")},
 58	})
 59	auth, err := gssh.NewPublicKeysFromFile("git", pkPath, "")
 60	is.NoErr(err)
 61	auth.HostKeyCallbackHelper = gssh.HostKeyCallbackHelper{
 62		HostKeyCallback: cssh.InsecureIgnoreHostKey(),
 63	}
 64	err = r.Push(&git.PushOptions{
 65		RemoteName: "origin",
 66		Auth:       auth,
 67	})
 68	is.NoErr(err)
 69}
 70
 71func TestCloneRepo(t *testing.T) {
 72	is := is.New(t)
 73	_, pkPath := createKeyPair(t)
 74	s := setupServer(t)
 75	defer s.Close()
 76	err := s.Reload()
 77	is.NoErr(err)
 78
 79	dst := t.TempDir()
 80	url := fmt.Sprintf("ssh://%s:%d/config", cfg.Host, cfg.Port)
 81	err = ggit.Clone(url, dst, ggit.CloneOptions{
 82		CommandOptions: ggit.CommandOptions{
 83			Envs: []string{
 84				fmt.Sprintf(`GIT_SSH_COMMAND=ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i %s -F /dev/null`, pkPath),
 85			},
 86		},
 87	})
 88	is.NoErr(err)
 89}
 90
 91func setupServer(t *testing.T) *Server {
 92	t.Helper()
 93	tmpdir := t.TempDir()
 94	cfg.RepoPath = filepath.Join(tmpdir, "repos")
 95	cfg.KeyPath = filepath.Join(tmpdir, "key")
 96	s := NewServer(cfg)
 97	go func() {
 98		s.Start()
 99	}()
100	t.Cleanup(func() {
101		s.Close()
102	})
103	return s
104}
105
106func createKeyPair(t *testing.T) (ssh.PublicKey, string) {
107	t.Helper()
108	is := is.New(t)
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}