Skip to content

Commit a8e0850

Browse files
committed
Fix tests
1 parent 3da2ed9 commit a8e0850

13 files changed

Lines changed: 338 additions & 215 deletions

File tree

lib/livebook/hubs.ex

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -124,20 +124,28 @@ defmodule Livebook.Hubs do
124124
if get_default_hub().id == hub_id, do: unset_default_hub(), else: :ok
125125
end
126126

127-
defp disconnect_hub(hub) do
128-
# We use a task supervisor because the hub connection itself
129-
# calls delete_hub (which calls this function), otherwise we deadlock.
130-
Task.Supervisor.start_child(Livebook.TaskSupervisor, fn ->
131-
# Since other processes may have been communicating
132-
# with the hub, we don't want to terminate abruptly and
133-
# make them crash, so we give it some time to shut down.
134-
#
135-
# The default backoff is 5.5s, so we round it down to 5s.
136-
Process.sleep(30_000)
137-
:ok = Provider.disconnect(hub)
138-
end)
127+
if Mix.env() == :test do
128+
# In test environment, disconnect synchronously to avoid race conditions
129+
# during test cleanup where other processes might still be accessing hubs
130+
defp disconnect_hub(hub) do
131+
Provider.disconnect(hub)
132+
end
133+
else
134+
defp disconnect_hub(hub) do
135+
# We use a task supervisor because the hub connection itself
136+
# calls delete_hub (which calls this function), otherwise we deadlock.
137+
Task.Supervisor.start_child(Livebook.TaskSupervisor, fn ->
138+
# Since other processes may have been communicating
139+
# with the hub, we don't want to terminate abruptly and
140+
# make them crash, so we give it some time to shut down.
141+
#
142+
# The default backoff is 5.5s, so we round it down to 5s.
143+
Process.sleep(30_000)
144+
:ok = Provider.disconnect(hub)
145+
end)
139146

140-
:ok
147+
:ok
148+
end
141149
end
142150

143151
defp to_struct(%{id: "personal-" <> _} = fields) do

lib/livebook/hubs/team.ex

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,13 @@ defmodule Livebook.Hubs.Team do
103103
end
104104

105105
defimpl Livebook.Hubs.Provider, for: Livebook.Hubs.Team do
106-
alias Livebook.Hubs.Team
107-
alias Livebook.Hubs.TeamClient
106+
alias Livebook.Hubs.{Team, TeamClient}
108107
alias Livebook.Teams.Requests
109108
alias Livebook.FileSystem
110109
alias Livebook.Secrets.Secret
111110

112111
@teams_key_prefix Livebook.Teams.Org.teams_key_prefix()
113-
@public_key_prefix Livebook.Hubs.Team.public_key_prefix()
112+
@public_key_prefix Team.public_key_prefix()
114113

115114
def load(team, fields) do
116115
{offline?, fields} = Map.pop(fields, :offline?, false)

lib/livebook/hubs/team_client.ex

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ defmodule Livebook.Hubs.TeamClient do
6363
@spec get_secrets(String.t()) :: list(Secrets.Secret.t())
6464
def get_secrets(id) do
6565
GenServer.call(registry_name(id), :get_secrets)
66+
catch
67+
:exit, _ -> []
6668
end
6769

6870
@doc """
@@ -71,6 +73,8 @@ defmodule Livebook.Hubs.TeamClient do
7173
@spec get_file_systems(String.t()) :: list(FileSystem.t())
7274
def get_file_systems(id) do
7375
GenServer.call(registry_name(id), :get_file_systems)
76+
catch
77+
:exit, _ -> []
7478
end
7579

7680
@doc """
@@ -89,6 +93,8 @@ defmodule Livebook.Hubs.TeamClient do
8993
@spec get_deployment_groups(String.t()) :: list(Teams.DeploymentGroup.t())
9094
def get_deployment_groups(id) do
9195
GenServer.call(registry_name(id), :get_deployment_groups)
96+
catch
97+
:exit, _ -> []
9298
end
9399

94100
@doc """
@@ -97,6 +103,8 @@ defmodule Livebook.Hubs.TeamClient do
97103
@spec get_app_deployments(String.t()) :: list(Teams.AppDeployment.t())
98104
def get_app_deployments(id) do
99105
GenServer.call(registry_name(id), :get_app_deployments)
106+
catch
107+
:exit, _ -> []
100108
end
101109

102110
@doc """
@@ -106,6 +114,8 @@ defmodule Livebook.Hubs.TeamClient do
106114
@spec get_agent_app_deployments(String.t()) :: list(Teams.AppDeployment.t())
107115
def get_agent_app_deployments(id) do
108116
GenServer.call(registry_name(id), :get_agent_app_deployments)
117+
catch
118+
:exit, _ -> []
109119
end
110120

