script_test.go

  1package testscript
  2
  3import (
  4	"context"
  5	"flag"
  6	"fmt"
  7	"os"
  8	"path/filepath"
  9	"sync"
 10	"testing"
 11	"time"
 12
 13	"github.com/charmbracelet/soft-serve/server"
 14	"github.com/charmbracelet/soft-serve/server/config"
 15	"github.com/charmbracelet/soft-serve/server/test"
 16	"github.com/rogpeppe/go-internal/testscript"
 17)
 18
 19var update = flag.Bool("update", false, "update script files")
 20
 21func TestScript(t *testing.T) {
 22	flag.Parse()
 23	var lock sync.Mutex
 24
 25	// we'll use this key to talk with soft serve, and since testscript changes
 26	// the cwd, we need to get its full path here
 27	key, err := filepath.Abs("./testdata/admin1")
 28	if err != nil {
 29		t.Fatal(err)
 30	}
 31
 32	// git does not handle 0600, and on clone, will save the files with its
 33	// default perm, 0644, which is too open for ssh.
 34	for _, f := range []string{
 35		"admin1",
 36		"admin2",
 37		"user1",
 38		"user2",
 39	} {
 40		if err := os.Chmod(filepath.Join("./testdata/", f), 0o600); err != nil {
 41			t.Fatal(err)
 42		}
 43	}
 44
 45	testscript.Run(t, testscript.Params{
 46		Dir:           "testdata/script",
 47		UpdateScripts: *update,
 48		Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){
 49			"soft": func(ts *testscript.TestScript, _ bool, args []string) {
 50				// TODO: maybe use plain ssh client here?
 51				args = append([]string{
 52					"-F", "/dev/null",
 53					"-o", "StrictHostKeyChecking=no",
 54					"-o", "UserKnownHostsFile=/dev/null",
 55					"-o", "IdentityAgent=none",
 56					"-o", "IdentitiesOnly=yes",
 57					"-i", key,
 58					"-p", ts.Getenv("SSH_PORT"),
 59					"localhost",
 60					"--",
 61				}, args...)
 62				ts.Check(ts.Exec("ssh", args...))
 63			},
 64		},
 65		Setup: func(e *testscript.Env) error {
 66			sshPort := test.RandomPort()
 67			e.Setenv("SSH_PORT", fmt.Sprintf("%d", sshPort))
 68			data := t.TempDir()
 69			cfg := config.Config{
 70				Name:     "Test Soft Serve",
 71				DataPath: data,
 72				InitialAdminKeys: []string{
 73					"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJI/1tawpdPmzuJcTGTJ+QReqB6cRUdKj4iQIdJUFdrl",
 74				},
 75				SSH: config.SSHConfig{
 76					ListenAddr:    fmt.Sprintf("localhost:%d", sshPort),
 77					PublicURL:     fmt.Sprintf("ssh://localhost:%d", sshPort),
 78					KeyPath:       filepath.Join(data, "ssh", "soft_serve_host_ed25519"),
 79					ClientKeyPath: filepath.Join(data, "ssh", "soft_serve_client_ed25519"),
 80				},
 81				Git: config.GitConfig{
 82					ListenAddr:     fmt.Sprintf("localhost:%d", test.RandomPort()),
 83					IdleTimeout:    3,
 84					MaxConnections: 32,
 85				},
 86				HTTP: config.HTTPConfig{
 87					ListenAddr: fmt.Sprintf("localhost:%d", test.RandomPort()),
 88					PublicURL:  fmt.Sprintf("http://localhost:%d", test.RandomPort()),
 89				},
 90				Stats: config.StatsConfig{
 91					ListenAddr: fmt.Sprintf("localhost:%d", test.RandomPort()),
 92				},
 93				Log: config.LogConfig{
 94					Format:     "text",
 95					TimeFormat: time.DateTime,
 96				},
 97			}
 98			ctx := config.WithContext(context.Background(), &cfg)
 99
100			// prevent race condition in lipgloss...
101			// this will probably be autofixed when we start using the colors
102			// from the ssh session instead of the server.
103			// XXX: take another look at this soon
104			lock.Lock()
105			srv, err := server.NewServer(ctx)
106			if err != nil {
107				return err
108			}
109			lock.Unlock()
110			go func() {
111				if err := srv.Start(); err != nil {
112					e.T().Fatal(err)
113				}
114			}()
115			e.Defer(func() {
116				if err := srv.Shutdown(context.Background()); err != nil {
117					e.T().Fatal(err)
118				}
119			})
120			return nil
121		},
122	})
123}