Skip to content

Commit

Permalink
Added ActorReference creation from the ActorBase class informations (#…
Browse files Browse the repository at this point in the history
…1277)

* Handled creation of ActorReference from Actor base class

Signed-off-by: Manuel Menegazzo <[email protected]>

* Updated null check

Signed-off-by: Manuel Menegazzo <[email protected]>

* Added unit test for GetActorReference from null actore and actor proxy

Signed-off-by: Manuel Menegazzo <[email protected]>

* Added test for ActorReference created inside Actor implementation

Signed-off-by: Manuel Menegazzo <[email protected]>

* Updated description

Signed-off-by: Manuel Menegazzo <[email protected]>

* Fixed test method naming

Signed-off-by: Manuel Menegazzo <[email protected]>

* Added unit test for exception generated in case the type is not convertible to an ActorReference

Signed-off-by: Manuel Menegazzo <[email protected]>

---------

Signed-off-by: Manuel Menegazzo <[email protected]>
  • Loading branch information
m3nax authored Jun 26, 2024
1 parent 8496253 commit ddce8a2
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 12 deletions.
30 changes: 18 additions & 12 deletions src/Dapr.Actors/ActorReference.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -16,6 +16,7 @@ namespace Dapr.Actors
using System;
using System.Runtime.Serialization;
using Dapr.Actors.Client;
using Dapr.Actors.Runtime;

/// <summary>
/// Encapsulation of a reference to an actor for serialization.
Expand Down Expand Up @@ -69,23 +70,28 @@ public object Bind(Type actorInterfaceType)

private static ActorReference GetActorReference(object actor)
{
if (actor == null)
{
throw new ArgumentNullException("actor");
}
ArgumentNullException.ThrowIfNull(actor, nameof(actor));

// try as IActorProxy for backward compatibility as customers's mock framework may rely on it before V2 remoting stack.
if (actor is IActorProxy actorProxy)
var actorReference = actor switch
{
return new ActorReference()
// try as IActorProxy for backward compatibility as customers's mock framework may rely on it before V2 remoting stack.
IActorProxy actorProxy => new ActorReference()
{
ActorId = actorProxy.ActorId,
ActorType = actorProxy.ActorType,
};
}
},
// Handle case when we want to get ActorReference inside the Actor implementation,
// we gather actor id and actor type from Actor base class.
Actor actorBase => new ActorReference()
{
ActorId = actorBase.Id,
ActorType = actorBase.Host.ActorTypeInfo.ActorTypeName,
},
// Handle case when we can't cast to IActorProxy or Actor.
_ => throw new ArgumentOutOfRangeException("actor", "Invalid actor object type."),
};

// TODO check for ActorBase
throw new ArgumentOutOfRangeException("actor");
return actorReference;
}
}
}
93 changes: 93 additions & 0 deletions test/Dapr.Actors.Test/ActorReferenceTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using System;
using System.Threading.Tasks;
using Dapr.Actors.Client;
using Dapr.Actors.Runtime;
using Dapr.Actors.Test;
using Xunit;

namespace Dapr.Actors
{
public class ActorReferenceTests
{
[Fact]
public void Get_WhenActorIsNull_ReturnsNull()
{
// Arrange
object actor = null;

// Act
var result = ActorReference.Get(actor);

// Assert
Assert.Null(result);
}

[Fact]
public void Get_FromActorProxy_ReturnsActorReference()
{
// Arrange
var expectedActorId = new ActorId("abc");
var expectedActorType = "TestActor";
var proxy = ActorProxy.Create(expectedActorId, typeof(ITestActor), expectedActorType);

// Act
var actorReference = ActorReference.Get(proxy);

// Assert
Assert.NotNull(actorReference);
Assert.Equal(expectedActorId, actorReference.ActorId);
Assert.Equal(expectedActorType, actorReference.ActorType);
}

[Fact]
public async Task Get_FromActorImplementation_ReturnsActorReference()
{
// Arrange
var expectedActorId = new ActorId("abc");
var expectedActorType = nameof(ActorReferenceTestActor);
var host = ActorHost.CreateForTest<ActorReferenceTestActor>(new ActorTestOptions() { ActorId = expectedActorId });
var actor = new ActorReferenceTestActor(host);

// Act
var actorReference = await actor.GetActorReference();

// Assert
Assert.NotNull(actorReference);
Assert.Equal(expectedActorId, actorReference.ActorId);
Assert.Equal(expectedActorType, actorReference.ActorType);
}

[Fact]
public void Get_WithInvalidObjectType_ThrowArgumentOutOfRangeException()
{
// Arrange
var actor = new object();

// Act
var act = () => ActorReference.Get(actor);

// Assert
var exception = Assert.Throws<ArgumentOutOfRangeException>(act);
Assert.Equal("actor", exception.ParamName);
Assert.Equal("Invalid actor object type. (Parameter 'actor')", exception.Message);
}
}

public interface IActorReferenceTestActor : IActor
{
Task<ActorReference> GetActorReference();
}

public class ActorReferenceTestActor : Actor, IActorReferenceTestActor
{
public ActorReferenceTestActor(ActorHost host)
: base(host)
{
}

public Task<ActorReference> GetActorReference()
{
return Task.FromResult(ActorReference.Get(this));
}
}
}

0 comments on commit ddce8a2

Please sign in to comment.