Windows2003-3790/tools/buildtimes.js

597 lines
16 KiB
JavaScript

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2000
//
// File: buildtimes.js
//
// Contents:
//
//
//
//----------------------------------------------------------------------------
//
// Globals
//
var g_reDate = new RegExp("[a-zA-Z0-9_-]+\\t(\\d{4})/(\\d{2})/(\\d{2}):(\\d{2}):(\\d{2}):(\\d{2})");
var g_reStartBuildExe = new RegExp("\\(([a-zA-Z]+)\\) Build for [a-zA-Z]+ started. PID=(\\d+)");
var g_rePassComplete = new RegExp("\\(([a-zA-Z]+)\\) pass (\\d) complete on pid (\\d+)");
var g_reTaskStep = new RegExp("\\(([a-zA-Z]+)\\) TASK STEPPING ");
var g_reProcessExit = new RegExp("\\(([a-zA-Z]+)\\) Process id (\\d+) exited");
var g_reStartPost = new RegExp("\\(([a-zA-Z]+)\\) postbuild task thread for Root started.");
var g_reExitPost = new RegExp("\\(([a-zA-Z]+)\\) postbuild for Root completed.");
var g_reStartBuild = new RegExp("STARTING PASS 0 of build.");
var g_reExitBuild = new RegExp("WAIT FOR NEXTPASS 2 of waitbuild");
var g_reStartCFPBTS = new RegExp("Received copyfilesfrompostbuildtoslave command from remote machine");
var g_reStartCFTPB = new RegExp("CopyFilesToPostBuild\\(([a-zA-Z]+)\\).*There are (\\d+) files");
var g_reLastCopyCFTPB = new RegExp("RoboCopyCopyFile\\(([a-zA-Z]+)\\)");
var g_reEndCFTPB = new RegExp("(Received) nextpass command from remote machine.");
var g_reBuildType = new RegExp("razzle.cmd");
// NTAXP01 2000/04/13:17:50:01 taskBuildFiles(strSDRoot) (Root) Build for Root started. PID=548
// NTAXP01 2000/04/13:17:56:20 ParseBuildMessages(pid) (Root) pass 0 complete on pid 548
// NTAXP01 2000/04/13:18:45:20 ParseBuildMessages(pid) (Root) pass 1 complete on pid 548
// NTAXP01 2000/04/13:21:59:11 ParseBuildMessages(pid) (Root) pass 2 complete on pid 548
// NTAXP01 2000/04/13:21:59:12 ParseBuildMessages(pid) (Root) Process id 548 exited!
// NTAXP01 2000/04/13:18:44:53 taskBuildFiles(strSDRoot) (Root) TASK STEPPING Root
// AXP64FRE 2000/04/13:17:49:27 MyRunLocalCommand(strCmd) (Root) RunLocalCommand('cmd /c d:\nt\Tools\razzle.cmd win64 free officialbuild no_certcheck no_sdrefresh no_title & sdinit && sd -s sync 2>&1', 'd:\nt\.', 'Sync Root', 'true', 'true', 'false')
// NTBLD04 2000/04/25:14:20:20 mtscript_js::OnRemoteExec(cmd) Received copyfilesfrompostbuildtoslave command from remote machine.
// NTBLD04 2000/04/25:14:19:55 CopyFilesToPostBuild(aPublishedEnlistments) (#0) There are 3 files
// NTBLD04 2000/04/25:14:19:55 RoboCopyCopyFile(srcdir) RoboCopy file d:\nt\public\sdk\lib\i386\AutoDiscovery.tlb to \\NTBLD03\d$\nt\Public\sdk\lib\i386\AutoDiscovery.tlb
// NTBLD04 2000/04/25:14:20:05 mtscript_js::OnRemoteExec(cmd) Received nextpass command from remote machine.
var g_aMatches =
[
{ re: g_reStartBuildExe, fn: NewDepot},
{ re: g_rePassComplete , fn: PassComplete},
{ re: g_reTaskStep , fn: TaskStep},
{ re: g_reProcessExit , fn: ProcessExit},
{ re: g_reStartPost , fn: PostStart},
{ re: g_reExitPost , fn: PostExit},
{ re: g_reStartBuild , fn: ElapsedStart},
{ re: g_reExitBuild , fn: ElapsedExit},
{ re: g_reStartCFPBTS , fn: StartCFPBTS},
{ re: g_reStartCFTPB , fn: StartCFTPB},
{ re: g_reLastCopyCFTPB, fn: LastFileCFTPB},
{ re: g_reEndCFTPB , fn: EndCFTPB}
];
var g_strBuildType;
var g_strMachine;
var g_aStrFileNames = new Array();
var g_FSObj = new ActiveXObject("Scripting.FileSystemObject");
var g_hDepots = new Object;
var g_hTimers = new Object;
var g_fMerged = true; // Merge "root" and "mergedcomponents" report
var g_fPrintElapsed = false;
var g_fPrintPost = false;
var g_CFObj;
// Add new methods...
Error.prototype.toString = Error_ToString;
//
// First, parse command line arguments
//
ParseArguments(WScript.Arguments);
main();
WScript.Quit(0);
function ParseArguments(Arguments)
{
var strArg;
var chArg0;
var chArg1;
var argn;
for(argn = 0; argn < Arguments.length; argn++)
{
strArg = Arguments(argn);
chArg0 = strArg.charAt(0);
chArg1 = strArg.toLowerCase().slice(1);
if (chArg0 != '-' && chArg0 != '/')
{
g_aStrFileNames[g_aStrFileNames.length] = Arguments(argn);
}
else
{
switch(chArg1)
{
case 'm':
g_fMerged = true;
break;
case 's':
g_fMerged = false;
break;
case 'e':
g_fPrintElapsed = true;
break;
case 'p':
g_fPrintPost = true;
break;
case '?':
LogMsg("HELP");
Usage();
break;
default:
LogMsg("HELP " + strArg);
Usage();
break;
}
}
}
if (g_aStrFileNames.length < 1)
Usage();
}
// PadDigits(n, cDigits)
// Return a string representation of the given
// number. Leading zeros are added to make the
// string cDigits long.
function PadDigits(n, cDigits)
{
var strDigits = '';
var i;
var strNumber = n.toString();
for(i = 0; i < cDigits - strNumber.length; ++i)
strDigits += '0';
return strDigits + n;
}
// PadString(str, cDigits)
function PadString(str, cDigits)
{
var strDigits = '';
var i;
for(i = 0; i < cDigits - str.length; ++i)
strDigits += ' ';
return str + strDigits;
}
function Error_ToString()
{
var i;
var str = 'Exception(';
/*
Only some error messages get filled in for "ex".
Specifically the text for disk full never seems
to get set by functions such as CreateTextFile().
*/
if (this.number != null && this.description == "")
{
switch(this.number)
{
case -2147024784:
this.description = "There is not enough space on the disk.";
break;
case -2147024894:
this.description = "The system cannot find the file specified.";
break;
case -2147023585:
this.description = "There are currently no logon servers available to service the logon request.";
break;
case -2147023170:
this.description = "The remote procedure call failed.";
break;
case -2147024837:
this.description = "An unexpected network error occurred";
break;
default:
this.description = "Error text not set for (" + this.number + ")";
break;
}
}
for(i in this)
{
str += i + ": " + this[i] + " ";
}
return str + ")";
}
function LogMsg(msg)
{
WScript.Echo(msg);
}
function Usage()
{
LogMsg('Usage: buildtimes [-s] [-e] [-p] path\\filename*.log');
LogMsg(' -s Do not merge build time of "root" and "mergedcomponents"');
LogMsg(' -e Print total elasped build time');
LogMsg(' -p Print postbuild time');
WScript.Quit(0);
}
//////////////////////////////////////
//////////////////////////////////////
// The DEPOT object
//////////////////////////////////////
//////////////////////////////////////
function Depot(strDepotName, nDepotPID)
{
this.strName = strDepotName;
this.nPID = nDepotPID;
this.nElapsed = 0;
this.nLast = 0; // used for postbuild
Depot.prototype.Begin = Depot_Begin;
Depot.prototype.SetLast = Depot_SetLast;
Depot.prototype.End = Depot_End;
Depot.prototype.End2 = Depot_End2;
Depot.prototype.Terminate = Depot_Terminate;
Depot.prototype.GetStrStatus = Depot_GetStrStatus;
}
function Depot_Begin(dateVal)
{
if (this.bBegin)
throw new Error(-1, "Multiple begins without end on depot " + this.strName);
this.nBegin = dateVal;
}
function Depot_SetLast(dateVal)
{
if (!this.nBegin)
throw new Error(-1, "SetLast without begin on depot " + this.strName);
this.nLast = dateVal;
}
function Depot_End(dateVal)
{
if (!this.nBegin)
throw new Error(-1, "End without begin on depot " + this.strName);
var delta = dateVal - this.nBegin;
delete this.nBegin;
this.nElapsed += delta;
}
function Depot_End2(dateVal)
{
if (!this.nBegin)
throw new Error(-1, "End without begin on depot " + this.strName);
var delta = dateVal - this.nBegin;
delete this.nBegin;
LogMsg("DELTA " + this.strName + " = " + delta);
this.nElapsed += delta;
}
function Depot_Terminate(dateVal)
{
}
function Depot_GetStrStatus()
{
var seconds = Math.floor(this.nElapsed / 1000);
var s = seconds % 60;
var m = Math.floor(seconds / 60) % 60;
var h = Math.floor(seconds / 60 / 60);
var strElapsed = PadDigits(h, 2) + ":" + PadDigits(m, 2) + ":" + PadDigits(s, 2);
return PadString(this.strName, 16) + " " + strElapsed;// + ", " + (this.nElapsed / 1000);
}
//////////////////////////////////////
//////////////////////////////////////
//////////////////////////////////////
function NewDepot(dateVal, strDepotName, a)
{
var nPID = a[0];
if (g_hDepots[strDepotName])
{
if (strDepotName == "root")
{
var depot = g_hDepots[strDepotName];
depot.Begin(dateVal);
}
else
throw new Error(-1, "Duplicate depot information for depot " + strDepotName);
}
var depot = new Depot(strDepotName, nPID);
depot.Begin(dateVal);
g_hDepots[strDepotName] = depot;
}
function PassComplete(dateVal, strDepotName, a)
{
var nPass = a[0];
var nPID = a[1];
var depot = g_hDepots[strDepotName];
if (!depot)
throw new Error(-1, "PassComplete on missing depot " + strDepotName);
depot.End(dateVal);
}
function TaskStep(dateVal, strDepotName)
{
var depot = g_hDepots[strDepotName];
if (!depot)
throw new Error(-1, "TaskStep on missing depot " + strDepotName);
depot.Begin(dateVal);
}
function ProcessExit(dateVal, strDepotName, a)
{
var nPID = a[0];
var depot = g_hDepots[strDepotName];
if (!depot)
throw new Error(-1, "ProcessExit on missing depot " + strDepotName);
depot.Terminate(dateVal);
}
function PostStart(dateVal, strDepotName)
{
if (g_fPrintPost)
{
var depot = new Depot('postbuild', 0);
depot.Begin(dateVal);
g_hTimers['postbuild'] = depot;
}
}
function PostExit(dateVal, strDepotName)
{
if (g_fPrintPost)
{
var depot = g_hTimers['postbuild'];
if (!depot)
throw new Error(-1, "TaskStep on missing depot " + 'postbuild');
depot.End(dateVal);
}
}
function ElapsedStart(dateVal, strDepotName)
{
if (g_fPrintElapsed)
{
var depot = new Depot('entirebuild', 0);
depot.Begin(dateVal);
g_hTimers['entirebuild'] = depot;
}
}
function ElapsedExit(dateVal, strDepotName)
{
if (g_fPrintElapsed)
{
var depot = g_hTimers['entirebuild'];
if (!depot)
throw new Error(-1, "TaskStep on missing depot " + 'entirebuild');
depot.End(dateVal);
}
}
function StartCFPBTS(dateVal, strDepotName)
{
var depot;
if (true)
{
if (g_CFObj)
EndCFTPB(dateVal, strDepotName);
depot = g_hTimers['toslave'];
if (!depot)
depot = new Depot('toslave', 0);
depot.Begin(dateVal);
depot.SetLast(dateVal);
g_hTimers['toslave'] = depot;
g_CFObj = depot;
// LogMsg("StartCFPBTS at " + ( new Date(dateVal)));
}
}
function StartCFTPB(dateVal, strDepotName)
{
var depot;
if (true)
{
if (g_CFObj)
EndCFTPB(dateVal, strDepotName);
depot = g_hTimers['topostbuild'];
if (!depot)
depot = new Depot('topostbuild', 0);
depot.Begin(dateVal);
depot.SetLast(dateVal);
g_hTimers['topostbuild'] = depot;
g_CFObj = depot;
//LogMsg("StartCFTPB at " + ( new Date(dateVal)));
}
}
function LastFileCFTPB(dateVal, strDepotName)
{
if (true)
{
if (g_CFObj)
{
g_CFObj.SetLast(dateVal);
}
}
}
function EndCFTPB(dateVal, strDepotName)
{
if (true)
{
var depot = null;
if (g_CFObj)
{
depot = g_CFObj;
//LogMsg("EndCFTPB at " + ( new Date(depot.nLast)));
depot.End(depot.nLast);
g_CFObj = null;
}
}
}
function ParseDate(strLine)
{
var a = g_reDate.exec(strLine);
if (!a)
{
throw new Error(-1, "Incorrect date format: " + strLine);
}
var d = new Date(a[1], a[2] - 1, a[3], a[4], a[5], a[6]);
return d.getTime();
}
function GetBuildType(strLine)
{
//Build Type: free
//Build Platform: 64bit
//Incremental Build: false
//Build Manager: BUILDCON1
//PostBuild Machine: AXP64FRE
var str;
var n;
var m;
var fWin64 = false;
var fFree = false;
n = strLine.indexOf("\t");
if (n >= 0)
{
g_strMachine = strLine.slice(0, n);
}
n = strLine.indexOf("razzle.cmd", 0);
if (n > 0)
{ // Extract the stuff between "razzle.cmd" and the first "&"
m = strLine.indexOf("&", n);
str = strLine.slice(n, m);
n = str.indexOf("win64");
if (n >= 0)
fWin64 = true;
n = str.indexOf("free");
if (n >= 0)
fFree = true;
g_strBuildType = (fWin64 ? "64bit " : "32bit ") + (fFree ? "free" : "checked");
}
}
function MergeRoot(str)
{
str = str.toLowerCase();
if (g_fMerged && str == "mergedcomponents")
return "root";
return str;
}
function ParseLogFile(strFileName)
{
var strDepotName;
var hFile = g_FSObj.OpenTextFile(strFileName, 1, false);
var a;
var nLine = 0;
var i;
try
{
while(1)
{
r = hFile.ReadLine();
++nLine;
if (!g_strBuildType)
{
if (g_reBuildType.test(r))
GetBuildType(r);
}
// debugger;
for(i = 0; i < g_aMatches.length; ++i)
{
a = g_aMatches[i].re.exec(r);
if (a != null)
{
if (a.length > 1)
strDepotName = MergeRoot(a[1]);
else
strDepotName = '';
a = a.slice(2);
g_aMatches[i].fn(ParseDate(r), strDepotName, a);
break;
}
}
}
}
catch(ex)
{
if (ex.number != -2146828226) // Input past end
{
LogMsg("Exception in ParseLogFile " + strFileName + ", line=" + nLine + ", ex=" + ex);
LogMsg("I is " + i);
}
}
hFile.Close();
}
function main()
{
var i;
var strDepot;
var depot;
for(i = 0; i < g_aStrFileNames.length; ++i)
{
g_strMachine = null;
g_strBuildType = null;
g_hDepots = new Object;
g_hTimers = new Object;
ParseLogFile(g_aStrFileNames[i]);
if (!g_strMachine)
g_strMachine = g_aStrFileNames[i];
g_strMachine = PadString(PadString(g_strMachine, 12) + g_strBuildType, 24);
//LogMsg(g_strMachine + ": " + g_strBuildType);
for(strDepot in g_hDepots)
{
LogMsg(g_strMachine + ": Depot: " + g_hDepots[strDepot].GetStrStatus());
}
for(strDepot in g_hTimers)
{
LogMsg(g_strMachine + ": " + g_hTimers[strDepot].GetStrStatus());
}
}
}