unit uOSMarkSuite;
{
  COSBI: Comprehensive Open Source Benchmarking Initiative
  Copyright (c) 2004 Van Smith

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

  The current web address of the GNU General Public License is:
  http://www.gnu.org/licenses/gpl.html

  You can contact the authors of this software at:
  cosbi@vanshardware.com
  See www.vanshardware.com or www.cosbi.org for more contact details.
}

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls, Grids, COSBI_Common, GR32_Blend, GR32_Image,
  GR32, ComCtrls, Gauges, Maze, uCOSBI_TTest, uCOSBI_TGraphicsTest, uOutput,
  uTests, Dhrystone, Whetstone, math, uCOSBI_SystemInfo, COSBI_Status;

Type

  TQTestSet = set of TQTests;

  TOSMarkTestResult = record
    TestType : TQTests;
    TestName : string;
    TestTime : double;
    TestScore : double;
    TestRawScore : double;
    TestRawUnits  : string;
  end; // TOSMarkTestResult = record

  TOSMarkTestResultArray = array of TOSMarkTestResult;

  TOSMarkTestResults = class( TComponent )
  private
    fOfficialRun : Boolean;
  protected
    fTestResults : TOSMarkTestResultArray;
    fHardwareInfo : THardwareInfo;
    fOsInfo : TOS_Info;
    fSystemInfo : TSystemInfo;
    fRunDateTime : TDateTime;
  public
    constructor Create( AOwner : TComponent ); override;
    procedure Initialize( aSystemInfo: TSystemInfo );
    function GetBestScore( aQTest : TQTests ): double;
    function GetAverageScore( aQTest : TQTests ): double;
    function GetWorstScore( aQTest : TQTests ): double;
    function GetCosbiScore(abGeometricMean : Boolean): double;
    function GetBestTime( aQTest : TQTests ): double;
    function GetAverageTime( aQTest : TQTests ): double;
    function GetWorstTime( aQTest : TQTests ): double;
    function GetBestResult( aQTest : TQTests ): string;
    function GetBestSuiteResults( aQTestSet : TQTestSet ): string;
    procedure AddResult( aTestResult : TOSMarkTestResult );
    property TestResults: TOSMarkTestResultArray read fTestResults;
    property OfficialRun : Boolean read fOfficialRun write fOfficialRun;
    property SystemInfo : TSystemInfo read fSystemInfo write fSystemInfo;
    property HardwareInfo : THardwareInfo read fHardwareInfo;
    property OsInfo : TOS_Info read fOsInfo;
    property RunDateTime : TDateTime read fRunDateTime write fRunDateTime;
  end; //TOSMarkTestResults

  TOSMarkTestSuite = Class( TComponent )
  private
  protected
    fStopWatch            : TStopwatch;
    fSelectedTests        : TQTestSet;
    fSelectAll            : Boolean;
    fOfficialRun          : Boolean;
    fOSMarkTestResults    : TOSMarkTestResults;
    fSystemInfo : TSystemInfo;
    fShowStatus : Boolean;
    fSpinUp : Boolean;
    fProcessIdleTasks : Boolean;
    fDiskDefrag : Boolean;
    fTargetDisk : char;
    fOutputString : string;
    fOnOutputString : TNotifyEvent;
    fTestName : string;
    fIteration : integer;
    fIterationFinal : integer;
    fOnTestBegins : TNotifyEvent;
    fTestScore : integer;
    fTestTime  : double;
    fOnTestEnds : TNotifyEvent;
    fTotalNumberOfTestsToRun : integer;
    fOnNumberOfTestToRun : TNotifyEvent;
    fOnTestSuiteRunStart : TNotifyEvent;
    fOnTestSuiteRunEnd : TNotifyEvent;
    fOnIterationStart : TNotifyEvent;
    fOnIterationEnd : TNotifyEvent;
    function CountTests   : integer;
    procedure TestSuiteRun( aiRunCount : integer );
    procedure OutputResultHeader( aiIterations : integer );
    procedure OutputSuiteResultHeader( aiIterations : integer );
    procedure OutputResultFooter;
    procedure LogResults( aQuickTest: TTest );
    procedure RunTest( var aTest : TTest;
                       aiRunCount : integer );
    procedure SetSystemInfo( Value : TSystemInfo );
  public
    constructor Create( AOwner : TComponent ); override;
    procedure Initialize( aSystemInfo: TSystemInfo);
    destructor Destroy; Override;
    procedure OutString( asOutputString : string );
    procedure RunTheseTests( aQTSet: TQTestSet; aiIterations: integer );
    procedure OfficialRun;
    procedure HandleDiskDefrag;
    procedure HandleProcessIdleTasks;
    procedure CheckDriveSpace;
    property SelectAll : Boolean read fSelectAll write fSelectAll;
    property SelectedTests : TQTestSet read fSelectedTests
                                       write fSelectedTests;
    property OSMarkTestResults : TOSMarkTestResults
                           read fOSMarkTestResults
                           write fOSMarkTestResults;
    property SystemInfo : TSystemInfo read fSystemInfo write SetSystemInfo;
    property ShowStatus : Boolean read fShowStatus write fShowStatus;
    property SpinUp : Boolean read fSpinUp write fSpinUp;
    property ProcessIdleTasks : Boolean read fProcessIdleTasks write fProcessIdleTasks;
    property DiskDefrag : Boolean read fDiskDefrag write fDiskDefrag;
    property TargetDisk : char read fTargetDisk write fTargetDisk;
    property OutputString :string read fOutputString write fOutputString;
    property Interation : integer read fIteration write fIteration;
    property InterationFinal : integer read fIterationFinal write fIterationFinal;
    property TestName : string read fTestName write fTestName;
    property TestScore : integer read fTestScore write fTestScore;
    property TestTime : double read fTestTime write fTestTime;
    property TotalNumberOfTestsToRun : integer read fTotalNumberOfTestsToRun
                                               write fTotalNumberOfTestsToRun;
    property OnOutputString : TNotifyEvent read fOnOutputString
                                           write fOnOutputString;
    property OnTestBegins : TNotifyEvent read fOnTestBegins write fOnTestBegins;
    property OnTestEnds : TNotifyEvent read fOnTestEnds  write fOnTestEnds;
    property OnNumberOfTestToRun : TNotifyEvent read fOnNumberOfTestToRun
                                                write fOnNumberOfTestToRun;
    property OnTestSuiteRunStart : TNotifyEvent read fOnTestSuiteRunStart
                                                 write fOnTestSuiteRunStart;
    property OnTestSuiteRunEnd : TNotifyEvent read fOnTestSuiteRunEnd
                                              write fOnTestSuiteRunEnd;
    property OnIterationStart : TNotifyEvent read fOnIterationStart
                                             write fOnIterationStart;
    property OnIterationEnd : TNotifyEvent read fOnIterationEnd
                                           write fOnIterationEnd;
  end; // TOSMarkTestSuite

const
  OFFICIAL_RUN_TESTS = [qtGrid, qtGridFP, qtFibThreads, qtNBody, qtPiThreads,
    qtPlotTrig, qtPlotTrig2, qtPlotLines, qtRandomDots, qtMandelbrotThreads,
    qtCircles, qtMaze, qtFern, qtRichEd, qtDrawEllipses, qtPi,
    qtDhrystoneThreads, qtWhetstoneThreads, qtMazeThreads, qtDrawRectangles,
    qtBandwidthBP64, qtMemLatency, qtOrthogonalThreads, qtIdenticalThreads,
    qtDrawLines, qtJpgDecode, qtImageResize,  qtImageRotate, qtMP3Encode,
    qtWebPageLoad, qtZipCompress, qtEncryptDecrypt, qtFileCopy, qtLorenz,
    qtNBodyOpenGL, qtPngOut, qt7zip, qtUpx
    ];

  OFFICIAL_RUN_ITERATIONS = 3;  //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ERR_TEST_TYPE_NOT_FOUND = ': You specified a test type that I could not find.';
  ERR_DRIVE_IS_TOO_SMALL = ': The drive you have chosen has too little free space to run drive tests.';

implementation

  constructor TOSMarkTestResults.Create( AOwner : TComponent );
  begin
    inherited;
  end; // constructor

  procedure TOSMarkTestResults.Initialize( aSystemInfo: TSystemInfo );
  begin
    if not assigned( aSystemInfo ) then begin
      raise exception.Create('TOSMarkTestResults.Initialize: Pass me an instantiated SystemInfo object, you dork!' );
    end; // if
    fSystemInfo := aSystemInfo;
    fSystemInfo.ShowStatus := TRUE;
    if not fSystemInfo.Initialized then begin
      fSystemInfo.Initialize;
    end;
    fHardwareInfo := fSystemInfo.HardwareInfo;
    fOsInfo := fSystemInfo.OsInfo;
    fRunDateTime := now;
  end;

  function TOSMarkTestResults.GetBestScore( aQTest : TQTests ): double;
  var
    i : integer;
  begin
    result := -1;
    for i := low( fTestResults ) to high( fTestResults ) do begin
      if (fTestResults[i].TestType = aQTest) then begin
        if fTestResults[i].TestScore > result then begin
          result := fTestResults[i].TestScore;
        end; // if
      end; // if
    end; // for
  end; //function TOSMarkTestResults.GetBestScore

  function TOSMarkTestResults.GetAverageScore( aQTest : TQTests ): double;
  var
    i : integer;
    liCount : integer;
    ldAccumulate : double;
  begin
    result := -1;
    liCount := 0;
    ldAccumulate := 0;
    for i := low( fTestResults ) to high( fTestResults ) do begin
      if (fTestResults[i].TestType = aQTest) then begin
        ldAccumulate := ldAccumulate + fTestResults[i].TestScore;
        inc( liCount );
      end; // if
    end; // for
    if liCount > 0 then result := ldAccumulate / liCount;
  end; //function TOSMarkTestResults.GetAverageScore

  function TOSMarkTestResults.GetWorstScore( aQTest : TQTests ): double;
  var
    i : integer;
  begin
    result := 10000000000000000;
    for i := low( fTestResults ) to high( fTestResults ) do begin
      if (fTestResults[i].TestType = aQTest) then begin
        if fTestResults[i].TestScore < result then begin
          result := fTestResults[i].TestScore;
        end; // if
      end; // if
    end; // for
  end; //function TOSMarkTestResults.GetWorstScore

  // GetCosbiScore will return the average score unless geometric mean is
  // specified.
  function TOSMarkTestResults.GetCosbiScore(abGeometricMean : Boolean): double;
  var
    lTest : TQTests;
    lFirstTest : TQTests;
    lLastTest : TQTests;
    liCount : integer;
    ldAccumulate : double;
  begin
    // geometric mean = (x1 * x2 * x3 ... * xn) ^ (1/n)
    result := -1;
    liCount := 0;
    if abGeometricMean then begin
      ldAccumulate := 1;
    end else begin
      ldAccumulate := 0;
    end;
    if fOfficialRun then begin
      lFirstTest := succ( qtFirstTest );
      lLastTest := pred( qtLastTest );
      for lTest := lFirstTest to lLastTest do begin
        if lTest in OFFICIAL_RUN_TESTS then begin
          if abGeometricMean then begin
            ldAccumulate := ldAccumulate * GetBestScore( lTest );
          end else begin
            ldAccumulate := ldAccumulate + GetBestScore( lTest );
          end;
          inc( liCount );
        end; // if lTest in OFFICIAL_RUN_TESTS
      end; // for lTest := qtFirstTest
      if abGeometricMean then begin
        if liCount > 0 then result := power( ldAccumulate, (1 / liCount) );
      end else begin
        if liCount > 0 then result := ldAccumulate / liCount;
      end;
    end; // if fOfficialRun
  end; //function TOSMarkTestResults.GetWorstScore

  function TOSMarkTestResults.GetBestTime( aQTest : TQTests ): double;
  var
    i : integer;
  begin
    result := 1000000000;
    for i := low( fTestResults ) to high( fTestResults ) do begin
      if (fTestResults[i].TestType = aQTest) then begin
        if fTestResults[i].TestTime < result then begin
          result := fTestResults[i].TestTime;
        end; // if
      end; // if
    end; // for
  end; //function TOSMarkTestResults.GetBestTime

  function TOSMarkTestResults.GetAverageTime( aQTest : TQTests ): double;
  var
    i : integer;
    liCount : integer;
    ldAccumulate : double;
  begin
    result := -1;
    liCount := 0;
    ldAccumulate := 0;
    for i := low( fTestResults ) to high( fTestResults ) do begin
      if (fTestResults[i].TestType = aQTest) then begin
        ldAccumulate := ldAccumulate + fTestResults[i].TestTime;
        inc( liCount );
      end; // if
    end; // for
    if liCount > 0 then result := ldAccumulate / liCount;
  end; //function TOSMarkTestResults.GetAverageTime

  function TOSMarkTestResults.GetWorstTime( aQTest : TQTests ): double;
  var
    i : integer;
  begin
    result := -1;
    for i := low( fTestResults ) to high( fTestResults ) do begin
      if (fTestResults[i].TestType = aQTest) then begin
        if fTestResults[i].TestTime > result then begin
          result := fTestResults[i].TestTime;
        end; // if
      end; // if
    end; // for
  end; //function TOSMarkTestResults.GetWorstTime

  procedure TOSMarkTestResults.AddResult( aTestResult : TOSMarkTestResult );
  var
    liArrayLength : integer;
  begin
    liArrayLength := high( fTestResults ) + 1; // zero based so add one
    SetLength( fTestResults, liArrayLength + 1 ); // bump up one element
    fTestResults[ liArrayLength ] := aTestResult; // store in last element
  end; // procedure TOSMarkTestResults.AddResult

  // GetBestResult returns a string with the test name, test score and test
  // time for the best result.
  function TOSMarkTestResults.GetBestResult( aQTest : TQTests ): string;
  var
    i : integer;
    ldBestScore : double;
  begin
    result := '';
    ldBestScore := -1;
    for i := low( fTestResults ) to high( fTestResults ) do begin
      if (fTestResults[i].TestType = aQTest) then begin
        if fTestResults[i].TestScore > ldBestScore then begin
          ldBestScore := fTestResults[i].TestScore;
          result := fTestResults[i].TestName + ', '  +
            FloatToStrF( fTestResults[i].TestScore, ffGeneral, 6, 0 ) + ', ' +
            FloatToStrF( fTestResults[i].TestTime, ffGeneral, 6, 3 );
        end; // if
      end; // if
    end; // for
    if result = '' then raise exception.Create( 'TOSMarkTestResults.GetBestResult' +
                                                ERR_TEST_TYPE_NOT_FOUND );
  end; //function TOSMarkTestResults.GetBestResult

  // GetBestSuiteResults returns a string with the test name, test score and test
  // time for the best result of each test in the suite.
  function TOSMarkTestResults.GetBestSuiteResults( aQTestSet : TQTestSet ): string;
  var
    lTest : TQTests;
    lFirstTest : TQTests;
    lLastTest : TQTests;
    lstrSuiteResult : string;
  begin
    result := '';
    lFirstTest := succ( qtFirstTest );
    lLastTest := pred( qtLastTest );
    for lTest := lFirstTest to lLastTest do begin
      if lTest in aQTestSet then begin
        result := result + GetBestResult( lTest ) + CR_LF;
      end; // if lTest in OFFICIAL_RUN_TESTS
    end; // for lTest := qtFirstTest
    if fOfficialRun then begin
      lstrSuiteResult := '*** COSBI OSMark, ' +
        FloatToStrF(GetCosbiScore( FALSE ), ffGeneral, 4, 0);
      //showMessage( lstrSuiteResult );
      result := result + lstrSuiteResult + CR_LF;
    end; // if fOfficialRun
  end; //function TOSMarkTestResults.GetBestSuiteResults

