@@ -5,20 +5,24 @@ import * as admin from 'firebase-admin';
5
5
import * as functions from 'firebase-functions' ;
6
6
import * as fs from 'fs' ;
7
7
8
- import * as v1 from './v1/index' ;
9
- const numTests = Object . keys ( v1 ) . filter ( ( k ) =>
10
- ( { } . hasOwnProperty . call ( v1 [ k ] , '__endpoint' ) )
11
- ) . length ;
12
- export { v1 } ;
8
+ import * as v1 from './v1' ;
9
+ import * as v2 from './v2' ;
10
+ const getNumTests = ( m : object ) : number => {
11
+ return Object . keys ( m ) . filter ( ( k ) =>
12
+ ( { } . hasOwnProperty . call ( m [ k ] , '__endpoint' ) )
13
+ ) . length ;
14
+ } ;
15
+ const numTests = getNumTests ( v1 ) + getNumTests ( v2 ) ;
16
+ export { v1 , v2 } ;
13
17
14
18
import * as testLab from './v1/testLab-utils' ;
19
+ import { REGION } from './region' ;
15
20
16
21
const firebaseConfig = JSON . parse ( process . env . FIREBASE_CONFIG ) ;
17
- const REGION = functions . config ( ) . functions . test_region ;
18
22
admin . initializeApp ( ) ;
19
23
20
- function callHttpsTrigger ( name : string , data : any ) {
21
- return fetch (
24
+ async function callHttpsTrigger ( name : string , data : any ) {
25
+ const resp = await fetch (
22
26
`https://${ REGION } -${ firebaseConfig . projectId } .cloudfunctions.net/${ name } ` ,
23
27
{
24
28
method : 'POST' ,
@@ -28,19 +32,56 @@ function callHttpsTrigger(name: string, data: any) {
28
32
body : JSON . stringify ( { data } ) ,
29
33
}
30
34
) ;
35
+ if ( ! resp . ok ) {
36
+ throw Error ( resp . statusText ) ;
37
+ }
38
+ }
39
+
40
+ async function callV2HttpsTrigger (
41
+ name : string ,
42
+ data : any ,
43
+ accessToken : string
44
+ ) {
45
+ let resp = await fetch (
46
+ `https://cloudfunctions.googleapis.com/v2beta/projects/${ firebaseConfig . projectId } /locations/${ REGION } /functions/${ name } ` ,
47
+ {
48
+ headers : {
49
+ Authorization : `Bearer ${ accessToken } ` ,
50
+ } ,
51
+ }
52
+ ) ;
53
+ if ( ! resp . ok ) {
54
+ throw new Error ( resp . statusText ) ;
55
+ }
56
+ const fn = await resp . json ( ) ;
57
+ const uri = fn . serviceConfig ?. uri ;
58
+ if ( ! uri ) {
59
+ throw new Error ( `Cannot call v2 https trigger ${ name } - no uri found` ) ;
60
+ }
61
+ resp = await fetch ( uri , {
62
+ method : 'POST' ,
63
+ headers : {
64
+ 'Content-Type' : 'application/json' ,
65
+ } ,
66
+ body : JSON . stringify ( { data } ) ,
67
+ } ) ;
68
+ if ( ! resp . ok ) {
69
+ throw new Error ( resp . statusText ) ;
70
+ }
31
71
}
32
72
33
- async function callScheduleTrigger ( functionName : string , region : string ) {
34
- const accessToken = await admin . credential
35
- . applicationDefault ( )
36
- . getAccessToken ( ) ;
73
+ async function callScheduleTrigger (
74
+ functionName : string ,
75
+ region : string ,
76
+ accessToken : string
77
+ ) {
37
78
const response = await fetch (
38
79
`https://cloudscheduler.googleapis.com/v1/projects/${ firebaseConfig . projectId } /locations/us-central1/jobs/firebase-schedule-${ functionName } -${ region } :run` ,
39
80
{
40
81
method : 'POST' ,
41
82
headers : {
42
83
'Content-Type' : 'application/json' ,
43
- Authorization : `Bearer ${ accessToken . access_token } ` ,
84
+ Authorization : `Bearer ${ accessToken } ` ,
44
85
} ,
45
86
}
46
87
) ;
@@ -56,7 +97,7 @@ async function updateRemoteConfig(
56
97
testId : string ,
57
98
accessToken : string
58
99
) : Promise < void > {
59
- await fetch (
100
+ const resp = await fetch (
60
101
`https://firebaseremoteconfig.googleapis.com/v1/projects/${ firebaseConfig . projectId } /remoteConfig` ,
61
102
{
62
103
method : 'PUT' ,
@@ -69,9 +110,12 @@ async function updateRemoteConfig(
69
110
body : JSON . stringify ( { version : { description : testId } } ) ,
70
111
}
71
112
) ;
113
+ if ( ! resp . ok ) {
114
+ throw new Error ( resp . statusText ) ;
115
+ }
72
116
}
73
117
74
- function v1Tests ( testId : string , accessToken : string ) {
118
+ function v1Tests ( testId : string , accessToken : string ) : Promise < void > [ ] {
75
119
return [
76
120
// A database write to trigger the Firebase Realtime Database tests.
77
121
admin
@@ -109,9 +153,16 @@ function v1Tests(testId: string, accessToken: string) {
109
153
. storage ( )
110
154
. bucket ( )
111
155
. upload ( '/tmp/' + testId + '.txt' ) ,
112
- testLab . startTestRun ( firebaseConfig . projectId , testId ) ,
156
+ testLab . startTestRun ( firebaseConfig . projectId , testId , accessToken ) ,
113
157
// Invoke the schedule for our scheduled function to fire
114
- callScheduleTrigger ( 'v1-schedule' , 'us-central1' ) ,
158
+ callScheduleTrigger ( 'v1-schedule' , 'us-central1' , accessToken ) ,
159
+ ] ;
160
+ }
161
+
162
+ function v2Tests ( testId : string , accessToken : string ) : Promise < void > [ ] {
163
+ return [
164
+ // Invoke a callable HTTPS trigger.
165
+ callV2HttpsTrigger ( 'v2-callabletests' , { foo : 'bar' , testId } , accessToken ) ,
115
166
] ;
116
167
}
117
168
@@ -136,15 +187,21 @@ export const integrationTests: any = functions
136
187
const accessToken = await admin . credential
137
188
. applicationDefault ( )
138
189
. getAccessToken ( ) ;
139
- await Promise . all ( [ ...v1Tests ( testId , accessToken . access_token ) ] ) ;
190
+ await Promise . all ( [
191
+ ...v1Tests ( testId , accessToken . access_token ) ,
192
+ ...v2Tests ( testId , accessToken . access_token ) ,
193
+ ] ) ;
140
194
// On test completion, check that all tests pass and reply "PASS", or provide further details.
141
195
functions . logger . info ( 'Waiting for all tests to report they pass...' ) ;
142
196
await new Promise < void > ( ( resolve , reject ) => {
143
197
setTimeout ( ( ) => reject ( new Error ( 'Timeout' ) ) , 5 * 60 * 1000 ) ;
144
198
let testsExecuted = 0 ;
145
199
testIdRef . on ( 'child_added' , ( snapshot ) => {
200
+ if ( snapshot . key === 'timestamp' ) {
201
+ return ;
202
+ }
146
203
testsExecuted += 1 ;
147
- if ( snapshot . key != 'timestamp' && ! snapshot . val ( ) . passed ) {
204
+ if ( ! snapshot . val ( ) . passed ) {
148
205
reject (
149
206
new Error (
150
207
`test ${ snapshot . key } failed; see database for details.`
0 commit comments