Open bblfish opened 1 year ago
@ybasket answered this on discord:
I think you could just do
IO.sleep(durationToWhatYouWantFromEpoch1970)
at the beginning of your test as a workaround. Still worth the issue though
We can probably expose some nicer ways to do this.
Thanks for the tip. It would help I think if the documentation made clear that clock always starts in 1970... Or an example for verifying signatures could make that clear.
I used that trick in the function doAt(time, ioact) of the signature verification suite.
It actually led me to find a timing error in the spec examples. See https://github.com/httpwg/http-extensions/issues/2347
Mhh this works very differently in the browser than in Java. It works as desired in Java but all the tests fail in JS using this method.
def doAt[A](start: FiniteDuration, act: IO[A]): IO[Option[Outcome[Id, Throwable, A]]] =
TestControl.execute(act).flatMap { ctrl =>
for
_ <- ctrl.results.assertEquals(None)
_ <- ctrl.advanceAndTick(start)
x <- ctrl.results
yield x
}
I guess in the browser TestControl
cannot really intercept the IO
for the WebCrypto API
's async crypto calls. So the result tends to be None
even after ctrl.results has been called.
In Java Signing is synchronous, whereas in JS it is async.
So is there another trick to set the time that would work better for the JS platform?
The obvious workaround to this was given by @SystemFw on Discord here: pass the time as a value to the function doing the testing.
So instead of passing the Clock implicity as I used to with the ME
below, I mow have the function generated take the time. (Duh!)
def signatureAuthN[F[_], A](
fetchKeyId: Rfc8941.SfString => F[SignatureVerifier[F, A]]
)(
using ME: MonadError[F, Throwable]
): (FiniteDuration, HttpSig) => F[A] = (now, httpSig) =>
(The function takes a function from a keyId to its crypto data, and generates a function that takes signature info and a time to return a verified key - the function is an extension on a request object, so it is given too)
Indeed that simplified the code, clarified things, and the tests now pass. https://github.com/bblfish/httpSig/pull/12
I'm going to leave this open to track an enhancement to the TestControl
API to make this a bit more obvious and idiomatic. In particular, I'd like to see some functionality on the TestControl
class which sets the clock by advancing time by the appropriate amount (which we can allow to be negative), as well as an additional default parameter on executeEmbed
(plus the appropriate bincompat shenanigans) which is something like clockStartTime
or something like that. Please feel free to bikeshed on teh API.
Use case: I have am writing an implementation of IETF http message signatures. The spec has a lot of examples of signed HTTP messages signed with a validity period. To test the library I would like to set the Clock to a specific valid time and to invalid times, to check that the implementation is correct, i.e. that it fails a correct signature when the date is no longer valid.
I have spent at a few hours looking through the isses that led to the test runtime including the very nice documentation, looked at the source code, issues that led to it. But I could not find out how to do that... I may be missing something obvious...