@@ -69,23 +69,28 @@ describe('functions/billing tests', () => {
6969 await handleLinuxFailures ( ffProc ) ;
7070 } ) ;
7171
72- it ( 'should notify Slack when budget is exceeded' , async ( ) => {
73- const jsonData = { costAmount : 500 , budgetAmount : 400 } ;
74- const encodedData = Buffer . from ( JSON . stringify ( jsonData ) ) . toString (
75- 'base64'
76- ) ;
77- const pubsubMessage = { data : encodedData , attributes : { } } ;
78-
79- const response = await requestRetry ( {
80- url : `${ BASE_URL } /notifySlack` ,
81- method : 'POST' ,
82- body : { data : pubsubMessage } ,
83- retryDelay : 200 ,
84- json : true ,
72+ describe ( 'functions_billing_slack' , ( ) => {
73+ it ( 'should notify Slack when budget is exceeded' , async ( ) => {
74+ const jsonData = { costAmount : 500 , budgetAmount : 400 } ;
75+ const encodedData = Buffer . from ( JSON . stringify ( jsonData ) ) . toString (
76+ 'base64'
77+ ) ;
78+ const pubsubMessage = { data : encodedData , attributes : { } } ;
79+
80+ const response = await requestRetry ( {
81+ url : `${ BASE_URL } /notifySlack` ,
82+ method : 'POST' ,
83+ body : { data : pubsubMessage } ,
84+ retryDelay : 200 ,
85+ json : true ,
86+ } ) ;
87+
88+ assert . strictEqual ( response . statusCode , 200 ) ;
89+ assert . strictEqual (
90+ response . body ,
91+ 'Slack notification sent successfully'
92+ ) ;
8593 } ) ;
86-
87- assert . strictEqual ( response . statusCode , 200 ) ;
88- assert . strictEqual ( response . body , 'Slack notification sent successfully' ) ;
8994 } ) ;
9095 } ) ;
9196
@@ -105,60 +110,64 @@ describe('functions/billing tests', () => {
105110 await handleLinuxFailures ( ffProc ) ;
106111 } ) ;
107112
108- it ( 'should disable billing when budget is exceeded' , async ( ) => {
109- // Use functions framework to ensure sample follows GCF specification
110- // (Invoking it directly works too, but DOES NOT ensure GCF compatibility)
113+ describe ( 'functions_billing_stop' , ( ) => {
114+ it ( 'should disable billing when budget is exceeded' , async ( ) => {
115+ // Use functions framework to ensure sample follows GCF specification
116+ // (Invoking it directly works too, but DOES NOT ensure GCF compatibility)
117+ const jsonData = { costAmount : 500 , budgetAmount : 400 } ;
118+ const encodedData = Buffer . from ( JSON . stringify ( jsonData ) ) . toString (
119+ 'base64'
120+ ) ;
121+ const pubsubMessage = { data : encodedData , attributes : { } } ;
122+
123+ const response = await requestRetry ( {
124+ url : `${ BASE_URL } /stopBilling` ,
125+ method : 'POST' ,
126+ body : { data : pubsubMessage } ,
127+ retryDelay : 200 ,
128+ json : true ,
129+ } ) ;
130+
131+ assert . strictEqual ( response . statusCode , 200 ) ;
132+ assert . ok ( response . body . includes ( 'Billing disabled' ) ) ;
133+ } ) ;
134+ } ) ;
135+ } ) ;
136+ } ) ;
137+
138+ describe ( 'shuts down GCE instances' , ( ) => {
139+ describe ( 'functions_billing_limit' , ( ) => {
140+ it ( 'should attempt to shut down GCE instances when budget is exceeded' , async ( ) => {
141+ // Mock GCE (because real GCE instances take too long to start/stop)
142+ const listInstancesResponseMock = {
143+ data : {
144+ items : [ { name : 'test-instance-1' , status : 'RUNNING' } ] ,
145+ } ,
146+ } ;
147+
148+ const computeMock = {
149+ instances : {
150+ list : sinon . stub ( ) . returns ( listInstancesResponseMock ) ,
151+ stop : sinon . stub ( ) . resolves ( { data : { } } ) ,
152+ } ,
153+ } ;
154+
155+ const googleapisMock = Object . assign ( { } , googleapis ) ;
156+ googleapisMock . google . compute = sinon . stub ( ) . returns ( computeMock ) ;
157+
158+ // Run test
111159 const jsonData = { costAmount : 500 , budgetAmount : 400 } ;
112160 const encodedData = Buffer . from ( JSON . stringify ( jsonData ) ) . toString (
113161 'base64'
114162 ) ;
115163 const pubsubMessage = { data : encodedData , attributes : { } } ;
116164
117- const response = await requestRetry ( {
118- url : `${ BASE_URL } /stopBilling` ,
119- method : 'POST' ,
120- body : { data : pubsubMessage } ,
121- retryDelay : 200 ,
122- json : true ,
123- } ) ;
165+ const sample = proxyquire ( '../' , { googleapis : googleapisMock } ) ; // kokoro-allow-mock
124166
125- assert . strictEqual ( response . statusCode , 200 ) ;
126- assert . ok ( response . body . includes ( 'Billing disabled' ) ) ;
127- } ) ;
128- } ) ;
129- } ) ;
167+ await sample . limitUse ( pubsubMessage ) ;
130168
131- describe ( 'shuts down GCE instances' , ( ) => {
132- it ( 'should attempt to shut down GCE instances when budget is exceeded' , async ( ) => {
133- // Mock GCE (because real GCE instances take too long to start/stop)
134- const listInstancesResponseMock = {
135- data : {
136- items : [ { name : 'test-instance-1' , status : 'RUNNING' } ] ,
137- } ,
138- } ;
139-
140- const computeMock = {
141- instances : {
142- list : sinon . stub ( ) . returns ( listInstancesResponseMock ) ,
143- stop : sinon . stub ( ) . resolves ( { data : { } } ) ,
144- } ,
145- } ;
146-
147- const googleapisMock = Object . assign ( { } , googleapis ) ;
148- googleapisMock . google . compute = sinon . stub ( ) . returns ( computeMock ) ;
149-
150- // Run test
151- const jsonData = { costAmount : 500 , budgetAmount : 400 } ;
152- const encodedData = Buffer . from ( JSON . stringify ( jsonData ) ) . toString (
153- 'base64'
154- ) ;
155- const pubsubMessage = { data : encodedData , attributes : { } } ;
156-
157- const sample = proxyquire ( '../' , { googleapis : googleapisMock } ) ; // kokoro-allow-mock
158-
159- await sample . limitUse ( pubsubMessage ) ;
160-
161- assert . strictEqual ( computeMock . instances . list . calledOnce , true ) ;
162- assert . ok ( computeMock . instances . stop . calledOnce ) ;
169+ assert . strictEqual ( computeMock . instances . list . calledOnce , true ) ;
170+ assert . ok ( computeMock . instances . stop . calledOnce ) ;
171+ } ) ;
163172 } ) ;
164173} ) ;
0 commit comments