package Ġcom . nft co . flow . sdk . test Ċ Ċ import Ġcom . nft co . flow . sdk .* Ċ import Ġcom . nft co . flow . sdk . cad ence . StringField Ċ import Ġcom . nft co . flow . sdk . crypto . Crypto Ċ import Ġcom . nft co . flow . sdk . crypto . KeyPair Ċ import Ġcom . nft co . flow . sdk . impl . Async Flow Access Api Impl Ċ import Ġcom . nft co . flow . sdk . impl . Flow Access Api Impl Ċ import Ġorg . ap igu ard ian . api . API Ċ import Ġorg . junit . jupiter . api . extension . After Each Callback Ċ import Ġorg . junit . jupiter . api . extension . BeforeEach Callback Ċ import Ġorg . junit . jupiter . api . extension . Extension Context Ċ import Ġorg . junit . jupiter . api . extension . Test ExecutionException Handler Ċ import Ġjava . io . ByteArray InputStream Ċ import Ġjava . io . File Ċ import Ġjava . io . InputStream Ċ import Ġjava . lang . annotation . Inherited Ċ import Ġjava . lang . reflect . Field Ċ import Ġjava . math . BigDecimal Ċ import Ġjava . net . Inet Address Ċ import Ġjava . net . Server Socket Ċ import Ġjava . util . concurrent . TimeUnit Ċ Ċ @ Target ( Annotation Target . FIELD ) Ċ @ Retention ( Annotation Retention . RUNTIME ) Ċ @ Must Be Document ed Ċ @ Inherited Ċ @ API ( status Ġ= ĠAPI . Status . ST ABLE , Ġsince Ġ= Ġ" 5 . 0 ") Ċ annotation Ġclass ĠFlow Test Client Ċ Ċ @ Retention ( Annotation Retention . RUNTIME ) Ċ @ Must Be Document ed Ċ @ Inherited Ċ @ API ( status Ġ= ĠAPI . Status . ST ABLE , Ġsince Ġ= Ġ" 5 . 0 ") Ċ annotation Ġclass ĠFlow Em ulator Command ( ĊĠĠĠ Ġval Ġvalue : ĠString Ġ= Ġ" flow ", ĊĠĠĠ Ġval Ġexpected Exit Value : ĠInt Ġ= Ġ 0 , ĊĠĠĠ Ġval Ġthrow OnError : ĠBoolean Ġ= Ġtrue , ĊĠĠĠ Ġval Ġtimeout : ĠLong Ġ= Ġ 1 0 , ĊĠĠĠ Ġval Ġunit : ĠTimeUnit Ġ= ĠTimeUnit . SECONDS Ċ ) Ċ Ċ @ Target ( Annotation Target . FIELD ) Ċ @ Retention ( Annotation Retention . RUNTIME ) Ċ @ Must Be Document ed Ċ @ Inherited Ċ @ API ( status Ġ= ĠAPI . Status . ST ABLE , Ġsince Ġ= Ġ" 5 . 0 ") Ċ annotation Ġclass ĠFlow ServiceAccount Credentials Ċ Ċ @ Target ( Annotation Target . FIELD ) Ċ @ Retention ( Annotation Retention . RUNTIME ) Ċ @ Must Be Document ed Ċ @ Inherited Ċ @ API ( status Ġ= ĠAPI . Status . ST ABLE , Ġsince Ġ= Ġ" 5 . 0 ") Ċ annotation Ġclass ĠFlow Test Account ( ĊĠĠĠ Ġval Ġsign Algo : ĠSignature Algorithm Ġ= ĠSignature Algorithm . ECD SA _ SE CP 2 5 6 k 1 , ĊĠĠĠ Ġval Ġhash Algo : ĠHash Algorithm Ġ= ĠHash Algorithm . SHA 3 _ 2 5 6 , ĊĠĠĠ Ġval ĠpublicKey : ĠString Ġ= Ġ"", ĊĠĠĠ Ġval ĠprivateKey : ĠString Ġ= Ġ"", ĊĠĠĠ Ġval Ġbalance : ĠDouble Ġ= Ġ 0 . 0 1 , ĊĠĠĠ Ġval Ġcontracts : ĠArray < Flow Test Contract Deployment > Ġ= Ġ[] Ċ ) Ċ Ċ @ Retention ( Annotation Retention . RUNTIME ) Ċ @ Must Be Document ed Ċ @ Inherited Ċ @ API ( status Ġ= ĠAPI . Status . ST ABLE , Ġsince Ġ= Ġ" 5 . 0 ") Ċ annotation Ġclass ĠFlow Test Contract Deployment ( ĊĠĠĠ Ġval Ġname : ĠString , ĊĠĠĠ Ġval ĠaddTo Registry : ĠBoolean Ġ= Ġtrue , ĊĠĠĠ Ġval Ġcode : ĠString Ġ= Ġ"", ĊĠĠĠ Ġval Ġcode Classpath Location : ĠString Ġ= Ġ"", ĊĠĠĠ Ġval Ġcode File Location : ĠString Ġ= Ġ"", ĊĠĠĠ Ġval Ġgas Limit : ĠInt Ġ= Ġ 1 0 0 0 , ĊĠĠĠ Ġval Ġarguments : ĠArray < Test Contract Arg > Ġ= Ġ[] Ċ ) Ċ Ċ @ Retention ( Annotation Retention . RUNTIME ) Ċ @ Must Be Document ed Ċ @ Inherited Ċ @ API ( status Ġ= ĠAPI . Status . ST ABLE , Ġsince Ġ= Ġ" 5 . 0 ") Ċ annotation Ġclass ĠTest Contract Arg ( ĊĠĠĠ Ġval Ġname : ĠString , ĊĠĠĠ Ġval Ġvalue : ĠString Ċ ) Ċ Ċ data Ġclass ĠTest Contract Deployment ( ĊĠĠĠ Ġval Ġname : ĠString , ĊĠĠĠ Ġval Ġcode : ĠString , ĊĠĠĠ Ġval Ġargs : ĠMap < String , Ġcom . nft co . flow . sdk . cad ence . Field <* >> Ċ ) Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġfrom ( name : ĠString , Ġcode : Ġ() Ġ-> ĠInputStream , Ġargs : ĠMap < String , Ġcom . nft co . flow . sdk . cad ence . Field <* >> Ġ= Ġmap Of ()): ĠTest Contract Deployment Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠTest Contract Deployment ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġname , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcode Ġ= Ġcode (). use Ġ{ ĠString ( it . read All Bytes ()) Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġargs Ġ= Ġargs ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ data Ġclass ĠTest Account ( ĊĠĠĠ Ġval Ġaddress : ĠString , ĊĠĠĠ Ġval ĠprivateKey : ĠString , ĊĠĠĠ Ġval ĠpublicKey : ĠString , ĊĠĠĠ Ġval Ġsign Algo : ĠSignature Algorithm , ĊĠĠĠ Ġval Ġhash Algo : ĠHash Algorithm , ĊĠĠĠ Ġval Ġkey Index : ĠInt , ĊĠĠĠ Ġval Ġbalance : ĠBigDecimal Ċ ) Ġ{ ĊĠĠĠ Ġval Ġsigner : ĠSign er ĊĠĠĠĠĠĠĠ Ġget () Ġ= ĠCrypto . get Signer ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠprivateKey Ġ= ĠCrypto . decode PrivateKey ( privateKey , Ġsign Algo ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhash Algo Ġ= Ġhash Algo ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠ Ġval Ġflow Address : ĠFlow Address Ġget () Ġ= ĠFlow Address ( address ) ĊĊĠĠĠ Ġval ĠisValid : ĠBoolean Ġget () Ġ= Ġ! address . isEmpty () ĊĠĠĠĠĠĠĠ Ġ&& Ġ! privateKey . isEmpty () ĊĠĠĠĠĠĠĠ Ġ&& Ġ! publicKey . isEmpty () ĊĠĠĠĠĠĠĠ Ġ&& Ġsign Algo Ġ!= ĠSignature Algorithm . UNKNOWN ĊĠĠĠĠĠĠĠ Ġ&& Ġhash Algo Ġ!= ĠHash Algorithm . UNKNOWN ĊĠĠĠĠĠĠĠ Ġ&& Ġkey Index Ġ>= Ġ 0 Ċ } Ċ Ċ data Ġclass ĠEm ulator ( ĊĠĠĠ Ġval Ġprocess : ĠProcess , ĊĠĠĠ Ġval Ġpid File : ĠFile , ĊĠĠĠ Ġval Ġhost : ĠString , ĊĠĠĠ Ġval Ġport : ĠInt , ĊĠĠĠ Ġval Ġrest Port : ĠInt , ĊĠĠĠ Ġval Ġadmin Port : ĠInt , ĊĠĠĠ Ġval Ġservice Account : ĠTest Account Ċ ) Ċ Ċ abstract Ġclass ĠAbstract Flow Em ulator Extension Ġ: ĠBefore Each Callback , ĠAfter Each Callback , ĠTest ExecutionException Handler Ġ{ ĊĊĠĠĠ Ġvar Ġprocess : ĠProcess ? Ġ= Ġnull ĊĠĠĠ Ġvar Ġpid File : ĠFile ? Ġ= Ġnull ĊĠĠĠ Ġvar Ġaccess Api : ĠFlow Access Api Impl ? Ġ= Ġnull ĊĠĠĠ Ġvar Ġasync Access Api : ĠAsync Flow Access Api Impl ? Ġ= Ġnull ĊĊĠĠĠ Ġprotected Ġabstract Ġfun Ġlaunch Em ulator ( context : ĠExtension Context ): ĠEm ulator ĊĊĠĠĠ Ġprotected Ġfun Ġ< T Ġ: ĠAnnotation > Ġwith Annotated Test Fields ( context : ĠExtension Context , Ġclazz : ĠClass < T >, Ġblock : Ġ( Any , ĠField , ĠT ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtests Ġ= Ġ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . test Instances . map Ġ{ Ġit . all Instances . toSet () Ġ}. orElse Get Ġ{ Ġempty Set () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ+ Ġcontext . test Instance . map Ġ{ Ġset Of ( it ) Ġ}. orElse Get Ġ{ Ġempty Set () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġtests . map Ġ{ Ġit Ġto Ġit . java Class . fields Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ Ġit . second . map Ġ{ Ġf Ġ-> Ġit . first Ġto Ġf Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . second . is Annotation Present ( clazz ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġblock ( it . first , Ġit . second , Ġit . second . getAnnotation ( clazz )) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠbeforeEach ( context : ĠExtension Context ) Ġ{ ĊĊĠĠĠĠĠĠĠ ĠFlow . configure Defaults ( chain Id Ġ= ĠFlow Chain Id . EM UL ATOR ) ĊĊĠĠĠĠĠĠĠ Ġval Ġemulator Ġ= Ġlaunch Em ulator ( context ) ĊĠĠĠĠĠĠĠ Ġthis . process Ġ= Ġemulator . process ĊĠĠĠĠĠĠĠ Ġthis . pid File Ġ= Ġemulator . pid File ĊĊĠĠĠĠĠĠĠ Ġthis . access Api Ġ= ĠFlow . new Access Api ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhost Ġ= Ġemulator . host , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġport Ġ= Ġemulator . port ĊĠĠĠĠĠĠĠ Ġ) Ġas ĠFlow Access Api Impl ĊĊĠĠĠĠĠĠĠ Ġthis . async Access Api Ġ= ĠFlow . new Async Access Api ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhost Ġ= Ġemulator . host , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġport Ġ= Ġemulator . port ĊĠĠĠĠĠĠĠ Ġ) Ġas ĠAsync Flow Access Api Impl ĊĊĠĠĠĠĠĠĠ Ġwith Annotated Test Fields ( context , ĠFlow Test Client :: class . java ) Ġ{ Ġinstance , Ġfield , Ġ_ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( field . type . equals ( Flow Access Api :: class . java )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield . is Accessible Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield . set ( instance , Ġthis . access Api !! ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( field . type . equals ( Async Flow Access Api :: class . java )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield . is Accessible Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield . set ( instance , Ġasync Access Api ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" field Ġ$ field Ġis Ġnot Ġof Ġtype ĠFlow Access Api Ġor ĠAsync Flow Access AP i " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġwith Annotated Test Fields ( context , ĠFlow ServiceAccount Credentials :: class . java ) Ġ{ Ġinstance , Ġfield , Ġ_ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! field . type . equals ( Test Account :: class . java )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" field Ġ$ field Ġis Ġnot Ġof Ġtype ĠTest Account ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ(! emulator . service Account . isValid ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" FLOW ĠService Ġaccount Ġconfiguration Ġis Ġnot Ġvalid " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfield . is Accessible Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfield . set ( instance , Ġemulator . service Account ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġwith Annotated Test Fields ( context , ĠFlow Test Account :: class . java ) Ġ{ Ġinstance , Ġfield , Ġannotation Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! field . type . equals ( Test Account :: class . java )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" field Ġ$ field Ġis Ġnot Ġof Ġtype ĠTest Account ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ(! emulator . service Account . isValid ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" FLOW ĠService Ġaccount Ġconfiguration Ġis Ġnot Ġvalid , Ġcannot Ġcreate Ġa ĠFlow Test Account " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Pair Ġ= Ġif Ġ( annotation . privateKey . isEmpty () Ġ&& Ġannotation . publicKey . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCrypto . generate KeyPair ( annotation . sign Algo ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠKey Pair ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġ= ĠCrypto . decode PrivateKey ( annotation . privateKey , Ġannotation . sign Algo ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpublic Ġ= ĠCrypto . decode PublicKey ( annotation . publicKey , Ġannotation . sign Algo ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġaddress Ġ= ĠFlow TestUtil . create Account ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapi Ġ= Ġthis . access Api !! , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġservice Account Ġ= Ġemulator . service Account , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠpublicKey Ġ= Ġkey Pair . public . hex , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsign Algo Ġ= Ġannotation . sign Algo , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhash Algo Ġ= Ġannotation . hash Algo , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbalance Ġ= ĠBigDecimal ( annotation . balance ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtest Account Ġ= ĠTest Account ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaddress Ġ= Ġaddress . formatted , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠprivateKey Ġ= Ġkey Pair . private . hex , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠpublicKey Ġ= Ġkey Pair . public . hex , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsign Algo Ġ= Ġannotation . sign Algo , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhash Algo Ġ= Ġannotation . hash Algo , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkey Index Ġ= Ġ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbalance Ġ= ĠBigDecimal ( annotation . balance ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfield . is Accessible Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfield . set ( instance , Ġtest Account ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdeploy Ġcontracts ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( deploy able Ġin Ġannotation . contracts ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFlow TestUtil . deploy Contracts ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapi Ġ= Ġthis . access Api !! , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaccount Ġ= Ġtest Account , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgas Limit Ġ= Ġdeploy able . gas Limit , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTest Contract Deployment . from ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġdeploy able . name , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcode Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( deploy able . code File Location . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFile ( deploy able . code File Location ). inputStream () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( deploy able . code Classpath Location . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstance . java Class . getResource AsStream ( deploy able . code Classpath Location ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠByteArrayInputStream ( deploy able . code . toByteArray ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġargs Ġ= Ġdeploy able . arguments . associate Ġ{ Ġit . name Ġto ĠString Field ( it . value ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ). send And WaitFor Se al () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. throw OnError () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( deploy able . addTo Registry ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFlow . DEFAULT _ ADDRESS _ REGISTRY . register ( deploy able . name , Ġtest Account . flow Address , ĠFlow Chain Id . EM UL ATOR ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ ĠRuntime . get Runtime (). add Shutdown Hook ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠThread ( this :: shutdown Em ulator ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠafterEach ( context : ĠExtension Context ) Ġ= Ġshutdown Em ulator () ĊĊĠĠĠ Ġoverride Ġfun Ġhandle Test ExecutionException ( context : ĠExtension Context , Ġthrowable : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshutdown Em ulator () ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġthrowable ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshutdown Em ulator () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġapi Ġ= Ġthis . access Api ĊĠĠĠĠĠĠĠ Ġif Ġ( api Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġapi . close () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . access Api Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġasync Api Ġ= Ġasync Access Api ĊĠĠĠĠĠĠĠ Ġif Ġ( async Api Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġasync Api . close () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . async Access Api Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġproc Ġ= Ġprocess ĊĠĠĠĠĠĠĠ Ġif Ġ( proc Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġproc . destroy () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġcount Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ(! proc . waitFor ( 1 , ĠTimeUnit . SECONDS )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġproc . destroy For c ibly () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcount ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( count Ġ>= Ġ 6 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" Unable Ġto Ġterminate Ġflow Ġemulator Ġprocess ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( pid File Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpid File ?. delete () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpid File Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġprocess Ġ= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġfun Ġfind Free Port ( host : ĠString ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠServer Socket ( 0 , Ġ 5 0 , ĠInet Address . get ByName ( host )). use Ġ{ Ġit . local Port Ġ} ĊĠĠĠ Ġ} Ċ } Ċ