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

Make Actors unit testable #576

Merged
merged 1 commit into from
Feb 1, 2021

Conversation

rynowak
Copy link
Contributor

@rynowak rynowak commented Feb 1, 2021

Description

Changes ActorHost constructor to be public again. Now the state manager
and http interactor are set via properties. This means that code in unit
tests won't be able to cover the methods that interact with timers or
reminders - however this was already the case. Testing state management
is covered by replacing the IActorStateManager with a mock.

Logged an issue to improve this.

Also added validation. If you try to use something that's not fully
initialized it will result in an exception with a meaningful message
instead of a null reference.

Also fixed some sources of indeterminism in our tests. This is still
pretty fragile, but for now the tests will at least be reliable.

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.

Fixes: #573, #574

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

{
throw new InvalidOperationException(
"The actor was initialized without an HTTP client, and so cannot interact with timers or reminders. " +
"This is likely to happen inside a unit test.");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

As described in the issue, this was already impossible to unit test. Now it just fails with a reasonable error message. I logged #575 to track improving this.

@@ -22,21 +22,17 @@ public sealed class ActorHost
/// <param name="jsonSerializerOptions">The <see cref="JsonSerializerOptions"/> to use for actor state persistence and message deserialization.</param>
/// <param name="loggerFactory">The logger factory.</param>
/// <param name="proxyFactory">The <see cref="ActorProxyFactory" />.</param>
/// <param name="daprInteractor">The <see cref="IDaprInteractor" />.</param>
internal ActorHost(
public ActorHost(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Users need to be able to access this for unit testing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks! My earlier change broke this.

var host = new ActorHost(this.ActorTypeInfo, actorId, this.jsonSerializerOptions, this.loggerFactory, this.proxyFactory)
{
DaprInteractor = this.daprInteractor,
StateProvider = new DaprStateProvider(this.daprInteractor, this.jsonSerializerOptions),
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 fix for #575 will be to do the same thing for reminders as we do for state. The Actor class is using the http interactor directly instead of a higher level abstraction, so it's not mockable.

@rynowak rynowak force-pushed the rynowak/release-1.0.0/fix-actor-testing branch from 457dcc2 to de0c7cb Compare February 1, 2021 17:11
Fixes:  #574

Changes ActorHost constructor to be public again. Now the state manager
and http interactor are set via properties. This means that code in unit
tests won't be able to cover the methods that interact with timers or
reminders - however this was already the case. Testing state management
is covered by replacing the `IActorStateManager` with a mock.

Logged an issue to improve this.

Also added validation. If you try to use something that's not fully
initialized it will result in an exception with a meaningful message
instead of a null reference.

Also skips tests that are failing due to #573. We know the cause of why
these are failing, and these tests have not been stable since they were
introduced. Failing additional CI builds is not giving us new
information.
@rynowak rynowak force-pushed the rynowak/release-1.0.0/fix-actor-testing branch from de0c7cb to f5a0807 Compare February 1, 2021 17:24
@codecov
Copy link

codecov bot commented Feb 1, 2021

Codecov Report

Merging #576 (f5a0807) into release-1.0.0 (7f9d23c) will decrease coverage by 4.23%.
The diff coverage is 29.72%.

Impacted file tree graph

@@                Coverage Diff                @@
##           release-1.0.0     #576      +/-   ##
=================================================
- Coverage          65.85%   61.62%   -4.24%     
=================================================
  Files                120      120              
  Lines               3957     3987      +30     
  Branches             436      438       +2     
=================================================
- Hits                2606     2457     -149     
- Misses              1231     1417     +186     
+ Partials             120      113       -7     
Impacted Files Coverage Δ
src/Dapr.Actors/Runtime/Actor.cs 57.50% <0.00%> (-9.17%) ⬇️
src/Dapr.Actors/Runtime/ActorStateManager.cs 7.33% <16.66%> (+1.27%) ⬆️
src/Dapr.Actors/Runtime/ActorHost.cs 83.33% <100.00%> (-2.39%) ⬇️
src/Dapr.Actors/Runtime/ActorManager.cs 50.98% <100.00%> (+1.31%) ⬆️
src/Dapr.Actors/Communication/WrappedMessage.cs 0.00% <0.00%> (-100.00%) ⬇️
...c/Dapr.Actors/Communication/ActorRequestMessage.cs 0.00% <0.00%> (-100.00%) ⬇️
src/Dapr.Actors/Communication/CacheEntry.cs 0.00% <0.00%> (-87.50%) ⬇️
...torMessageBodyDataContractSerializationProvider.cs 4.16% <0.00%> (-54.17%) ⬇️
...tors/Communication/WrappedRequestMessageFactory.cs 0.00% <0.00%> (-50.00%) ⬇️
....Actors/Communication/ActorRequestMessageHeader.cs 0.00% <0.00%> (-47.83%) ⬇️
... and 13 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7f9d23c...f5a0807. Read the comment docs.

@rynowak
Copy link
Contributor Author

rynowak commented Feb 1, 2021

The negative coverage diff is due to skipping tests that have flaky behavior. Restoring these tests is tracked separately.

@rynowak rynowak merged commit 55e0dba into release-1.0.0 Feb 1, 2021
@rynowak rynowak deleted the rynowak/release-1.0.0/fix-actor-testing branch February 1, 2021 19:47
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.

2 participants