Refactor mocks
This commit is contained in:
parent
a17857576d
commit
9c3523d9d1
|
@ -21,5 +21,8 @@ config :phoenix, :plug_init_mode, :runtime
|
|||
|
||||
config :chronoscope, Chronoscope.NTS,
|
||||
behaviour: Chronoscope.NTS.BehaviourMock,
|
||||
datetime: Chronoscope.NTS.DateTimeMock,
|
||||
ssl: Chronoscope.NTS.SSLMock
|
||||
date_time: Chronoscope.NTS.DateTimeMock,
|
||||
ssl: Chronoscope.NTS.SSLMock,
|
||||
registry: Chronoscope.NTS.RegistryMock,
|
||||
dynamic_supervisor: Chronoscope.NTS.DynamicSupervisorMock,
|
||||
gen_server: Chronoscope.NTS.GenServerMock
|
||||
|
|
|
@ -9,22 +9,26 @@ defmodule Chronoscope.NTS do
|
|||
|
||||
alias Chronoscope.NTS
|
||||
|
||||
@registry Application.compile_env(:chronoscope, Chronoscope.NTS)[:registry] || Registry
|
||||
@genserver Application.compile_env(:chronoscope, Chronoscope.NTS)[:gen_server] || GenServer
|
||||
@dynamic_supervisor Application.compile_env(:chronoscope, Chronoscope.NTS)[:dynamic_supervisor] || DynamicSupervisor
|
||||
|
||||
def healthy?() do
|
||||
true
|
||||
end
|
||||
|
||||
def list() do
|
||||
NTS.DynamicSupervisor
|
||||
|> DynamicSupervisor.which_children()
|
||||
|> Enum.map(fn {_, pid, _, _} -> GenServer.call(pid, :list) end)
|
||||
|> @dynamic_supervisor.which_children()
|
||||
|> Enum.map(fn {_, pid, _, _} -> @genserver.call(pid, :list) end)
|
||||
end
|
||||
|
||||
def remove(host, port) do
|
||||
name = client_name(%{host: host, port: port})
|
||||
|
||||
case Registry.lookup(NTS.Registry, name) do
|
||||
[{pid, _}] -> GenServer.call(pid, :terminate)
|
||||
[] -> {:error, :notfound}
|
||||
case @registry.lookup(NTS.Registry, name) do
|
||||
[{pid, _}] -> {:ok, @genserver.call(pid, :terminate)}
|
||||
[] -> {:error, :not_found}
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -32,13 +36,13 @@ defmodule Chronoscope.NTS do
|
|||
def key_establishment(host, port) do
|
||||
%{host: host, port: port}
|
||||
|> client_pid()
|
||||
|> GenServer.call(:key_establishment)
|
||||
|> @genserver.call(:key_establishment)
|
||||
end
|
||||
|
||||
defp client_pid(server) do
|
||||
name = client_name(server)
|
||||
|
||||
case Registry.lookup(NTS.Registry, name) do
|
||||
case @registry.lookup(NTS.Registry, name) do
|
||||
[{pid, _}] -> pid
|
||||
[] -> start_client(server, name)
|
||||
end
|
||||
|
@ -50,7 +54,7 @@ defmodule Chronoscope.NTS do
|
|||
|
||||
defp start_client(server, name) do
|
||||
NTS.DynamicSupervisor
|
||||
|> DynamicSupervisor.start_child({NTS.Client, server: server, name: {:via, Registry, {NTS.Registry, name}}})
|
||||
|> @dynamic_supervisor.start_child({NTS.Client, server: server, name: {:via, @registry, {NTS.Registry, name}}})
|
||||
|> then(fn {:ok, pid} -> pid end)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
defmodule Chronoscope.NTS.Certificate do
|
||||
@date_time Application.compile_env(:chronoscope, Chronoscope.NTS)[:date_time] || DateTime
|
||||
|
||||
def expiration_date(certificate) do
|
||||
{:Validity, _, {:utcTime, expiration}} =
|
||||
certificate
|
||||
|
@ -20,7 +22,7 @@ defmodule Chronoscope.NTS.Certificate do
|
|||
|
||||
defp short_year_to_full_year(short_year) do
|
||||
{century, current_year} =
|
||||
datetime().utc_now().year
|
||||
@date_time.utc_now().year
|
||||
|> to_string()
|
||||
|> String.split_at(-2)
|
||||
|
||||
|
@ -32,8 +34,4 @@ defmodule Chronoscope.NTS.Certificate do
|
|||
|> then(&"#{&1 + 1}#{short_year}")
|
||||
end
|
||||
end
|
||||
|
||||
defp datetime() do
|
||||
Application.get_env(:chronoscope, Chronoscope.NTS)[:datetime] || DateTime
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,6 +5,7 @@ defmodule Chronoscope.NTS.Client do
|
|||
alias Chronoscope.NTS.KeyEstablishmentClient
|
||||
|
||||
@interval_in_seconds 30
|
||||
@date_time Application.compile_env(:chronoscope, Chronoscope.NTS)[:date_time] || DateTime
|
||||
|
||||
def start_link(server: server, name: name) do
|
||||
GenServer.start_link(__MODULE__, server, name: name)
|
||||
|
@ -70,10 +71,6 @@ defmodule Chronoscope.NTS.Client do
|
|||
end
|
||||
|
||||
defp utc_now() do
|
||||
datetime().utc_now()
|
||||
end
|
||||
|
||||
defp datetime() do
|
||||
Application.get_env(:chronoscope, Chronoscope.NTS)[:datetime] || DateTime
|
||||
@date_time.utc_now()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,6 +6,7 @@ defmodule Chronoscope.NTS.KeyEstablishmentClient do
|
|||
alias Chronoscope.NTS.KeyEstablishmentResponse
|
||||
|
||||
@timeout_in_milliseconds 3000
|
||||
@ssl Application.compile_env(:chronoscope, Chronoscope.NTS)[:ssl] || :ssl
|
||||
|
||||
def key_establishment(%{host: host, port: port}) do
|
||||
case ssl_connect(host, port) do
|
||||
|
@ -21,7 +22,7 @@ defmodule Chronoscope.NTS.KeyEstablishmentClient do
|
|||
defp ssl_connect(host, port) do
|
||||
host
|
||||
|> String.to_charlist()
|
||||
|> ssl().connect(port, tls_options(host), @timeout_in_milliseconds)
|
||||
|> @ssl.connect(port, tls_options(host), @timeout_in_milliseconds)
|
||||
end
|
||||
|
||||
defp tls_options(host) do
|
||||
|
@ -31,21 +32,21 @@ defmodule Chronoscope.NTS.KeyEstablishmentClient do
|
|||
end
|
||||
|
||||
defp perform_key_establishment(socket) do
|
||||
:ok = ssl().send(socket, KeyEstablishmentRequest.create())
|
||||
{:ok, peercert} = ssl().peercert(socket)
|
||||
:ok = @ssl.send(socket, KeyEstablishmentRequest.create())
|
||||
{:ok, peercert} = @ssl.peercert(socket)
|
||||
|
||||
receive do
|
||||
{:ssl, _socket, response} ->
|
||||
ssl().close(socket)
|
||||
@ssl.close(socket)
|
||||
parse_response(response, peercert)
|
||||
|
||||
msg ->
|
||||
ssl().close(socket)
|
||||
@ssl.close(socket)
|
||||
Logger.error("received unexpected message: #{inspect(msg)}")
|
||||
{:error, :no_response}
|
||||
after
|
||||
@timeout_in_milliseconds ->
|
||||
ssl().close(socket)
|
||||
@ssl.close(socket)
|
||||
Logger.error("timed out waiting for response")
|
||||
{:error, :timeout}
|
||||
end
|
||||
|
@ -67,8 +68,4 @@ defmodule Chronoscope.NTS.KeyEstablishmentClient do
|
|||
{:error, String.trim(error)}
|
||||
end
|
||||
end
|
||||
|
||||
defp ssl() do
|
||||
Application.get_env(:chronoscope, Chronoscope.NTS)[:ssl] || :ssl
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,6 +7,7 @@ defmodule ChronoscopeWeb.API.V1.NTS.KeyEstablishmentController do
|
|||
|
||||
@default_port 4460
|
||||
@max_host_length 255
|
||||
@nts Application.compile_env(:chronoscope, NTS)[:behaviour] || NTS
|
||||
|
||||
def get(conn, %{"host" => host, "port" => port}) do
|
||||
try do
|
||||
|
@ -41,7 +42,7 @@ defmodule ChronoscopeWeb.API.V1.NTS.KeyEstablishmentController do
|
|||
defp key_establishment_response(host, port) do
|
||||
host
|
||||
|> String.slice(0, @max_host_length)
|
||||
|> nts_behaviour().key_establishment(port)
|
||||
|> @nts.key_establishment(port)
|
||||
end
|
||||
|
||||
defp format_response(response) do
|
||||
|
@ -55,8 +56,4 @@ defmodule ChronoscopeWeb.API.V1.NTS.KeyEstablishmentController do
|
|||
|> put_status(:bad_request)
|
||||
|> json(%{error: message})
|
||||
end
|
||||
|
||||
defp nts_behaviour() do
|
||||
Application.get_env(:chronoscope, NTS)[:behaviour] || NTS
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
defmodule Chronoscope.NTSTest do
|
||||
use Chronoscope.Case
|
||||
|
||||
alias Chronoscope.NTS.DynamicSupervisorMock
|
||||
alias Chronoscope.NTS.GenServerMock
|
||||
alias Chronoscope.NTS.RegistryMock
|
||||
|
||||
import Chronoscope.NTS
|
||||
import Mox
|
||||
|
||||
setup :verify_on_exit!
|
||||
|
||||
describe "Chronoscope.NTS.healthy?()" do
|
||||
test "is healthy" do
|
||||
|
@ -11,13 +18,30 @@ defmodule Chronoscope.NTSTest do
|
|||
|
||||
describe "Chronoscope.NTS.list()" do
|
||||
test "shows empty client list" do
|
||||
DynamicSupervisorMock
|
||||
|> expect(:which_children, fn _ -> [] end)
|
||||
|
||||
assert list() == []
|
||||
end
|
||||
|
||||
test "lists all children" do
|
||||
DynamicSupervisorMock
|
||||
|> expect(:which_children, fn _ -> [{1, 2, 3, 4}, {5, 6, 7, 8}] end)
|
||||
|
||||
GenServerMock
|
||||
|> expect(:call, fn 2, :list -> :one end)
|
||||
|> expect(:call, fn 6, :list -> :two end)
|
||||
|
||||
assert list() == [:one, :two]
|
||||
end
|
||||
end
|
||||
|
||||
describe "Chronoscope.NTS.remove()" do
|
||||
test "does nothing if the client doesn't exist" do
|
||||
assert remove("localhost", 1111) == {:error, :notfound}
|
||||
RegistryMock
|
||||
|> expect(:lookup, fn _, _ -> [] end)
|
||||
|
||||
assert remove("localhost", 1111) == {:error, :not_found}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
defmodule Chronoscope.DateTime.Behaviour do
|
||||
@callback utc_now :: DateTime.t()
|
||||
end
|
||||
|
||||
defmodule Chronoscope.SSL.Behaviour do
|
||||
@callback connect(any(), any(), any(), any()) :: {:ok, any()} | {:error, any()}
|
||||
@callback send(any(), any()) :: :ok | {:error, any()}
|
||||
@callback peercert(any()) :: {:ok, any()} | {:error, any()}
|
||||
@callback close(any()) :: :ok | {:error, any()}
|
||||
end
|
||||
|
||||
defmodule Chronoscope.Registry.Behaviour do
|
||||
@callback lookup(atom(), any()) :: [{pid(), any()}]
|
||||
end
|
||||
|
||||
defmodule Chronoscope.DynamicSupervisor.Behaviour do
|
||||
@callback start_child(Supervisor.supervisor(), any()) :: any()
|
||||
@callback which_children(Supervisor.supervisor()) :: [any()]
|
||||
end
|
||||
|
||||
defmodule Chronoscope.GenServer.Behaviour do
|
||||
@callback call(pid(), any()) :: any()
|
||||
end
|
|
@ -1,19 +1,6 @@
|
|||
defmodule Chronoscope.DateTime.Behaviour do
|
||||
@callback utc_now :: DateTime.t()
|
||||
end
|
||||
|
||||
defmodule Chronoscope.DateTime.Stub do
|
||||
@behaviour Chronoscope.DateTime.Behaviour
|
||||
def utc_now(), do: DateTime.utc_now()
|
||||
end
|
||||
|
||||
defmodule Chronoscope.SSL.Behaviour do
|
||||
@callback connect(any(), any(), any(), any()) :: {:ok, any()} | {:error, any()}
|
||||
@callback send(any(), any()) :: :ok | {:error, any()}
|
||||
@callback peercert(any()) :: {:ok, any()} | {:error, any()}
|
||||
@callback close(any()) :: :ok | {:error, any()}
|
||||
end
|
||||
|
||||
Mox.defmock(Chronoscope.NTS.BehaviourMock, for: Chronoscope.NTS.Behaviour)
|
||||
Mox.defmock(Chronoscope.NTS.DateTimeMock, for: Chronoscope.DateTime.Behaviour)
|
||||
Mox.defmock(Chronoscope.NTS.SSLMock, for: Chronoscope.SSL.Behaviour)
|
||||
Mox.defmock(Chronoscope.NTS.RegistryMock, for: Chronoscope.Registry.Behaviour)
|
||||
Mox.defmock(Chronoscope.NTS.DynamicSupervisorMock, for: Chronoscope.DynamicSupervisor.Behaviour)
|
||||
Mox.defmock(Chronoscope.NTS.GenServerMock, for: Chronoscope.GenServer.Behaviour)
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
defmodule Chronoscope.DateTime.Stub do
|
||||
@behaviour Chronoscope.DateTime.Behaviour
|
||||
def utc_now(), do: DateTime.utc_now()
|
||||
end
|
Loading…
Reference in New Issue