package Ġcom . network nt . email . handler Ċ Ċ import Ġassert k . Assert Ċ import Ġassert k . assertions . contains Ċ import Ġassert k . assertions . isEqualTo Ċ import Ġcom . network nt . client . Http 2 Client Ċ import Ġcom . network nt . server . Server Ċ import Ġio . under tow . Under tow Options Ċ import Ġio . under tow . client . Client Callback Ċ import Ġio . under tow . client . Client Exchange Ċ import Ġio . under tow . client . Client Request Ċ import Ġio . under tow . client . ClientResponse Ċ import Ġio . under tow . util . Flex Base 6 4 Ċ import Ġio . under tow . util . Headers Ċ import Ġio . under tow . util . Http String Ċ import Ġio . under tow . util . Methods Ċ import Ġmu . Kotlin Logging Ċ import Ġorg . junit . jupiter . api . extension . After All Callback Ċ import Ġorg . junit . jupiter . api . extension . Before All Callback Ċ import Ġorg . junit . jupiter . api . extension . Extension Context Ċ import Ġorg . x nio . Option Map Ċ import Ġjava . io . IOException Ċ import Ġjava . net . Server Socket Ċ import Ġjava . net . URI Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . Count DownLatch Ċ import Ġjava . util . concurrent . atomic . Atomic Reference Ċ Ċ /** Ċ Ġ* ĠJ unit 5 ĠExtension Ġwhich Ġsets Ġup Ġa Ġlight - server ĠBefore All Ġtests Ġand Ġtear s Ġit Ġdown ĠAfter All . Ċ Ġ* ĠUse Ġwith Ġ`@ Extend With ( Light Test Server :: class )` Ċ Ġ* Ċ Ġ* ĠThe Ġfirst Ġtime Ġa Ġserver Ġis Ġstarted Ġin Ġa Ġparticular ĠVM , Ġa Ġrandom Ġport Ġis Ġassigned Ġto Ġit Ġto Ġavoid Ġcl ashes Ġbetween Ċ Ġ* Ġconcurrent Ġtest Ġruns Ġor Ġother Ġactive Ġservers . Ċ Ġ* Ċ Ġ* ĠThere Ġare Ġalso Ġstatic Ġutility Ġmethods Ġto Ġmake Ġrequests Ġto Ġthe Ġconfigured Ġserver . Ċ Ġ*/ Ċ class ĠLight Test Server () Ġ: ĠBefore All Callback , ĠAfter All Callback Ġ{ ĊĊĠĠĠ Ġ// ĠEXT ENSION ĠL IF E - CYCLE ĠMETHO DS ĊĊĠĠĠ Ġvar Ġold Is Dynamic Port : ĠBoolean ? Ġ= Ġnull ĊĠĠĠ Ġvar Ġold Https Port : ĠInt ? Ġ= Ġnull ĊĊĠĠĠ Ġ// ĠPatch ĠServer . config Ġand Ġstart Ġserver ĊĠĠĠ Ġoverride Ġfun Ġbefore All ( context : ĠExtension Context ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġold Is Dynamic Port Ġ= ĠServer . config . is Dynamic Port ĊĠĠĠĠĠĠĠ Ġold Https Port Ġ= ĠServer . config . https Port ĊĠĠĠĠĠĠĠ ĠServer . config . is Dynamic Port Ġ= Ġfalse ĊĠĠĠĠĠĠĠ ĠServer . config . https Port Ġ= Ġhttps Port ĊĠĠĠĠĠĠĠ ĠServer . start () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠStop Ġserver Ġand Ġun patch Ġconfig ĊĠĠĠ Ġoverride Ġfun Ġafter All ( context : ĠExtension Context ?) Ġ{ ĊĠĠĠĠĠĠĠ ĠServer . stop () ĊĠĠĠĠĠĠĠ ĠServer . config . is Dynamic Port Ġ= Ġold Is Dynamic Port !! ĊĠĠĠĠĠĠĠ ĠServer . config . https Port Ġ= Ġold Https Port !! ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġlog Ġ= ĠKotlin Logging . logger Ġ{} ĊĊĠĠĠĠĠĠĠ Ġ// ĠSERVER ĠSTATE ĊĊĠĠĠĠĠĠĠ Ġval Ġhttps Port Ġ= Ġrandom Free Port ( 4 0 0 0 0 , Ġ 6 0 0 0 0 ) ĊĠĠĠĠĠĠĠ Ġval ĠbaseUrl Ġ= Ġ" https :// localhost :$ https Port " ĊĊĊĠĠĠĠĠĠĠ Ġ// ĠMAKE ĠREQUEST S ĠTO ĠSERVER ĊĊĠĠĠĠĠĠĠ Ġ/** ĠMake Ġa ĠGET Ġrequest Ġto Ġthe Ġserver Ġmaintained Ġby Ġthis Ġextension . Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġmake GetRequest ( path : ĠString , Ġauth : ĠString ? Ġ= Ġnull ): ĠClient Response Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġmake Request ( path , ĠMethods . GET , Ġnull , Ġauth ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĠMake Ġa ĠPOST Ġrequest Ġto Ġthe Ġserver Ġmaintained Ġby Ġthis Ġextension . Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġmake Post Request ( path : ĠString , Ġbody : ĠString , Ġauth : ĠString ? Ġ= Ġnull ): ĠClient Response Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġmake Request ( path , ĠMethods . POST , Ġbody , Ġauth ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĠMake Ġa ĠPUT Ġrequest Ġto Ġthe Ġserver Ġmaintained Ġby Ġthis Ġextension . Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġmake Put Request ( path : ĠString , Ġbody : ĠString , Ġauth : ĠString ? Ġ= Ġnull ): ĠClient Response Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġmake Request ( path , ĠMethods . PUT , Ġbody , Ġauth ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĠMake Ġa ĠDELETE Ġrequest Ġto Ġthe Ġserver Ġmaintained Ġby Ġthis Ġextension . Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġmake Delete Request ( path : ĠString , Ġauth : ĠString ? Ġ= Ġnull ): ĠClient Response Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġmake Request ( path , ĠMethods . DELETE , Ġnull , Ġauth ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĠFinds Ġa Ġrandom Ġfree Ġport Ġby Ġattempting Ġto Ġlisten Ġon Ġrandom Ġports Ġuntil Ġit Ġsucceeds . Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġrandom Free Port ( min Port : ĠInt , Ġmax Port : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrandom Ġ= ĠRandom () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġport Ġ= Ġrandom . nextInt ( max Port Ġ- Ġmin Port ) Ġ+ Ġmin Port ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġss Ġ= ĠServer Socket ( port ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġss . close () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġport ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info Ġ{ Ġ" Port Ġ${ port } Ġwas Ġbusy " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĠMake Ġa Ġrequest Ġto Ġthe Ġserver Ġmaintained Ġby Ġthis Ġextension . Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġmake Request ( path : ĠString , Ġmethod : ĠHttp String , Ġbody : ĠString ?, Ġauth : ĠString ? Ġ= Ġnull ): ĠClient Response Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info Ġ{ Ġ"${ method } Ġ:: Ġ$ baseUrl Ġ:: Ġ${ path }" Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġclient Ġ= ĠHttp 2 Client . getInstance () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġclient . connect ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠURI ( baseUrl ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠHttp 2 Client . WORK ER , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠHttp 2 Client . SSL , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠHttp 2 Client . BUFFER _ POOL , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOption Map . create ( Under tow Options . ENABLE _ HTTP 2 , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ). get (). use Ġ{ Ġconnection Ġ-> ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠClient Request (). set Path ( path ). set Method ( method ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġauthenticate ( request , Ġauth ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġl atch Ġ= ĠCount DownLatch ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġreference Ġ= ĠAtomic Reference < ClientResponse >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcallback : ĠClient Callback < Client Exchange > ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( body Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcallback Ġ= Ġclient . create Client Callback ( reference , Ġl atch ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info Ġ{ Ġ" body : Ġ${ body }" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfirst Char Ġ= Ġif Ġ( body . length Ġ> Ġ 0 ) Ġbody [ 0 ] Ġelse Ġ'\ u 0 0 0 0 ' ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( first Char Ġ== Ġ'[' Ġ|| Ġfirst Char Ġ== Ġ'{ ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . request Headers . put ( Headers . CONTENT _ TYPE , Ġ" application / json ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . request Headers . put ( Headers . CONTENT _ TYPE , Ġ" text / plain ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . request Headers . put ( Headers . TRANSFER _ ENCODING , Ġ" chunk ed ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcallback Ġ= Ġclient . create Client Callback ( reference , Ġl atch , Ġbody ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconnection . send Request ( request , Ġcallback ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġl atch . await () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġreference . get () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info Ġ{ Ġ" Response Ġcode Ġ= Ġ${ response . response Code }" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info Ġ{ Ġ" Response Ġbody Ġ= Ġ${ response . get Attachment ( Http 2 Client . RESPONSE _ BODY )}" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresponse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġauthenticate ( request : ĠClient Request , Ġauth : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( auth Ġ== Ġnull ) Ġreturn ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info Ġ{ Ġ" auth Ġ= Ġ${ auth }" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbytes Ġ= Ġauth . toByteArray ( Charsets . UTF _ 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info Ġ{ Ġ" bytes Ġ= Ġ${ bytes }" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġencoded Ġ= ĠFlex Base 6 4 . encode String ( bytes , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info Ġ{ Ġ" encoded Ġ= Ġ${ encoded }" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . request Headers . add ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠHeaders . AUTHORIZATION , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Basic Ġ${ encoded }" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun ĠAssert < ClientResponse >. rc Is EqualTo ( expected : ĠInt ) Ġ= Ġgiven Ġ{ Ġactual Ġ-> ĊĠĠĠ ĠassertThat ( actual . response Code , Ġ" Response ĠCode "). isEqualTo ( expected ) Ċ } Ċ Ċ fun ĠAssert < ClientResponse >. body Is EqualTo ( expected : ĠString ) Ġ= Ġgiven Ġ{ Ġactual Ġ-> ĊĠĠĠ ĠassertThat ( actual . get Attachment ( com . network nt . client . Http 2 Client . RESPONSE _ BODY ), Ġ" Body "). isEqualTo ( expected ) Ċ } Ċ Ċ fun ĠAssert < ClientResponse >. body Contains ( expected : ĠString ) Ġ Ġ= Ġgiven Ġ{ actual Ġ-> ĊĠĠĠ ĠassertThat ( actual . get Attachment ( com . network nt . client . Http 2 Client . RESPONSE _ BODY ), Ġ" Body "). contains ( expected ) Ċ } Ċ