Files
OwnCord/Server/admin/export_test.go
T

89 lines
3.2 KiB
Go
Raw Normal View History

package admin
import (
"errors"
"sync/atomic"
"time"
"github.com/owncord/server/auth"
"github.com/owncord/server/db"
)
// CaptureSetupLimiter installs h so the next NewAdminAPI call reports the
// *auth.RateLimiter it creates for the /setup endpoint. NewAdminAPI returns
// only an http.Handler, so this is the only way tests can reach that limiter
// to check whether its stale entries get reaped.
func CaptureSetupLimiter(h func(*auth.RateLimiter)) (restore func()) {
prev := setupLimiterHook
setupLimiterHook = h
return func() { setupLimiterHook = prev }
}
// SetSetupLimiterReapTiming overrides the interval and max-window the setup
// endpoint's rate-limiter reaper uses, so tests don't wait on the real
// 5-minute interval.
func SetSetupLimiterReapTiming(interval, maxWindow time.Duration) (restore func()) {
prevI, prevW := setupLimiterReapInterval, setupLimiterReapMaxWindow
setupLimiterReapInterval = interval
setupLimiterReapMaxWindow = maxWindow
return func() {
setupLimiterReapInterval = prevI
setupLimiterReapMaxWindow = prevW
}
}
// SetBackupBaseDir overrides backupBaseDir so tests can point backup handlers
// at a temp dir. Lives here so it stays out of the production binary.
func SetBackupBaseDir(dir string) { backupBaseDir = dir }
// StubCopyBackup swaps the restore path's file-copy hook so tests can inject
// mid-copy failures that pass the pre-copy integrity gate. CopyBackupForTest
// is the real implementation, for stubs that only want to fail once.
func StubCopyBackup(fn func(src, dst string) error) (restore func()) {
prev := copyBackupFile
copyBackupFile = fn
return func() { copyBackupFile = prev }
}
// CopyBackupForTest exposes the real copyFile for StubCopyBackup delegates.
var CopyBackupForTest = copyFile
// StubCloseError makes the next handleRestoreBackup call's database.Close()
// return err instead of actually closing the pools, so tests can exercise the
// Close-failure branch without a genuine driver-level close error (see
// dbCloser's doc comment for why that's not otherwise reachable in a test).
func StubCloseError(msg string) (restore func()) {
closeMu.Lock()
prev := dbCloser
dbCloser = func(*db.DB) error { return errors.New(msg) }
closeMu.Unlock()
return func() {
closeMu.Lock()
dbCloser = prev
closeMu.Unlock()
}
}
// ApplyStagedUpdate exposes applyStagedUpdate (the on-disk swap + respawn
// logic behind POST /updates/apply's background goroutine) so tests can drive
// its abort paths directly with fake filesystem paths, instead of exercising
// the full HTTP handler — which resolves exePath via os.Executable() and
// would rename/replace the running test binary itself.
var ApplyStagedUpdate = applyStagedUpdate
// StubRestart replaces the process-restart hook for the duration of a test and
// returns a func reporting whether a restart was requested. Without this the
// restore handler would respawn and os.Exit the test binary.
func StubRestart() (restarted func() bool, restore func()) {
restartMu.Lock()
prev := restartSelf
called := &atomic.Bool{}
restartSelf = func(string) { called.Store(true) }
restartMu.Unlock()
return called.Load, func() {
restartMu.Lock()
restartSelf = prev
restartMu.Unlock()
}
}