mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-11-10 06:01:44 +08:00
Improve integration tests infrastructure (#2583)
This commit is contained in:
parent
fdac5cfe4f
commit
3d289448cd
5 changed files with 218 additions and 497 deletions
|
|
@ -6,168 +6,37 @@ defmodule Livebook.Hubs.TeamClientTest do
|
||||||
setup do
|
setup do
|
||||||
Livebook.Hubs.Broadcasts.subscribe([:connection, :file_systems, :secrets])
|
Livebook.Hubs.Broadcasts.subscribe([:connection, :file_systems, :secrets])
|
||||||
Livebook.Teams.Broadcasts.subscribe([:clients, :deployment_groups, :app_deployments, :agents])
|
Livebook.Teams.Broadcasts.subscribe([:clients, :deployment_groups, :app_deployments, :agents])
|
||||||
|
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
test "rejects the web socket connection with invalid credentials", %{user: user, token: token} do
|
describe "connect" do
|
||||||
team =
|
test "successfully authenticates the websocket connection", %{user: user, node: node} do
|
||||||
build(:team,
|
team = build_team_hub(user, node)
|
||||||
user_id: user.id,
|
|
||||||
org_id: 123_456,
|
|
||||||
org_key_id: 123_456,
|
|
||||||
session_token: token
|
|
||||||
)
|
|
||||||
|
|
||||||
id = team.id
|
|
||||||
|
|
||||||
TeamClient.start_link(team)
|
|
||||||
|
|
||||||
assert_receive {:hub_server_error, ^id, error}
|
|
||||||
|
|
||||||
assert error ==
|
|
||||||
"#{team.hub_name}: Your session is out-of-date. Please re-join the organization."
|
|
||||||
|
|
||||||
refute Livebook.Hubs.hub_exists?(team.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "handle events" do
|
|
||||||
setup %{user: user, node: node} do
|
|
||||||
team = create_team_hub(user, node)
|
|
||||||
id = team.id
|
id = team.id
|
||||||
|
TeamClient.start_link(team)
|
||||||
|
|
||||||
assert_receive {:hub_connected, ^id}
|
assert_receive {:hub_connected, ^id}
|
||||||
assert_receive {:client_connected, ^id}
|
assert_receive {:client_connected, ^id}
|
||||||
|
|
||||||
{:ok, team: team}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "receives secret events", %{team: team} do
|
test "rejects the web socket connection with invalid credentials", %{user: user, token: token} do
|
||||||
secret = build(:secret, name: "SECRET", value: "BAR")
|
team =
|
||||||
assert Livebook.Hubs.create_secret(team, secret) == :ok
|
build(:team,
|
||||||
|
user_id: user.id,
|
||||||
name = secret.name
|
org_id: 123_456,
|
||||||
value = secret.value
|
org_key_id: 123_456,
|
||||||
|
session_token: token
|
||||||
# receives `{:secret_created, secret}` event
|
)
|
||||||
# with the value decrypted
|
|
||||||
assert_receive {:secret_created, %{name: ^name, value: ^value}}
|
|
||||||
|
|
||||||
# updates the secret
|
|
||||||
updated_secret = Map.replace!(secret, :value, "BAZ")
|
|
||||||
assert Livebook.Hubs.update_secret(team, updated_secret) == :ok
|
|
||||||
|
|
||||||
new_value = updated_secret.value
|
|
||||||
|
|
||||||
# receives `{:secret_updated, secret}` event
|
|
||||||
# with the value decrypted
|
|
||||||
assert_receive {:secret_updated, %{name: ^name, value: ^new_value}}
|
|
||||||
|
|
||||||
# deletes the secret
|
|
||||||
assert Livebook.Hubs.delete_secret(team, updated_secret) == :ok
|
|
||||||
|
|
||||||
# receives `{:secret_deleted, secret}` event
|
|
||||||
assert_receive {:secret_deleted, %{name: ^name, value: ^new_value}}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "receives file system events", %{team: team} do
|
|
||||||
file_system =
|
|
||||||
build(:fs_s3, bucket_url: "https://file_system.s3.amazonaws.com", region: "us-east-1")
|
|
||||||
|
|
||||||
assert Livebook.Hubs.create_file_system(team, file_system) == :ok
|
|
||||||
|
|
||||||
bucket_url = file_system.bucket_url
|
|
||||||
region = file_system.region
|
|
||||||
|
|
||||||
# receives `{:file_system_created, file_system}` event
|
|
||||||
assert_receive {:file_system_created,
|
|
||||||
%{external_id: id, bucket_url: ^bucket_url, region: ^region}}
|
|
||||||
|
|
||||||
# updates the file system
|
|
||||||
updated_file_system = %{file_system | region: "eu-central-1", external_id: id}
|
|
||||||
assert Livebook.Hubs.update_file_system(team, updated_file_system) == :ok
|
|
||||||
|
|
||||||
new_region = updated_file_system.region
|
|
||||||
|
|
||||||
# receives `{:file_system_updated, file_system}` event
|
|
||||||
assert_receive {:file_system_updated,
|
|
||||||
%{external_id: ^id, bucket_url: ^bucket_url, region: ^new_region}}
|
|
||||||
|
|
||||||
# deletes the file system
|
|
||||||
assert Livebook.Hubs.delete_file_system(team, updated_file_system) == :ok
|
|
||||||
|
|
||||||
# receives `{:file_system_deleted, file_system}` event
|
|
||||||
assert_receive {:file_system_deleted, %{external_id: ^id, bucket_url: ^bucket_url}}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "receives deployment group events", %{team: team} do
|
|
||||||
deployment_group =
|
|
||||||
build(:deployment_group, name: "DEPLOYMENT_GROUP_#{team.id}", mode: :online)
|
|
||||||
|
|
||||||
assert {:ok, _} = Livebook.Teams.create_deployment_group(team, deployment_group)
|
|
||||||
%{name: name, mode: mode} = deployment_group
|
|
||||||
|
|
||||||
# receives `{:event, :deployment_group_created, deployment_group}` event
|
|
||||||
assert_receive {:deployment_group_created, %{name: ^name, mode: ^mode}}
|
|
||||||
end
|
|
||||||
|
|
||||||
@tag :tmp_dir
|
|
||||||
test "receives app events", %{team: team, node: node, tmp_dir: tmp_dir} do
|
|
||||||
deployment_group = build(:deployment_group, name: team.id, mode: :online)
|
|
||||||
assert {:ok, id} = Livebook.Teams.create_deployment_group(team, deployment_group)
|
|
||||||
|
|
||||||
id = to_string(id)
|
|
||||||
|
|
||||||
assert_receive {:deployment_group_created, %{id: ^id}}
|
|
||||||
|
|
||||||
# creates the app deployment
|
|
||||||
slug = Livebook.Utils.random_short_id()
|
|
||||||
title = "MyNotebook-#{slug}"
|
|
||||||
app_settings = %{Livebook.Notebook.AppSettings.new() | slug: slug}
|
|
||||||
|
|
||||||
notebook = %{
|
|
||||||
Livebook.Notebook.new()
|
|
||||||
| app_settings: app_settings,
|
|
||||||
name: title,
|
|
||||||
hub_id: team.id,
|
|
||||||
deployment_group_id: id
|
|
||||||
}
|
|
||||||
|
|
||||||
files_dir = Livebook.FileSystem.File.local(tmp_dir)
|
|
||||||
{:ok, app_deployment} = Livebook.Teams.AppDeployment.new(notebook, files_dir)
|
|
||||||
:ok = Livebook.Teams.deploy_app(team, app_deployment)
|
|
||||||
|
|
||||||
sha = app_deployment.sha
|
|
||||||
multi_session = app_settings.multi_session
|
|
||||||
access_type = app_settings.access_type
|
|
||||||
|
|
||||||
assert_receive {:app_deployment_started,
|
|
||||||
%Livebook.Teams.AppDeployment{
|
|
||||||
slug: ^slug,
|
|
||||||
sha: ^sha,
|
|
||||||
title: ^title,
|
|
||||||
multi_session: ^multi_session,
|
|
||||||
access_type: ^access_type,
|
|
||||||
deployment_group_id: ^id
|
|
||||||
} = app_deployment}
|
|
||||||
|
|
||||||
# force app deployment to be deleted
|
|
||||||
erpc_call(node, :toggle_app_deployment, [app_deployment.id, team.org_id])
|
|
||||||
|
|
||||||
assert_receive {:app_deployment_stopped, ^app_deployment}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "receives the user events", %{team: team, node: node} do
|
|
||||||
Livebook.Hubs.Broadcasts.subscribe([:crud])
|
|
||||||
|
|
||||||
# force user to be deleted from org
|
|
||||||
erpc_call(node, :delete_user_org, [team.user_id, team.org_id])
|
|
||||||
|
|
||||||
id = team.id
|
id = team.id
|
||||||
reason = "#{team.hub_name}: you were removed from the org"
|
|
||||||
|
|
||||||
assert_receive {:hub_server_error, ^id, ^reason}
|
start_supervised!({TeamClient, team})
|
||||||
assert_receive {:hub_deleted, ^id}
|
|
||||||
refute team in Livebook.Hubs.get_hubs()
|
assert_receive {:hub_server_error, ^id, error}
|
||||||
|
|
||||||
|
assert error ==
|
||||||
|
"#{team.hub_name}: Your session is out-of-date. Please re-join the organization."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -187,6 +56,20 @@ defmodule Livebook.Hubs.TeamClientTest do
|
||||||
{:ok, team: team, user_connected: user_connected}
|
{:ok, team: team, user_connected: user_connected}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "receives the user events", %{team: team, node: node} do
|
||||||
|
Livebook.Hubs.Broadcasts.subscribe([:crud])
|
||||||
|
|
||||||
|
# force user to be deleted from org
|
||||||
|
erpc_call(node, :delete_user_org, [team.user_id, team.org_id])
|
||||||
|
|
||||||
|
id = team.id
|
||||||
|
reason = "#{team.hub_name}: you were removed from the org"
|
||||||
|
|
||||||
|
assert_receive {:hub_server_error, ^id, ^reason}
|
||||||
|
assert_receive {:hub_deleted, ^id}
|
||||||
|
refute team in Livebook.Hubs.get_hubs()
|
||||||
|
end
|
||||||
|
|
||||||
test "dispatches the secrets list", %{team: team, user_connected: user_connected} do
|
test "dispatches the secrets list", %{team: team, user_connected: user_connected} do
|
||||||
secret =
|
secret =
|
||||||
build(:secret,
|
build(:secret,
|
||||||
|
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
defmodule Livebook.Hubs.TeamTest do
|
|
||||||
use Livebook.TeamsIntegrationCase, async: true
|
|
||||||
|
|
||||||
alias Livebook.Hubs.Provider
|
|
||||||
|
|
||||||
describe "stamping" do
|
|
||||||
test "generates and verifies stamp for a notebook", %{user: user, node: node} do
|
|
||||||
team = create_team_hub(user, node)
|
|
||||||
|
|
||||||
notebook_source = """
|
|
||||||
# Team notebook
|
|
||||||
|
|
||||||
# Intro
|
|
||||||
|
|
||||||
```elixir
|
|
||||||
IO.puts("Hello!")
|
|
||||||
```
|
|
||||||
"""
|
|
||||||
|
|
||||||
metadata = %{"key" => "value"}
|
|
||||||
|
|
||||||
assert {:ok, stamp} = Provider.notebook_stamp(team, notebook_source, metadata)
|
|
||||||
|
|
||||||
assert {:ok, ^metadata} = Provider.verify_notebook_stamp(team, notebook_source, stamp)
|
|
||||||
|
|
||||||
assert {:error, :invalid} =
|
|
||||||
Provider.verify_notebook_stamp(team, notebook_source <> "change\n", stamp)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -3,8 +3,15 @@ defmodule Livebook.HubsTest do
|
||||||
|
|
||||||
alias Livebook.Hubs
|
alias Livebook.Hubs
|
||||||
|
|
||||||
|
setup do
|
||||||
|
Livebook.Hubs.Broadcasts.subscribe([:connection, :file_systems, :secrets])
|
||||||
|
Livebook.Teams.Broadcasts.subscribe([:clients])
|
||||||
|
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
test "get_hubs/0 returns a list of persisted hubs", %{user: user, node: node} do
|
test "get_hubs/0 returns a list of persisted hubs", %{user: user, node: node} do
|
||||||
team = create_team_hub(user, node)
|
team = connect_to_teams(user, node)
|
||||||
assert team in Hubs.get_hubs()
|
assert team in Hubs.get_hubs()
|
||||||
|
|
||||||
Hubs.delete_hub(team.id)
|
Hubs.delete_hub(team.id)
|
||||||
|
|
@ -12,7 +19,7 @@ defmodule Livebook.HubsTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "get_metadata/0 returns a list of persisted hubs normalized", %{user: user, node: node} do
|
test "get_metadata/0 returns a list of persisted hubs normalized", %{user: user, node: node} do
|
||||||
team = create_team_hub(user, node)
|
team = connect_to_teams(user, node)
|
||||||
metadata = Hubs.Provider.to_metadata(team)
|
metadata = Hubs.Provider.to_metadata(team)
|
||||||
|
|
||||||
assert metadata in Hubs.get_metadata()
|
assert metadata in Hubs.get_metadata()
|
||||||
|
|
@ -28,7 +35,7 @@ defmodule Livebook.HubsTest do
|
||||||
Hubs.fetch_hub!("nonexistent")
|
Hubs.fetch_hub!("nonexistent")
|
||||||
end
|
end
|
||||||
|
|
||||||
team = create_team_hub(user, node)
|
team = connect_to_teams(user, node)
|
||||||
|
|
||||||
assert Hubs.fetch_hub!(team.id) == team
|
assert Hubs.fetch_hub!(team.id) == team
|
||||||
end
|
end
|
||||||
|
|
@ -49,7 +56,7 @@ defmodule Livebook.HubsTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "updates hub", %{user: user, node: node} do
|
test "updates hub", %{user: user, node: node} do
|
||||||
team = create_team_hub(user, node)
|
team = connect_to_teams(user, node)
|
||||||
Hubs.save_hub(%{team | hub_emoji: "🐈"})
|
Hubs.save_hub(%{team | hub_emoji: "🐈"})
|
||||||
|
|
||||||
assert Hubs.fetch_hub!(team.id).hub_emoji == "🐈"
|
assert Hubs.fetch_hub!(team.id).hub_emoji == "🐈"
|
||||||
|
|
@ -58,10 +65,13 @@ defmodule Livebook.HubsTest do
|
||||||
|
|
||||||
describe "create_secret/2" do
|
describe "create_secret/2" do
|
||||||
test "creates a new secret", %{user: user, node: node} do
|
test "creates a new secret", %{user: user, node: node} do
|
||||||
hub = create_team_hub(user, node)
|
hub = connect_to_teams(user, node)
|
||||||
secret = build(:secret, name: "FOO", value: "BAR")
|
name = secret_name(hub)
|
||||||
|
value = hub.id
|
||||||
|
secret = build(:secret, name: name, value: value, hub_id: hub.id)
|
||||||
|
|
||||||
assert Hubs.create_secret(hub, secret) == :ok
|
assert Hubs.create_secret(hub, secret) == :ok
|
||||||
|
assert secret in Hubs.get_secrets(hub)
|
||||||
|
|
||||||
# Guarantee uniqueness
|
# Guarantee uniqueness
|
||||||
assert {:error, changeset} = Hubs.create_secret(hub, secret)
|
assert {:error, changeset} = Hubs.create_secret(hub, secret)
|
||||||
|
|
@ -69,69 +79,83 @@ defmodule Livebook.HubsTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns changeset errors when data is invalid", %{user: user, node: node} do
|
test "returns changeset errors when data is invalid", %{user: user, node: node} do
|
||||||
hub = create_team_hub(user, node)
|
hub = connect_to_teams(user, node)
|
||||||
secret = build(:secret, name: "LB_FOO", value: "BAR")
|
secret = build(:secret, name: "LB_FOO", value: "BAR", hub_id: hub.id)
|
||||||
|
|
||||||
assert {:error, changeset} = Hubs.create_secret(hub, secret)
|
assert {:error, changeset} = Hubs.create_secret(hub, secret)
|
||||||
assert "cannot start with the LB_ prefix" in errors_on(changeset).name
|
assert "cannot start with the LB_ prefix" in errors_on(changeset).name
|
||||||
|
refute secret in Hubs.get_secrets(hub)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "update_secret/2" do
|
describe "update_secret/2" do
|
||||||
test "updates a secret", %{user: user, node: node} do
|
test "updates a secret", %{user: user, node: node} do
|
||||||
hub = create_team_hub(user, node)
|
hub = connect_to_teams(user, node)
|
||||||
secret = build(:secret, name: "UPDATE_ME", value: "BAR")
|
name = secret_name(hub)
|
||||||
|
value = hub.id
|
||||||
|
secret = build(:secret, name: name, value: value, hub_id: hub.id)
|
||||||
|
|
||||||
assert Hubs.create_secret(hub, secret) == :ok
|
assert Hubs.create_secret(hub, secret) == :ok
|
||||||
|
assert_receive {:secret_created, %{name: ^name, value: ^value}}
|
||||||
|
assert secret in Hubs.get_secrets(hub)
|
||||||
|
|
||||||
update_secret = Map.replace!(secret, :value, "BAZ")
|
new_value = "BAZ"
|
||||||
assert Hubs.update_secret(hub, update_secret) == :ok
|
updated_secret = Map.replace!(secret, :value, new_value)
|
||||||
|
|
||||||
|
assert Hubs.update_secret(hub, updated_secret) == :ok
|
||||||
|
assert_receive {:secret_updated, %{name: ^name, value: ^new_value}}
|
||||||
|
refute secret in Hubs.get_secrets(hub)
|
||||||
|
assert updated_secret in Hubs.get_secrets(hub)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns changeset errors when data is invalid", %{user: user, node: node} do
|
test "returns changeset errors when data is invalid", %{user: user, node: node} do
|
||||||
hub = create_team_hub(user, node)
|
hub = connect_to_teams(user, node)
|
||||||
secret = build(:secret, name: "FIX_ME", value: "BAR")
|
name = secret_name(hub)
|
||||||
|
value = hub.id
|
||||||
|
secret = build(:secret, name: name, value: value, hub_id: hub.id)
|
||||||
|
|
||||||
assert Hubs.create_secret(hub, secret) == :ok
|
assert Hubs.create_secret(hub, secret) == :ok
|
||||||
|
assert_receive {:secret_created, %{name: ^name, value: ^value}}
|
||||||
|
|
||||||
update_secret = Map.replace!(secret, :value, "")
|
updated_secret = Map.replace!(secret, :value, "")
|
||||||
|
|
||||||
assert {:error, changeset} = Hubs.update_secret(hub, update_secret)
|
assert {:error, changeset} = Hubs.update_secret(hub, updated_secret)
|
||||||
assert "can't be blank" in errors_on(changeset).value
|
assert "can't be blank" in errors_on(changeset).value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "delete_secret/2" do
|
test "delete_secret/2 deletes a secret", %{user: user, node: node} do
|
||||||
test "deletes a secret", %{user: user, node: node} do
|
hub = connect_to_teams(user, node)
|
||||||
hub = create_team_hub(user, node)
|
name = secret_name(hub)
|
||||||
secret = build(:secret, name: "DELETE_ME", value: "BAR")
|
value = hub.id
|
||||||
|
secret = build(:secret, name: name, value: value, hub_id: hub.id)
|
||||||
|
|
||||||
assert Hubs.create_secret(hub, secret) == :ok
|
assert Hubs.create_secret(hub, secret) == :ok
|
||||||
assert Hubs.delete_secret(hub, secret) == :ok
|
assert_receive {:secret_created, %{name: ^name, value: ^value}}
|
||||||
|
assert secret in Hubs.get_secrets(hub)
|
||||||
|
|
||||||
# Guarantee it's been removed and will return HTTP status 404
|
assert Hubs.delete_secret(hub, secret) == :ok
|
||||||
assert Hubs.delete_secret(hub, secret) ==
|
assert_receive {:secret_deleted, %{name: ^name, value: ^value}}
|
||||||
{:transport_error,
|
refute secret in Hubs.get_secrets(hub)
|
||||||
"Something went wrong, try again later or please file a bug if it persists"}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "returns transport errors when secret doesn't exists", %{user: user, node: node} do
|
# Guarantee it's been removed and will return HTTP status 404
|
||||||
hub = create_team_hub(user, node)
|
assert Hubs.delete_secret(hub, secret) ==
|
||||||
secret = build(:secret, name: "I_CANT_EXIST", value: "BAR")
|
{:transport_error,
|
||||||
|
"Something went wrong, try again later or please file a bug if it persists"}
|
||||||
|
|
||||||
# Guarantee it doesn't exists and will return HTTP status 404
|
refute_receive {:secret_deleted, _}
|
||||||
assert Hubs.delete_secret(hub, secret) ==
|
|
||||||
{:transport_error,
|
|
||||||
"Something went wrong, try again later or please file a bug if it persists"}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "create_file_system/2" do
|
describe "create_file_system/2" do
|
||||||
test "creates a new file system", %{user: user, node: node} do
|
test "creates a new file system", %{user: user, node: node} do
|
||||||
hub = create_team_hub(user, node)
|
hub = connect_to_teams(user, node)
|
||||||
file_system = build(:fs_s3, bucket_url: "https://file_system_created.s3.amazonaws.com")
|
|
||||||
|
bucket_url = "https://#{hub.id}.s3.amazonaws.com"
|
||||||
|
file_system = build(:fs_s3, bucket_url: bucket_url)
|
||||||
|
region = file_system.region
|
||||||
|
|
||||||
assert Hubs.create_file_system(hub, file_system) == :ok
|
assert Hubs.create_file_system(hub, file_system) == :ok
|
||||||
|
assert_receive {:file_system_created, %{bucket_url: ^bucket_url, region: ^region}}
|
||||||
|
|
||||||
# Guarantee uniqueness
|
# Guarantee uniqueness
|
||||||
assert {:error, changeset} = Hubs.create_file_system(hub, file_system)
|
assert {:error, changeset} = Hubs.create_file_system(hub, file_system)
|
||||||
|
|
@ -139,32 +163,35 @@ defmodule Livebook.HubsTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns changeset errors when data is invalid", %{user: user, node: node} do
|
test "returns changeset errors when data is invalid", %{user: user, node: node} do
|
||||||
hub = create_team_hub(user, node)
|
hub = connect_to_teams(user, node)
|
||||||
file_system = build(:fs_s3, bucket_url: nil)
|
file_system = build(:fs_s3, bucket_url: nil)
|
||||||
|
|
||||||
assert {:error, changeset} = Hubs.create_file_system(hub, file_system)
|
assert {:error, changeset} = Hubs.create_file_system(hub, file_system)
|
||||||
assert "can't be blank" in errors_on(changeset).bucket_url
|
assert "can't be blank" in errors_on(changeset).bucket_url
|
||||||
|
refute_receive {:file_system_created, _}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "update_file_system/2" do
|
describe "update_file_system/2" do
|
||||||
test "updates a file system", %{user: user, node: node} do
|
test "updates a file system", %{user: user, node: node} do
|
||||||
hub = create_team_hub(user, node)
|
hub = connect_to_teams(user, node)
|
||||||
teams_file_system = create_teams_file_system(hub, node)
|
bucket_url = "https://#{hub.id}.s3.amazonaws.com"
|
||||||
|
file_system = build(:fs_s3, bucket_url: bucket_url)
|
||||||
|
|
||||||
file_system =
|
assert Hubs.create_file_system(hub, file_system) == :ok
|
||||||
build(:fs_s3,
|
assert_receive {:file_system_created, %{external_id: external_id} = file_system}
|
||||||
bucket_url: teams_file_system.name,
|
assert file_system in Hubs.get_file_systems(hub)
|
||||||
region: "us-east-1",
|
|
||||||
external_id: to_string(teams_file_system.id)
|
|
||||||
)
|
|
||||||
|
|
||||||
update_file_system = Map.replace!(file_system, :region, "eu-central-1")
|
updated_file_system = Map.replace!(file_system, :region, "eu-central-1")
|
||||||
assert Hubs.update_file_system(hub, update_file_system) == :ok
|
|
||||||
|
assert Hubs.update_file_system(hub, updated_file_system) == :ok
|
||||||
|
assert_receive {:file_system_updated, %{external_id: ^external_id, region: "eu-central-1"}}
|
||||||
|
refute file_system in Hubs.get_file_systems(hub)
|
||||||
|
assert updated_file_system in Hubs.get_file_systems(hub)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns changeset errors when data is invalid", %{user: user, node: node} do
|
test "returns changeset errors when data is invalid", %{user: user, node: node} do
|
||||||
hub = create_team_hub(user, node)
|
hub = connect_to_teams(user, node)
|
||||||
teams_file_system = create_teams_file_system(hub, node)
|
teams_file_system = create_teams_file_system(hub, node)
|
||||||
|
|
||||||
file_system =
|
file_system =
|
||||||
|
|
@ -177,42 +204,64 @@ defmodule Livebook.HubsTest do
|
||||||
|
|
||||||
assert {:error, changeset} = Hubs.update_file_system(hub, update_file_system)
|
assert {:error, changeset} = Hubs.update_file_system(hub, update_file_system)
|
||||||
assert "can't be blank" in errors_on(changeset).bucket_url
|
assert "can't be blank" in errors_on(changeset).bucket_url
|
||||||
|
refute_receive {:file_system_updated, _}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "delete_file_system/2" do
|
test "delete_file_system/2 deletes a file system", %{user: user, node: node} do
|
||||||
test "deletes a file system", %{user: user, node: node} do
|
hub = connect_to_teams(user, node)
|
||||||
hub = create_team_hub(user, node)
|
bucket_url = "https://#{hub.id}.s3.amazonaws.com"
|
||||||
teams_file_system = create_teams_file_system(hub, node)
|
file_system = build(:fs_s3, bucket_url: bucket_url)
|
||||||
|
|
||||||
file_system =
|
assert Hubs.create_file_system(hub, file_system) == :ok
|
||||||
build(:fs_s3,
|
assert_receive {:file_system_created, %{external_id: external_id} = file_system}
|
||||||
bucket_url: teams_file_system.name,
|
assert file_system in Hubs.get_file_systems(hub)
|
||||||
region: "us-east-1",
|
|
||||||
external_id: to_string(teams_file_system.id)
|
|
||||||
)
|
|
||||||
|
|
||||||
assert Hubs.delete_file_system(hub, file_system) == :ok
|
assert Hubs.delete_file_system(hub, file_system) == :ok
|
||||||
|
assert_receive {:file_system_deleted, %{external_id: ^external_id}}
|
||||||
|
refute file_system in Hubs.get_file_systems(hub)
|
||||||
|
|
||||||
# Guarantee it's been removed and will return HTTP status 404
|
# Guarantee it's been removed and will return HTTP status 404
|
||||||
assert Hubs.delete_file_system(hub, file_system) ==
|
assert Hubs.delete_file_system(hub, file_system) ==
|
||||||
{:transport_error,
|
{:transport_error,
|
||||||
"Something went wrong, try again later or please file a bug if it persists"}
|
"Something went wrong, try again later or please file a bug if it persists"}
|
||||||
end
|
|
||||||
|
|
||||||
test "returns transport errors when file system doesn't exists", %{user: user, node: node} do
|
refute_receive {:file_system_deleted, _}
|
||||||
hub = create_team_hub(user, node)
|
end
|
||||||
|
|
||||||
file_system =
|
test "generates and verifies stamp for a notebook", %{user: user, node: node} do
|
||||||
build(:fs_s3,
|
team = connect_to_teams(user, node)
|
||||||
bucket_url: "https://i_cant_exist.s3.amazonaws.com",
|
|
||||||
external_id: "123456789"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Guarantee it doesn't exists and will return HTTP status 404
|
notebook_source = """
|
||||||
assert Hubs.delete_file_system(hub, file_system) ==
|
# Team notebook
|
||||||
{:transport_error,
|
|
||||||
"Something went wrong, try again later or please file a bug if it persists"}
|
# Intro
|
||||||
end
|
|
||||||
|
```elixir
|
||||||
|
IO.puts("Hello!")
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
|
||||||
|
metadata = %{"key" => "value"}
|
||||||
|
|
||||||
|
assert {:ok, stamp} = Hubs.Provider.notebook_stamp(team, notebook_source, metadata)
|
||||||
|
assert {:ok, ^metadata} = Hubs.Provider.verify_notebook_stamp(team, notebook_source, stamp)
|
||||||
|
|
||||||
|
assert {:error, :invalid} =
|
||||||
|
Hubs.Provider.verify_notebook_stamp(team, notebook_source <> "change\n", stamp)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp connect_to_teams(user, node) do
|
||||||
|
%{id: id} = team = create_team_hub(user, node)
|
||||||
|
assert_receive {:hub_connected, ^id}
|
||||||
|
assert_receive {:client_connected, ^id}
|
||||||
|
|
||||||
|
team
|
||||||
|
end
|
||||||
|
|
||||||
|
defp secret_name(%{id: id}) do
|
||||||
|
id
|
||||||
|
|> String.replace("-", "_")
|
||||||
|
|> String.upcase()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,226 +0,0 @@
|
||||||
defmodule Livebook.Teams.ConnectionTest do
|
|
||||||
alias Livebook.FileSystem
|
|
||||||
use Livebook.TeamsIntegrationCase, async: true
|
|
||||||
|
|
||||||
alias Livebook.Teams.Connection
|
|
||||||
|
|
||||||
describe "connect" do
|
|
||||||
test "successfully authenticates the websocket connection", %{user: user, node: node} do
|
|
||||||
{_, headers} = build_team_headers(user, node)
|
|
||||||
|
|
||||||
assert {:ok, _conn} = Connection.start_link(self(), headers)
|
|
||||||
assert_receive :connected
|
|
||||||
end
|
|
||||||
|
|
||||||
test "rejects the websocket connection with invalid credentials", %{user: user} do
|
|
||||||
headers = [
|
|
||||||
{"x-user", to_string(user.id)},
|
|
||||||
{"x-org", to_string(user.id)},
|
|
||||||
{"x-org-key", to_string(user.id)},
|
|
||||||
{"x-session-token", "foo"}
|
|
||||||
]
|
|
||||||
|
|
||||||
assert {:ok, _conn} = Connection.start_link(self(), headers)
|
|
||||||
|
|
||||||
assert_receive {:server_error,
|
|
||||||
"Your session is out-of-date. Please re-join the organization."}
|
|
||||||
|
|
||||||
assert {:ok, _conn} = Connection.start_link(self(), [])
|
|
||||||
|
|
||||||
assert_receive {:server_error,
|
|
||||||
"Invalid request. Please re-join the organization and update Livebook if the issue persists."}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "handle events" do
|
|
||||||
test "receives the secret_created event", %{user: user, node: node} do
|
|
||||||
{hub, headers} = build_team_headers(user, node)
|
|
||||||
|
|
||||||
assert {:ok, _conn} = Connection.start_link(self(), headers)
|
|
||||||
assert_receive :connected
|
|
||||||
|
|
||||||
# creates a new secret
|
|
||||||
secret = build(:secret, name: "FOO", value: "BAR")
|
|
||||||
assert Livebook.Hubs.create_secret(hub, secret) == :ok
|
|
||||||
|
|
||||||
# receives `{:event, :secret_created, secret_created}` event
|
|
||||||
# without decrypting the value
|
|
||||||
assert_receive {:event, :secret_created, secret_created}
|
|
||||||
assert secret_created.name == secret.name
|
|
||||||
refute secret_created.value == secret.value
|
|
||||||
end
|
|
||||||
|
|
||||||
test "receives the file_system_created event", %{user: user, node: node} do
|
|
||||||
{hub, headers} = build_team_headers(user, node)
|
|
||||||
|
|
||||||
assert {:ok, _conn} = Connection.start_link(self(), headers)
|
|
||||||
assert_receive :connected
|
|
||||||
|
|
||||||
# creates a new file system
|
|
||||||
file_system = build(:fs_s3, bucket_url: "https://file_system_created.s3.amazonaws.com")
|
|
||||||
assert Livebook.Hubs.create_file_system(hub, file_system) == :ok
|
|
||||||
type = Livebook.FileSystems.type(file_system)
|
|
||||||
%{name: name} = FileSystem.external_metadata(file_system)
|
|
||||||
|
|
||||||
# receives `{:event, :file_system_created, file_system_created}` event
|
|
||||||
# without decrypting the value
|
|
||||||
assert_receive {:event, :file_system_created, file_system_created}
|
|
||||||
assert file_system_created.name == name
|
|
||||||
assert file_system_created.type == to_string(type)
|
|
||||||
refute file_system_created.value == FileSystem.dump(file_system)
|
|
||||||
assert is_binary(file_system_created.value)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "receives the deployment_group_created event", %{user: user, node: node} do
|
|
||||||
{hub, headers} = build_team_headers(user, node)
|
|
||||||
|
|
||||||
assert {:ok, _conn} = Connection.start_link(self(), headers)
|
|
||||||
assert_receive :connected
|
|
||||||
|
|
||||||
# creates a new deployment group with offline mode
|
|
||||||
deployment_group = build(:deployment_group, name: "FOO", mode: :offline, clustering: :dns)
|
|
||||||
|
|
||||||
assert {:ok, _id} =
|
|
||||||
Livebook.Teams.create_deployment_group(hub, deployment_group)
|
|
||||||
|
|
||||||
# deployment_group name and mode are not encrypted
|
|
||||||
assert_receive {:event, :deployment_group_created, deployment_group_created}
|
|
||||||
assert deployment_group_created.name == deployment_group.name
|
|
||||||
assert String.to_existing_atom(deployment_group_created.mode) == deployment_group.mode
|
|
||||||
|
|
||||||
assert String.to_existing_atom(deployment_group_created.clustering) ==
|
|
||||||
deployment_group.clustering
|
|
||||||
|
|
||||||
# since the deployment group is with offline mode, the agent key shouldn't exists
|
|
||||||
assert deployment_group_created.agent_keys == []
|
|
||||||
|
|
||||||
# creates a new deployment group with online mode
|
|
||||||
deployment_group = build(:deployment_group, name: "BAR", mode: :online, clustering: :dns)
|
|
||||||
{:ok, _id} = Livebook.Teams.create_deployment_group(hub, deployment_group)
|
|
||||||
|
|
||||||
# deployment_group name and mode are not encrypted
|
|
||||||
assert_receive {:event, :deployment_group_created, deployment_group_created}
|
|
||||||
assert deployment_group_created.name == deployment_group.name
|
|
||||||
assert String.to_existing_atom(deployment_group_created.mode) == deployment_group.mode
|
|
||||||
|
|
||||||
assert String.to_existing_atom(deployment_group_created.clustering) ==
|
|
||||||
deployment_group.clustering
|
|
||||||
|
|
||||||
# receives the built-in agent key
|
|
||||||
assert [agent_key] = deployment_group_created.agent_keys
|
|
||||||
assert is_binary(agent_key.key)
|
|
||||||
assert agent_key.deployment_group_id == deployment_group_created.id
|
|
||||||
end
|
|
||||||
|
|
||||||
@tag :tmp_dir
|
|
||||||
test "receives the app deployments list from user_connected event",
|
|
||||||
%{user: user, node: node, tmp_dir: tmp_dir} do
|
|
||||||
{hub, headers} = build_team_headers(user, node)
|
|
||||||
|
|
||||||
# creates a new deployment group
|
|
||||||
deployment_group = build(:deployment_group, name: "BAZ", mode: :online)
|
|
||||||
{:ok, id} = Livebook.Teams.create_deployment_group(hub, deployment_group)
|
|
||||||
|
|
||||||
# creates a new app deployment
|
|
||||||
deployment_group_id = to_string(id)
|
|
||||||
slug = Livebook.Utils.random_short_id()
|
|
||||||
title = "MyNotebook3-#{slug}"
|
|
||||||
app_settings = %{Livebook.Notebook.AppSettings.new() | slug: slug}
|
|
||||||
|
|
||||||
notebook = %{
|
|
||||||
Livebook.Notebook.new()
|
|
||||||
| app_settings: app_settings,
|
|
||||||
name: title,
|
|
||||||
hub_id: hub.id,
|
|
||||||
deployment_group_id: deployment_group_id
|
|
||||||
}
|
|
||||||
|
|
||||||
files_dir = Livebook.FileSystem.File.local(tmp_dir)
|
|
||||||
|
|
||||||
{:ok, %Livebook.Teams.AppDeployment{} = app_deployment} =
|
|
||||||
Livebook.Teams.AppDeployment.new(notebook, files_dir)
|
|
||||||
|
|
||||||
# since we want to fetch the app deployment from connection event,
|
|
||||||
# we need to persist it before we connect to the WebSocket
|
|
||||||
:ok = Livebook.Teams.deploy_app(hub, app_deployment)
|
|
||||||
|
|
||||||
assert {:ok, _conn} = Connection.start_link(self(), headers)
|
|
||||||
assert_receive :connected
|
|
||||||
|
|
||||||
assert_receive {:event, :user_connected, user_connected}
|
|
||||||
assert [app_deployment2] = user_connected.app_deployments
|
|
||||||
assert app_deployment2.title == title
|
|
||||||
assert app_deployment2.slug == slug
|
|
||||||
assert app_deployment2.sha == app_deployment.sha
|
|
||||||
assert app_deployment2.deployment_group_id == deployment_group_id
|
|
||||||
end
|
|
||||||
|
|
||||||
@tag :tmp_dir
|
|
||||||
test "receives the app deployments list from agent_connected event",
|
|
||||||
%{user: user, node: node, tmp_dir: tmp_dir} do
|
|
||||||
# To create a new app deployment, we need use the User connection
|
|
||||||
{hub, _headers} = build_team_headers(user, node)
|
|
||||||
|
|
||||||
# creates a new deployment group
|
|
||||||
deployment_group = build(:deployment_group, name: "BAZ", mode: :online)
|
|
||||||
{:ok, id} = Livebook.Teams.create_deployment_group(hub, deployment_group)
|
|
||||||
teams_deployment_group = erpc_call(node, :get_deployment_group!, [id])
|
|
||||||
[teams_agent_key] = teams_deployment_group.agent_keys
|
|
||||||
|
|
||||||
# creates a new app deployment
|
|
||||||
slug = Livebook.Utils.random_short_id()
|
|
||||||
title = "MyNotebook3-#{slug}"
|
|
||||||
app_settings = %{Livebook.Notebook.AppSettings.new() | slug: slug}
|
|
||||||
|
|
||||||
notebook = %{
|
|
||||||
Livebook.Notebook.new()
|
|
||||||
| app_settings: app_settings,
|
|
||||||
name: title,
|
|
||||||
hub_id: hub.id,
|
|
||||||
deployment_group_id: to_string(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
files_dir = Livebook.FileSystem.File.local(tmp_dir)
|
|
||||||
|
|
||||||
{:ok, %Livebook.Teams.AppDeployment{} = app_deployment} =
|
|
||||||
Livebook.Teams.AppDeployment.new(notebook, files_dir)
|
|
||||||
|
|
||||||
# since we want to fetch the app deployment from connection event,
|
|
||||||
# we need to persist it before we connect to the WebSocket
|
|
||||||
:ok = Livebook.Teams.deploy_app(hub, app_deployment)
|
|
||||||
|
|
||||||
# As we need to be Agent to receive the app deployments list to be deployed,
|
|
||||||
# we will create another connection here
|
|
||||||
public_key = hub.org_public_key
|
|
||||||
|
|
||||||
hub = %{
|
|
||||||
hub
|
|
||||||
| user_id: nil,
|
|
||||||
org_public_key: nil,
|
|
||||||
session_token: teams_agent_key.key
|
|
||||||
}
|
|
||||||
|
|
||||||
agent_name = Livebook.Config.agent_name()
|
|
||||||
|
|
||||||
headers = [
|
|
||||||
{"x-lb-version", Livebook.Config.app_version()},
|
|
||||||
{"x-org", to_string(hub.org_id)},
|
|
||||||
{"x-org-key", to_string(hub.org_key_id)},
|
|
||||||
{"x-agent-name", agent_name},
|
|
||||||
{"x-agent-key", hub.session_token}
|
|
||||||
]
|
|
||||||
|
|
||||||
assert {:ok, _conn} = Connection.start_link(self(), headers)
|
|
||||||
assert_receive :connected
|
|
||||||
|
|
||||||
assert_receive {:event, :agent_connected, agent_connected}
|
|
||||||
assert agent_connected.name == agent_name
|
|
||||||
assert agent_connected.public_key == public_key
|
|
||||||
assert [app_deployment2] = agent_connected.app_deployments
|
|
||||||
assert app_deployment2.title == title
|
|
||||||
assert app_deployment2.slug == slug
|
|
||||||
assert app_deployment2.sha == app_deployment.sha
|
|
||||||
assert app_deployment2.deployment_group_id == to_string(id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,9 +1,16 @@
|
||||||
defmodule Livebook.TeamsTest do
|
defmodule Livebook.TeamsTest do
|
||||||
use Livebook.TeamsIntegrationCase, async: true
|
use Livebook.TeamsIntegrationCase, async: true
|
||||||
|
|
||||||
alias Livebook.{Notebook, Teams, Utils}
|
alias Livebook.{FileSystem, Notebook, Teams, Utils}
|
||||||
alias Livebook.Teams.Org
|
alias Livebook.Teams.Org
|
||||||
|
|
||||||
|
setup do
|
||||||
|
Livebook.Hubs.Broadcasts.subscribe([:connection, :file_systems, :secrets])
|
||||||
|
Livebook.Teams.Broadcasts.subscribe([:clients, :deployment_groups, :app_deployments, :agents])
|
||||||
|
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
describe "create_org/1" do
|
describe "create_org/1" do
|
||||||
test "returns the device flow data to confirm the org creation" do
|
test "returns the device flow data to confirm the org creation" do
|
||||||
org = build(:org)
|
org = build(:org)
|
||||||
|
|
@ -161,10 +168,17 @@ defmodule Livebook.TeamsTest do
|
||||||
|
|
||||||
describe "create_deployment_group/2" do
|
describe "create_deployment_group/2" do
|
||||||
test "creates a new deployment group when the data is valid", %{user: user, node: node} do
|
test "creates a new deployment group when the data is valid", %{user: user, node: node} do
|
||||||
team = create_team_hub(user, node)
|
team = connect_to_teams(user, node)
|
||||||
deployment_group = build(:deployment_group)
|
|
||||||
|
|
||||||
assert {:ok, _id} = Teams.create_deployment_group(team, deployment_group)
|
deployment_group =
|
||||||
|
build(:deployment_group, name: "DEPLOYMENT_GROUP_#{team.id}", mode: :online)
|
||||||
|
|
||||||
|
assert {:ok, id} = Teams.create_deployment_group(team, deployment_group)
|
||||||
|
|
||||||
|
%{name: name, mode: mode} = deployment_group
|
||||||
|
id = to_string(id)
|
||||||
|
|
||||||
|
assert_receive {:deployment_group_created, %{id: ^id, name: ^name, mode: ^mode}}
|
||||||
|
|
||||||
# Guarantee uniqueness
|
# Guarantee uniqueness
|
||||||
assert {:error, changeset} = Teams.create_deployment_group(team, deployment_group)
|
assert {:error, changeset} = Teams.create_deployment_group(team, deployment_group)
|
||||||
|
|
@ -172,50 +186,69 @@ defmodule Livebook.TeamsTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns changeset errors when the name is invalid", %{user: user, node: node} do
|
test "returns changeset errors when the name is invalid", %{user: user, node: node} do
|
||||||
team = create_team_hub(user, node)
|
team = connect_to_teams(user, node)
|
||||||
deployment_group = %{build(:deployment_group) | name: ""}
|
deployment_group = %{build(:deployment_group) | name: ""}
|
||||||
|
|
||||||
assert {:error, changeset} = Teams.create_deployment_group(team, deployment_group)
|
assert {:error, changeset} = Teams.create_deployment_group(team, deployment_group)
|
||||||
assert "can't be blank" in errors_on(changeset).name
|
assert "can't be blank" in errors_on(changeset).name
|
||||||
|
refute_receive {:deployment_group_created, _}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns changeset errors when the mode is invalid", %{user: user, node: node} do
|
test "returns changeset errors when the mode is invalid", %{user: user, node: node} do
|
||||||
team = create_team_hub(user, node)
|
team = connect_to_teams(user, node)
|
||||||
deployment_group = %{build(:deployment_group) | mode: "invalid"}
|
deployment_group = %{build(:deployment_group) | mode: "invalid"}
|
||||||
|
|
||||||
assert {:error, changeset} = Teams.create_deployment_group(team, deployment_group)
|
assert {:error, changeset} = Teams.create_deployment_group(team, deployment_group)
|
||||||
assert "is invalid" in errors_on(changeset).mode
|
assert "is invalid" in errors_on(changeset).mode
|
||||||
|
refute_receive {:deployment_group_created, _}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "deploy_app/2" do
|
describe "deploy_app/2" do
|
||||||
@tag :tmp_dir
|
@tag :tmp_dir
|
||||||
test "deploys app to Teams from a notebook", %{user: user, node: node, tmp_dir: tmp_dir} do
|
test "deploys app to Teams from a notebook", %{user: user, node: node, tmp_dir: tmp_dir} do
|
||||||
team = create_team_hub(user, node)
|
team = connect_to_teams(user, node)
|
||||||
deployment_group = build(:deployment_group, name: "BAZ", mode: :online)
|
deployment_group = build(:deployment_group, name: "BAZ", mode: :online)
|
||||||
|
|
||||||
{:ok, id} = Teams.create_deployment_group(team, deployment_group)
|
{:ok, id} = Teams.create_deployment_group(team, deployment_group)
|
||||||
|
|
||||||
app_settings = %{Notebook.AppSettings.new() | slug: Utils.random_short_id()}
|
id = to_string(id)
|
||||||
|
assert_receive {:deployment_group_created, %{id: ^id}}
|
||||||
|
|
||||||
|
# creates the app deployment
|
||||||
|
slug = Utils.random_short_id()
|
||||||
|
title = "MyNotebook-#{slug}"
|
||||||
|
app_settings = %{Notebook.AppSettings.new() | slug: slug}
|
||||||
|
|
||||||
notebook = %{
|
notebook = %{
|
||||||
Notebook.new()
|
Notebook.new()
|
||||||
| app_settings: app_settings,
|
| app_settings: app_settings,
|
||||||
name: "MyNotebook",
|
name: title,
|
||||||
hub_id: team.id,
|
hub_id: team.id,
|
||||||
deployment_group_id: to_string(id)
|
deployment_group_id: id
|
||||||
}
|
}
|
||||||
|
|
||||||
files_dir = Livebook.FileSystem.File.local(tmp_dir)
|
files_dir = FileSystem.File.local(tmp_dir)
|
||||||
|
|
||||||
assert {:ok, app_deployment} = Teams.AppDeployment.new(notebook, files_dir)
|
assert {:ok, app_deployment} = Teams.AppDeployment.new(notebook, files_dir)
|
||||||
assert Teams.deploy_app(team, app_deployment) == :ok
|
assert Teams.deploy_app(team, app_deployment) == :ok
|
||||||
|
|
||||||
|
sha = app_deployment.sha
|
||||||
|
multi_session = app_settings.multi_session
|
||||||
|
access_type = app_settings.access_type
|
||||||
|
|
||||||
|
assert_receive {:app_deployment_started,
|
||||||
|
%Livebook.Teams.AppDeployment{
|
||||||
|
slug: ^slug,
|
||||||
|
sha: ^sha,
|
||||||
|
title: ^title,
|
||||||
|
multi_session: ^multi_session,
|
||||||
|
access_type: ^access_type,
|
||||||
|
deployment_group_id: ^id
|
||||||
|
} = app_deployment2}
|
||||||
|
|
||||||
assert {:error,
|
assert {:error,
|
||||||
%{errors: [slug: {"should only contain alphanumeric characters and dashes", []}]}} =
|
%{errors: [slug: {"should only contain alphanumeric characters and dashes", []}]}} =
|
||||||
Teams.deploy_app(team, %{app_deployment | slug: "@abc"})
|
Teams.deploy_app(team, %{app_deployment | slug: "@abc"})
|
||||||
|
|
||||||
# Since the fields below belongs to AppSettings, we're mapping the errors to `:file` field.
|
|
||||||
assert {:error, %{errors: [multi_session: {"can't be blank", []}]}} =
|
assert {:error, %{errors: [multi_session: {"can't be blank", []}]}} =
|
||||||
Teams.deploy_app(team, %{app_deployment | multi_session: nil})
|
Teams.deploy_app(team, %{app_deployment | multi_session: nil})
|
||||||
|
|
||||||
|
|
@ -224,6 +257,18 @@ defmodule Livebook.TeamsTest do
|
||||||
|
|
||||||
assert {:error, %{errors: [access_type: {"is invalid", []}]}} =
|
assert {:error, %{errors: [access_type: {"is invalid", []}]}} =
|
||||||
Teams.deploy_app(team, %{app_deployment | access_type: :abc})
|
Teams.deploy_app(team, %{app_deployment | access_type: :abc})
|
||||||
|
|
||||||
|
# force app deployment to be stopped
|
||||||
|
erpc_call(node, :toggle_app_deployment, [app_deployment2.id, team.org_id])
|
||||||
|
assert_receive {:app_deployment_stopped, ^app_deployment2}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp connect_to_teams(user, node) do
|
||||||
|
%{id: id} = team = create_team_hub(user, node)
|
||||||
|
assert_receive {:hub_connected, ^id}
|
||||||
|
assert_receive {:client_connected, ^id}
|
||||||
|
|
||||||
|
team
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue