Skip to content

Commit

Permalink
Add test for validate worker for handling size profile
Browse files Browse the repository at this point in the history
  • Loading branch information
zacksiri committed Jul 18, 2024
1 parent 21a4661 commit 14e40ea
Show file tree
Hide file tree
Showing 8 changed files with 269 additions and 70 deletions.
5 changes: 4 additions & 1 deletion lib/uplink/packages.ex
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ defmodule Uplink.Packages do
defdelegate get_or_create_project_name(client, metadata),
to: Metadata.Manager

defdelegate get_or_upsert_size_profile(cient, metadata),
defdelegate get_size_profile(metadata),
to: Metadata.Manager

defdelegate upsert_size_profile(metadata),
to: Metadata.Manager

defdelegate profile_name(metadata),
Expand Down
24 changes: 21 additions & 3 deletions lib/uplink/packages/install/validate.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ defmodule Uplink.Packages.Install.Validate do

alias Members.Actor

alias Packages.{
Install
}
alias Packages.Install
alias Packages.Metadata

alias Clients.LXD

Expand Down Expand Up @@ -41,9 +40,28 @@ defmodule Uplink.Packages.Install.Validate do

install
|> Packages.build_install_state(actor)
|> ensure_size_profile_exists()
|> ensure_profile_exists()
end

defp ensure_size_profile_exists(
%{metadata: %Metadata{package_size: nil}} = state
),
do: state

defp ensure_size_profile_exists(
%{metadata: %Metadata{package_size: %Metadata.Size{}} = metadata} =
state
) do
case Packages.upsert_size_profile(metadata) do
{:ok, _} ->
state

{:error, error} ->
raise "Error: #{inspect(error)} occured when attempting to update or create size profile"
end
end

