173 lines
4.3 KiB
Elixir
173 lines
4.3 KiB
Elixir
|
# Pleroma: A lightweight social networking server
|
||
|
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||
|
|
||
|
defmodule Gun.ConnectionsTest do
|
||
|
use ExUnit.Case, async: true
|
||
|
alias Pleroma.Gun.{Connections, Conn, API}
|
||
|
|
||
|
setup do
|
||
|
name = :test_gun_connections
|
||
|
{:ok, pid} = Connections.start_link(name)
|
||
|
|
||
|
{:ok, name: name, pid: pid}
|
||
|
end
|
||
|
|
||
|
test "opens connection and reuse it on next request", %{name: name, pid: pid} do
|
||
|
conn = Connections.get_conn(name, "http://some-domain.com", genserver_pid: pid)
|
||
|
|
||
|
assert is_pid(conn)
|
||
|
assert Process.alive?(conn)
|
||
|
|
||
|
reused_conn = Connections.get_conn(name, "http://some-domain.com", genserver_pid: pid)
|
||
|
|
||
|
assert conn == reused_conn
|
||
|
|
||
|
%Connections{
|
||
|
conns: %{
|
||
|
"some-domain.com:80" => %Conn{
|
||
|
conn: ^conn,
|
||
|
state: :up,
|
||
|
waiting_pids: []
|
||
|
}
|
||
|
}
|
||
|
} = Connections.get_state(name)
|
||
|
end
|
||
|
|
||
|
test "reuses connection based on protocol", %{name: name, pid: pid} do
|
||
|
conn = Connections.get_conn(name, "http://some-domain.com", genserver_pid: pid)
|
||
|
assert is_pid(conn)
|
||
|
assert Process.alive?(conn)
|
||
|
|
||
|
https_conn = Connections.get_conn(name, "https://some-domain.com", genserver_pid: pid)
|
||
|
|
||
|
refute conn == https_conn
|
||
|
|
||
|
reused_https = Connections.get_conn(name, "https://some-domain.com", genserver_pid: pid)
|
||
|
|
||
|
refute conn == reused_https
|
||
|
|
||
|
assert reused_https == https_conn
|
||
|
|
||
|
%Connections{
|
||
|
conns: %{
|
||
|
"some-domain.com:80" => %Conn{
|
||
|
conn: ^conn,
|
||
|
state: :up,
|
||
|
waiting_pids: []
|
||
|
},
|
||
|
"some-domain.com:443" => %Conn{
|
||
|
conn: ^https_conn,
|
||
|
state: :up,
|
||
|
waiting_pids: []
|
||
|
}
|
||
|
}
|
||
|
} = Connections.get_state(name)
|
||
|
end
|
||
|
|
||
|
test "process gun_down message", %{name: name, pid: pid} do
|
||
|
conn = Connections.get_conn(name, "http://gun_down.com", genserver_pid: pid)
|
||
|
|
||
|
refute conn
|
||
|
|
||
|
%Connections{
|
||
|
conns: %{
|
||
|
"gun_down.com:80" => %Conn{
|
||
|
conn: _,
|
||
|
state: :down,
|
||
|
waiting_pids: _
|
||
|
}
|
||
|
}
|
||
|
} = Connections.get_state(name)
|
||
|
end
|
||
|
|
||
|
test "process gun_down message and then gun_up", %{name: name, pid: pid} do
|
||
|
conn = Connections.get_conn(name, "http://gun_down_and_up.com", genserver_pid: pid)
|
||
|
|
||
|
refute conn
|
||
|
|
||
|
%Connections{
|
||
|
conns: %{
|
||
|
"gun_down_and_up.com:80" => %Conn{
|
||
|
conn: _,
|
||
|
state: :down,
|
||
|
waiting_pids: _
|
||
|
}
|
||
|
}
|
||
|
} = Connections.get_state(name)
|
||
|
|
||
|
conn = Connections.get_conn(name, "http://gun_down_and_up.com", genserver_pid: pid)
|
||
|
|
||
|
assert is_pid(conn)
|
||
|
assert Process.alive?(conn)
|
||
|
|
||
|
%Connections{
|
||
|
conns: %{
|
||
|
"gun_down_and_up.com:80" => %Conn{
|
||
|
conn: _,
|
||
|
state: :up,
|
||
|
waiting_pids: []
|
||
|
}
|
||
|
}
|
||
|
} = Connections.get_state(name)
|
||
|
end
|
||
|
|
||
|
test "async processes get same conn for same domain", %{name: name, pid: pid} do
|
||
|
tasks =
|
||
|
for _ <- 1..5 do
|
||
|
Task.async(fn ->
|
||
|
Connections.get_conn(name, "http://some-domain.com", genserver_pid: pid)
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
tasks_with_results = Task.yield_many(tasks)
|
||
|
|
||
|
results =
|
||
|
Enum.map(tasks_with_results, fn {task, res} ->
|
||
|
res || Task.shutdown(task, :brutal_kill)
|
||
|
end)
|
||
|
|
||
|
conns = for {:ok, value} <- results, do: value
|
||
|
|
||
|
%Connections{
|
||
|
conns: %{
|
||
|
"some-domain.com:80" => %Conn{
|
||
|
conn: conn,
|
||
|
state: :up,
|
||
|
waiting_pids: []
|
||
|
}
|
||
|
}
|
||
|
} = Connections.get_state(name)
|
||
|
|
||
|
assert Enum.all?(conns, fn res -> res == conn end)
|
||
|
end
|
||
|
|
||
|
describe "integration test" do
|
||
|
@describetag :integration
|
||
|
|
||
|
test "opens connection and reuse it on next request", %{name: name} do
|
||
|
api = Pleroma.Config.get([API])
|
||
|
Pleroma.Config.put([API], :gun)
|
||
|
on_exit(fn -> Pleroma.Config.put([API], api) end)
|
||
|
conn = Connections.get_conn(name, "http://httpbin.org")
|
||
|
|
||
|
assert is_pid(conn)
|
||
|
assert Process.alive?(conn)
|
||
|
|
||
|
reused_conn = Connections.get_conn(name, "http://httpbin.org")
|
||
|
|
||
|
assert conn == reused_conn
|
||
|
|
||
|
%Connections{
|
||
|
conns: %{
|
||
|
"httpbin.org:80" => %Conn{
|
||
|
conn: ^conn,
|
||
|
state: :up,
|
||
|
waiting_pids: []
|
||
|
}
|
||
|
}
|
||
|
} = Connections.get_state(name)
|
||
|
end
|
||
|
end
|
||
|
end
|