private async Task ValidateResults(List <ExpectedGrainActivity> txGrains) { await ReportResults(txGrains); foreach (ExpectedGrainActivity activity in txGrains) { var grain = activity.Grain; List <BitArrayState> actual = await grain.Get(); // self consistency check, all resources should be the same BitArrayState first = actual.FirstOrDefault(); Assert.NotNull(first); foreach (BitArrayState result in actual) { Assert.Equal(first.Length, result.Length); Assert.Equal(first.ToString(), result.ToString()); } // Check against expected. // Only need to check if behavior was not ambiguous. // Only need to check first, since we've already verified all resources are the same. var expected = activity.Expected; var unambigous = activity.Unambiguous; Assert.Equal(first.Length, expected.Length); var unambiguousExpected = expected & unambigous; var unambiguousFirst = first & unambigous; var difference = unambiguousFirst ^ unambiguousExpected; if (unambiguousExpected != unambiguousFirst) { this.Log("Inconsistent results:\n" + $"{first} Actual state\n" + $"{expected} Expected state\n" + $"{unambigous} Unambiguous bits\n" + $"{difference} Inconsistencies\n" + $"Grain: {grain}"); } Assert.Equal(unambiguousExpected.ToString(), unambiguousFirst.ToString()); } }
private async Task ValidateResults(List <ExpectedGrainActivity> txGrains) { await Task.WhenAll(txGrains.Select(a => a.GetActual())); this.Log($"Got all {txGrains.Count} actual values"); bool pass = true; int i = 0; foreach (ExpectedGrainActivity activity in txGrains) { BitArrayState expected = activity.Expected; BitArrayState unambiguous = activity.Unambiguous; BitArrayState unambuguousExpected = expected & unambiguous; List <BitArrayState> actual = activity.Actual; BitArrayState first = actual.FirstOrDefault(); if (first == null) { this.Log($"No activity for {i} ({activity.GrainId})"); pass = false; continue; } int j = 0; foreach (BitArrayState result in actual) { // skip comparing first to first. if (ReferenceEquals(first, result)) { continue; } // Check if each state is identical to the first state. var difference = result ^ first; if (difference.Value.Any(v => v != 0)) { this.Log($"Activity on grain {i}, state {j} did not match 'first':\n" + $" {first}\n" + $"^ {result}\n" + $"= {difference}\n" + $"Activation: {activity.GrainId}"); pass = false; } j++; } // Check if the unambiguous portions of the first match. var unambiguousFirst = first & unambiguous; var unambiguousDifference = unambuguousExpected ^ unambiguousFirst; if (unambiguousDifference.Value.Any(v => v != 0)) { this.Log( $"First state on grain {i} did not match 'expected':\n" + $" {unambuguousExpected}\n" + $"^ {unambiguousFirst}\n" + $"= {unambiguousDifference}\n" + $"Activation: {activity.GrainId}"); pass = false; } i++; } this.Log($"Report complete : {pass}"); Assert.True(pass); }