OrleansContrib/OrleansTestKit

Calling this.GetPrimaryKey() from base class is failing

keithazzopardi opened this issue · 2 comments

I have a grain which is inheriting from a GrainBase. In the GrainBase I have a method which is using this.GetPrimaryKey() to perform another operation. I'm having the following error on this.GetPrimaryKey() when running the tests only.

Message: System.ArgumentException : Passing a half baked grain as an argument. It is possible that you instantiated a grain class explicitly, as a regular object and not via Orleans runtime or via proper test mocking
Parameter name: grain

Thanks for the report, @keithazzopardi. Is it possible for you to create and share some example code that reproduces the issue?

Digging into Orleans... I found the following GrainExtensions code:

...

var grainBase = grain as Grain;
if (grainBase != null)
{
    if (grainBase.Data == null || grainBase.Data.Identity == null)
    {
        throw new ArgumentException(WRONG_GRAIN_ERROR_MSG, "grain");
    }
    return grainBase.Data.Identity;
}

...

The grainBase.Data == null check leads to the error message you cite. And that appears problematic for the test kit based on the definition of Grain.Data:

// Do not use this directly because we currently don't provide a way to inject it;
// any interaction with it will result in non unit-testable code. Any behaviour that can be accessed 
// from within client code (including subclasses of this class), should be exposed through IGrainRuntime.
// The better solution is to refactor this interface and make it injectable through the constructor.
internal IActivationData Data;

Check out dotnet/orleans#3086 and dotnet/orleans#3145. I think we may be stuck.

Now, it doesn't look like all GetPrimaryKey extension methods/overloads call the above code path. While far from ideal, it may be possible to get things working with implementation changes that force a different code path. I'm going to close this issue as it appears to be a limitation upstream. However, feel free to reopen this issue with some example code if you want to explore the possibilility of getting it work with code changes.