Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to be compatible with pyfirecreset v2.6.0 #36

Merged
merged 39 commits into from
Jul 30, 2024

Conversation

khsrali
Copy link
Contributor

@khsrali khsrali commented Jun 27, 2024

  • Some TODO's are done
  • Wherever relevant issues opened and addressed in aiida-core, pyfirecrest, and firecrest
  • Added new tests. The old tests, although more sophisticated is harder to debug. New tests focuses only on aiida-firecrest by mocking pyfirecrest only, not firecrest server.
  • Current states still depends on un-merged PR#6043, but functional with latest features of aiida v2.5.2

…aiida-core`.

- Refactor FirecrestScheduler to handle pagination for retrieving active jobs
- dynamic_info() is added to retrieve machine information without user input.
- put & get & copy passed manual test.
- Added `dereference` option wherever relevant
- Added new tests. The old tests, although more suffesticated is harder to debug. New test focuses only on aiida-firecrest by mocking pyfirecrest only, not the server.
bug fix: iglob() is sending relative path to listdir()
compatibility with new version of firecrest: extract() and compress()  will take care of submission if needed
@khsrali khsrali requested a review from agoscinski June 27, 2024 11:46
Copy link
Contributor

@agoscinski agoscinski left a comment

Choose a reason for hiding this comment

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

Did a first skim through the PR, but I need more time to really understand logic.

.pre-commit-config.yaml Outdated Show resolved Hide resolved
aiida_firecrest/remote_path.py Show resolved Hide resolved
aiida_firecrest/scheduler.py Outdated Show resolved Hide resolved
aiida_firecrest/scheduler.py Outdated Show resolved Hide resolved
aiida_firecrest/scheduler.py Show resolved Hide resolved
aiida_firecrest/transport.py Show resolved Hide resolved
aiida_firecrest/utils_test.py Outdated Show resolved Hide resolved
tests/tests_mocking_pyfirecrest/test_transport.py Outdated Show resolved Hide resolved
aiida_firecrest/utils_test.py Outdated Show resolved Hide resolved
pyproject.toml Outdated Show resolved Hide resolved
@khsrali
Copy link
Contributor Author

khsrali commented Jun 28, 2024

Thanks a lot @agoscinski for your review, I'll wait for more comments :)

@khsrali khsrali requested a review from agoscinski July 3, 2024 14:44
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
Copy link
Contributor Author

@khsrali khsrali left a comment

Choose a reason for hiding this comment

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

Thanks @DropD
please let me know if you have more comments

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
Copy link
Contributor

@agoscinski agoscinski left a comment

Choose a reason for hiding this comment

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

There seems some over lap between the files in tests/*py and tests/tests_mocking_pyfirecrest/*py. Can you maybe explain the test files at the top of the files with a docstring more detailed? There seems to be also not a consistent setup between these levels: For example the same function _firecrest_computer is one leve in tests/test_computers.py and one level in tests/tests_mocking_pyfirecrest/conftest.py

.pre-commit-config.yaml Outdated Show resolved Hide resolved
pyproject.toml Outdated Show resolved Hide resolved
aiida_firecrest/scheduler.py Outdated Show resolved Hide resolved
aiida_firecrest/utils_test.py Outdated Show resolved Hide resolved
aiida_firecrest/utils_test.py Outdated Show resolved Hide resolved
aiida_firecrest/utils_test.py Outdated Show resolved Hide resolved
aiida_firecrest/scheduler.py Outdated Show resolved Hide resolved
aiida_firecrest/scheduler.py Show resolved Hide resolved
pyproject.toml Outdated Show resolved Hide resolved
aiida_firecrest/utils_test.py Outdated Show resolved Hide resolved
Copy link
Member

@unkcpz unkcpz left a comment

Choose a reason for hiding this comment

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

Thanks @khsrali . My major concern here is the remove of tests on a mocked firecrest server.
As an alternative you manually reimplement fixtures from Firecrest, which is more flasky. Because any future change make in the server side you need to update your test and can not assure the backward compatibility.

If the docker image of CSCS is not able to use, then maybe push them to fix and report the problem or get the helps?

CHANGELOG.md Outdated Show resolved Hide resolved
README.md Outdated
Client ID: username-client
Client Secret: xyz
Client Machine: daint
Maximum file size for direct transfer (MB) [5.0]:
Temp directory on server: /scratch/something/
Copy link
Member

Choose a reason for hiding this comment

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

Is the something folder provide by CSCS? If it is the folder of user's scratch folder it should be more specific.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a folder that user should allocate in his space for temporary transported files.
I'll add a comment to clarify that.

README.md Outdated


If these tests, pass and still you have trouble in real deployment, that means your installed version of pyfirecrest is behaving differently from what `aiida-firecrest` expects in `MockFirecrest` in `tests/tests_mocking_pyfirecrest/conftest.py`.
If there is no version of `aiida-firecrest` available that supports your `pyfirecrest` version and if down/upgrading your `pyfirecrest` to a supported version is not an option, you might try the following:
Copy link
Member

Choose a reason for hiding this comment

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

What you mean by "your pyfirecrest"? If I understand correctly, pyfirecrest is a dependency of aiida-firecrest and it is the client so it should all controlled from aiida-firecrest side to pinning down or check the API version is compatible.

Comment on lines 35 to 55
computer = orm.Computer(
label="test_computer",
description="test computer",
hostname="-",
workdir=str(_scratch),
transport_type="firecrest",
scheduler_type="firecrest",
)
computer.set_minimum_job_poll_interval(5)
computer.set_default_mpiprocs_per_machine(1)
computer.configure(
url=" https://URI",
token_uri="https://TOKEN_URI",
client_id="CLIENT_ID",
client_secret=str(_secret_path),
client_machine="MACHINE_NAME",
small_file_size_mb=1.0,
temp_directory=str(_temp_directory),
)
computer.store()
return computer
Copy link
Member

Choose a reason for hiding this comment

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

Is aiida-core test computer fixture you can use (check this one https://github.com/aiidateam/aiida-core/blob/de83e2ce43101ddb8b5aeaa5c3e18d1e5c85590a/src/aiida/manage/tests/pytest_fixtures.py#L548)? At least make this an independent fixture, like f7t_computer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, we could use that. What is f7t_computer?

record_requests: bool = request.config.getoption("--firecrest-requests")
telemetry: RequestTelemetry | None = None

if config_path is not None:
Copy link
Member

Choose a reason for hiding this comment

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

Therefore I thought to drop this feature for now, will retrieve later if the docker image is maintained again.

If you drop it "for now", it may not come back anymore. If it is maintained and used by CSCS, should we ask them to fix it?

tests/conftest.py Outdated Show resolved Hide resolved
aiida_firecrest/transport.py Show resolved Hide resolved
aiida_firecrest/transport.py Outdated Show resolved Hide resolved
aiida_firecrest/transport.py Outdated Show resolved Hide resolved
firecrest_url=self._url,
authorization=ClientCredentialsAuth(client_id, secret, token_uri),
)
except Exception as e:
Copy link
Member

Choose a reason for hiding this comment

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

What is the exact error type when it can not connect. This part has two possible exception types, one is when create Auth, the other is when create client? Can you just raise so it propagate directly from pyfirecrest?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, but the whole message {e} is reported, in the next line, (including the actual error type).
I translated everything in one error type for better handling of the plugin later one.
Right now, mainly these errors might raise:
packaging.version.InvalidVersion
requests.exceptions.RequestException

@unkcpz
Copy link
Member

unkcpz commented Jul 17, 2024

As discussed with @khsrali offline, I am fine with removing integration test by using firecrest image to mock some real response. As @khsrali pointed out, pyfirecrest did not do it as well. But I'd suggest to still keep it in mind and open an issue to remember to bring it back with the help from CSCS people to provide a robust and easy to deploy docker-compose solution.

@khsrali khsrali changed the title Upgrade to be compatible with pyfirecreset v2.5.0 Upgrade to be compatible with pyfirecreset v2.6.0 Jul 23, 2024
Copy link
Contributor

@agoscinski agoscinski left a comment

Choose a reason for hiding this comment

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

As discussed with @khsrali offline, I am fine with removing integration test by using firecrest image to mock some real response. As @khsrali pointed out, pyfirecrest did not do it as well. But I'd suggest to still keep it in mind and open an issue to remember to bring it back with the help from CSCS people to provide a robust and easy to deploy docker-compose solution.

Also talked with @khsrali about it. The suggestion we agreed on would be to keep the tests that are used with the deployed the firecrest docker image, but disable it for the moment, since the docker image is outdated and maintenance of it not our job. So the structure would be.

Testing structure:

┌─────────────────┐─────────►┌─────────────┐───►┌───────────────────────┐
│ aiida_firecrest │ disabled │ pyfirecrest │    │ FirecREST demo docker │
└─────────────┬───┘◄─────────└─────────────┘◄───└───────────────────────┘
         ▲    │                                                             
         │    └──────────────►┌─────────────────┐                           
         │                    │ MockPyFirecrest │                           
         └────────────────────└─────────────────┘                           
        
We implememented two ways test aiida_fircrest. One is by mocking pyfirercrest with a `MockPyFirecrest` class.
The second is deploying the `FirecREST docker <https://github.com/eth-cscs/firecrest/tree/master/deploy/demo>`_
image and communicating with it through pyfirercest. Because the the docker image is out-of-date for the moment,
we disabled these tests until it has been updated.

