Files
wehub-resource-sync 75f3dd141c
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CI and Release / lint-frontend (push) Has been cancelled
CI and Release / dockerfile-scan (push) Has been cancelled
CI and Release / test-frontend (push) Has been cancelled
CI and Release / lint-verification-agent (push) Has been cancelled
CI and Release / test-verification-agent (push) Has been cancelled
CI and Release / e2e-verification-agent (push) Has been cancelled
CI and Release / test-backend (push) Has been cancelled
CI and Release / build-dev-image (push) Has been cancelled
CI and Release / push-dev-image (push) Has been cancelled
CI and Release / build-image (push) Has been cancelled
CI and Release / build-verification-image (push) Has been cancelled
CI and Release / determine-version (push) Has been cancelled
CI and Release / push-image (push) Has been cancelled
CI and Release / push-verification-image (12) (push) Has been cancelled
CI and Release / lint-backend (push) Has been cancelled
CI and Release / push-verification-image (17) (push) Has been cancelled
CI and Release / push-verification-image (18) (push) Has been cancelled
CI and Release / release (push) Has been cancelled
CI and Release / publish-helm-chart (push) Has been cancelled
CI and Release / push-verification-image (13) (push) Has been cancelled
CI and Release / push-verification-image (14) (push) Has been cancelled
CI and Release / push-verification-image (15) (push) Has been cancelled
CI and Release / push-verification-image (16) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:11:07 +08:00

224 lines
4.5 KiB
Go

package runner
import (
"bytes"
"context"
"io"
"sync"
"sync/atomic"
"github.com/google/uuid"
"databasus-verification-agent/internal/features/api"
"databasus-verification-agent/internal/features/dbconn"
"databasus-verification-agent/internal/features/restore"
"databasus-verification-agent/internal/features/verifier"
)
type fakeAPI struct {
mu sync.Mutex
claims []*api.JobAssignment
claimErrs []error
claimIdx int
downloadBody []byte
downloadErr error
reportErr error
reportedReqs []api.ReportRequest
reportedIDs []uuid.UUID
reportCalled int
}
func (f *fakeAPI) ClaimVerification(
_ context.Context, _ api.AgentCapacity,
) (*api.JobAssignment, error) {
f.mu.Lock()
defer f.mu.Unlock()
i := f.claimIdx
f.claimIdx++
if i < len(f.claimErrs) && f.claimErrs[i] != nil {
return nil, f.claimErrs[i]
}
if i < len(f.claims) {
return f.claims[i], nil
}
return nil, nil
}
func (f *fakeAPI) DownloadBackup(
_ context.Context, _ uuid.UUID,
) (io.ReadCloser, error) {
if f.downloadErr != nil {
return nil, f.downloadErr
}
return io.NopCloser(bytes.NewReader(f.downloadBody)), nil
}
func (f *fakeAPI) Report(
_ context.Context, verificationID uuid.UUID, req api.ReportRequest,
) error {
f.mu.Lock()
defer f.mu.Unlock()
f.reportCalled++
f.reportedReqs = append(f.reportedReqs, req)
f.reportedIDs = append(f.reportedIDs, verificationID)
return f.reportErr
}
func (f *fakeAPI) lastReport() (api.ReportRequest, bool) {
f.mu.Lock()
defer f.mu.Unlock()
if len(f.reportedReqs) == 0 {
return api.ReportRequest{}, false
}
return f.reportedReqs[len(f.reportedReqs)-1], true
}
type fakeContainer struct {
inContainerConn dbconn.Conn
verifierConn dbconn.Conn
terminated bool
diskUsageBytes int64
diskUsageErr error
}
func (c *fakeContainer) Exec(
_ context.Context, _ []string, stdin io.Reader, _ []string,
) (restore.ExecResult, error) {
if stdin != nil {
_, _ = io.Copy(io.Discard, stdin)
}
return restore.ExecResult{}, nil
}
func (c *fakeContainer) GetInContainerConn() dbconn.Conn { return c.inContainerConn }
func (c *fakeContainer) GetVerifierConn() dbconn.Conn { return c.verifierConn }
func (c *fakeContainer) GetDiskUsageBytes(context.Context) (int64, error) {
return c.diskUsageBytes, c.diskUsageErr
}
func (c *fakeContainer) Terminate(context.Context) error {
c.terminated = true
return nil
}
type fakeSpawner struct {
container JobContainer
err error
}
func (s *fakeSpawner) Spawn(_ context.Context, _ SpawnRequest) (JobContainer, error) {
if s.err != nil {
return nil, s.err
}
return s.container, nil
}
type fakeRestorer struct {
stageErr error
runResult restore.Result
runErr error
runBlocks bool
runEntered atomic.Bool
runCtxCancelled atomic.Bool
// calls records the restore-related call order ("pre", "restore", "post") for a single job.
calls []string
// runParallelJobs records the -j value RunPgRestore was invoked with.
runParallelJobs int
}
func (r *fakeRestorer) StageBackupViaExec(
_ context.Context, _ restore.ExecRunner, body io.Reader, _ string,
) error {
if body != nil {
_, _ = io.Copy(io.Discard, body)
}
return r.stageErr
}
func (r *fakeRestorer) RunPgRestore(
ctx context.Context, _ restore.ExecRunner, _ string, _ dbconn.Conn, parallelJobs int,
) (restore.Result, error) {
r.calls = append(r.calls, "restore")
r.runParallelJobs = parallelJobs
if r.runBlocks {
r.runEntered.Store(true)
<-ctx.Done()
r.runCtxCancelled.Store(true)
return restore.Result{}, ctx.Err()
}
return r.runResult, r.runErr
}
func (r *fakeRestorer) RunTimescalePreRestore(context.Context, dbconn.Conn) error {
r.calls = append(r.calls, "pre")
return nil
}
func (r *fakeRestorer) RunTimescalePostRestore(context.Context, dbconn.Conn) error {
r.calls = append(r.calls, "post")
return nil
}
type fakeStats struct {
stats verifier.Stats
err error
}
func (s *fakeStats) CollectStats(context.Context, dbconn.Conn) (verifier.Stats, error) {
return s.stats, s.err
}
type fakeRegistrar struct {
mu sync.Mutex
registered map[uuid.UUID]struct{}
aborted bool
}
func newFakeRegistrar() *fakeRegistrar {
return &fakeRegistrar{registered: make(map[uuid.UUID]struct{})}
}
func (r *fakeRegistrar) TrackVerification(id uuid.UUID, _ context.CancelFunc) {
r.mu.Lock()
defer r.mu.Unlock()
r.registered[id] = struct{}{}
}
func (r *fakeRegistrar) UntrackVerification(id uuid.UUID) {
r.mu.Lock()
defer r.mu.Unlock()
delete(r.registered, id)
}
func (r *fakeRegistrar) IsAborted(uuid.UUID) bool {
r.mu.Lock()
defer r.mu.Unlock()
return r.aborted
}