I’m currently implementing a protocol that relies on a lot of crypto and certificates. I got some samples to use in my tests and one of them contains a certificate path that I need to validate. However, the valid_until field of the leaf certificate is 280520162044Z: the certificate has expired.
However, I cannot change it since I don’t have the parent certificate’s corresponding private key, and I guess changing a field would change the signature.
Therefore, is it possible to change the current time of the EVM to make my test pass, and using Erlang functions (not by changing the time of my machine)? And just in one (synced) test?
You could mock out your source of time. Searching for timecop elixir also found a package by @kokolegorille so they are probably a good source of info.
There’s an interesting comment saying it’s better to use the process dictionary since “time” change is limited to the process (the test case in my case) and is destroyed when the (test) process dies. So that you can run your tests in parallel! Thanks for the tip
Here’s the code:
if
...
and parse_cert_datetime(valid_from) < Wax.Utils.Timestamp.get_timestamp()
and parse_cert_datetime(valid_to) > Wax.Utils.Timestamp.get_timestamp()
...
(instead of directly calling :os.system_time(:second))
Wax.Utils.Timestamp:
defmodule Wax.Utils.Timestamp do
@adapter if Mix.env() == :test, do: Wax.Utils.Timestamp.TimeTravel, else: Wax.Utils.Timestamp.Real
@spec get_timestamp() :: non_neg_integer()
def get_timestamp do
@adapter.get_timestamp()
end
end
Wax.Utils.Timestamp.Real
defmodule Wax.Utils.Timestamp.Real do
@spec get_timestamp() :: non_neg_integer()
def get_timestamp() do
:os.system_time(:second)
end
end
Wax.Utils.Timestamp.TimeTravel
defmodule Wax.Utils.Timestamp.TimeTravel do
@spec get_timestamp() :: non_neg_integer()
def get_timestamp() do
if Process.get(:mock_time) do
Process.get(:mock_time)
else
:os.system_time(:second)
end
end
@spec set_timestamp(non_neg_integer()) :: no_return()
def set_timestamp(timestamp) do
Process.put(:mock_time, timestamp)
end
end