Skip to content

Commit

Permalink
Check that recipe being used to fulfil a recipe exists.
Browse files Browse the repository at this point in the history
  • Loading branch information
mjkw31 committed Oct 29, 2024
1 parent 9276919 commit 4ab2688
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 81 deletions.
16 changes: 12 additions & 4 deletions softpack_core/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,9 @@ async def request_recipe( # type: ignore[no-untyped-def]
+ f'URL: {data["url"]}\n'
+ f'Description: {data["description"]}'
)
msg["Subject"] = f'SoftPack Recipe Request: {data["name"]}@{data["version"]}'
msg[
"Subject"
] = f'SoftPack Recipe Request: {data["name"]}@{data["version"]}'
msg["From"] = recipeConfig["fromAddr"]
msg["To"] = recipeConfig["toAddr"]

Expand All @@ -198,8 +200,9 @@ async def request_recipe( # type: ignore[no-untyped-def]
if recipeConfig["localHostname"] is not None:
localhostname = recipeConfig["localHostname"]


s = smtplib.SMTP(recipeConfig["smtp"], local_hostname=localhostname)
s = smtplib.SMTP(
recipeConfig["smtp"], local_hostname=localhostname
)
s.sendmail(
recipeConfig["fromAddr"],
[recipeConfig["toAddr"]],
Expand Down Expand Up @@ -233,7 +236,12 @@ async def fulfil_recipe( # type: ignore[no-untyped-def]
data["requestedName"], data["requestedVersion"]
)

if r is None:
if r is None or not any(
version == data["version"]
for pkg in app.spack.stored_packages
if pkg.name == data["name"]
for version in pkg.versions
):
return {"error": "Unknown Recipe"}

for env in Environment.iter():
Expand Down
8 changes: 6 additions & 2 deletions softpack_core/spack.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,15 @@ def __init__(self) -> None:
self.versions: list[Package] = list()
self.descriptions: dict[str, str] = dict()

def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None:
def handle_starttag(
self, tag: str, attrs: list[tuple[str, str | None]]
) -> None:
"""Handle open tags."""
if tag == "div":
self.recipe = next(
attr[1] for attr in attrs if attr[0] == "id" and isinstance(attr[1], str)
attr[1]
for attr in attrs
if attr[0] == "id" and isinstance(attr[1], str)
)
elif tag == "dt":
self.onDT = True
Expand Down
194 changes: 119 additions & 75 deletions tests/integration/test_recipe_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
EnvironmentInput,
PackageInput,
)
from softpack_core.spack import Package
from tests.integration.utils import builder_called_correctly

pytestmark = pytest.mark.repo
Expand Down Expand Up @@ -124,82 +125,125 @@ def test_request_recipe(httpx_post, testable_env_input):

httpx_post.assert_not_called()

resp = client.post(
url="/fulfilRequestedRecipe",
json={
"name": "finalRecipe",
"version": "1.2.1",
"requestedName": "a_recipe",
"requestedVersion": "1.2",
},
app.spack.stored_packages.append(
Package(name="finalRecipe", versions=["1.2.1"])
)

assert resp.json() == {"message": "Recipe Fulfilled"}

httpx_post.assert_called_once()

env.name = "my_env-1"
env.packages[1] = PackageInput.from_name("[email protected]")

builder_called_correctly(httpx_post, env)

envs = Environment.iter()

assert len(envs) == 3
assert len(envs[0].packages) == 2
assert envs[0].packages[0].name == "pkg"
assert envs[0].packages[0].version == "1"
assert envs[0].packages[1].name == "finalRecipe"
assert envs[0].packages[1].version == "1.2.1"

resp = client.get(url="/requestedRecipes")

assert resp.json() == [
{
"name": "b_recipe",
"version": "1.4",
"description": "Another description",
"url": "http://example.com",
"username": "me2",
try:
resp = client.post(
url="/fulfilRequestedRecipe",
json={
"name": "finalRecipe",
"version": "1.2.1",
"requestedName": "a_recipe",
"requestedVersion": "1.2",
},
)

assert resp.json() == {"message": "Recipe Fulfilled"}

httpx_post.assert_called_once()

env.name = "my_env-1"
env.packages[1] = PackageInput.from_name("[email protected]")

builder_called_correctly(httpx_post, env)

envs = Environment.iter()

assert len(envs) == 3
assert len(envs[0].packages) == 2
assert envs[0].packages[0].name == "pkg"
assert envs[0].packages[0].version == "1"
assert envs[0].packages[1].name == "finalRecipe"
assert envs[0].packages[1].version == "1.2.1"

resp = client.get(url="/requestedRecipes")

assert resp.json() == [
{
"name": "b_recipe",
"version": "1.4",
"description": "Another description",
"url": "http://example.com",
"username": "me2",
}
]

resp = client.post(
url="/removeRequestedRecipe",
json={"name": "b_recipe", "version": "1.4"},
)

assert resp.json() == {"message": "Request Removed"}

resp = client.get(url="/requestedRecipes")

assert resp.json() == []

resp = client.post(
url="/requestRecipe",
json={
"name": "c_recipe",
"version": "0.9",
"description": "Lorem ipsum.",
"url": "http://example.com",
"username": "me",
},
)

env = EnvironmentInput.from_path("users/me/my_env-2")
env.packages = [
PackageInput.from_name("pkg@1"),
PackageInput.from_name("*[email protected]"),
]

assert isinstance(Environment.create(env), CreateEnvironmentSuccess)

resp = client.post(
url="/removeRequestedRecipe",
json={"name": "c_recipe", "version": "0.9"},
)

assert resp.json() == {
"error": "There are environments relying on this requested recipe;"
+ " can not delete."
}
]

resp = client.post(
url="/removeRequestedRecipe",
json={"name": "b_recipe", "version": "1.4"},
)

assert resp.json() == {"message": "Request Removed"}

resp = client.get(url="/requestedRecipes")

assert resp.json() == []

resp = client.post(
url="/requestRecipe",
json={
"name": "c_recipe",
"version": "0.9",
"description": "Lorem ipsum.",
"url": "http://example.com",
"username": "me",
},
)

env = EnvironmentInput.from_path("users/me/my_env-2")
env.packages = [
PackageInput.from_name("pkg@1"),
PackageInput.from_name("*[email protected]"),
]

assert isinstance(Environment.create(env), CreateEnvironmentSuccess)

resp = client.post(
url="/removeRequestedRecipe",
json={"name": "c_recipe", "version": "0.9"},
)

assert resp.json() == {
"error": "There are environments relying on this requested recipe; "
+ "can not delete."
}
resp = client.post(
url="/fulfilRequestedRecipe",
json={
"name": "no_recipe",
"version": "1",
"requestedName": "c_recipe",
"requestedVersion": "0.9",
},
)

assert resp.json() == {"error": "Unknown Recipe"}

resp = client.post(
url="/fulfilRequestedRecipe",
json={
"name": "finalRecipe",
"version": "1",
"requestedName": "c_recipe",
"requestedVersion": "0.9",
},
)

assert resp.json() == {"error": "Unknown Recipe"}

resp = client.post(
url="/fulfilRequestedRecipe",
json={
"name": "finalRecipe",
"version": "1.2.1",
"requestedName": "c_recipe",
"requestedVersion": "0.9",
},
)

assert resp.json() == {"message": "Recipe Fulfilled"}
finally:
app.spack.stored_packages.pop()

0 comments on commit 4ab2688

Please sign in to comment.