From aa1c74437b6e31b2bbdc8606000e3728b6651498 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Tue, 29 Mar 2022 18:47:05 -0400 Subject: [PATCH] chore: add server tests --- .gitignore | 1 + server/middleware.go | 1 + server/middleware_test.go | 28 ++++++++++ server/server.go | 5 ++ server/server_test.go | 115 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 150 insertions(+) create mode 100644 server/middleware_test.go create mode 100644 server/server_test.go diff --git a/.gitignore b/.gitignore index cceafdf52..0a3b2a832 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ cmd/soft/soft .ssh .repos dist +testdata \ No newline at end of file diff --git a/server/middleware.go b/server/middleware.go index a87ae492d..9f3f23009 100644 --- a/server/middleware.go +++ b/server/middleware.go @@ -47,6 +47,7 @@ func softServeMiddleware(ac *appCfg.Config) wish.Middleware { for _, rp := range ac.Source.AllRepos() { if rp.Name() == repo { repoExists = true + break } } if !repoExists { diff --git a/server/middleware_test.go b/server/middleware_test.go new file mode 100644 index 000000000..9b8fe2661 --- /dev/null +++ b/server/middleware_test.go @@ -0,0 +1,28 @@ +package server + +import ( + "testing" + + "github.com/charmbracelet/soft-serve/internal/config" + "github.com/charmbracelet/wish/testsession" + "github.com/gliderlabs/ssh" + "github.com/matryer/is" +) + +var () + +func TestMiddleware(t *testing.T) { + is := is.New(t) + appCfg, err := config.NewConfig(cfg) + is.NoErr(err) + _ = testsession.New(t, &ssh.Server{ + Handler: softServeMiddleware(appCfg)(func(s ssh.Session) { + t.Run("TestCatConfig", func(t *testing.T) { + _, err := s.Write([]byte("config/config.json")) + if err == nil { + t.Errorf("Expected error, got nil") + } + }) + }), + }, nil) +} diff --git a/server/server.go b/server/server.go index 3f6a56ccb..87bc47551 100644 --- a/server/server.go +++ b/server/server.go @@ -73,3 +73,8 @@ func (srv *Server) Start() error { func (srv *Server) Shutdown(ctx context.Context) error { return srv.SSHServer.Shutdown(ctx) } + +// Close closes the SSH server. +func (srv *Server) Close() error { + return srv.SSHServer.Close() +} diff --git a/server/server_test.go b/server/server_test.go new file mode 100644 index 000000000..1eb3673c3 --- /dev/null +++ b/server/server_test.go @@ -0,0 +1,115 @@ +package server + +import ( + "fmt" + "os" + "path/filepath" + "testing" + + "github.com/charmbracelet/keygen" + "github.com/charmbracelet/soft-serve/config" + "github.com/gliderlabs/ssh" + "github.com/go-git/go-git/v5" + gconfig "github.com/go-git/go-git/v5/config" + "github.com/go-git/go-git/v5/plumbing/object" + gssh "github.com/go-git/go-git/v5/plumbing/transport/ssh" + "github.com/matryer/is" + cssh "golang.org/x/crypto/ssh" +) + +var ( + testdata = "testdata" + cfg = &config.Config{ + BindAddr: "", + Host: "localhost", + Port: 22222, + RepoPath: fmt.Sprintf("%s/repos", testdata), + KeyPath: fmt.Sprintf("%s/key", testdata), + } + pkPath = "" +) + +func TestServer(t *testing.T) { + t.Cleanup(func() { + os.RemoveAll(testdata) + }) + is := is.New(t) + _, pkPath = createKeyPair(t) + s := setupServer(t) + err := s.Reload() + is.NoErr(err) + t.Run("TestPushRepo", testPushRepo) + t.Run("TestCloneRepo", testCloneRepo) +} + +func testPushRepo(t *testing.T) { + is := is.New(t) + rp := t.TempDir() + r, err := git.PlainInit(rp, false) + is.NoErr(err) + wt, err := r.Worktree() + is.NoErr(err) + _, err = wt.Filesystem.Create("testfile") + is.NoErr(err) + _, err = wt.Add("testfile") + is.NoErr(err) + author := &object.Signature{ + Name: "test", + Email: "", + } + _, err = wt.Commit("test commit", &git.CommitOptions{ + All: true, + Author: author, + Committer: author, + }) + is.NoErr(err) + _, err = r.CreateRemote(&gconfig.RemoteConfig{ + Name: "origin", + URLs: []string{fmt.Sprintf("ssh://%s:%d/%s", cfg.Host, cfg.Port, "testrepo")}, + }) + auth, err := gssh.NewPublicKeysFromFile("git", pkPath, "") + is.NoErr(err) + auth.HostKeyCallbackHelper = gssh.HostKeyCallbackHelper{ + HostKeyCallback: cssh.InsecureIgnoreHostKey(), + } + err = r.Push(&git.PushOptions{ + RemoteName: "origin", + Auth: auth, + }) + is.NoErr(err) +} + +func testCloneRepo(t *testing.T) { + is := is.New(t) + auth, err := gssh.NewPublicKeysFromFile("git", pkPath, "") + is.NoErr(err) + auth.HostKeyCallbackHelper = gssh.HostKeyCallbackHelper{ + HostKeyCallback: cssh.InsecureIgnoreHostKey(), + } + dst := t.TempDir() + _, err = git.PlainClone(dst, false, &git.CloneOptions{ + URL: fmt.Sprintf("ssh://%s:%d/config", cfg.Host, cfg.Port), + Auth: auth, + }) + is.NoErr(err) +} + +func setupServer(t *testing.T) *Server { + s := NewServer(cfg) + go func() { + s.Start() + }() + defer s.Close() + return s +} + +func createKeyPair(t *testing.T) (ssh.PublicKey, string) { + is := is.New(t) + t.Helper() + keyDir := t.TempDir() + kp, err := keygen.NewWithWrite(keyDir, "id", nil, keygen.Ed25519) + is.NoErr(err) + pubkey, _, _, _, err := ssh.ParseAuthorizedKey(kp.PublicKey) + is.NoErr(err) + return pubkey, filepath.Join(keyDir, "id_ed25519") +}