mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-09-07 05:24:40 +08:00
79 lines
2.7 KiB
Elixir
79 lines
2.7 KiB
Elixir
defmodule Livebook.Runtime.Evaluator.ObjectTrackerTest do
|
|
use ExUnit.Case, async: true
|
|
|
|
alias Livebook.Runtime.Evaluator.ObjectTracker
|
|
|
|
setup do
|
|
{:ok, object_tracker} = start_supervised(ObjectTracker)
|
|
%{object_tracker: object_tracker}
|
|
end
|
|
|
|
test "monitor/5 returns an error when the given object doesn't exist",
|
|
%{object_tracker: object_tracker} do
|
|
assert {:error, :bad_object} =
|
|
ObjectTracker.monitor(object_tracker, :object1, self(), :object1_released, false)
|
|
end
|
|
|
|
test "sends scheduled monitor messages when all object references are released",
|
|
%{object_tracker: object_tracker} do
|
|
ObjectTracker.add_reference(object_tracker, :object1, {self(), :ref1})
|
|
ObjectTracker.add_reference(object_tracker, :object1, {self(), :ref2})
|
|
|
|
ObjectTracker.monitor(object_tracker, :object1, self(), :object1_released, false)
|
|
|
|
ObjectTracker.remove_reference_sync(object_tracker, {self(), :ref1})
|
|
ObjectTracker.remove_reference_sync(object_tracker, {self(), :ref2})
|
|
|
|
assert_received :object1_released
|
|
end
|
|
|
|
test "does not execute hooks when other references still point to the object",
|
|
%{object_tracker: object_tracker} do
|
|
ObjectTracker.add_reference(object_tracker, :object1, {self(), :ref1})
|
|
ObjectTracker.add_reference(object_tracker, :object1, {self(), :ref2})
|
|
|
|
ObjectTracker.monitor(object_tracker, :object1, self(), :object1_released, false)
|
|
|
|
ObjectTracker.remove_reference_sync(object_tracker, {self(), :ref1})
|
|
|
|
refute_received :object1_released
|
|
end
|
|
|
|
test "remove_reference_sync/2 awaits for monitor acknowledgments",
|
|
%{object_tracker: object_tracker} do
|
|
ObjectTracker.add_reference(object_tracker, :object1, {self(), :ref1})
|
|
|
|
ObjectTracker.monitor(object_tracker, :object1, self(), :object1_released1, true)
|
|
ObjectTracker.monitor(object_tracker, :object1, self(), :object1_released2, false)
|
|
|
|
myself = self()
|
|
|
|
spawn_link(fn ->
|
|
ObjectTracker.remove_reference_sync(object_tracker, {myself, :ref1})
|
|
send(myself, :removed)
|
|
end)
|
|
|
|
assert_receive {:object1_released1, ^object_tracker, reply_as}
|
|
assert_receive :object1_released2
|
|
|
|
refute_receive :removed
|
|
send(object_tracker, reply_as)
|
|
assert_receive :removed
|
|
end
|
|
|
|
test "removes a reference if its process terminates", %{object_tracker: object_tracker} do
|
|
reference_pid =
|
|
spawn(fn ->
|
|
receive do
|
|
:stop -> :ok
|
|
end
|
|
end)
|
|
|
|
ObjectTracker.add_reference(object_tracker, :object1, {reference_pid, :ref1})
|
|
|
|
ObjectTracker.monitor(object_tracker, :object1, self(), :object1_released, false)
|
|
|
|
send(reference_pid, :stop)
|
|
assert_receive :object1_released
|
|
end
|
|
end
|