// TOSMarkTestResults ends...........................................................

// TOSMarkTestSuite begins.......................................................

constructor TOSMarkTestSuite.Create( AOwner : TComponent );
begin
  fShowStatus := FALSE;
  fSpinUp := FALSE;
  fProcessIdleTasks := FALSE;
  fDiskDefrag := FALSE;
  fTargetDisk := 'c';
  inherited;
end; // constructor


procedure TOSMarkTestSuite.Initialize( aSystemInfo: TSystemInfo);
begin
  if not assigned( aSystemInfo ) then begin
    raise exception.Create('TOSMarkTestSuite.Initialize: Pass me an instantiated SystemInfo object, you dork!' );
  end; // if
  fSystemInfo := aSystemInfo;
  fOSMarkTestResults := TOSMarkTestResults.Create(self);
  fOSMarkTestResults.Initialize( aSystemInfo );
  fOSMarkTestResults.SystemInfo := fSystemInfo;
  fStopWatch := fSystemInfo.StopWatch;
end; // procedure TOSMarkTestSuite.Initialize;

destructor TOSMarkTestSuite.Destroy;
begin
  FreeAndNil( fOSMarkTestResults );
  inherited;
end; // constructor TOSMarkTestSuite.Create;

procedure TOSMarkTestSuite.SetSystemInfo( Value : TSystemInfo );
begin
  fSystemInfo := Value;
