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

Add storage exception injection logic into fault injection test runner #4874

Merged
merged 1 commit into from
Aug 28, 2018

Conversation

xiazen
Copy link
Contributor

@xiazen xiazen commented Aug 23, 2018

Adding fault injection test case

  • inject storage exception before store, during Prepare
  • inject storage exception after store, during Prepare
  • inject storage exception before store, during Confirm
  • inject storage exception after store, during Confirm
  • inject storage exception before store, during PrepareAndCommit
  • inject storage exception after store, during PrepareAndCommit

injecting exception before store simulates situation that state update failed to persist
injecting exception after store simulates situation that state update succeed to persist, but runtime think it failed

currently all tests failed... I don't think I have a test logic issue. But please give me a second eye.

{
void BeforeStore();
void AfterStore();
}
Copy link
Member

Choose a reason for hiding this comment

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

Seems odd that a fault injector would be added into the public abstractions package... is there a better way?

Eg, could we generalize this to ITransactionStorageObserver or a name with a similarly general meaning?

Copy link
Member

Choose a reason for hiding this comment

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

Even better, could this be implemented using something like a decorator pattern instead? It seems that we could decorate ITransactionalStateStorage<TState> as-needed and avoid special-casing the code. As a bonus, doing so would remove the class of errors whereby we forget to call the Before/After methods around the Store call.

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 storage exception injection logic is too deep into the implementation, if using decorator pattern, I might need to decorate every class.. I will see what I can do there. may decorate ITransactionalStateStorage is a good alternative. But then we need to decorate different storage provider implementation if we have multiple

@xiazen
Copy link
Contributor Author

xiazen commented Aug 23, 2018

@sebastianburckhardt this is the failed storage exception injection tests I mentioned in the meeting. You can see more on what I described in the meeting here

long? commitUpTo,

// if non-null, abort all pending transactions with sequence numbers strictly larger than this one.
long? abortAfter
Copy link
Member

Choose a reason for hiding this comment

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

Usually doc comments like these would go above the method, like:

/// <summary>
/// Register a timer to send regular callbacks to this grain.
/// This timer will keep the current grain from being deactivated.
/// </summary>
/// <param name="asyncCallback"></param>
/// <param name="state"></param>
/// <param name="dueTime"></param>
/// <param name="period"></param>
/// <param name="name"></param>
/// <returns></returns>

You could include this info there.

public class FaultInjectionAzureTableTransactionStateStorageFactory : ITransactionalStateStorageFactory,
ILifecycleParticipant<ISiloLifecycle>
{
private readonly AzureTableTransactionalStateStorageFactory factory;
Copy link
Member

Choose a reason for hiding this comment

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

Could these be made more generic (I don't know), by resolving types using a different name?
eg, FaultInjectionTransactionStateStorageFactory takes some named options which tell it the name of the factory to use to resolve the transactional storage.

Or similarly, FaultInjectionTransactionStateStorage<TState> could take those options and do the resolution.

That way, we don't need new classes for each one.

As an alternative to options, we could use convention-based registration, like $"{name}_inner" for the type being resolved.

Copy link
Contributor

Choose a reason for hiding this comment

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

We could probably make this more generic, but the fault tolerance of the system should, in theory, be storage independent, so we should really only need to run the storage fault injection tests against a single storage to identify the issues. If we do have a more generic need in the future, we can generalize this at the time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It probably can be made more generic, but currently there's only one type of fault injection tx state used. So more generic version of this doesn't have much usage now. We can make it more generic when we have more than 1 testTxState used in tests.

Copy link
Member

Choose a reason for hiding this comment

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

Sounds good to me

[SkippableFact]
public async Task SingleGrainReadTransaction()
{
const int expected = 5;
Copy link
Contributor

@veikkoeeva veikkoeeva Aug 27, 2018

Choose a reason for hiding this comment

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

This is a nit, but I believe .NET naming conventions calls for capitalizing the first letter in constant variable declarations.

@veikkoeeva
Copy link
Contributor

@xiazen, @ReubenBond Could this point out some insight on how to add fault injection to Orleans in general? It looks to me it would be a useful feature together with #4805 and maybe the overall design would/could converge or take account these.

@ReubenBond
Copy link
Member

@veikkoeeva generally, you can inject faults using grain call filters

@xiazen
Copy link
Contributor Author

xiazen commented Aug 27, 2018

@dotnet-bot test functional please

@ReubenBond
Copy link
Member

Needs rebase

@xiazen xiazen force-pushed the storage-fault-injection branch from 494f28c to 56b63b8 Compare August 27, 2018 23:15
@xiazen
Copy link
Contributor Author

xiazen commented Aug 27, 2018

rebased and squashed for easy rabse. waiting for tests.

@ReubenBond ReubenBond merged commit 85ce296 into dotnet:master Aug 28, 2018
@github-actions github-actions bot locked and limited conversation to collaborators Dec 6, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants