|
|
//+---------------------------------------------------------------------------
//
// 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()); } } }
|