Files
2023-11-12 19:12:47 +01:00

116 lines
3.1 KiB
Elixir

defmodule TeslaMate.TerrainTest do
use TeslaMate.DataCase, async: true
alias TeslaMate.Terrain
def start_terrain(name, responses \\ %{}) do
log_name = :"log_#{name}"
srtm_name = :"srtm_#{name}"
{:ok, _pid} = start_supervised({LogMock, name: log_name, pid: self(), last_update: nil})
{:ok, _pid} = start_supervised({SRTMMock, name: srtm_name, pid: self(), responses: responses})
opts = [
name: name,
timeout: 500,
deps_log: {LogMock, log_name},
deps_srtm: {SRTMMock, srtm_name}
]
{:ok, _} = start_supervised({Terrain, opts})
assert_receive {:get_positions_without_elevation, 0}
:ok
end
describe "get_elevation/1" do
test "return the elevation", %{test: name} do
:ok = start_terrain(name, %{{0, 0} => fn -> {:ok, 42} end})
assert 42 == Terrain.get_elevation(name, {0, 0})
assert_received {SRTM, {:get_elevation, 0, 0, [disk_cache_path: ".srtm_cache"]}}
refute_receive _
end
@tag :capture_log
test "return nil if an error occurred", %{test: name} do
:ok = start_terrain(name, %{{0, 0} => fn -> {:error, :kaputt} end})
assert Terrain.get_elevation(name, {0, 0}) == nil
TestHelper.eventually(fn ->
assert_received {SRTM, {:get_elevation, 0, 0, _opts}}
end)
refute_receive _
end
test "returns nil if the task takes longer than 100ms", %{test: name} do
:ok =
start_terrain(name, %{
{0, 0} => fn ->
Process.sleep(550)
{:ok, 42}
end
})
assert Terrain.get_elevation(name, {0, 0}) == nil
TestHelper.eventually(fn ->
assert_received {SRTM, {:get_elevation, 0, 0, _opts}}
end)
# still blocked
assert Terrain.get_elevation(name, {0, 0}) == nil
refute_receive _, 300
end
@tag :capture_log
test "handles long running tasks that return with an error", %{test: name} do
:ok =
start_terrain(name, %{
{1, 1} => fn ->
Process.sleep(101)
{:error, :kaputt}
end
})
assert Terrain.get_elevation(name, {1, 1}) == nil
TestHelper.eventually(fn ->
assert_received {SRTM, {:get_elevation, 1, 1, _opts}}
end)
refute_receive _
end
@tag :capture_log
test "breaks circuit if too many queries fail", %{test: name} do
:ok =
start_terrain(name, %{
{0, 0} => fn -> {:error, :kaputt} end
})
assert Terrain.get_elevation(name, {0, 0}) == nil
assert Terrain.get_elevation(name, {0, 0}) == nil
assert Terrain.get_elevation(name, {0, 0}) == nil
assert Terrain.get_elevation(name, {0, 0}) == nil
assert Terrain.get_elevation(name, {0, 0}) == nil
# circuit broke after 3 attempts
TestHelper.eventually(
fn ->
assert_received {SRTM, {:get_elevation, 0, 0, _opts}}
assert_received {SRTM, {:get_elevation, 0, 0, _opts}}
assert_received {SRTM, {:get_elevation, 0, 0, _opts}}
end,
attempts: 25
)
refute_receive _
end
end
end