Repository: whatyouhide/redix
Pull request #252 (2023-06-17 07:44:43)

Fix tests on OTP 26
Closes https://github.com/whatyouhide/redix/issues/251.

coveralls: ## Pull Request Test Coverage Report for [Build d53d3ff34c66623b2832e5c53a6dc222f18330d7-PR-252](https://coveralls.io/builds/60797597)

* **3** of **5**   **(60.0%)**  changed or added relevant lines in **1** file are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage decreased (**-0.1%**) to **85.859%**

---

|  Changes Missing Coverage | Covered Lines | Changed/Added Lines | % |
| :-----|--------------|--------|---: |
| [lib/redix/exceptions.ex](https://coveralls.io/builds/60797597/source?filename=lib%2Fredix%2Fexceptions.ex#L59) | 3 | 5 | 60.0%
<!-- | **Total:** | **3** | **5** | **60.0%** | -->


|  Totals | [![Coverage Status](https://coveralls.io/builds/60797597/badge)](https://coveralls.io/builds/60797597) |
| :-- | --: |
| Change from base [Build 3ba88b96e08ceab95e0839fc48f58adf488709dd](https://coveralls.io/builds/59939100): |  -0.1% |
| Covered Lines: | 595 |
| Relevant Lines: | 693 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 087efc9..5279563 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -14,12 +14,19 @@ jobs:
       fail-fast: false
       matrix:
         include:
+          - otp: "26.0"
+            elixir: "1.15.0-rc.2"
+            version-type: strict
+
           - otp: "25.3"
             elixir: "1.14.3"
             coverage: true
             lint: true
+            version-type: loose
+
           - otp: "23.0"
             elixir: "1.11.2"
+            version-type: loose
 
     env:
       GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
@@ -27,7 +34,7 @@ jobs:
 
     steps:
       - name: Clone the repository
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
 
       - name: Start Docker
         run: docker-compose up --detach
@@ -37,6 +44,7 @@ jobs:
         with:
           otp-version: ${{matrix.otp}}
           elixir-version: ${{matrix.elixir}}
+          version-type: ${{matrix.version-type}}
 
       - name: Cache dependencies
         id: cache-deps
diff --git a/lib/redix/exceptions.ex b/lib/redix/exceptions.ex
index cd6a0ca..317c75f 100644
--- a/lib/redix/exceptions.ex
+++ b/lib/redix/exceptions.ex
@@ -45,6 +45,7 @@ defmodule Redix.ConnectionError do
 
   defexception [:reason]
 
+  @impl true
   def message(%__MODULE__{reason: reason}) do
     format_reason(reason)
   end
@@ -55,14 +56,17 @@ defmodule Redix.ConnectionError do
 
   # Manually returned by us when the connection is closed and someone tries to
   # send a command to Redis.
-  defp format_reason(:closed) do
-    "the connection to Redis is closed"
-  end
-
-  defp format_reason(reason) do
-    case :inet.format_error(reason) do
-      ~c"unknown POSIX error" -> inspect(reason)
-      message -> List.to_string(message)
+  defp format_reason(:closed), do: "the connection to Redis is closed"
+
+  if System.otp_release() >= "26" do
+    defp format_reason(reason), do: reason |> :inet.format_error() |> List.to_string()
+  else
+    defp format_reason(reason) do
+      case :inet.format_error(reason) do
+        ~c"unknown POSIX error" = message when is_atom(reason) -> "#{message}: #{reason}"
+        ~c"unknown POSIX error" -> inspect(reason)
+        message -> List.to_string(message)
+      end
     end
   end
 end
diff --git a/mix.exs b/mix.exs
index 3b69cae..2044348 100644
--- a/mix.exs
+++ b/mix.exs
@@ -64,7 +64,10 @@ defmodule Redix.Mixfile do
       {:ex_doc, "~> 0.28", only: :dev},
       {:excoveralls, "~> 0.14", only: :test},
       {:propcheck, "~> 1.1", only: :test},
-      {:stream_data, "~> 0.4", only: [:dev, :test]}
+      {:stream_data, "~> 0.4", only: [:dev, :test]},
+
+      # https://github.com/elixir-lang/elixir/issues/12653
+      {:ssl_verify_fun, ">= 0.0.0", manager: :rebar3, only: :test, override: true}
     ]
   end
 end


Test patch:
diff --git a/test/redix/connection_error_test.exs b/test/redix/connection_error_test.exs
index 44a6014..c594301 100644
--- a/test/redix/connection_error_test.exs
+++ b/test/redix/connection_error_test.exs
@@ -8,7 +8,7 @@ defmodule Redix.ConnectionErrorTest do
   end
 
   test "Exception.message/1 with an unknown reason" do
-    assert Exception.message(%ConnectionError{reason: :unknown}) == ":unknown"
+    assert Exception.message(%ConnectionError{reason: :unknown}) == "unknown POSIX error: unknown"
   end
 
   test "Exception.message/1 with a TCP/SSL closed message" do
diff --git a/test/redix_test.exs b/test/redix_test.exs
index 45e67a1..55a078a 100644
--- a/test/redix_test.exs
+++ b/test/redix_test.exs
@@ -135,18 +135,20 @@ defmodule RedixTest do
     end
 
     test "when unable to connect to Redis with sync_connect: true" do
-      capture_log(fn ->
-        Process.flag(:trap_exit, true)
+      Process.flag(:trap_exit, true)
 
-        assert {:error, %Redix.ConnectionError{reason: reason}} =
-                 Redix.start_link(host: "nonexistent", sync_connect: true)
+      assert {:error, %Redix.ConnectionError{reason: reason}} =
+               Redix.start_link(host: "nonexistent", sync_connect: true)
 
-        assert_receive {:EXIT, _pid, %Redix.ConnectionError{}}, 1000
+      # Apparently somewhere the error reason is :nxdomain but some other times it's
+      # :timeout.
+      assert reason in [:nxdomain, :timeout]
 
-        # Apparently somewhere the error reason is :nxdomain but some other times it's
-        # :timeout.
-        assert reason in [:nxdomain, :timeout]
-      end)
+      # TODO: Remove this when we require OTP 26+. In OTP 26, exits in gen_server:init/1
+      # get caught by proc_lib: https://github.com/erlang/otp/pull/6843
+      if System.otp_release() < "26" do
+        assert_receive {:EXIT, _pid, %Redix.ConnectionError{}}, 1000
+      end
     end
 
     test "when unable to connect to Redis with sync_connect: false" do
@@ -171,19 +173,23 @@ defmodule RedixTest do
       assert Redix.command(pid, ["PING"]) == {:ok, "PONG"}
     end
 
+    @tag :capture_log
     test "using a rediss:// url, unknown certificate" do
-      capture_log(fn ->
-        Process.flag(:trap_exit, true)
+      Process.flag(:trap_exit, true)
 
-        assert {:error, error} =
-                 Redix.start_link("rediss://localhost:6384/3",
-                   socket_opts: [reuse_sessions: false],
-                   sync_connect: true
-                 )
+      assert {:error, error} =
+               Redix.start_link("rediss://localhost:6384/3",
+                 socket_opts: [reuse_sessions: false],
+                 sync_connect: true
+               )
 
-        assert %Redix.ConnectionError{reason: {:tls_alert, _}} = error
+      assert %Redix.ConnectionError{reason: {:tls_alert, _}} = error
+
+      # TODO: Remove this when we require OTP 26+. In OTP 26, exits in gen_server:init/1
+      # get caught by proc_lib: https://github.com/erlang/otp/pull/6843
+      if System.otp_release() < "26" do
         assert_receive {:EXIT, _pid, ^error}, 1000
-      end)
+      end
     end
 
     test "with IPv6" do
@@ -476,7 +482,7 @@ defmodule RedixTest do
     end
 
     test "connection errors", %{conn: c} do
-      assert_raise Redix.ConnectionError, ":timeout", fn ->
+      assert_raise Redix.ConnectionError, "unknown POSIX error: timeout", fn ->
         Redix.command!(c, ["PING"], timeout: 0)
       end
     end
@@ -497,7 +503,7 @@ defmodule RedixTest do
     end
 
     test "connection errors", %{conn: c} do
-      assert_raise Redix.ConnectionError, ":timeout", fn ->
+      assert_raise Redix.ConnectionError, "unknown POSIX error: timeout", fn ->
         Redix.pipeline!(c, [["PING"]], timeout: 0)
       end
     end