@@ -4,7 +4,7 @@ import type { ApiClient } from "../../../../src/common/atlas/apiClient.js";
44import type { IntegrationTest } from "../../helpers.js" ;
55import { setupIntegrationTest , defaultTestConfig , defaultDriverOptions } from "../../helpers.js" ;
66import type { SuiteCollector } from "vitest" ;
7- import { afterAll , beforeAll , describe } from "vitest" ;
7+ import { afterAll , beforeEach , describe } from "vitest" ;
88
99export type IntegrationTestFunction = ( integration : IntegrationTest ) => void ;
1010
@@ -36,19 +36,13 @@ export function withProject(integration: IntegrationTest, fn: ProjectTestFunctio
3636 return describe ( "with project" , ( ) => {
3737 let projectId : string = "" ;
3838
39- beforeAll ( async ( ) => {
39+ beforeAllWithRetry ( async ( ) => {
4040 const apiClient = integration . mcpServer ( ) . session . apiClient ;
41-
42- try {
43- const group = await createProject ( apiClient ) ;
44- projectId = group . id ;
45- } catch ( error ) {
46- console . error ( "Failed to create project:" , error ) ;
47- throw error ;
48- }
41+ const group = await createProject ( apiClient ) ;
42+ projectId = group . id ;
4943 } ) ;
5044
51- afterAll ( async ( ) => {
45+ afterAllWithRetry ( async ( ) => {
5246 const apiClient = integration . mcpServer ( ) . session . apiClient ;
5347 if ( projectId ) {
5448 // projectId may be empty if beforeAll failed.
@@ -70,6 +64,63 @@ export function withProject(integration: IntegrationTest, fn: ProjectTestFunctio
7064 } ) ;
7165}
7266
67+ export function beforeAllWithRetry ( fixture : ( ) => Promise < void > ) : void {
68+ beforeEach ( async ( ) => {
69+ const MAX_SETUP_ATTEMPTS = 10 ;
70+ const SETUP_BACKOFF_MS = 10 ;
71+ let lastError : Error | undefined = undefined ;
72+
73+ for ( let attempt = 0 ; attempt < MAX_SETUP_ATTEMPTS ; attempt ++ ) {
74+ try {
75+ await fixture ( ) ;
76+ lastError = undefined ;
77+ break ;
78+ } catch ( error : unknown ) {
79+ if ( error instanceof Error ) {
80+ lastError = error ;
81+ } else {
82+ lastError = new Error ( String ( error ) ) ;
83+ }
84+
85+ console . error ( "beforeAll(attempt:" , attempt , "):" , error ) ;
86+ await new Promise ( ( resolve ) => setTimeout ( resolve , SETUP_BACKOFF_MS * attempt ) ) ;
87+ }
88+ }
89+
90+ if ( lastError ) {
91+ throw lastError ;
92+ }
93+ } ) ;
94+ }
95+
96+ export function afterAllWithRetry ( fixture : ( ) => Promise < void > ) : void {
97+ afterAll ( async ( ) => {
98+ const MAX_SETUP_ATTEMPTS = 10 ;
99+ const SETUP_BACKOFF_MS = 10 ;
100+ let lastError : Error | undefined = undefined ;
101+
102+ for ( let attempt = 0 ; attempt < MAX_SETUP_ATTEMPTS ; attempt ++ ) {
103+ try {
104+ await fixture ( ) ;
105+ lastError = undefined ;
106+ break ;
107+ } catch ( error ) {
108+ if ( error instanceof Error ) {
109+ lastError = error ;
110+ } else {
111+ lastError = new Error ( String ( error ) ) ;
112+ }
113+ console . error ( "afterAll(attempt:" , attempt , "):" , error ) ;
114+ await new Promise ( ( resolve ) => setTimeout ( resolve , SETUP_BACKOFF_MS * attempt ) ) ;
115+ }
116+ }
117+
118+ if ( lastError ) {
119+ throw lastError ;
120+ }
121+ } ) ;
122+ }
123+
73124export function parseTable ( text : string ) : Record < string , string > [ ] {
74125 const data = text
75126 . split ( "\n" )
0 commit comments