end; // procedure TOSMarkTestSuite.SetSystemInfo( Value : TStopWatch );

procedure TOSMarkTestSuite.OutString( asOutputString : string );
begin
  fOutputString := asOutputString;
  if assigned( OnOutputString ) then OnOutputString( self );
  Application.ProcessMessages;
end; //procedure TOSMarkTestSuite.OutputString( var asOutputString : string )

procedure TOSMarkTestSuite.HandleDiskDefrag;
var
  i : integer;
  lfrmStatus : TfrmStatus;
begin
  // defrag drive:
  if fDiskDefrag then begin
    OutString( 'Defragging drive ' + fTargetDisk + ':...' );
    lfrmStatus := TfrmStatus.Create( nil );
    try
      lfrmStatus.Clear;
      lfrmStatus.Show;
      lfrmStatus.AddLine('Please be patient.');
      lfrmStatus.AddLine('This could take awhile.');
      lfrmStatus.AddLine('Defragmenting drive five times...');
      for i := 1 to 5 do begin
        lfrmStatus.AddLine('Starting defrag #' + IntToStr( i ) );
        RunDiskDefrag( fTargetDisk, 1 );
        lfrmStatus.AddLine('Finished defrag #:' + IntToStr( i ) );
      end; // for
    finally
      lfrmStatus.Release;
      freeAndNil( lfrmStatus );
    end; // try..finally
  end; // if
