@@ -6,6 +6,7 @@ import * as reporter from "../../../../deploy/functions/release/reporter";
6
6
import * as executor from "../../../../deploy/functions/release/executor" ;
7
7
import * as gcfNSV2 from "../../../../gcp/cloudfunctionsv2" ;
8
8
import * as gcfNS from "../../../../gcp/cloudfunctions" ;
9
+ import * as eventarcNS from "../../../../gcp/eventarc" ;
9
10
import * as pollerNS from "../../../../operation-poller" ;
10
11
import * as pubsubNS from "../../../../gcp/pubsub" ;
11
12
import * as schedulerNS from "../../../../gcp/cloudscheduler" ;
@@ -24,6 +25,7 @@ describe("Fabricator", () => {
24
25
// Stub all GCP APIs to make sure this test is hermetic
25
26
let gcf : sinon . SinonStubbedInstance < typeof gcfNS > ;
26
27
let gcfv2 : sinon . SinonStubbedInstance < typeof gcfNSV2 > ;
28
+ let eventarc : sinon . SinonStubbedInstance < typeof eventarcNS > ;
27
29
let poller : sinon . SinonStubbedInstance < typeof pollerNS > ;
28
30
let pubsub : sinon . SinonStubbedInstance < typeof pubsubNS > ;
29
31
let scheduler : sinon . SinonStubbedInstance < typeof schedulerNS > ;
@@ -35,6 +37,7 @@ describe("Fabricator", () => {
35
37
beforeEach ( ( ) => {
36
38
gcf = sinon . stub ( gcfNS ) ;
37
39
gcfv2 = sinon . stub ( gcfNSV2 ) ;
40
+ eventarc = sinon . stub ( eventarcNS ) ;
38
41
poller = sinon . stub ( pollerNS ) ;
39
42
pubsub = sinon . stub ( pubsubNS ) ;
40
43
scheduler = sinon . stub ( schedulerNS ) ;
@@ -58,6 +61,10 @@ describe("Fabricator", () => {
58
61
gcfv2 . createFunction . rejects ( new Error ( "unexpected gcfv2.createFunction" ) ) ;
59
62
gcfv2 . updateFunction . rejects ( new Error ( "unexpected gcfv2.updateFunction" ) ) ;
60
63
gcfv2 . deleteFunction . rejects ( new Error ( "unexpected gcfv2.deleteFunction" ) ) ;
64
+ eventarc . createChannel . rejects ( new Error ( "unexpected eventarc.createChannel" ) ) ;
65
+ eventarc . deleteChannel . rejects ( new Error ( "unexpected eventarc.deleteChannel" ) ) ;
66
+ eventarc . getChannel . rejects ( new Error ( "unexpected eventarc.getChannel" ) ) ;
67
+ eventarc . updateChannel . rejects ( new Error ( "unexpected eventarc.updateChannel" ) ) ;
61
68
run . getIamPolicy . rejects ( new Error ( "unexpected run.getIamPolicy" ) ) ;
62
69
run . setIamPolicy . rejects ( new Error ( "unexpected run.setIamPolicy" ) ) ;
63
70
run . setInvokerCreate . rejects ( new Error ( "unexpected run.setInvokerCreate" ) ) ;
@@ -481,6 +488,97 @@ describe("Fabricator", () => {
481
488
) ;
482
489
} ) ;
483
490
491
+ it ( "handles already existing eventarc channels" , async ( ) => {
492
+ eventarc . createChannel . callsFake ( ( { name } ) => {
493
+ expect ( name ) . to . equal ( "channel" ) ;
494
+ const err = new Error ( "Already exists" ) ;
495
+ ( err as any ) . status = 409 ;
496
+ return Promise . reject ( err ) ;
497
+ } ) ;
498
+ gcfv2 . createFunction . resolves ( { name : "op" , done : false } ) ;
499
+ poller . pollOperation . resolves ( { serviceConfig : { service : "service" } } ) ;
500
+
501
+ const ep = endpoint (
502
+ {
503
+ eventTrigger : {
504
+ eventType : "custom.test.event" ,
505
+ channel : "channel" ,
506
+ retry : false ,
507
+ } ,
508
+ } ,
509
+ {
510
+ platform : "gcfv2" ,
511
+ }
512
+ ) ;
513
+
514
+ await fab . createV2Function ( ep ) ;
515
+ expect ( eventarc . createChannel ) . to . have . been . called ;
516
+ expect ( gcfv2 . createFunction ) . to . have . been . called ;
517
+ } ) ;
518
+
519
+ it ( "creates channels if necessary" , async ( ) => {
520
+ const channelName = "channel" ;
521
+ eventarc . createChannel . callsFake ( ( { name } ) => {
522
+ expect ( name ) . to . equal ( channelName ) ;
523
+ return Promise . resolve ( {
524
+ name : "op-resource-name" ,
525
+ metadata : {
526
+ createTime : "" ,
527
+ target : "" ,
528
+ verb : "" ,
529
+ requestedCancellation : false ,
530
+ apiVersion : "" ,
531
+ } ,
532
+ done : false ,
533
+ } ) ;
534
+ } ) ;
535
+ gcfv2 . createFunction . resolves ( { name : "op" , done : false } ) ;
536
+ poller . pollOperation . resolves ( { serviceConfig : { service : "service" } } ) ;
537
+
538
+ const ep = endpoint (
539
+ {
540
+ eventTrigger : {
541
+ eventType : "custom.test.event" ,
542
+ channel : channelName ,
543
+ retry : false ,
544
+ } ,
545
+ } ,
546
+ {
547
+ platform : "gcfv2" ,
548
+ }
549
+ ) ;
550
+
551
+ await fab . createV2Function ( ep ) ;
552
+ expect ( eventarc . createChannel ) . to . have . been . calledOnceWith ( { name : channelName } ) ;
553
+ expect ( poller . pollOperation ) . to . have . been . called ;
554
+ } ) ;
555
+
556
+ it ( "wraps errors thrown while creating channels" , async ( ) => {
557
+ eventarc . createChannel . callsFake ( ( ) => {
558
+ const err = new Error ( "🤷♂️" ) ;
559
+ ( err as any ) . status = 400 ;
560
+ return Promise . reject ( err ) ;
561
+ } ) ;
562
+
563
+ const ep = endpoint (
564
+ {
565
+ eventTrigger : {
566
+ eventType : "custom.test.event" ,
567
+ channel : "channel" ,
568
+ retry : false ,
569
+ } ,
570
+ } ,
571
+ {
572
+ platform : "gcfv2" ,
573
+ }
574
+ ) ;
575
+
576
+ await expect ( fab . createV2Function ( ep ) ) . to . eventually . be . rejectedWith (
577
+ reporter . DeploymentError ,
578
+ "upsert eventarc channel"
579
+ ) ;
580
+ } ) ;
581
+
484
582
it ( "throws on create function failure" , async ( ) => {
485
583
gcfv2 . createFunction . rejects ( new Error ( "Server failure" ) ) ;
486
584
@@ -1168,7 +1266,7 @@ describe("Fabricator", () => {
1168
1266
await fab . setTrigger ( endpoint ( { httpsTrigger : { } } ) ) ;
1169
1267
} ) ;
1170
1268
1171
- it ( "does nothing for event triggers" , async ( ) => {
1269
+ it ( "does nothing for event triggers without channels " , async ( ) => {
1172
1270
// all APIs throw by default
1173
1271
const ep = endpoint ( {
1174
1272
eventTrigger : {
0 commit comments