tests/test_calculation.py Show resolved Hide resolved
tests/conftest.py Show resolved Hide resolved
tests/conftest.py Show resolved Hide resolved
.pre-commit-config.yaml Outdated Show resolved Hide resolved
CHANGELOG.md Outdated Show resolved Hide resolved
│ aiida_firecrest │ │ pyfirecrest │ │ FirecREST server │
└─────────────────┘◄───└─────────────┘◄───└──────────────────┘

if `config_path` is not given, it monkeypatches pyfirecrest so we never
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if `config_path` is not given, it monkeypatches pyfirecrest so we never
if no config file is not provided, it monkeypatches pyfirecrest so we never

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The suggestion is an unclear sentence :)

tests/conftest.py Outdated Show resolved Hide resolved
tests/conftest.py Outdated Show resolved Hide resolved
khsrali and others added 2 commits July 29, 2024 19:27
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file is partially moved to conftest.py
Excepts parts that are related to mock FirectREST server.
We now mock pyfirecrest for simplicity.

Copy link

codecov bot commented Jul 30, 2024

Codecov Report

Attention: Patch coverage is 79.17808% with 76 lines in your changes missing coverage. Please review.

Project coverage is 79.94%. Comparing base (eb7f751) to head (7254af5).

Files Patch % Lines
aiida_firecrest/transport.py 82.25% 55 Missing ⚠️
aiida_firecrest/scheduler.py 61.81% 21 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #36      +/-   ##
==========================================
+ Coverage   76.25%   79.94%   +3.68%     
==========================================
  Files           6        4       -2     
  Lines        1057      678     -379     
