public async Task WriteWithETagViolation() { TestGrainState <EntityWithIntegerKeyWithEtag> grainState = Internal.Utils.CreateAndStoreGrainState <EntityWithIntegerKeyWithEtag>(_serviceProvider); TestGrainReference grainRef = TestGrainReference.Create(grainState.State); // update the database EntityWithIntegerKeyWithEtag clone = grainState.State.Clone(); clone.Title = "Updated"; using (var context = _serviceProvider.GetRequiredService <TestDbContext>()) { context.Entry(clone).State = EntityState.Modified; context.SaveChanges(); } // This should fail grainState.State.Title = "Failing Update"; await Assert.ThrowsAsync <InconsistentStateException>(() => _storage.WriteStateAsync(typeof(GrainWithIntegerKeyWithEtag).FullName, grainRef, grainState)); }
public async Task UpdateCustomGetterGrainState() { var entity = new EntityWithGuidKey(); Internal.Utils.StoreGrainState(_serviceProvider, entity); entity.Title += "UPDATED"; var state = new GrainStateWrapper <EntityWithGuidKey>() { Value = entity }; var grainState = new TestGrainState <GrainStateWrapper <EntityWithGuidKey> >() { State = state }; TestGrainReference grainRef = TestGrainReference.Create(entity); await _storage.WriteStateAsync(typeof(GrainWithCustomStateGuidKey).FullName, grainRef, grainState ); Internal.Utils.AssertEntityEqualityVsDb( _serviceProvider, grainState.State?.Value); }
public async Task ReadCustomGetterGrainStateNoPreCompile() { var entity = new EntityWithGuidKey(); Internal.Utils.StoreGrainState(_serviceProvider, entity); var state = new GrainStateWrapper <EntityWithGuidKey>() { Value = entity }; var grainState = new TestGrainState <GrainStateWrapper <EntityWithGuidKey> >() { State = state }; TestGrainReference grainRef = TestGrainReference.Create(entity); grainState.State = null; await _storage.ReadStateAsync(typeof(GrainWithCustomStateGuidKeyNoPreCompile).FullName, grainRef, grainState ); Internal.Utils.AssertEntityEqualityVsDb( _serviceProvider, grainState.State?.Value); }
public async Task MemoryStorageGrainEnforcesEtagsTest() { var memoryStorageGrain = this.GrainFactory.GetGrain <IMemoryStorageGrain>(random.Next()); // Delete grain state from empty grain, should be safe. await memoryStorageGrain.DeleteStateAsync("stateStore", "grainStoreKey", "eTag"); // Read grain state from empty grain, should be safe, but return nothing. IGrainState grainState = await memoryStorageGrain.ReadStateAsync("stateStore", "grainStoreKey"); Assert.Null(grainState); // write state with etag, when there is nothing in storage. Most storage should fail this, but memory storage should succeed. await memoryStorageGrain.WriteStateAsync("grainType", "grainId", TestGrainState.CreateRandom()); // write new state with null etag string newEtag = await memoryStorageGrain.WriteStateAsync("grain", "id", TestGrainState.CreateWithEtag(null)); Assert.NotNull(newEtag); // try to write new state with null etag; var ex = await Assert.ThrowsAsync <MemoryStorageEtagMismatchException>(() => memoryStorageGrain.WriteStateAsync("grain", "id", TestGrainState.CreateWithEtag(null))); // try to write new state with different etag; ex = await Assert.ThrowsAsync <MemoryStorageEtagMismatchException>(() => memoryStorageGrain.WriteStateAsync("grain", "id", TestGrainState.CreateWithEtag(newEtag + "a"))); // Write new state with good etag; string latestEtag = await memoryStorageGrain.WriteStateAsync("grain", "id", TestGrainState.CreateWithEtag(newEtag)); Assert.NotNull(latestEtag); // try delete state with null etag ex = await Assert.ThrowsAsync <MemoryStorageEtagMismatchException>(() => memoryStorageGrain.DeleteStateAsync("grain", "id", null)); // try delete state with wrong etag ex = await Assert.ThrowsAsync <MemoryStorageEtagMismatchException>(() => memoryStorageGrain.DeleteStateAsync("grain", "id", latestEtag + "a")); // delete state await memoryStorageGrain.DeleteStateAsync("grain", "id", latestEtag); // Read grain deleted grain state, should be safe, but return nothing. grainState = await memoryStorageGrain.ReadStateAsync("grain", "id"); Assert.Null(grainState); // try delete already deleted grain state ex = await Assert.ThrowsAsync <MemoryStorageEtagMismatchException>(() => memoryStorageGrain.DeleteStateAsync("grain", "id", latestEtag)); // try to write state to deleted state. ex = await Assert.ThrowsAsync <MemoryStorageEtagMismatchException>(() => memoryStorageGrain.WriteStateAsync("grain", "id", TestGrainState.CreateWithEtag(latestEtag))); // Make sure we can write new state to a deleted state await memoryStorageGrain.WriteStateAsync("grain", "id", TestGrainState.CreateWithEtag(null)); }
public async Task ReadInvalidConfiguredCustomKeyStateShouldFail() { TestGrainState <InvalidConfiguredEntityWithCustomGuidKey> grainState = Internal.Utils.CreateAndStoreGrainState <InvalidConfiguredEntityWithCustomGuidKey>(_serviceProvider); TestGrainReference grainRef = TestGrainReference.Create <InvalidConfiguredGrainWithGuidKey>(0); await Assert.ThrowsAsync <GrainStorageConfigurationException>(() => _storage.ReadStateAsync( typeof(InvalidConfiguredGrainWithGuidKey).FullName, grainRef, grainState)); }
public async Task ReadTaggedEntityShouldSuccessForNullState() { TestGrainState <EntityWithIntegerKeyWithEtag> grainState = new TestGrainState <EntityWithIntegerKeyWithEtag>(); TestGrainReference grainRef = TestGrainReference.Create <GrainWithIntegerKeyWithEtag>(0); await _storage.ReadStateAsync(typeof(GrainWithIntegerKeyWithEtag).FullName, grainRef, grainState); Assert.Null(grainState.ETag); }
public async Task ReadConfiguredCustomKeyStateShouldPassForGrainsWithSameStateType() { TestGrainState <ConfiguredEntityWithCustomGuidKey> grainState = Internal.Utils.CreateAndStoreGrainState <ConfiguredEntityWithCustomGuidKey>(_serviceProvider); TestGrainReference grainRef = TestGrainReference.Create <ConfiguredGrainWithCustomGuidKey2>( grainState.State.CustomKey, grainState.State.CustomKeyExt); await _storage.ReadStateAsync(typeof(ConfiguredGrainWithCustomGuidKey2).FullName, grainRef, grainState); }
private async Task TestWriteAsync <TGrain, TState, TKey>() where TState : Entity <TKey>, new() where TGrain : Grain <TState> { TestGrainState <TState> grainState = CreateGrainState <TState>(); TestGrainReference grainRef = TestGrainReference.Create(grainState.State); await _storage.WriteStateAsync(typeof(TGrain).FullName, grainRef, grainState ); Internal.Utils.AssertEntityEqualityVsDb(_serviceProvider, grainState.State); }
public async Task StateShoudContainETag() { TestGrainState <EntityWithIntegerKeyWithEtag> grainState = Internal.Utils.CreateAndStoreGrainState <EntityWithIntegerKeyWithEtag>(_serviceProvider); TestGrainReference grainRef = TestGrainReference.Create(grainState.State); await _storage.ReadStateAsync(typeof(GrainWithIntegerKeyWithEtag).FullName, grainRef, grainState); string expected = BitConverter.ToString(grainState.State.ETag) .Replace("-", string.Empty); Assert.Equal(expected, grainState.ETag); }
public async Task ReadTaggedEntityShouldSuccessForNullEtag() { TestGrainState <EntityWithIntegerKeyWithEtag> grainState = Internal.Utils.StoreGrainState <EntityWithIntegerKeyWithEtag>(_serviceProvider, new EntityWithIntegerKeyWithEtag { ETag = null }); TestGrainReference grainRef = TestGrainReference.Create(grainState.State); await _storage.ReadStateAsync(typeof(GrainWithIntegerKeyWithEtag).FullName, grainRef, grainState); Assert.Null(grainState.ETag); }
private async Task TestClearAsync <TGrain, TState, TKey>() where TState : Entity <TKey>, new() where TGrain : Grain <TState> { TestGrainState <TState> grainState = Internal.Utils.CreateAndStoreGrainState <TState>(_serviceProvider); TestGrainReference grainRef = TestGrainReference.Create(grainState.State); await _storage.ClearStateAsync(typeof(TGrain).FullName, grainRef, grainState ); var actual = Internal.Utils.FetchEntityFromDb(_serviceProvider, grainState.State); Assert.Null(actual); }
public async Task SinglePropertyWrite() { TestGrainState <EntityWithIntegerKey> grainState = Internal.Utils.CreateAndStoreGrainState <EntityWithIntegerKey>(_serviceProvider); grainState.State.Title = "Should get updated"; grainState.State.KeyExt = "Should not get updated"; TestGrainReference grainRef = TestGrainReference.Create(grainState.State); GrainStorageContext <EntityWithIntegerKey> .ConfigureEntryState( entry => entry .Property(e => e.Title) .IsModified = true ); await _storage.WriteStateAsync(typeof(GrainWithIntegerKey).FullName, grainRef, grainState); var stored = (EntityWithIntegerKey) Internal.Utils.FetchEntityFromDb(_serviceProvider, grainState.State); Assert.Equal("Should get updated", stored?.Title); Assert.NotEqual("Should not get updated", stored?.KeyExt); GrainStorageContext <EntityWithIntegerKey> .Clear(); // Future updates should update the whole object if not configured await _storage.WriteStateAsync(typeof(GrainWithIntegerKey).FullName, grainRef, grainState); stored = (EntityWithIntegerKey) Internal.Utils.FetchEntityFromDb(_serviceProvider, grainState.State); Assert.Equal(stored, grainState.State); }