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