end; // procedure TOSMarkTestSuiteHandleDiskDefrag;

procedure TOSMarkTestSuite.HandleProcessIdleTasks;
var
  lfrmStatus : TfrmStatus;
begin
  // process idle task:
  if fProcessIdleTasks then begin
    OutString( 'Forcing XP to process idle tasks... ' );
    lfrmStatus := TfrmStatus.Create( nil );
    try
      lfrmStatus.Clear;
      lfrmStatus.Show;
      lfrmStatus.AddLine('Please be patient.');
      lfrmStatus.AddLine('Processing idle tasks...');
      RunProcessIdleTasks;
    finally
      lfrmStatus.Release;
      freeAndNil( lfrmStatus );
    end; // try..finally
  end; // if
end; // procedure TOSMarkTestSuite.HandleProcessIdleTasks;

procedure TOSMarkTestSuite.CheckDriveSpace;
begin
  if qtFileCopy in fSelectedTests then begin
    if not DriveIsBigEnough( fTargetDisk, ONE_BILLION ) then begin
      raise Exception.Create( 'TOSMarkTestSuite.CheckDriveSpace' + ERR_DRIVE_IS_TOO_SMALL );
    end; // if
  end; // if
end; //

procedure TOSMarkTestSuite.RunTheseTests( aQTSet: TQTestSet; aiIterations: integer );
var
  i : integer;
  nbr_tests : integer;
