Network Programming in Elixir and Erlang: Chat integration tests are failing at random

Title: Network Programming in Elixir and Erlang (p. 56)

Hi,
Thanks for the amazing book, first and foremost.

I found that Chat app integration tests, as they are provided on page 56, are randomly failing when I’m running them multiple times.

For example, all mix test runs were executed against the same codebase, with no modifications. Some runs succeeded, some failed and failed in different tests.

mix test
Compiling 1 file (.ex)
Generated chat app

16:48:32.613 [info] Started chat server on port 4101
Running ExUnit with seed: 621706, max_cases: 20

.........
Finished in 0.2 seconds (0.2s async, 0.00s sync)
1 doctest, 8 tests, 0 failures
mix test

16:48:34.200 [info] Started chat server on port 4101
Running ExUnit with seed: 208381, max_cases: 20

.........
Finished in 0.2 seconds (0.2s async, 0.00s sync)
1 doctest, 8 tests, 0 failures
mix test

16:48:35.467 [info] Started chat server on port 4101
Running ExUnit with seed: 474408, max_cases: 20

.........
Finished in 0.2 seconds (0.2s async, 0.00s sync)
1 doctest, 8 tests, 0 failures
mix test

16:48:36.701 [info] Started chat server on port 4101
Running ExUnit with seed: 709368, max_cases: 20

