Gesamtprüfung: Zeitlimit für Gitea, Aufräumen ohne Weiterleitung
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
febac3c2a3
commit
d5c70a5bd6
7 files changed
+233
-11
No files matched your search
@@ -42,20 +42,27 @@ import { createHash } from 'node:crypto'
|
||||
* hooksOf: (fullName: string) => object[],
|
||||
* setDown: (down: boolean) => void,
|
||||
* setTransferDelay: (ms: number) => void,
|
||||
* setResponseDelay: (ms: number) => void,
|
||||
* setTransferNoop: () => void,
|
||||
* failNext: (spec: {method: string, pathIncludes: string, status: number}) => void,
|
||||
* close: () => Promise<void>,
|
||||
* }>} `calls` waechst live, in der Reihenfolge, in der die Anfragen eintreffen - VOR einer
|
||||
* etwaigen `setTransferDelay`-Verzoegerung der Antwort. `repo()`/`hooksOf()` lesen den
|
||||
* aktuellen Stand direkt (ohne Weiterleitung ueber einen umgezogenen alten Namen).
|
||||
* etwaigen `setTransferDelay`/`setResponseDelay`-Verzoegerung der Antwort. `repo()`/`hooksOf()`
|
||||
* lesen den aktuellen Stand direkt (ohne Weiterleitung ueber einen umgezogenen alten Namen).
|
||||
* `failNext({method, pathIncludes, status})` laesst GENAU die naechste Anfrage, deren Methode
|
||||
* passt und deren Pfad `pathIncludes` enthaelt, mit diesem Status und einer generischen
|
||||
* JSON-Fehlermeldung scheitern (danach wieder normales Verhalten) - fuer Tests, die einen
|
||||
* einzelnen Aufruf gezielt fehlschlagen lassen wollen, ohne den ganzen Server abzuschalten.
|
||||
* `setResponseDelay(ms)` verzoegert JEDE Antwort um `ms` (z.B. fuer einen Timeout-Test).
|
||||
* `setTransferNoop()` laesst genau den naechsten Transfer-Aufruf mit 201 und UNVERAENDERTEM
|
||||
* `full_name` antworten (Gitea meldet Erfolg, hat aber nichts verschoben).
|
||||
*/
|
||||
export async function startFakeGitea(options = {}) {
|
||||
const calls = []
|
||||
let isDown = false
|
||||
let transferDelayMs = 0
|
||||
let responseDelayMs = 0
|
||||
let transferNoopNext = false
|
||||
const pendingFailures = []
|
||||
|
||||
let nextRepoId = 1
|
||||
@@ -235,9 +242,17 @@ export async function startFakeGitea(options = {}) {
|
||||
const found = findRepoOrRedirect(match[1], match[2])
|
||||
if (!found) return send(res, 404, { message: 'Not Found' })
|
||||
if (found.redirectTo) return sendRepoRedirect(res, found.redirectTo, '/transfer')
|
||||
const key = found.key
|
||||
const record = found.record
|
||||
|
||||
// Simuliert eine Gitea-Antwort, die Erfolg meldet, aber tatsaechlich nichts verschoben hat
|
||||
// (Bug-Szenario fuer Controller-Ruling R10 Ein-Zeiler-Absicherung): 201 mit UNVERAENDERTEM
|
||||
// full_name, kein Owner-/Key-Wechsel, keine Weiterleitung.
|
||||
if (transferNoopNext) {
|
||||
transferNoopNext = false
|
||||
return send(res, 201, serializeRepo(record))
|
||||
}
|
||||
|
||||
const key = found.key
|
||||
const newOwner = body?.new_owner
|
||||
if (!newOwner) return send(res, 422, { message: 'new_owner erforderlich' })
|
||||
|
||||
@@ -435,6 +450,8 @@ export async function startFakeGitea(options = {}) {
|
||||
body: parsedBody,
|
||||
})
|
||||
|
||||
if (responseDelayMs > 0) await sleep(responseDelayMs)
|
||||
|
||||
const failIdx = pendingFailures.findIndex(
|
||||
(f) => f.method === req.method && url.pathname.includes(f.pathIncludes)
|
||||
)
|
||||
@@ -510,6 +527,16 @@ export async function startFakeGitea(options = {}) {
|
||||
transferDelayMs = Number(ms) || 0
|
||||
}
|
||||
|
||||
/** Verzoegert JEDE Antwort um `ms` (z.B. um einen `GITEA_TIMEOUT_MS`-Abbruch zu provozieren). */
|
||||
function setResponseDelay(ms) {
|
||||
responseDelayMs = Number(ms) || 0
|
||||
}
|
||||
|
||||
/** Laesst den naechsten Transfer-Aufruf 201 mit UNVERAENDERTEM full_name melden (kein Umzug). */
|
||||
function setTransferNoop() {
|
||||
transferNoopNext = true
|
||||
}
|
||||
|
||||
function failNext({ method, pathIncludes, status }) {
|
||||
pendingFailures.push({ method, pathIncludes, status })
|
||||
}
|
||||
@@ -519,5 +546,17 @@ export async function startFakeGitea(options = {}) {
|
||||
return new Promise((resolve) => server.close(() => resolve()))
|
||||
}
|
||||
|
||||
return { baseUrl, calls, repo, addRepo, hooksOf, setDown, setTransferDelay, failNext, close }
|
||||
return {
|
||||
baseUrl,
|
||||
calls,
|
||||
repo,
|
||||
addRepo,
|
||||
hooksOf,
|
||||
setDown,
|
||||
setTransferDelay,
|
||||
setResponseDelay,
|
||||
setTransferNoop,
|
||||
failNext,
|
||||
close,
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user