begin
  fSelectedTests := aQTSet;
  nbr_tests := CountTests;
  if nbr_tests = 0 then begin
    showmessage( 'TOSMarkTestSuite.RunTests: You have not selected any tests.');
    exit;
  end; // if

  fIterationFinal := aiIterations;
  fTotalNumberOfTestsToRun := nbr_tests * aiIterations;
  if assigned( OnTestSuiteRunStart ) then OnTestSuiteRunStart( self );

  CheckDriveSpace;
  HandleDiskDefrag;
  HandleProcessIdleTasks;

  OutputResultHeader( aiIterations );
  for i := 1 to aiIterations do begin
    fIteration := i;
    if assigned( OnIterationStart ) then OnIterationStart( self );
    application.ProcessMessages;
    TestSuiteRun( i );
    if assigned( OnIterationEnd ) then OnIterationEnd( self );
    application.ProcessMessages;
  end; // for i...
  if aiIterations > 1 then begin
    OutputSuiteResultHeader( aiIterations );
    OutString( fOSMarkTestResults.GetBestSuiteResults( aQTSet ) );
  end; // if
  OutputResultFooter;
  if assigned( OnTestSuiteRunEnd ) then OnTestSuiteRunEnd( self );
end; // procedure TOSMarkTestSuite.RunTests

procedure TOSMarkTestSuite.OutputResultHeader( aiIterations : integer );
begin
  OutString('');
  if fSpinUp then begin
    OutString('>> "Spin up" CPU selected');
  end; // if
  if aiIterations = 1 then
    OutString('*** Test Starts (' + IntToStr(aiIterations) + ' iteration) ***')
  else
    OutString('*** Test Starts (' + IntToStr(aiIterations) + ' iterations) ***');
  OutString('');
  OutString('Test, Score, Time(s)');
  OutString('====  =====  =======');
end; // procedure TOSMarkTestSuite.OutputResultHeader;

procedure TOSMarkTestSuite.OutputSuiteResultHeader( aiIterations : integer );
begin
  OutString('');
  OutString('**** Best Results for ' + IntToStr(aiIterations) + ' iterations ****');
  OutString('');
  OutString('Test, Score, Time(s)');
  OutString('====  =====  =======');
end; // procedure TOSMarkTestSuite.OutputResultHeader;

procedure TOSMarkTestSuite.OutputResultFooter;
begin
  OutString('');
  OutString('*** Test Ends ***');
end; // procedure TOSMarkTestSuite.OutputResultFooter;

procedure TOSMarkTestSuite.LogResults( aQuickTest: TTest );
var
  lTestResult : TOSMarkTestResult;
begin
  lTestResult.TestType := aQuickTest.QTestType;
  lTestResult.TestName := aQuickTest.TestName;
  lTestResult.TestTime := aQuickTest.MinTime;
  lTestResult.TestScore := aQuickTest.GetScore(0);
  lTestResult.TestRawScore := aQuickTest.RawScore;
  lTestResult.TestRawUnits := aQuickTest.RawUnits;
  fOSMarkTestResults.AddResult( lTestResult );