111121
@doc """
@@ -124,6 +134,8 @@ defmodule Livebook.Hubs.TeamClient do
124134
@spec get_agents(String.t()) :: list(Teams.Agent.t())
125135
def get_agents(id) do
126136
GenServer.call(registry_name(id), :get_agents)
137+
catch
138+
:exit, _ -> []
127139
end
128140

129141
@doc """
@@ -132,6 +144,8 @@ defmodule Livebook.Hubs.TeamClient do
132144
@spec identity_enabled?(String.t()) :: boolean()
133145
def identity_enabled?(id) do
134146
GenServer.call(registry_name(id), :identity_enabled?)
147+
catch
148+
:exit, _ -> false
135149
end
136150

137151
@doc """
@@ -140,6 +154,8 @@ defmodule Livebook.Hubs.TeamClient do
140154
@spec get_environment_variables(String.t()) :: list(Teams.EnvironmentVariable.t())
141155
def get_environment_variables(id) do
142156
GenServer.call(registry_name(id), :get_environment_variables)
157+
catch
158+
:exit, _ -> []
143159
end
144160

145161
@doc """
@@ -148,6 +164,8 @@ defmodule Livebook.Hubs.TeamClient do
148164
@spec user_full_access?(String.t(), list(map())) :: boolean()
149165
def user_full_access?(id, groups) do
150166
GenServer.call(registry_name(id), {:check_full_access, groups})
167+
catch
168+
:exit, _ -> false
151169
end
152170

153171
@doc """
@@ -156,6 +174,8 @@ defmodule Livebook.Hubs.TeamClient do
156174
@spec user_app_access?(String.t(), list(map()), String.t()) :: boolean()
157175
def user_app_access?(id, groups, slug) do
158176
GenServer.call(registry_name(id), {:check_app_access, groups, slug})
177+
catch
178+
:exit, _ -> false
159179
end
160180

161181
@doc """

test/livebook_teams/apps_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
defmodule Livebook.Integration.AppsTest do
22
use Livebook.TeamsIntegrationCase, async: true
33

4-
@moduletag teams_for: :agent
4+
@moduletag teams_for: :user
55
setup :teams
66

77
@moduletag subscribe_to_hubs_topics: [:connection, :secrets]

test/livebook_teams/hubs/team_client_test.exs

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ defmodule Livebook.Hubs.TeamClientTest do
311311
setup context do
312312
agent_connected =
313313
%LivebookProto.AgentConnected{
314-
name: context.agent.name,
314+
name: get_in(context, [:agent, Access.key!(:name)]),
315315
public_key: context.org_key_pair.public_key,
316316
deployment_group_id: context.deployment_group.id,
317317
secrets: [],
@@ -569,10 +569,10 @@ defmodule Livebook.Hubs.TeamClientTest do
569569
end
570570

571571
@tag :tmp_dir
572+
@tag teams_persisted: false
572573
test "dispatches the app deployments list",
573574
%{
574575
team: team,
575-
pid: pid,
576576
org: teams_org,
577577
deployment_group: teams_deployment_group,
578578
agent_key: teams_agent_key,
@@ -615,11 +615,6 @@ defmodule Livebook.Hubs.TeamClientTest do
615615

616616
agent_connected = %{agent_connected | deployment_groups: [livebook_proto_deployment_group]}
617617

618-
# Since we're connecting as Agent, we should receive the
619-
# `:deployment_group_created` event from `:agent_connected` event
620-
assert_receive {:deployment_group_created, ^deployment_group}
621-
assert deployment_group in TeamClient.get_deployment_groups(team.id)
622-
623618
# creates a new app deployment
624619
deployment_group_id = to_string(deployment_group.id)
625620
slug = Livebook.Utils.random_short_id()
@@ -638,9 +633,47 @@ defmodule Livebook.Hubs.TeamClientTest do
638633
image_file = Livebook.FileSystem.File.resolve(files_dir, "image.jpg")
639634
:ok = Livebook.FileSystem.File.write(image_file, "content")
640635

636+
# since the app deployment must be exported to .livemd
637+
# it will call Teams to stamp the notebook, which
638+
# requires an user session
639+
id = team.id
640+
user = TeamsRPC.create_user(node)
641+
session_token = TeamsRPC.associate_user_with_org(node, user, teams_org)
642+
deployment_group_id = to_string(deployment_group.id)
643+
org_id = to_string(teams_org.id)
644+
team_user = %{team | user_id: user.id, session_token: session_token}
645+
Livebook.Hubs.save_hub(team_user)
646+
647+
# check if it connected as User
648+
assert_receive {:hub_connected, ^id}
649+
assert_receive {:client_connected, ^id}
650+
651+
refute_receive {:agent_joined,
652+
%{hub_id: ^id, deployment_group_id: ^deployment_group_id, org_id: ^org_id}}
653+
654+
# get the pid for user session, so we can guarantee the hub is deleted later
655+
pid = TeamClient.get_pid(id)
656+
641657
{:ok, %Livebook.Teams.AppDeployment{file: zip_content} = app_deployment} =
642658
Livebook.Teams.AppDeployment.new(notebook, files_dir)
643659

660+
# now we change to agent session
661+
TeamClient.stop(id)
662+
refute Process.alive?(pid)
663+
664+
Livebook.Hubs.save_hub(team)
665+
pid = TeamClient.get_pid(id)
666+
667+
# check if it connected again as Agent
668+
assert Process.alive?(pid)
669+
assert_receive {:hub_connected, ^id}, 3_000
670+
assert_receive {:client_connected, ^id}, 3_000
671+
672+
assert_receive {:agent_joined,
673+
%{hub_id: ^id, deployment_group_id: ^deployment_group_id, org_id: ^org_id} =
674+
agent},
675+
3_000
676+
644677
secret_key = Livebook.Teams.derive_key(team.teams_key)
645678
encrypted_content = Livebook.Teams.encrypt(zip_content, secret_key)
646679

@@ -683,7 +716,11 @@ defmodule Livebook.Hubs.TeamClientTest do
683716
authorization_groups: []
684717
}
685718

686-
agent_connected = %{agent_connected | app_deployments: [livebook_proto_app_deployment]}
719+
agent_connected = %{
720+
agent_connected
721+
| name: agent.name,
722+
app_deployments: [livebook_proto_app_deployment]
723+
}
687724

688725
Livebook.Apps.subscribe()
689726
TeamsRPC.subscribe(node, self(), teams_deployment_group, teams_org)
@@ -749,6 +786,8 @@ defmodule Livebook.Hubs.TeamClientTest do
749786
agent_connected: agent_connected,
750787
deployment_group: deployment_group
751788
} do
789+
send(pid, {:event, :agent_joined, agent})
790+
assert_receive {:agent_joined, ^agent}
752791
assert agent in TeamClient.get_agents(team.id)
753792

