@@ -9,6 +9,7 @@ import * as path from 'path';
9
9
import { setGlobalVariable } from './e2e/utils/env' ;
10
10
import { gitClean } from './e2e/utils/git' ;
11
11
import { createNpmRegistry } from './e2e/utils/registry' ;
12
+ import { AddressInfo , createServer } from 'net' ;
12
13
13
14
Error . stackTraceLimit = Infinity ;
14
15
@@ -122,118 +123,121 @@ if (testsToRun.length == allTests.length) {
122
123
setGlobalVariable ( 'argv' , argv ) ;
123
124
setGlobalVariable ( 'ci' , process . env [ 'CI' ] ?. toLowerCase ( ) === 'true' || process . env [ 'CI' ] === '1' ) ;
124
125
setGlobalVariable ( 'package-manager' , argv . yarn ? 'yarn' : 'npm' ) ;
125
- setGlobalVariable ( 'package-registry' , 'http://localhost:4873' ) ;
126
-
127
- const registryProcess = createNpmRegistry ( ) ;
128
- const secureRegistryProcess = createNpmRegistry ( true ) ;
129
-
130
- testsToRun
131
- . reduce ( ( previous , relativeName , testIndex ) => {
132
- // Make sure this is a windows compatible path.
133
- let absoluteName = path . join ( e2eRoot , relativeName ) ;
134
- if ( / ^ w i n / . test ( process . platform ) ) {
135
- absoluteName = absoluteName . replace ( / \\ / g, path . posix . sep ) ;
136
- }
137
-
138
- return previous . then ( ( ) => {
139
- currentFileName = relativeName . replace ( / \. t s $ / , '' ) ;
140
- const start = + new Date ( ) ;
141
-
142
- const module = require ( absoluteName ) ;
143
- const originalEnvVariables = {
144
- ...process . env ,
145
- } ;
146
-
147
- const fn : ( skipClean ?: ( ) => void ) => Promise < void > | void =
148
- typeof module == 'function'
149
- ? module
150
- : typeof module . default == 'function'
151
- ? module . default
152
- : ( ) => {
153
- throw new Error ( 'Invalid test module.' ) ;
154
- } ;
155
-
156
- let clean = true ;
157
- let previousDir = null ;
158
-
159
- return Promise . resolve ( )
160
- . then ( ( ) => printHeader ( currentFileName , testIndex ) )
161
- . then ( ( ) => ( previousDir = process . cwd ( ) ) )
162
- . then ( ( ) => logStack . push ( lastLogger ( ) . createChild ( currentFileName ) ) )
163
- . then ( ( ) => fn ( ( ) => ( clean = false ) ) )
164
- . then (
165
- ( ) => logStack . pop ( ) ,
166
- ( err ) => {
167
- logStack . pop ( ) ;
168
- throw err ;
169
- } ,
170
- )
171
- . then ( ( ) => console . log ( '----' ) )
172
- . then ( ( ) => {
173
- // If we're not in a setup, change the directory back to where it was before the test.
174
- // This allows tests to chdir without worrying about keeping the original directory.
175
- if ( ! allSetups . includes ( relativeName ) && previousDir ) {
176
- process . chdir ( previousDir ) ;
177
-
178
- // Restore env variables before each test.
179
- console . log ( ' Restoring original environment variables...' ) ;
180
- process . env = originalEnvVariables ;
181
- }
182
- } )
183
- . then ( ( ) => {
184
- // Only clean after a real test, not a setup step. Also skip cleaning if the test
185
- // requested an exception.
186
- if ( ! allSetups . includes ( relativeName ) && clean ) {
187
- logStack . push ( new logging . NullLogger ( ) ) ;
188
- return gitClean ( ) . then (
189
- ( ) => logStack . pop ( ) ,
190
- ( err ) => {
191
- logStack . pop ( ) ;
192
- throw err ;
193
- } ,
194
- ) ;
126
+
127
+ Promise . all ( [ findFreePort ( ) , findFreePort ( ) ] ) . then ( async ( [ httpPort , httpsPort ] ) => {
128
+ setGlobalVariable ( 'package-registry' , 'http://localhost:' + httpPort ) ;
129
+
130
+ const registryProcess = await createNpmRegistry ( httpPort , httpPort ) ;
131
+ const secureRegistryProcess = await createNpmRegistry ( httpPort , httpsPort , true ) ;
132
+
133
+ return testsToRun
134
+ . reduce ( ( previous , relativeName , testIndex ) => {
135
+ // Make sure this is a windows compatible path.
136
+ let absoluteName = path . join ( e2eRoot , relativeName ) ;
137
+ if ( / ^ w i n / . test ( process . platform ) ) {
138
+ absoluteName = absoluteName . replace ( / \\ / g, path . posix . sep ) ;
139
+ }
140
+
141
+ return previous . then ( ( ) => {
142
+ currentFileName = relativeName . replace ( / \. t s $ / , '' ) ;
143
+ const start = + new Date ( ) ;
144
+
145
+ const module = require ( absoluteName ) ;
146
+ const originalEnvVariables = {
147
+ ...process . env ,
148
+ } ;
149
+
150
+ const fn : ( skipClean ?: ( ) => void ) => Promise < void > | void =
151
+ typeof module == 'function'
152
+ ? module
153
+ : typeof module . default == 'function'
154
+ ? module . default
155
+ : ( ) => {
156
+ throw new Error ( 'Invalid test module.' ) ;
157
+ } ;
158
+
159
+ let clean = true ;
160
+ let previousDir = null ;
161
+
162
+ return Promise . resolve ( )
163
+ . then ( ( ) => printHeader ( currentFileName , testIndex ) )
164
+ . then ( ( ) => ( previousDir = process . cwd ( ) ) )
165
+ . then ( ( ) => logStack . push ( lastLogger ( ) . createChild ( currentFileName ) ) )
166
+ . then ( ( ) => fn ( ( ) => ( clean = false ) ) )
167
+ . then (
168
+ ( ) => logStack . pop ( ) ,
169
+ ( err ) => {
170
+ logStack . pop ( ) ;
171
+ throw err ;
172
+ } ,
173
+ )
174
+ . then ( ( ) => console . log ( '----' ) )
175
+ . then ( ( ) => {
176
+ // If we're not in a setup, change the directory back to where it was before the test.
177
+ // This allows tests to chdir without worrying about keeping the original directory.
178
+ if ( ! allSetups . includes ( relativeName ) && previousDir ) {
179
+ process . chdir ( previousDir ) ;
180
+
181
+ // Restore env variables before each test.
182
+ console . log ( ' Restoring original environment variables...' ) ;
183
+ process . env = originalEnvVariables ;
184
+ }
185
+ } )
186
+ . then ( ( ) => {
187
+ // Only clean after a real test, not a setup step. Also skip cleaning if the test
188
+ // requested an exception.
189
+ if ( ! allSetups . includes ( relativeName ) && clean ) {
190
+ logStack . push ( new logging . NullLogger ( ) ) ;
191
+ return gitClean ( ) . then (
192
+ ( ) => logStack . pop ( ) ,
193
+ ( err ) => {
194
+ logStack . pop ( ) ;
195
+ throw err ;
196
+ } ,
197
+ ) ;
198
+ }
199
+ } )
200
+ . then (
201
+ ( ) => printFooter ( currentFileName , start ) ,
202
+ ( err ) => {
203
+ printFooter ( currentFileName , start ) ;
204
+ console . error ( err ) ;
205
+ throw err ;
206
+ } ,
207
+ ) ;
208
+ } ) ;
209
+ } , Promise . resolve ( ) )
210
+ . then (
211
+ ( ) => {
212
+ registryProcess . kill ( ) ;
213
+ secureRegistryProcess . kill ( ) ;
214
+
215
+ console . log ( colors . green ( 'Done.' ) ) ;
216
+ process . exit ( 0 ) ;
217
+ } ,
218
+ ( err ) => {
219
+ console . log ( '\n' ) ;
220
+ console . error ( colors . red ( `Test "${ currentFileName } " failed...` ) ) ;
221
+ console . error ( colors . red ( err . message ) ) ;
222
+ console . error ( colors . red ( err . stack ) ) ;
223
+
224
+ registryProcess . kill ( ) ;
225
+ secureRegistryProcess . kill ( ) ;
226
+
227
+ if ( argv . debug ) {
228
+ console . log ( `Current Directory: ${ process . cwd ( ) } ` ) ;
229
+ console . log ( 'Will loop forever while you debug... CTRL-C to quit.' ) ;
230
+
231
+ /* eslint-disable no-constant-condition */
232
+ while ( 1 ) {
233
+ // That's right!
195
234
}
196
- } )
197
- . then (
198
- ( ) => printFooter ( currentFileName , start ) ,
199
- ( err ) => {
200
- printFooter ( currentFileName , start ) ;
201
- console . error ( err ) ;
202
- throw err ;
203
- } ,
204
- ) ;
205
- } ) ;
206
- } , Promise . resolve ( ) )
207
- . then (
208
- ( ) => {
209
- registryProcess . kill ( ) ;
210
- secureRegistryProcess . kill ( ) ;
211
-
212
- console . log ( colors . green ( 'Done.' ) ) ;
213
- process . exit ( 0 ) ;
214
- } ,
215
- ( err ) => {
216
- console . log ( '\n' ) ;
217
- console . error ( colors . red ( `Test "${ currentFileName } " failed...` ) ) ;
218
- console . error ( colors . red ( err . message ) ) ;
219
- console . error ( colors . red ( err . stack ) ) ;
220
-
221
- registryProcess . kill ( ) ;
222
- secureRegistryProcess . kill ( ) ;
223
-
224
- if ( argv . debug ) {
225
- console . log ( `Current Directory: ${ process . cwd ( ) } ` ) ;
226
- console . log ( 'Will loop forever while you debug... CTRL-C to quit.' ) ;
227
-
228
- /* eslint-disable no-constant-condition */
229
- while ( 1 ) {
230
- // That's right!
231
235
}
232
- }
233
236
234
- process . exit ( 1 ) ;
235
- } ,
236
- ) ;
237
+ process . exit ( 1 ) ;
238
+ } ,
239
+ ) ;
240
+ } ) ;
237
241
238
242
function printHeader ( testName : string , testIndex : number ) {
239
243
const text = `${ testIndex + 1 } of ${ testsToRun . length } ` ;
@@ -257,3 +261,21 @@ function printFooter(testName: string, startTime: number) {
257
261
console . log ( colors . green ( 'Last step took ' ) + colors . bold . blue ( '' + t ) + colors . green ( 's...' ) ) ;
258
262
console . log ( '' ) ;
259
263
}
264
+
265
+ async function findFreePort ( ) : Promise < number > {
266
+ return new Promise ( ( resolve , reject ) => {
267
+ const srv = createServer ( ( sock ) => {
268
+ sock . end ( ( ) =>
269
+ srv . close ( ( err ) => {
270
+ if ( err ) {
271
+ reject ( err ) ;
272
+ } else {
273
+ resolve ( ( srv . address ( ) as AddressInfo ) . port ) ;
274
+ }
275
+ } ) ,
276
+ ) ;
277
+
278
+ srv . listen ( 0 ) ;
279
+ } ) ;
280
+ } ) ;
281
+ }
0 commit comments