......
16:48:36.961 [error] GenServer #PID<0.180.0> terminating
** (FunctionClauseError) no function clause matching in Chat.Connection.handle_info/2
    (chat 0.1.0) lib/chat/connection.ex:19: Chat.Connection.handle_info({:tcp_closed, #Port<0.11>}, %Chat.Connection{socket: #Port<0.11>, username: "amy", buffer: ""})
    (stdlib 6.2.2.2) gen_server.erl:2345: :gen_server.try_handle_info/3
    (stdlib 6.2.2.2) gen_server.erl:2433: :gen_server.handle_msg/6
    (stdlib 6.2.2.2) proc_lib.erl:329: :proc_lib.init_p_do_apply/3
Last message: {:tcp_closed, #Port<0.11>}
State: %Chat.Connection{socket: #Port<0.11>, username: "amy", buffer: ""}

16:48:36.961 [error] GenServer #PID<0.181.0> terminating
** (FunctionClauseError) no function clause matching in Chat.Connection.handle_info/2
    (chat 0.1.0) lib/chat/connection.ex:19: Chat.Connection.handle_info({:tcp_closed, #Port<0.12>}, %Chat.Connection{socket: #Port<0.12>, username: "bern", buffer: ""})
    (stdlib 6.2.2.2) gen_server.erl:2345: :gen_server.try_handle_info/3
    (stdlib 6.2.2.2) gen_server.erl:2433: :gen_server.handle_msg/6
    (stdlib 6.2.2.2) proc_lib.erl:329: :proc_lib.init_p_do_apply/3
Last message: {:tcp_closed, #Port<0.12>}
State: %Chat.Connection{socket: #Port<0.12>, username: "bern", buffer: ""}

16:48:36.961 [error] GenServer #PID<0.179.0> terminating
** (FunctionClauseError) no function clause matching in Chat.Connection.handle_info/2
    (chat 0.1.0) lib/chat/connection.ex:19: Chat.Connection.handle_info({:tcp_closed, #Port<0.8>}, %Chat.Connection{socket: #Port<0.8>, username: "jd", buffer: ""})
    (stdlib 6.2.2.2) gen_server.erl:2345: :gen_server.try_handle_info/3
    (stdlib 6.2.2.2) gen_server.erl:2433: :gen_server.handle_msg/6
    (stdlib 6.2.2.2) proc_lib.erl:329: :proc_lib.init_p_do_apply/3
Last message: {:tcp_closed, #Port<0.8>}
State: %Chat.Connection{socket: #Port<0.8>, username: "jd", buffer: ""}


  1) test server closes connection ficlient sends register message twice (Chat.IntegrationTest)
     test/chat/integration_test.exs:9
     Assertion with =~ failed
     code:  assert log =~ "Invalid Register message"
     left:  ""
     right: "Invalid Register message"
     stacktrace:
       test/chat/integration_test.exs:21: (test)

..
Finished in 0.2 seconds (0.2s async, 0.00s sync)
1 doctest, 8 tests, 1 failure
mix test

16:48:55.294 [info] Started chat server on port 4101
Running ExUnit with seed: 303579, max_cases: 20

......

  1) test server closes connection ficlient sends register message twice (Chat.IntegrationTest)
     test/chat/integration_test.exs:9
     Assertion with =~ failed
     code:  assert log =~ "Invalid Register message"
     left:  ""
     right: "Invalid Register message"
     stacktrace:
       test/chat/integration_test.exs:21: (test)

..
Finished in 0.2 seconds (0.2s async, 0.00s sync)
1 doctest, 8 tests, 1 failure
mix test

16:48:57.808 [info] Started chat server on port 4101
Running ExUnit with seed: 817244, max_cases: 20

......

  1) test server closes connection ficlient sends register message twice (Chat.IntegrationTest)
     test/chat/integration_test.exs:9
     Assertion with =~ failed
     code:  assert log =~ "Invalid Register message"
     left:  ""
     right: "Invalid Register message"
     stacktrace:
       test/chat/integration_test.exs:21: (test)

..
Finished in 0.2 seconds (0.2s async, 0.00s sync)
1 doctest, 8 tests, 1 failure
mix test

16:48:59.453 [info] Started chat server on port 4101
Running ExUnit with seed: 461426, max_cases: 20

......

  1) test server closes connection ficlient sends register message twice (Chat.IntegrationTest)
     test/chat/integration_test.exs:9
     Assertion with =~ failed
     code:  assert log =~ "Invalid Register message"
     left:  ""
     right: "Invalid Register message"
     stacktrace:
       test/chat/integration_test.exs:21: (test)

..
Finished in 0.2 seconds (0.2s async, 0.00s sync)
1 doctest, 8 tests, 1 failure
mix test

16:49:00.937 [info] Started chat server on port 4101
Running ExUnit with seed: 944586, max_cases: 20

......
16:49:01.205 [error] GenServer #PID<0.180.0> terminating
** (FunctionClauseError) no function clause matching in Chat.Connection.handle_info/2
    (chat 0.1.0) lib/chat/connection.ex:19: Chat.Connection.handle_info({:tcp_closed, #Port<0.10>}, %Chat.Connection{socket: #Port<0.10>, username: "amy", buffer: ""})
    (stdlib 6.2.2.2) gen_server.erl:2345: :gen_server.try_handle_info/3
    (stdlib 6.2.2.2) gen_server.erl:2433: :gen_server.handle_msg/6
    (stdlib 6.2.2.2) proc_lib.erl:329: :proc_lib.init_p_do_apply/3
Last message: {:tcp_closed, #Port<0.10>}
State: %Chat.Connection{socket: #Port<0.10>, username: "amy", buffer: ""}

16:49:01.205 [error] GenServer #PID<0.181.0> terminating
** (FunctionClauseError) no function clause matching in Chat.Connection.handle_info/2
    (chat 0.1.0) lib/chat/connection.ex:19: Chat.Connection.handle_info({:tcp_closed, #Port<0.12>}, %Chat.Connection{socket: #Port<0.12>, username: "bern", buffer: ""})
    (stdlib 6.2.2.2) gen_server.erl:2345: :gen_server.try_handle_info/3
    (stdlib 6.2.2.2) gen_server.erl:2433: :gen_server.handle_msg/6
    (stdlib 6.2.2.2) proc_lib.erl:329: :proc_lib.init_p_do_apply/3
Last message: {:tcp_closed, #Port<0.12>}
State: %Chat.Connection{socket: #Port<0.12>, username: "bern", buffer: ""}

16:49:01.205 [error] GenServer #PID<0.179.0> terminating
** (FunctionClauseError) no function clause matching in Chat.Connection.handle_info/2
    (chat 0.1.0) lib/chat/connection.ex:19: Chat.Connection.handle_info({:tcp_closed, #Port<0.8>}, %Chat.Connection{socket: #Port<0.8>, username: "jd", buffer: ""})
    (stdlib 6.2.2.2) gen_server.erl:2345: :gen_server.try_handle_info/3
    (stdlib 6.2.2.2) gen_server.erl:2433: :gen_server.handle_msg/6
    (stdlib 6.2.2.2) proc_lib.erl:329: :proc_lib.init_p_do_apply/3
Last message: {:tcp_closed, #Port<0.8>}
State: %Chat.Connection{socket: #Port<0.8>, username: "jd", buffer: ""}


  1) test server closes connection ficlient sends register message twice (Chat.IntegrationTest)
     test/chat/integration_test.exs:9
     Assertion with =~ failed
     code:  assert log =~ "Invalid Register message"
     left:  ""
     right: "Invalid Register message"
     stacktrace:
       test/chat/integration_test.exs:21: (test)

..
Finished in 0.2 seconds (0.2s async, 0.00s sync)
1 doctest, 8 tests, 1 failure
mix test

16:49:02.370 [info] Started chat server on port 4101
Running ExUnit with seed: 378187, max_cases: 20

......

  1) test server closes connection ficlient sends register message twice (Chat.IntegrationTest)
     test/chat/integration_test.exs:9
     Assertion with =~ failed
     code:  assert log =~ "Invalid Register message"
     left:  ""
     right: "Invalid Register message"
     stacktrace:
       test/chat/integration_test.exs:21: (test)

..
Finished in 0.2 seconds (0.2s async, 0.00s sync)
1 doctest, 8 tests, 1 failure
mix test

16:49:04.997 [info] Started chat server on port 4101
Running ExUnit with seed: 5948, max_cases: 20

......

  1) test server closes connection ficlient sends register message twice (Chat.IntegrationTest)
     test/chat/integration_test.exs:9
     Assertion with =~ failed
     code:  assert log =~ "Invalid Register message"
     left:  ""
     right: "Invalid Register message"
     stacktrace:
       test/chat/integration_test.exs:21: (test)

..
Finished in 0.2 seconds (0.2s async, 0.00s sync)
1 doctest, 8 tests, 1 failure
mix test

16:49:08.565 [info] Started chat server on port 4101
Running ExUnit with seed: 573340, max_cases: 20

......

  1) test server closes connection ficlient sends register message twice (Chat.IntegrationTest)
     test/chat/integration_test.exs:9
     Assertion with =~ failed
     code:  assert log =~ "Invalid Register message"
     left:  ""
     right: "Invalid Register message"
     stacktrace:
       test/chat/integration_test.exs:21: (test)

..
Finished in 0.2 seconds (0.2s async, 0.00s sync)
1 doctest, 8 tests, 1 failure
mix test

16:49:16.089 [info] Started chat server on port 4101
Running ExUnit with seed: 98240, max_cases: 20

.........
Finished in 0.2 seconds (0.2s async, 0.00s sync)
1 doctest, 8 tests, 0 failures

The repo to reproduce the issue is available at GitHub - lessless/chat: Errata for