Skip to content

Conversation

@unkcpz
Copy link
Member

@unkcpz unkcpz commented Oct 3, 2023

fixes #188

@unkcpz
Copy link
Member Author

unkcpz commented Oct 3, 2023

It is quite hard to test the feature added here since 1) don't know how to test the image_is_latest function which rely on the real image 2) don't know how to test the warning is properly raised in the start stage which are currently in the life cycle test.

I test it manually and works as I expected.

EDIT: the added util function is tested by checking with a light weight image.
EDIT: see the last commit where I tried to test this feature. But has to import the util as a module otherwise the function can not be overridden. Not sure this is proper.

@unkcpz unkcpz requested a review from danielhollas October 3, 2023 21:20
@codecov
Copy link

codecov bot commented Oct 3, 2023

Codecov Report

Attention: 4 lines in your changes are missing coverage. Please review.

Comparison is base (1eedb9d) 86.32% compared to head (5d3cf30) 86.11%.

❗ Current head 5d3cf30 differs from pull request most recent head 42f0867. Consider uploading reports for the commit 42f0867 to get more accurate results

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #193      +/-   ##
==========================================
- Coverage   86.32%   86.11%   -0.21%     
==========================================
  Files           9        9              
  Lines         914      929      +15     
==========================================
+ Hits          789      800      +11     
- Misses        125      129       +4     
Flag Coverage Δ
py-3.10 86.00% <73.33%> (-0.21%) ⬇️
py-3.11 86.00% <73.33%> (-0.21%) ⬇️
py-3.8 85.96% <73.33%> (-0.21%) ⬇️
py-3.9 86.06% <73.33%> (-0.21%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
aiidalab_launch/__main__.py 79.81% <100.00%> (+0.18%) ⬆️
aiidalab_launch/util.py 82.85% <66.66%> (-1.52%) ⬇️

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@unkcpz unkcpz force-pushed the fix/188/warn-when-new-image-avail branch from b884cd9 to e658d11 Compare October 3, 2023 21:34
Copy link
Contributor

@danielhollas danielhollas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thanks for improving this and adding a test!

Just a couple of small suggestions.

def test_image_is_latest(docker_client):
"""Test that the latest version is identified correctly."""
# download the alpine image for testing
image_name = "alpine:latest"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use something more lightweight, perhaps the hello-world image from Docker?

Also, it is not clear to me, is this image then automatically deleted in enable_docker_pull fixture?

Copy link
Member Author

@unkcpz unkcpz Oct 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more lightweight, perhaps the hello-world image from Docker?

👍

is this image then automatically deleted in enable_docker_pull fixture?

No, I don't think so. This fixture is to guarantee the test will be skipped if it contains docker pull.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What a surprise, the hello-world is bigger than alpine. 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh. But that seems to be only true for for windows (which does not exist for Alpine), for linux it is only a couple of kB, i.e. an order of magnitute smaller. So I would still prefer to switch to hello-world image, and mark this test as skipped if ran on windows (I don't think we support windows anyway, but just to ensure we do not end up downloading 100Mb in case anybody tried it).

Also since these tests rely on the network, I would prefer if they were marked as "slow".

image_name = "alpine:latest"
docker_client.images.pull(image_name)

# check that the image is identified as latest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to also test the converse, i.e. pull some outdated version of the same image and check that it is identified as not latest. That should be possible right? (should be a separate test to keep it clean)

Copy link
Member Author

@unkcpz unkcpz Oct 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it can, by pulling the old image and retag it. See the new commit.


if instance.image is None:
raise click.ClickException(
f"Unable to find image '{profile.image}'. "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please delete the line below. We now automatically try to download the image when we do not find it locally, so this advice is not helpful.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, I wasn't aware of it in #184, this conditional never be hit.

@unkcpz unkcpz force-pushed the fix/188/warn-when-new-image-avail branch from 1fabd9f to 42f0867 Compare October 6, 2023 08:27
@unkcpz unkcpz requested a review from danielhollas October 6, 2023 08:29
Copy link
Contributor

@danielhollas danielhollas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @unkcpz, I have a couple more comments. My biggest concern here is to not accidentaly delete all images on the machine. 😰

# there is a new image with the same tag, the id will be different.
# We can not use image id, see https://windsock.io/explaining-docker-image-ids/
local_digest = local_image.attrs.get("RepoDigests")[0].split("@")[-1]
remote_digest = remote_image.attrs.get("Descriptor", {}).get("digest")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the remote_digest ends up being None here? We should probably return true in that case, since that is likely a problem with the Dockerhub and we should not pull. (or it could indicate that the API changed)

# There is no need to check creation date of the image, since the once
# there is a new image with the same tag, the id will be different.
# We can not use image id, see https://windsock.io/explaining-docker-image-ids/
local_digest = local_image.attrs.get("RepoDigests")[0].split("@")[-1]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a little unhappy about the split()[-1] here since that does not seem very robust. But if there is not a better way of getting the digest than I guess it is fine.



@pytest.fixture(scope="function")
def remove_created_images(docker_client):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a little nervous here, how does this ensure that we do not wipe out all the images on the machine? Is that ensured by the docker_client fixture?

Even if it supposedly is, I would be much more comfortable if we filtered the image names somehow (e.g. the image name needs to contain test or some other unique string.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this more, this approach is definitely not safe since, since other processes can create docker images in the meantime while the test is running. The logic here would delete these images.

Instead we could perhaps hard-code the name of the test image (`hello-world"), which should always be safe to delete.

result: Result = runner.invoke(
cli.cli, ["start", "--no-browser", "--no-pull", "--wait=300"]
)
assert "Warning!" in result.output.strip()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you get this assert be a more specific than just "Warning"? That is too generic.
Also please also check the exit code and that the container is up and has already been running, as done above?

assert_status_up()

# test the warning message of image not the latest is not raised
assert "Warning!" not in result.output.strip()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, you could maybe have this assert earlier after the container is first started. Then you could move the monkeypatch above as well and avoid starting up the container for the third time.

def test_image_is_latest(docker_client):
"""Test that the latest version is identified correctly."""
# download the alpine image for testing
image_name = "alpine:latest"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh. But that seems to be only true for for windows (which does not exist for Alpine), for linux it is only a couple of kB, i.e. an order of magnitute smaller. So I would still prefer to switch to hello-world image, and mark this test as skipped if ran on windows (I don't think we support windows anyway, but just to ensure we do not end up downloading 100Mb in case anybody tried it).

Also since these tests rely on the network, I would prefer if they were marked as "slow".

@giovannipizzi
Copy link
Member

I think it's important to have this merged, and/or also probably have some 'hard reset' function that deletes the image? (Now even if I do aiidalab-launch reset it only cleans up data and container, but not the image, so I keep getting the version I had first downloaded. I understand reset is "per-profile" but probably it should also print information as well if there is a new image?) This might be important for the school in 1 month at PSI @mikibonacci @unkcpz @superstar54 @edan-bainglass

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Notify user when new image is available

4 participants