80 lines
2.0 KiB
Go
80 lines
2.0 KiB
Go
package e2e
|
|
|
|
import (
|
|
"context"
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"math/big"
|
|
"os"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
// applyMigrations brings a fresh database up to the current schema by running
|
|
// every up-migration in order. It reads the directory instead of taking a
|
|
// hand-written list so that adding a migration cannot leave a test silently
|
|
// running against a stale schema.
|
|
func applyMigrations(t *testing.T, ctx context.Context, pool *pgxpool.Pool) {
|
|
t.Helper()
|
|
|
|
dir := filepath.Join(repoRoot(t), "migrations")
|
|
entries, err := os.ReadDir(dir)
|
|
if err != nil {
|
|
t.Fatalf("read migrations dir: %v", err)
|
|
}
|
|
|
|
var names []string
|
|
for _, e := range entries {
|
|
if !e.IsDir() && strings.HasSuffix(e.Name(), ".up.sql") {
|
|
names = append(names, e.Name())
|
|
}
|
|
}
|
|
if len(names) == 0 {
|
|
t.Fatalf("no up-migrations found in %s", dir)
|
|
}
|
|
sort.Strings(names)
|
|
|
|
for _, name := range names {
|
|
sql, err := os.ReadFile(filepath.Join(dir, name))
|
|
if err != nil {
|
|
t.Fatalf("read migration %s: %v", name, err)
|
|
}
|
|
if _, err := pool.Exec(ctx, string(sql)); err != nil {
|
|
t.Fatalf("apply migration %s: %v", name, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// selfSignedTLSCert issues an in-memory certificate for the STARTTLS handshake
|
|
// in tests. Certificate validation is not what these tests exercise.
|
|
func selfSignedTLSCert(t *testing.T) tls.Certificate {
|
|
t.Helper()
|
|
|
|
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
if err != nil {
|
|
t.Fatalf("generate key: %v", err)
|
|
}
|
|
template := &x509.Certificate{
|
|
SerialNumber: big.NewInt(1),
|
|
Subject: pkix.Name{CommonName: "mail.test"},
|
|
DNSNames: []string{"mail.test", "localhost"},
|
|
NotBefore: time.Now().Add(-time.Hour),
|
|
NotAfter: time.Now().Add(24 * time.Hour),
|
|
}
|
|
der, err := x509.CreateCertificate(rand.Reader, template, template, &key.PublicKey, key)
|
|
if err != nil {
|
|
t.Fatalf("create certificate: %v", err)
|
|
}
|
|
|
|
return tls.Certificate{Certificate: [][]byte{der}, PrivateKey: key}
|
|
}
|