From 5da7d802c2ae891c33cc6a0420fc3f17bada870c Mon Sep 17 00:00:00 2001 From: Kayla Firestack Date: Tue, 5 Dec 2023 14:02:09 -0500 Subject: [PATCH] feat(elixir/1.15): update to elixir 1.15 and OTP 26 (#2294) * feat(elixir/1.15): update to elixir 1.15 and OTP 26 * fix(elixir/1.15): reformat with updated formatter rules * fix(elixir/1.15): update `ecto` to be compatible with elixir 1.15 ecto used the word `dynamic` somewhere, and that has since become a keyword in elixir * fix(elixir/1.15): update `guardian` to be compatible with elixir-1.15 * fix(elixlir/1.15): replace `System.stacktrace` with `__STACKTRACE__` * fix(elixir/1.15): remove usages of `get_env` in non-function scopes * cleanup(elixir/1.15): change Logger `warn` atom and function to `warning` * fix(elixir/1.15): update "snapshot" tests which relied on map key order * fix(elixir/1.15): update `dialyxir` to be compatible with elixir-1.15 * fix(elixir/1.15): suppress dialyzer warning about handle_errors/2 function * update(mix): update elixir to 1.15 * fix:test(ex/realtime/alerts_fetcher): mock api for start GenServer test so that `do_poll` doesn't error * test:fix(ex/alerts_fetcher): mock out api endpoint for test failure * fix:test(ex/realtime/vehicle): assert on decoded JSON instead of string Should fix issues with map atom keys being reordered * fix:test(ex/stream_test): pass `conn` to each successive `Conn.chunk` call * doc(ex/api/stream_test): document github issue for failing test * fix:test(ex): remove async from modules containing unstable tests These issues are with tests which access and assert on behavior from the global logger --------- Co-authored-by: Josh Larson --- .tool-versions | 4 +- Dockerfile | 4 +- config/test.exs | 2 +- lib/concentrate/merge.ex | 2 +- .../producer/http/state_machine.ex | 16 +++--- lib/geonames.ex | 2 +- lib/notifications/bridge.ex | 10 ++-- lib/notifications/notification.ex | 2 +- lib/realtime/alerts_fetcher.ex | 4 +- lib/realtime/data_status_alerter.ex | 2 +- lib/schedule/fetcher.ex | 2 +- lib/schedule/garage.ex | 2 +- lib/schedule/hastus/activity.ex | 2 +- lib/skate/migrate.ex | 2 +- lib/skate/warm_up.ex | 4 +- lib/skate_web/endpoint.ex | 2 +- lib/skate_web/router.ex | 7 ++- mix.exs | 4 +- mix.lock | 8 +-- test/api/stream_test.exs | 15 +++-- .../producer/http/state_machine_test.exs | 10 ++-- test/geonames_test.exs | 2 +- test/notifications/bridge_test.exs | 8 +-- test/realtime/alerts_fetcher_test.exs | 57 +++++++++++-------- test/realtime/vehicle_test.exs | 49 +++++++++++++--- test/schedule/fetcher_test.exs | 4 +- test/schedule/garage_test.exs | 4 +- test/schedule/gtfs/feed_info_test.exs | 2 +- test/skate/repo_test.exs | 5 +- .../controllers/page_controller_test.exs | 2 +- 30 files changed, 144 insertions(+), 95 deletions(-) diff --git a/.tool-versions b/.tool-versions index 9408fcead..643a9c8a4 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,4 +1,4 @@ -elixir 1.13.3-otp-24 -erlang 24.3.2 +elixir 1.15.7-otp-26 +erlang 26.1.2 nodejs 20.7.0 adr-tools 3.0.0 diff --git a/Dockerfile b/Dockerfile index f73155dfc..2107042a4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM hexpm/elixir:1.13.3-erlang-24.3.2-alpine-3.15.0 AS elixir-builder +FROM hexpm/elixir:1.15.7-erlang-26.1.2-alpine-3.17.5 AS elixir-builder # elixir expects utf8. ENV LANG=C.UTF-8 \ @@ -48,7 +48,7 @@ ENV SENTRY_RELEASE=${SENTRY_RELEASE} RUN mix do compile --force, phx.digest, release -FROM alpine:3.15.4 +FROM alpine:3.17.5 RUN apk upgrade --no-cache --update diff --git a/config/test.exs b/config/test.exs index fcff84f2c..7fa9f88ce 100644 --- a/config/test.exs +++ b/config/test.exs @@ -27,4 +27,4 @@ config :ueberauth, Ueberauth, cognito: {Skate.Ueberauth.Strategy.Fake, [groups: ["skate-dispatcher", "skate-nav-beta"]]} ] -config :logger, level: :warn +config :logger, level: :warning diff --git a/lib/concentrate/merge.ex b/lib/concentrate/merge.ex index 126881409..757cf366c 100644 --- a/lib/concentrate/merge.ex +++ b/lib/concentrate/merge.ex @@ -109,7 +109,7 @@ defmodule Concentrate.Merge do def handle_info(msg, state) do _ = - Logger.warn(fn -> + Logger.warning(fn -> "unknown message to #{__MODULE__} #{inspect(self())}: #{inspect(msg)}" end) diff --git a/lib/concentrate/producer/http/state_machine.ex b/lib/concentrate/producer/http/state_machine.ex index 05a0828a6..033135189 100644 --- a/lib/concentrate/producer/http/state_machine.ex +++ b/lib/concentrate/producer/http/state_machine.ex @@ -304,11 +304,11 @@ defmodule Concentrate.Producer.HTTP.StateMachine do {[parsed], machine} rescue error -> - log_parse_error(error, machine, System.stacktrace()) + log_parse_error(error, machine, __STACKTRACE__) {[], machine} catch error -> - log_parse_error(error, machine, System.stacktrace()) + log_parse_error(error, machine, __STACKTRACE__) {[], machine} end @@ -326,7 +326,7 @@ defmodule Concentrate.Producer.HTTP.StateMachine do if time_since_last_success >= machine.content_warning_timeout do _ = - Logger.warn(fn -> + Logger.warning(fn -> delay = div(time_since_last_success, 1000) "#{__MODULE__}: feed has not been updated url=#{inspect(machine.url)} delay=#{delay}" end) @@ -379,11 +379,11 @@ defmodule Concentrate.Producer.HTTP.StateMachine do [{message, delay} | fallback_messages] end - defp error_log_level(:closed), do: :warn - defp error_log_level({:closed, _}), do: :warn - defp error_log_level({:ssl_closed, _}), do: :warn - defp error_log_level(:timeout), do: :warn - defp error_log_level({:unexpected_code, _}), do: :warn + defp error_log_level(:closed), do: :warning + defp error_log_level({:closed, _}), do: :warning + defp error_log_level({:ssl_closed, _}), do: :warning + defp error_log_level(:timeout), do: :warning + defp error_log_level({:unexpected_code, _}), do: :warning defp error_log_level(_), do: :error defp now do diff --git a/lib/geonames.ex b/lib/geonames.ex index 75be91304..5a92f9e3f 100644 --- a/lib/geonames.ex +++ b/lib/geonames.ex @@ -43,7 +43,7 @@ defmodule Geonames do Jason.decode!(body, strings: :copy) response -> - Logger.warn( + Logger.warning( "#{__MODULE__} unexpected_response url=#{sanitized_url} response=#{inspect(response)} time=#{time_in_ms} retry=#{retry?}" ) diff --git a/lib/notifications/bridge.ex b/lib/notifications/bridge.ex index 155e75eb2..19f79851c 100644 --- a/lib/notifications/bridge.ex +++ b/lib/notifications/bridge.ex @@ -33,7 +33,7 @@ defmodule Notifications.Bridge do def init(_opts) do case Application.get_env(:skate, :bridge_url) do nil -> - Logger.warn("not starting Bridge: no url configured") + Logger.warning("not starting Bridge: no url configured") :ignore _ -> @@ -65,7 +65,7 @@ defmodule Notifications.Bridge do end def handle_info(msg, state) do - Logger.warn("#{__MODULE__} unknown message: #{inspect(msg)}") + Logger.warning("#{__MODULE__} unknown message: #{inspect(msg)}") {:noreply, state} end @@ -90,18 +90,18 @@ defmodule Notifications.Bridge do do_parse_response(response) _ -> - Logger.warn("bridge_api_failure: could not parse json response") + Logger.warning("bridge_api_failure: could not parse json response") nil end end def parse_response({:ok, %HTTPoison.Response{status_code: status}}) do - Logger.warn("bridge_api_failure: status code #{inspect(status)}") + Logger.warning("bridge_api_failure: status code #{inspect(status)}") nil end def parse_response({:error, %HTTPoison.Error{reason: reason}}) do - Logger.warn("bridge_api_failure: #{inspect(reason)}") + Logger.warning("bridge_api_failure: #{inspect(reason)}") nil end diff --git a/lib/notifications/notification.ex b/lib/notifications/notification.ex index c09a1a578..c0810e07a 100644 --- a/lib/notifications/notification.ex +++ b/lib/notifications/notification.ex @@ -175,7 +175,7 @@ defmodule Notifications.Notification do notification end - @spec unexpired_notifications_for_user(DbUser.id(), (() -> Util.Time.timestamp())) :: [t()] + @spec unexpired_notifications_for_user(DbUser.id(), (-> Util.Time.timestamp())) :: [t()] def unexpired_notifications_for_user(user_id, now_fn \\ &Util.Time.now/0) do cutoff_time = now_fn.() - @notification_expiration_threshold diff --git a/lib/realtime/alerts_fetcher.ex b/lib/realtime/alerts_fetcher.ex index 185b27aa3..6f87a17f0 100644 --- a/lib/realtime/alerts_fetcher.ex +++ b/lib/realtime/alerts_fetcher.ex @@ -72,13 +72,13 @@ defmodule Realtime.AlertsFetcher do Logger.info("#{__MODULE__}: updated_alerts url=#{inspect(url)}") {:error, error} -> - Logger.warn( + Logger.warning( "#{__MODULE__}: unable_to_parse_alerts url=#{inspect(url)} error=#{inspect(error)}" ) end response -> - Logger.warn( + Logger.warning( "#{__MODULE__}: unexpected_response url=#{inspect(url)} response=#{inspect(response)}" ) end diff --git a/lib/realtime/data_status_alerter.ex b/lib/realtime/data_status_alerter.ex index c3540f56d..50bc74131 100644 --- a/lib/realtime/data_status_alerter.ex +++ b/lib/realtime/data_status_alerter.ex @@ -31,7 +31,7 @@ defmodule Realtime.DataStatusAlerter do @impl GenServer def handle_info({:new_data_status, data_status}, state) do if data_status == :outage do - Logger.warn("Data outage detected data_outage_detected") + Logger.warning("Data outage detected data_outage_detected") end {:noreply, state} diff --git a/lib/schedule/fetcher.ex b/lib/schedule/fetcher.ex index d64d32c11..897938d33 100644 --- a/lib/schedule/fetcher.ex +++ b/lib/schedule/fetcher.ex @@ -268,7 +268,7 @@ defmodule Schedule.Fetcher do {:ok, nil, last_modified} response -> - Logger.warn(fn -> + Logger.warning(fn -> "#{__MODULE__}: Unexpected response from #{url} : #{inspect(response)}" end) diff --git a/lib/schedule/garage.ex b/lib/schedule/garage.ex index 2c666462e..40ab21461 100644 --- a/lib/schedule/garage.ex +++ b/lib/schedule/garage.ex @@ -32,7 +32,7 @@ defmodule Schedule.Garage do garage = @block_code_mapping[block_code] if is_nil(garage) do - Logger.warn("#{__MODULE__}: Unrecognized block code: #{inspect(block_code)}") + Logger.warning("#{__MODULE__}: Unrecognized block code: #{inspect(block_code)}") end garage diff --git a/lib/schedule/hastus/activity.ex b/lib/schedule/hastus/activity.ex index 09d93dadb..e83df8af8 100644 --- a/lib/schedule/hastus/activity.ex +++ b/lib/schedule/hastus/activity.ex @@ -146,7 +146,7 @@ defmodule Schedule.Hastus.Activity do end) if trips_in_piece == [] do - Logger.warn(fn -> + Logger.warning(fn -> "Operator activity with no trips: #{activity.schedule_id} #{activity.run_id} start_time:#{activity.start_time}" end) end diff --git a/lib/skate/migrate.ex b/lib/skate/migrate.ex index 490e61a6d..d6029c500 100644 --- a/lib/skate/migrate.ex +++ b/lib/skate/migrate.ex @@ -35,7 +35,7 @@ defmodule Skate.Migrate do Logger.info("#{__MODULE__} async migrations finished") rescue e -> - Logger.warn("#{__MODULE__} async migrations failed. error=#{inspect(e)}") + Logger.warning("#{__MODULE__} async migrations failed. error=#{inspect(e)}") :ok end diff --git a/lib/skate/warm_up.ex b/lib/skate/warm_up.ex index b63e42c98..1e9ad9880 100644 --- a/lib/skate/warm_up.ex +++ b/lib/skate/warm_up.ex @@ -47,7 +47,7 @@ defmodule Skate.WarmUp do {:ok, result} {:error, error} -> - Logger.warn( + Logger.warning( "#{__MODULE__} warmup query failed. attempt=#{attempt} query_number=#{index} reason=#{inspect(error)}" ) @@ -93,7 +93,7 @@ defmodule Skate.WarmUp do if max_attempts == attempt do result else - Logger.warn(format_result_message(result)) + Logger.warning(format_result_message(result)) :timer.sleep(:timer.seconds(seconds_between_attempts)) check_connections_warmed_up(%{config | attempt: attempt + 1}) end diff --git a/lib/skate_web/endpoint.ex b/lib/skate_web/endpoint.ex index 4a1c0b462..a01178138 100644 --- a/lib/skate_web/endpoint.ex +++ b/lib/skate_web/endpoint.ex @@ -2,7 +2,7 @@ defmodule SkateWeb.Endpoint do use Phoenix.Endpoint, otp_app: :skate socket "/socket", SkateWeb.UserSocket, - websocket: [check_origin: Application.get_env(:skate, :websocket_check_origin, false)], + websocket: [check_origin: Application.compile_env(:skate, :websocket_check_origin, false)], longpoll: false # Serve at "/" the static files from "priv/static" directory. diff --git a/lib/skate_web/router.ex b/lib/skate_web/router.ex index 6b64d9415..c0844ae6b 100644 --- a/lib/skate_web/router.ex +++ b/lib/skate_web/router.ex @@ -2,13 +2,18 @@ defmodule SkateWeb.Router do use SkateWeb, :router use Plug.ErrorHandler use Sentry.Plug + # Dialyzer expects any module with `use Plug.ErrorHandler` to + # implement a `handle_errors` function. `Sentry.Plug` implements + # that function, but Dialyzer isn't aware of that. Because of that, + # we suppress the warning here. + @dialyzer {:nowarn_function, handle_errors: 2} # We prefer to redirect at the load balancer level, but for security through # redundancy, we're keeping this plug just in case. # A note: this does not affect anything before the `Skate.Router` plug in `endpoint.ex` # e.g., static assets will not get redirected to HTTPS. pipeline :redirect_prod_http do - if Application.get_env(:skate, :redirect_http?) do + if Application.compile_env(:skate, :redirect_http?) do plug(Plug.SSL, rewrite_on: [:x_forwarded_proto]) end end diff --git a/mix.exs b/mix.exs index 0f8ce1d55..980b9857d 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule Skate.MixProject do [ app: :skate, version: "0.1.0", - elixir: "~> 1.13", + elixir: "~> 1.15", elixirc_paths: elixirc_paths(Mix.env()), compilers: [:phoenix] ++ Mix.compilers(), start_permanent: Mix.env() == :prod, @@ -52,7 +52,7 @@ defmodule Skate.MixProject do {:configparser_ex, "~> 4.0", only: :dev}, {:credo, "~> 1.6", only: [:dev, :test], runtime: false}, {:csv, "~> 2.4.1"}, - {:dialyxir, "~> 1.0", only: [:dev, :test], runtime: false}, + {:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false}, {:diskusage_logger, "~> 0.2.0"}, {:ecto_sql, "~> 3.4"}, {:ehmon, github: "mbta/ehmon", only: :prod}, diff --git a/mix.lock b/mix.lock index 5670101ff..0ca7e4a11 100644 --- a/mix.lock +++ b/mix.lock @@ -13,10 +13,10 @@ "csv": {:hex, :csv, "2.4.1", "50e32749953b6bf9818dbfed81cf1190e38cdf24f95891303108087486c5925e", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm", "54508938ac67e27966b10ef49606e3ad5995d665d7fc2688efb3eab1307c9079"}, "db_connection": {:hex, :db_connection, "2.4.3", "3b9aac9f27347ec65b271847e6baeb4443d8474289bd18c1d6f4de655b70c94d", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c127c15b0fa6cfb32eed07465e05da6c815b032508d4ed7c116122871df73c12"}, "decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"}, - "dialyxir": {:hex, :dialyxir, "1.3.0", "fd1672f0922b7648ff9ce7b1b26fcf0ef56dda964a459892ad15f6b4410b5284", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "00b2a4bcd6aa8db9dcb0b38c1225b7277dca9bc370b6438715667071a304696f"}, + "dialyxir": {:hex, :dialyxir, "1.4.2", "764a6e8e7a354f0ba95d58418178d486065ead1f69ad89782817c296d0d746a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "516603d8067b2fd585319e4b13d3674ad4f314a5902ba8130cd97dc902ce6bbd"}, "diskusage_logger": {:hex, :diskusage_logger, "0.2.0", "04fc48b538fe4de43153542a71ea94f623d54707d85844123baacfceedf625c3", [:mix], [], "hexpm", "e3f2aed1b0fc4590931c089a6453a4c4eb4c945912aa97bcabcc0cff7851f34d"}, "earmark_parser": {:hex, :earmark_parser, "1.4.33", "3c3fd9673bb5dcc9edc28dd90f50c87ce506d1f71b70e3de69aa8154bc695d44", [:mix], [], "hexpm", "2d526833729b59b9fdb85785078697c72ac5e5066350663e5be6a1182da61b8f"}, - "ecto": {:hex, :ecto, "3.9.4", "3ee68e25dbe0c36f980f1ba5dd41ee0d3eb0873bccae8aeaf1a2647242bffa35", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "de5f988c142a3aa4ec18b85a4ec34a2390b65b24f02385c1144252ff6ff8ee75"}, + "ecto": {:hex, :ecto, "3.9.6", "2f420c173efcb2e22fa4f8fc41e75e02b3c5bd4cffef12085cae5418c12e530d", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "df17bc06ba6f78a7b764e4a14ef877fe5f4499332c5a105ace11fe7013b72c84"}, "ecto_sql": {:hex, :ecto_sql, "3.9.2", "34227501abe92dba10d9c3495ab6770e75e79b836d114c41108a4bf2ce200ad5", [:mix], [{:db_connection, "~> 2.5 or ~> 2.4.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1eb5eeb4358fdbcd42eac11c1fbd87e3affd7904e639d77903c1358b2abd3f70"}, "ehmon": {:git, "https://github.com/mbta/ehmon.git", "1fb603262bd02d74a16183bd8f344dcace9d7561", []}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, @@ -30,14 +30,14 @@ "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, "gen_stage": {:hex, :gen_stage, "1.2.1", "19d8b5e9a5996d813b8245338a28246307fd8b9c99d1237de199d21efc4c76a1", [:mix], [], "hexpm", "83e8be657fa05b992ffa6ac1e3af6d57aa50aace8f691fcf696ff02f8335b001"}, "gettext": {:hex, :gettext, "0.22.3", "c8273e78db4a0bb6fba7e9f0fd881112f349a3117f7f7c598fa18c66c888e524", [:mix], [{:expo, "~> 0.4.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "935f23447713954a6866f1bb28c3a878c4c011e802bcd68a726f5e558e4b64bd"}, - "guardian": {:hex, :guardian, "2.2.4", "3dafdc19665411c96b2796d184064d691bc08813a132da5119e39302a252b755", [:mix], [{:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "6f83d4309c16ec2469da8606bb2a9815512cc2fac1595ad34b79940a224eb110"}, + "guardian": {:hex, :guardian, "2.3.2", "78003504b987f2b189d76ccf9496ceaa6a454bb2763627702233f31eb7212881", [:mix], [{:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "b189ff38cd46a22a8a824866a6867ca8722942347f13c33f7d23126af8821b52"}, "guardian_phoenix": {:hex, :guardian_phoenix, "2.0.1", "89a817265af09a6ddf7cb1e77f17ffca90cea2db10ff888375ef34502b2731b1", [:mix], [{:guardian, "~> 2.0", [hex: :guardian, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.3", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "21f439246715192b231f228680465d1ed5fbdf01555a4a3b17165532f5f9a08c"}, "hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"}, "hpax": {:hex, :hpax, "0.1.1", "2396c313683ada39e98c20a75a82911592b47e5c24391363343bde74f82396ca", [:mix], [], "hexpm", "0ae7d5a0b04a8a60caf7a39fcf3ec476f35cc2cc16c05abea730d3ce6ac6c826"}, "httpoison": {:hex, :httpoison, "2.1.0", "655fd9a7b0b95ee3e9a3b535cf7ac8e08ef5229bab187fa86ac4208b122d934b", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "fc455cb4306b43827def4f57299b2d5ac8ac331cb23f517e734a4b78210a160c"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, - "jose": {:hex, :jose, "1.11.2", "f4c018ccf4fdce22c71e44d471f15f723cb3efab5d909ab2ba202b5bf35557b3", [:mix, :rebar3], [], "hexpm", "98143fbc48d55f3a18daba82d34fe48959d44538e9697c08f34200fa5f0947d2"}, + "jose": {:hex, :jose, "1.11.6", "613fda82552128aa6fb804682e3a616f4bc15565a048dabd05b1ebd5827ed965", [:mix, :rebar3], [], "hexpm", "6275cb75504f9c1e60eeacb771adfeee4905a9e182103aa59b53fed651ff9738"}, "lcov_ex": {:hex, :lcov_ex, "0.3.3", "1745a88e46606c4f86408299f54878b7d0cd22ea3e9c54b0018b6ed631a9ce87", [:mix], [], "hexpm", "ea373ec4d2df213357c5a464be16ab08d1e58e61ea2de784a483780c22a1e74a"}, "logster": {:hex, :logster, "1.0.2", "9a1f8987ac46a4227b7ee15c8097d9a5d3b9f55befbd2c44f06caefa4addacf0", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ec6c5fa0e2a180526e86083c9b33507181103b63b967ac47c52ec4f54c9b828b"}, "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"}, diff --git a/test/api/stream_test.exs b/test/api/stream_test.exs index b1f1d02ae..c9bf09259 100644 --- a/test/api/stream_test.exs +++ b/test/api/stream_test.exs @@ -58,6 +58,9 @@ 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) @@ -68,12 +71,12 @@ defmodule Api.StreamTest do "id" => "vehicle" } - Conn.chunk(conn, "event: ignores unexpected events\n\n") - Conn.chunk(conn, "ignored garbled data\n\n") - Conn.chunk(conn, "event: reset\ndata: #{Jason.encode!([data])}\n\n") - Conn.chunk(conn, "event: add\ndata: #{Jason.encode!(data)}\n\n") - Conn.chunk(conn, "event: update\ndata: #{Jason.encode!(data)}\n\n") - Conn.chunk(conn, "event: remove\ndata: #{Jason.encode!(data)}\n\n") + {: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") + {: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) diff --git a/test/concentrate/producer/http/state_machine_test.exs b/test/concentrate/producer/http/state_machine_test.exs index acedb80ec..e14fe2f6e 100644 --- a/test/concentrate/producer/http/state_machine_test.exs +++ b/test/concentrate/producer/http/state_machine_test.exs @@ -134,7 +134,7 @@ defmodule Concentrate.Producer.HTTP.StateMachineTest do ] log = - capture_log([level: :warn], fn -> + capture_log([level: :warning], fn -> _ = run_machine("url", opts, messages) end) @@ -152,7 +152,7 @@ defmodule Concentrate.Producer.HTTP.StateMachineTest do ] log = - capture_log([level: :warn], fn -> + capture_log([level: :warning], fn -> _ = run_machine("url", opts, messages) end) @@ -171,7 +171,7 @@ defmodule Concentrate.Producer.HTTP.StateMachineTest do ] log = - capture_log([level: :warn], fn -> + capture_log([level: :warning], fn -> _ = run_machine("url", opts, messages) end) @@ -188,7 +188,7 @@ defmodule Concentrate.Producer.HTTP.StateMachineTest do ] log = - capture_log([level: :warn], fn -> + capture_log([level: :warning], fn -> _ = run_machine("url", opts, messages) end) @@ -216,7 +216,7 @@ defmodule Concentrate.Producer.HTTP.StateMachineTest do fetch_after = 1000 log = - capture_log([level: :warn], fn -> + capture_log([level: :warning], fn -> assert {_machine, [], [{{:fetch, "url"}, ^fetch_after} | _]} = run_machine("url", [fetch_after: fetch_after], messages) end) diff --git a/test/geonames_test.exs b/test/geonames_test.exs index bdf61f6c1..1fc9ad5a1 100644 --- a/test/geonames_test.exs +++ b/test/geonames_test.exs @@ -1,5 +1,5 @@ defmodule GeonamesTest do - use ExUnit.Case, async: true + use ExUnit.Case import Test.Support.Helpers import ExUnit.CaptureLog import Plug.Conn diff --git a/test/notifications/bridge_test.exs b/test/notifications/bridge_test.exs index ca6ac5cb3..2c2f72e33 100644 --- a/test/notifications/bridge_test.exs +++ b/test/notifications/bridge_test.exs @@ -185,7 +185,7 @@ defmodule Notifications.BridgeTest do test "Logs warning on bad message" do log = - capture_log([level: :warn], fn -> + capture_log([level: :warning], fn -> {:noreply, _state} = handle_info(:bad_message, nil) end) @@ -196,7 +196,7 @@ defmodule Notifications.BridgeTest do describe "parse_response/1" do test "Logs warning with bad status code" do log = - capture_log([level: :warn], fn -> + capture_log([level: :warning], fn -> refute parse_response({:ok, %HTTPoison.Response{status_code: 500}}) end) @@ -205,7 +205,7 @@ defmodule Notifications.BridgeTest do test "Logs warning when request fails" do log = - capture_log([level: :warn], fn -> + capture_log([level: :warning], fn -> refute parse_response({:error, %HTTPoison.Error{reason: "Unknown error"}}) end) @@ -214,7 +214,7 @@ defmodule Notifications.BridgeTest do test "Logs warning when parsing fails" do log = - capture_log([level: :warn], fn -> + capture_log([level: :warning], fn -> refute parse_response( {:ok, %HTTPoison.Response{status_code: 201, body: "invalid json"}} ) diff --git a/test/realtime/alerts_fetcher_test.exs b/test/realtime/alerts_fetcher_test.exs index ffda23820..4b0816d38 100644 --- a/test/realtime/alerts_fetcher_test.exs +++ b/test/realtime/alerts_fetcher_test.exs @@ -60,8 +60,25 @@ defmodule Realtime.AlertsFetcherTest do ] } + setup tags do + if tags[:mock_api] do + bypass = Bypass.open() + api_url = "http://localhost:#{bypass.port}/" + reassign_env(:skate, :api_url, api_url) + + %{bypass: bypass} + else + :ok + end + end + describe "start_link/1" do - test "starts GenServer" do + @tag :mock_api + test "starts GenServer", %{bypass: bypass} do + Bypass.stub(bypass, "GET", "/alerts", fn _ -> + Bypass.pass(bypass) + end) + assert {:ok, _pid} = AlertsFetcher.start_link(update_fn: fn _ -> :ok end) end end @@ -88,10 +105,8 @@ defmodule Realtime.AlertsFetcherTest do end describe "handle_continue/2" do - test "fetches alerts" do - bypass = Bypass.open() - api_url = "http://localhost:#{bypass.port}/" - reassign_env(:skate, :api_url, api_url) + @tag :mock_api + test "fetches alerts", %{bypass: bypass} do test_pid = self() update_fn = fn alerts -> @@ -112,11 +127,9 @@ defmodule Realtime.AlertsFetcherTest do end describe "handle_info/2" do - test "fetches alerts and logs on success" do + @tag :mock_api + test "fetches alerts and logs on success", %{bypass: bypass} do set_log_level(:info) - bypass = Bypass.open() - api_url = "http://localhost:#{bypass.port}/" - reassign_env(:skate, :api_url, api_url) test_pid = self() update_fn = fn alerts -> @@ -140,11 +153,8 @@ defmodule Realtime.AlertsFetcherTest do assert log =~ "updated_alerts" end - test "handles unsuccessful HTTP request" do - bypass = Bypass.open() - api_url = "http://localhost:#{bypass.port}/" - reassign_env(:skate, :api_url, api_url) - + @tag :mock_api + test "handles unsuccessful HTTP request", %{bypass: bypass} do update_fn = fn _ -> :ok end {:ok, state, _} = AlertsFetcher.init(update_fn: update_fn) @@ -154,18 +164,15 @@ defmodule Realtime.AlertsFetcherTest do end) log = - capture_log([level: :warn], fn -> + capture_log([level: :warning], fn -> assert {:noreply, _state} = AlertsFetcher.handle_info(:query_api, state) end) assert log =~ "unexpected_response" end - test "handles malformed response" do - bypass = Bypass.open() - api_url = "http://localhost:#{bypass.port}/" - reassign_env(:skate, :api_url, api_url) - + @tag :mock_api + test "handles malformed response", %{bypass: bypass} do update_fn = fn _ -> :ok end {:ok, state, _} = AlertsFetcher.init(update_fn: update_fn) @@ -175,18 +182,18 @@ defmodule Realtime.AlertsFetcherTest do end) log = - capture_log([level: :warn], fn -> + capture_log([level: :warning], fn -> assert {:noreply, _state} = AlertsFetcher.handle_info(:query_api, state) end) assert log =~ "unable_to_parse_alerts" end - test "handles multiple alerts per route, multiple routes per alert, and non-detour alerts" do + @tag :mock_api + test "handles multiple alerts per route, multiple routes per alert, and non-detour alerts", %{ + bypass: bypass + } do set_log_level(:info) - bypass = Bypass.open() - api_url = "http://localhost:#{bypass.port}/" - reassign_env(:skate, :api_url, api_url) test_pid = self() update_fn = fn alerts -> diff --git a/test/realtime/vehicle_test.exs b/test/realtime/vehicle_test.exs index 1c1c7956f..b3f29fea4 100644 --- a/test/realtime/vehicle_test.exs +++ b/test/realtime/vehicle_test.exs @@ -675,14 +675,47 @@ defmodule Realtime.VehicleTest do end_of_trip_type: :another_trip } - encoded_string = Jason.encode!(vehicle) - - assert encoded_string =~ "\"id\":\"y1261\"" - - assert encoded_string =~ "\"route_id\":\"28\"" - - assert encoded_string =~ - "\"data_discrepancies\":[{\"attribute\":\"trip_id\",\"sources\":[{\"id\":\"swiftly\",\"value\":\"swiftly-trip-id\"},{\"id\":\"busloc\",\"value\":\"busloc-trip-id\"}]},{\"attribute\":\"route_id\",\"sources\":[{\"id\":\"swiftly\",\"value\":null},{\"id\":\"busloc\",\"value\":\"busloc-route-id\"}]}]" + decoded_vehicle = + vehicle + |> Jason.encode!() + |> Jason.decode!(keys: :atoms!) + + assert decoded_vehicle.id == "y1261" + assert decoded_vehicle.route_id == "28" + + assert decoded_vehicle.data_discrepancies == + Jason.decode!(~s( + [ + { + "attribute": "trip_id", + "sources": [ + { + "id": "swiftly", + "value": "swiftly-trip-id" + }, + { + "id": "busloc", + "value": "busloc-trip-id" + } + ] + }, + { + "attribute": "route_id", + "sources": [ + { + "id": "swiftly", + "value": null + }, + { + "id": "busloc", + "value": "busloc-route-id" + } + ] + } + ] + ), + keys: :atoms! + ) end end end diff --git a/test/schedule/fetcher_test.exs b/test/schedule/fetcher_test.exs index 0c489f708..67951205d 100644 --- a/test/schedule/fetcher_test.exs +++ b/test/schedule/fetcher_test.exs @@ -99,8 +99,8 @@ defmodule Schedule.FetcherTest do set_log_level(:info) # Mismatch in number of columns per line to trigger CSV parse error - {:ok, {'file.zip', zip_binary}} = - :zip.zip('file.zip', [{'calendar.txt', "column_1,column_2\n1,2,3"}], [:memory]) + {:ok, {~c"file.zip", zip_binary}} = + :zip.zip(~c"file.zip", [{~c"calendar.txt", "column_1,column_2\n1,2,3"}], [:memory]) Bypass.expect(bypass, fn conn -> conn diff --git a/test/schedule/garage_test.exs b/test/schedule/garage_test.exs index 0361d95a5..0b4acf81c 100644 --- a/test/schedule/garage_test.exs +++ b/test/schedule/garage_test.exs @@ -30,7 +30,7 @@ defmodule Schedule.GarageTest do test "handles unknown garage code" do log = - capture_log([level: :warn], fn -> + capture_log([level: :warning], fn -> [%Schedule.Gtfs.Route{garages: garages}] = Schedule.Garage.add_garages_to_routes([build(:gtfs_route, %{id: "route1"})], %{ "1234" => build(:trip, %{id: "1234", block_id: "X12-34", route_id: "route1"}) @@ -44,7 +44,7 @@ defmodule Schedule.GarageTest do test "silently ignores private carrier garage code" do log = - capture_log([level: :warn], fn -> + capture_log([level: :warning], fn -> [%Schedule.Gtfs.Route{garages: garages}] = Schedule.Garage.add_garages_to_routes([build(:gtfs_route, %{id: "route1"})], %{ "1234" => build(:trip, %{id: "1234", block_id: "J12-34", route_id: "route1"}) diff --git a/test/schedule/gtfs/feed_info_test.exs b/test/schedule/gtfs/feed_info_test.exs index 1095d4894..9fb74ab40 100644 --- a/test/schedule/gtfs/feed_info_test.exs +++ b/test/schedule/gtfs/feed_info_test.exs @@ -1,5 +1,5 @@ defmodule Schedule.Gtfs.FeedInfoTest do - use ExUnit.Case, async: true + use ExUnit.Case import ExUnit.CaptureLog, only: [capture_log: 1] alias Schedule.Gtfs.FeedInfo diff --git a/test/skate/repo_test.exs b/test/skate/repo_test.exs index d0e08fa44..967e560d2 100644 --- a/test/skate/repo_test.exs +++ b/test/skate/repo_test.exs @@ -56,8 +56,9 @@ defmodule Skate.RepoTest do ssl_opts: [ cacertfile: "priv/aws-cert-bundle.pem", verify: :verify_peer, - server_name_indication: 'db_server_hostname', - verify_fun: {&:ssl_verify_hostname.verify_fun/3, [check_hostname: 'db_server_hostname']} + server_name_indication: ~c"db_server_hostname", + verify_fun: + {&:ssl_verify_hostname.verify_fun/3, [check_hostname: ~c"db_server_hostname"]} ] ] diff --git a/test/skate_web/controllers/page_controller_test.exs b/test/skate_web/controllers/page_controller_test.exs index f758c84ff..09d9caf16 100644 --- a/test/skate_web/controllers/page_controller_test.exs +++ b/test/skate_web/controllers/page_controller_test.exs @@ -173,7 +173,7 @@ defmodule SkateWeb.PageControllerTest do conn = get(conn, "/") assert html_response(conn, 200) =~ - "data-map-limits=\"{"east":3,"north":1,"south":2,"west":4}\"" + "data-map-limits=\"{"north":1,"south":2,"east":3,"west":4}\"" end @tag :authenticated