end; // procedure TOSMarkTestSuite.LogResult;

function TOSMarkTestSuite.CountTests;
var
  lQuickTest : TQTests;
begin
  result := 0;
  for lQuickTest := qtFirstTest to qtLastTest do begin
    if lQuickTest in fSelectedTests then begin
      inc( result );
    end; // if
  end; // for
end; // procedure TOSMarkTestSuite.CountTests;

procedure TOSMarkTestSuite.RunTest( var aTest : TTest;
                                   aiRunCount : integer );
begin
  with aTest do begin
    StopWatch := fStopWatch;
    if aiRunCount > 0 then RunCount := aiRunCount;
    ShowStatus := fShowStatus;
    SpinUp := fSpinUp;
    fTestName := aTest.TestName;
    if assigned( OnTestBegins ) then OnTestBegins( self );
    application.ProcessMessages;
    Run;
    fTestScore := GetScore(0);
    fTestTime := MinTime;
    if assigned( OnTestEnds ) then OnTestEnds( self );
    application.ProcessMessages;
    OutString( TestName + ', ' + IntToStr(GetScore(0)) + ', ' +
      GetFormattedMinTime );
    LogResults( aTest );
  end; // with
end; // procedure TOSMarkTestSuite.RunTest;

procedure TOSMarkTestSuite.TestSuiteRun( aiRunCount : integer );
var
  lTest : TTest;