defp ensure_profile_exists(%{
install: install,
metadata: metadata,
Expand Down
3 changes: 1 addition & 2 deletions lib/uplink/packages/instance/bootstrap.ex
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ defmodule Uplink.Packages.Instance.Bootstrap do

profile_name = Packages.profile_name(metadata)

size_profile_name =
Packages.get_or_upsert_size_profile(client, metadata)
size_profile_name = Packages.get_size_profile(metadata)

lxd_project_name = Packages.get_or_create_project_name(client, metadata)

Expand Down
2 changes: 1 addition & 1 deletion lib/uplink/packages/instance/upgrade.ex
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ defmodule Uplink.Packages.Instance.Upgrade do

defp handle_update_config(client, instance, metadata) do
profile_name = Packages.profile_name(metadata)
size_profile_name = Packages.get_or_upsert_size_profile(client, metadata)
size_profile_name = Packages.get_size_profile(metadata)

profiles = [profile_name, "default"]

Expand Down
37 changes: 25 additions & 12 deletions lib/uplink/packages/metadata/manager.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
defmodule Uplink.Packages.Metadata.Manager do
alias Uplink.Packages.Metadata
alias Uplink.Clients.LXD

defdelegate parse(params),
to: Metadata
Expand Down Expand Up @@ -32,14 +33,27 @@ defmodule Uplink.Packages.Metadata.Manager do
end
end

def get_or_upsert_size_profile(_client, %Metadata{package_size: nil}), do: nil
def get_size_profile(%Metadata{package_size: nil}), do: nil

def get_or_upsert_size_profile(
client,
%Metadata{package_size: %Metadata.Size{}} = metadata
) do
def get_size_profile(%Metadata{} = metadata) do
size_profile = size_profile_name(metadata)

LXD.client()
|> Lexdee.get_profile(size_profile)
|> case do
{:ok, %{body: %{"name" => _name}}} ->
size_profile

{:error, %{"error_code" => 404}} ->
nil
end
end

def upsert_size_profile(%Metadata{package_size: %Metadata.Size{}} = metadata) do
size_profile = size_profile_name(metadata)

client = LXD.client()

client
|> Lexdee.get_profile(size_profile)
|> case do
Expand Down Expand Up @@ -79,16 +93,15 @@ defmodule Uplink.Packages.Metadata.Manager do

defp create_size_profile(client, %Metadata{} = metadata) do
profile_params = build_size_config(metadata)
profile_name = profile_params["name"]

client
|> Lexdee.create_profile(profile_params)
|> case do
{:ok, %{body: nil}} ->
profile_name
{:ok, :size_profile_created}

{:error, %{"error" => _message}} ->
nil
{:error, %{"error" => message}} ->
{:error, message}
end
end

Expand All @@ -102,10 +115,10 @@ defmodule Uplink.Packages.Metadata.Manager do
|> Lexdee.update_profile(profile_name, profile_params)
|> case do
{:ok, %{body: _body}} ->
profile_name
{:ok, :size_profile_updated}

{:error, %{"error" => _message}} ->
nil
{:error, %{"error" => message}} ->
{:error, message}
end
end

Expand Down
207 changes: 207 additions & 0 deletions test/uplink/packages/install/validate_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -195,4 +195,211 @@ defmodule Uplink.Packages.Install.ValidateTest do
assert install.current_state == "executing"
end
end

@deployment_params_with_package_size %{
"hash" => "some-hash-with-package-size",
"archive_url" => "http://localhost/archives/packages.zip",
"stack" => "alpine/3.14",
"channel" => "develop",
"metadata" => %{
"id" => 1,
"slug" => "uplink-web",
"service_port" => 4000,
"exposed_port" => 49152,
"package_size" => %{
"slug" => "medium",
"allocation" => %{
"cpu" => 1,
"cpu_allowance" => "100%",
"cpu_priority" => 10,
"memory" => 1,
"memory_unit" => "GiB",
"memory_swap" => false,
"memory_enforce" => "hard"
}
},
"channel" => %{
"slug" => "develop",
"package" => %{
"slug" => "something-1640927800",
"credential" => %{
"public_key" => "public_key"
},
"organization" => %{
"slug" => "upmaru"
}
}
},
"instances" => [
%{
"id" => 1,
"slug" => "something-1",
"node" => %{
"slug" => "some-node"
}
}
]
}
}

describe "with package size" do
setup %{actor: actor} do
create_profile = File.read!("test/fixtures/lxd/profiles/create.json")

metadata = Map.get(@deployment_params_with_package_size, "metadata")

{:ok, metadata} = Packages.parse_metadata(metadata)

app =
metadata
|> Metadata.app_slug()
|> Packages.get_or_create_app()

{:ok, deployment} =
Packages.get_or_create_deployment(
app,
@deployment_params_with_package_size
)

{:ok, install} =
Packages.create_install(deployment, %{
"installation_id" => 1,
"deployment" => @deployment_params_with_package_size
})

signature = compute_signature(deployment.hash)

Cache.put(
{:deployment, signature, install.instellar_installation_id},
metadata
)

{:ok, %{resource: validating_install}} =
Packages.transition_install_with(install, actor, "validate")

size_profile =
"size.#{metadata.channel.package.organization.slug}.#{metadata.channel.package.slug}.#{validating_install.metadata_snapshot.package_size.slug}"

{:ok,
install: validating_install,
deployment: deployment,
metadata: metadata,
create_profile: create_profile,
size_profile: size_profile}
end

test "can create app profile and size profile", %{
bypass: bypass,
install: install,
actor: actor,
list_profiles: list_profiles,
size_profile: size_profile
} do
size_profile_not_found =
File.read!("test/fixtures/lxd/profiles/not_found.json")

Bypass.expect_once(
bypass,
"GET",
"/1.0/profiles/#{size_profile}",
fn conn ->
conn
|> Plug.Conn.put_resp_header("content-type", "application/json")
|> Plug.Conn.resp(404, size_profile_not_found)
end
)

create_profile = File.read!("test/fixtures/lxd/profiles/create.json")

Bypass.expect(
bypass,
"POST",
"/1.0/profiles",
fn conn ->
conn
|> Plug.Conn.put_resp_header("content-type", "application/json")
|> Plug.Conn.resp(200, create_profile)
end
)

Bypass.expect_once(bypass, "GET", "/1.0/profiles", fn conn ->
conn
|> Plug.Conn.put_resp_header("content-type", "application/json")
|> Plug.Conn.resp(200, list_profiles)
end)

assert {:ok, %{resource: install}} =
perform_job(Validate, %{
install_id: install.id,
actor_id: actor.id
})

assert install.current_state == "executing"
end

test "can update app profile and size profile", %{
bypass: bypass,
install: install,
metadata: metadata,
actor: actor,
size_profile: size_profile
} do
list_profiles =
File.read!("test/fixtures/lxd/profiles/list_profile_exists.json")

update_profile = File.read!("test/fixtures/lxd/profiles/update.json")

profile_name = Packages.profile_name(metadata)

Bypass.expect_once(bypass, "GET", "/1.0/profiles", fn conn ->
conn
|> Plug.Conn.put_resp_header("content-type", "application/json")
|> Plug.Conn.resp(200, list_profiles)
end)

size_profile_response =
File.read!("test/fixtures/lxd/profiles/show_size_profile.json")

Bypass.expect_once(
bypass,
"GET",
"/1.0/profiles/#{size_profile}",
fn conn ->
conn
|> Plug.Conn.put_resp_header("content-type", "application/json")
|> Plug.Conn.resp(200, size_profile_response)
end
)

Bypass.expect_once(
bypass,
"PATCH",
"/1.0/profiles/#{profile_name}",
fn conn ->
conn
|> Plug.Conn.put_resp_header("content-type", "application/json")
|> Plug.Conn.resp(200, update_profile)
end
)

Bypass.expect_once(
bypass,
"PATCH",
"/1.0/profiles/#{size_profile}",
fn conn ->
conn
|> Plug.Conn.put_resp_header("content-type", "application/json")
|> Plug.Conn.resp(200, update_profile)
end
)

assert {:ok, %{resource: install}} =
perform_job(Validate, %{
install_id: install.id,
actor_id: actor.id
})

assert install.current_state == "executing"
end
end
end
Loading

0 comments on commit 14e40ea

Please sign in to comment.