@@ -13,6 +13,7 @@ import { LegacyFunctionLoader } from '../../src/LegacyFunctionLoader';
13
13
import { WorkerChannel } from '../../src/WorkerChannel' ;
14
14
import { Msg as AppStartMsg } from '../startApp.test' ;
15
15
import { beforeEventHandlerSuite } from './beforeEventHandlerSuite' ;
16
+ import { Msg as WorkerTerminateMsg } from './terminateWorker.test' ;
16
17
import { TestEventStream } from './TestEventStream' ;
17
18
import { Msg as WorkerInitMsg } from './WorkerInitHandler.test' ;
18
19
import LogCategory = rpc . RpcLog . RpcLogCategory ;
@@ -333,13 +334,15 @@ describe('InvocationHandler', () => {
333
334
let channel : WorkerChannel ;
334
335
let coreApi : typeof coreTypes ;
335
336
let testDisposables : coreTypes . Disposable [ ] = [ ] ;
337
+ let processExitStub : sinon . SinonStub ;
336
338
337
339
before ( async ( ) => {
338
340
const result = beforeEventHandlerSuite ( ) ;
339
341
stream = result . stream ;
340
342
loader = < TestFunctionLoader > result . loader ;
341
343
channel = result . channel ;
342
344
coreApi = await import ( '@azure/functions-core' ) ;
345
+ processExitStub = sinon . stub ( process , 'exit' ) ;
343
346
} ) ;
344
347
345
348
beforeEach ( async ( ) => {
@@ -354,6 +357,10 @@ describe('InvocationHandler', () => {
354
357
testDisposables = [ ] ;
355
358
} ) ;
356
359
360
+ after ( ( ) => {
361
+ processExitStub . restore ( ) ;
362
+ } ) ;
363
+
357
364
function sendInvokeMessage ( inputData ?: rpc . IParameterBinding [ ] | null ) : void {
358
365
stream . addTestMessage ( {
359
366
requestId : 'testReqId' ,
@@ -924,6 +931,57 @@ describe('InvocationHandler', () => {
924
931
expect ( hookData ) . to . equal ( 'appStartpreInvocpostInvoc' ) ;
925
932
} ) ;
926
933
934
+ it ( 'appHookData changes from invocation hooks are persisted in app terminate hook contexts' , async ( ) => {
935
+ const expectedAppHookData = {
936
+ hello : 'world' ,
937
+ test : {
938
+ test2 : 3 ,
939
+ } ,
940
+ } ;
941
+
942
+ loader . getFunction . returns ( { callback : async ( ) => { } , metadata : Binding . queue } ) ;
943
+
944
+ testDisposables . push (
945
+ coreApi . registerHook ( 'preInvocation' , ( context : coreTypes . PreInvocationContext ) => {
946
+ Object . assign ( context . appHookData , expectedAppHookData ) ;
947
+ hookData += 'preInvoc' ;
948
+ } )
949
+ ) ;
950
+
951
+ testDisposables . push (
952
+ coreApi . registerHook ( 'postInvocation' , ( context : coreTypes . PostInvocationContext ) => {
953
+ expect ( context . appHookData ) . to . deep . equal ( expectedAppHookData ) ;
954
+ hookData += 'postInvoc' ;
955
+ } )
956
+ ) ;
957
+
958
+ sendInvokeMessage ( [ InputData . http ] ) ;
959
+ await stream . assertCalledWith (
960
+ Msg . receivedInvocLog ( ) ,
961
+ Msg . executingHooksLog ( 1 , 'preInvocation' ) ,
962
+ Msg . executedHooksLog ( 'preInvocation' ) ,
963
+ Msg . executingHooksLog ( 1 , 'postInvocation' ) ,
964
+ Msg . executedHooksLog ( 'postInvocation' ) ,
965
+ Msg . invocResponse ( [ ] )
966
+ ) ;
967
+
968
+ const terminateFunc = sinon . spy ( ( context : coreTypes . AppTerminateContext ) => {
969
+ expect ( context . appHookData ) . to . deep . equal ( expectedAppHookData ) ;
970
+ hookData += 'appTerminate' ;
971
+ } ) ;
972
+ testDisposables . push ( coreApi . registerHook ( 'appTerminate' , terminateFunc ) ) ;
973
+
974
+ stream . addTestMessage ( WorkerTerminateMsg . workerTerminate ( ) ) ;
975
+
976
+ await stream . assertCalledWith (
977
+ WorkerTerminateMsg . receivedWorkerTerminateLog ,
978
+ AppStartMsg . executingHooksLog ( 1 , 'appTerminate' ) ,
979
+ AppStartMsg . executedHooksLog ( 'appTerminate' )
980
+ ) ;
981
+ expect ( terminateFunc . callCount ) . to . be . equal ( 1 ) ;
982
+ expect ( hookData ) . to . equal ( 'preInvocpostInvocappTerminate' ) ;
983
+ } ) ;
984
+
927
985
it ( 'hookData changes from appStart hooks are not persisted in invocation hook contexts' , async ( ) => {
928
986
const functionAppDirectory = __dirname ;
929
987
const startFunc = sinon . spy ( ( context : coreTypes . AppStartContext ) => {
@@ -982,6 +1040,61 @@ describe('InvocationHandler', () => {
982
1040
expect ( hookData ) . to . equal ( 'appStartpreInvocpostInvoc' ) ;
983
1041
} ) ;
984
1042
1043
+ it ( 'hookData changes from invocation hooks are not persisted in app terminate contexts' , async ( ) => {
1044
+ const expectedAppHookData = {
1045
+ hello : 'world' ,
1046
+ test : {
1047
+ test2 : 3 ,
1048
+ } ,
1049
+ } ;
1050
+
1051
+ loader . getFunction . returns ( { callback : async ( ) => { } , metadata : Binding . queue } ) ;
1052
+
1053
+ testDisposables . push (
1054
+ coreApi . registerHook ( 'preInvocation' , ( context : coreTypes . PreInvocationContext ) => {
1055
+ Object . assign ( context . hookData , expectedAppHookData ) ;
1056
+ expect ( context . appHookData ) . to . be . empty ;
1057
+ hookData += 'preInvoc' ;
1058
+ } )
1059
+ ) ;
1060
+
1061
+ testDisposables . push (
1062
+ coreApi . registerHook ( 'postInvocation' , ( context : coreTypes . PostInvocationContext ) => {
1063
+ expect ( context . hookData ) . to . deep . equal ( expectedAppHookData ) ;
1064
+ expect ( context . appHookData ) . to . be . empty ;
1065
+ hookData += 'postInvoc' ;
1066
+ } )
1067
+ ) ;
1068
+
1069
+ sendInvokeMessage ( [ InputData . http ] ) ;
1070
+ await stream . assertCalledWith (
1071
+ Msg . receivedInvocLog ( ) ,
1072
+ Msg . executingHooksLog ( 1 , 'preInvocation' ) ,
1073
+ Msg . executedHooksLog ( 'preInvocation' ) ,
1074
+ Msg . executingHooksLog ( 1 , 'postInvocation' ) ,
1075
+ Msg . executedHooksLog ( 'postInvocation' ) ,
1076
+ Msg . invocResponse ( [ ] )
1077
+ ) ;
1078
+
1079
+ const terminateFunc = sinon . spy ( ( context : coreTypes . AppTerminateContext ) => {
1080
+ expect ( context . appHookData ) . to . be . empty ;
1081
+ expect ( context . hookData ) . to . be . empty ;
1082
+ hookData += 'appTerminate' ;
1083
+ } ) ;
1084
+ testDisposables . push ( coreApi . registerHook ( 'appTerminate' , terminateFunc ) ) ;
1085
+
1086
+ stream . addTestMessage ( WorkerTerminateMsg . workerTerminate ( ) ) ;
1087
+
1088
+ await stream . assertCalledWith (
1089
+ WorkerTerminateMsg . receivedWorkerTerminateLog ,
1090
+ AppStartMsg . executingHooksLog ( 1 , 'appTerminate' ) ,
1091
+ AppStartMsg . executedHooksLog ( 'appTerminate' )
1092
+ ) ;
1093
+
1094
+ expect ( terminateFunc . callCount ) . to . be . equal ( 1 ) ;
1095
+ expect ( hookData ) . to . equal ( 'preInvocpostInvocappTerminate' ) ;
1096
+ } ) ;
1097
+
985
1098
it ( 'appHookData changes are persisted between invocation-level hooks' , async ( ) => {
986
1099
const expectedAppHookData = {
987
1100
hello : 'world' ,
0 commit comments