begin
  if qtGrid in fSelectedTests then begin
    lTest := TGridBlastTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtGrid in fSelectedTests
  if qtGridFP in fSelectedTests then begin
    lTest := TGridBlastFPTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtGrid in fSelectedTests
  if qtFibThreads in fSelectedTests then begin
    lTest := TFibThreadTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtFibThreadTest
  if qtNBody in fSelectedTests then begin
    lTest := TnBodyTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtNBody in fSelectedTests
  if qtPiThreads in fSelectedTests then begin
    lTest := TPiThreadTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtPiThreads
  if qtPlotTrig in fSelectedTests then begin
    lTest := TTrigTest.Create;
    try
      RunTest( lTest, aiRunCount  );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtPlotTrig in fSelectedTests
  if qtPlotTrig2 in fSelectedTests then begin
    lTest := TTrigTest2.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtPlotTrig2 in fSelectedTests
  if qtPlotLines in fSelectedTests then begin
    lTest := TPlotLinesTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtPlotLines in fSelectedTests
  if qtRandomDots in fSelectedTests then begin
    lTest := TRandomDotsTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtRandomDots in fSelectedTests
  if qtMandelbrotThreads in fSelectedTests then begin
    lTest := TMandelbrotThreadTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtMandelbrotThreads
  if qtCircles in fSelectedTests then begin
    lTest := TFilledCircleTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; //if qtCircles in fSelectedTests
  if qtMaze in fSelectedTests then begin
    lTest := TMazeTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; //if qtMaze in fSelectedTests
  if qtFern in fSelectedTests then begin
    lTest := TFernTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtFern in fSelectedTests
  if qtRichEd in fSelectedTests then begin
    lTest := TRichEditTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtRichEd in fSelectedTests
  if qtDrawEllipses in fSelectedTests then begin
    lTest := TDrawEllipsesTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtDrawEllipses
  if qtPi in fSelectedTests then begin
    lTest := TPiTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtPi in fSelectedTests
  if qtDhrystoneThreads in fSelectedTests then begin
    lTest := TDhrystoneThreadTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtDhrystoneThreads
  if qtWhetstoneThreads in fSelectedTests then begin
    lTest := TWhetstoneThreadTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtWhetstoneThreads
  if qtMazeThreads in fSelectedTests then begin
    lTest := TMazeThreadTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtMazeThreads in fSelectedTests
  if qtDrawRectangles in fSelectedTests then begin
    lTest := TDrawRectanglesTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtDrawRectangles
  if qtBandwidthBP64 in fSelectedTests then begin
    lTest := TBandwidthBP64ThreadTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtBandwidthBP64
  if qtMemLatency in fSelectedTests then begin
    lTest := TMemLatencyThreadTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtMemLatency
  if qtOrthogonalThreads in fSelectedTests then begin
    lTest := TOrthogonalThreadTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtOrthogonalThreads
  if qtIdenticalThreads in fSelectedTests then begin
    lTest := TIdenticalThreadTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtIndenticalThreads
  if qtDrawLines in fSelectedTests then begin
    lTest := TDrawLinesTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtDrawLines
  if qtJpgDecode in fSelectedTests then begin
    lTest := TJpgDecodeTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtJpgDecode
  if qtImageResize in fSelectedTests then begin
    lTest := TImageResizeTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtIndenticalThreads
  if qtImageRotate in fSelectedTests then begin
    lTest := TImageRotateTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtIndenticalThreads
  if qtMp3Encode in fSelectedTests then begin
    lTest := TMp3EncoderTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtMp3Encode
  if qtWebPageLoad in fSelectedTests then begin
    lTest := TWebPageLoad.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtWebPageLoad
  if qtZipCompress in fSelectedTests then begin
    lTest := TZipCompressTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtZipCompress
  if qtEncryptDecrypt in fSelectedTests then begin
    lTest := TAesThreadTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtEncryptDecrypt
  if qtFileCopy in fSelectedTests then begin
    lTest := TFileCopyTest.Create;
    try
      TFileCopyTest( lTest ).TargetDrive := fTargetDisk;
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtFileCopy
  if qtLorenz in fSelectedTests then begin
    lTest := TLorenzTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtLorenz
  if qtNBodyOpenGL in fSelectedTests then begin
    lTest := TNBodyOpenGL.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtNBodyOpenGL
  if qtDhrystone in fSelectedTests then begin
    lTest := TDhrystone.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtDhrystone in fSelectedTests
  if qtPngOut in fSelectedTests then begin
    lTest := TPngOutThreadTest.Create;
    try
      TPngOutThreadTest( lTest ).TargetDrive := fTargetDisk;
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtPngOut in fSelectedTests
  if qt7zip in fSelectedTests then begin
    lTest := T7zipThreadTest.Create;
    try
      T7zipThreadTest( lTest ).TargetDrive := fTargetDisk;
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qt7zip in fSelectedTests
  if qtUpx in fSelectedTests then begin
    lTest := TUpxThreadTest.Create;
    try
      TUpxThreadTest( lTest ).TargetDrive := fTargetDisk;
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtUpx in fSelectedTests
  if qtWhetstone in fSelectedTests then begin
    lTest := TWhetstone.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtWhetstone in fSelectedTests
  if qtFib in fSelectedTests then begin
    lTest := TFibonacciTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtFib in fSelectedTests
  if qtFernThreads in fSelectedTests then begin
    lTest := TFernThreadTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtFernThreads
  if qtFPMultiply in fSelectedTests then begin
    lTest := TFPMultiplyTest.Create;
    try
      RunTest( lTest, aiRunCount );
    finally
      FreeAndNil( lTest );
    end;
  end; // if qtFPMultiply
end; // procedure TestRun( aiRunCount : integer );

procedure TOSMarkTestSuite.OfficialRun;
begin
  fOfficialRun := TRUE;
  fOSMarkTestResults.OfficialRun := TRUE;
  RunTheseTests( OFFICIAL_RUN_TESTS, OFFICIAL_RUN_ITERATIONS );
  fOfficialRun := FALSE;
end; // procedure TOSMarkTestSuite.btnOfficialRunClick(Sender: TObject);

end.
