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

Mock Actor merge attempt 2 (see desc) #750

Open
wants to merge 31 commits into
base: main
Choose a base branch
from

Conversation

lor1113
Copy link

@lor1113 lor1113 commented Nov 1, 2024

New merge request made due to manually copying changes into a new branch being seemingly the only way to avoid weird git diff issues.

Description

Added Mock Actor capability.

NOTE: Due to not being able to get dapr-docs running in its own dev container despite repeated attempts (I am simply not a frontend coder so i don't know how to debug all the weird errors it was spitting out), I have not been able to actually view the new documentation within a running instance of the website. I have written it nonetheless using the same templating as the others, as well as basic markdown syntax, but it would be appreciated if someone who has a develop version of the docs website working on their machine could just give it a quick look to make sure it's not somehow broken.

Issue reference

We strive to have all PR being opened based on an issue, where the problem or feature have been discussed prior to implementation.

Please reference the issue this PR will close: #737

Checklist

Please make sure you've completed the relevant tasks for this PR, out of the following list:

  • Code compiles correctly
  • Created/updated tests
  • Extended the documentation

@lor1113 lor1113 requested review from a team as code owners November 1, 2024 21:57
@lor1113 lor1113 mentioned this pull request Nov 1, 2024
3 tasks
Copy link
Contributor

@elena-kolevska elena-kolevska left a comment

Choose a reason for hiding this comment

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

I'm sorry I haven't gotten to this PR yet, we're all really busy with the 1.15 release.
I noticed you renamed one of the docs files. I think we should revert that change, because this .md is shown directly in the dapr docs: https://docs.dapr.io/developing-applications/sdks/python/python-actor/.
Also, please move the new docs you added in the existing page.

Signed-off-by: Lorenzo Curcio <[email protected]>
@lor1113
Copy link
Author

lor1113 commented Nov 11, 2024

@elena-kolevska

The file was renamed such that it would be able to have sub-files, like how the main "Extensions" page under the Python SDK documentation is called "index.md" (https://docs.dapr.io/developing-applications/sdks/python/python-sdk-extensions/) with the idea that the mock actor documentation could be confined to a sub-file for brevity.

Requested changes have been made regardless. It's now simply appended to the end of the current actor documentation.

Signed-off-by: Lorenzo Curcio <[email protected]>
@lor1113
Copy link
Author

lor1113 commented Nov 19, 2024

This should fix the formatting and type issues (with some type:ignores, but I don't think there's a better way without significant work), I also re-ran the tests to make sure they didn't break since I last checked them (worth noting that I do actually get some tests breaking, some random grpc client ones, possibly because I'm just running directly on windows and not using a dev container since it kept breaking for me). All the actor tests + the new ones I added run OK at least.

Copy link

codecov bot commented Nov 19, 2024

Codecov Report

Attention: Patch coverage is 57.73196% with 82 lines in your changes missing coverage. Please review.

Project coverage is 84.92%. Comparing base (bffb749) to head (e17a85b).
Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
dapr/actor/runtime/mock_state_manager.py 49.04% 80 Missing ⚠️
dapr/actor/runtime/state_manager.py 71.42% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #750      +/-   ##
==========================================
- Coverage   86.63%   84.92%   -1.71%     
==========================================
  Files          84       89       +5     
  Lines        4473     4975     +502     
==========================================
+ Hits         3875     4225     +350     
- Misses        598      750     +152     

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


🚨 Try these New Features:

Copy link
Contributor

@elena-kolevska elena-kolevska left a comment

Choose a reason for hiding this comment

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

Looks great @lor1113!
I suggested some text cleanup in the docs (thank you for writing such a detailed guide).
As you had noticed before, there's a bug in the try_add_state method of the state manager, and I already sent a pr here: #756.
Feel free to update your mock to follow the same logic.

Two requests: please add a unit test for the mock state manager and an example for using a mock in the examples directory, that also serves as our suite of integration tests.

Again, great work!

dapr/actor/runtime/mock_actor.py Outdated Show resolved Hide resolved
daprdocs/content/en/python-sdk-docs/python-actor.md Outdated Show resolved Hide resolved
daprdocs/content/en/python-sdk-docs/python-actor.md Outdated Show resolved Hide resolved
daprdocs/content/en/python-sdk-docs/python-actor.md Outdated Show resolved Hide resolved
daprdocs/content/en/python-sdk-docs/python-actor.md Outdated Show resolved Hide resolved
daprdocs/content/en/python-sdk-docs/python-actor.md Outdated Show resolved Hide resolved
daprdocs/content/en/python-sdk-docs/python-actor.md Outdated Show resolved Hide resolved
daprdocs/content/en/python-sdk-docs/python-actor.md Outdated Show resolved Hide resolved
@@ -69,6 +70,9 @@ def __init__(self, actor: 'Actor'):
self._type_name = actor.runtime_ctx.actor_type_info.type_name

self._default_state_change_tracker: Dict[str, StateMetadata] = {}
self._mock_state: Dict[str, Any]
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need this?

Copy link
Author

Choose a reason for hiding this comment

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

If you don't add this, then because of the type hinting problems mentioned earlier, the _mock_state, _mock_reminders and _mock_timer variables won't be correctly type hinted by the IDE, and will show up as white unknown variables.

With those type hint stubs
image

Without

image

Yes the code would still run just fine, but it's not very nice, no?

Type hinting the MockStateManager is of no use, because (as you can see in the image) it thinks the _state_manager variable it is dealing with is an ActorStateManager instead of MockStateManager.

In my view adding these stubs to ActorStateManager is harmless (at least, I cannot think of a scenario where they might cause problems or be undesirable) so I think they're worth having.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm leaning more towards removing the _mock arguments from the main code, and rely on good documentation (which @lor1113 already did) for awareness of the properties' existence. What do you think @berndverst ?

dapr/actor/runtime/mock_state_manager.py Outdated Show resolved Hide resolved
Lorenzo Curcio and others added 4 commits December 3, 2024 10:35
Signed-off-by: Lorenzo Curcio <[email protected]>
Signed-off-by: Elena Kolevska <[email protected]>
Signed-off-by: Lorenzo Curcio <[email protected]>
This reverts commit 254ad17.

Signed-off-by: Lorenzo Curcio <[email protected]>
Fixing bug in try_add_state as mentioned in PR dapr#756

Co-authored-by: Elena Kolevska <[email protected]>
Signed-off-by: Lorenzo Curcio <[email protected]>
Signed-off-by: Lorenzo Curcio <[email protected]>
lor1113 and others added 5 commits December 3, 2024 10:37
Whoops missed this

Co-authored-by: Elena Kolevska <[email protected]>
Signed-off-by: Lorenzo Curcio <[email protected]>
Co-authored-by: Elena Kolevska <[email protected]>
Signed-off-by: Lorenzo Curcio <[email protected]>
Co-authored-by: Elena Kolevska <[email protected]>
Signed-off-by: Lorenzo Curcio <[email protected]>
Co-authored-by: Elena Kolevska <[email protected]>
Signed-off-by: Lorenzo Curcio <[email protected]>
Co-authored-by: Elena Kolevska <[email protected]>
Signed-off-by: Lorenzo Curcio <[email protected]>
lor1113 and others added 6 commits December 3, 2024 10:38
Co-authored-by: Elena Kolevska <[email protected]>
Signed-off-by: Lorenzo Curcio <[email protected]>
Co-authored-by: Elena Kolevska <[email protected]>
Signed-off-by: Lorenzo Curcio <[email protected]>
Co-authored-by: Elena Kolevska <[email protected]>
Signed-off-by: Lorenzo Curcio <[email protected]>
Signed-off-by: Lorenzo Curcio <[email protected]>
Signed-off-by: Lorenzo Curcio <[email protected]>
Copy link
Contributor

@elena-kolevska elena-kolevska left a comment

Choose a reason for hiding this comment

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

here's the fix for the examples test and a few other suggestions. Looking through the other changes now.

examples/demo_actor/demo_actor/test_demo_actor.py Outdated Show resolved Hide resolved
examples/demo_actor/README.md Outdated Show resolved Hide resolved
tests/actor/test_mock_state_manager.py Outdated Show resolved Hide resolved
lor1113 and others added 4 commits December 3, 2024 19:47
Co-authored-by: Elena Kolevska <[email protected]>
Signed-off-by: Lorenzo Curcio <[email protected]>
Signed-off-by: Lorenzo Curcio <[email protected]>
Signed-off-by: Lorenzo Curcio <[email protected]>
didnt see this earlier whoops

Co-authored-by: Elena Kolevska <[email protected]>
Signed-off-by: Lorenzo Curcio <[email protected]>
**The `_on_activate` method will not be called automatically the way it is when Dapr initializes a new Actor instance. You should call it manually as needed as part of your tests.**

The `__init__`, `register_timer`, `unregister_timer`, `register_reminder`, `unregister_reminder` methods are all overwritten by the MockActor class that gets applied as a mixin via `create_mock_actor`. If your actor itself overwrites these methods, those modifications will themselves be overwritten and the actor will likely not behave as you expect.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we suggest a workaround here? For example, creating their own mock actor wrapper, using our mock.

Copy link
Author

Choose a reason for hiding this comment

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

It's a bit hard to think about how to suggest a workaround here, as by definition if someone is overriding those methods they're already doing something pretty out-of-the-box where it's hard to suggest a generic fix. But I did add in something in the latest commit, see if you approve.

### Usage and Limitations

**The `_on_activate` method will not be called automatically the way it is when Dapr initializes a new Actor instance. You should call it manually as needed as part of your tests.**
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this by design, so users can have more control _on_activate? If yes, please mention that.

The actor `_runtime_ctx` variable is set to None. All the normal actor methods have been overwritten such as to not call it, but if your code itself interacts directly with `_runtime_ctx`, it will likely break.

The actor _state_manager is overwritten with an instance of `MockStateManager`. This has all the same methods and functionality of the base `ActorStateManager`, except for using the various `_mock` variables for storing data instead of the `_runtime_ctx`. If your code implements its own custom state manager it will be overwritten and your code will likely break.
Copy link
Contributor

@elena-kolevska elena-kolevska Dec 3, 2024

Choose a reason for hiding this comment

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

your code will likely break

This can sound a bit scary to users :) Let's say "tests may fail" instead.
There was another instance of the same phrasing, I think, I'd update that one too.

examples/demo_actor/README.md Outdated Show resolved Hide resolved
@@ -69,6 +70,9 @@ def __init__(self, actor: 'Actor'):
self._type_name = actor.runtime_ctx.actor_type_info.type_name

self._default_state_change_tracker: Dict[str, StateMetadata] = {}
self._mock_state: Dict[str, Any]
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm leaning more towards removing the _mock arguments from the main code, and rely on good documentation (which @lor1113 already did) for awareness of the properties' existence. What do you think @berndverst ?

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.

[FEATURE REQUEST] Mock actor objects for using testing
2 participants