aboutsummaryrefslogtreecommitdiff
path: root/test/support
diff options
context:
space:
mode:
authorHaelwenn <contact+git.pleroma.social@hacktivis.me>2022-09-02 22:35:40 +0000
committerHaelwenn <contact+git.pleroma.social@hacktivis.me>2022-09-02 22:35:40 +0000
commitb439e91f57d1d7f26e94acc62703a64c747773da (patch)
tree6ab4889ffa2ef637226def90eb0758d338ef19b6 /test/support
parente22a7722403fb3a6eb147f16de0c021d3d8c0f5f (diff)
downloadpleroma-b439e91f57d1d7f26e94acc62703a64c747773da.tar.gz
Revert "Merge branch 'rewrite/integration-test-websocket-client' into 'develop'"
This reverts merge request !3649
Diffstat (limited to 'test/support')
-rw-r--r--test/support/websocket_client.ex193
1 files changed, 27 insertions, 166 deletions
diff --git a/test/support/websocket_client.ex b/test/support/websocket_client.ex
index 43f2854de..d149b324e 100644
--- a/test/support/websocket_client.ex
+++ b/test/support/websocket_client.ex
@@ -3,199 +3,60 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Integration.WebsocketClient do
- @moduledoc """
- A WebSocket client used to test Mastodon API streaming
-
- Based on Phoenix Framework's WebsocketClient
- https://github.com/phoenixframework/phoenix/blob/master/test/support/websocket_client.exs
- """
-
- use GenServer
- import Kernel, except: [send: 2]
-
- defstruct [
- :conn,
- :request_ref,
- :websocket,
- :caller,
- :status,
- :resp_headers,
- :sender,
- closing?: false
- ]
+ # https://github.com/phoenixframework/phoenix/blob/master/test/support/websocket_client.exs
@doc """
- Starts the WebSocket client for given ws URL. `Phoenix.Socket.Message`s
- received from the server are forwarded to the sender pid.
+ Starts the WebSocket server for given ws URL. Received Socket.Message's
+ are forwarded to the sender pid
"""
- def connect(sender, url, headers \\ []) do
- with {:ok, socket} <- GenServer.start_link(__MODULE__, {sender}),
- {:ok, :connected} <- GenServer.call(socket, {:connect, url, headers}) do
- {:ok, socket}
- end
+ def start_link(sender, url, headers \\ []) do
+ :crypto.start()
+ :ssl.start()
+
+ :websocket_client.start_link(
+ String.to_charlist(url),
+ __MODULE__,
+ [sender],
+ extra_headers: headers
+ )
end
@doc """
Closes the socket
"""
def close(socket) do
- GenServer.cast(socket, :close)
+ send(socket, :close)
end
@doc """
Sends a low-level text message to the client.
"""
def send_text(server_pid, msg) do
- GenServer.call(server_pid, {:text, msg})
+ send(server_pid, {:text, msg})
end
@doc false
- def init({sender}) do
- state = %__MODULE__{sender: sender}
-
- {:ok, state}
+ def init([sender], _conn_state) do
+ {:ok, %{sender: sender}}
end
@doc false
- def handle_call({:connect, url, headers}, from, state) do
- uri = URI.parse(url)
-
- http_scheme =
- case uri.scheme do
- "ws" -> :http
- "wss" -> :https
- end
-
- ws_scheme =
- case uri.scheme do
- "ws" -> :ws
- "wss" -> :wss
- end
-
- path =
- case uri.query do
- nil -> uri.path
- query -> uri.path <> "?" <> query
- end
-
- with {:ok, conn} <- Mint.HTTP.connect(http_scheme, uri.host, uri.port),
- {:ok, conn, ref} <- Mint.WebSocket.upgrade(ws_scheme, conn, path, headers) do
- state = %{state | conn: conn, request_ref: ref, caller: from}
- {:noreply, state}
- else
- {:error, reason} ->
- {:reply, {:error, reason}, state}
-
- {:error, conn, reason} ->
- {:reply, {:error, reason}, put_in(state.conn, conn)}
- end
+ def websocket_handle(frame, _conn_state, state) do
+ send(state.sender, frame)
+ {:ok, state}
end
@doc false
- def handle_info(message, state) do
- case Mint.WebSocket.stream(state.conn, message) do
- {:ok, conn, responses} ->
- state = put_in(state.conn, conn) |> handle_responses(responses)
- if state.closing?, do: do_close(state), else: {:noreply, state}
-
- {:error, conn, reason, _responses} ->
- state = put_in(state.conn, conn) |> reply({:error, reason})
- {:noreply, state}
-
- :unknown ->
- {:noreply, state}
- end
- end
-
- defp do_close(state) do
- # Streaming a close frame may fail if the server has already closed
- # for writing.
- _ = stream_frame(state, :close)
- Mint.HTTP.close(state.conn)
- {:stop, :normal, state}
- end
-
- defp handle_responses(state, responses)
-
- defp handle_responses(%{request_ref: ref} = state, [{:status, ref, status} | rest]) do
- put_in(state.status, status)
- |> handle_responses(rest)
- end
-
- defp handle_responses(%{request_ref: ref} = state, [{:headers, ref, resp_headers} | rest]) do
- put_in(state.resp_headers, resp_headers)
- |> handle_responses(rest)
- end
-
- defp handle_responses(%{request_ref: ref} = state, [{:done, ref} | rest]) do
- case Mint.WebSocket.new(state.conn, ref, state.status, state.resp_headers) do
- {:ok, conn, websocket} ->
- %{state | conn: conn, websocket: websocket, status: nil, resp_headers: nil}
- |> reply({:ok, :connected})
- |> handle_responses(rest)
-
- {:error, conn, reason} ->
- put_in(state.conn, conn)
- |> reply({:error, reason})
- end
+ def websocket_info({:text, msg}, _conn_state, state) do
+ {:reply, {:text, msg}, state}
end
- defp handle_responses(%{request_ref: ref, websocket: websocket} = state, [
- {:data, ref, data} | rest
- ])
- when websocket != nil do
- case Mint.WebSocket.decode(websocket, data) do
- {:ok, websocket, frames} ->
- put_in(state.websocket, websocket)
- |> handle_frames(frames)
- |> handle_responses(rest)
-
- {:error, websocket, reason} ->
- put_in(state.websocket, websocket)
- |> reply({:error, reason})
- end
+ def websocket_info(:close, _conn_state, _state) do
+ {:close, <<>>, "done"}
end
- defp handle_responses(state, [_response | rest]) do
- handle_responses(state, rest)
- end
-
- defp handle_responses(state, []), do: state
-
- defp handle_frames(state, frames) do
- {frames, state} =
- Enum.flat_map_reduce(frames, state, fn
- # prepare to close the connection when a close frame is received
- {:close, _code, _data}, state ->
- {[], put_in(state.closing?, true)}
-
- frame, state ->
- {[frame], state}
- end)
-
- Enum.each(frames, &Kernel.send(state.sender, &1))
-
- state
- end
-
- defp reply(state, response) do
- if state.caller, do: GenServer.reply(state.caller, response)
- put_in(state.caller, nil)
- end
-
- # Encodes a frame as a binary and sends it along the wire, keeping `conn`
- # and `websocket` up to date in `state`.
- defp stream_frame(state, frame) do
- with {:ok, websocket, data} <- Mint.WebSocket.encode(state.websocket, frame),
- state = put_in(state.websocket, websocket),
- {:ok, conn} <- Mint.WebSocket.stream_request_body(state.conn, state.request_ref, data) do
- {:ok, put_in(state.conn, conn)}
- else
- {:error, %Mint.WebSocket{} = websocket, reason} ->
- {:error, put_in(state.websocket, websocket), reason}
-
- {:error, conn, reason} ->
- {:error, put_in(state.conn, conn), reason}
- end
+ @doc false
+ def websocket_terminate(_reason, _conn_state, _state) do
+ :ok
end
end