internal async Task TestIndexesWithDeactivations <TIGrain, TProperties>(int intAdjustBase = 0)
            where TIGrain : ITestMultiIndexGrain, IIndexableGrain where TProperties : ITestMultiIndexProperties
        {
            using (var tw = new TestConsoleOutputWriter(this.Output, $"start test: TIGrain = {nameof(TIGrain)}, TProperties = {nameof(TProperties)}"))
            {
                // Use intAdjust to test that different values for the same grain type are handled correctly; see MultiIndex_All.
                var          intAdjust       = intAdjustBase * 1000000;
                var          adj1            = intAdjust + 1;
                var          adj11           = intAdjust + 11;
                var          adj111          = intAdjust + 111;
                var          adj1111         = intAdjust + 1111;
                var          adj2            = intAdjust + 2;
                var          adj3            = intAdjust + 3;
                var          adj4            = intAdjust + 4;
                var          adj1000         = intAdjust + 1000;
                var          adj2000         = intAdjust + 2000;
                var          adj3000         = intAdjust + 3000;
                var          adj4000         = intAdjust + 4000;
                var          adjOne          = "one" + intAdjust;
                var          adjEleven       = "eleven" + intAdjust;
                var          adjOneEleven    = "oneeleven" + intAdjust;
                var          adjElevenEleven = "eleveneleven" + intAdjust;
                var          adjTwo          = "two" + intAdjust;
                var          adjThree        = "three" + intAdjust;
                var          adjFour         = "four" + intAdjust;
                var          adj1k           = "1k" + intAdjust;
                var          adj2k           = "2k" + intAdjust;
                var          adj3k           = "3k" + intAdjust;
                var          adj4k           = "4k" + intAdjust;
                const string unindexedString = "unindexed_";

                async Task <TIGrain> makeGrain(int uInt, string uString, int nuInt, string nuString)
                {
                    var grain = this.GetGrain <TIGrain>(GrainPkFromUniqueInt(uInt));
                    await grain.SetUniqueInt(uInt);

                    await grain.SetUniqueString(uString);

                    await grain.SetNonUniqueInt(nuInt);

                    await grain.SetNonUniqueString(nuString);

                    await grain.SetUnIndexedString(unindexedString + uString);

                    return(grain);
                }

                var p1 = await makeGrain(adj1, adjOne, adj1000, adj1k);

                var p11 = await makeGrain(adj11, adjEleven, adj1000, adj1k);

                var p111 = await makeGrain(adj111, adjOneEleven, adj1000, adj1k);

                var p1111 = await makeGrain(adj1111, adjElevenEleven, adj1000, adj1k);

                var p2 = await makeGrain(adj2, adjTwo, adj2000, adj2k);

                var p3 = await makeGrain(adj3, adjThree, adj3000, adj3k);

                // UniqueInt and UniqueString are defined as Unique for non-PerSilo partitioning only; we do not test duplicates here.
                var intIndexes = await this.GetAndWaitForIndexes <int, TIGrain>(ITC.UniqueIntProperty, ITC.NonUniqueIntProperty);

                var isActiveUqInt    = intIndexes[0].GetType().IsActiveIndex();
                var isActiveNonUqInt = intIndexes[1].GetType().IsActiveIndex();
                var stringIndexes    = await this.GetAndWaitForIndexes <string, TIGrain>(ITC.UniqueStringProperty, ITC.NonUniqueStringProperty);

                var isActiveUqString    = stringIndexes[0].GetType().IsActiveIndex();
                var isActiveNonUqString = stringIndexes[1].GetType().IsActiveIndex();

                Assert.Equal(1, await this.GetUniqueIntCount <TIGrain, TProperties>(adj1));
                Assert.Equal(1, await this.GetUniqueIntCount <TIGrain, TProperties>(adj11));
                Assert.Equal(1, await this.GetUniqueStringCount <TIGrain, TProperties>(adjOne));
                Assert.Equal(1, await this.GetUniqueStringCount <TIGrain, TProperties>(adjEleven));
                Assert.Equal(1, await this.GetUniqueIntCount <TIGrain, TProperties>(adj2));
                Assert.Equal(1, await this.GetUniqueIntCount <TIGrain, TProperties>(adj3));
                Assert.Equal(1, await this.GetUniqueStringCount <TIGrain, TProperties>(adjTwo));
                Assert.Equal(1, await this.GetUniqueStringCount <TIGrain, TProperties>(adjThree));
                Assert.Equal(1, await this.GetNonUniqueIntCount <TIGrain, TProperties>(adj2000));
                Assert.Equal(1, await this.GetNonUniqueIntCount <TIGrain, TProperties>(adj3000));
                Assert.Equal(1, await this.GetNonUniqueStringCount <TIGrain, TProperties>(adj2k));
                Assert.Equal(1, await this.GetNonUniqueStringCount <TIGrain, TProperties>(adj3k));

                async Task verifyCount(int expected1, int expected11, int expected1000)
                {
                    Assert.Equal(expected1, await this.GetUniqueIntCount <TIGrain, TProperties>(adj1));
                    Assert.Equal(expected1, await this.GetUniqueStringCount <TIGrain, TProperties>(adjOne));
                    Assert.Equal(isActiveUqInt ? expected11 : 1, await this.GetUniqueIntCount <TIGrain, TProperties>(adj11));
                    Assert.Equal(isActiveUqString ? expected11 : 1, await this.GetUniqueStringCount <TIGrain, TProperties>(adjEleven));
                    Assert.Equal(isActiveNonUqInt ? expected1000 : 4, await this.GetNonUniqueIntCount <TIGrain, TProperties>(adj1000));
                    Assert.Equal(isActiveNonUqString ? expected1000 : 4, await this.GetNonUniqueStringCount <TIGrain, TProperties>(adj1k));
                }

                Console.WriteLine("*** First Verify ***");
                await verifyCount(1, 1, 4);

                Console.WriteLine("*** First Deactivate ***");
                await p11.Deactivate();

                await Task.Delay(ITC.DelayUntilIndexesAreUpdatedLazily);

                Console.WriteLine("*** Second Verify ***");
                await verifyCount(1, 0, 3);

                Console.WriteLine("*** Second and Third Deactivate ***");
                await p111.Deactivate();

                await p1111.Deactivate();

                await Task.Delay(ITC.DelayUntilIndexesAreUpdatedLazily);

                Console.WriteLine("*** Third Verify ***");
                await verifyCount(1, 0, 1);

                Console.WriteLine("*** GetGrain ***");
                p11 = this.GetGrain <TIGrain>(p11.GetPrimaryKeyLong());
                Assert.Equal(adj1000, await p11.GetNonUniqueInt());
                Assert.Equal(unindexedString + adjEleven, await p11.GetUnIndexedString());

                Console.WriteLine("*** Fourth Verify ***");
                await verifyCount(1, 1, 2);

                Console.WriteLine("*** Fifth Verify ***");
                Assert.Equal(1, await this.GetUniqueIntCount <TIGrain, TProperties>(adj3));
                Assert.Equal(1, await this.GetUniqueStringCount <TIGrain, TProperties>(adjThree));
                Assert.Equal(1, await this.GetNonUniqueIntCount <TIGrain, TProperties>(adj3000));
                Assert.Equal(1, await this.GetNonUniqueStringCount <TIGrain, TProperties>(adj3k));

                Console.WriteLine("*** Update 3x to 4x ***");
                await p3.SetUniqueInt(adj4);

                await p3.SetUniqueString(adjFour);

                await p3.SetNonUniqueInt(adj4000);

                await p3.SetNonUniqueString(adj4k);

                Console.WriteLine("*** Sixth Verify ***");
                Assert.Equal(0, await this.GetUniqueIntCount <TIGrain, TProperties>(adj3));
                Assert.Equal(0, await this.GetUniqueStringCount <TIGrain, TProperties>(adjThree));
                Assert.Equal(0, await this.GetNonUniqueIntCount <TIGrain, TProperties>(adj3000));
                Assert.Equal(0, await this.GetNonUniqueStringCount <TIGrain, TProperties>(adj3k));
                Assert.Equal(1, await this.GetUniqueIntCount <TIGrain, TProperties>(adj4));
                Assert.Equal(1, await this.GetUniqueStringCount <TIGrain, TProperties>(adjFour));
                Assert.Equal(1, await this.GetNonUniqueIntCount <TIGrain, TProperties>(adj4000));
                Assert.Equal(1, await this.GetNonUniqueStringCount <TIGrain, TProperties>(adj4k));
            }
        }
Ejemplo n.º 2
0
        internal async Task TestIndexesWithDeactivations <TIGrain, TProperties>(int intAdjust = 0)
            where TIGrain : ITestIndexGrain, IIndexableGrain where TProperties : ITestIndexProperties
        {
            using (var tw = new TestConsoleOutputWriter(this.Output, $"start test: TIGrain = {nameof(TIGrain)}, TProperties = {nameof(TProperties)}"))
            {
                // Use intAdjust to test that different values for the same grain type are handled correctly; see MultiIndex_All.
                var adj1            = intAdjust + 1;
                var adj11           = intAdjust + 11;
                var adj111          = intAdjust + 111;
                var adj1111         = intAdjust + 1111;
                var adj2            = intAdjust + 2;
                var adj3            = intAdjust + 3;
                var adj1000         = intAdjust + 1000;
                var adj2000         = intAdjust + 2000;
                var adj3000         = intAdjust + 3000;
                var adjOne          = "one" + intAdjust;
                var adjEleven       = "eleven" + intAdjust;
                var adjOneEleven    = "oneeleven" + intAdjust;
                var adjElevenEleven = "eleveneleven" + intAdjust;
                var adjTwo          = "two" + intAdjust;
                var adjThree        = "three" + intAdjust;
                var adj1k           = "1k" + intAdjust;
                var adj2k           = "2k" + intAdjust;
                var adj3k           = "3k" + intAdjust;

                Task <TIGrain> makeGrain(int uInt, string uString, int nuInt, string nuString)
                => this.CreateGrain <TIGrain>(uInt, uString, nuInt, nuString);

                var p1 = await makeGrain(adj1, adjOne, adj1000, adj1k);

                var p11 = await makeGrain(adj11, adjEleven, adj1000, adj1k);

                var p111 = await makeGrain(adj111, adjOneEleven, adj1000, adj1k);

                var p1111 = await makeGrain(adj1111, adjElevenEleven, adj1000, adj1k);

                var p2 = await makeGrain(adj2, adjTwo, adj2000, adj2k);

                var p3 = await makeGrain(adj3, adjThree, adj3000, adj3k);

                var intIndexes = await this.GetAndWaitForIndexes <int, TIGrain>(ITC.UniqueIntIndex, ITC.NonUniqueIntIndex);

                var  nonUniqueIntIndexType = intIndexes[1].GetType();
                bool ignoreDeactivate      = typeof(ITotalIndex).IsAssignableFrom(nonUniqueIntIndexType) ||
                                             typeof(IDirectStorageManagedIndex).IsAssignableFrom(nonUniqueIntIndexType);
                var stringIndexes = await this.GetAndWaitForIndexes <string, TIGrain>(ITC.UniqueStringIndex, ITC.NonUniqueStringIndex);

                Assert.Equal(1, await this.GetUniqueStringCount <TIGrain, TProperties>(adjOne));
                Assert.Equal(1, await this.GetUniqueStringCount <TIGrain, TProperties>(adjEleven));
                Assert.Equal(1, await this.GetUniqueIntCount <TIGrain, TProperties>(adj2));
                Assert.Equal(1, await this.GetUniqueIntCount <TIGrain, TProperties>(adj3));
                Assert.Equal(1, await this.GetUniqueStringCount <TIGrain, TProperties>(adjTwo));
                Assert.Equal(1, await this.GetUniqueStringCount <TIGrain, TProperties>(adjThree));
                Assert.Equal(1, await this.GetNonUniqueIntCount <TIGrain, TProperties>(adj2000));
                Assert.Equal(1, await this.GetNonUniqueIntCount <TIGrain, TProperties>(adj3000));
                Assert.Equal(1, await this.GetNonUniqueStringCount <TIGrain, TProperties>(adj2k));
                Assert.Equal(1, await this.GetNonUniqueStringCount <TIGrain, TProperties>(adj3k));

                async Task verifyCount(int expected1, int expected11, int expected1000)
                {
                    Assert.Equal(expected1, await this.GetUniqueIntCount <TIGrain, TProperties>(adj1));
                    Assert.Equal(expected11, await this.GetUniqueIntCount <TIGrain, TProperties>(adj11));
                    Assert.Equal(expected1000, await this.GetNonUniqueIntCount <TIGrain, TProperties>(adj1000));
                    Assert.Equal(expected1000, await this.GetNonUniqueStringCount <TIGrain, TProperties>(adj1k));
                }

                Console.WriteLine("*** First Verify ***");
                await verifyCount(1, 1, 4);

                Console.WriteLine("*** First Deactivate ***");
                await p11.Deactivate();

                await Task.Delay(ITC.DelayUntilIndexesAreUpdatedLazily);

                Console.WriteLine("*** Second Verify ***");
                await verifyCount(1, ignoreDeactivate? 1 : 0, ignoreDeactivate? 4 : 3);

                Console.WriteLine("*** Second and Third Deactivate ***");
                await p111.Deactivate();

                await p1111.Deactivate();

                await Task.Delay(ITC.DelayUntilIndexesAreUpdatedLazily);

                Console.WriteLine("*** Third Verify ***");
                await verifyCount(1, ignoreDeactivate? 1 : 0, ignoreDeactivate? 4 : 1);

                Console.WriteLine("*** GetGrain ***");
                p11 = this.GetGrain <TIGrain>(p11.GetPrimaryKeyLong());
                Assert.Equal(adj1000, await p11.GetNonUniqueInt());
                Console.WriteLine("*** Fourth Verify ***");
                await verifyCount(1, 1, ignoreDeactivate? 4 : 2);
            }
        }
        internal async Task TestEmployeeIndexesWithDeactivations <TIPersonGrain, TPersonProperties, TIJobGrain, TJobProperties, TIEmployeeGrain, TEmployeeProperties>(int intAdjustBase = 0)
            where TIPersonGrain : IIndexableGrain, IPersonGrain, IGrainWithIntegerKey
            where TPersonProperties : IPersonProperties
            where TIJobGrain : IIndexableGrain, IJobGrain, IGrainWithIntegerKey
            where TJobProperties : IJobProperties
            where TIEmployeeGrain : IIndexableGrain, IEmployeeGrain, IGrainWithIntegerKey
            where TEmployeeProperties : IEmployeeProperties
        {
            using (var tw = new TestConsoleOutputWriter(this.Output, $"start test: TIPersonGrain = {nameof(TIPersonGrain)}, TIJobGrain = {nameof(TIJobGrain)}, TIEmployeeGrain = {nameof(TIEmployeeGrain)}"))
            {
                // Use intAdjust to test that different values for the same grain type are handled correctly; see MultiInterface_All.
                const int grainIdBase = 1000000;
                var       intAdjust   = intAdjustBase * grainIdBase;
                var       name1       = $"name_{intAdjust + 1}";
                var       name11      = $"name__{intAdjust + 11}";
                var       name111     = $"name__{intAdjust + 111}";
                var       name1111    = $"name__{intAdjust + 1111}";
                var       name2       = $"name_2_{intAdjust}";
                var       name3       = $"name_3_{intAdjust}";
                var       name4       = $"name_4_{intAdjust}";
                var       age1        = intAdjust + 1;
                var       age2        = intAdjust + 2;
                var       age3        = intAdjust + 3;
                var       age4        = intAdjust + 4;

                var title1    = $"title_{intAdjust + 1}";
                var title11   = $"title_{intAdjust + 11}";
                var title111  = $"title_{intAdjust + 111}";
                var title1111 = $"title_{intAdjust + 1111}";
                var title2    = $"title2_{intAdjust}";
                var title3    = $"title3_{intAdjust}";
                var title4    = $"title4_{intAdjust}";
                var dept1     = $"department_{intAdjust + 1}";
                var dept2     = $"department_{intAdjust + 2}";
                var dept3     = $"department_{intAdjust + 3}";
                var dept4     = $"department_{intAdjust + 4}";

                const int employeeIdBase = grainIdBase * 100;
                int       id             = intAdjust;
                async Task <(TIPersonGrain person, TIJobGrain job, IEmployeeGrain employee)> makeGrain(string name, int age, string title, string dept)
                {
                    var personGrain = this.GetGrain <TIPersonGrain>(GrainPkFromUniqueInt(++id));
                    var transactionalPersistence = personGrain as ITestTransactionalPersistence;

                    if (transactionalPersistence != null)
                    {
                        await transactionalPersistence.InitializeStateTxn();
                    }

                    await personGrain.SetName(name);

                    await personGrain.SetAge(age);

                    var jobGrain = personGrain.Cast <TIJobGrain>();
                    await jobGrain.SetTitle(title);

                    await jobGrain.SetDepartment(dept);

                    var employeeGrain = personGrain.Cast <TIEmployeeGrain>();
                    await employeeGrain.SetEmployeeId(id + employeeIdBase);

                    await employeeGrain.SetSalary(id);  // not indexed

                    await jobGrain.SetDepartment(dept);

                    Task writeGrainAsync()
                    {
                        var selector = id % 3;

                        if (transactionalPersistence != null)
                        {
                            return(transactionalPersistence.WriteStateTxn());
                        }
                        return(selector == 0
                            ? personGrain.WriteState()
                            : (selector == 1) ? jobGrain.WriteState() : employeeGrain.WriteState());
                    }

                    await writeGrainAsync();

                    return(personGrain, jobGrain, employeeGrain);
                }

                var p1 = await makeGrain(name1, age1, title1, dept1);

                var p11 = await makeGrain(name11, age1, title11, dept1);

                var p111 = await makeGrain(name111, age1, title111, dept1);

                var p1111 = await makeGrain(name1111, age1, title1111, dept1);

                var p2 = await makeGrain(name2, age2, title2, dept2);

                var p3 = await makeGrain(name3, age3, title3, dept3);

                // Name and Title are defined as Unique for non-PerSilo partitioning only; we do not test duplicates here.
                // Age and Department may have multiple entries; additionally, they may or may not be of a type that
                // is "Total" -- either TotalIndex or DSMI, in which case deactivations do not really deactivate them.
                var nameIndex = await this.GetAndWaitForIndex <string, TIPersonGrain>(ITC.NameProperty);

                var isActiveName = nameIndex.GetType().IsActiveIndex();
                var ageIndex     = await this.GetAndWaitForIndex <int, TIPersonGrain>(ITC.AgeProperty);

                var isActiveAge = ageIndex.GetType().IsActiveIndex();
                var jobIndexes  = await this.GetAndWaitForIndexes <string, TIJobGrain>(ITC.TitleProperty, ITC.DepartmentProperty);

                var isActiveTitle   = jobIndexes[0].GetType().IsActiveIndex();
                var isActiveDept    = jobIndexes[1].GetType().IsActiveIndex();
                var employeeIdIndex = await this.GetAndWaitForIndex <int, TIEmployeeGrain>(ITC.EmployeeIdProperty);

                var isActiveEmployeeId = employeeIdIndex.GetType().IsActiveIndex();

                Assert.Equal(1, await this.GetNameCount <TIPersonGrain, TPersonProperties>(name1));
                Assert.Equal(1, await this.GetNameCount <TIPersonGrain, TPersonProperties>(name11));
                Assert.Equal(1, await this.GetNameCount <TIPersonGrain, TPersonProperties>(name2));
                Assert.Equal(1, await this.GetNameCount <TIPersonGrain, TPersonProperties>(name3));
                Assert.Equal(1, await this.GetPersonAgeCount <TIPersonGrain, TPersonProperties>(age2));
                Assert.Equal(1, await this.GetPersonAgeCount <TIPersonGrain, TPersonProperties>(age3));

                Assert.Equal(1, await this.GetJobTitleCount <TIJobGrain, TJobProperties>(title1));
                Assert.Equal(1, await this.GetJobTitleCount <TIJobGrain, TJobProperties>(title11));
                Assert.Equal(1, await this.GetJobTitleCount <TIJobGrain, TJobProperties>(title2));
                Assert.Equal(1, await this.GetJobTitleCount <TIJobGrain, TJobProperties>(title3));
                Assert.Equal(1, await this.GetJobDepartmentCount <TIJobGrain, TJobProperties>(dept2));
                Assert.Equal(1, await this.GetJobDepartmentCount <TIJobGrain, TJobProperties>(dept3));

                async Task verifyCount(int expectedDups, int expected11, int expected111, int expected1111)
                {
                    // Verify the duplicated count as well as sanity-checking for some of the non-duplicated ones.
                    Assert.Equal(1, await this.GetNameCount <TIPersonGrain, TPersonProperties>(name1));
                    Assert.Equal(isActiveName ? expected11 : 1, await this.GetNameCount <TIPersonGrain, TPersonProperties>(name11));
                    Assert.Equal(isActiveName ? expected111 : 1, await this.GetNameCount <TIPersonGrain, TPersonProperties>(name111));
                    Assert.Equal(isActiveName ? expected1111 : 1, await this.GetNameCount <TIPersonGrain, TPersonProperties>(name1111));
                    Assert.Equal(1, await this.GetNameCount <TIPersonGrain, TPersonProperties>(name2));
                    Assert.Equal(isActiveAge ? expectedDups : 4, await this.GetPersonAgeCount <TIPersonGrain, TPersonProperties>(age1));
                    Assert.Equal(1, await this.GetPersonAgeCount <TIPersonGrain, TPersonProperties>(age2));

                    Assert.Equal(1, await this.GetJobTitleCount <TIJobGrain, TJobProperties>(title1));
                    Assert.Equal(isActiveTitle ? expected11 : 1, await this.GetJobTitleCount <TIJobGrain, TJobProperties>(title11));
                    Assert.Equal(isActiveTitle ? expected111 : 1, await this.GetJobTitleCount <TIJobGrain, TJobProperties>(title111));
                    Assert.Equal(isActiveTitle ? expected1111 : 1, await this.GetJobTitleCount <TIJobGrain, TJobProperties>(title1111));
                    Assert.Equal(1, await this.GetJobTitleCount <TIJobGrain, TJobProperties>(title2));
                    Assert.Equal(isActiveDept ? expectedDups : 4, await this.GetJobDepartmentCount <TIJobGrain, TJobProperties>(dept1));
                    Assert.Equal(1, await this.GetJobDepartmentCount <TIJobGrain, TJobProperties>(dept2));

                    // EmployeeId is in parallel with expected11(1(1))
                    var employeeId0 = employeeIdBase + intAdjust;

                    Assert.Equal(1, await this.GetEmployeeIdCount <TIEmployeeGrain, TEmployeeProperties>(employeeId0 + 1));
                    Assert.Equal(isActiveEmployeeId ? expected11 : 1, await this.GetEmployeeIdCount <TIEmployeeGrain, TEmployeeProperties>(employeeId0 + 2));
                    Assert.Equal(isActiveEmployeeId ? expected111 : 1, await this.GetEmployeeIdCount <TIEmployeeGrain, TEmployeeProperties>(employeeId0 + 3));
                    Assert.Equal(isActiveEmployeeId ? expected1111 : 1, await this.GetEmployeeIdCount <TIEmployeeGrain, TEmployeeProperties>(employeeId0 + 4));
                }

                Console.WriteLine("*** First Verify ***");
                await verifyCount(4, 1, 1, 1);

                Console.WriteLine("*** First Deactivate ***");
                await p11.person.Deactivate();

                await Task.Delay(ITC.DelayUntilIndexesAreUpdatedLazily);

                Console.WriteLine("*** Second Verify ***");
                await verifyCount(3, 0, 1, 1);

                Console.WriteLine("*** Second and Third Deactivate ***");
                await p111.person.Deactivate();

                await p1111.person.Deactivate();

                await Task.Delay(ITC.DelayUntilIndexesAreUpdatedLazily);

                Console.WriteLine("*** Third Verify ***");
                await verifyCount(1, 0, 0, 0);

                Console.WriteLine("*** GetGrain ***");
                var p11person = this.GetGrain <TIPersonGrain>(p11.person.GetPrimaryKeyLong());
                var p11transactionalPersistence = p11person as ITestTransactionalPersistence;
                await(p11transactionalPersistence != null ? p11transactionalPersistence.InitializeStateTxn() : p11person.InitializeState());

                Assert.Equal(name11, await p11person.GetName());
                var p11job = p11person.Cast <TIJobGrain>();
                Assert.Equal(title11, await p11job.GetTitle());
                var p11employee = p11job.Cast <TIEmployeeGrain>();
                // EmployeeId is incremented in parallel with intAdjust
                Assert.Equal(intAdjust + 2, await p11employee.GetSalary());

                Console.WriteLine("*** Fourth Verify ***");
                await verifyCount(2, 1, 0, 0);

                Console.WriteLine("*** Fifth Verify ***");
                Assert.Equal(1, await this.GetNameCount <TIPersonGrain, TPersonProperties>(name3));
                Assert.Equal(1, await this.GetPersonAgeCount <TIPersonGrain, TPersonProperties>(age3));
                Assert.Equal(1, await this.GetJobTitleCount <TIJobGrain, TJobProperties>(title3));
                Assert.Equal(1, await this.GetJobDepartmentCount <TIJobGrain, TJobProperties>(dept3));

                Console.WriteLine("*** Update 3x to 4x ***");
                await p3.person.SetName(name4);

                await p3.person.SetAge(age4);

                await p3.job.SetTitle(title4);

                await p3.job.SetDepartment(dept4);

                var p3transactionalPersistence = p3.person as ITestTransactionalPersistence;
                await(p3transactionalPersistence != null ? p3transactionalPersistence.WriteStateTxn() : p3.person.WriteState());

                Console.WriteLine("*** Sixth Verify ***");
                Assert.Equal(0, await this.GetNameCount <TIPersonGrain, TPersonProperties>(name3));
                Assert.Equal(0, await this.GetPersonAgeCount <TIPersonGrain, TPersonProperties>(age3));
                Assert.Equal(0, await this.GetJobTitleCount <TIJobGrain, TJobProperties>(title3));
                Assert.Equal(0, await this.GetJobDepartmentCount <TIJobGrain, TJobProperties>(dept3));
                Assert.Equal(1, await this.GetNameCount <TIPersonGrain, TPersonProperties>(name4));
                Assert.Equal(1, await this.GetPersonAgeCount <TIPersonGrain, TPersonProperties>(age4));
                Assert.Equal(1, await this.GetJobTitleCount <TIJobGrain, TJobProperties>(title4));
                Assert.Equal(1, await this.GetJobDepartmentCount <TIJobGrain, TJobProperties>(dept4));
            }
        }