LupineExerciserManagerImpl.mesa.
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last edited by BZM on 18-Mar-82 13:25:29.
Last edited by Andrew Birrell on July 7, 1982 6:35 pm
Last edited by Bob Hagmann on February 11, 1985 8:41:06 am PST
DIRECTORY
BasicTime USING [GetClockPulses, GMT, Now, Pulses],
Convert USING [Error, IntFromRope],
IO USING [card, GetLineRope, int, PutChar, PutF, PutFR, PutRope, rope, STREAM, time],
Loader USING [BCDBuildTime],
LupineExerciser
USING [
Counter, Exercise, ExerciseIndex, ExerciseList,
StandardPasses, StandardTrialsPerPass, StandardTestsPerTrial,
String ],
LupineExerciserPrivate
USING [
ExerciseHandle, ExerciseObject, FinishPrecisionTimings,
InitPrecisionTimings, InitTestParameters, SpyOperation ],
SpyClient USING [DisplayData, StandardSpy, StartSpy, StopSpy, ZeroData],
Process USING[ CheckForAbort],
Random USING [ChooseInt, Create],
Rope USING [InlineLength, InlineFetch, ROPE, Substr],
ViewerIO
USING [CreateViewerStreams];
LupineExerciserManagerImpl:
PROGRAM
IMPORTS
BasicTime, Convert, IO, LupineExerciserPrivate, Loader, Process,
RandomInt, Rope, ViewerIO
EXPORTS LupineExerciser, LupineExerciserPrivate
= BEGIN OPEN LupineExerciser;
PerformExercises:
PUBLIC
PROCEDURE [
nameOfExercisedInterface: String,
exercises: ExerciseList ] =
BEGIN ENABLE ABORTED => CONTINUE;
logFileName: Rope.
ROPE = UniqueName [
root: nameOfExercisedInterface, extension: "log" ];
inLogStream, outLogStream: IO.STREAM;
LogStreamPutChar: PROC [char: CHARACTER] = {IO.PutChar[outLogStream, char]};
exerciseObject: LupineExerciserPrivate.ExerciseObject;
[inLogStream, outLogStream] ← ViewerIO.CreateViewerStreams["Lupine Exerciser Manager"];
exerciseObject ← [inLogStream: inLogStream, outLogStream: outLogStream];
DoExercises[
self: @exerciseObject,
exerciseName: nameOfExercisedInterface,
logFileName: logFileName,
exercises: exercises
! ABORTED => CONTINUE ];
END;
DoExercises:
PROCEDURE [
self: Handle,
exerciseName, logFileName: String,
exercises: ExerciseList ] =
BEGIN
DO
OPEN tp: self.tp;
ENABLE {
QuitExercises => EXIT;
AbortExercises => CONTINUE };
pass: Counter;
numExercises: ExerciseIndex = LENGTH[exercises];
EstablishTestParameters[self, exerciseName, logFileName];
IF tp.spying
THEN CallSpy[self,
IF tp.spyOnProcs THEN startAndWatchProcs ELSE startAndWatchModules ];
FOR pass
IN [1..tp.passes]
DO
self.outLogStream.PutF["\n\nStarting pass %g of %g...\n", IO.int[pass], IO.int[tp.passes]];
FOR exerciseMarch: ExerciseIndex
IN [0..numExercises)
DO
exercise: ExerciseIndex;
IF tp.testRandomly
THEN
BEGIN
OPEN Random;
exercise ← ChooseInt[min: 0, max: numExercises-1];
tp.trialsPerPass ← ChooseInt[min: 1, max: MAX[1,tp.maxTrialsPerPass] ];
tp.testsPerTrial ← ChooseInt[min: 0, max: tp.maxTestsPerTrial];
END
ELSE
BEGIN
exercise ← exerciseMarch;
tp.trialsPerPass ← tp.maxTrialsPerPass;
tp.testsPerTrial ← tp.maxTestsPerTrial;
END;
LupineExerciserPrivate.InitPrecisionTimings[self];
exercises[exercise].routine[
exerciser: self,
name: exercises[exercise].name,
trials: tp.trialsPerPass,
testsPerTrial: tp.testsPerTrial,
checkResults: tp.checkResults
! UNWIND => LupineExerciserPrivate.FinishPrecisionTimings[self] ];
LupineExerciserPrivate.FinishPrecisionTimings[self];
ENDLOOP;
ENDLOOP;
IF tp.spying
THEN CallSpy[self,
(
SELECT tp.showSpyData
FROM
afterEachTest => stop,
afterAllTests => stopAndDisplayStats,
ENDCASE => ERROR) ];
ENDLOOP;
END;
QuitExercises: PRIVATE ERROR = CODE;
EstablishTestParameters:
PROCEDURE [
self: Handle,
exerciseName, logFileName: String ] =
BEGIN
now: BasicTime.GMT ← BasicTime.Now[];
built: BasicTime.GMT ← Loader.BCDBuildTime[];
self.tp ← LupineExerciserPrivate.InitTestParameters;
self.outLogStream.PutF["\nLupine RPC Exerciser of %g on %g.\nStarting %g exercise; the log is %g.\n\n", IO.time[built], IO.time[now], IO.rope[exerciseName], IO.rope[logFileName]];
DO
OPEN tp: self.tp;
BEGIN
ENABLE Convert.Error =>
GOTO TryAgain;
GetCount:
PROC
RETURNS [Counter] =
INLINE {RETURN[Convert.IntFromRope[reply.Substr[start: 1]]]};
reply: Rope.ROPE ← NIL;
self.outLogStream.PutRope[">>"];
CheckAbort[self];
reply ← self.inLogStream.GetLineRope[];
CheckAbort[self];
IF reply.InlineLength[] > 0
THEN
SELECT reply.InlineFetch[0]
FROM
'd, 'D => {tp.checkResults ← FALSE};
'e, 'E => {tp.useDoradoClock ← tp.countOnlyEmulatorCycles ← TRUE};
'f, 'F => {tp ← LupineExerciserPrivate.InitTestParameters};
'g, 'G => {EXIT};
'h, 'H => {tp.useDoradoClock ← TRUE};
'm, 'M => {tp.spying ← TRUE; tp.spyOnProcs ← FALSE};
'p, 'P => {tp.passes ← GetCount[]};
'o, 'O => {tp.maxTrialsPerPass ← GetCount[]};
't, 'T => {tp.maxTestsPerTrial ← GetCount[]};
'r, 'R => {tp.testRandomly ← TRUE};
's, 'S => {tp.spying ← TRUE; tp.showSpyData ← afterAllTests};
'x, 'x => {tp.spying ← TRUE; tp.showSpyData ← afterEachTest};
'q, 'Q => {ERROR QuitExercises};
'- => {NULL};
'? => {TypeHelp[self]};
ENDCASE => GOTO TryAgain;
EXITS
TryAgain => self.outLogStream.PutRope["???\n"]
END;
ENDLOOP;
END;
TypeHelp:
PROCEDURE [self: Handle] =
BEGIN
self.outLogStream.PutRope["
The exerciser options are:
D Don't check results of remote calls for correctness.
E Exclude nonemulator cycles in timings (Dorados only).
F Flush and start over.
G Go (type this last).
H High precision timings (Dorados only).
M Module-level (coarse) spying.
Pn Number of passes of entire exercise.
On Number of trials of each pass.
Tn Number of tests (eg, calls) per trial.
R Choose trials, tests, and exercises randomly.
S Spy after all passes are over.
X Spy at the exit of each trial.
Q Quit this program immediately.
? Type this explanation.
^DEL To abort at any time.
The default options are P1 Q1 R2000 G.\n\n" ];
END;
AbortExercises:
PRIVATE
ERROR =
CODE;
Raised by CheckAbort and caught in DoExercises.
CheckAbort:
PUBLIC
PROC [self: Handle] =
BEGIN
Process.CheckForAbort[!
ABORTED =>
{
self.outLogStream.PutRope["\nTest aborted...\n\n"];
ERROR AbortExercises;
};
];
END;
UniqueName:
PROCEDURE [root, extension: String]
RETURNS [rootSuffix: String] =
INLINE BEGIN
pulses: BasicTime.Pulses ← BasicTime.GetClockPulses[];
rootSuffix ← IO.PutFR["%g.%g.%g", IO.rope[root], IO.card[pulses], IO.rope[extension]];
END;
CallSpy:
PUBLIC
PROCEDURE [
self: Handle,
operation: LupineExerciserPrivate.SpyOperation ] =
--TEMP, until spy converts to 3.2-- {};
BEGIN OPEN SpyClient;
SELECT operation FROM
startAndWatchProcs, startAndWatchModules => {StandardSpy; ZeroData};
startSpying => StartSpy;
stopSpying => StopSpy;
displayStats, stopAndDisplayStats =>
{StopSpy; DisplayData[herald: "Called by LupineExerciser.", stream: NIL]};
stop => StopSpy;
ENDCASE => ERROR;
END;