diff --git a/lib/deployex/observer/port.ex b/lib/deployex/observer/port.ex index eb5cc37..5338ade 100644 --- a/lib/deployex/observer/port.ex +++ b/lib/deployex/observer/port.ex @@ -14,6 +14,7 @@ defmodule Deployex.Observer.Port do ...> [h | _] = :erlang.ports() ...> assert %{connected: _, id: _, name: _, os_pid: _} = Port.info(h) ...> assert :undefined = Port.info(nil) + ...> assert :undefined = Port.info("") """ @spec info(atom(), port()) :: :undefined | %{connected: any(), id: any(), name: any(), os_pid: any()} diff --git a/lib/deployex_web/live/observer/attention.ex b/lib/deployex_web/live/observer/attention.ex new file mode 100644 index 0000000..57bf7e6 --- /dev/null +++ b/lib/deployex_web/live/observer/attention.ex @@ -0,0 +1,35 @@ +defmodule DeployexWeb.Observer.Attention do + @moduledoc false + use Phoenix.Component + + attr :message, :string, required: true + + def content(assigns) do + ~H""" +
+ +
+ """ + end +end diff --git a/lib/deployex_web/live/observer/index.ex b/lib/deployex_web/live/observer/index.ex index fe49e95..2e221a9 100644 --- a/lib/deployex_web/live/observer/index.ex +++ b/lib/deployex_web/live/observer/index.ex @@ -138,9 +138,9 @@ defmodule DeployexWeb.ObserverLive do <%= if @current_selected_id.type == "pid" do %> - + <% else %> - + <% end %> diff --git a/lib/deployex_web/live/observer/port.ex b/lib/deployex_web/live/observer/port.ex index f5cf9b7..7ea2dd5 100644 --- a/lib/deployex_web/live/observer/port.ex +++ b/lib/deployex_web/live/observer/port.ex @@ -4,13 +4,16 @@ defmodule DeployexWeb.Observer.Port do use DeployexWeb, :html use Phoenix.Component + alias DeployexWeb.Observer.Attention + attr :info, :map, required: true + attr :id, :map, required: true def content(assigns) do info = assigns.info port_overview = - if info do + if is_map(info) do [ %{name: "Id", value: "#{info.id}"}, %{name: "Name", value: "#{info.name}"}, @@ -27,18 +30,24 @@ defmodule DeployexWeb.Observer.Port do ~H"""
-
-
- <.table_process id="port-overview-table" title="Overview" rows={@port_overview}> - <:col :let={item}> - <%= item.name %> - - <:col :let={item}> - <%= item.value %> - - -
-
+ <%= cond do %> + <% @info == nil -> %> + <% @info == :undefined -> %> + + <% true -> %> +
+
+ <.table_process id="port-overview-table" title="Overview" rows={@port_overview}> + <:col :let={item}> + <%= item.name %> + + <:col :let={item}> + <%= item.value %> + + +
+
+ <% end %>
""" end diff --git a/lib/deployex_web/live/observer/process.ex b/lib/deployex_web/live/observer/process.ex index 5915494..c77f97a 100644 --- a/lib/deployex_web/live/observer/process.ex +++ b/lib/deployex_web/live/observer/process.ex @@ -4,37 +4,39 @@ defmodule DeployexWeb.Observer.Process do use DeployexWeb, :html use Phoenix.Component + alias DeployexWeb.Observer.Attention + attr :info, :map, required: true + attr :id, :map, required: true def content(assigns) do info = assigns.info - process_overview = - if info do - [ - %{name: "Id", value: "#{inspect(info.pid)}"}, - %{name: "Registered name", value: "#{info.registered_name}"}, - %{name: "Status", value: "#{info.meta.status}"}, - %{name: "Class", value: "#{info.meta.class}"}, - %{name: "Message Queue Length", value: "#{info.message_queue_len}"}, - %{name: "Group Leader", value: "#{inspect(info.relations.group_leader)}"}, - %{name: "Trap exit", value: "#{info.trap_exit}"} - ] - else - nil - end + {process_overview, process_memory} = + if is_map(info) do + process_overview = + [ + %{name: "Id", value: "#{inspect(info.pid)}"}, + %{name: "Registered name", value: "#{info.registered_name}"}, + %{name: "Status", value: "#{info.meta.status}"}, + %{name: "Class", value: "#{info.meta.class}"}, + %{name: "Message Queue Length", value: "#{info.message_queue_len}"}, + %{name: "Group Leader", value: "#{inspect(info.relations.group_leader)}"}, + %{name: "Trap exit", value: "#{info.trap_exit}"} + ] - process_memory = - if info do - [ - %{name: "Total", value: "#{info.memory.total}"}, - %{name: "Heap Size", value: "#{info.memory.heap_size}"}, - %{name: "Stack Size", value: "#{info.memory.stack_size}"}, - %{name: "GC Min Heap Size", value: "#{info.memory.gc_min_heap_size}"}, - %{name: "GC FullSweep After", value: "#{info.memory.gc_full_sweep_after}"} - ] + process_memory = + [ + %{name: "Total", value: "#{info.memory.total}"}, + %{name: "Heap Size", value: "#{info.memory.heap_size}"}, + %{name: "Stack Size", value: "#{info.memory.stack_size}"}, + %{name: "GC Min Heap Size", value: "#{info.memory.gc_min_heap_size}"}, + %{name: "GC FullSweep After", value: "#{info.memory.gc_full_sweep_after}"} + ] + + {process_overview, process_memory} else - nil + {nil, nil} end assigns = @@ -44,37 +46,43 @@ defmodule DeployexWeb.Observer.Process do ~H"""
-
-
- <.table_process id="process-overview-table" title="Overview" rows={@process_overview}> - <:col :let={item}> - <%= item.name %> - - <:col :let={item}> - <%= item.value %> - - + <%= cond do %> + <% @info == nil -> %> + <% @info == :undefined -> %> + + <% true -> %> +
+
+ <.table_process id="process-overview-table" title="Overview" rows={@process_overview}> + <:col :let={item}> + <%= item.name %> + + <:col :let={item}> + <%= item.value %> + + - <.table_process id="process-memory-table" title="Memory" rows={@process_memory}> - <:col :let={item}> - <%= item.name %> - - <:col :let={item}> - <%= item.value %> - - + <.table_process id="process-memory-table" title="Memory" rows={@process_memory}> + <:col :let={item}> + <%= item.name %> + + <:col :let={item}> + <%= item.value %> + + - <.relations title="State" value={"#{inspect(@info.state)}"} /> -
+ <.relations title="State" value={"#{inspect(@info.state)}"} /> +
-
- <.relations title="Links" value={"#{inspect(@info.relations.links)}"} /> +
+ <.relations title="Links" value={"#{inspect(@info.relations.links)}"} /> - <.relations title="Ancestors" value={"#{inspect(@info.relations.ancestors)}" } /> - <.relations title="Monitors" value={"#{inspect(@info.relations.monitors)}"} /> - <.relations title="Monitored by" value={"#{inspect(@info.relations.monitored_by)}"} /> -
-
+ <.relations title="Ancestors" value={"#{inspect(@info.relations.ancestors)}" } /> + <.relations title="Monitors" value={"#{inspect(@info.relations.monitors)}"} /> + <.relations title="Monitored by" value={"#{inspect(@info.relations.monitored_by)}"} /> +
+
+ <% end %>
""" end diff --git a/test/deployex_web/live/observer/index_test.exs b/test/deployex_web/live/observer/index_test.exs index 0681120..936a9df 100644 --- a/test/deployex_web/live/observer/index_test.exs +++ b/test/deployex_web/live/observer/index_test.exs @@ -203,6 +203,43 @@ defmodule DeployexWeb.Observer.IndexTest do refute html =~ "Connected" end + test "Select Service+Apps and select a process that is dead or doesn't exist", %{conn: conn} do + node = Node.self() |> to_string + service = String.replace(node, "@", "-") + + Deployex.RpcMock + |> stub(:call, fn node, module, function, args, timeout -> + :rpc.call(node, module, function, args, timeout) + end) + |> stub(:pinfo, fn pid, information -> :rpc.pinfo(pid, information) end) + + {:ok, index_live, _html} = live(conn, ~p"/observer") + + index_live + |> element("#observer-multi-select-toggle-options") + |> render_click() + + index_live + |> element("#observer-multi-select-apps-kernel-add-item") + |> render_click() + + index_live + |> element("#observer-multi-select-services-#{service}-add-item") + |> render_click() + + series_name = "#{Node.self()}::kernel" + + id = "#PID<0.0.11111>" + + html = + index_live + |> element("#observer-tree") + |> render_hook("request-process", %{"id" => id, "series_name" => series_name}) + + # Check the Process information is not being shown + assert html =~ "Process #PID<0.0.11111> is either dead or protected" + end + test "Select Service+Apps and select a port to request information", %{conn: conn} do node = Node.self() |> to_string service = String.replace(node, "@", "-") @@ -250,6 +287,43 @@ defmodule DeployexWeb.Observer.IndexTest do assert html =~ "Connected" end + test "Select Service+Apps and select a port that is dead or doesn't exist", %{conn: conn} do + node = Node.self() |> to_string + service = String.replace(node, "@", "-") + + Deployex.RpcMock + |> stub(:call, fn node, module, function, args, timeout -> + :rpc.call(node, module, function, args, timeout) + end) + |> stub(:pinfo, fn pid, information -> :rpc.pinfo(pid, information) end) + + {:ok, index_live, _html} = live(conn, ~p"/observer") + + index_live + |> element("#observer-multi-select-toggle-options") + |> render_click() + + index_live + |> element("#observer-multi-select-apps-kernel-add-item") + |> render_click() + + index_live + |> element("#observer-multi-select-services-#{service}-add-item") + |> render_click() + + series_name = "#{Node.self()}::kernel" + + id = "#Port<0.100>" + + html = + index_live + |> element("#observer-tree") + |> render_hook("request-process", %{"id" => id, "series_name" => series_name}) + + # Check the Port information is not being shown + assert html =~ "Port #Port<0.100> is either dead or protected" + end + test "Select Service+Apps and select a reference to request information", %{conn: conn} do node = Node.self() |> to_string service = String.replace(node, "@", "-")