test(e2e): introduce e2e test framework with local forgejo

This commit is contained in:
Julian Tölle 2025-06-15 16:29:30 +02:00
parent 6ed133946e
commit af70a267f5
4 changed files with 221 additions and 0 deletions

23
test/e2e/forgejo/app.ini Normal file
View file

@ -0,0 +1,23 @@
WORK_PATH = /data/gitea
[database]
DB_TYPE = sqlite3
PATH = /data/gitea/forgejo.db
[security]
INSTALL_LOCK = true
SECRET_KEY = releaser-pleaser
INTERNAL_TOKEN = releaser-pleaser
[service]
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL = false
DISABLE_REGISTRATION = true
[server]
DOMAIN = localhost
HTTP_PORT = 3000
ROOT_URL = http://localhost:3000/
[oauth2]
JWT_SECRET = rTD-FL2n_aBB6v4AOcr5lBvwgZ6PSr3HGZAuNH6nMu8

View file

@ -0,0 +1,12 @@
services:
forgejo:
image: codeberg.org/forgejo/forgejo:11
ports:
- '3000:3000'
- '222:22'
volumes:
- data:/data/gitea
- ./app.ini:/data/gitea/conf/app.ini:ro
volumes:
data:

View file

@ -0,0 +1,147 @@
//go:build e2e_forgejo
package forgejo
import (
"bytes"
"context"
"crypto/rand"
"encoding/hex"
"fmt"
"log/slog"
"os/exec"
"strings"
"testing"
"codeberg.org/mvdkleijn/forgejo-sdk/forgejo/v2"
"github.com/apricote/releaser-pleaser/cmd/rp/cmd"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const (
TestAPIURL = "http://localhost:3000"
TestUserNameTemplate = "rp-%s"
TestUserPassword = "releaser-pleaser"
TestUserEmailTemplate = "releaser-pleaser-%s@example.com"
TestTokenName = "rp"
TestTokenScopes = "write:user,write:issue,write:repository"
TestDefaultBranch = "main"
)
var (
TestToken string
TestUserName string
TestClient *forgejo.Client
)
func randomSuffix() string {
bytes := make([]byte, 4)
if _, err := rand.Read(bytes); err != nil {
panic(err)
}
return hex.EncodeToString(bytes)
}
func setupTestUser(ctx context.Context, suffix string) string {
TestUserName = fmt.Sprintf(TestUserNameTemplate, suffix)
if output, err := exec.CommandContext(ctx,
"docker", "compose", "exec", "--user=1000", "forgejo",
"forgejo", "admin", "user", "create",
"--username", TestUserName,
"--password", TestUserPassword,
"--email", fmt.Sprintf(TestUserEmailTemplate, suffix),
"--must-change-password=false",
).CombinedOutput(); err != nil {
slog.ErrorContext(ctx, "failed to create forgejo user", "err", err, "output", output)
panic(err)
}
token, err := exec.CommandContext(ctx,
"docker", "compose", "exec", "--user=1000", "forgejo",
"forgejo", "admin", "user", "generate-access-token",
"--username", TestUserName,
"--token-name", TestTokenName,
"--scopes", TestTokenScopes,
"--raw",
).Output()
if err != nil {
slog.ErrorContext(ctx, "failed to create forgejo token", "err", err)
panic(err)
}
return strings.TrimSpace(string(token))
}
func setupTestClient(ctx context.Context, token string) *forgejo.Client {
client, err := forgejo.NewClient(TestAPIURL,
forgejo.SetToken(token),
forgejo.SetUserAgent("releaser-pleaser-e2e-tests"),
forgejo.SetContext(ctx),
// forgejo.SetDebugMode(),
)
if err != nil {
panic(err)
}
return client
}
type Repository struct {
Name string
}
func NewRepository(t *testing.T, name string) *Repository {
t.Helper()
r := &Repository{
Name: fmt.Sprintf("%s-%s", name, randomSuffix())}
repo, _, err := TestClient.CreateRepo(forgejo.CreateRepoOption{
Name: r.Name,
Description: name,
DefaultBranch: TestDefaultBranch,
})
require.NoError(t, err)
require.NotNil(t, repo)
return r
}
func Run(t *testing.T, r *Repository, extraFiles []string) (stdout bytes.Buffer, stderr bytes.Buffer, err error) {
t.Helper()
ctx := t.Context()
rootCmd := cmd.NewRootCmd()
rootCmd.SetArgs([]string{
"run", "--forge=forgejo",
fmt.Sprintf("--branch=%s", TestDefaultBranch),
fmt.Sprintf("--owner=%s", TestUserName),
fmt.Sprintf("--repo=%s", r.Name),
fmt.Sprintf("--extra-files=%q", strings.Join(extraFiles, "\n")),
fmt.Sprintf("--api-url=%s", TestAPIURL),
fmt.Sprintf("--api-token=%s", TestToken),
fmt.Sprintf("--username=%s", TestUserName),
})
rootCmd.SetOut(&stdout)
rootCmd.SetErr(&stderr)
err = rootCmd.ExecuteContext(ctx)
return stdout, stderr, err
}
func MustRun(t *testing.T, r *Repository, extraFiles []string) {
t.Helper()
stdout, stderr, err := Run(t, r, extraFiles)
if !assert.NoError(t, err) {
t.Log(stdout)
t.Log(stderr)
}
}

View file

@ -0,0 +1,39 @@
//go:build e2e_forgejo
package forgejo
import (
"context"
"os"
"testing"
"github.com/stretchr/testify/require"
)
func TestMain(m *testing.M) {
ctx := context.Background()
suffix := randomSuffix()
TestToken = setupTestUser(ctx, suffix)
TestClient = setupTestClient(ctx, TestToken)
os.Exit(m.Run())
}
func TestAPIAccess(t *testing.T) {
user, _, err := TestClient.GetMyUserInfo()
require.NoError(t, err)
require.NotNil(t, user)
}
func TestCreateRepository(t *testing.T) {
_ = NewRepository(t, t.Name())
}
func TestRun(t *testing.T) {
repo := NewRepository(t, t.Name())
MustRun(t, repo, []string{})
}