示例#1
0
        public ConsistencyTestHarness(
            IGrainFactory grainFactory,
            int numGrains,
            int seed,
            bool avoidDeadlocks,
            bool avoidTimeouts,
            ReadWriteDetermination readWrite,
            bool tolerateUnknownExceptions)
        {
            this.grainFactory = grainFactory;

            numGrains.Should().BeLessThan(ConsistencyTestOptions.MaxGrains);
            this.options = new ConsistencyTestOptions()
            {
                AvoidDeadlocks = avoidDeadlocks,
                ReadWrite      = readWrite,
                MaxDepth       = 5,
                NumGrains      = numGrains,
                RandomSeed     = seed,
                AvoidTimeouts  = avoidTimeouts,
                GrainOffset    = (DateTime.UtcNow.Ticks & 0xFFFFFFFF) * ConsistencyTestOptions.MaxGrains,
            };

            this.tuples    = new Dictionary <int, SortedDictionary <int, Dictionary <string, HashSet <string> > > >();
            this.succeeded = new HashSet <string>();
            this.aborted   = new HashSet <string>();
            this.indoubt   = new Dictionary <string, string>();

            // determine what to check for in the end
            this.tolerateUnknownExceptions = tolerateUnknownExceptions;
        }
示例#2
0
        public virtual async Task RandomizedConsistency(int numGrains, int scale, bool avoidDeadlocks, bool avoidTimeouts, ReadWriteDetermination readwrite)
        {
            var random = new Random(scale + numGrains * 1000 + (avoidDeadlocks ? 666 : 333) + ((int)readwrite) * 123976);

            var harness = new ConsistencyTestHarness(grainFactory, numGrains, random.Next(), avoidDeadlocks, avoidTimeouts, readwrite, StorageErrorInjectionActive);

            // first, run the random work load to generate history events
            testOutput($"start at {DateTime.UtcNow}");
            int numThreads      = scale;
            int numTxsPerThread = scale * scale;

            // start the threads that run transactions
            var tasks = new Task[numThreads];

            for (int i = 0; i < numThreads; i++)
            {
                tasks[i] = harness.RunRandomTransactionSequence(i, numTxsPerThread, grainFactory, this.testOutput);
            }

            // wait for the test to finish
            await Task.WhenAll(tasks);

            testOutput($"end at {DateTime.UtcNow}");

            // golden path: all transactions are expected to pass when avoiding deadlocks and lock upgrades
            if (!StorageErrorInjectionActive &&
                avoidDeadlocks &&
                (readwrite == ReadWriteDetermination.PerGrain || readwrite == ReadWriteDetermination.PerTransaction))
            {
                harness.NumAborted.Should().Be(0);
            }

            // then, analyze the history results
            var tolerateGenericTimeouts   = StorageErrorInjectionActive || (scale >= 3 && !avoidTimeouts);
            var tolerateUnknownExceptions = StorageAdaptorHasLimitedCommitSpace || StorageErrorInjectionActive;

            harness.CheckConsistency(tolerateGenericTimeouts, tolerateUnknownExceptions);
        }
 public override Task RandomizedConsistency(int numGrains, int scale, bool avoidDeadlocks,
                                            bool avoidTimeouts, ReadWriteDetermination readwrite)
 {
     return(base.RandomizedConsistency(numGrains, scale, avoidDeadlocks, avoidTimeouts, readwrite));
 }