From bb9123e16a41829bde30897a1747ff4f794b99ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szuma?= Date: Mon, 16 Oct 2023 12:13:52 +0200 Subject: [PATCH 01/17] Handle webhook --- config/integration_test.exs | 4 +-- config/test.exs | 4 +-- docker-compose-dev.yaml | 3 +- docker-compose-integration.yaml | 14 ++++++--- lib/jellyfish/notifier.ex | 10 +++++++ lib/jellyfish/room.ex | 3 +- mix.exs | 10 ++++--- mix.lock | 11 +++++-- test/jellyfish/notifier_test.exs | 49 ++++++++++++++++++++++++++++++-- test/support/webhook_plug.ex | 34 ++++++++++++++++++++++ test/test_helper.exs | 4 --- 11 files changed, 121 insertions(+), 25 deletions(-) create mode 100644 test/support/webhook_plug.ex diff --git a/config/integration_test.exs b/config/integration_test.exs index 0492dc5..6998aa3 100644 --- a/config/integration_test.exs +++ b/config/integration_test.exs @@ -2,6 +2,4 @@ import Config config :jellyfish_server_sdk, server_address: "jellyfish:5002", - server_api_token: "development", - divo: "docker-compose-integration.yaml", - divo_wait: [dwell: 1_500, max_tries: 50] + server_api_token: "development" diff --git a/config/test.exs b/config/test.exs index 1024d01..db4745c 100644 --- a/config/test.exs +++ b/config/test.exs @@ -2,6 +2,4 @@ import Config config :jellyfish_server_sdk, server_address: "localhost:5002", - server_api_token: "development", - divo: "docker-compose-dev.yaml", - divo_wait: [dwell: 1_500, max_tries: 50] + server_api_token: "development" diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index 4e12b7e..7bb97dd 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -2,7 +2,8 @@ version: "3" services: jellyfish: - image: "ghcr.io/jellyfish-dev/jellyfish:${TAG:-edge}" + # image: "ghcr.io/jellyfish-dev/jellyfish:${TAG:-edge}" + image: "tmp" container_name: jellyfish restart: on-failure healthcheck: diff --git a/docker-compose-integration.yaml b/docker-compose-integration.yaml index 80009f5..e4c334a 100644 --- a/docker-compose-integration.yaml +++ b/docker-compose-integration.yaml @@ -8,8 +8,11 @@ services: - MIX_ENV=integration_test volumes: - .:/app + ports: + - "4000:4000" networks: - - network + test_network: + ipv4_address: 172.28.0.2 depends_on: jellyfish: condition: service_healthy @@ -21,8 +24,11 @@ services: environment: - JF_HOST=jellyfish:5002 networks: - - network + test_network: + ipv4_address: 172.28.0.3 networks: - network: - driver: bridge + test_network: + ipam: + config: + - subnet: 172.28.0.0/16 diff --git a/lib/jellyfish/notifier.ex b/lib/jellyfish/notifier.ex index 191b8e2..b733c61 100644 --- a/lib/jellyfish/notifier.ex +++ b/lib/jellyfish/notifier.ex @@ -164,6 +164,16 @@ defmodule Jellyfish.Notifier do :ok end + @spec handle_json(term()) :: struct() + def handle_json(json) do + %ServerMessage{content: {_type, notification}} = + json + |> Map.get("notification") + |> ServerMessage.decode() + + Notification.to_notification(notification) + end + defp connect(fun, opts) do {address, api_token, secure?} = Utils.get_options_or_defaults(opts) address = if secure?, do: "wss://#{address}", else: "ws://#{address}" diff --git a/lib/jellyfish/room.ex b/lib/jellyfish/room.ex index aaba150..5602215 100644 --- a/lib/jellyfish/room.ex +++ b/lib/jellyfish/room.ex @@ -121,7 +121,8 @@ defmodule Jellyfish.Room do "/room", %{ "maxPeers" => Keyword.get(opts, :max_peers), - "videoCodec" => Keyword.get(opts, :video_codec) + "videoCodec" => Keyword.get(opts, :video_codec), + "webhookUrl" => Keyword.get(opts, :webhook_url) } ), {:ok, data} <- Map.fetch(body, "data"), diff --git a/mix.exs b/mix.exs index b516049..f4f6c9e 100644 --- a/mix.exs +++ b/mix.exs @@ -58,14 +58,16 @@ defmodule Membrane.Template.Mixfile do # protobuf deps {:protobuf, "~> 0.12.0"}, - # Tests - {:divo, "~> 1.3.1", only: [:test]}, # Docs, credo, test coverage, dialyzer {:ex_doc, ">= 0.0.0", only: :dev, runtime: false}, {:dialyxir, ">= 0.0.0", only: :dev, runtime: false}, {:credo, ">= 0.0.0", only: :dev, runtime: false}, - {:excoveralls, ">= 0.0.0", only: [:test, :integration_test], runtime: false} + {:excoveralls, ">= 0.0.0", only: [:test, :integration_test], runtime: false}, + + # Test deps + {:plug_cowboy, "~> 2.5", only: [:test, :integration_test]}, + {:phoenix_pubsub, "~> 2.1", only: [:test, :integration_test]} ] end @@ -113,7 +115,7 @@ defmodule Membrane.Template.Mixfile do def aliases do [ integration_test: [ - "cmd docker compose -f docker-compose-integration.yaml pull", + # "cmd docker compose -f docker-compose-integration.yaml pull", "cmd docker compose -f docker-compose-integration.yaml run test" ] ] diff --git a/mix.lock b/mix.lock index 5652275..b30cae7 100644 --- a/mix.lock +++ b/mix.lock @@ -1,9 +1,11 @@ %{ "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, "castore": {:hex, :castore, "1.0.3", "7130ba6d24c8424014194676d608cb989f62ef8039efd50ff4b3f33286d06db8", [:mix], [], "hexpm", "680ab01ef5d15b161ed6a95449fac5c6b8f60055677a8e79acf01b27baa4390b"}, + "cowboy": {:hex, :cowboy, "2.10.0", "ff9ffeff91dae4ae270dd975642997afe2a1179d94b1887863e43f681a203e26", [:make, :rebar3], [{:cowlib, "2.12.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "3afdccb7183cc6f143cb14d3cf51fa00e53db9ec80cdcd525482f5e99bc41d6b"}, + "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, + "cowlib": {:hex, :cowlib, "2.12.1", "a9fa9a625f1d2025fe6b462cb865881329b5caff8f1854d1cbc9f9533f00e1e1", [:make, :rebar3], [], "hexpm", "163b73f6367a7341b33c794c4e88e7dbfe6498ac42dcd69ef44c5bc5507c8db0"}, "credo": {:hex, :credo, "1.7.0", "6119bee47272e85995598ee04f2ebbed3e947678dee048d10b5feca139435f75", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "6839fcf63d1f0d1c0f450abc8564a57c43d644077ab96f2934563e68b8a769d7"}, "dialyxir": {:hex, :dialyxir, "1.4.1", "a22ed1e7bd3a3e3f197b68d806ef66acb61ee8f57b3ac85fc5d57354c5482a93", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "84b795d6d7796297cca5a3118444b80c7d94f7ce247d49886e7c291e1ae49801"}, - "divo": {:hex, :divo, "1.3.2", "3a5ce880a1fe930ea804361d1b57b5144129e79e1c856623d923a6fab6d539a1", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:patiently, "~> 0.2", [hex: :patiently, repo: "hexpm", optional: false]}], "hexpm", "4bd035510838959709db2cacd28edd2eda7948d0e7f1b0dfa810a134c913a88a"}, "earmark_parser": {:hex, :earmark_parser, "1.4.35", "437773ca9384edf69830e26e9e7b2e0d22d2596c4a6b17094a3b29f01ea65bb8", [:mix], [], "hexpm", "8652ba3cb85608d0d7aa2d21b45c6fad4ddc9a1f9a1f1b30ca3a246f0acc33f6"}, "elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, @@ -18,8 +20,13 @@ "mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"}, "mint": {:hex, :mint, "1.5.1", "8db5239e56738552d85af398798c80648db0e90f343c8469f6c6d8898944fb6f", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "4a63e1e76a7c3956abd2c72f370a0d0aecddc3976dea5c27eccbecfa5e7d5b1e"}, "nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"}, - "patiently": {:hex, :patiently, "0.2.0", "67eb139591e10c4b363ae0198e832552f191c58894731efd3bf124ec4722267a", [:mix], [], "hexpm", "c08cc5edc27def565647a9b55a0bea8025a5f81a4472e57692f28f2292c44c94"}, + "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.3", "3168d78ba41835aecad272d5e8cd51aa87a7ac9eb836eabc42f6e57538e3731d", [:mix], [], "hexpm", "bba06bc1dcfd8cb086759f0edc94a8ba2bc8896d5331a1e2c2902bf8e36ee502"}, + "plug": {:hex, :plug, "1.15.1", "b7efd81c1a1286f13efb3f769de343236bd8b7d23b4a9f40d3002fc39ad8f74c", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "459497bd94d041d98d948054ec6c0b76feacd28eec38b219ca04c0de13c79d30"}, + "plug_cowboy": {:hex, :plug_cowboy, "2.6.1", "9a3bbfceeb65eff5f39dab529e5cd79137ac36e913c02067dba3963a26efe9b2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "de36e1a21f451a18b790f37765db198075c25875c64834bcc82d90b309eb6613"}, + "plug_crypto": {:hex, :plug_crypto, "2.0.0", "77515cc10af06645abbfb5e6ad7a3e9714f805ae118fa1a70205f80d2d70fe73", [:mix], [], "hexpm", "53695bae57cc4e54566d993eb01074e4d894b65a3766f1c43e2c61a1b0f45ea9"}, "protobuf": {:hex, :protobuf, "0.12.0", "58c0dfea5f929b96b5aa54ec02b7130688f09d2de5ddc521d696eec2a015b223", [:mix], [{:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "75fa6cbf262062073dd51be44dd0ab940500e18386a6c4e87d5819a58964dc45"}, + "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, + "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, "tesla": {:hex, :tesla, "1.7.0", "a62dda2f80d4f8a925eb7b8c5b78c461e0eb996672719fe1a63b26321a5f8b4e", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.13", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:msgpax, "~> 2.3", [hex: :msgpax, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "2e64f01ebfdb026209b47bc651a0e65203fcff4ae79c11efb73c4852b00dc313"}, "websockex": {:hex, :websockex, "0.4.3", "92b7905769c79c6480c02daacaca2ddd49de936d912976a4d3c923723b647bf0", [:mix], [], "hexpm", "95f2e7072b85a3a4cc385602d42115b73ce0b74a9121d0d6dbbf557645ac53e4"}, } diff --git a/test/jellyfish/notifier_test.exs b/test/jellyfish/notifier_test.exs index 73d458b..047bd1d 100644 --- a/test/jellyfish/notifier_test.exs +++ b/test/jellyfish/notifier_test.exs @@ -16,11 +16,38 @@ defmodule Jellyfish.NotifierTest do alias Jellyfish.MetricsReport alias Jellyfish.WS + alias Phoenix.PubSub @peer_opts %Peer.WebRTC{} @max_peers 10 @video_codec :vp8 + @webhook_port 4000 + @webhook_url "http://172.28.0.2:#{@webhook_port}/" + @pubsub Jellyfish.PubSub + + setup_all do + children = [ + {Plug.Cowboy, + plug: WebHookPlug, scheme: :http, options: [port: @webhook_port, ip: {0, 0, 0, 0}]}, + {Phoenix.PubSub, name: Jellyfish.PubSub} + ] + + {:ok, _pid} = + Supervisor.start_link(children, + strategy: :one_for_one + ) + + :ok + end + + setup do + :ok = PubSub.subscribe(@pubsub, "webhook") + + on_exit(fn -> + :ok = PubSub.unsubscribe(@pubsub, "webhook") + end) + end describe "connecting to the server and subcribing for events" do test "when credentials are valid" do @@ -43,18 +70,28 @@ defmodule Jellyfish.NotifierTest do test "when room gets created and then deleted", %{client: client} do {:ok, %Jellyfish.Room{id: room_id}, _jellyfish_address} = - Room.create(client, max_peers: @max_peers, video_codec: @video_codec) + Room.create(client, + max_peers: @max_peers, + video_codec: @video_codec, + webhook_url: @webhook_url + ) assert_receive {:jellyfish, %RoomCreated{room_id: ^room_id}} + assert_receive %RoomCreated{room_id: ^room_id}, 2_500 :ok = Room.delete(client, room_id) assert_receive {:jellyfish, %RoomDeleted{room_id: ^room_id}} + assert_receive %RoomDeleted{room_id: ^room_id}, 2_500 end test "when peer connects and then disconnects", %{client: client} do {:ok, %Jellyfish.Room{id: room_id}, jellyfish_address} = - Room.create(client, max_peers: @max_peers, video_codec: @video_codec) + Room.create(client, + max_peers: @max_peers, + video_codec: @video_codec, + webhook_url: @webhook_url + ) {:ok, %Jellyfish.Peer{id: peer_id}, peer_token} = Room.add_peer(client, room_id, @peer_opts) @@ -65,10 +102,12 @@ defmodule Jellyfish.NotifierTest do :ok = WS.send_frame(peer_ws, auth_request) assert_receive {:jellyfish, %PeerConnected{peer_id: ^peer_id, room_id: ^room_id}} + assert_receive %PeerConnected{peer_id: ^peer_id, room_id: ^room_id}, 2_500 :ok = Room.delete_peer(client, room_id, peer_id) assert_receive {:jellyfish, %PeerDisconnected{peer_id: ^peer_id, room_id: ^room_id}} + assert_receive %PeerDisconnected{peer_id: ^peer_id, room_id: ^room_id}, 2_500 end end @@ -83,7 +122,10 @@ defmodule Jellyfish.NotifierTest do test "with one peer", %{client: client} do {:ok, %Jellyfish.Room{id: room_id}, jellyfish_address} = - Room.create(client, max_peers: @max_peers) + Room.create(client, + max_peers: @max_peers, + webhook_url: @webhook_url + ) {:ok, %Jellyfish.Peer{id: peer_id}, peer_token} = Room.add_peer(client, room_id, @peer_opts) @@ -93,6 +135,7 @@ defmodule Jellyfish.NotifierTest do :ok = WS.send_frame(peer_ws, auth_request) assert_receive {:jellyfish, %PeerConnected{peer_id: ^peer_id, room_id: ^room_id}} + assert_receive %PeerConnected{peer_id: ^peer_id, room_id: ^room_id}, 2_500 assert_receive {:jellyfish, %MetricsReport{metrics: metrics}} when metrics != %{}, 1500 end diff --git a/test/support/webhook_plug.ex b/test/support/webhook_plug.ex new file mode 100644 index 0000000..a485ce8 --- /dev/null +++ b/test/support/webhook_plug.ex @@ -0,0 +1,34 @@ +defmodule WebHookPlug do + @moduledoc false + import Plug.Conn + alias Jellyfish.Notifier + alias Phoenix.PubSub + + @pubsub Jellyfish.PubSub + + def init(opts) do + # initialize options + + IO.inspect("START WebHookPlug") + + opts + end + + def call(conn, _opts) do + {:ok, body, conn} = Plug.Conn.read_body(conn, []) + notification = Jason.decode!(body) + + notification = + if notification == %{} do + notification + else + Notifier.handle_json(notification) + end + + :ok = PubSub.broadcast(@pubsub, "webhook", notification) + + conn + |> put_resp_content_type("text/plain") + |> send_resp(200, "OK") + end +end diff --git a/test/test_helper.exs b/test/test_helper.exs index 0bffcaa..6a0af57 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -1,5 +1 @@ -if Mix.env() != :integration_test do - Divo.Suite.start(services: [:jellyfish]) -end - ExUnit.start(capture_log: true) From f94b482dcee6e30f757db89545530147cb4edadf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szuma?= Date: Mon, 16 Oct 2023 13:20:39 +0200 Subject: [PATCH 02/17] Remove usage of Divo --- mix.exs | 45 ++++++++++++++++++++++++++++++++---- test/support/webhook_plug.ex | 2 -- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/mix.exs b/mix.exs index f4f6c9e..e80fed5 100644 --- a/mix.exs +++ b/mix.exs @@ -114,10 +114,47 @@ defmodule Membrane.Template.Mixfile do def aliases do [ - integration_test: [ - # "cmd docker compose -f docker-compose-integration.yaml pull", - "cmd docker compose -f docker-compose-integration.yaml run test" - ] + test: &test_or_docker/1 ] end + + defp test_or_docker(_) do + if System.find_executable("docker") do + IO.puts("Running tests using Docker...") + docker_compose_prefix = ["docker", "compose", "-f", "docker-compose-integration.yaml"] + # {output, _exit_status} = System.cmd("docker", docker_compose_prefix ++ ["pull"]) + # stream_command(docker_compose_prefix ++ ["pull"]) + stream_command(docker_compose_prefix ++ ["run", "test"]) + else + IO.puts("Running tests locally...") + Mix.Task.run("test") + end + end + + defp stream_command(cmd) do + port = + Port.open({:spawn, Enum.join(cmd, " ")}, [ + {:line, 1024}, + :use_stdio, + :stderr_to_stdout, + :exit_status + ]) + + receive_and_print(port) + end + + defp receive_and_print(port) do + receive do + {^port, {:data, {:eol, line}}} -> + IO.puts(line) + receive_and_print(port) + + {^port, {:data, data}} -> + IO.puts(data) + receive_and_print(port) + + {^port, {:exit_status, exit_status}} -> + IO.puts("Docker command exited with status code: #{exit_status}") + end + end end diff --git a/test/support/webhook_plug.ex b/test/support/webhook_plug.ex index a485ce8..255936d 100644 --- a/test/support/webhook_plug.ex +++ b/test/support/webhook_plug.ex @@ -9,8 +9,6 @@ defmodule WebHookPlug do def init(opts) do # initialize options - IO.inspect("START WebHookPlug") - opts end From 56e348486b041b24d7fa2844cafdbd52468bbf5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szuma?= Date: Thu, 19 Oct 2023 12:19:04 +0200 Subject: [PATCH 03/17] Change docker image --- docker-compose-dev.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index 7bb97dd..4e12b7e 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -2,8 +2,7 @@ version: "3" services: jellyfish: - # image: "ghcr.io/jellyfish-dev/jellyfish:${TAG:-edge}" - image: "tmp" + image: "ghcr.io/jellyfish-dev/jellyfish:${TAG:-edge}" container_name: jellyfish restart: on-failure healthcheck: From abb7fcdd55c6f76a1f2ae4b166cc378341f9ce69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szuma?= Date: Fri, 20 Oct 2023 08:07:50 +0200 Subject: [PATCH 04/17] Docker works --- .circleci/config.yml | 2 +- docker-compose-dev.yaml | 3 ++- docker-compose-test.yaml | 34 ++++++++++++++++++++++++++++++++ test/jellyfish/notifier_test.exs | 2 +- test/jellyfish/room_test.exs | 4 ++-- 5 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 docker-compose-test.yaml diff --git a/.circleci/config.yml b/.circleci/config.yml index 534de67..ab1bf53 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,7 +16,7 @@ jobs: executor: machine_executor_amd64 steps: - checkout - - run: docker compose -f docker-compose-integration.yaml run test + - run: docker compose -f docker-compose-test.yaml run test - codecov/upload workflows: diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index 4e12b7e..7bb97dd 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -2,7 +2,8 @@ version: "3" services: jellyfish: - image: "ghcr.io/jellyfish-dev/jellyfish:${TAG:-edge}" + # image: "ghcr.io/jellyfish-dev/jellyfish:${TAG:-edge}" + image: "tmp" container_name: jellyfish restart: on-failure healthcheck: diff --git a/docker-compose-test.yaml b/docker-compose-test.yaml new file mode 100644 index 0000000..cbf5d88 --- /dev/null +++ b/docker-compose-test.yaml @@ -0,0 +1,34 @@ +version: "3" + +services: + test: + image: hexpm/elixir:1.14.4-erlang-25.3.2-alpine-3.16.5 + command: sh -c "cd app/ && apk add git && mix local.hex --force && mix local.rebar --force && mix deps.get && mix coveralls.json --warnings-as-errors $TEST_ARGS" + environment: + - MIX_ENV=integration_test + volumes: + - .:/app + ports: + - "4000:4000" + networks: + test_network: + ipv4_address: 172.28.0.2 + depends_on: + jellyfish: + condition: service_healthy + + jellyfish: + extends: + file: docker-compose-dev.yaml + service: jellyfish + environment: + - JF_HOST=jellyfish:5002 + networks: + test_network: + ipv4_address: 172.28.0.3 + +networks: + test_network: + ipam: + config: + - subnet: 172.28.0.0/24 diff --git a/test/jellyfish/notifier_test.exs b/test/jellyfish/notifier_test.exs index 047bd1d..6d0d69c 100644 --- a/test/jellyfish/notifier_test.exs +++ b/test/jellyfish/notifier_test.exs @@ -106,7 +106,7 @@ defmodule Jellyfish.NotifierTest do :ok = Room.delete_peer(client, room_id, peer_id) - assert_receive {:jellyfish, %PeerDisconnected{peer_id: ^peer_id, room_id: ^room_id}} + assert_receive {:jellyfish, %PeerDisconnected{peer_id: ^peer_id, room_id: ^room_id}}, 1_000 assert_receive %PeerDisconnected{peer_id: ^peer_id, room_id: ^room_id}, 2_500 end end diff --git a/test/jellyfish/room_test.exs b/test/jellyfish/room_test.exs index 4e3f6f2..7f22315 100644 --- a/test/jellyfish/room_test.exs +++ b/test/jellyfish/room_test.exs @@ -84,12 +84,12 @@ defmodule Jellyfish.RoomTest do end test "when request is invalid, max peers", %{client: client} do - assert {:error, "Request failed: maxPeers must be a number"} = + assert {:error, "Request failed: Expected maxPeers to be a number, got: abc"} = Room.create(client, max_peers: @invalid_max_peers) end test "when request is invalid, video codec", %{client: client} do - assert {:error, "Request failed: videoCodec must be 'h264' or 'vp8'"} = + assert {:error, "Request failed: Expected videoCodec to be 'h264' or 'vp8', got: opus"} = Room.create(client, video_codec: @invalid_video_codec) end end From 55895235fe603293845be9c353fb4771c4adb4fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szuma?= Date: Fri, 20 Oct 2023 12:09:03 +0200 Subject: [PATCH 05/17] Remove old jellyfish container before starting test --- docker-compose-dev.yaml | 3 +-- docker-compose-integration.yaml | 34 --------------------------------- docker-compose-test.yaml | 2 +- mix.exs | 12 +++++++----- 4 files changed, 9 insertions(+), 42 deletions(-) delete mode 100644 docker-compose-integration.yaml diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index 7bb97dd..4e12b7e 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -2,8 +2,7 @@ version: "3" services: jellyfish: - # image: "ghcr.io/jellyfish-dev/jellyfish:${TAG:-edge}" - image: "tmp" + image: "ghcr.io/jellyfish-dev/jellyfish:${TAG:-edge}" container_name: jellyfish restart: on-failure healthcheck: diff --git a/docker-compose-integration.yaml b/docker-compose-integration.yaml deleted file mode 100644 index e4c334a..0000000 --- a/docker-compose-integration.yaml +++ /dev/null @@ -1,34 +0,0 @@ -version: "3" - -services: - test: - image: hexpm/elixir:1.14.4-erlang-25.3.2-alpine-3.16.5 - command: sh -c "cd app/ && apk add git && mix local.hex --force && mix local.rebar --force && mix deps.get && mix coveralls.json --warnings-as-errors" - environment: - - MIX_ENV=integration_test - volumes: - - .:/app - ports: - - "4000:4000" - networks: - test_network: - ipv4_address: 172.28.0.2 - depends_on: - jellyfish: - condition: service_healthy - - jellyfish: - extends: - file: docker-compose-dev.yaml - service: jellyfish - environment: - - JF_HOST=jellyfish:5002 - networks: - test_network: - ipv4_address: 172.28.0.3 - -networks: - test_network: - ipam: - config: - - subnet: 172.28.0.0/16 diff --git a/docker-compose-test.yaml b/docker-compose-test.yaml index cbf5d88..791af6f 100644 --- a/docker-compose-test.yaml +++ b/docker-compose-test.yaml @@ -3,7 +3,7 @@ version: "3" services: test: image: hexpm/elixir:1.14.4-erlang-25.3.2-alpine-3.16.5 - command: sh -c "cd app/ && apk add git && mix local.hex --force && mix local.rebar --force && mix deps.get && mix coveralls.json --warnings-as-errors $TEST_ARGS" + command: sh -c "cd app/ && apk add git && mix local.hex --force && mix local.rebar --force && mix deps.get && mix coveralls.json --warnings-as-errors" environment: - MIX_ENV=integration_test volumes: diff --git a/mix.exs b/mix.exs index e80fed5..91b8aa9 100644 --- a/mix.exs +++ b/mix.exs @@ -118,13 +118,15 @@ defmodule Membrane.Template.Mixfile do ] end - defp test_or_docker(_) do + defp test_or_docker(_opts) do if System.find_executable("docker") do IO.puts("Running tests using Docker...") - docker_compose_prefix = ["docker", "compose", "-f", "docker-compose-integration.yaml"] - # {output, _exit_status} = System.cmd("docker", docker_compose_prefix ++ ["pull"]) - # stream_command(docker_compose_prefix ++ ["pull"]) - stream_command(docker_compose_prefix ++ ["run", "test"]) + + docker_compose_prefix = ["docker", "compose", "-f", "docker-compose-test.yaml"] + + stream_command(["docker", "rm", "-f", "jellyfish"]) + stream_command(docker_compose_prefix ++ ["pull"]) + stream_command(docker_compose_prefix ++ ["run", "--remove-orphans", "test"]) else IO.puts("Running tests locally...") Mix.Task.run("test") From 20ddfbb8e5fd7e066edc5a34518b4c250c0fbfed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szuma?= Date: Fri, 20 Oct 2023 14:25:44 +0200 Subject: [PATCH 06/17] Remove unused code in webhook_plug --- test/support/webhook_plug.ex | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/test/support/webhook_plug.ex b/test/support/webhook_plug.ex index 255936d..9a5e70f 100644 --- a/test/support/webhook_plug.ex +++ b/test/support/webhook_plug.ex @@ -7,8 +7,6 @@ defmodule WebHookPlug do @pubsub Jellyfish.PubSub def init(opts) do - # initialize options - opts end @@ -16,12 +14,7 @@ defmodule WebHookPlug do {:ok, body, conn} = Plug.Conn.read_body(conn, []) notification = Jason.decode!(body) - notification = - if notification == %{} do - notification - else - Notifier.handle_json(notification) - end + notification = Notifier.handle_json(notification) :ok = PubSub.broadcast(@pubsub, "webhook", notification) From 330494dd62e661f2a2ac99c436696e4a1d4dd025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szuma?= Date: Mon, 23 Oct 2023 14:36:32 +0200 Subject: [PATCH 07/17] Changes after review --- config/integration_test.exs | 5 --- config/test.exs | 5 ++- docker-compose-test.yaml | 2 - lib/jellyfish/notifier.ex | 23 +++++++++-- lib/jellyfish/room.ex | 1 + mix.exs | 45 ++++++++++++-------- test/jellyfish/notifier_test.exs | 70 +++++++++++++++++++++----------- test/jellyfish/room_test.exs | 14 ++++--- test/support/webhook_plug.ex | 4 +- 9 files changed, 111 insertions(+), 58 deletions(-) delete mode 100644 config/integration_test.exs diff --git a/config/integration_test.exs b/config/integration_test.exs deleted file mode 100644 index 6998aa3..0000000 --- a/config/integration_test.exs +++ /dev/null @@ -1,5 +0,0 @@ -import Config - -config :jellyfish_server_sdk, - server_address: "jellyfish:5002", - server_api_token: "development" diff --git a/config/test.exs b/config/test.exs index db4745c..797732c 100644 --- a/config/test.exs +++ b/config/test.exs @@ -1,5 +1,6 @@ import Config config :jellyfish_server_sdk, - server_address: "localhost:5002", - server_api_token: "development" + server_address: "jellyfish:5002", + server_api_token: "development", + webhook_address: "172.28.0.2" diff --git a/docker-compose-test.yaml b/docker-compose-test.yaml index 791af6f..817cab5 100644 --- a/docker-compose-test.yaml +++ b/docker-compose-test.yaml @@ -4,8 +4,6 @@ services: test: image: hexpm/elixir:1.14.4-erlang-25.3.2-alpine-3.16.5 command: sh -c "cd app/ && apk add git && mix local.hex --force && mix local.rebar --force && mix deps.get && mix coveralls.json --warnings-as-errors" - environment: - - MIX_ENV=integration_test volumes: - .:/app ports: diff --git a/lib/jellyfish/notifier.ex b/lib/jellyfish/notifier.ex index b733c61..9dc68e2 100644 --- a/lib/jellyfish/notifier.ex +++ b/lib/jellyfish/notifier.ex @@ -7,7 +7,7 @@ defmodule Jellyfish.Notifier do ``` # Start the Notifier - iex> {:ok, notifier} = Jellyfish.Notifier.start() + iex> {:ok, _notifier} = Jellyfish.Notifier.start() {:ok, #PID<0.301.0>} ``` @@ -164,8 +164,25 @@ defmodule Jellyfish.Notifier do :ok end - @spec handle_json(term()) :: struct() - def handle_json(json) do + @doc """ + Decode received webhook to `Jellyfish.Notification` structs. + + ``` + iex> %{ + "notification" => <<18, 76, 10, 36, 102, 98, 102, 52, 49, 57, 48, 99, 45, 53, 99, 55, 54, 45, 52, + 49, 53, 99, 45, 56, 57, 51, 57, 45, 53, 50, 99, 54, 101, 100, 50, 48, 56, 54, + 56, 98, 18, 36, 99, 55, 50, 51, 54, 53, 56, 55, 45, 53, 100, 102, 56, 45, 52, + 98, 52, 49, 45, 98, 54, 101, 52, 45, 50, 54, 56, 101, 55, 49, 49, 51, 51, 101, + 101, 50>> + } |> Jellyfish.Notifier.decode_webhook() + %Jellyfish.Notification.PeerConnected{ + room_id: "fbf4190c-5c76-415c-8939-52c6ed20868b", + peer_id: "c7236587-5df8-4b41-b6e4-268e71133ee2" + } + ``` + """ + @spec decode_webhook(term()) :: struct() + def decode_webhook(json) do %ServerMessage{content: {_type, notification}} = json |> Map.get("notification") diff --git a/lib/jellyfish/room.ex b/lib/jellyfish/room.ex index 5602215..06e8def 100644 --- a/lib/jellyfish/room.ex +++ b/lib/jellyfish/room.ex @@ -4,6 +4,7 @@ defmodule Jellyfish.Room do ## Examples ``` + iex> iex> client = Jellyfish.Client.new() iex> assert {:ok, %Jellyfish.Room{ ...> components: [], diff --git a/mix.exs b/mix.exs index 91b8aa9..706008c 100644 --- a/mix.exs +++ b/mix.exs @@ -33,7 +33,8 @@ defmodule Membrane.Template.Mixfile do "coveralls.detail": :test, "coveralls.post": :test, "coveralls.html": :test, - "coveralls.json": :test + "coveralls.json": :test, + test_without_docker: :test ] ] end @@ -44,7 +45,7 @@ defmodule Membrane.Template.Mixfile do ] end - defp elixirc_paths(env) when env in [:test, :integration_test], do: ["lib", "test/support"] + defp elixirc_paths(:test), do: ["lib", "test/support"] defp elixirc_paths(_env), do: ["lib"] defp deps do @@ -63,11 +64,11 @@ defmodule Membrane.Template.Mixfile do {:ex_doc, ">= 0.0.0", only: :dev, runtime: false}, {:dialyxir, ">= 0.0.0", only: :dev, runtime: false}, {:credo, ">= 0.0.0", only: :dev, runtime: false}, - {:excoveralls, ">= 0.0.0", only: [:test, :integration_test], runtime: false}, + {:excoveralls, ">= 0.0.0", only: :test, runtime: false}, # Test deps - {:plug_cowboy, "~> 2.5", only: [:test, :integration_test]}, - {:phoenix_pubsub, "~> 2.1", only: [:test, :integration_test]} + {:plug_cowboy, "~> 2.5", only: :test}, + {:phoenix_pubsub, "~> 2.1", only: :test} ] end @@ -114,22 +115,34 @@ defmodule Membrane.Template.Mixfile do def aliases do [ - test: &test_or_docker/1 + test: &test_in_docker/1, + test_without_docker: ["test --force"] ] end - defp test_or_docker(_opts) do - if System.find_executable("docker") do - IO.puts("Running tests using Docker...") + defp test_in_docker(opts) do + cond do + List.last(opts) == "--force" -> + IO.puts("Running tests locally (it requires setting up jellyfish without docker) ...") - docker_compose_prefix = ["docker", "compose", "-f", "docker-compose-test.yaml"] + System.put_env("SERVER_ADDRESS", "127.0.0.1:5002") + System.put_env("WEBHOOK_ADDRESS", "127.0.0.1") - stream_command(["docker", "rm", "-f", "jellyfish"]) - stream_command(docker_compose_prefix ++ ["pull"]) - stream_command(docker_compose_prefix ++ ["run", "--remove-orphans", "test"]) - else - IO.puts("Running tests locally...") - Mix.Task.run("test") + Mix.Task.run("test", ["--exclude", "doctest"]) + + System.find_executable("docker") -> + IO.puts("Running tests using Docker...") + + docker_compose_prefix = ["docker", "compose", "-f", "docker-compose-test.yaml"] + + stream_command(["docker", "rm", "-f", "jellyfish"]) + stream_command(docker_compose_prefix ++ ["pull"]) + stream_command(docker_compose_prefix ++ ["run", "--remove-orphans", "test"]) + + true -> + IO.puts("Running tests inside docker container ...") + + Mix.Task.run("test") end end diff --git a/test/jellyfish/notifier_test.exs b/test/jellyfish/notifier_test.exs index 6d0d69c..1e0bfef 100644 --- a/test/jellyfish/notifier_test.exs +++ b/test/jellyfish/notifier_test.exs @@ -1,6 +1,5 @@ defmodule Jellyfish.NotifierTest do use ExUnit.Case - alias Jellyfish.{Client, Notifier, Peer, Room} alias Jellyfish.PeerMessage @@ -23,7 +22,6 @@ defmodule Jellyfish.NotifierTest do @max_peers 10 @video_codec :vp8 @webhook_port 4000 - @webhook_url "http://172.28.0.2:#{@webhook_port}/" @pubsub Jellyfish.PubSub setup_all do @@ -47,50 +45,76 @@ defmodule Jellyfish.NotifierTest do on_exit(fn -> :ok = PubSub.unsubscribe(@pubsub, "webhook") end) + + webhook_address = + System.get_env( + "WEBHOOK_ADDRESS", + Application.fetch_env!(:jellyfish_server_sdk, :webhook_address) + ) + + webhook_address = "http://#{webhook_address}:#{@webhook_port}/" + + server_address = + System.get_env( + "SERVER_ADDRESS", + Application.fetch_env!(:jellyfish_server_sdk, :server_address) + ) + + {:ok, %{webhook_address: webhook_address, server_address: server_address}} end describe "connecting to the server and subcribing for events" do - test "when credentials are valid" do - assert {:ok, pid} = Notifier.start_link() + test "when credentials are valid", %{server_address: server_address} do + assert {:ok, pid} = Notifier.start_link(server_address: server_address) assert is_pid(pid) end - test "when token is invalid" do - assert {:error, :invalid_token} = Notifier.start_link(server_api_token: "invalid_token") + test "when token is invalid", %{server_address: server_address} do + assert {:error, :invalid_token} = + Notifier.start_link( + server_api_token: "invalid_token", + server_address: server_address + ) end end describe "receiving notifications" do - setup do - {:ok, notifier} = Notifier.start_link() + setup %{server_address: server_address, webhook_address: webhook_address} do + {:ok, notifier} = Notifier.start_link(server_address: server_address) :ok = Notifier.subscribe_server_notifications(notifier) - %{client: Client.new()} + %{client: Client.new(server_address: server_address), webhook_address: webhook_address} end - test "when room gets created and then deleted", %{client: client} do + test "when room gets created and then deleted", %{ + client: client, + webhook_address: webhook_address + } do {:ok, %Jellyfish.Room{id: room_id}, _jellyfish_address} = Room.create(client, max_peers: @max_peers, video_codec: @video_codec, - webhook_url: @webhook_url + webhook_url: webhook_address ) assert_receive {:jellyfish, %RoomCreated{room_id: ^room_id}} - assert_receive %RoomCreated{room_id: ^room_id}, 2_500 + assert_receive {:webhook, %RoomCreated{room_id: ^room_id}}, 2_500 :ok = Room.delete(client, room_id) assert_receive {:jellyfish, %RoomDeleted{room_id: ^room_id}} - assert_receive %RoomDeleted{room_id: ^room_id}, 2_500 + assert_receive {:webhook, %RoomDeleted{room_id: ^room_id}}, 2_500 end - test "when peer connects and then disconnects", %{client: client} do + test "when peer connects and then disconnects", %{ + client: client, + webhook_address: webhook_address + } do {:ok, %Jellyfish.Room{id: room_id}, jellyfish_address} = Room.create(client, max_peers: @max_peers, video_codec: @video_codec, - webhook_url: @webhook_url + webhook_url: webhook_address ) {:ok, %Jellyfish.Peer{id: peer_id}, peer_token} = Room.add_peer(client, room_id, @peer_opts) @@ -102,29 +126,29 @@ defmodule Jellyfish.NotifierTest do :ok = WS.send_frame(peer_ws, auth_request) assert_receive {:jellyfish, %PeerConnected{peer_id: ^peer_id, room_id: ^room_id}} - assert_receive %PeerConnected{peer_id: ^peer_id, room_id: ^room_id}, 2_500 + assert_receive {:webhook, %PeerConnected{peer_id: ^peer_id, room_id: ^room_id}}, 2_500 :ok = Room.delete_peer(client, room_id, peer_id) assert_receive {:jellyfish, %PeerDisconnected{peer_id: ^peer_id, room_id: ^room_id}}, 1_000 - assert_receive %PeerDisconnected{peer_id: ^peer_id, room_id: ^room_id}, 2_500 + assert_receive {:webhook, %PeerDisconnected{peer_id: ^peer_id, room_id: ^room_id}}, 2_500 end end describe "receiving metrics" do - setup do - {:ok, notifier} = Notifier.start_link() + setup %{server_address: server_address, webhook_address: webhook_address} do + {:ok, notifier} = Notifier.start_link(server_address: server_address) :ok = Notifier.subscribe_server_notifications(notifier) :ok = Notifier.subscribe_metrics(notifier) - %{client: Client.new()} + %{client: Client.new(server_address: server_address), webhook_address: webhook_address} end - test "with one peer", %{client: client} do + test "with one peer", %{client: client, webhook_address: webhook_address} do {:ok, %Jellyfish.Room{id: room_id}, jellyfish_address} = Room.create(client, max_peers: @max_peers, - webhook_url: @webhook_url + webhook_url: webhook_address ) {:ok, %Jellyfish.Peer{id: peer_id}, peer_token} = Room.add_peer(client, room_id, @peer_opts) @@ -135,7 +159,7 @@ defmodule Jellyfish.NotifierTest do :ok = WS.send_frame(peer_ws, auth_request) assert_receive {:jellyfish, %PeerConnected{peer_id: ^peer_id, room_id: ^room_id}} - assert_receive %PeerConnected{peer_id: ^peer_id, room_id: ^room_id}, 2_500 + assert_receive {:webhook, %PeerConnected{peer_id: ^peer_id, room_id: ^room_id}}, 2_500 assert_receive {:jellyfish, %MetricsReport{metrics: metrics}} when metrics != %{}, 1500 end diff --git a/test/jellyfish/room_test.exs b/test/jellyfish/room_test.exs index 7f22315..0124962 100644 --- a/test/jellyfish/room_test.exs +++ b/test/jellyfish/room_test.exs @@ -43,11 +43,17 @@ defmodule Jellyfish.RoomTest do end setup do - %{client: Client.new()} + server_address = + System.get_env( + "SERVER_ADDRESS", + Application.fetch_env!(:jellyfish_server_sdk, :server_address) + ) + + %{client: Client.new(server_address: server_address), server_address: server_address} end describe "auth" do - test "correct token", %{client: client} do + test "correct token", %{client: client, server_address: server_address} do assert {:ok, room, jellyfish_address} = Room.create(client, max_peers: @max_peers, video_codec: @video_codec) @@ -58,7 +64,6 @@ defmodule Jellyfish.RoomTest do peers: [] } = room - server_address = Application.fetch_env!(:jellyfish_server_sdk, :server_address) assert ^server_address = jellyfish_address end @@ -69,7 +74,7 @@ defmodule Jellyfish.RoomTest do end describe "Room.create/2" do - test "when request is valid", %{client: client} do + test "when request is valid", %{client: client, server_address: server_address} do assert {:ok, room, jellyfish_address} = Room.create(client, max_peers: @max_peers) assert %Jellyfish.Room{ @@ -79,7 +84,6 @@ defmodule Jellyfish.RoomTest do peers: [] } = room - server_address = Application.fetch_env!(:jellyfish_server_sdk, :server_address) assert ^server_address = jellyfish_address end diff --git a/test/support/webhook_plug.ex b/test/support/webhook_plug.ex index 9a5e70f..69dbebf 100644 --- a/test/support/webhook_plug.ex +++ b/test/support/webhook_plug.ex @@ -14,9 +14,9 @@ defmodule WebHookPlug do {:ok, body, conn} = Plug.Conn.read_body(conn, []) notification = Jason.decode!(body) - notification = Notifier.handle_json(notification) + notification = Notifier.decode_webhook(notification) - :ok = PubSub.broadcast(@pubsub, "webhook", notification) + :ok = PubSub.broadcast(@pubsub, "webhook", {:webhook, notification}) conn |> put_resp_content_type("text/plain") From 715b4dceb90cf6b7dd686a02b50b768894129e88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szuma?= Date: Mon, 23 Oct 2023 14:44:15 +0200 Subject: [PATCH 08/17] Add utils module for reading WEBHOOK_ADDRESS and SERVER_ADDRESS --- lib/jellyfish/notifier.ex | 4 ++-- lib/jellyfish/room.ex | 1 - mix.exs | 4 ++-- test/jellyfish/notifier_test.exs | 14 ++------------ test/jellyfish/room_test.exs | 6 +----- test/support/utils.ex | 20 ++++++++++++++++++++ 6 files changed, 27 insertions(+), 22 deletions(-) create mode 100644 test/support/utils.ex diff --git a/lib/jellyfish/notifier.ex b/lib/jellyfish/notifier.ex index 9dc68e2..a829f93 100644 --- a/lib/jellyfish/notifier.ex +++ b/lib/jellyfish/notifier.ex @@ -7,7 +7,7 @@ defmodule Jellyfish.Notifier do ``` # Start the Notifier - iex> {:ok, _notifier} = Jellyfish.Notifier.start() + iex> {:ok, notifier} = Jellyfish.Notifier.start() {:ok, #PID<0.301.0>} ``` @@ -165,7 +165,7 @@ defmodule Jellyfish.Notifier do end @doc """ - Decode received webhook to `Jellyfish.Notification` structs. + Decode received webhook to notification structs. ``` iex> %{ diff --git a/lib/jellyfish/room.ex b/lib/jellyfish/room.ex index 06e8def..5602215 100644 --- a/lib/jellyfish/room.ex +++ b/lib/jellyfish/room.ex @@ -4,7 +4,6 @@ defmodule Jellyfish.Room do ## Examples ``` - iex> iex> client = Jellyfish.Client.new() iex> assert {:ok, %Jellyfish.Room{ ...> components: [], diff --git a/mix.exs b/mix.exs index 706008c..46d0d8a 100644 --- a/mix.exs +++ b/mix.exs @@ -116,13 +116,13 @@ defmodule Membrane.Template.Mixfile do def aliases do [ test: &test_in_docker/1, - test_without_docker: ["test --force"] + test_without_docker: ["test --without_docker"] ] end defp test_in_docker(opts) do cond do - List.last(opts) == "--force" -> + List.last(opts) == "--without_docker" -> IO.puts("Running tests locally (it requires setting up jellyfish without docker) ...") System.put_env("SERVER_ADDRESS", "127.0.0.1:5002") diff --git a/test/jellyfish/notifier_test.exs b/test/jellyfish/notifier_test.exs index 1e0bfef..14a63bd 100644 --- a/test/jellyfish/notifier_test.exs +++ b/test/jellyfish/notifier_test.exs @@ -46,19 +46,9 @@ defmodule Jellyfish.NotifierTest do :ok = PubSub.unsubscribe(@pubsub, "webhook") end) - webhook_address = - System.get_env( - "WEBHOOK_ADDRESS", - Application.fetch_env!(:jellyfish_server_sdk, :webhook_address) - ) - - webhook_address = "http://#{webhook_address}:#{@webhook_port}/" + webhook_address = Jellyfish.Test.Utils.read_webhook_address(@webhook_port) - server_address = - System.get_env( - "SERVER_ADDRESS", - Application.fetch_env!(:jellyfish_server_sdk, :server_address) - ) + server_address = Jellyfish.Test.Utils.read_server_address() {:ok, %{webhook_address: webhook_address, server_address: server_address}} end diff --git a/test/jellyfish/room_test.exs b/test/jellyfish/room_test.exs index 0124962..f7f8406 100644 --- a/test/jellyfish/room_test.exs +++ b/test/jellyfish/room_test.exs @@ -43,11 +43,7 @@ defmodule Jellyfish.RoomTest do end setup do - server_address = - System.get_env( - "SERVER_ADDRESS", - Application.fetch_env!(:jellyfish_server_sdk, :server_address) - ) + server_address = Jellyfish.Test.Utils.read_server_address() %{client: Client.new(server_address: server_address), server_address: server_address} end diff --git a/test/support/utils.ex b/test/support/utils.ex new file mode 100644 index 0000000..fdd6d91 --- /dev/null +++ b/test/support/utils.ex @@ -0,0 +1,20 @@ +defmodule Jellyfish.Test.Utils do + @moduledoc false + + def read_server_address() do + System.get_env( + "SERVER_ADDRESS", + Application.fetch_env!(:jellyfish_server_sdk, :server_address) + ) + end + + def read_webhook_address(webhook_port) do + webhook_address = + System.get_env( + "WEBHOOK_ADDRESS", + Application.fetch_env!(:jellyfish_server_sdk, :webhook_address) + ) + + "http://#{webhook_address}:#{webhook_port}/" + end +end From 021ad60e58bbc99e9bd76c630b2b76b2bd1f04e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szuma?= Date: Tue, 24 Oct 2023 07:55:24 +0200 Subject: [PATCH 09/17] Add module WebhookNotifier --- README.md | 8 ++--- config/test.exs | 2 +- docker-compose-test.yaml | 12 ------- examples/server_socket.exs | 6 ++-- lib/jellyfish/webhook_notifier.ex | 35 +++++++++++++++++++ lib/jellyfish/{notifier.ex => ws_notifier.ex} | 35 +++---------------- mix.exs | 8 ++--- test/jellyfish/notifier_test.exs | 17 ++++----- test/support/webhook_plug.ex | 4 +-- 9 files changed, 62 insertions(+), 65 deletions(-) create mode 100644 lib/jellyfish/webhook_notifier.ex rename lib/jellyfish/{notifier.ex => ws_notifier.ex} (86%) diff --git a/README.md b/README.md index d70e85a..488fe30 100644 --- a/README.md +++ b/README.md @@ -35,14 +35,14 @@ config :jellyfish_server_sdk, secure?: true ``` -Alternatively, the connection options can be provided when creating a `Jellyfish.Client` or starting `Jellyfish.Notifier`: +Alternatively, the connection options can be provided when creating a `Jellyfish.Client` or starting `Jellyfish.WSNotifier`: ```elixir client = Jellyfish.Client.new(server_address: "localhost:5002", server_api_token: "your-jellyfish-token") {:ok, notifier} = - Jellyfish.Notifier.start( + Jellyfish.WSNotifier.start( server_address: "localhost:5002", server_api_token: "your-jellyfish-token" ) @@ -54,8 +54,8 @@ Make API calls to Jellyfish and receive server events: ```elixir # start process responsible for receiving events -{:ok, notifier} = Jellyfish.Notifier.start() -:ok = Jellyfish.Notifier.subscribe_server_notifications(notifier) +{:ok, notifier} = Jellyfish.WSNotifier.start() +:ok = Jellyfish.WSNotifier.subscribe_server_notifications(notifier) # create HTTP client instance client = Jellyfish.Client.new() diff --git a/config/test.exs b/config/test.exs index 797732c..16882d2 100644 --- a/config/test.exs +++ b/config/test.exs @@ -3,4 +3,4 @@ import Config config :jellyfish_server_sdk, server_address: "jellyfish:5002", server_api_token: "development", - webhook_address: "172.28.0.2" + webhook_address: "test" diff --git a/docker-compose-test.yaml b/docker-compose-test.yaml index 817cab5..1c87ad7 100644 --- a/docker-compose-test.yaml +++ b/docker-compose-test.yaml @@ -8,9 +8,6 @@ services: - .:/app ports: - "4000:4000" - networks: - test_network: - ipv4_address: 172.28.0.2 depends_on: jellyfish: condition: service_healthy @@ -21,12 +18,3 @@ services: service: jellyfish environment: - JF_HOST=jellyfish:5002 - networks: - test_network: - ipv4_address: 172.28.0.3 - -networks: - test_network: - ipam: - config: - - subnet: 172.28.0.0/24 diff --git a/examples/server_socket.exs b/examples/server_socket.exs index e3e4b55..2ff3361 100644 --- a/examples/server_socket.exs +++ b/examples/server_socket.exs @@ -9,10 +9,10 @@ server_address = "localhost:5002" server_api_token = "development" {:ok, notifier} = - Jellyfish.Notifier.start(server_address: server_address, server_api_token: server_api_token) + Jellyfish.WSNotifier.start(server_address: server_address, server_api_token: server_api_token) -{:ok, _rooms} = Jellyfish.Notifier.subscribe_server_notifications(notifier, :all) -:ok = Jellyfish.Notifier.subscribe_metrics(notifier) +{:ok, _rooms} = Jellyfish.WSNotifier.subscribe_server_notifications(notifier, :all) +:ok = Jellyfish.WSNotifier.subscribe_metrics(notifier) receive_notification = fn receive_notification -> receive do diff --git a/lib/jellyfish/webhook_notifier.ex b/lib/jellyfish/webhook_notifier.ex new file mode 100644 index 0000000..243f1b8 --- /dev/null +++ b/lib/jellyfish/webhook_notifier.ex @@ -0,0 +1,35 @@ +defmodule Jellyfish.WebhookNotifier do + @moduledoc """ + Module defining a function allowing decoding received webhook notificaiton from jellyfish to notification structs. + """ + + @doc """ + Decode received webhook to notification structs. + + ``` + iex> %{ + ...> "notification" => <<18, 76, 10, 36, 102, 98, 102, 52, 49, 57, 48, 99, 45, 53, 99, 55, 54, 45, 52, + ...> 49, 53, 99, 45, 56, 57, 51, 57, 45, 53, 50, 99, 54, 101, 100, 50, 48, 56, 54, + ...> 56, 98, 18, 36, 99, 55, 50, 51, 54, 53, 56, 55, 45, 53, 100, 102, 56, 45, 52, + ...> 98, 52, 49, 45, 98, 54, 101, 52, 45, 50, 54, 56, 101, 55, 49, 49, 51, 51, 101, + ...> 101, 50>> + ...> } |> Jellyfish.WebhookNotifier.receive() + %Jellyfish.Notification.PeerConnected{ + room_id: "fbf4190c-5c76-415c-8939-52c6ed20868b", + peer_id: "c7236587-5df8-4b41-b6e4-268e71133ee2" + } + ``` + """ + + alias Jellyfish.{Notification, ServerMessage} + + @spec receive(term()) :: struct() + def receive(json) do + %ServerMessage{content: {_type, notification}} = + json + |> Map.get("notification") + |> ServerMessage.decode() + + Notification.to_notification(notification) + end +end diff --git a/lib/jellyfish/notifier.ex b/lib/jellyfish/ws_notifier.ex similarity index 86% rename from lib/jellyfish/notifier.ex rename to lib/jellyfish/ws_notifier.ex index a829f93..ed29861 100644 --- a/lib/jellyfish/notifier.ex +++ b/lib/jellyfish/ws_notifier.ex @@ -1,4 +1,4 @@ -defmodule Jellyfish.Notifier do +defmodule Jellyfish.WSNotifier do @moduledoc """ Module defining a process responsible for establishing WebSocket connection and receiving events from Jellyfish server. @@ -7,13 +7,13 @@ defmodule Jellyfish.Notifier do ``` # Start the Notifier - iex> {:ok, notifier} = Jellyfish.Notifier.start() + iex> {:ok, notifier} = Jellyfish.WSNotifier.start() {:ok, #PID<0.301.0>} ``` ``` # Subscribe current process to server notifications. - iex> :ok = Jellyfish.Notifier.subscribe_server_notifications(notifier) + iex> :ok = Jellyfish.WSNotifier.subscribe_server_notifications(notifier) # here add a room and a peer using functions from `Jellyfish.Room` module # you should receive a notification after the peer established connection @@ -28,7 +28,7 @@ defmodule Jellyfish.Notifier do When starting the Notifier, you can provide the name under which the process will be registered. ``` - iex> {:ok, notifier} = Jellyfish.Notifier.start_link(name: Jellyfish.Notifier) + iex> {:ok, notifier} = Jellyfish.WSNotifier.start_link(name: Jellyfish.WSNotifier) ``` """ @@ -164,33 +164,6 @@ defmodule Jellyfish.Notifier do :ok end - @doc """ - Decode received webhook to notification structs. - - ``` - iex> %{ - "notification" => <<18, 76, 10, 36, 102, 98, 102, 52, 49, 57, 48, 99, 45, 53, 99, 55, 54, 45, 52, - 49, 53, 99, 45, 56, 57, 51, 57, 45, 53, 50, 99, 54, 101, 100, 50, 48, 56, 54, - 56, 98, 18, 36, 99, 55, 50, 51, 54, 53, 56, 55, 45, 53, 100, 102, 56, 45, 52, - 98, 52, 49, 45, 98, 54, 101, 52, 45, 50, 54, 56, 101, 55, 49, 49, 51, 51, 101, - 101, 50>> - } |> Jellyfish.Notifier.decode_webhook() - %Jellyfish.Notification.PeerConnected{ - room_id: "fbf4190c-5c76-415c-8939-52c6ed20868b", - peer_id: "c7236587-5df8-4b41-b6e4-268e71133ee2" - } - ``` - """ - @spec decode_webhook(term()) :: struct() - def decode_webhook(json) do - %ServerMessage{content: {_type, notification}} = - json - |> Map.get("notification") - |> ServerMessage.decode() - - Notification.to_notification(notification) - end - defp connect(fun, opts) do {address, api_token, secure?} = Utils.get_options_or_defaults(opts) address = if secure?, do: "wss://#{address}", else: "ws://#{address}" diff --git a/mix.exs b/mix.exs index 46d0d8a..737473b 100644 --- a/mix.exs +++ b/mix.exs @@ -34,7 +34,7 @@ defmodule Membrane.Template.Mixfile do "coveralls.post": :test, "coveralls.html": :test, "coveralls.json": :test, - test_without_docker: :test + "test.local": :test ] ] end @@ -116,7 +116,7 @@ defmodule Membrane.Template.Mixfile do def aliases do [ test: &test_in_docker/1, - test_without_docker: ["test --without_docker"] + "test.local": ["test --without_docker"] ] end @@ -135,9 +135,9 @@ defmodule Membrane.Template.Mixfile do docker_compose_prefix = ["docker", "compose", "-f", "docker-compose-test.yaml"] - stream_command(["docker", "rm", "-f", "jellyfish"]) stream_command(docker_compose_prefix ++ ["pull"]) - stream_command(docker_compose_prefix ++ ["run", "--remove-orphans", "test"]) + stream_command(docker_compose_prefix ++ ["up", "--remove-orphans", "test"]) + stream_command(docker_compose_prefix ++ ["down"]) true -> IO.puts("Running tests inside docker container ...") diff --git a/test/jellyfish/notifier_test.exs b/test/jellyfish/notifier_test.exs index 14a63bd..cc966c0 100644 --- a/test/jellyfish/notifier_test.exs +++ b/test/jellyfish/notifier_test.exs @@ -1,6 +1,7 @@ defmodule Jellyfish.NotifierTest do use ExUnit.Case - alias Jellyfish.{Client, Notifier, Peer, Room} + doctest Jellyfish.WebhookNotifier + alias Jellyfish.{Client, WSNotifier, Peer, Room} alias Jellyfish.PeerMessage alias Jellyfish.PeerMessage.AuthRequest @@ -55,13 +56,13 @@ defmodule Jellyfish.NotifierTest do describe "connecting to the server and subcribing for events" do test "when credentials are valid", %{server_address: server_address} do - assert {:ok, pid} = Notifier.start_link(server_address: server_address) + assert {:ok, pid} = WSNotifier.start_link(server_address: server_address) assert is_pid(pid) end test "when token is invalid", %{server_address: server_address} do assert {:error, :invalid_token} = - Notifier.start_link( + WSNotifier.start_link( server_api_token: "invalid_token", server_address: server_address ) @@ -70,8 +71,8 @@ defmodule Jellyfish.NotifierTest do describe "receiving notifications" do setup %{server_address: server_address, webhook_address: webhook_address} do - {:ok, notifier} = Notifier.start_link(server_address: server_address) - :ok = Notifier.subscribe_server_notifications(notifier) + {:ok, notifier} = WSNotifier.start_link(server_address: server_address) + :ok = WSNotifier.subscribe_server_notifications(notifier) %{client: Client.new(server_address: server_address), webhook_address: webhook_address} end @@ -127,9 +128,9 @@ defmodule Jellyfish.NotifierTest do describe "receiving metrics" do setup %{server_address: server_address, webhook_address: webhook_address} do - {:ok, notifier} = Notifier.start_link(server_address: server_address) - :ok = Notifier.subscribe_server_notifications(notifier) - :ok = Notifier.subscribe_metrics(notifier) + {:ok, notifier} = WSNotifier.start_link(server_address: server_address) + :ok = WSNotifier.subscribe_server_notifications(notifier) + :ok = WSNotifier.subscribe_metrics(notifier) %{client: Client.new(server_address: server_address), webhook_address: webhook_address} end diff --git a/test/support/webhook_plug.ex b/test/support/webhook_plug.ex index 69dbebf..b45f898 100644 --- a/test/support/webhook_plug.ex +++ b/test/support/webhook_plug.ex @@ -1,7 +1,7 @@ defmodule WebHookPlug do @moduledoc false import Plug.Conn - alias Jellyfish.Notifier + alias Jellyfish.WebhookNotifier alias Phoenix.PubSub @pubsub Jellyfish.PubSub @@ -14,7 +14,7 @@ defmodule WebHookPlug do {:ok, body, conn} = Plug.Conn.read_body(conn, []) notification = Jason.decode!(body) - notification = Notifier.decode_webhook(notification) + notification = WebhookNotifier.receive(notification) :ok = PubSub.broadcast(@pubsub, "webhook", {:webhook, notification}) From 938b3145a9ea55207f70a393f363ac22ef169f4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szuma?= Date: Tue, 24 Oct 2023 08:02:31 +0200 Subject: [PATCH 10/17] Fix typo --- lib/jellyfish/webhook_notifier.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jellyfish/webhook_notifier.ex b/lib/jellyfish/webhook_notifier.ex index 243f1b8..4d6f502 100644 --- a/lib/jellyfish/webhook_notifier.ex +++ b/lib/jellyfish/webhook_notifier.ex @@ -1,6 +1,6 @@ defmodule Jellyfish.WebhookNotifier do @moduledoc """ - Module defining a function allowing decoding received webhook notificaiton from jellyfish to notification structs. + Module defining a function allowing decoding received webhook notification from jellyfish to notification structs. """ @doc """ From 6e2764e778f68fc1ab6242edfdc6421108861c7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szuma?= Date: Tue, 24 Oct 2023 08:08:53 +0200 Subject: [PATCH 11/17] Change docker compose run to docker compose up in circle.ci config --- .circleci/config.yml | 2 +- test/jellyfish/notifier_test.exs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ab1bf53..2664168 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,7 +16,7 @@ jobs: executor: machine_executor_amd64 steps: - checkout - - run: docker compose -f docker-compose-test.yaml run test + - run: docker compose -f docker-compose-test.yaml up test - codecov/upload workflows: diff --git a/test/jellyfish/notifier_test.exs b/test/jellyfish/notifier_test.exs index cc966c0..3bce7cd 100644 --- a/test/jellyfish/notifier_test.exs +++ b/test/jellyfish/notifier_test.exs @@ -1,7 +1,7 @@ defmodule Jellyfish.NotifierTest do use ExUnit.Case doctest Jellyfish.WebhookNotifier - alias Jellyfish.{Client, WSNotifier, Peer, Room} + alias Jellyfish.{Client, Peer, Room, WSNotifier} alias Jellyfish.PeerMessage alias Jellyfish.PeerMessage.AuthRequest From a96b0ba5a554b42a65138b4f49a7d2a2d39eff41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szuma?= Date: Tue, 24 Oct 2023 10:04:51 +0200 Subject: [PATCH 12/17] Use Application.put_env in test.local --- lib/jellyfish/webhook_notifier.ex | 5 ++--- mix.exs | 4 ++-- test/support/utils.ex | 18 ++++++++++-------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/lib/jellyfish/webhook_notifier.ex b/lib/jellyfish/webhook_notifier.ex index 4d6f502..70bda5f 100644 --- a/lib/jellyfish/webhook_notifier.ex +++ b/lib/jellyfish/webhook_notifier.ex @@ -3,6 +3,8 @@ defmodule Jellyfish.WebhookNotifier do Module defining a function allowing decoding received webhook notification from jellyfish to notification structs. """ + alias Jellyfish.{Notification, ServerMessage} + @doc """ Decode received webhook to notification structs. @@ -20,9 +22,6 @@ defmodule Jellyfish.WebhookNotifier do } ``` """ - - alias Jellyfish.{Notification, ServerMessage} - @spec receive(term()) :: struct() def receive(json) do %ServerMessage{content: {_type, notification}} = diff --git a/mix.exs b/mix.exs index 737473b..5d39d52 100644 --- a/mix.exs +++ b/mix.exs @@ -125,8 +125,8 @@ defmodule Membrane.Template.Mixfile do List.last(opts) == "--without_docker" -> IO.puts("Running tests locally (it requires setting up jellyfish without docker) ...") - System.put_env("SERVER_ADDRESS", "127.0.0.1:5002") - System.put_env("WEBHOOK_ADDRESS", "127.0.0.1") + Application.put_env(:jellyfish_server_sdk, :local_server_address, "127.0.0.1:5002") + Application.put_env(:jellyfish_server_sdk, :local_webhook_address, "127.0.0.1") Mix.Task.run("test", ["--exclude", "doctest"]) diff --git a/test/support/utils.ex b/test/support/utils.ex index fdd6d91..2110be6 100644 --- a/test/support/utils.ex +++ b/test/support/utils.ex @@ -2,18 +2,20 @@ defmodule Jellyfish.Test.Utils do @moduledoc false def read_server_address() do - System.get_env( - "SERVER_ADDRESS", - Application.fetch_env!(:jellyfish_server_sdk, :server_address) - ) + Application.fetch_env(:jellyfish_server_sdk, :local_server_address) + |> case do + {:ok, value} -> value + :error -> Application.fetch_env!(:jellyfish_server_sdk, :server_address) + end end def read_webhook_address(webhook_port) do webhook_address = - System.get_env( - "WEBHOOK_ADDRESS", - Application.fetch_env!(:jellyfish_server_sdk, :webhook_address) - ) + Application.fetch_env(:jellyfish_server_sdk, :local_webhook_address) + |> case do + {:ok, value} -> value + :error -> Application.fetch_env!(:jellyfish_server_sdk, :webhook_address) + end "http://#{webhook_address}:#{webhook_port}/" end From 99138058b15a5385075e5c52b39e0d69620c78b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szuma?= Date: Tue, 24 Oct 2023 11:13:52 +0200 Subject: [PATCH 13/17] Remove Jellyfish.Test.Utils module --- config/test_local.exs | 6 +++++ mix.exs | 15 +++++------ test/jellyfish/notifier_test.exs | 45 +++++++++++++------------------- test/jellyfish/room_test.exs | 12 +++++---- test/support/utils.ex | 22 ---------------- 5 files changed, 37 insertions(+), 63 deletions(-) create mode 100644 config/test_local.exs delete mode 100644 test/support/utils.ex diff --git a/config/test_local.exs b/config/test_local.exs new file mode 100644 index 0000000..58f9b3d --- /dev/null +++ b/config/test_local.exs @@ -0,0 +1,6 @@ +import Config + +config :jellyfish_server_sdk, + server_address: "127.0.0.1:5002", + server_api_token: "development", + webhook_address: "127.0.0.1" diff --git a/mix.exs b/mix.exs index 5d39d52..991d2f0 100644 --- a/mix.exs +++ b/mix.exs @@ -45,7 +45,7 @@ defmodule Membrane.Template.Mixfile do ] end - defp elixirc_paths(:test), do: ["lib", "test/support"] + defp elixirc_paths(env) when env in [:test, :test_local], do: ["lib", "test/support"] defp elixirc_paths(_env), do: ["lib"] defp deps do @@ -64,11 +64,11 @@ defmodule Membrane.Template.Mixfile do {:ex_doc, ">= 0.0.0", only: :dev, runtime: false}, {:dialyxir, ">= 0.0.0", only: :dev, runtime: false}, {:credo, ">= 0.0.0", only: :dev, runtime: false}, - {:excoveralls, ">= 0.0.0", only: :test, runtime: false}, + {:excoveralls, ">= 0.0.0", only: [:test, :test_local], runtime: false}, # Test deps - {:plug_cowboy, "~> 2.5", only: :test}, - {:phoenix_pubsub, "~> 2.1", only: :test} + {:plug_cowboy, "~> 2.5", only: [:test, :test_local]}, + {:phoenix_pubsub, "~> 2.1", only: [:test, :test_local]} ] end @@ -116,7 +116,7 @@ defmodule Membrane.Template.Mixfile do def aliases do [ test: &test_in_docker/1, - "test.local": ["test --without_docker"] + "test.local": ["cmd MIX_ENV=test_local mix test --without_docker"] ] end @@ -125,10 +125,7 @@ defmodule Membrane.Template.Mixfile do List.last(opts) == "--without_docker" -> IO.puts("Running tests locally (it requires setting up jellyfish without docker) ...") - Application.put_env(:jellyfish_server_sdk, :local_server_address, "127.0.0.1:5002") - Application.put_env(:jellyfish_server_sdk, :local_webhook_address, "127.0.0.1") - - Mix.Task.run("test", ["--exclude", "doctest"]) + Mix.Task.run("test") System.find_executable("docker") -> IO.puts("Running tests using Docker...") diff --git a/test/jellyfish/notifier_test.exs b/test/jellyfish/notifier_test.exs index 3bce7cd..926a6ab 100644 --- a/test/jellyfish/notifier_test.exs +++ b/test/jellyfish/notifier_test.exs @@ -23,6 +23,8 @@ defmodule Jellyfish.NotifierTest do @max_peers 10 @video_codec :vp8 @webhook_port 4000 + @webhook_host Application.compile_env!(:jellyfish_server_sdk, :webhook_address) + @webhook_address "http://#{@webhook_host}:#{@webhook_port}/" @pubsub Jellyfish.PubSub setup_all do @@ -46,46 +48,36 @@ defmodule Jellyfish.NotifierTest do on_exit(fn -> :ok = PubSub.unsubscribe(@pubsub, "webhook") end) - - webhook_address = Jellyfish.Test.Utils.read_webhook_address(@webhook_port) - - server_address = Jellyfish.Test.Utils.read_server_address() - - {:ok, %{webhook_address: webhook_address, server_address: server_address}} end describe "connecting to the server and subcribing for events" do - test "when credentials are valid", %{server_address: server_address} do - assert {:ok, pid} = WSNotifier.start_link(server_address: server_address) + test "when credentials are valid", %{} do + assert {:ok, pid} = WSNotifier.start_link() assert is_pid(pid) end - test "when token is invalid", %{server_address: server_address} do + test "when token is invalid", %{} do assert {:error, :invalid_token} = - WSNotifier.start_link( - server_api_token: "invalid_token", - server_address: server_address - ) + WSNotifier.start_link(server_api_token: "invalid_token") end end describe "receiving notifications" do - setup %{server_address: server_address, webhook_address: webhook_address} do - {:ok, notifier} = WSNotifier.start_link(server_address: server_address) + setup do + {:ok, notifier} = WSNotifier.start_link() :ok = WSNotifier.subscribe_server_notifications(notifier) - %{client: Client.new(server_address: server_address), webhook_address: webhook_address} + %{client: Client.new()} end test "when room gets created and then deleted", %{ - client: client, - webhook_address: webhook_address + client: client } do {:ok, %Jellyfish.Room{id: room_id}, _jellyfish_address} = Room.create(client, max_peers: @max_peers, video_codec: @video_codec, - webhook_url: webhook_address + webhook_url: @webhook_address ) assert_receive {:jellyfish, %RoomCreated{room_id: ^room_id}} @@ -98,14 +90,13 @@ defmodule Jellyfish.NotifierTest do end test "when peer connects and then disconnects", %{ - client: client, - webhook_address: webhook_address + client: client } do {:ok, %Jellyfish.Room{id: room_id}, jellyfish_address} = Room.create(client, max_peers: @max_peers, video_codec: @video_codec, - webhook_url: webhook_address + webhook_url: @webhook_address ) {:ok, %Jellyfish.Peer{id: peer_id}, peer_token} = Room.add_peer(client, room_id, @peer_opts) @@ -127,19 +118,19 @@ defmodule Jellyfish.NotifierTest do end describe "receiving metrics" do - setup %{server_address: server_address, webhook_address: webhook_address} do - {:ok, notifier} = WSNotifier.start_link(server_address: server_address) + setup do + {:ok, notifier} = WSNotifier.start_link() :ok = WSNotifier.subscribe_server_notifications(notifier) :ok = WSNotifier.subscribe_metrics(notifier) - %{client: Client.new(server_address: server_address), webhook_address: webhook_address} + %{client: Client.new()} end - test "with one peer", %{client: client, webhook_address: webhook_address} do + test "with one peer", %{client: client} do {:ok, %Jellyfish.Room{id: room_id}, jellyfish_address} = Room.create(client, max_peers: @max_peers, - webhook_url: webhook_address + webhook_url: @webhook_address ) {:ok, %Jellyfish.Peer{id: peer_id}, peer_token} = Room.add_peer(client, room_id, @peer_opts) diff --git a/test/jellyfish/room_test.exs b/test/jellyfish/room_test.exs index f7f8406..a7eae78 100644 --- a/test/jellyfish/room_test.exs +++ b/test/jellyfish/room_test.exs @@ -43,13 +43,11 @@ defmodule Jellyfish.RoomTest do end setup do - server_address = Jellyfish.Test.Utils.read_server_address() - - %{client: Client.new(server_address: server_address), server_address: server_address} + %{client: Client.new()} end describe "auth" do - test "correct token", %{client: client, server_address: server_address} do + test "correct token", %{client: client} do assert {:ok, room, jellyfish_address} = Room.create(client, max_peers: @max_peers, video_codec: @video_codec) @@ -60,6 +58,8 @@ defmodule Jellyfish.RoomTest do peers: [] } = room + server_address = Application.fetch_env!(:jellyfish_server_sdk, :server_address) + assert ^server_address = jellyfish_address end @@ -70,7 +70,7 @@ defmodule Jellyfish.RoomTest do end describe "Room.create/2" do - test "when request is valid", %{client: client, server_address: server_address} do + test "when request is valid", %{client: client} do assert {:ok, room, jellyfish_address} = Room.create(client, max_peers: @max_peers) assert %Jellyfish.Room{ @@ -80,6 +80,8 @@ defmodule Jellyfish.RoomTest do peers: [] } = room + server_address = Application.fetch_env!(:jellyfish_server_sdk, :server_address) + assert ^server_address = jellyfish_address end diff --git a/test/support/utils.ex b/test/support/utils.ex deleted file mode 100644 index 2110be6..0000000 --- a/test/support/utils.ex +++ /dev/null @@ -1,22 +0,0 @@ -defmodule Jellyfish.Test.Utils do - @moduledoc false - - def read_server_address() do - Application.fetch_env(:jellyfish_server_sdk, :local_server_address) - |> case do - {:ok, value} -> value - :error -> Application.fetch_env!(:jellyfish_server_sdk, :server_address) - end - end - - def read_webhook_address(webhook_port) do - webhook_address = - Application.fetch_env(:jellyfish_server_sdk, :local_webhook_address) - |> case do - {:ok, value} -> value - :error -> Application.fetch_env!(:jellyfish_server_sdk, :webhook_address) - end - - "http://#{webhook_address}:#{webhook_port}/" - end -end From 63d6d1c1672105d8a78115991f546a8d87582277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szuma?= <56085570+Rados13@users.noreply.github.com> Date: Wed, 25 Oct 2023 09:24:31 +0200 Subject: [PATCH 14/17] Update lib/jellyfish/webhook_notifier.ex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michał Śledź --- lib/jellyfish/webhook_notifier.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jellyfish/webhook_notifier.ex b/lib/jellyfish/webhook_notifier.ex index 70bda5f..6e0ee78 100644 --- a/lib/jellyfish/webhook_notifier.ex +++ b/lib/jellyfish/webhook_notifier.ex @@ -6,7 +6,7 @@ defmodule Jellyfish.WebhookNotifier do alias Jellyfish.{Notification, ServerMessage} @doc """ - Decode received webhook to notification structs. + Decodes received webhook to notification structs. ``` iex> %{ From 97065c6056f390f0de4a6808d8b74a8a551d370b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szuma?= <56085570+Rados13@users.noreply.github.com> Date: Wed, 25 Oct 2023 09:24:38 +0200 Subject: [PATCH 15/17] Update mix.exs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michał Śledź --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index 991d2f0..a0212a0 100644 --- a/mix.exs +++ b/mix.exs @@ -128,7 +128,7 @@ defmodule Membrane.Template.Mixfile do Mix.Task.run("test") System.find_executable("docker") -> - IO.puts("Running tests using Docker...") + IO.puts("Running tests using Docker. To run tests without Docker call \"mix test.local\"") docker_compose_prefix = ["docker", "compose", "-f", "docker-compose-test.yaml"] From 0635cf633a4ed011facd703e5ce80bb58b3fa029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szuma?= Date: Wed, 25 Oct 2023 11:01:34 +0200 Subject: [PATCH 16/17] Return to static IP in docker-compose-test --- .circleci/config.yml | 2 +- config/test.exs | 2 +- docker-compose-test.yaml | 12 ++++++++++++ mix.exs | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2664168..ab1bf53 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,7 +16,7 @@ jobs: executor: machine_executor_amd64 steps: - checkout - - run: docker compose -f docker-compose-test.yaml up test + - run: docker compose -f docker-compose-test.yaml run test - codecov/upload workflows: diff --git a/config/test.exs b/config/test.exs index 16882d2..797732c 100644 --- a/config/test.exs +++ b/config/test.exs @@ -3,4 +3,4 @@ import Config config :jellyfish_server_sdk, server_address: "jellyfish:5002", server_api_token: "development", - webhook_address: "test" + webhook_address: "172.28.0.2" diff --git a/docker-compose-test.yaml b/docker-compose-test.yaml index 1c87ad7..817cab5 100644 --- a/docker-compose-test.yaml +++ b/docker-compose-test.yaml @@ -8,6 +8,9 @@ services: - .:/app ports: - "4000:4000" + networks: + test_network: + ipv4_address: 172.28.0.2 depends_on: jellyfish: condition: service_healthy @@ -18,3 +21,12 @@ services: service: jellyfish environment: - JF_HOST=jellyfish:5002 + networks: + test_network: + ipv4_address: 172.28.0.3 + +networks: + test_network: + ipam: + config: + - subnet: 172.28.0.0/24 diff --git a/mix.exs b/mix.exs index a0212a0..8314a3a 100644 --- a/mix.exs +++ b/mix.exs @@ -133,7 +133,7 @@ defmodule Membrane.Template.Mixfile do docker_compose_prefix = ["docker", "compose", "-f", "docker-compose-test.yaml"] stream_command(docker_compose_prefix ++ ["pull"]) - stream_command(docker_compose_prefix ++ ["up", "--remove-orphans", "test"]) + stream_command(docker_compose_prefix ++ ["run", "--remove-orphans", "test"]) stream_command(docker_compose_prefix ++ ["down"]) true -> From 6192c0304152d7cabb362832d2d69de8db98b2f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szuma?= Date: Wed, 25 Oct 2023 15:38:55 +0200 Subject: [PATCH 17/17] Remove static IP from docker-compose --- .circleci/config.yml | 2 +- config/test.exs | 2 +- docker-compose-test.yaml | 12 ------------ mix.exs | 6 +++++- 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ab1bf53..2008c48 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,7 +16,7 @@ jobs: executor: machine_executor_amd64 steps: - checkout - - run: docker compose -f docker-compose-test.yaml run test + - run: docker compose -f docker-compose-test.yaml up test --exit-code-from test - codecov/upload workflows: diff --git a/config/test.exs b/config/test.exs index 797732c..16882d2 100644 --- a/config/test.exs +++ b/config/test.exs @@ -3,4 +3,4 @@ import Config config :jellyfish_server_sdk, server_address: "jellyfish:5002", server_api_token: "development", - webhook_address: "172.28.0.2" + webhook_address: "test" diff --git a/docker-compose-test.yaml b/docker-compose-test.yaml index 817cab5..1c87ad7 100644 --- a/docker-compose-test.yaml +++ b/docker-compose-test.yaml @@ -8,9 +8,6 @@ services: - .:/app ports: - "4000:4000" - networks: - test_network: - ipv4_address: 172.28.0.2 depends_on: jellyfish: condition: service_healthy @@ -21,12 +18,3 @@ services: service: jellyfish environment: - JF_HOST=jellyfish:5002 - networks: - test_network: - ipv4_address: 172.28.0.3 - -networks: - test_network: - ipam: - config: - - subnet: 172.28.0.0/24 diff --git a/mix.exs b/mix.exs index 8314a3a..c65ec14 100644 --- a/mix.exs +++ b/mix.exs @@ -133,7 +133,11 @@ defmodule Membrane.Template.Mixfile do docker_compose_prefix = ["docker", "compose", "-f", "docker-compose-test.yaml"] stream_command(docker_compose_prefix ++ ["pull"]) - stream_command(docker_compose_prefix ++ ["run", "--remove-orphans", "test"]) + + stream_command( + docker_compose_prefix ++ ["up", "--remove-orphans", "test", "--exit-code-from", "test"] + ) + stream_command(docker_compose_prefix ++ ["down"]) true ->