parent
bd31796d40
commit
75c88fac85
@ -0,0 +1,65 @@ |
||||
defmodule EthereumJSONRPC.RequestCoordinatorTest do |
||||
use ExUnit.Case |
||||
use EthereumJSONRPC.Case |
||||
|
||||
alias EthereumJSONRPC.RollingWindow |
||||
alias EthereumJSONRPC.RequestCoordinator |
||||
|
||||
import Mox |
||||
|
||||
setup :set_mox_global |
||||
setup :verify_on_exit! |
||||
|
||||
defp sleep_time(timeouts) do |
||||
wait_per_timeout = |
||||
:ethereum_jsonrpc |
||||
|> Application.get_env(RequestCoordinator) |
||||
|> Keyword.fetch!(:wait_per_timeout) |
||||
|
||||
timeouts * wait_per_timeout |
||||
end |
||||
|
||||
setup do |
||||
table = Application.get_env(:ethereum_jsonrpc, EthereumJSONRPC.RequestCoordinator)[:rolling_window_opts][:table] |
||||
|
||||
:ets.delete_all_objects(table) |
||||
|
||||
%{table: table} |
||||
end |
||||
|
||||
test "rolling window increments on timeout", %{table: table} do |
||||
expect(EthereumJSONRPC.Mox, :json_rpc, fn _, _ -> {:error, :timeout} end) |
||||
|
||||
RequestCoordinator.perform(%{}, EthereumJSONRPC.Mox, [], :timer.minutes(60)) |
||||
|
||||
assert RollingWindow.count(table, :timeout) == 1 |
||||
end |
||||
|
||||
test "waits the configured amount of time per failure", %{table: table} do |
||||
RollingWindow.inc(table, :timeout) |
||||
RollingWindow.inc(table, :timeout) |
||||
RollingWindow.inc(table, :timeout) |
||||
RollingWindow.inc(table, :timeout) |
||||
RollingWindow.inc(table, :timeout) |
||||
RollingWindow.inc(table, :timeout) |
||||
|
||||
test_process = self() |
||||
|
||||
expect(EthereumJSONRPC.Mox, :json_rpc, fn _, _ -> |
||||
send(test_process, :called_json_rpc) |
||||
end) |
||||
|
||||
# Calculate expected sleep time as if there were one less failure, allowing |
||||
# a margin of error between the refute_receive, assert_receive, and actual |
||||
# call. |
||||
wait_time = sleep_time(5) |
||||
|
||||
Task.async(fn -> |
||||
RequestCoordinator.perform(%{}, EthereumJSONRPC.Mox, [], :timer.minutes(60)) |
||||
end) |
||||
|
||||
refute_receive(:called_json_rpc, wait_time) |
||||
|
||||
assert_receive(:called_json_rpc, wait_time) |
||||
end |
||||
end |
@ -0,0 +1,102 @@ |
||||
defmodule EthereumJSONRPC.RollingWindowTest do |
||||
use ExUnit.Case, async: true |
||||
use EthereumJSONRPC.Case |
||||
|
||||
alias EthereumJSONRPC.RollingWindow |
||||
|
||||
@table :table |
||||
|
||||
setup do |
||||
# We set `window_length` to a large time frame so that we can sweep manually to simulate |
||||
# time passing |
||||
RollingWindow.start_link([table: @table, window_length: :timer.minutes(120), window_count: 3], name: RollingWindow) |
||||
|
||||
:ok |
||||
end |
||||
|
||||
defp sweep do |
||||
GenServer.call(RollingWindow, :sweep) |
||||
end |
||||
|
||||
test "when no increments have happened, inspect returns an empty list" do |
||||
assert RollingWindow.inspect(@table, :foobar) == [] |
||||
end |
||||
|
||||
test "when no increments hafve happened, count returns 0" do |
||||
assert RollingWindow.count(@table, :foobar) == 0 |
||||
end |
||||
|
||||
test "when an increment has happened, inspect returns the count for that window" do |
||||
RollingWindow.inc(@table, :foobar) |
||||
|
||||
assert RollingWindow.inspect(@table, :foobar) == [1] |
||||
end |
||||
|
||||
test "when an increment has happened, count returns the count for that window" do |
||||
RollingWindow.inc(@table, :foobar) |
||||
|
||||
assert RollingWindow.count(@table, :foobar) == 1 |
||||
end |
||||
|
||||
test "when an increment has happened in multiple windows, inspect returns the count for both windows" do |
||||
RollingWindow.inc(@table, :foobar) |
||||
sweep() |
||||
RollingWindow.inc(@table, :foobar) |
||||
|
||||
assert RollingWindow.inspect(@table, :foobar) == [1, 1] |
||||
end |
||||
|
||||
test "when an increment has happened in multiple windows, count returns the sum of both windows" do |
||||
RollingWindow.inc(@table, :foobar) |
||||
sweep() |
||||
RollingWindow.inc(@table, :foobar) |
||||
|
||||
assert RollingWindow.count(@table, :foobar) == 2 |
||||
end |
||||
|
||||
test "when an increment has happened in multiple windows, with an empty window in between, inspect shows that empty window" do |
||||
RollingWindow.inc(@table, :foobar) |
||||
sweep() |
||||
sweep() |
||||
RollingWindow.inc(@table, :foobar) |
||||
|
||||
assert RollingWindow.inspect(@table, :foobar) == [1, 0, 1] |
||||
end |
||||
|
||||
test "when an increment has happened in multiple windows, with an empty window in between, count still sums all windows" do |
||||
RollingWindow.inc(@table, :foobar) |
||||
sweep() |
||||
sweep() |
||||
RollingWindow.inc(@table, :foobar) |
||||
|
||||
assert RollingWindow.count(@table, :foobar) == 2 |
||||
end |
||||
|
||||
test "when an increment has happened, but has been swept <window_count> times, it no longer appears in inspect" do |
||||
RollingWindow.inc(@table, :foobar) |
||||
sweep() |
||||
sweep() |
||||
RollingWindow.inc(@table, :foobar) |
||||
sweep() |
||||
RollingWindow.inc(@table, :foobar) |
||||
|
||||
assert RollingWindow.inspect(@table, :foobar) == [1, 1, 0] |
||||
end |
||||
|
||||
test "when an increment has happened, but has been swept <window_count> times, it no longer is included in count" do |
||||
RollingWindow.inc(@table, :foobar) |
||||
sweep() |
||||
sweep() |
||||
RollingWindow.inc(@table, :foobar) |
||||
sweep() |
||||
RollingWindow.inc(@table, :foobar) |
||||
|
||||
assert RollingWindow.count(@table, :foobar) == 2 |
||||
end |
||||
|
||||
test "sweeping schedules another sweep" do |
||||
{:ok, state} = RollingWindow.init(table: :anything, window_length: 1, window_count: 1) |
||||
RollingWindow.handle_info(:sweep, state) |
||||
assert_receive(:sweep) |
||||
end |
||||
end |
Loading…
Reference in new issue