From a22044c2c4bd94364fe8869df86810631bf0b66e Mon Sep 17 00:00:00 2001 From: Xiangrong Hao <falood@gmail.com> Date: Sun, 23 Jul 2017 11:10:05 -0700 Subject: [PATCH] add more test when port stop or crash (#28) * add more test when port stop or crash * fix watcher port filter condition --- lib/file_system/backends/fs_inotify.ex | 7 +++++++ lib/file_system/backends/fs_mac.ex | 7 +++++++ lib/file_system/backends/fs_windows.ex | 7 +++++++ lib/file_system/worker.ex | 3 ++- test/file_system_test.exs | 23 ++++++++++++++++++++++- 5 files changed, 45 insertions(+), 2 deletions(-) diff --git a/lib/file_system/backends/fs_inotify.ex b/lib/file_system/backends/fs_inotify.ex index 141682f..b673b50 100644 --- a/lib/file_system/backends/fs_inotify.ex +++ b/lib/file_system/backends/fs_inotify.ex @@ -41,6 +41,8 @@ defmodule FileSystem.Backends.FSInotify do {:spawn_executable, to_charlist(find_executable())}, [:stream, :exit_status, {:line, 16384}, {:args, port_args}, {:cd, System.tmp_dir!()}] ) + Process.link(port) + Process.flag(:trap_exit, true) {:ok, %{port: port, worker_pid: args[:worker_pid]}} end @@ -55,6 +57,11 @@ defmodule FileSystem.Backends.FSInotify do {:stop, :normal, state} end + def handle_info({:EXIT, port, _reason}, %{port: port}=state) do + send(state.worker_pid, {:backend_file_event, self(), :stop}) + {:noreply, state} + end + def handle_info(_, state) do {:noreply, state} end diff --git a/lib/file_system/backends/fs_mac.ex b/lib/file_system/backends/fs_mac.ex index f816f05..65d39b7 100644 --- a/lib/file_system/backends/fs_mac.ex +++ b/lib/file_system/backends/fs_mac.ex @@ -45,6 +45,8 @@ defmodule FileSystem.Backends.FSMac do {:spawn_executable, to_charlist(find_executable())}, [:stream, :exit_status, {:line, 16384}, {:args, port_args}, {:cd, System.tmp_dir!()}] ) + Process.link(port) + Process.flag(:trap_exit, true) {:ok, %{port: port, worker_pid: args[:worker_pid]}} end @@ -59,6 +61,11 @@ defmodule FileSystem.Backends.FSMac do {:stop, :normal, state} end + def handle_info({:EXIT, port, _reason}, %{port: port}=state) do + send(state.worker_pid, {:backend_file_event, self(), :stop}) + {:noreply, state} + end + def handle_info(_, state) do {:noreply, state} end diff --git a/lib/file_system/backends/fs_windows.ex b/lib/file_system/backends/fs_windows.ex index 1242ebd..89b1ecb 100644 --- a/lib/file_system/backends/fs_windows.ex +++ b/lib/file_system/backends/fs_windows.ex @@ -40,6 +40,8 @@ defmodule FileSystem.Backends.FSWindows do {:spawn_executable, to_charlist(find_executable())}, [:stream, :exit_status, {:line, 16384}, {:args, port_args}, {:cd, System.tmp_dir!()}] ) + Process.link(port) + Process.flag(:trap_exit, true) {:ok, %{port: port, worker_pid: args[:worker_pid]}} end @@ -54,6 +56,11 @@ defmodule FileSystem.Backends.FSWindows do {:stop, :normal, state} end + def handle_info({:EXIT, port, _reason}, %{port: port}=state) do + send(state.worker_pid, {:backend_file_event, self(), :stop}) + {:noreply, state} + end + def handle_info(_, state) do {:noreply, state} end diff --git a/lib/file_system/worker.ex b/lib/file_system/worker.ex index f110770..b771a6c 100644 --- a/lib/file_system/worker.ex +++ b/lib/file_system/worker.ex @@ -25,7 +25,8 @@ defmodule FileSystem.Worker do end def handle_info({:DOWN, _pid, _, ref, _reason}, state) do - {:noreply, pop_in(state.subscribers[ref])} + subscribers = Map.drop(state.subscribers, [ref]) |> IO.inspect + {:noreply, %{state | subscribers: subscribers}} end def handle_info(_, state) do diff --git a/test/file_system_test.exs b/test/file_system_test.exs index d63d690..750b5d3 100644 --- a/test/file_system_test.exs +++ b/test/file_system_test.exs @@ -1,13 +1,34 @@ defmodule FileSystemTest do use ExUnit.Case, async: true - test "subscribe api" do + test "file event api" do tmp_dir = System.cmd("mktemp", ["-d"]) |> elem(0) |> String.trim {:ok, pid} = FileSystem.start_link(dirs: [tmp_dir]) FileSystem.subscribe(pid) + :timer.sleep(200) File.touch("#{tmp_dir}/a") assert_receive {:file_event, ^pid, {_path, _events}}, 5000 + + new_subscriber = spawn(fn -> + FileSystem.subscribe(pid) + :timer.sleep(10000) + end) + assert Process.alive?(new_subscriber) + Process.exit(new_subscriber, :kill) + refute Process.alive?(new_subscriber) + + :timer.sleep(200) + File.touch("#{tmp_dir}/b") + assert_receive {:file_event, ^pid, {_path, _events}}, 5000 + + Port.list + |> Enum.reject(fn port -> + :undefined == port |> Port.info |> Access.get(:os_pid) + end) + |> Enum.each(&Port.close/1) + assert_receive {:file_event, ^pid, :stop}, 5000 + File.rm_rf!(tmp_dir) end end -- GitLab