-
Notifications
You must be signed in to change notification settings - Fork 27
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
🐛 maintenance/flaky tests #2867
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2867 +/- ##
========================================
- Coverage 78.2% 75.8% -2.4%
========================================
Files 673 680 +7
Lines 27602 27707 +105
Branches 3218 3218
========================================
- Hits 21596 21026 -570
- Misses 5222 5990 +768
+ Partials 784 691 -93
Flags with carried forward coverage won't be shown. Click here to find out more.
|
a944020
to
1ed2070
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please find some questions and comments below.
In the end I did not understand where the issue with the flaky test was. Could you point it out please?
services/web/server/src/simcore_service_webserver/director_v2_core.py
Outdated
Show resolved
Hide resolved
services/web/server/src/simcore_service_webserver/projects/projects_api.py
Outdated
Show resolved
Hide resolved
services/web/server/src/simcore_service_webserver/projects/projects_api.py
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for taking care of this flakyness(es)... please just have a look at my comments
packages/postgres-database/src/simcore_postgres_database/models/users.py
Show resolved
Hide resolved
services/web/server/src/simcore_service_webserver/director/director_api.py
Show resolved
Hide resolved
services/web/server/src/simcore_service_webserver/director_v2_core.py
Outdated
Show resolved
Hide resolved
services/web/server/src/simcore_service_webserver/projects/projects_api.py
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not so sure about how you use suppress. Please check my comment below.
The rest seems fine. 👍
services/web/server/src/simcore_service_webserver/director_v2_core.py
Outdated
Show resolved
Hide resolved
services/web/server/src/simcore_service_webserver/projects/projects_api.py
Outdated
Show resolved
Hide resolved
services/web/server/src/simcore_service_webserver/projects/projects_api.py
Outdated
Show resolved
Hide resolved
91692b2
to
65eeaf8
Compare
0399fa3
to
b853925
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good. Please check my comments.
|
||
# devenv | ||
RUN pip install \ | ||
pydeps |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, this looks nice and helpful. Maybe also pin this version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO a tool (in contrast with a library) should by default always get the latest and greatest ... except if there is a problem, in which we might add constraints.
This is the approach we follow with e.g. package managers like pip etc
# Examples: | ||
# - SEE https://pydeps.readthedocs.io/en/latest/#usage | ||
# | ||
# pydeps services/web/server/src/simcore_service_webserver --only "simcore_service_webserver.projects" --no-show --cluster |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it produces an output, were is that file placed and how would you view it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It creates a svg in the working dir (more details in the doc)
I will attach to the PR the one I was generating to decouple the modules in the project plugin
resource_value, | ||
err, | ||
) | ||
can_remove_all = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why set it to True here, it's already True. What am I missing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, the default is true, then depending on the handler is becomes True or False.
Actually the problem is that I forgot to remove the with suppress(ProjectLockError)
in remove_project_dynamic_services
. I agreed with @sanderegg that it should be raised so the caller can
identify the error instead of silently failing
@@ -188,37 +190,48 @@ async def remove_disconnected_user_resources( | |||
dead_key, | |||
) | |||
|
|||
can_remove_all = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me the name is not helpful? Why not can_remove_project
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not a project what your remove, but resources.
Rationale: the parent function is called remove_disconnected_user_resources
and this variable is can_remove_all
. I think it is pretty clear from the context that it refers to the "resource of a disconnected user"
logger.debug("Deleting user %s with %s", f"{user_id=}", f"{user_role=}") | ||
await remove_user(app=app, user_id=user_id) | ||
|
||
except UserNotFoundError: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why this is silent. Is this correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes.
Until we review the logic in the garbage-collector, the concurrent context in which this task cleans services is pretty wide.
One of the situations is that when this function is called, the user might not even exists .. in which case either get_user_role
or remove_all_projects_for_user
will raise that and therefore, there is nothing else to do...
# Even if any of the steps below fail, the project will remain invisible | ||
# TODO: see https://github.com/ITISFoundation/osparc-simcore/pull/2522 | ||
|
||
await db.set_hidden_flag(f"{project_uuid}", enabled=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can basically hide a project while it is locked. Is this intended? Would it not cause other issues?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that is the basic idea.
Yes, is intended on a temporary basis until the trash feature is in place (as explained in the note)
I did not see any but cannot be 100% sure. In any case it is part of the trash feature so we can even use it as a prototype of it. In addition, it also partially solves the problem of deletion of data since the project is removed from the database last (instead of first as it happened until now).
user_name_data = await get_user_name(app, user_id) | ||
user_role: UserRole = await get_user_role(app, user_id) | ||
|
||
with suppress(ProjectLockError): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, if the project is locked, this will prevent stopping it since an error will break raised and caught by suppress.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After analyzing how remove_project_dynamic_services
is used (and due to it's intrinsic design limitations) I decided to change this behavior in the latest version and avoid silent failures if locked. I leave this way the caller to handle that case. SEE doc of this function for details.
I also agreed on this with @sanderegg
SEE notes in lock_project_and_notify_state_update
services/web/server/src/simcore_service_webserver/projects/projects_db.py
Show resolved
Hide resolved
@ITISFoundation/dev-team After several reviews, this PR will be split in smaller ones. The concept of project_api or in general a "plugin api" has to be reviewed and agreed upon before submitting a new PR. |
What do these changes do?
Tackles this flaky tests:
producing (sometimes) this error
Highlights on changes
projects
plugin:_core_*
modules. This was carefully setup to reduce coupling (see new pydeps tooling added). See (1).projects.projects_handler
modules in two submodules: one for standard methods and the rest (see modules docs).. See (3).projects.projects_api
is a facade module that exposes which functions can be used from other plugins . See (2).projects._core_delete
and reimplemented. NOTE thetprojects_handlers_crud.delete_project
first marks the project as invisible and creates a fire-and-forget task that now deletes the project from the db at the end.scripts/pydeps
tools to visualize dependenciessave_state
flag logic: UsingUserRole
comparison instead ofis_guest_user
to check whether the state shall be saved or not. The logic ofis_guest_user
is not very clear when raise ProgrammationError ... --> marked as deprecated.-[x] 🗑️ removed
models_library/settings/services_common.py
and ♻️ moved toDirectorV2Settings
:director_v2_api
functions including service as dynamic_service because now directorv2 service handles other type of services (and more to come):retrieve
andrequest_retrieve_dyn_service
had the same implementation: nowsafe_/retrieve_dynamic_service_inputs
!!director_v2_service_responses_mock
fixtures and adjustedauto_use
only where justified (explained with NOTE)type: ignore
because of pre-commit error@GitHK I would like to review the logic ofremove_project_interactive_service
as used here with youremove_project_dynamic_services
Related issue/s
How to test
CI tests on postgres and webserver
Checklist
pycln --all
make openapi-specs
,git commit ...
and thenmake version-*
)cd packages/postgres-database
,make setup-commit
,sc-pg review -m "my changes"