==========================================
- Hits          806      542     -264     
+ Misses        251      136     -115     
Flag Coverage Δ
pytests 79.94% <79.17%> (+3.68%) ⬆️

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

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

Copy link
Contributor

@agoscinski agoscinski left a comment

Choose a reason for hiding this comment

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

Looks good, almost there, only minor comments.

CHANGELOG.md Outdated Show resolved Hide resolved
CHANGELOG.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated
@@ -195,3 +199,13 @@ although it is of note that you can find these files directly where you your `fi
[codecov-link]: https://codecov.io/gh/aiidateam/aiida-firecrest
[black-badge]: https://img.shields.io/badge/code%20style-black-000000.svg
[black-link]: https://github.com/ambv/black


### :bug: Fishing :bug: Bugs :bug:
Copy link
Contributor

Choose a reason for hiding this comment

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

It is really not a clear title

Suggested change
### :bug: Fishing :bug: Bugs :bug:
### :bug: Reporting bugs

Copy link
Contributor Author

Choose a reason for hiding this comment

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

final offer ### :bug: Fishing Bugs :bug:

tests/test_calculation.py Show resolved Hide resolved
client.mkdir(config.compute_resource, config.workdir, p=True)
client.mkdir(config.compute_resource, config.temp_directory, p=True)

# if record_requests:
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 write some comment here why you have this commented code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, I had added between line 149-151

self.extract = extract
self.copy = copy
self.submit = submit
self.poll_active = poll_active
Copy link
Contributor

@agoscinski agoscinski Jul 30, 2024

Choose a reason for hiding this comment

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

This pattern is a bit weird for me. Cant you move the global functions you set here to the class as methods? So for example

class MockFirecrest:
    def __init__(self, firecrest_url, *args, **kwargs):
        ...
        self.whoami = whoami

def whoami(...):
    ...

->

class MockFirecrest:
    def __init__(self, firecrest_url, *args, **kwargs):
        ...
    def whoami(self, ...):
        ...

Copy link
Contributor

@agoscinski agoscinski Jul 30, 2024

Choose a reason for hiding this comment

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

If the need to be you can mark them as @staticmethod

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @agoscinski for your good suggestion.
I initially defined it this way just to remember what I have mocked and what I haven't mocked.

But now that tests has been developed, we can do it the right way.


if script_remote_path and not Path(script_remote_path).exists():
raise FileNotFoundError(f"File {script_remote_path} does not exist")
job_id = random.randint(10000, 99999)
Copy link
Contributor

Choose a reason for hiding this comment

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

Not exactly sure what you mean @khsrali. Because this is for mocking, the job_id does not matter here? Can't you hardcode it if the number does not matter? Using random without a seed is a pattern that looks like opening the door for surprising behaviors or making debugging harder.

tests/test_scheduler.py Outdated Show resolved Hide resolved
Copy link
Contributor

@agoscinski agoscinski left a comment

Choose a reason for hiding this comment

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

I think it is okay for a merge, since a lot of issues depend on FirecREST and waiting until they are solved would block this PR unnecessary long.

Thanks @khsrali for the work! It was probably quite some annoying debugging.

@khsrali khsrali merged commit 7006d3d into aiidateam:main Jul 30, 2024
7 checks passed
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.

5 participants