1- import type { MongoClusterOptions } from "mongodb-runner" ;
2- import { MongoCluster } from "mongodb-runner" ;
31import path from "path" ;
42import { fileURLToPath } from "url" ;
53import fs from "fs/promises" ;
@@ -16,9 +14,8 @@ import {
1614import type { UserConfig , DriverOptions } from "../../../../src/common/config.js" ;
1715import { afterAll , afterEach , beforeAll , beforeEach , describe , expect , it } from "vitest" ;
1816import { EJSON } from "bson" ;
19- import { GenericContainer } from "testcontainers" ;
20- import type { StartedTestContainer } from "testcontainers" ;
21- import { ShellWaitStrategy } from "testcontainers/build/wait-strategies/shell-wait-strategy.js" ;
17+ import { MongoDBClusterProcess } from "./mongodbClusterProcess.js" ;
18+ import type { MongoClusterConfiguration } from "./mongodbClusterProcess.js" ;
2219
2320const __dirname = path . dirname ( fileURLToPath ( import . meta. url ) ) ;
2421
@@ -52,6 +49,12 @@ const testDataPaths = [
5249 } ,
5350] ;
5451
52+ const DEFAULT_MONGODB_PROCESS_OPTIONS : MongoClusterConfiguration = {
53+ runner : true ,
54+ downloadOptions : { enterprise : false } ,
55+ serverArgs : [ ] ,
56+ } ;
57+
5558interface MongoDBIntegrationTest {
5659 mongoClient : ( ) => MongoClient ;
5760 connectionString : ( ) => string ;
@@ -68,11 +71,10 @@ export function describeWithMongoDB(
6871 fn : ( integration : MongoDBIntegrationTestCase ) => void ,
6972 getUserConfig : ( mdbIntegration : MongoDBIntegrationTest ) => UserConfig = ( ) => defaultTestConfig ,
7073 getDriverOptions : ( mdbIntegration : MongoDBIntegrationTest ) => DriverOptions = ( ) => defaultDriverOptions ,
71- downloadOptions : MongoClusterOptions [ "downloadOptions" ] | MongoSearchConfiguration = { enterprise : false } ,
72- serverArgs : string [ ] = [ ]
74+ downloadOptions : MongoClusterConfiguration = DEFAULT_MONGODB_PROCESS_OPTIONS
7375) : void {
74- describe . skipIf ( ! isMongoDBEnvSupported ( downloadOptions ) ) ( name , ( ) => {
75- const mdbIntegration = setupMongoDBIntegrationTest ( downloadOptions , serverArgs ) ;
76+ describe . skipIf ( ! MongoDBClusterProcess . isConfigurationSupportedInCurrentEnv ( downloadOptions ) ) ( name , ( ) => {
77+ const mdbIntegration = setupMongoDBIntegrationTest ( downloadOptions ) ;
7678 const integration = setupIntegrationTest (
7779 ( ) => ( {
7880 ...getUserConfig ( mdbIntegration ) ,
@@ -98,35 +100,10 @@ export function describeWithMongoDB(
98100 } ) ;
99101}
100102
101- function isSearchOptions (
102- opt : MongoClusterOptions [ "downloadOptions" ] | MongoSearchConfiguration
103- ) : opt is MongoSearchConfiguration {
104- return ( opt as MongoSearchConfiguration ) ?. search === true ;
105- }
106-
107- function isTestContainersCluster (
108- cluster : MongoCluster | StartedTestContainer | undefined
109- ) : cluster is StartedTestContainer {
110- return ! ! ( cluster as StartedTestContainer ) ?. stop ;
111- }
112-
113- function isMongoDBEnvSupported (
114- downloadOptions : MongoClusterOptions [ "downloadOptions" ] | MongoSearchConfiguration
115- ) : boolean {
116- // on GHA, OSX does not support nested virtualisation and we don't release
117- // windows containers, so for now we can only run these tests in Linux.
118- if ( isSearchOptions ( downloadOptions ) && process . env . GITHUB_ACTIONS === "true" ) {
119- return process . platform === "linux" ;
120- }
121-
122- return true ;
123- }
124-
125103export function setupMongoDBIntegrationTest (
126- downloadOptions : MongoClusterOptions [ "downloadOptions" ] | MongoSearchConfiguration ,
127- serverArgs : string [ ]
104+ configuration : MongoClusterConfiguration = DEFAULT_MONGODB_PROCESS_OPTIONS
128105) : MongoDBIntegrationTest {
129- let mongoCluster : MongoCluster | StartedTestContainer | undefined ;
106+ let mongoCluster : MongoDBClusterProcess | undefined ;
130107 let mongoClient : MongoClient | undefined ;
131108 let randomDbName : string ;
132109
@@ -140,61 +117,11 @@ export function setupMongoDBIntegrationTest(
140117 } ) ;
141118
142119 beforeAll ( async function ( ) {
143- if ( isSearchOptions ( downloadOptions ) ) {
144- mongoCluster = await new GenericContainer ( downloadOptions . image ?? "mongodb/mongodb-atlas-local:8" )
145- . withExposedPorts ( 27017 )
146- . withCommand ( [ "/usr/local/bin/runner" , "server" ] )
147- . withWaitStrategy ( new ShellWaitStrategy ( `mongosh --eval 'db.test.getSearchIndexes()'` ) )
148- . start ( ) ;
149- return ;
150- }
151-
152- // Downloading Windows executables in CI takes a long time because
153- // they include debug symbols...
154- const tmpDir = path . join ( __dirname , ".." , ".." , ".." , "tmp" ) ;
155- await fs . mkdir ( tmpDir , { recursive : true } ) ;
156-
157- // On Windows, we may have a situation where mongod.exe is not fully released by the OS
158- // before we attempt to run it again, so we add a retry.
159- let dbsDir = path . join ( tmpDir , "mongodb-runner" , "dbs" ) ;
160- for ( let i = 0 ; i < 10 ; i ++ ) {
161- try {
162- mongoCluster = await MongoCluster . start ( {
163- tmpDir : dbsDir ,
164- logDir : path . join ( tmpDir , "mongodb-runner" , "logs" ) ,
165- topology : "standalone" ,
166- version : downloadOptions ?. version ?? "8.0.12" ,
167- downloadOptions,
168- args : serverArgs ,
169- } ) ;
170-
171- return ;
172- } catch ( err ) {
173- if ( i < 5 ) {
174- // Just wait a little bit and retry
175- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
176- console . error ( `Failed to start cluster in ${ dbsDir } , attempt ${ i } : ${ err } ` ) ;
177- await new Promise ( ( resolve ) => setTimeout ( resolve , 1000 ) ) ;
178- } else {
179- // If we still fail after 5 seconds, try another db dir
180- console . error (
181- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
182- `Failed to start cluster in ${ dbsDir } , attempt ${ i } : ${ err } . Retrying with a new db dir.`
183- ) ;
184- dbsDir = path . join ( tmpDir , "mongodb-runner" , `dbs${ i - 5 } ` ) ;
185- }
186- }
187- }
188-
189- throw new Error ( "Failed to start cluster after 10 attempts" ) ;
120+ mongoCluster = await MongoDBClusterProcess . spinUp ( configuration ) ;
190121 } , 120_000 ) ;
191122
192123 afterAll ( async function ( ) {
193- if ( isTestContainersCluster ( mongoCluster ) ) {
194- await mongoCluster . stop ( ) ;
195- } else {
196- await mongoCluster ?. close ( ) ;
197- }
124+ await mongoCluster ?. close ( ) ;
198125 mongoCluster = undefined ;
199126 } ) ;
200127
@@ -203,12 +130,7 @@ export function setupMongoDBIntegrationTest(
203130 throw new Error ( "beforeAll() hook not ran yet" ) ;
204131 }
205132
206- if ( isTestContainersCluster ( mongoCluster ) ) {
207- const mappedPort = mongoCluster . getMappedPort ( 27017 ) ;
208- return `mongodb://${ mongoCluster . getHost ( ) } :${ mappedPort } ` ;
209- }
210-
211- return mongoCluster . connectionString ;
133+ return mongoCluster . connectionString ( ) ;
212134 } ;
213135
214136 return {
@@ -219,7 +141,6 @@ export function setupMongoDBIntegrationTest(
219141 return mongoClient ;
220142 } ,
221143 connectionString : getConnectionString ,
222-
223144 randomDbName : ( ) => randomDbName ,
224145 } ;
225146}
0 commit comments