internal bool TransformerCallback()

in Tpm2Tester/TestSubstrate/TestFuzzer.cs [1049:1195]


        internal bool TransformerCallback(CommandInfo info, ref byte[] parmsBuf,
                                        TpmHandle[] inHandles)
        {
            if (parmsBuf.Length == 0 && info.HandleCountIn == 0)
            {
                // There is no sense in fuzzing this command.
                Substrate.Assert(!IsFuzzing);
                SkipRawFuzzer = true;
                return false;
            }

            TpmCc cmdCode = info.CommandCode;

            TimeSpan progressPeriod = new TimeSpan(0, 0, 2);
            DateTime now = DateTime.Now;

            if (!FuzzedCommands.ContainsKey(cmdCode))
            {
                AverageCmdComplexity = AverageCmdComplexity * FuzzedCommands.Count
                                        / (FuzzedCommands.Count + 1);
                FuzzedCommands.Add(cmdCode, new FuzzStats(info));
            }

            FuzzStats cmdStat = FuzzedCommands[cmdCode];

            if (!IsFuzzing)
            {
                // We are not yet fuzzing. Start the next fuzzing series now?

                if (!IsCommandSafe(cmdCode, inHandles))
                {
                    // Fuzzing this command may get theTPM bricked
                    return false;
                }

                if (FuzzCmd == null)
                {
                    if (cmdStat.fuzzSeries == 0)
                    {
                        Threshold = BaseFuzzProbability + (1.0 - 1.0 / (cmdStat.fuzzBypassed + 1))
                                                         * (MaxFuzzProbability - BaseFuzzProbability);
                    }
                    else
                    {
                        if (LastFuzzedCommand != cmdCode)
                        {
                            Threshold = BaseFuzzProbability;
                        }
                        else
                        {
                            // Decrease the chance of fuzzing the same command twice in a row
                            Threshold = MinFuzzProbability
                                      + Threshold * (BaseFuzzProbability - MinFuzzProbability);
                        }

                        AdjustFuzzingProbability(cmdStat);
                    }
                }
                else if (cmdCode.ToString() != FuzzCmd)
                {
                    // Exclusive fuzzing mode: skip all commands but FuzzCmd
                    return false;
                }
                else
                {
                    // Exclusive fuzzing mode uses a random fuzzing probability
                    Threshold = MinFuzzProbability
                              + Globs.GetRandomDouble() * (MaxFuzzProbability - MinFuzzProbability);
                }

                Debug.Assert(Threshold >= MinFuzzProbability && Threshold <= MaxFuzzProbability);

                if (Globs.GetRandomDouble() > Threshold)
                {
                    ++cmdStat.fuzzBypassed;
                    ++TotalFuzzBypasses;
                    return false;
                }

                // Start fuzzing...
                ++TotalFuzzSeries;
                ++cmdStat.fuzzSeries;
                AverageFuzzSeriesPerCmd = (double)TotalFuzzSeries / FuzzedCommands.Count;
                IsFuzzing = true;
                // Ignore test failures from this point until the end of the test case
                MainTestContext.ReportErrors = false;
                CurFuzzCmd = cmdCode;
                CurFuzzingSeriesHadSuccesses = CurFuzzingSeriesHadFailures = false;
                CurFuzzStats = new FuzzStats(info);
                TimeSpan toGo = TestCfg.TestEndTime - now;
                if(toGo < new TimeSpan())
                {
                    toGo = new TimeSpan();
                }
                WriteToLog("Fuzzing {0} ({1} to go) ", cmdCode,
                           toGo.ToString(@"dd\d\ hh\:mm\:ss"), ConsoleColor.Magenta);
                NextProgressReportTime = now + progressPeriod;
                CurFuzzEndTime = now + MaxCommandFuzzTime;
            }

            Debug.Assert(CurFuzzCmd != TpmCc.None);
            Debug.Assert(CurFuzzCmd == cmdCode);

            try
            {
                if (   DoFuzzCommand(cmdStat, ref parmsBuf, inHandles)
                    && SkipRawFuzzer)
                {
                    ++CurFuzzStats.tgtFuzzes;
                }
                else
                {
                    ++CurFuzzStats.rawFuzzes;
                }
            }
            catch (Exception)
            {
                StopFuzzing("!");
                throw;
            }

            uint fuzzCount = CurFuzzStats.tgtFuzzes + CurFuzzStats.rawFuzzes;

            Debug.Assert(fuzzCount - 1 == CurFuzzStats.succeeded + CurFuzzStats.failed);

            // After a while it is better to fuzz something else
            if (now > CurFuzzEndTime || fuzzCount > MaxFuzzCount)
            {
                StopFuzzing("\\");
                throw new EscapeException();
            }

            // Report progress
            if (now > NextProgressReportTime || fuzzCount % (MaxFuzzCount / 20) == 0)
            {
                ReportFuzzProgress();
                NextProgressReportTime = now + progressPeriod;
            }

            if (   FuzzCountToBreak == fuzzCount
                && (cmdCode.ToString() == BreakCmd || BreakCount == fuzzCount))
            {
                // Trigger debug break point
                Debug.Assert("Debug break" == "");
            }
            return true;
        }