Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ex/api/stream_test): fix intermitently failing tests #2303

Merged
merged 11 commits into from
Dec 7, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 32 additions & 64 deletions test/api/stream_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ defmodule Api.StreamTest do
use ExUnit.Case, async: false
import Test.Support.Helpers
alias Plug.Conn
alias ServerSentEventStage, as: SSES

describe "build_options" do
setup do
Expand All @@ -17,38 +18,22 @@ defmodule Api.StreamTest do
end

describe "start_link" do
setup do
bypass = Bypass.open()

{:ok, %{bypass: bypass}}
end

test "starts a genserver that sends events", %{bypass: bypass} do
Bypass.expect(bypass, fn conn ->
conn = Conn.send_chunked(conn, 200)
@data %{
"attributes" => [],
"type" => "vehicle",
"id" => "vehicle"
}

data = %{
"attributes" => [],
"type" => "vehicle",
"id" => "vehicle"
}

Conn.chunk(conn, "event: reset\ndata: #{Jason.encode!([data])}\n\n")
conn
end)
test "starts a genserver that sends events" do
data = @data

assert {:ok, sses} =
[
name: :start_link_test,
base_url: "http://localhost:#{bypass.port}",
path: "/vehicles",
params: [
"fields[vehicle]": "direction_id,current_status,longitude,latitude,bearing",
include: "stop,trip"
]
]
|> Api.Stream.build_options()
|> ServerSentEventStage.start_link()
GenStage.from_enumerable([
%SSES.Event{
event: "reset",
data: Jason.encode!(data)
}
])

assert {:ok, pid} = Api.Stream.start_link(name: __MODULE__, subscribe_to: sses)

Expand All @@ -58,46 +43,29 @@ defmodule Api.StreamTest do
|> Enum.take(1)
end

# We're seeing occasional failures in this test due to an underlying issue
# with the `Bypass` library. There is an
# [open issue on Bypass's github](https://github.com/PSPDFKit-labs/bypass/issues/120).
test "handles api events", %{bypass: bypass} do
Bypass.expect(bypass, fn conn ->
conn = Conn.send_chunked(conn, 200)

data = %{
"attributes" => [],
"type" => "vehicle",
"id" => "vehicle"
}

{:ok, conn} = Conn.chunk(conn, "event: ignores unexpected events\n\n")
{:ok, conn} = Conn.chunk(conn, "ignored garbled data\n\n")
{:ok, conn} = Conn.chunk(conn, "event: reset\ndata: #{Jason.encode!([data])}\n\n")
{:ok, conn} = Conn.chunk(conn, "event: add\ndata: #{Jason.encode!(data)}\n\n")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this introduce flakiness if Jason.encode! doesn't follow the same key order each time?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe so, because we're asserting on the type returned and the event returned, but it doesn't seem that we're asserting on any of the JSON data.

{:ok, conn} = Conn.chunk(conn, "event: update\ndata: #{Jason.encode!(data)}\n\n")
{:ok, conn} = Conn.chunk(conn, "event: remove\ndata: #{Jason.encode!(data)}\n\n")
conn
end)
test "handles api events" do
data = @data

assert {:ok, sses} =
[
base_url: "http://localhost:#{bypass.port}",
path: "/vehicles"
]
|> Api.Stream.build_options()
|> ServerSentEventStage.start_link()
GenStage.from_enumerable([
%SSES.Event{event: "ignores unexpected events"},
# garbled data contains no data and the `event` is `message`
%SSES.Event{event: "message"},
%SSES.Event{event: "reset", data: Jason.encode!([data])},
%SSES.Event{event: "add", data: Jason.encode!(data)},
%SSES.Event{event: "update", data: Jason.encode!(data)},
%SSES.Event{event: "remove", data: Jason.encode!(data)}
])

assert {:ok, pid} = Api.Stream.start_link(name: __MODULE__, subscribe_to: sses)

stream = GenStage.stream([pid])

assert [
%Api.Stream.Event{event: :reset},
%Api.Stream.Event{event: :add},
%Api.Stream.Event{event: :update},
%Api.Stream.Event{event: :remove}
] = Enum.take(stream, 4)
stream =
assert [
%Api.Stream.Event{event: :reset},
%Api.Stream.Event{event: :add},
%Api.Stream.Event{event: :update},
%Api.Stream.Event{event: :remove}
] = [pid] |> GenStage.stream() |> Enum.take(4)
end
end
end