/** Ċ Ġ* ĠCopyright Ġ 2 0 1 8 ĠRo yal ĠBank Ġof ĠS co tl and Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ package Ġio . blue bank . bra id . client . inv ocations . impl Ċ Ċ import Ġio . blue bank . bra id . core . jsonrpc . Json RPC ErrorResponse Ċ import Ġio . blue bank . bra id . core . jsonrpc . Json RPC Result Response Ċ import Ġio . blue bank . bra id . core . logging . logger For Ċ import Ġorg . junit . Test Ċ import Ġkotlin . reflect . jvm . java Method Ċ import Ġkotlin . test . assertEquals Ċ import Ġkotlin . test . assert Fails With Ċ import Ġkotlin . test . assertFalse Ċ import Ġkotlin . test . assertTrue Ċ Ċ class ĠFuture Invocation Strategy Test Ġ{ ĊĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠ Ġprivate Ġval Ġlog Ġ= Ġlogger For < Future Invocation Strategy Test >() ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġ` that Ġif ĠInv ocations Ġprovides Ġthe Ġwrong ĠrequestId Ġan Ġexception Ġis Ġraised `() Ġ{ ĊĠĠĠ Ġval Ġinv ocations Ġ= ĠMock Inv ocations () ĊĊĠĠĠ Ġval Ġstrategy Ġ= ĠFuture Invocation Strategy ( ĊĠĠĠĠĠ Ġinv ocations , ĊĠĠĠĠĠ ĠTest Interface :: test Future . name , ĊĠĠĠĠĠ ĠTest Interface :: test Future . java Method ?. generic ReturnType !! , ĊĠĠĠĠĠ ĠarrayOf () ĊĠĠĠ Ġ) ĊĠĠĠ Ġval Ġfuture Ġ= Ġstrategy . getResult () Ġ// Ġk icks Ġoff Ġthe Ġinvocation ĊĠĠĠ ĠassertEquals ( 1 , Ġinv ocations . active Requests Count , Ġ" that Ġthere Ġis Ġone Ġactive Ġrequest ") ĊĠĠĠ ĠassertEquals ( ĊĠĠĠĠĠ Ġstrategy , ĊĠĠĠĠĠ Ġinv ocations . get Invocation Strategy ( inv ocations . last RequestId ), ĊĠĠĠĠĠ Ġ" that Ġthe Ġstrategy Ġis Ġour Ġfuture Ġstrategy " ĊĠĠĠ Ġ) ĊĠĠĠ ĠassertFalse ( future . is Complete , Ġ" that Ġthe Ġfuture Ġshould Ġnot Ġhave Ġcompleted ") ĊĊĠĠĠ Ġ// Ġsimulate Ġreceiving Ġa Ġmessage Ġthat Ġthe Ġinvocation Ġhas Ġnever Ġbeen ĊĠĠĠ Ġinv ocations . receive ( Json RPC Result Response ( id Ġ= Ġ 2 , Ġresult Ġ= Ġ" dod gy Ġresult ")) ĊĠĠĠ ĠassertEquals ( ĊĠĠĠĠĠĠ 1 , ĊĠĠĠĠĠ Ġinv ocations . active Requests Count , ĊĠĠĠĠĠ Ġ" that Ġthere Ġis Ġstill Ġone Ġactive Ġrequest " ĊĠĠĠ Ġ) ĊĠĠĠ ĠassertEquals ( ĊĠĠĠĠĠ Ġstrategy , ĊĠĠĠĠĠ Ġinv ocations . get Invocation Strategy ( inv ocations . last RequestId ), ĊĠĠĠĠĠ Ġ" that Ġthe Ġstrategy Ġis Ġour Ġfuture Ġstrategy " ĊĠĠĠ Ġ) ĊĠĠĠ ĠassertFalse ( future . is Complete , Ġ" that Ġthe Ġfuture Ġshould Ġnot Ġhave Ġcompleted ") ĊĊĠĠĠ Ġ// Ġnow Ġlet 's Ġassume Ġthat ĠInv ocations Impl Ġhas Ġbroken Ġ- Ġdoes Ġthe Ġfuture Ġstrategy Ġdeal Ġwith Ġdod gy ĠrequestId ĊĠĠĠ Ġ// Ġsend Ġin Ġa Ġresponse Ġbut Ġon Ġa Ġdifferent ĠrequestId Ġ- Ġthis Ġshould Ġthrow Ġan Ġexception ĊĠĠĠ Ġassert Fails With < IllegalStateException > Ġ{ ĊĠĠĠĠĠ Ġstrategy . onNext ( ĊĠĠĠĠĠĠĠĠ 2 , ĊĠĠĠĠĠĠĠ Ġ" this Ġshould Ġthrow Ġbecause Ġof Ġthe ĠrequestId Ġnot Ġmatching " ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġassert Fails With < IllegalStateException > Ġ{ ĊĠĠĠĠĠ Ġstrategy . onError ( ĊĠĠĠĠĠĠĠĠ 2 , ĊĠĠĠĠĠĠĠ ĠException (" this Ġshould Ġalso Ġthrow Ġbecause Ġof Ġthe ĠrequestId Ġnot Ġmatching ") ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġassert Fails With < IllegalStateException > Ġ{ Ġstrategy . on Completed ( 2 ) Ġ} ĊĊĠĠĠ Ġ// Ġnow Ġtry Ġcomplet ing Ġthe Ġfuture ĊĠĠĠ Ġinv ocations . receive ( Json RPC Result Response ( id Ġ= Ġ 1 , Ġresult Ġ= Ġ" pi ")) ĊĠĠĠ ĠassertEquals ( ĊĠĠĠĠĠĠ 0 , ĊĠĠĠĠĠ Ġinv ocations . active Requests Count , ĊĠĠĠĠĠ Ġ" that Ġthe Ġinvocation Ġhas Ġbeen Ġcompleted " ĊĠĠĠ Ġ) ĊĠĠĠ ĠassertTrue ( future . is Complete , Ġ" that Ġthe Ġfuture Ġshould Ġnot Ġhave Ġcompleted ") ĊĠĠĠ ĠassertEquals (" pi ", Ġfuture . result ()) ĊĊĠĠĠ Ġ// Ġnow Ġlet 's Ġimagine Ġwe Ġget Ġmessages Ġfor Ġa Ġcompleted Ġfuture ĊĠĠĠ Ġassert Fails With < IllegalStateException > Ġ{ ĊĠĠĠĠĠ Ġstrategy . onNext ( ĊĠĠĠĠĠĠĠĠ 1 , ĊĠĠĠĠĠĠĠ Ġ" this Ġshould Ġthrow Ġbecause Ġfuture Ġis Ġalready Ġcompleted " ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġassert Fails With < IllegalStateException > Ġ{ ĊĠĠĠĠĠ Ġstrategy . onError ( ĊĠĠĠĠĠĠĠĠ 1 , ĊĠĠĠĠĠĠĠ ĠException (" this Ġthrows Ġbecause Ġfuture Ġis Ġalready Ġcompleted ") ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġ// Ġwe Ġshould Ġbe Ġable Ġto Ġcall Ġthe Ġon Completed Ġmessage Ġfor Ġcomplet eness Ġ- Ġthis Ġshouldn 't Ġbe Ġcalled Ġever Ġby Ġthe Ġprotocol ĊĠĠĠ Ġ// Ġnever Ġthe Ġless , Ġwe Ġcheck Ġthat Ġthe Ġ[ Invocation Strategy ] Ġinternal ĠAPI Ġis Ġconsistent ĊĠĠĠ Ġstrategy . on Completed ( 1 ) ĊĊĠĠĠ Ġ// Ġbut Ġa Ġsecond Ġtime Ġshould Ġraise Ġan Ġinternal Ġerror ĊĠĠĠ Ġassert Fails With < IllegalStateException > Ġ{ Ġstrategy . on Completed ( 1 ) Ġ} ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġ` that Ġan Ġinvocation Ġcan Ġend Ġwith Ġerror `() Ġ{ ĊĠĠĠ Ġval Ġinv ocations Ġ= ĠMock Inv ocations () ĊĠĠĠ Ġval Ġstrategy Ġ= ĠFuture Invocation Strategy ( ĊĠĠĠĠĠ Ġinv ocations , ĊĠĠĠĠĠ ĠTest Interface :: test Future . name , ĊĠĠĠĠĠ ĠTest Interface :: test Future . java Method ?. generic ReturnType !! , ĊĠĠĠĠĠ ĠarrayOf () ĊĠĠĠ Ġ) ĊĠĠĠ Ġval Ġfuture Ġ= Ġstrategy . getResult () Ġ// Ġk icks Ġoff Ġthe Ġinvocation ĊĠĠĠ ĠassertEquals ( 1 , Ġinv ocations . active Requests Count , Ġ" that Ġthere Ġis Ġone Ġactive Ġrequest ") ĊĠĠĠ ĠassertEquals ( ĊĠĠĠĠĠ Ġstrategy , ĊĠĠĠĠĠ Ġinv ocations . get Invocation Strategy ( inv ocations . last RequestId ), ĊĠĠĠĠĠ Ġ" that Ġthe Ġstrategy Ġis Ġour Ġfuture Ġstrategy " ĊĠĠĠ Ġ) ĊĠĠĠ ĠassertFalse ( future . is Complete , Ġ" that Ġthe Ġfuture Ġshould Ġnot Ġhave Ġcompleted ") ĊĠĠĠ Ġ// Ġsimulate Ġreceiving Ġan Ġexception Ġmessage Ġthat Ġthe Ġinvocation Ġhas Ġnever Ġbeen ĊĠĠĠ Ġinv ocations . receive ( ĊĠĠĠĠĠ ĠJson RPC ErrorResponse . internal Error ( ĊĠĠĠĠĠĠĠ Ġid Ġ= Ġ 1 , ĊĠĠĠĠĠĠĠ Ġmessage Ġ= Ġ" exception !" ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ) ĊĠĠĠ ĠassertEquals ( ĊĠĠĠĠĠĠ 0 , ĊĠĠĠĠĠ Ġinv ocations . active Requests Count , ĊĠĠĠĠĠ Ġ" that Ġthere Ġis Ġstill Ġone Ġactive Ġrequest " ĊĠĠĠ Ġ) ĊĠĠĠ ĠassertTrue ( future . failed (), Ġ" that Ġthe Ġfuture Ġshould Ġnot Ġhave Ġcompleted ") ĊĠĠĠ ĠassertEquals (" exception !", Ġfuture . cause (). message ) ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġ` that Ġwe Ġtrap Ġexceptions Ġfrom Ġa Ġfuture Ġhandler Ġthat Ġthrows Ġexception Ġon Ġhandling Ġan Ġinvocation Ġresult `() Ġ{ ĊĠĠĠ Ġval Ġinv ocations Ġ= ĠMock Inv ocations () ĊĠĠĠ Ġval Ġstrategy Ġ= ĠFuture Invocation Strategy ( ĊĠĠĠĠĠ Ġinv ocations , ĊĠĠĠĠĠ ĠTest Interface :: test Future . name , ĊĠĠĠĠĠ ĠTest Interface :: test Future . java Method ?. generic ReturnType !! , ĊĠĠĠĠĠ ĠarrayOf () ĊĠĠĠ Ġ) ĊĠĠĠ Ġval Ġfuture Ġ= Ġstrategy . getResult () Ġ// Ġk icks Ġoff Ġthe Ġinvocation ĊĊĠĠĠ Ġ// Ġhandler Ġis Ġfault y Ġand Ġthrows Ġan Ġexception Ġ- Ġwe Ġare Ġtesting Ġthat Ġwe Ġcorrectly Ġreport Ġthis Ġup ĊĠĠĠ Ġfuture . set Handler Ġ{ Ġthrow ĠRuntimeException (" oh Ġoh !") Ġ} ĊĊĠĠĠ ĠassertEquals ( 1 , Ġinv ocations . active Requests Count , Ġ" that Ġthere Ġis Ġone Ġactive Ġrequest ") ĊĠĠĠ ĠassertEquals ( ĊĠĠĠĠĠ Ġstrategy , ĊĠĠĠĠĠ Ġinv ocations . get Invocation Strategy ( inv ocations . last RequestId ), ĊĠĠĠĠĠ Ġ" that Ġthe Ġstrategy Ġis Ġour Ġfuture Ġstrategy " ĊĠĠĠ Ġ) ĊĠĠĠ ĠassertFalse ( future . is Complete , Ġ" that Ġthe Ġfuture Ġshould Ġnot Ġhave Ġcompleted ") ĊĊĠĠĠ Ġ// Ġsimulate Ġreceiving Ġthe Ġresult ĊĠĠĠ Ġassert Fails With < RuntimeException > Ġ{ Ġstrategy . onNext ( 1 , Ġ" result ") Ġ} ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġ` that Ġwe Ġtrap Ġexceptions Ġfrom Ġa Ġfuture Ġhandler Ġthat Ġthrows Ġexception Ġon Ġhandling Ġan Ġinvocation Ġexception `() Ġ{ ĊĠĠĠ Ġval Ġinv ocations Ġ= ĠMock Inv ocations () ĊĠĠĠ Ġval Ġstrategy Ġ= ĠFuture Invocation Strategy ( ĊĠĠĠĠĠ Ġinv ocations , ĊĠĠĠĠĠ ĠTest Interface :: test Future . name , ĊĠĠĠĠĠ ĠTest Interface :: test Future . java Method ?. generic ReturnType !! , ĊĠĠĠĠĠ ĠarrayOf () ĊĠĠĠ Ġ) ĊĠĠĠ Ġval Ġfuture Ġ= Ġstrategy . getResult () Ġ// Ġk icks Ġoff Ġthe Ġinvocation ĊĊĠĠĠ Ġ// Ġhandler Ġis Ġfault y Ġand Ġthrows Ġan Ġexception Ġ- Ġwe Ġare Ġtesting Ġthat Ġwe Ġcorrectly Ġreport Ġthis Ġup ĊĠĠĠ Ġfuture . set Handler Ġ{ Ġthrow ĠRuntimeException (" oh Ġoh !") Ġ} ĊĊĠĠĠ ĠassertEquals ( 1 , Ġinv ocations . active Requests Count , Ġ" that Ġthere Ġis Ġone Ġactive Ġrequest ") ĊĠĠĠ ĠassertEquals ( ĊĠĠĠĠĠ Ġstrategy , ĊĠĠĠĠĠ Ġinv ocations . get Invocation Strategy ( inv ocations . last RequestId ), ĊĠĠĠĠĠ Ġ" that Ġthe Ġstrategy Ġis Ġour Ġfuture Ġstrategy " ĊĠĠĠ Ġ) ĊĠĠĠ ĠassertFalse ( future . is Complete , Ġ" that Ġthe Ġfuture Ġshould Ġnot Ġhave Ġcompleted ") ĊĊĠĠĠ Ġ// Ġsimulate Ġreceiving Ġthe Ġresult ĊĠĠĠ Ġassert Fails With < RuntimeException > Ġ{ ĊĠĠĠĠĠ Ġstrategy . onError ( ĊĠĠĠĠĠĠĠĠ 1 , ĊĠĠĠĠĠĠĠ ĠRuntimeException (" invocation Ġexception ") ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġ` that Ġreceiving Ġa Ġmessage Ġfor Ġan Ġun inv oked Ġstrategy Ġfails `() Ġ{ ĊĠĠĠ Ġval Ġinv ocations Ġ= ĠMock Inv ocations () ĊĠĠĠ Ġval Ġstrategy Ġ= ĠFuture Invocation Strategy ( ĊĠĠĠĠĠ Ġinv ocations , ĊĠĠĠĠĠ ĠTest Interface :: test Future . name , ĊĠĠĠĠĠ ĠTest Interface :: test Future . java Method ?. generic ReturnType !! , ĊĠĠĠĠĠ ĠarrayOf () ĊĠĠĠ Ġ) ĊĠĠĠ Ġassert Fails With < java . lang . IllegalStateException > Ġ{ Ġstrategy . on Completed ( 1 ) Ġ} ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġ` that Ġthrowing Ġan Ġexception Ġduring Ġnetwork Ġinvocation Ġcauses Ġget Result Ġto Ġfail `() Ġ{ ĊĠĠĠ Ġval Ġinv ocations Ġ= ĠMock Inv ocations Ġ{ Ġthrow Ġerror (" boom ") Ġ} ĊĠĠĠ Ġval Ġstrategy Ġ= ĠFuture Invocation Strategy ( ĊĠĠĠĠĠ Ġinv ocations , ĊĠĠĠĠĠ ĠTest Interface :: test Future . name , ĊĠĠĠĠĠ ĠTest Interface :: test Future . java Method ?. generic ReturnType !! , ĊĠĠĠĠĠ ĠarrayOf () ĊĠĠĠ Ġ) ĊĠĠĠ Ġval Ġresult Ġ= Ġstrategy . getResult () ĊĠĠĠ ĠassertTrue Ġ{ Ġresult . failed () Ġ&& Ġresult . cause () Ġis Ġjava . lang . IllegalStateException Ġ} ĊĠ Ġ} Ċ } ĊĊ