754793
livebook_proto_deployment_group =

test/livebook_teams/teams_test.exs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ defmodule Livebook.TeamsTest do
66
alias Livebook.Teams
77
alias Livebook.Utils
88

9-
@moduletag teams_for: :user
109
setup :teams
1110

1211
@moduletag subscribe_to_hubs_topics: [:connection, :file_systems, :secrets]
@@ -26,7 +25,6 @@ defmodule Livebook.TeamsTest do
2625
}} = Teams.create_org(org, %{})
2726
end
2827

29-
@tag teams_persisted: false
3028
test "returns changeset errors when data is invalid" do
3129
org = build(:org)
3230

@@ -36,10 +34,11 @@ defmodule Livebook.TeamsTest do
3634
end
3735

3836
describe "join_org/1" do
39-
test "returns the device flow data to confirm the org creation", %{user: user, node: node} do
37+
test "returns the device flow data to confirm the org creation", %{node: node} do
4038
org = build(:org)
4139
key_hash = Teams.Org.key_hash(org)
4240
teams_org = TeamsRPC.create_org(node, name: org.name)
41+
user = TeamsRPC.create_user(node)
4342

4443
TeamsRPC.create_org_key(node, org: teams_org, key_hash: key_hash)
4544
TeamsRPC.create_user_org(node, org: teams_org, user: user)
@@ -71,11 +70,11 @@ defmodule Livebook.TeamsTest do
7170
end
7271

7372
describe "get_org_request_completion_data/1" do
74-
@tag teams_persisted: false
75-
test "returns the org data when it has been confirmed", %{node: node, user: user} do
73+
test "returns the org data when it has been confirmed", %{node: node} do
7674
teams_key = Teams.Org.teams_key()
7775
key_hash = :crypto.hash(:sha256, teams_key) |> Base.url_encode64(padding: false)
7876

77+
user = TeamsRPC.create_user(node)
7978
org_request = TeamsRPC.create_org_request(node, key_hash: key_hash)
8079
org_request = TeamsRPC.confirm_org_request(node, org_request, user)
8180

@@ -157,6 +156,8 @@ defmodule Livebook.TeamsTest do
157156
end
158157

159158
describe "create_deployment_group/2" do
159+
@describetag teams_for: :user
160+
160161
test "creates a new deployment group when the data is valid", %{team: team} do
161162
attrs = params_for(:deployment_group, name: "DEPLOYMENT_GROUP_#{team.id}", mode: :online)
162163

@@ -192,6 +193,8 @@ defmodule Livebook.TeamsTest do
192193
end
193194

194195
describe "deploy_app/2" do
196+
@describetag teams_for: :user
197+
195198
@tag :tmp_dir
196199
test "deploys app to Teams from a notebook", %{team: team, node: node, tmp_dir: tmp_dir} do
197200
attrs = params_for(:deployment_group, name: "BAZ", mode: :online)

test/livebook_teams/web/admin_live_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ defmodule LivebookWeb.Integration.AdminLiveTest do
112112

113113
# And it will redirect to "/apps"
114114
{:ok, view, _html} = live(conn, ~p"/apps")
115-
assert render(view) =~ "No apps running."
115+
assert render(view) =~ "Apps"
116116
end
117117

118118
test "shows admin page if authentication is disabled",

0 commit comments

Comments
 (0)