Best JavaScript code snippet using redwood
executionengine.js
Source:executionengine.js
...49 }50 //git.deleteFiles(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username+"/build"),os.tmpDir()+"jar_"+req.body.executionID);51 deleteDir(os.tmpDir()+"/jar_"+req.body.executionID);52 common.logger.log("Stop button was pushed");53 cleanExecutionMachines(req.body.executionID,function(){54 updateExecution({_id:req.body.executionID},{$set:{status:"Ready To Run"}},true,function(){55 executionsRoute.updateExecutionTotals(req.body.executionID);56 res.contentType('json');57 res.json({success:true});58 delete executions[req.body.executionID];59 });60 });61};62exports.startexecutionPost = function(req, res){63 db = common.getDB();64 if (req.body.testcases.length == 0){65 res.contentType('json');66 res.json({error:"No Test Cases are selected for execution."});67 return;68 }69 var executionID = req.body.executionID;70 var ignoreStatus = req.body.ignoreStatus;71 var ignoreScreenshots = req.body.ignoreScreenshots;72 var allScreenshots = req.body.allScreenshots;73 var ignoreAfterState = req.body.ignoreAfterState;74 var sendEmail = req.body.sendEmail;75 var machines = req.body.machines;76 var variables = {};77 var testcases = req.body.testcases;78 var template = null;79 //clean up previous files if needed80 /*81 for(var file in fileSync){82 if (file.indexOf() != "_id"){83 record.getAt(0).set(propt,item[propt]);84 }85 }86 */87 req.body.variables.forEach(function(variable){88 variables[variable.name] = variable.value;89 });90 var machineConflict = false;91 var updatingConflict = false;92 machines.forEach(function(machine){93 if (machine.state == "Running Test"){94 machineConflict = true;95 }96 else if (machine.state == "Updating"){97 updatingConflict = true;98 }99 });100 if(machineConflict == true){101 res.contentType('json');102 res.json({error:"Selected machines are currently running other tests."});103 return;104 }105 if(updatingConflict == true){106 res.contentType('json');107 res.json({error:"Selected machines are being updated."});108 return;109 }110 if(executions[executionID]){111 res.contentType('json');112 res.json({error:"Execution is already running."});113 return;114 }115 if(req.body.templates){116 template = req.body.templates[0]117 }118 executions[executionID] = {template:template,sendEmail:sendEmail,ignoreAfterState:ignoreAfterState,ignoreStatus:ignoreStatus,ignoreScreenshots:ignoreScreenshots,allScreenshots:allScreenshots,testcases:{},machines:machines,variables:variables,currentTestCases:{},project:req.cookies.project,username:req.cookies.username,returnVars:{}};119 updateExecution({_id:executionID},{$set:{status:"Running",user:req.cookies.username}},false);120 compileBuild(req.cookies.project,req.cookies.username,function(err){121 if (err != null){122 res.contentType('json');123 res.json({error:"Unable to compile scripts."});124 updateExecution({_id:executionID},{$set:{status:"Ready To Run"}},true);125 delete executions[executionID];126 }127 else{128 //copy files for each execution to prevent conflicts129 //git.copyFiles(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username+"/build"),"jar",os.tmpDir()+"/jar_"+executionID,function(){130 copyFiles(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username+"/build"),os.tmpDir()+"/jar_"+executionID,function(){131 copyFiles(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username+"/build/jar"),os.tmpDir()+"/jar_"+executionID,function(){132 zipPythonFiles(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username),os.tmpDir()+"/jar_"+executionID,function(){133 cacheSourceCode(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username),function(sourceCache){134 if(executions[executionID]){135 executions[executionID].sourceCache = sourceCache;136 }137 else{138 return;139 }140 verifyMachineState(machines,function(err){141 if(err){142 updateExecution({_id:executionID},{$set:{status:"Ready To Run"}},true);143 res.contentType('json');144 res.json({error:err});145 //git.deleteFiles(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username+"/build"),os.tmpDir()+"/jar_"+req.body.executionID);146 deleteDir(os.tmpDir()+"/jar_"+req.body.executionID);147 delete executions[executionID];148 return;149 }150 VerifyCloudCapacity(executions[executionID].template,function(response){151 if(response.err || response.capacityAvailable == false){152 var message = "";153 if(response.err){154 message = response.err155 }156 else{157 message = "Cloud does not have the capacity to run this execution."158 }159 updateExecution({_id:executionID},{$set:{status:"Ready To Run",cloudStatus:"Error: "+message}},true);160 res.contentType('json');161 res.json({error:"Cloud Error: "+message});162 //git.deleteFiles(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username+"/build"),os.tmpDir()+"/jar_"+req.body.executionID);163 deleteDir(os.tmpDir()+"/jar_"+req.body.executionID);164 delete executions[executionID];165 return;166 }167 res.contentType('json');168 res.json({success:true});169 lockMachines(machines,executionID,function(){170 if(executions[executionID].template){171 updateExecution({_id:executionID},{$set:{status:"Running",cloudStatus:"Provisioning Virtual Machines..."}},false);172 }173 else{174 updateExecution({_id:executionID},{$set:{status:"Running",cloudStatus:""}},false);175 }176 StartCloudMachines(template,executionID,function(cloudMachines){177 if(cloudMachines.err){178 unlockMachines(machines);179 updateExecution({_id:executionID},{$set:{status:"Ready To Run",cloudStatus:"Error: "+cloudMachines.err}},true);180 //git.deleteFiles(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username+"/build"),os.tmpDir()+"/jar_"+req.body.executionID);181 deleteDir(os.tmpDir()+"/jar_"+req.body.executionID);182 delete executions[executionID];183 return;184 }185 if(executions[executionID].template){186 updateExecution({_id:executionID},{$set:{cloudStatus:"Virtual Machines have been provisioned."}},false);187 }188 executions[executionID].machines = machines.concat(cloudMachines);189 getGlobalVars(executionID,function(){190 testcases.forEach(function(testcase){191 testcase.dbID = testcase.testcaseID;192 if(testcase.tcData){193 testcase.testcaseID = testcase.testcaseID+testcase.rowIndex;194 executions[executionID].testcases[testcase.testcaseID] = testcase;195 }196 else{197 executions[executionID].testcases[testcase.testcaseID] = testcase;198 }199 });200 //see if there is a base state201 suiteBaseState(executionID,executions[executionID].machines,function(){202 //magic happens here203 applyMultiThreading(executionID,function(){204 updateExecution({_id:executionID},{$set:{status:"Running",lastRunDate:new Date()}},false,function(){205 executeTestCases(executions[executionID].testcases,executionID);206 });207 })208 });209 });210 });211 });212 });213 });214 });215 });216 });217 });218 }219 });220};221function zipPythonFiles(projectDir,destDir,callback){222 fs.mkdir(destDir,function(){223 fs.exists(projectDir + "/PythonWorkDir",function(exists){224 if(exists == true){225 git.lsFiles(projectDir + "/src/",["*.py"],function(data){226 if ((data != "")&&(data.indexOf("\n") != -1)){227 var libDir = projectDir + "/PythonWorkDir/Lib";228 if(process.platform != "win32"){229 libDir = projectDir + "/PythonWorkDir/lib/python2.7";230 }231 zipDir(libDir,destDir+"/pythonLibs.zip",['**','!**.pyc','!**/*.pyc'],function(){232 zipDir(projectDir + "/src/",destDir+"/pythonSources.zip",['**/*.py','**.py','**/*.cfg','**/*.ini'],function(){233 callback();234 });235 })236 }237 else{238 callback();239 }240 });241 }242 else{243 callback()244 }245 });246 });247}248function zipDir(sourceDir,targetFile,pattern,callback){249 fs.exists(sourceDir,function(exists){250 if(exists == true){251 var output = fs.createWriteStream(targetFile);252 /*253 var archive = archiver('tar', {254 gzip: true,255 gzipOptions: {256 level: 1257 }258 });259 */260 var archive = archiver('zip');261 output.on('close', function () {262 output.end();263 callback();264 console.log(archive.pointer() + ' total bytes');265 console.log('archiver has been finalized and the output file descriptor has closed.');266 });267 archive.on('error', function(err){268 console.log(err);269 //throw err;270 });271 archive.pipe(output);272 archive.bulk([273 { expand: true, cwd: sourceDir, src: pattern}274 ]);275 archive.finalize();276 }277 else{278 callback()279 }280 })281}282exports.compileBuild = function(project,username,callback){compileBuild(project,username,callback)};283function compileBuild(project,username,callback){284 var workDir = rootDir+project+"/"+username;285 var msg = {project:project,username:username,java:true,python:true,csharp:true};286 var compileScripts = function(){287 var compileOut = "";288 //random id for compile proc289 var id;290 for (var i = 0; i < 24; i++) {291 id += Math.floor(Math.random() * 10).toString(16);292 }293 compile.operation(msg,id,function(data){compileOut = compileOut + data},function(){294 if (compileOut.indexOf("BUILD FAILED") != -1){295 callback("unable to compile")296 }297 else{298 callback(null)299 }300 })301 };302 needToCompileJava(workDir,project,function(compileJava){303 msg.java = compileJava;304 needToCompilePython(workDir,project,username,function(compilePython){305 msg.python = compilePython;306 needToCompileCSharp(workDir,project,function(compileCSharp){307 msg.csharp = compileCSharp;308 compileScripts();309 })310 })311 })312}313function needToCompilePython(workDir,project,username,callback){314 var needToCompile = true;315 if(compilations[project+username+"python"]){316 git.filesModifiedSinceDate(workDir,compilations[project+username+"python"],function(data){317 if (data == ""){318 needToCompile = false;319 }320 else{321 compilations[project+username+"python"] = new Date();322 }323 callback(needToCompile)324 });325 }326 else{327 compilations[project+username+"python"] = new Date();328 callback(needToCompile);329 }330}331function needToCompileJava(workDir,project,callback){332 var needToCompile = true;333 fs.exists(workDir+"/build/jar/"+project+".jar", function (exists) {334 if(exists == true){335 fs.stat(workDir+"/build/jar/"+project+".jar",function(err,stats){336 if(err) {337 callback(needToCompile);338 }339 else{340 git.filesModifiedSinceDate(workDir,stats.mtime,function(data){341 if (data == ""){342 needToCompile = false;343 }344 callback(needToCompile)345 });346 }347 });348 }349 else{350 callback(needToCompile);351 }352 });353}354function needToCompileCSharp(workDir,project,callback){355 var needToCompile = true;356 fs.exists(workDir+"/build/RedwoodHQAutomation.dll", function (exists) {357 if(exists == true){358 fs.stat(workDir+"/build/RedwoodHQAutomation.dll",function(err,stats){359 if(err) {360 callback(needToCompile);361 }362 else{363 git.filesModifiedSinceDate(workDir,stats.mtime,function(data){364 if (data == ""){365 needToCompile = false;366 }367 callback(needToCompile)368 });369 }370 });371 }372 else{373 callback(needToCompile);374 }375 });376}377function applyMultiThreading(executionID,callback){378 var count = 0;379 var mainMachinesCount = executions[executionID].machines.length;380 executions[executionID].machines.forEach(function(machine){381 db.collection('machines', function(err, collection) {382 collection.findOne({_id:new ObjectID(machine._id)}, {}, function(err, dbMachine) {383 var startThread = 0;384 if(dbMachine){385 startThread = dbMachine.takenThreads - machine.threads;386 }387 //if(startThread != 0){388 // startThread = dbMachine.lastStartThread + 1389 //}390 //collection.findAndModify({_id:new ObjectID(machine._id)},{},{$set:{lastStartThread:startThread}},{safe:true,new:true},function(err,data){391 //});392 common.logger.info("staring at:"+startThread);393 machine.threadID = startThread;394 //if more than one thread run base state if not let it go395 if (machine.threads > 1){396 machine.multiThreaded = true;397 agentBaseState(executions[executionID].project+"/"+executions[executionID].username,executionID,machine.host,machine.port,machine.threadID,function(err){398 machine.runBaseState = true;399 var newMachineCount = 1;400 for(var i=machine.threads;i>1;i--){401 var newMachine = {};402 for (var key in machine) {403 newMachine[key] = machine[key];404 }405 newMachine.threadID = i+startThread-1;406 common.logger.info(newMachine);407 if(!executions[executionID]) return;408 executions[executionID].machines.push(newMachine);409 sendAgentCommand(newMachine.host,newMachine.port,{command:"start launcher",executionID:executionID,threadID:newMachine.threadID},3,function(err){410 newMachineCount++;411 if (newMachineCount == machine.threads){412 count++;413 if(count == mainMachinesCount){414 callback();415 }416 }417 });418 }419 });420 }421 else{422 count++;423 if(count == mainMachinesCount){424 callback();425 }426 }427 });428 });429 });430}431function suiteBaseState(executionID,machines,callback){432 var count = 0;433 var foundSuiteState = false;434 var suiteBaseTCs = [];435 var lastMachine = function(){436 if (count === machines.length){437 if (suiteBaseTCs.length > 0){438 executions[executionID].cachedTCs = executions[executionID].testcases;439 executions[executionID].testcases = {};440 suiteBaseTCs.forEach(function(tc){441 executions[executionID].testcases[tc.testcaseID] = tc;442 });443 executions[executionID].baseStateFailed = false;444 }445 callback()446 }447 };448 machines.forEach(function(machine){449 if(machine.baseState){450 foundSuiteState = true;451 machine.roles.push(machine.host);452 db.collection('testcases', function(err, collection) {453 collection.insert({baseState:true,name:machine.host+"_state",status:"Automated",type:"collection",collection:[{order:"1",actionid:machine.baseState,host:machine.host,executionflow:"Record Error Stop Test Case",parameters:[]}]}, {safe:true},function(err,testcaseData){454 db.collection('executiontestcases', function(err, collection) {455 //collection.save({_id:machine.resultID},{},{$set:{executionID:executionID,name:machine.host+"_state",status:"Not Run",testcaseID:testcaseData[0]._id.__id,_id: machine.resultID}}, {safe:true,new:true},function(err,returnData){456 collection.save({baseState:true,executionID:executionID,name:machine.host+"_state",status:"Not Run",testcaseID:testcaseData[0]._id.toString(),_id: machine.baseStateTCID},function(err,returnData){457 suiteBaseTCs.push({testcaseID:testcaseData[0]._id.toString(),retryCount:0,_id:machine.baseStateTCID,status:"Not Run",name:machine.host+"_state",dbID:testcaseData[0]._id.toString(),type:"collection"});458 count++;459 lastMachine();460 });461 });462 });463 });464 }465 else{466 count++;467 }468 lastMachine();469 });470}471exports.cacheSourceCode = function(rootPath,callback){cacheSourceCode(rootPath,callback)};472function cacheSourceCode(rootPath,callback){473 git.lsFiles(rootPath,["*.groovy","*.java"],function(data){474 var files = [];475 if ((data != "")&&(data.indexOf("\n") != -1)){476 files = data.split("\n",data.match(/\n/g).length);477 }478 callback(files);479 })480}481function getGlobalVars(executionID,callback){482 db.collection('variables', function(err, collection) {483 collection.find({taskVar:false}, {}, function(err, cursor) {484 cursor.each(function(err, variable) {485 if(variable == null) {486 callback();487 }488 else{489 executions[executionID].variables[variable.name] = variable.value;490 }491 });492 })493 });494}495function cleanUpMachines(machines,executionID,callback){496 var count = 0;497 machines.forEach(function(machine){498 sendAgentCommand(machine.host,machine.port,{command:"cleanup",executionID:executionID},3,function(err){499 count++;500 if(count == machines.length){501 if(callback) callback();502 }503 });504 })505}506function executeTestCases(testcases,executionID){507 if (!executions[executionID]) return;508 executions[executionID].executingTCs = true;509 var variables = executions[executionID].variables;510 var machines = executions[executionID].machines;511 var tcArray = [];512 for(var key in testcases){513 tcArray.push(key);514 }515 //execution all done516 //if (tcArray.length == 0){517 var finishExecution = function(callback){518 if (executions[executionID].cachedTCs){519 if(executions[executionID].baseStateFailed === true){520 unlockCloudMachines(executions[executionID].machines);521 unlockMachines(machines,function(){522 cleanUpMachines(executions[executionID].machines,executionID,function(){523 });524 updateExecution({_id:executionID},{$set:{status:"Ready To Run"}},true,function(){525 executionsRoute.updateExecutionTotals(executionID,function(){526 if(executions[executionID].sendEmail == true) sendNotification(executionID);527 //git.deleteFiles(path.join(__dirname, '../public/automationscripts/'+executions[executionID].project+"/"+executions[executionID].username+"/build"),os.tmpDir()+"/jar_"+executionID);528 deleteDir(os.tmpDir()+"/jar_"+executionID);529 delete executions[executionID];530 });531 });532 callback(true)533 });534 return;535 }536 executions[executionID].machines.forEach(function(machine){537 machine.baseState = null;538 });539 executions[executionID].testcases = executions[executionID].cachedTCs;540 delete executions[executionID].cachedTCs;541 tcArray = [];542 for(key in executions[executionID].testcases){543 tcArray.push(key);544 }545 testcases = executions[executionID].testcases;546 callback(false)547 }548 else{549 if(executions[executionID]){550 var shouldFinish = true;551 //if something is running dont finish the execution552 for(var tc in executions[executionID].testcases) {553 if(tc.finished == false) shouldFinish = false;554 }555 if(shouldFinish == false) return;556 unlockCloudMachines(executions[executionID].machines);557 unlockMachines(executions[executionID].machines,function(){558 if(!executions[executionID]) return;559 cleanUpMachines(executions[executionID].machines,executionID,function(){560 });561 updateExecution({_id:executionID},{$set:{status:"Ready To Run"}},true,function(){562 executionsRoute.updateExecutionTotals(executionID,function(){563 if(executions[executionID] && executions[executionID].sendEmail == true) sendNotification(executionID);564 //git.deleteFiles(path.join(__dirname, '../public/automationscripts/'+executions[executionID].project+"/"+executions[executionID].username+"/build"),os.tmpDir()+"/jar_"+executionID);565 deleteDir(os.tmpDir()+"/jar_"+executionID);566 delete executions[executionID];567 });568 });569 callback(true)570 });571 }572 //return;573 }574 };575 var count = 0;576 var doneCount = 0;577 var nextTC = function(){578 if (!testcases[tcArray[count]]){579 executions[executionID].executingTCs = false;580 return;581 }582 if (testcases[tcArray[count]].executing == true){583 count++;584 nextTC();585 return;586 }587 else if(testcases[tcArray[count]].finished == true){588 count++;589 doneCount++;590 if (doneCount == tcArray.length){591 finishExecution(function(finishIt){592 if(finishIt == false){593 count = 0;594 nextTC();595 }596 else{597 if(executions[executionID]) executions[executionID].executingTCs = false;598 }599 });600 return;601 }602 nextTC();603 return;604 }605 testcases[tcArray[count]].executing = true;606 startTCExecution(testcases[tcArray[count]].testcaseID,testcases[tcArray[count]].dbID,variables,executionID,function(){607 if (!executions[executionID]) return;608 count++;609 var machineAvailable = false;610 machines.forEach(function(machine){611 if(machine.runningTC == undefined){612 machineAvailable = true;613 }614 });615 if((count < tcArray.length)&&(machineAvailable == true)){616 nextTC();617 }618 else{619 executions[executionID].executingTCs = false;620 //remove any useless machines621 var toRemove = [];622 machines.forEach(function(machine){623 if(machine.runningTC == undefined){624 //don't remove any machines if this is just a suite base state that is running625 if(!executions[executionID].cachedTCs){626 toRemove.push(machine)627 }628 }629 });630 unlockMachines(toRemove,function(){631 toRemove.forEach(function(machine){632 machines.splice(machines.indexOf(machine),1);633 });634 });635 //if nothing else to execute finish it.636 var somethingToRun = false;637 tcArray.forEach(function(testcaseCount){638 if(testcases[testcaseCount].finished != true){639 somethingToRun = true;640 }641 });642 if(somethingToRun == false){643 finishExecution(function(finishIt){644 if(finishIt == false){645 count = 0;646 nextTC();647 }648 else{649 if(executions[executionID]) executions[executionID].executingTCs = false;650 }651 });652 }653 }654 });655 };656 if (count == 0) nextTC();657}658function startTCExecution(id,dbID,variables,executionID,callback){659 GetTestCaseDetails(id,dbID,executionID,function(testcase,result,hosts){660 if(testcase == null){661 callback();662 return;663 }664 //if(executions[executionID].testcases[id].tcData && executions[executionID].testcases[id].tcData != ""){665 // testcase.tcData = executions[executionID].testcases[id].tcData;666 //}667 testcase.variables = {};668 testcase.machines = [];669 testcase.machineVars = [];670 var reservedHosts = [];671 var busyMachines = false;672 if(!executions[executionID]) return;673 executions[executionID].machines.forEach(function(machine,index){674 if(machine.runningTC != undefined){675 busyMachines = true;676 }677 hosts.forEach(function(host){678 if((machine.roles.indexOf(host) != -1)&& (reservedHosts.indexOf(host) == -1) &&((machine.runningTC == undefined)||(machine.runningTC == testcase))){679 machine.runningTC = testcase;680 reservedHosts.push(host);681 testcase.machines.push(machine);682 machine.roles.forEach(function(role){683 if (machine.machineVars){684 machine.machineVars.forEach(function(variable){685 testcase.machineVars["Machine."+role+"."+variable.name] = variable.value686 });687 }688 testcase.machineVars["Machine."+role+".Host"] = machine.host;689 testcase.machineVars["Machine."+role+".Port"] = machine.port;690 })691 }692 });693 });694 if ((testcase.machines.length == 0) || (reservedHosts.length != hosts.length)){695 if(busyMachines == true){696 executions[executionID].testcases[id].executing = false;697 callback();698 return;699 }700 }701 result.status = "Running";702 createResult(result,function(writtenResult){703 result._id = writtenResult[0]._id;704 result.executionID = executionID;705 if(executions[executionID].testcases[id].tcData && executions[executionID].testcases[id].tcData != ""){706 result.tcData = executions[executionID].testcases[id].tcData;707 result.rowIndex = executions[executionID].testcases[id].rowIndex;708 }709 if(!executions[executionID]) return;710 executions[executionID].currentTestCases[id] = {testcase:testcase,result:result,executionTestCaseID:id};711 for (var attrname in testcase.machineVars) { testcase.variables[attrname] = testcase.machineVars[attrname]; }712 for (var attrname in variables) { testcase.variables[attrname] = variables[attrname]; }713 if(result.rowIndex){714 testcase.variables["Framework.TestCaseName"] = testcase.dbTestCase.name+"_"+result.rowIndex;715 }716 else{717 testcase.variables["Framework.TestCaseName"] = testcase.dbTestCase.name;718 }719 if (result.tcData){720 for (var tcDataColumn in result.tcData) { testcase.variables["TCData."+tcDataColumn] = result.tcData[tcDataColumn]; }721 }722 //testcase.machines = [];723 testcase.startDate = new Date();724 if (((testcase.dbTestCase.status != "Automated")||(testcase.statusError)) && (executions[executionID].ignoreStatus == false)){725 var error = "";726 if (testcase.statusError){727 error = testcase.statusError728 }else if(testcase.dbTestCase.status == "To be Automated"){729 error = "Test Case is not Automated"730 }else if(testcase.dbTestCase.status == "Needs Maintenance"){731 error = "Test Case Needs Maintenance"732 }733 //if (callback){734 // callback({error:error});735 //}736 result.error = testcase.dbTestCase.status;737 result.status = "Not Run";738 //result.result = testcase.dbTestCase.status;739 result.result = error;740 updateResult(result);741 //executions[executionID].testcases[id].result = result;742 finishTestCaseExecution(executions[executionID],executionID,executions[executionID].testcases[id]._id,executions[executionID].currentTestCases[id]);743 callback();744 return;745 }746 //if there is nothing to execute just finish the TC747 if (((testcase.dbTestCase.type === "collection")&&(testcase.actions.length == 0)) || ((testcase.dbTestCase.type === "script")&&(testcase.dbTestCase.script == ""))){748 //if (callback){749 // callback();750 //}751 result.status = "Finished";752 result.result = "Passed";753 updateResult(result);754 finishTestCaseExecution(executions[executionID],executionID,executions[executionID].testcases[id]._id,executions[executionID].currentTestCases[id]);755 callback();756 return;757 }758 //updateExecutionTestCase({_id:testcases[0]._id.executionTestCaseID},{$set:{"status":"Running"}});759 var machines = executions[executionID].machines;760 machines.sort(function(a,b){761 return a.roles.length - b.roles.length;762 });763 /*764 var reservedHosts = [];765 testcase.machines = [];766 testcase.machineVars = [];767 machines.forEach(function(machine,index){768 hosts.forEach(function(host){769 if((machine.roles.indexOf(host) != -1)&& (reservedHosts.indexOf(host) == -1) &&((machine.runningTC == undefined)||(machine.runningTC == testcase))){770 machine.runningTC = testcase;771 reservedHosts.push(host);772 testcase.machines.push(machine);773 machine.roles.forEach(function(role){774 if (machine.machineVars){775 machine.machineVars.forEach(function(variable){776 testcase.machineVars["Machine."+role+"."+variable.name] = variable.value777 });778 }779 testcase.machineVars["Machine."+role+".Host"] = machine.host;780 testcase.machineVars["Machine."+role+".Port"] = machine.port;781 })782 }783 });784 });785 */786 if ((testcase.machines.length == 0) || (reservedHosts.length != hosts.length)){787 //if (callback){788 // callback({error:"Unable to find matching machine for this test case. Roles required are:"+hosts.join()});789 //}790 //updateExecutionTestCase({_id:executions[executionID].testcases[id]._id},{$set:{"status":"Finished",result:"Failed",resultID:result._id,error:"Unable to find matching machine for this test case. Roles required are:"+hosts.join()}});791 result.error = "Unable to find matching machine for this test case. Roles required are:"+hosts.join();792 result.status = "Finished";793 result.result = "Failed";794 updateResult(result);795 finishTestCaseExecution(executions[executionID],executionID,executions[executionID].testcases[id]._id,executions[executionID].currentTestCases[id]);796 callback();797 return;798 }799 var count = 0;800 var errorFound = false;801 //var startTC = function(){802 //var agentInstructions = {command:"run action",executionID:executionID,testcaseID:testcase.dbTestCase._id,variables:executions[executionID].variables};803 var agentInstructions = {command:"run action",executionID:executionID,testcaseID:id,variables:executions[executionID].variables};804 var foundMachine = null;805 var runBaseState = function(){806 agentBaseState(executions[executionID].project+"/"+executions[executionID].username,executionID,foundMachine.host,foundMachine.port,foundMachine.threadID,function(err){807 if (err){808 result.error = err.error;809 result.status = "Finished";810 result.result = "Failed";811 updateResult(result);812 if (executions[executionID] && executions[executionID].currentTestCases[id]){813 executions[executionID].currentTestCases[id].result = result;814 finishTestCaseExecution(executions[executionID],executionID,executions[executionID].testcases[id]._id,executions[executionID].currentTestCases[id]);815 }816 }817 else{818 foundMachine.runBaseState = true;819 sendAgentCommand(foundMachine.host,foundMachine.port,agentInstructions,3);820 }821 });822 };823 //if test case is a script and NOT an action collection824 if (testcase.dbTestCase.type !== "collection"){825 if ((testcase.script == "") || (!testcase.script)){826 result.error = "Test Case does not have a script assigned";827 result.status = "Finished";828 result.result = "Failed";829 updateResult(result);830 //executions[executionID].testcases[id].result = result;831 finishTestCaseExecution(executions[executionID],executionID,executions[executionID].testcases[id]._id,executions[executionID].currentTestCases[id]);832 return;833 }834 agentInstructions.name = testcase.name;835 agentInstructions.ignoreScreenshots = executions[executionID].ignoreScreenshots;836 agentInstructions.allScreenshots = executions[executionID].allScreenshots;837 agentInstructions.executionID = executionID;838 agentInstructions.testcaseName = testcase.name;839 agentInstructions.script = testcase.script;840 agentInstructions.scriptLang = testcase.scriptLang;841 agentInstructions.resultID = result._id.toString();842 agentInstructions.parameters = [];843 agentInstructions.type = testcase.dbTestCase.type;844 var actionHost = "Default";845 //if(action.dbAction.host != "") actionHost = action.dbAction.host;846 testcase.machines.forEach(function(machine){847 if ((machine.roles.indexOf(actionHost) != -1)&&(foundMachine == null)){848 foundMachine = machine;849 }850 });851 agentInstructions.threadID = foundMachine.threadID;852 updateExecutionTestCase({_id:executions[executionID].testcases[id]._id},{$set:{"status":"Running","result":"",error:"",trace:"",resultID:result._id,startdate:testcase.startDate,enddate:"",runtime:"",host:foundMachine.host,vncport:foundMachine.vncport}},foundMachine.host,foundMachine.vncport);853 executionsRoute.updateExecutionTotals(executionID);854 if (foundMachine.runBaseState === true){855 if (foundMachine.multiThreaded == true){856 sendAgentCommand(foundMachine.host,foundMachine.port,agentInstructions,30);857 }858 else{859 //make sure the files are actually there, in case of revert to snapshot or not persistent VMs files860 //could have changed while test case was running861 sendAgentCommand(foundMachine.host,foundMachine.port,{command:"files loaded",executionID:executionID},30,function(message){862 if (message.loaded == true){863 sendAgentCommand(foundMachine.host,foundMachine.port,agentInstructions,30);864 }865 else{866 runBaseState();867 }868 });869 }870 }871 else{872 runBaseState();873 }874 callback();875 return;876 }877 findNextAction(testcase.actions,testcase.variables,function(action){878 if (!executions[executionID]) return;879 if(!executions[executionID].currentTestCases[id]) return;880 if(action == null){881 finishTestCaseExecution(executions[executionID],executionID,executions[executionID].testcases[id]._id,executions[executionID].currentTestCases[id]);882 return;883 }884 executions[executionID].currentTestCases[id].currentAction = action;885 agentInstructions.name = action.name;886 agentInstructions.executionflow = action.dbAction.executionflow;887 agentInstructions.executionID = executionID;888 agentInstructions.ignoreScreenshots = executions[executionID].ignoreScreenshots;889 agentInstructions.allScreenshots = executions[executionID].allScreenshots;890 agentInstructions.returnValueName = action.dbAction.returnvalue;891 agentInstructions.testcaseName = testcase.dbTestCase.name;892 agentInstructions.script = action.script;893 agentInstructions.scriptLang = action.scriptLang;894 agentInstructions.resultID = result._id.toString();895 agentInstructions.parameters = [];896 action.dbAction.parameters.forEach(function(parameter){897 agentInstructions.parameters.push({name:parameter.paramname,value:parameter.paramvalue});898 });899 var actionHost = "Default";900 if(action.dbAction.host != "") actionHost = action.dbAction.host;901 testcase.machines.forEach(function(machine){902 if ((machine.roles.indexOf(actionHost) != -1)&&(foundMachine == null)){903 foundMachine = machine;904 }905 });906 callback();907 agentInstructions.threadID = foundMachine.threadID;908 updateExecutionTestCase({_id:executions[executionID].testcases[id]._id},{$set:{"status":"Running","result":"",error:"",trace:"",resultID:result._id,startdate:testcase.startDate,enddate:"",runtime:"",host:foundMachine.host,vncport:foundMachine.vncport}},foundMachine.host,foundMachine.vncport);909 if ((testcase.machines.length > 0) &&((testcase.machines[0].baseState))){910 updateExecutionMachine(executionID,testcase.machines[0]._id,"",result._id.toString());911 }912 executionsRoute.updateExecutionTotals(executionID);913 if (foundMachine.runBaseState === true){914 if (foundMachine.multiThreaded == true){915 sendAgentCommand(foundMachine.host,foundMachine.port,agentInstructions,30);916 }917 else{918 //make sure the files are actually there, in case of revert to snapshot or not persistent VMs files919 //could have changed while test case was running920 sendAgentCommand(foundMachine.host,foundMachine.port,{command:"files loaded",executionID:executionID},30,function(message){921 if (message.loaded == true){922 sendAgentCommand(foundMachine.host,foundMachine.port,agentInstructions,30);923 }924 else{925 runBaseState();926 }927 });928 }929 }930 else{931 runBaseState();932 }933 });934 })935 });936}937exports.logPost = function(req,res){938 var insertLogMessage = function(record){939 var executionID = record.executionID.replace(/-/g, '');940 delete record.command;941 delete record.executionID;942 db.collection('executionlogs'+executionID, function(err, collection) {943 collection.insert(record, {safe:true},function(err,returnData){944 });945 });946 };947 if(Array.isArray(req.body) == true){948 req.body.forEach(function(record){949 insertLogMessage(record);950 });951 realtime.emitMessage("AddExecutionLog",req.body);952 }953 else{954 insertLogMessage(req.body);955 realtime.emitMessage("AddExecutionLog",[req.body]);956 }957 res.contentType('json');958 res.set('Connection','Close');959 res.json({success:true});960};961exports.actionresultPost = function(req, res){962 res.contentType('json');963 res.set('Connection','Close');964 res.json({success:true});965 var execution = executions[req.body.executionID];966 if (!execution) return;967 var testcase = execution.currentTestCases[req.body.testcaseID];968 if (testcase == undefined) return;969 if (testcase.testcase.script){970 testcase.result.status = "Finished";971 testcase.result.result = req.body.result;972 if (req.body.error){973 testcase.result.error = req.body.error;974 }975 else{976 testcase.result.error = "";977 }978 if (req.body.trace){979 formatTrace(req.body.trace,execution.sourceCache,function(trace){980 testcase.result.trace = trace;981 testcase.trace = trace;982 if(trace == "") testcase.result.trace = req.body.trace;983 updateResult(testcase.result);984 });985 }986 else{987 updateResult(testcase.result);988 }989 finishTestCaseExecution(execution,req.body.executionID,execution.testcases[testcase.executionTestCaseID]._id,testcase);990 return;991 }992 var actionFlow = testcase.currentAction.dbAction.executionflow;993 testcase.currentAction.result.status = "Finished";994 testcase.currentAction.result.result = req.body.result;995 if (req.body.error && actionFlow != "Ignore Error Continue Test Case"){996 testcase.result.error = req.body.error;997 testcase.currentAction.result.error = req.body.error;998 }999 if(!testcase.result.error){1000 testcase.result.error = "";1001 }1002 if (req.body.trace && actionFlow != "Ignore Error Continue Test Case"){1003 testcase.result.trace = req.body.trace;1004 testcase.currentAction.result.trace = req.body.trace;1005 testcase.trace = req.body.trace;1006 }1007 if (req.body.screenshot){1008 testcase.result.screenshot = req.body.screenshot;1009 testcase.currentAction.result.screenshot = req.body.screenshot;1010 }1011 if ((req.body.returnValue)&&(testcase.currentAction.dbAction.returnvalue != "")){1012 if(!execution.returnVars[req.body.testcaseID]){1013 execution.returnVars[req.body.testcaseID] = {};1014 }1015 execution.returnVars[req.body.testcaseID][testcase.currentAction.dbAction.returnvalue] = req.body.returnValue;1016 //.[testcase.currentAction.dbAction.returnvalue] = req.body.returnValue;1017 //execution.variables[testcase.currentAction.dbAction.returnvalue] = req.body.returnValue;1018 }1019 if (req.body.result == "Failed"){1020 if (actionFlow == "Record Error Stop Test Case"){1021 testcase.result.status = "Finished";1022 testcase.result.result = "Failed";1023 testcase.runAfterState = true;1024 testcase.testcase.actions.forEach(function(action){1025 if(!action.dbAction.afterState == true){1026 action.runAction = false;1027 }1028 });1029 //updateExecutionTestCase({_id:execution.testcases[testcase.executionTestCaseID]._id},{$set:{error:testcase.result.error,trace:testcase.trace}});1030 /*1031 markFinishedResults(testcase.result.children,execution.sourceCache,function(){1032 updateResult(testcase.result);1033 });1034 finishTestCaseExecution(execution,req.body.executionID,execution.testcases[testcase.executionTestCaseID]._id,testcase);1035 return;1036 */1037 }1038 else if (actionFlow == "Record Error Continue Test Case"){1039 testcase.result.result = "Failed";1040 updateExecutionTestCase({_id:execution.testcases[testcase.executionTestCaseID]._id},{$set:{result:"Failed",trace:testcase.trace}});1041 }1042 else{1043 testcase.currentAction.result.result = "";1044 testcase.currentAction.result.trace = "";1045 testcase.currentAction.result.error = "";1046 //testcase.result.result = "";1047 //testcase.result.error = "";1048 }1049 }1050 var actionVariables = {};1051 for (var attrname in testcase.testcase.variables) { actionVariables[attrname] = testcase.testcase.variables[attrname]; }1052 for (var attrname in testcase.machineVars) { actionVariables[attrname] = testcase.machineVars[attrname]; }1053 if(execution.returnVars[testcase.executionTestCaseID]){1054 for (var attrname in execution.returnVars[testcase.executionTestCaseID]) { actionVariables[attrname] = execution.returnVars[testcase.executionTestCaseID][attrname]; }1055 }1056 findNextAction(testcase.testcase.actions,actionVariables,function(action){1057 if(action == null){1058 testcase.result.status = "Finished";1059 if(testcase.result.result != "Failed") testcase.result.result = "Passed";1060 markFinishedResults(testcase.result.children,execution.sourceCache,function(){1061 updateResult(testcase.result);1062 });1063 finishTestCaseExecution(execution,req.body.executionID,execution.testcases[testcase.executionTestCaseID]._id,testcase);1064 return;1065 }1066 else{1067 markFinishedResults(testcase.result.children,execution.sourceCache,function(){1068 updateResult(testcase.result);1069 });1070 }1071 var foundMachine = null;1072 var actionHost = "Default";1073 if(action.dbAction.host != "") actionHost = action.dbAction.host;1074 testcase.testcase.machines.forEach(function(machine){1075 if ((machine.roles.indexOf(actionHost) != -1)&&(foundMachine == null)){1076 foundMachine = machine;1077 }1078 });1079 updateExecutionTestCase({_id:execution.testcases[testcase.executionTestCaseID]._id},{$set:{"status":"Running","result":"",host:foundMachine.host,vncport:foundMachine.vncport}},foundMachine.host,foundMachine.vncport);1080 testcase.result.status = "Running";1081 var agentInstructions = {command:"run action",executionID:req.body.executionID,threadID:foundMachine.threadID,testcaseID:testcase.executionTestCaseID,variables:testcase.testcase.variables};1082 execution.currentTestCases[testcase.executionTestCaseID].currentAction = action;1083 agentInstructions.name = action.name;1084 agentInstructions.executionflow = action.dbAction.executionflow;1085 agentInstructions.executionID = req.body.executionID;1086 agentInstructions.ignoreScreenshots = executions[req.body.executionID].ignoreScreenshots;1087 agentInstructions.allScreenshots = executions[req.body.executionID].allScreenshots;1088 agentInstructions.returnValueName = action.dbAction.returnvalue;1089 agentInstructions.testcaseName = testcase.testcase.dbTestCase.name;1090 agentInstructions.script = action.script;1091 agentInstructions.scriptLang = action.scriptLang;1092 agentInstructions.resultID = testcase.result._id.toString();1093 agentInstructions.parameters = [];1094 action.dbAction.parameters.forEach(function(parameter){1095 agentInstructions.parameters.push({name:parameter.paramname,value:parameter.paramvalue});1096 });1097 var runBaseState = function(){1098 agentBaseState(execution.project+"/"+execution.username,req.body.executionID,foundMachine.host,foundMachine.port,foundMachine.threadID,function(err){1099 if (err){1100 testcase.result.error = err.error;1101 testcase.result.status = "Finished";1102 testcase.result.result = "Failed";1103 updateResult(testcase.result);1104 if (execution && testcase.dbTestCase){1105 execution.currentTestCases[testcase.executionTestCaseID].result = "Failed";1106 finishTestCaseExecution(execution,req.body.executionID,execution.testcases[id]._id,execution.currentTestCases[testcase.executionTestCaseID]);1107 }1108 }1109 else{1110 foundMachine.runBaseState = true;1111 sendAgentCommand(foundMachine.host,foundMachine.port,agentInstructions,3);1112 }1113 });1114 };1115 if (foundMachine.runBaseState === true){1116 if (foundMachine.multiThreaded == true){1117 sendAgentCommand(foundMachine.host,foundMachine.port,agentInstructions,3);1118 }1119 else{1120 //make sure the files are actually there, in case of revert to snapshot or not persistent VMs files1121 //could have changed while test case was running1122 sendAgentCommand(foundMachine.host,foundMachine.port,{command:"files loaded",executionID:req.body.executionID},3,function(message){1123 if (message.loaded == true){1124 sendAgentCommand(foundMachine.host,foundMachine.port,agentInstructions,3);1125 }1126 else{1127 runBaseState();1128 }1129 });1130 }1131 }1132 else{1133 runBaseState();1134 }1135 });1136};1137//last action or we are done with the TC1138//start next test case if there is one1139function finishTestCaseExecution(execution,executionID,testcaseId,testcase){1140 //updateExecutionTestCase({_id:execution.testcases[testcase.executionTestCaseID]._id},{$set:{"status":"Finished",result:testcase.result.result}});1141 var date = new Date();1142 var status = "Finished";1143 if((testcase.result.result != "Passed") && (testcase.result.result != "Failed")){1144 status = "Not Run";1145 }1146 var updateTC = function(){1147 updateExecutionTestCase({_id:testcaseId},{$set:{trace:testcase.trace,"status":status,resultID:testcase.result._id.toString(),result:testcase.result.result,error:testcase.result.error,enddate:date,runtime:date-testcase.testcase.startDate,host:"",vncport:""}});1148 executionsRoute.updateExecutionTotals(executionID);1149 };1150 //update machine base state result1151 if(execution.cachedTCs){1152 if (testcase.testcase.machines.length > 0){1153 updateExecutionMachine(executionID,testcase.testcase.machines[0]._id,testcase.result.result,testcase.result._id.toString(),function(){1154 updateTC();1155 });1156 }1157 else{1158 updateTC();1159 }1160 //updateExecutionMachine({testcase.testcase.machines[0]._id)},{$set:{result:testcase.result.result,resultID:testcase.result._id.__id}});1161 }1162 else{1163 updateTC();1164 }1165 var count = 0;1166 var retry = false;1167 if(testcase.result.result == "Failed"){1168 if (execution.testcases[testcase.executionTestCaseID].retryCount > 0){1169 retry = true;1170 execution.testcases[testcase.executionTestCaseID].retryCount--;1171 execution.testcases[testcase.executionTestCaseID].executing = false;1172 execution.returnVars[testcase.executionTestCaseID] = {};1173 }1174 if (execution.cachedTCs){1175 execution.baseStateFailed = true;1176 }1177 }1178 if(testcase.testcase.machines.length === 0){1179 if (retry == false){1180 //delete execution.testcases[testcase.executionTestCaseID];1181 execution.testcases[testcase.executionTestCaseID].finished = true;1182 execution.testcases[testcase.executionTestCaseID].executing = false;1183 }1184 delete execution.currentTestCases[testcase.executionTestCaseID];1185 executeTestCases(execution.testcases,executionID);1186 return;1187 }1188 testcase.testcase.machines.forEach(function(machine){1189 delete machine.runningTC;1190 count++;1191 if (count == testcase.testcase.machines.length){1192 if (retry == false){1193 //delete execution.testcases[testcase.executionTestCaseID];1194 execution.testcases[testcase.executionTestCaseID].finished = true;1195 execution.testcases[testcase.executionTestCaseID].executing = false;1196 }1197 delete execution.currentTestCases[testcase.executionTestCaseID];1198 //if(execution.executingTCs != true){1199 executeTestCases(execution.testcases,executionID);1200 //}1201 }1202 });1203}1204exports.formatTrace = function(trace,sourceCache,callback){formatTrace(trace,sourceCache,callback)};1205function formatTrace(trace,sourceCache,callback){1206 var newTrace = "";1207 var traceCount = 0;1208 var traces = trace.split(",");1209 traces.forEach(function(line){1210 traceCount++;1211 var fileName = line.substring(line.indexOf("(")+1,line.indexOf(":"));1212 var lineNumber = line.substring(line.indexOf(":")+1,line.indexOf(")"));1213 var location = line.substring(0,line.indexOf("("));1214 location = location.trim();1215 location = location.replace("[","");1216 var count = 0;1217 var found = false;1218 if((location.indexOf("org.codehaus.") != -1) || (location.indexOf("java.lang.") != -1) || (location.indexOf("groovy.lang.") != -1) || (location.indexOf("redwood.launcher.") != -1)|| (location.indexOf("sun.reflect.") != -1)){1219 if (line.indexOf("[") == 0){1220 newTrace += line;1221 }1222 else{1223 newTrace += ",\r\n"+line;1224 }1225 if (traceCount == traces.length){1226 callback(newTrace);1227 }1228 return;1229 }1230 if ((fileName.indexOf(".groovy") != -1) ||(fileName.indexOf(".java") != -1)){1231 sourceCache.forEach(function(file){1232 if (found == true) return;1233 if (file.indexOf("/"+fileName) != -1){1234 if(location.replace(/\./g, '/').indexOf(file.substring(0,file.lastIndexOf("/")).replace("src/", '')) != -1){1235 found = true;1236 var parsedLineNumber = (parseInt(lineNumber,10)-1).toString();1237 newTrace += ",\r\n<a style= 'color: blue;' href='javascript:openScript(""+ file +"",""+ parsedLineNumber +"")'>" + line +"</a>";1238 }1239 }1240 count++;1241 if (count == sourceCache.length){1242 if (found == false){1243 if (line.indexOf("[") == 0){1244 newTrace += line;1245 }1246 else{1247 newTrace += ",\r\n"+line;1248 }1249 }1250 if (traceCount == traces.length){1251 callback(newTrace);1252 }1253 }1254 });1255 }1256 else{1257 if (traceCount == traces.length){1258 callback(newTrace);1259 }1260 }1261 });1262}1263function markFinishedResults(results,sourceCache,callback){1264 var count = 0;1265 var result = "Passed";1266 var status = "Finished";1267 results.forEach(function(action){1268 if (action.status == "Not Run"){1269 if (action.children.length != 0){1270 markFinishedResults(action.children,sourceCache,function(childStatus,childResult,markFinished){1271 action.expanded = false;1272 if (markFinished === true){1273 action.status = "Finished";1274 action.result = "Failed";1275 action.expanded = true;1276 callback("Finished","Failed",true);1277 return;1278 }1279 count++;1280 if (childStatus == "Not Run"){1281 status = "Not Run";1282 result = "";1283 }1284 if((childStatus == "Finished") && (childResult == "Failed")){1285 result = "Failed";1286 action.expanded = true;1287 }1288 if(count == action.children.length){1289 action.result = result;1290 action.status = status;1291 if (status == "Finished"){1292 if ((action.executionflow == "Record Error Stop Test Case")&&(result == "Failed")){1293 callback(status,result,true)1294 }1295 else{1296 callback(status,result)1297 }1298 }1299 else{1300 callback(status,"")1301 }1302 }1303 })1304 }1305 else{1306 callback("Not Run","")1307 }1308 }1309 else{1310 var returnValue;1311 if ((action.executionflow == "Record Error Stop Test Case")&&(action.result == "Failed")){1312 returnValue = function(){callback("Finished","Failed",true)}1313 }1314 else{1315 returnValue = function(){callback("Finished",action.result)}1316 }1317 if(action.result == "Failed"){1318 action.expanded = true;1319 }1320 if(action.trace){1321 formatTrace(action.trace,sourceCache,function(trace){1322 if(trace != "") action.trace = trace;1323 returnValue();1324 })1325 }1326 else{1327 returnValue();1328 }1329 }1330 });1331}1332exports.agentBaseState = function(project,executionID,agentHost,port,threadID,callback){agentBaseState(project,executionID,agentHost,port,threadID,callback)};1333function agentBaseState(project,executionID,agentHost,port,threadID,callback){1334 sendAgentCommand(agentHost,port,{command:"cleanup",executionID:executionID},3,function(message){1335 if (message && message.error){1336 callback(message);1337 return;1338 }1339 if(executions[executionID]){1340 executions[executionID].fileReqs = [];1341 }1342 else if(executionID.indexOf("unittest") == -1){1343 return;1344 }1345 //os.tmpDir()+"/jar_"+executionID1346 syncFilesWithAgent(agentHost,port,path.join(__dirname, '../public/automationscripts/'+project+"/bin"),"executionfiles/"+executionID+"/bin",executionID,function(error){1347 if(error) {callback(error);return}1348 syncFilesWithAgent(agentHost,port,path.join(__dirname, '../launcher'),"executionfiles/"+executionID+"/launcher",executionID,function(error){1349 if(error) {callback(error);return}1350 syncFilesWithAgent(agentHost,port,path.join(__dirname, '../public/automationscripts/'+project+"/External Libraries"),"executionfiles/"+executionID+"/lib",executionID,function(error){1351 if(error) {callback(error);return}1352 syncFilesWithAgent(agentHost,port,os.tmpDir()+"/jar_"+executionID,"executionfiles/"+executionID+"/lib",executionID,function(error){1353 if(error) {callback(error);return}1354 sendAgentCommand(agentHost,port,{command:"start launcher",executionID:executionID,threadID:threadID},3,function(message){1355 if ((message) && (message.error)){1356 callback(message);1357 }1358 else{1359 callback();1360 }1361 });1362 })1363 })1364 })1365 });1366 });1367}1368function syncFilesWithAgent_old(agentHost,port,rootPath,destDir,callback){1369 var walker = walk.walkSync(rootPath);1370 var fileCount = 0;1371 walker.on("file", function (root, fileStats, next) {1372 fileCount++;1373 var path = root.replace(rootPath,"");1374 var dest = "";1375 if (path == ""){1376 dest = destDir +"/"+ fileStats.name;1377 }1378 else{1379 dest = destDir + path+"/"+fileStats.name1380 }1381 sendFileToAgent(root+"/"+fileStats.name,dest,agentHost,port,3,function(){1382 fileCount--;1383 if(fileCount == 0){1384 callback();1385 }1386 });1387 });1388 walker.on("end",function(){1389 if (fileCount == 0) callback();1390 });1391}1392function syncFilesWithAgent(agentHost,port,rootPath,destDir,executionID,callback){1393 var walker = walk.walkSync(rootPath);1394 var fileCount = 0;1395 var files = [];1396 var foundError = false;1397 var sendFiles = function(){1398 if(foundError) return;1399 fileCount++;1400 if (!files[fileCount-1]){1401 callback();1402 return;1403 }1404 sendFileToAgent(files[fileCount-1].file,files[fileCount-1].dest,agentHost,port,3,executionID,function(error){1405 if(error){1406 foundError = true;1407 callback(error);1408 return;1409 }1410 if(fileCount === files.length){1411 callback();1412 }1413 else{1414 sendFiles()1415 }1416 });1417 };1418 walker.on("file", function (root, fileStats, next) {1419 var path = root.replace(rootPath,"");1420 var dest = "";1421 if (path == ""){1422 dest = destDir +"/"+ fileStats.name;1423 }1424 else{1425 dest = destDir + path+"/"+fileStats.name1426 }1427 files.push({file:root+"/"+fileStats.name,dest:dest});1428 /*1429 sendFileToAgent(root+"/"+fileStats.name,dest,agentHost,port,3,executionID,function(error){1430 if(error){1431 foundError = true;1432 callback(error);1433 return;1434 }1435 fileCount++;1436 if(fileCount === files.length){1437 callback();1438 }1439 })1440 */1441 });1442 walker.on("end",function(){1443 if(files.length == 0) {1444 callback();1445 return;1446 }1447 sendFiles();1448 });1449}1450//if agent already got the file in cache don't copy1451function matchFileWithAgent(file,dest,agentHost,port,retryCount,callback){1452 //don't match pythonLibs or python sources1453 if (file.indexOf("pythonLibs.zip", file.length - "pythonLibs.zip".length) !== -1 || file.indexOf("pythonSources.zip", file.length - "pythonSources.zip".length) !== -1){1454 if(callback) callback({error:null,success:true,matched:false});1455 //if(callback) callback();1456 return;1457 }1458 var options = {1459 hostname: agentHost,1460 port: port,1461 path: '/matchfile',1462 method: 'POST',1463 headers: {1464 'Content-Type': 'application/json'1465 }1466 };1467 var req = http.request(options, function(res) {1468 res.setEncoding('utf8');1469 res.on('data', function (chunk) {1470 try{1471 var msg = JSON.parse(chunk);1472 }1473 catch(err){1474 if (callback) callback(err);1475 }1476 if((msg )&&(msg.error != null)){1477 if (callback) callback(msg.error);1478 }1479 else if (msg){1480 if(callback) callback(msg);1481 }1482 else{1483 if(callback) callback();1484 }1485 });1486 });1487 var retryMatch = function(message){1488 if(retryCount <= 0){1489 if (callback) callback("Unable to connect to machine: "+agentHost + " error: " + message);1490 common.logger.error('matchFileWithAgent problem with request: ' + message+ ' ');1491 }1492 else{1493 retryCount--;1494 setTimeout(matchFileWithAgent(file,dest,agentHost,port,retryCount,callback),1000)1495 }1496 };1497 req.on('error', function(e) {1498 retryMatch(e.message)1499 });1500 //fs.readFile(file, function(err, buf) {1501 // write data to request body1502 //req.write(JSON.stringify({dest:dest,file:file,md5:md5(buf)}));1503 var md5sum = require("crypto").createHash('md5');1504 var s = fs.ReadStream(file);1505 fileSync[file] = s;1506 s.on('data',function(d){1507 md5sum.update(d);1508 });1509 s.on('error',function(err){1510 s.destroy.bind(s);1511 retryMatch("Unable to read file:"+file)1512 });1513 s.on('close',function(){1514 var d = md5sum.digest('hex');1515 this.destroy();1516 req.write(JSON.stringify({dest:dest,file:file,md5:d.toString()}));1517 req.end();1518 //md5sum.end();1519 });1520 //});1521}1522function sendFileToAgent(file,dest,agentHost,port,retryCount,executionID,callback){1523 if (file in fileSync){1524 if(fileSync[file].close){1525 fileSync[file].destroy();1526 delete fileSync[file];1527 }1528 }1529 fileSync[file] = true;1530 matchFileWithAgent(file,dest,agentHost,port,0,function(response){1531 if(response && response.matched == true){1532 if(file in fileSync && fileSync[file].close){1533 fileSync[file].destroy();1534 }1535 delete fileSync[file];1536 if (callback) callback();1537 return;1538 }1539 try{1540 var stat = fs.statSync(file);1541 var readStream = fs.createReadStream(file);1542 }1543 catch(e){1544 if (callback) callback({error: "Can't read file: " + file + " " + e.message});1545 return;1546 }1547 fileSync[file] = readStream;1548 var boundary = '--------------------------';1549 for (var i = 0; i < 24; i++) {1550 boundary += Math.floor(Math.random() * 10).toString(16);1551 }1552 var message = '------' + boundary + '\r\n'1553 // use your file's mime type here, if known1554 + 'Content-Disposition: form-data; name="file"; filename="'+dest+'"\r\n'1555 + 'Content-Type: application/octet-stream\r\n'1556 // "name" is the name of the form field1557 // "filename" is the name of the original file1558 + 'Content-Transfer-Encoding: binary\r\n\r\n';1559 var options = {1560 hostname: agentHost,1561 port: port,1562 path: '/fileupload',1563 method: 'POST',1564 headers: {1565 //'Content-Type': 'text/plain'//,1566 'Content-Type': 'multipart/form-data; boundary=----'+boundary,1567 //'Content-Disposition': 'form-data; name="file"; filename="ProjectName.jar"',1568 //'Content-Length': 33601569 //'Content-Length': stat.size + message.length + 30 + boundary.length1570 'Content-Length': stat.size + message.length + boundary.length + 141571 }1572 };1573 var req = http.request(options, function(res) {1574 //res.setEncoding('utf8');1575 res.on('data', function (chunk) {1576 readStream.destroy();1577 if (file in fileSync){1578 if(fileSync[file].close){1579 fileSync[file].destroy();1580 delete fileSync[file];1581 }1582 }1583 if (callback) callback();1584 });1585 res.on('close', function(){1586 if(file in fileSync && fileSync[file].close){1587 fileSync[file].destroy();1588 }1589 delete fileSync[file];1590 readStream.destroy.bind(readStream);1591 });1592 });1593 if( executions[executionID] && executions[executionID].fileReqs){1594 executions[executionID].fileReqs.push(req);1595 }1596 var handleError = function(e){1597 readStream.destroy();1598 if(file in fileSync && fileSync[file].close){1599 fileSync[file].destroy();1600 }1601 delete fileSync[file];1602 if(retryCount <= 0){1603 if (callback) callback({error:'sendFileToAgent problem with request: ' + e.message+ ' file:'+file});1604 common.logger.error('sendFileToAgent problem with request: ' + e.message+ ' file:'+file);1605 }1606 else{1607 retryCount--;1608 setTimeout(sendFileToAgent(file,dest,agentHost,port,retryCount,executionID,callback),1000)1609 }1610 };1611 req.setTimeout(300000, function(){1612 handleError({message:"Unable to connect to machine: "+agentHost + " CONNECTION TIMEOUT"});1613 this.end();1614 });1615 req.on('error', function(e) {1616 handleError(e);1617 this.end();1618 });1619 req.write(message);1620 //readStream.pipe(req, { end: false });1621 readStream.on("error",function(e){1622 this.end();1623 handleError(e);1624 }).pipe(req, { end: false });1625 readStream.on("end", function(){1626 try{1627 req.end('\r\n------' + boundary + '--\r\n');1628 }1629 catch(e){1630 //req.end();1631 readStream.destroy();1632 }1633 });1634 readStream.on('close',function(){1635 if(file in fileSync && fileSync[file].close){1636 fileSync[file].destroy();1637 }1638 delete fileSync[file];1639 })1640 })1641}1642exports.sendAgentCommand = function(agentHost,port,command,retryCount,callback){sendAgentCommand(agentHost,port,command,retryCount,callback)};1643function sendAgentCommand(agentHost,port,command,retryCount,callback){1644 common.logger.info(command);1645 var options = {1646 hostname: agentHost,1647 port: port,1648 path: '/command',1649 method: 'POST',1650 headers: {1651 'Content-Type': 'application/json'1652 }1653 };1654 var req = http.request(options, function(res) {1655 res.setEncoding('utf8');1656 res.on('data', function (chunk) {1657 try{1658 var msg = JSON.parse(chunk);1659 }1660 catch(err){1661 if (callback) callback({error:err});1662 }1663 if((msg )&&(msg.error != null)){1664 if (callback) callback({error:msg.error});1665 }1666 else if (msg){1667 if(callback) callback(msg);1668 }1669 else{1670 if(callback) callback();1671 }1672 });1673 });1674 //req.setTimeout(50000, function(){1675 // if (callback) callback({error:"Unable to connect to machine: "+agentHost + " CONNECTION TIMEOUT"});1676 //});1677 req.on('error', function(e) {1678 retryCount = 0;1679 if(retryCount <= 0){1680 if (callback) callback({error:"Unable to connect to machine: "+agentHost + " error: " + e.message});1681 common.logger.error('sendAgentCommand problem with request: ' + e.message+ ' ');1682 }1683 else{1684 retryCount--;1685 setTimeout(sendAgentCommand(agentHost,port,command,retryCount,callback),3000)1686 }1687 //req.close();1688 });1689 // write data to request body1690 req.write(JSON.stringify(command));1691 req.end();1692}1693function resolveParamValue(value,variables){1694 var returnNULL = false;1695 var resolveVariable = function(stringValue){1696 return stringValue.replace(new RegExp("\\$\\{([\\s\\w_.-]+)\\}", "g" ),function(a,b){1697 if(b in variables){1698 if (variables[b] == "<NULL>"){1699 if (returnNULL == true){1700 return "<NULL>"1701 }1702 else{1703 return "";1704 }1705 }1706 else{1707 return variables[b];1708 }1709 }1710 else{1711 return a;1712 }1713 });1714 };1715 if(Object.prototype.toString.call(value) == '[object Array]'){1716 if((value.length == 1) && (value[0] === "<NULL>")){1717 return [];1718 }1719 else{1720 var returnValue = [];1721 value.forEach(function(arrayItem){1722 returnValue.push(resolveVariable(arrayItem))1723 });1724 return returnValue;1725 }1726 }1727 else if (typeof value != "string"){1728 return value;1729 }1730 if (value.length > 4){1731 if ((value.indexOf("$\{") == 0) &&(value.charAt(value.length -1) == "}") && (value.split("}").length > 1))1732 {1733 returnNULL = true;1734 }1735 }1736 return resolveVariable(value);1737}1738function createResult(result,callback){1739 db.collection('testcaseresults', function(err, collection) {1740 result._id = new ObjectID(result._id);1741 collection.insert(result, {safe:true},function(err,returnData){1742 callback(returnData);1743 });1744 });1745}1746function updateResult(result,callback){1747 db.collection('testcaseresults', function(err, collection) {1748 collection.save(result,{safe:true},function(err,data){1749 if(err) common.logger.error("ERROR updating results: "+err);1750 if (callback){1751 callback(err);1752 }1753 //realtime.emitMessage("UpdateResult",result);1754 realtime.emitMessage("UpdateResult"+result._id.toString(),result);1755 });1756 });1757}1758function updateExecutionTestCase(query,update,machineHost,vncport,callback){1759 db.collection('executiontestcases', function(err, collection) {1760 collection.findAndModify(query,{},update,{safe:true,new:true},function(err,data){1761 if(err) common.logger.error("ERROR updating results: "+err.message);1762 if (data == null){1763 if (callback){1764 callback(err);1765 }1766 return;1767 }1768 if (data && data.status == "Finished"){1769 elasticSearch.indexTCResult(data,"PUT");1770 }1771 if (machineHost){1772 data.host = machineHost;1773 data.vncport = vncport;1774 }1775 realtime.emitMessage("UpdateExecutionTestCase",data);1776 if (callback){1777 callback(err);1778 }1779 });1780 });1781}1782function updateExecution(query,update,finished,callback){1783 db.collection('executions', function(err, collection) {1784 collection.findAndModify(query,{},update,{safe:true,new:true},function(err,data){1785 try{1786 elasticSearch.indexExecution(data);1787 }1788 catch(e){1789 console.log(e);1790 }1791 if(err) {1792 common.logger.error("ERROR updating execution: "+err.message);1793 return;1794 }1795 realtime.emitMessage("UpdateExecutions",data);1796 if(finished === true){1797 realtime.emitMessage("FinishExecution",data);1798 }1799 if (callback){1800 callback(err);1801 }1802 });1803 });1804}1805function updateExecutionMachine(executionID,machineID,result,resultID,callback){1806 db.collection('executions', function(err, collection) {1807 collection.update({_id:executionID,machines:{$elemMatch:{_id:machineID}}},{$set:{'machines.$.result':result,'machines.$.resultID':resultID}},{safe:true,new:true},function(err,data){1808 //realtime.emitMessage("UpdateExecutions",data);1809 if (callback){1810 callback(err);1811 }1812 });1813 });1814}1815function cleanExecutionMachines(executionID,callback){1816 db.collection('executions', function(err, collection) {1817 collection.findOne({_id:executionID},function(err,data){1818 //realtime.emitMessage("UpdateExecutions",data);1819 if(data != null){1820 data.machines.forEach(function(machine){1821 machine.result = "";1822 machine.resultID = "";1823 });1824 collection.save(data,{safe:true},function(err){1825 //realtime.emitMessage("UpdateExecutions",data);1826 if (callback) callback();1827 });1828 }1829 });...
executionengine original.js
Source:executionengine original.js
...32 }33 //git.deleteFiles(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username+"/build"),os.tmpDir()+"jar_"+req.body.executionID);34 deleteDir(os.tmpDir()+"/jar_"+req.body.executionID);35 common.logger.log("Stop button was pushed");36 cleanExecutionMachines(req.body.executionID,function(){37 updateExecution({_id:req.body.executionID},{$set:{status:"Ready To Run"}},true,function(){38 executionsRoute.updateExecutionTotals(req.body.executionID);39 res.contentType('json');40 res.json({success:true});41 delete executions[req.body.executionID];42 });43 });44};45exports.startexecutionPost = function(req, res){46 db = common.getDB();47 if (req.body.testcases.length == 0){48 res.contentType('json');49 res.json({error:"No Test Cases are selected for execution."});50 return;51 }52 var executionID = req.body.executionID;53 var ignoreStatus = req.body.ignoreStatus;54 var ignoreScreenshots = req.body.ignoreScreenshots;55 var allScreenshots = req.body.allScreenshots;56 var ignoreAfterState = req.body.ignoreAfterState;57 var sendEmail = req.body.sendEmail;58 var machines = req.body.machines;59 var variables = {};60 var testcases = req.body.testcases;61 var template = null;62 req.body.variables.forEach(function(variable){63 variables[variable.name] = variable.value;64 });65 var machineConflict = false;66 var updatingConflict = false;67 machines.forEach(function(machine){68 if (machine.state == "Running Test"){69 machineConflict = true;70 }71 else if (machine.state == "Updating"){72 updatingConflict = true;73 }74 });75 if(machineConflict == true){76 res.contentType('json');77 res.json({error:"Selected machines are currently running other tests."});78 return;79 }80 if(updatingConflict == true){81 res.contentType('json');82 res.json({error:"Selected machines are being updated."});83 return;84 }85 if(executions[executionID]){86 res.contentType('json');87 res.json({error:"Execution is already running."});88 return;89 }90 if(req.body.templates){91 template = req.body.templates[0]92 }93 executions[executionID] = {template:template,sendEmail:sendEmail,ignoreAfterState:ignoreAfterState,ignoreStatus:ignoreStatus,ignoreScreenshots:ignoreScreenshots,allScreenshots:allScreenshots,testcases:{},machines:machines,variables:variables,currentTestCases:{},project:req.cookies.project,username:req.cookies.username,returnVars:{}};94 compileBuild(req.cookies.project,req.cookies.username,function(err){95 if (err != null){96 res.contentType('json');97 res.json({error:"Unable to compile scripts."});98 delete executions[executionID];99 }100 else{101 //copy files for each execution to prevent conflicts102 //git.copyFiles(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username+"/build"),"jar",os.tmpDir()+"/jar_"+executionID,function(){103 copyFiles(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username+"/build"),os.tmpDir()+"/jar_"+executionID,function(){104 copyFiles(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username+"/build/jar"),os.tmpDir()+"/jar_"+executionID,function(){105 zipPythonFiles(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username),os.tmpDir()+"/jar_"+executionID,function(){106 cacheSourceCode(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username),function(sourceCache){107 executions[executionID].sourceCache = sourceCache;108 verifyMachineState(machines,function(err){109 if(err){110 updateExecution({_id:executionID},{$set:{status:"Ready To Run"}},true);111 res.contentType('json');112 res.json({error:err});113 //git.deleteFiles(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username+"/build"),os.tmpDir()+"/jar_"+req.body.executionID);114 deleteDir(os.tmpDir()+"/jar_"+req.body.executionID);115 delete executions[executionID];116 return;117 }118 VerifyCloudCapacity(executions[executionID].template,function(response){119 if(response.err || response.capacityAvailable == false){120 var message = "";121 if(response.err){122 message = response.err123 }124 else{125 message = "Cloud does not have the capacity to run this execution."126 }127 updateExecution({_id:executionID},{$set:{status:"Ready To Run",cloudStatus:"Error: "+message}},true);128 res.contentType('json');129 res.json({error:"Cloud Error: "+message});130 //git.deleteFiles(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username+"/build"),os.tmpDir()+"/jar_"+req.body.executionID);131 deleteDir(os.tmpDir()+"/jar_"+req.body.executionID);132 delete executions[executionID];133 return;134 }135 res.contentType('json');136 res.json({success:true});137 lockMachines(machines,executionID,function(){138 if(executions[executionID].template){139 updateExecution({_id:executionID},{$set:{status:"Running",cloudStatus:"Provisioning Virtual Machines..."}},false);140 }141 else{142 updateExecution({_id:executionID},{$set:{status:"Running",cloudStatus:""}},false);143 }144 StartCloudMachines(template,executionID,function(cloudMachines){145 if(cloudMachines.err){146 unlockMachines(machines);147 updateExecution({_id:executionID},{$set:{status:"Ready To Run",cloudStatus:"Error: "+cloudMachines.err}},true);148 //git.deleteFiles(path.join(__dirname, '../public/automationscripts/'+req.cookies.project+"/"+req.cookies.username+"/build"),os.tmpDir()+"/jar_"+req.body.executionID);149 deleteDir(os.tmpDir()+"/jar_"+req.body.executionID);150 delete executions[executionID];151 return;152 }153 if(executions[executionID].template){154 updateExecution({_id:executionID},{$set:{cloudStatus:"Virtual Machines have been provisioned."}},false);155 }156 executions[executionID].machines = machines.concat(cloudMachines);157 getGlobalVars(executionID,function(){158 testcases.forEach(function(testcase){159 executions[executionID].testcases[testcase.testcaseID] = testcase;160 });161 //see if there is a base state162 suiteBaseState(executionID,executions[executionID].machines,function(){163 //magic happens here164 applyMultiThreading(executionID,function(){165 updateExecution({_id:executionID},{$set:{status:"Running",lastRunDate:new Date()}},false,function(){166 executeTestCases(executions[executionID].testcases,executionID);167 });168 })169 });170 });171 });172 });173 });174 });175 });176 });177 });178 });179 }180 });181};182function zipPythonFiles(projectDir,destDir,callback){183 fs.exists(projectDir + "/PythonWorkDir",function(exists){184 if(exists == true){185 git.lsFiles(projectDir + "/src/",["*.py"],function(data){186 if ((data != "")&&(data.indexOf("\n") != -1)){187 zipDir(projectDir + "/PythonWorkDir/Lib",destDir+"/pythonLibs.zip",['**','!**.pyc','!**/*.pyc'],function(){188 zipDir(projectDir + "/src/",destDir+"/pythonSources.zip",['**/*.py','**.py'],function(){189 callback();190 });191 })192 }193 else{194 callback();195 }196 });197 }198 else{199 callback()200 }201 });202}203function zipDir(sourceDir,targetFile,pattern,callback){204 fs.exists(sourceDir,function(exists){205 if(exists == true){206 var output = fs.createWriteStream(targetFile);207 /*208 var archive = archiver('tar', {209 gzip: true,210 gzipOptions: {211 level: 1212 }213 });214 */215 var archive = archiver('zip');216 output.on('close', function () {217 output.end();218 callback();219 console.log(archive.pointer() + ' total bytes');220 console.log('archiver has been finalized and the output file descriptor has closed.');221 });222 archive.on('error', function(err){223 console.log(err);224 //throw err;225 });226 archive.pipe(output);227 archive.bulk([228 { expand: true, cwd: sourceDir, src: pattern}229 ]);230 archive.finalize();231 }232 else{233 callback()234 }235 })236}237exports.compileBuild = function(project,username,callback){compileBuild(project,username,callback)};238function compileBuild(project,username,callback){239 var workDir = rootDir+project+"/"+username;240 var msg = {project:project,username:username,java:true,python:true,csharp:true};241 var compileScripts = function(){242 var compileOut = "";243 //random id for compile proc244 var id;245 for (var i = 0; i < 24; i++) {246 id += Math.floor(Math.random() * 10).toString(16);247 }248 compile.operation(msg,id,function(data){compileOut = compileOut + data},function(){249 if (compileOut.indexOf("BUILD FAILED") != -1){250 callback("unable to compile")251 }252 else{253 callback(null)254 }255 })256 };257 needToCompileJava(workDir,project,function(compileJava){258 msg.java = compileJava;259 needToCompilePython(workDir,project,username,function(compilePython){260 msg.python = compilePython;261 needToCompileCSharp(workDir,project,function(compileCSharp){262 msg.csharp = compileCSharp;263 compileScripts();264 })265 })266 })267}268function needToCompilePython(workDir,project,username,callback){269 var needToCompile = true;270 if(compilations[project+username+"python"]){271 git.commitsSinceDate(workDir,compilations[project+username+"python"],function(data){272 if (data == "0\n"){273 needToCompile = false;274 }275 else{276 compilations[project+username+"python"] = new Date();277 }278 callback(needToCompile)279 });280 }281 else{282 compilations[project+username+"python"] = new Date();283 callback(needToCompile);284 }285}286function needToCompileJava(workDir,project,callback){287 var needToCompile = true;288 fs.exists(workDir+"/build/jar/"+project+".jar", function (exists) {289 if(exists == true){290 fs.stat(workDir+"/build/jar/"+project+".jar",function(err,stats){291 if(err) {292 callback(needToCompile);293 }294 else{295 git.commitsSinceDate(workDir,stats.mtime,function(data){296 if (data == "0\n"){297 needToCompile = false;298 }299 callback(needToCompile)300 });301 }302 });303 }304 else{305 callback(needToCompile);306 }307 });308}309function needToCompileCSharp(workDir,project,callback){310 var needToCompile = true;311 fs.exists(workDir+"/build/RedwoodHQAutomation.dll", function (exists) {312 if(exists == true){313 fs.stat(workDir+"/build/RedwoodHQAutomation.dll",function(err,stats){314 if(err) {315 callback(needToCompile);316 }317 else{318 git.commitsSinceDate(workDir,stats.mtime,function(data){319 if (data == "0\n"){320 needToCompile = false;321 }322 callback(needToCompile)323 });324 }325 });326 }327 else{328 callback(needToCompile);329 }330 });331}332function applyMultiThreading(executionID,callback){333 var count = 0;334 var mainMachinesCount = executions[executionID].machines.length;335 executions[executionID].machines.forEach(function(machine){336 db.collection('machines', function(err, collection) {337 collection.findOne({_id:db.bson_serializer.ObjectID(machine._id)}, {}, function(err, dbMachine) {338 var startThread = 0;339 if(dbMachine){340 startThread = dbMachine.takenThreads - machine.threads;341 }342 if(startThread != 0){343 startThread = dbMachine.lastStartThread + 1344 }345 collection.findAndModify({_id:db.bson_serializer.ObjectID(machine._id)},{},{$set:{lastStartThread:startThread}},{safe:true,new:true},function(err,data){346 });347 common.logger.info("staring at:"+startThread);348 machine.threadID = startThread;349 //if more than one thread run base state if not let it go350 if (machine.threads > 1){351 machine.multiThreaded = true;352 agentBaseState(executions[executionID].project+"/"+executions[executionID].username,executionID,machine.host,machine.port,machine.threadID,function(err){353 machine.runBaseState = true;354 var newMachineCount = 1;355 for(var i=machine.threads;i>1;i--){356 var newMachine = {};357 for (var key in machine) {358 newMachine[key] = machine[key];359 }360 newMachine.threadID = i+startThread-1;361 common.logger.info(newMachine);362 executions[executionID].machines.push(newMachine);363 sendAgentCommand(newMachine.host,newMachine.port,{command:"start launcher",executionID:executionID,threadID:newMachine.threadID},3,function(err){364 newMachineCount++;365 if (newMachineCount == machine.threads){366 count++;367 if(count == mainMachinesCount){368 callback();369 }370 }371 });372 }373 });374 }375 else{376 count++;377 if(count == mainMachinesCount){378 callback();379 }380 }381 });382 });383 });384}385function suiteBaseState(executionID,machines,callback){386 var count = 0;387 var foundSuiteState = false;388 var suiteBaseTCs = [];389 var lastMachine = function(){390 if (count === machines.length){391 if (suiteBaseTCs.length > 0){392 executions[executionID].cachedTCs = executions[executionID].testcases;393 executions[executionID].testcases = {};394 suiteBaseTCs.forEach(function(tc){395 executions[executionID].testcases[tc.testcaseID] = tc;396 });397 executions[executionID].baseStateFailed = false;398 }399 callback()400 }401 };402 machines.forEach(function(machine){403 if(machine.baseState){404 foundSuiteState = true;405 machine.roles.push(machine.host);406 db.collection('testcases', function(err, collection) {407 collection.insert({baseState:true,name:machine.host+"_state",status:"Automated",type:"collection",collection:[{order:"1",actionid:machine.baseState,host:machine.host,executionflow:"Record Error Stop Test Case",parameters:[]}]}, {safe:true},function(err,testcaseData){408 db.collection('executiontestcases', function(err, collection) {409 //collection.save({_id:machine.resultID},{},{$set:{executionID:executionID,name:machine.host+"_state",status:"Not Run",testcaseID:testcaseData[0]._id.__id,_id: machine.resultID}}, {safe:true,new:true},function(err,returnData){410 collection.save({baseState:true,executionID:executionID,name:machine.host+"_state",status:"Not Run",testcaseID:testcaseData[0]._id.__id,_id: machine.baseStateTCID},function(err,returnData){411 suiteBaseTCs.push({testcaseID:testcaseData[0]._id.__id,retryCount:0,_id:machine.baseStateTCID,status:"Not Run",name:machine.host+"_state",type:"collection"});412 count++;413 lastMachine();414 });415 });416 });417 });418 }419 else{420 count++;421 }422 lastMachine();423 });424}425exports.cacheSourceCode = function(rootPath,callback){cacheSourceCode(rootPath,callback)};426function cacheSourceCode(rootPath,callback){427 git.lsFiles(rootPath,["*.groovy","*.java"],function(data){428 var files = [];429 if ((data != "")&&(data.indexOf("\n") != -1)){430 files = data.split("\n",data.match(/\n/g).length);431 }432 callback(files);433 })434}435function getGlobalVars(executionID,callback){436 db.collection('variables', function(err, collection) {437 collection.find({taskVar:false}, {}, function(err, cursor) {438 cursor.each(function(err, variable) {439 if(variable == null) {440 callback();441 }442 else{443 executions[executionID].variables[variable.name] = variable.value;444 }445 });446 })447 });448}449function cleanUpMachines(machines,executionID,callback){450 var count = 0;451 machines.forEach(function(machine){452 sendAgentCommand(machine.host,machine.port,{command:"cleanup",executionID:executionID},3,function(err){453 count++;454 if(count == machines.length){455 if(callback) callback();456 }457 });458 })459}460function executeTestCases(testcases,executionID){461 if (!executions[executionID]) return;462 executions[executionID].executingTCs = true;463 var variables = executions[executionID].variables;464 var machines = executions[executionID].machines;465 var tcArray = [];466 for(var key in testcases){467 tcArray.push(key);468 }469 //execution all done470 //if (tcArray.length == 0){471 var finishExecution = function(callback){472 if (executions[executionID].cachedTCs){473 if(executions[executionID].baseStateFailed === true){474 unlockCloudMachines(executions[executionID].machines);475 unlockMachines(machines,function(){476 cleanUpMachines(executions[executionID].machines,executionID,function(){477 });478 updateExecution({_id:executionID},{$set:{status:"Ready To Run"}},true,function(){479 executionsRoute.updateExecutionTotals(executionID,function(){480 if(executions[executionID].sendEmail == true) sendNotification(executionID);481 //git.deleteFiles(path.join(__dirname, '../public/automationscripts/'+executions[executionID].project+"/"+executions[executionID].username+"/build"),os.tmpDir()+"/jar_"+executionID);482 deleteDir(os.tmpDir()+"/jar_"+executionID);483 delete executions[executionID];484 });485 });486 callback(true)487 });488 return;489 }490 executions[executionID].machines.forEach(function(machine){491 machine.baseState = null;492 });493 executions[executionID].testcases = executions[executionID].cachedTCs;494 delete executions[executionID].cachedTCs;495 tcArray = [];496 for(key in executions[executionID].testcases){497 tcArray.push(key);498 }499 testcases = executions[executionID].testcases;500 callback(false)501 }502 else{503 if(executions[executionID]){504 unlockCloudMachines(executions[executionID].machines);505 unlockMachines(executions[executionID].machines,function(){506 cleanUpMachines(executions[executionID].machines,executionID,function(){507 });508 updateExecution({_id:executionID},{$set:{status:"Ready To Run"}},true,function(){509 executionsRoute.updateExecutionTotals(executionID,function(){510 if(executions[executionID].sendEmail == true) sendNotification(executionID);511 //git.deleteFiles(path.join(__dirname, '../public/automationscripts/'+executions[executionID].project+"/"+executions[executionID].username+"/build"),os.tmpDir()+"/jar_"+executionID);512 deleteDir(os.tmpDir()+"/jar_"+executionID);513 delete executions[executionID];514 });515 });516 callback(true)517 });518 }519 //return;520 }521 };522 var count = 0;523 var doneCount = 0;524 var nextTC = function(){525 if (!testcases[tcArray[count]]){526 executions[executionID].executingTCs = false;527 return;528 }529 if (testcases[tcArray[count]].executing == true){530 count++;531 nextTC();532 return;533 }534 else if(testcases[tcArray[count]].finished == true){535 count++;536 doneCount++;537 if (doneCount == tcArray.length){538 finishExecution(function(finishIt){539 if(finishIt == false){540 count = 0;541 nextTC();542 }543 else{544 if(executions[executionID]) executions[executionID].executingTCs = false;545 }546 });547 return;548 }549 nextTC();550 return;551 }552 testcases[tcArray[count]].executing = true;553 startTCExecution(testcases[tcArray[count]].testcaseID,variables,executionID,function(){554 if (!executions[executionID]) return;555 count++;556 var machineAvailable = false;557 machines.forEach(function(machine){558 if(machine.runningTC == undefined){559 machineAvailable = true;560 }561 });562 if((count < tcArray.length)&&(machineAvailable == true)){563 nextTC();564 }565 else{566 executions[executionID].executingTCs = false;567 //remove any useless machines568 var toRemove = [];569 machines.forEach(function(machine){570 if(machine.runningTC == undefined){571 //don't remove any machines if this is just a suite base state that is running572 if(!executions[executionID].cachedTCs){573 toRemove.push(machine)574 }575 }576 });577 unlockMachines(toRemove,function(){578 toRemove.forEach(function(machine){579 machines.splice(machines.indexOf(machine),1);580 });581 });582 //if nothing else to execute finish it.583 var somethingToRun = false;584 tcArray.forEach(function(testcaseCount){585 if(testcases[testcaseCount].finished != true){586 somethingToRun = true;587 }588 });589 if(somethingToRun == false){590 finishExecution(function(finishIt){591 if(finishIt == false){592 count = 0;593 nextTC();594 }595 else{596 if(executions[executionID]) executions[executionID].executingTCs = false;597 }598 });599 }600 }601 });602 };603 if (count == 0) nextTC();604}605function startTCExecution(id,variables,executionID,callback){606 GetTestCaseDetails(id,executionID,function(testcase,result,hosts){607 if(testcase == null){608 callback();609 return;610 }611 testcase.machines = [];612 testcase.machineVars = [];613 var reservedHosts = [];614 var busyMachines = false;615 executions[executionID].machines.forEach(function(machine,index){616 if(machine.runningTC != undefined){617 busyMachines = true;618 }619 hosts.forEach(function(host){620 if((machine.roles.indexOf(host) != -1)&& (reservedHosts.indexOf(host) == -1) &&((machine.runningTC == undefined)||(machine.runningTC == testcase))){621 machine.runningTC = testcase;622 reservedHosts.push(host);623 testcase.machines.push(machine);624 machine.roles.forEach(function(role){625 if (machine.machineVars){626 machine.machineVars.forEach(function(variable){627 testcase.machineVars["Machine."+role+"."+variable.name] = variable.value628 });629 }630 testcase.machineVars["Machine."+role+".Host"] = machine.host;631 testcase.machineVars["Machine."+role+".Port"] = machine.port;632 })633 }634 });635 });636 if ((testcase.machines.length == 0) || (reservedHosts.length != hosts.length)){637 if(busyMachines == true){638 executions[executionID].testcases[id].executing = false;639 callback();640 return;641 }642 }643 result.status = "Running";644 createResult(result,function(writtenResult){645 result._id = writtenResult[0]._id;646 result.executionID = executionID;647 executions[executionID].currentTestCases[testcase.dbTestCase._id] = {testcase:testcase,result:result,executionTestCaseID:id};648 //testcase.machines = [];649 testcase.startDate = new Date();650 if (((testcase.dbTestCase.status != "Automated")||(testcase.statusError)) && (executions[executionID].ignoreStatus == false)){651 var error = "";652 if (testcase.statusError){653 error = testcase.statusError654 }else if(testcase.dbTestCase.status == "To be Automated"){655 error = "Test Case is not Automated"656 }else if(testcase.dbTestCase.status == "Needs Maintenance"){657 error = "Test Case Needs Maintenance"658 }659 //if (callback){660 // callback({error:error});661 //}662 result.error = testcase.dbTestCase.status;663 result.status = "Not Run";664 //result.result = testcase.dbTestCase.status;665 result.result = error;666 updateResult(result);667 //executions[executionID].testcases[id].result = result;668 finishTestCaseExecution(executions[executionID],executionID,executions[executionID].testcases[id]._id,executions[executionID].currentTestCases[testcase.dbTestCase._id]);669 callback();670 return;671 }672 //if there is nothing to execute just finish the TC673 if (((testcase.dbTestCase.type === "collection")&&(testcase.actions.length == 0)) || ((testcase.dbTestCase.type === "script")&&(testcase.dbTestCase.script == ""))){674 //if (callback){675 // callback();676 //}677 result.status = "Finished";678 result.result = "Passed";679 updateResult(result);680 finishTestCaseExecution(executions[executionID],executionID,executions[executionID].testcases[id]._id,executions[executionID].currentTestCases[testcase.dbTestCase._id]);681 callback();682 return;683 }684 //updateExecutionTestCase({_id:testcases[0]._id.executionTestCaseID},{$set:{"status":"Running"}});685 var machines = executions[executionID].machines;686 machines.sort(function(a,b){687 return a.roles.length - b.roles.length;688 });689 /*690 var reservedHosts = [];691 testcase.machines = [];692 testcase.machineVars = [];693 machines.forEach(function(machine,index){694 hosts.forEach(function(host){695 if((machine.roles.indexOf(host) != -1)&& (reservedHosts.indexOf(host) == -1) &&((machine.runningTC == undefined)||(machine.runningTC == testcase))){696 machine.runningTC = testcase;697 reservedHosts.push(host);698 testcase.machines.push(machine);699 machine.roles.forEach(function(role){700 if (machine.machineVars){701 machine.machineVars.forEach(function(variable){702 testcase.machineVars["Machine."+role+"."+variable.name] = variable.value703 });704 }705 testcase.machineVars["Machine."+role+".Host"] = machine.host;706 testcase.machineVars["Machine."+role+".Port"] = machine.port;707 })708 }709 });710 });711 */712 if ((testcase.machines.length == 0) || (reservedHosts.length != hosts.length)){713 //if (callback){714 // callback({error:"Unable to find matching machine for this test case. Roles required are:"+hosts.join()});715 //}716 //updateExecutionTestCase({_id:executions[executionID].testcases[id]._id},{$set:{"status":"Finished",result:"Failed",resultID:result._id,error:"Unable to find matching machine for this test case. Roles required are:"+hosts.join()}});717 result.error = "Unable to find matching machine for this test case. Roles required are:"+hosts.join();718 result.status = "Finished";719 result.result = "Failed";720 updateResult(result);721 finishTestCaseExecution(executions[executionID],executionID,executions[executionID].testcases[id]._id,executions[executionID].currentTestCases[testcase.dbTestCase._id]);722 callback();723 return;724 }725 var count = 0;726 var errorFound = false;727 //var startTC = function(){728 var agentInstructions = {command:"run action",executionID:executionID,testcaseID:testcase.dbTestCase._id,variables:executions[executionID].variables};729 var foundMachine = null;730 var runBaseState = function(){731 agentBaseState(executions[executionID].project+"/"+executions[executionID].username,executionID,foundMachine.host,foundMachine.port,foundMachine.threadID,function(err){732 if (err){733 result.error = err.error;734 result.status = "Finished";735 result.result = "Failed";736 updateResult(result);737 if (executions[executionID]){738 executions[executionID].currentTestCases[testcase.dbTestCase._id].result = result;739 finishTestCaseExecution(executions[executionID],executionID,executions[executionID].testcases[id]._id,executions[executionID].currentTestCases[testcase.dbTestCase._id]);740 }741 }742 else{743 foundMachine.runBaseState = true;744 sendAgentCommand(foundMachine.host,foundMachine.port,agentInstructions,3);745 }746 });747 };748 //if test case is a script and NOT an action collection749 if (testcase.dbTestCase.type !== "collection"){750 if ((testcase.script == "") || (!testcase.script)){751 result.error = "Test Case does not have a script assigned";752 result.status = "Finished";753 result.result = "Failed";754 updateResult(result);755 //executions[executionID].testcases[id].result = result;756 finishTestCaseExecution(executions[executionID],executionID,executions[executionID].testcases[id]._id,executions[executionID].currentTestCases[testcase.dbTestCase._id]);757 return;758 }759 agentInstructions.name = testcase.name;760 agentInstructions.ignoreScreenshots = executions[executionID].ignoreScreenshots;761 agentInstructions.allScreenshots = executions[executionID].allScreenshots;762 agentInstructions.executionID = executionID;763 agentInstructions.testcaseName = testcase.name;764 agentInstructions.script = testcase.script;765 agentInstructions.scriptLang = testcase.scriptLang;766 agentInstructions.resultID = result._id.__id;767 agentInstructions.parameters = [];768 agentInstructions.type = testcase.dbTestCase.type;769 var actionHost = "Default";770 //if(action.dbAction.host != "") actionHost = action.dbAction.host;771 testcase.machines.forEach(function(machine){772 if ((machine.roles.indexOf(actionHost) != -1)&&(foundMachine == null)){773 foundMachine = machine;774 }775 });776 agentInstructions.threadID = foundMachine.threadID;777 updateExecutionTestCase({_id:executions[executionID].testcases[id]._id},{$set:{"status":"Running","result":"",error:"",trace:"",resultID:result._id,startdate:testcase.startDate,enddate:"",runtime:"",host:foundMachine.host,vncport:foundMachine.vncport}},foundMachine.host,foundMachine.vncport);778 executionsRoute.updateExecutionTotals(executionID);779 if (foundMachine.runBaseState === true){780 if (foundMachine.multiThreaded == true){781 sendAgentCommand(foundMachine.host,foundMachine.port,agentInstructions,3);782 }783 else{784 //make sure the files are actually there, in case of revert to snapshot or not persistent VMs files785 //could have changed while test case was running786 sendAgentCommand(foundMachine.host,foundMachine.port,{command:"files loaded",executionID:executionID},3,function(message){787 if (message.loaded == true){788 sendAgentCommand(foundMachine.host,foundMachine.port,agentInstructions,3);789 }790 else{791 runBaseState();792 }793 });794 }795 }796 else{797 runBaseState();798 }799 callback();800 return;801 }802 callback();803 for (var attrname in testcase.machineVars) { variables[attrname] = testcase.machineVars[attrname]; }804 variables["Framework.TestCaseName"] = testcase.dbTestCase.name;805 findNextAction(testcase.actions,variables,function(action){806 if (!executions[executionID]) return;807 if(!executions[executionID].currentTestCases[testcase.dbTestCase._id]) return;808 if(action == null){809 finishTestCaseExecution(executions[executionID],executionID,executions[executionID].testcases[id]._id,executions[executionID].currentTestCases[testcase.dbTestCase._id]);810 return;811 }812 executions[executionID].currentTestCases[testcase.dbTestCase._id].currentAction = action;813 agentInstructions.name = action.name;814 agentInstructions.executionflow = action.dbAction.executionflow;815 agentInstructions.executionID = executionID;816 agentInstructions.ignoreScreenshots = executions[executionID].ignoreScreenshots;817 agentInstructions.allScreenshots = executions[executionID].allScreenshots;818 agentInstructions.returnValueName = action.dbAction.returnvalue;819 agentInstructions.testcaseName = testcase.dbTestCase.name;820 agentInstructions.script = action.script;821 agentInstructions.scriptLang = action.scriptLang;822 agentInstructions.resultID = result._id.__id;823 agentInstructions.parameters = [];824 action.dbAction.parameters.forEach(function(parameter){825 agentInstructions.parameters.push({name:parameter.paramname,value:parameter.paramvalue});826 });827 var actionHost = "Default";828 if(action.dbAction.host != "") actionHost = action.dbAction.host;829 testcase.machines.forEach(function(machine){830 if ((machine.roles.indexOf(actionHost) != -1)&&(foundMachine == null)){831 foundMachine = machine;832 }833 });834 agentInstructions.threadID = foundMachine.threadID;835 updateExecutionTestCase({_id:executions[executionID].testcases[id]._id},{$set:{"status":"Running","result":"",error:"",trace:"",resultID:result._id,startdate:testcase.startDate,enddate:"",runtime:"",host:foundMachine.host,vncport:foundMachine.vncport}},foundMachine.host,foundMachine.vncport);836 if ((testcase.machines.length > 0) &&((testcase.machines[0].baseState))){837 updateExecutionMachine(executionID,testcase.machines[0]._id,"",result._id.__id);838 }839 executionsRoute.updateExecutionTotals(executionID);840 if (foundMachine.runBaseState === true){841 if (foundMachine.multiThreaded == true){842 sendAgentCommand(foundMachine.host,foundMachine.port,agentInstructions,3);843 }844 else{845 //make sure the files are actually there, in case of revert to snapshot or not persistent VMs files846 //could have changed while test case was running847 sendAgentCommand(foundMachine.host,foundMachine.port,{command:"files loaded",executionID:executionID},3,function(message){848 if (message.loaded == true){849 sendAgentCommand(foundMachine.host,foundMachine.port,agentInstructions,3);850 }851 else{852 runBaseState();853 }854 });855 }856 }857 else{858 runBaseState();859 }860 });861 })862 });863}864exports.logPost = function(req,res){865 var record = req.body;866 var executionID = record.executionID.replace(/-/g, '');867 delete record.command;868 delete record.executionID;869 db.collection('executionlogs'+executionID, function(err, collection) {870 collection.insert(record, {safe:true},function(err,returnData){871 res.contentType('json');872 res.json({success:true});873 realtime.emitMessage("AddExecutionLog",record);874 });875 });876};877exports.actionresultPost = function(req, res){878 res.contentType('json');879 res.json({success:true});880 var execution = executions[req.body.executionID];881 if (!execution) return;882 var testcase = execution.currentTestCases[req.body.testcaseID];883 if (testcase == undefined) return;884 if (testcase.testcase.script){885 testcase.result.status = "Finished";886 testcase.result.result = req.body.result;887 if (req.body.error){888 testcase.result.error = req.body.error;889 }890 else{891 testcase.result.error = "";892 }893 if (req.body.trace){894 formatTrace(req.body.trace,execution.sourceCache,function(trace){895 testcase.result.trace = trace;896 if(trace == "") testcase.result.trace = req.body.trace;897 updateResult(testcase.result);898 });899 }900 else{901 updateResult(testcase.result);902 }903 finishTestCaseExecution(execution,req.body.executionID,execution.testcases[testcase.executionTestCaseID]._id,testcase);904 return;905 }906 testcase.currentAction.result.status = "Finished";907 testcase.currentAction.result.result = req.body.result;908 if(!testcase.result.error){909 testcase.result.error = "";910 }911 if (req.body.error){912 testcase.result.error = req.body.error;913 testcase.currentAction.result.error = req.body.error;914 }915 if (req.body.trace){916 testcase.result.trace = req.body.trace;917 testcase.currentAction.result.trace = req.body.trace;918 testcase.trace = req.body.trace;919 }920 if (req.body.screenshot){921 testcase.result.screenshot = req.body.screenshot;922 testcase.currentAction.result.screenshot = req.body.screenshot;923 }924 if ((req.body.returnValue)&&(testcase.currentAction.dbAction.returnvalue != "")){925 if(!execution.returnVars[req.body.testcaseID]){926 execution.returnVars[req.body.testcaseID] = {};927 }928 execution.returnVars[req.body.testcaseID][testcase.currentAction.dbAction.returnvalue] = req.body.returnValue;929 //.[testcase.currentAction.dbAction.returnvalue] = req.body.returnValue;930 //execution.variables[testcase.currentAction.dbAction.returnvalue] = req.body.returnValue;931 }932 var actionFlow = testcase.currentAction.dbAction.executionflow;933 if (req.body.result == "Failed"){934 if (actionFlow == "Record Error Stop Test Case"){935 testcase.result.status = "Finished";936 testcase.result.result = "Failed";937 testcase.runAfterState = true;938 testcase.testcase.actions.forEach(function(action){939 if(!action.dbAction.afterState == true){940 action.runAction = false;941 }942 });943 //updateExecutionTestCase({_id:execution.testcases[testcase.executionTestCaseID]._id},{$set:{error:testcase.result.error,trace:testcase.trace}});944 /*945 markFinishedResults(testcase.result.children,execution.sourceCache,function(){946 updateResult(testcase.result);947 });948 finishTestCaseExecution(execution,req.body.executionID,execution.testcases[testcase.executionTestCaseID]._id,testcase);949 return;950 */951 }952 else if (actionFlow == "Record Error Continue Test Case"){953 testcase.result.result = "Failed";954 updateExecutionTestCase({_id:execution.testcases[testcase.executionTestCaseID]._id},{$set:{result:"Failed",trace:testcase.trace}});955 }956 else{957 testcase.currentAction.result.result = "";958 testcase.currentAction.result.trace = "";959 testcase.currentAction.result.error = "";960 testcase.result.result = "";961 testcase.result.error = "";962 }963 }964 markFinishedResults(testcase.result.children,execution.sourceCache,function(){965 updateResult(testcase.result);966 });967 var actionVariables = {};968 for (var attrname in execution.variables) { actionVariables[attrname] = execution.variables[attrname]; }969 for (var attrname in testcase.machineVars) { actionVariables[attrname] = testcase.machineVars[attrname]; }970 if(execution.returnVars[testcase.executionTestCaseID]){971 for (var attrname in execution.returnVars[testcase.executionTestCaseID]) { actionVariables[attrname] = execution.returnVars[testcase.executionTestCaseID][attrname]; }972 }973 findNextAction(testcase.testcase.actions,actionVariables,function(action){974 if(action == null){975 testcase.result.status = "Finished";976 if(testcase.result.result != "Failed") testcase.result.result = "Passed";977 updateResult(testcase.result);978 finishTestCaseExecution(execution,req.body.executionID,execution.testcases[testcase.executionTestCaseID]._id,testcase);979 return;980 }981 var foundMachine = null;982 var actionHost = "Default";983 if(action.dbAction.host != "") actionHost = action.dbAction.host;984 testcase.testcase.machines.forEach(function(machine){985 if ((machine.roles.indexOf(actionHost) != -1)&&(foundMachine == null)){986 foundMachine = machine;987 }988 });989 updateExecutionTestCase({_id:execution.testcases[testcase.executionTestCaseID]._id},{$set:{"status":"Running","result":"",host:foundMachine.host,vncport:foundMachine.vncport}},foundMachine.host,foundMachine.vncport);990 testcase.result.status = "Running";991 var agentInstructions = {command:"run action",executionID:req.body.executionID,threadID:foundMachine.threadID,testcaseID:testcase.testcase.dbTestCase._id,variables:execution.variables};992 execution.currentTestCases[testcase.testcase.dbTestCase._id].currentAction = action;993 agentInstructions.name = action.name;994 agentInstructions.executionflow = action.dbAction.executionflow;995 agentInstructions.executionID = req.body.executionID;996 agentInstructions.ignoreScreenshots = executions[req.body.executionID].ignoreScreenshots;997 agentInstructions.allScreenshots = executions[req.body.executionID].allScreenshots;998 agentInstructions.returnValueName = action.dbAction.returnvalue;999 agentInstructions.testcaseName = testcase.testcase.dbTestCase.name;1000 agentInstructions.script = action.script;1001 agentInstructions.scriptLang = action.scriptLang;1002 agentInstructions.resultID = testcase.result._id.__id;1003 agentInstructions.parameters = [];1004 action.dbAction.parameters.forEach(function(parameter){1005 agentInstructions.parameters.push({name:parameter.paramname,value:parameter.paramvalue});1006 });1007 var runBaseState = function(){1008 agentBaseState(execution.project+"/"+execution.username,req.body.executionID,foundMachine.host,foundMachine.port,foundMachine.threadID,function(err){1009 if (err){1010 testcase.result.error = err.error;1011 testcase.result.status = "Finished";1012 testcase.result.result = "Failed";1013 updateResult(testcase.result);1014 if (execution){1015 execution.currentTestCases[testcase.dbTestCase._id].result = "Failed";1016 finishTestCaseExecution(execution,req.body.executionID,execution.testcases[id]._id,execution.currentTestCases[testcase.dbTestCase._id]);1017 }1018 }1019 else{1020 foundMachine.runBaseState = true;1021 sendAgentCommand(foundMachine.host,foundMachine.port,agentInstructions,3);1022 }1023 });1024 };1025 if (foundMachine.runBaseState === true){1026 if (foundMachine.multiThreaded == true){1027 sendAgentCommand(foundMachine.host,foundMachine.port,agentInstructions,3);1028 }1029 else{1030 //make sure the files are actually there, in case of revert to snapshot or not persistent VMs files1031 //could have changed while test case was running1032 sendAgentCommand(foundMachine.host,foundMachine.port,{command:"files loaded",executionID:req.body.executionID},3,function(message){1033 if (message.loaded == true){1034 sendAgentCommand(foundMachine.host,foundMachine.port,agentInstructions,3);1035 }1036 else{1037 runBaseState();1038 }1039 });1040 }1041 }1042 else{1043 runBaseState();1044 }1045 });1046};1047//last action or we are done with the TC1048//start next test case if there is one1049function finishTestCaseExecution(execution,executionID,testcaseId,testcase){1050 //updateExecutionTestCase({_id:execution.testcases[testcase.executionTestCaseID]._id},{$set:{"status":"Finished",result:testcase.result.result}});1051 var date = new Date();1052 var status = "Finished";1053 if((testcase.result.result != "Passed") && (testcase.result.result != "Failed")){1054 status = "Not Run";1055 }1056 var updateTC = function(){1057 updateExecutionTestCase({_id:testcaseId},{$set:{trace:testcase.trace,"status":status,resultID:testcase.result._id.__id,result:testcase.result.result,error:testcase.result.error,enddate:date,runtime:date-testcase.testcase.startDate,host:"",vncport:""}});1058 executionsRoute.updateExecutionTotals(executionID);1059 };1060 //update machine base state result1061 if(execution.cachedTCs){1062 if (testcase.testcase.machines.length > 0){1063 updateExecutionMachine(executionID,testcase.testcase.machines[0]._id,testcase.result.result,testcase.result._id.__id,function(){1064 updateTC();1065 });1066 }1067 else{1068 updateTC();1069 }1070 //updateExecutionMachine({testcase.testcase.machines[0]._id)},{$set:{result:testcase.result.result,resultID:testcase.result._id.__id}});1071 }1072 else{1073 updateTC();1074 }1075 var count = 0;1076 var retry = false;1077 if(testcase.result.result == "Failed"){1078 if (execution.testcases[testcase.executionTestCaseID].retryCount > 0){1079 retry = true;1080 execution.testcases[testcase.executionTestCaseID].retryCount--;1081 execution.testcases[testcase.executionTestCaseID].executing = false;1082 execution.returnVars[testcase.executionTestCaseID] = {};1083 }1084 if (execution.cachedTCs){1085 execution.baseStateFailed = true;1086 }1087 }1088 if(testcase.testcase.machines.length === 0){1089 if (retry == false){1090 //delete execution.testcases[testcase.executionTestCaseID];1091 execution.testcases[testcase.executionTestCaseID].finished = true;1092 execution.testcases[testcase.executionTestCaseID].executing = false;1093 }1094 delete execution.currentTestCases[testcase.executionTestCaseID];1095 executeTestCases(execution.testcases,executionID);1096 return;1097 }1098 testcase.testcase.machines.forEach(function(machine){1099 delete machine.runningTC;1100 count++;1101 if (count == testcase.testcase.machines.length){1102 if (retry == false){1103 //delete execution.testcases[testcase.executionTestCaseID];1104 execution.testcases[testcase.executionTestCaseID].finished = true;1105 execution.testcases[testcase.executionTestCaseID].executing = false;1106 }1107 delete execution.currentTestCases[testcase.executionTestCaseID];1108 if(execution.executingTCs != true){1109 executeTestCases(execution.testcases,executionID);1110 }1111 }1112 });1113}1114exports.formatTrace = function(trace,sourceCache,callback){formatTrace(trace,sourceCache,callback)};1115function formatTrace(trace,sourceCache,callback){1116 var newTrace = "";1117 var traceCount = 0;1118 var traces = trace.split(",");1119 traces.forEach(function(line){1120 traceCount++;1121 var fileName = line.substring(line.indexOf("(")+1,line.indexOf(":"));1122 var lineNumber = line.substring(line.indexOf(":")+1,line.indexOf(")"));1123 var location = line.substring(0,line.indexOf("("));1124 location = location.trim();1125 location = location.replace("[","");1126 var count = 0;1127 var found = false;1128 if((location.indexOf("org.codehaus.") != -1) || (location.indexOf("java.lang.") != -1) || (location.indexOf("groovy.lang.") != -1) || (location.indexOf("redwood.launcher.") != -1)|| (location.indexOf("sun.reflect.") != -1)){1129 if (line.indexOf("[") == 0){1130 newTrace += line;1131 }1132 else{1133 newTrace += ",\r\n"+line;1134 }1135 if (traceCount == traces.length){1136 callback(newTrace);1137 }1138 return;1139 }1140 if ((fileName.indexOf(".groovy") != -1) ||(fileName.indexOf(".java") != -1)){1141 sourceCache.forEach(function(file){1142 if (found == true) return;1143 if (file.indexOf("/"+fileName) != -1){1144 if(location.replace(/\./g, '/').indexOf(file.substring(0,file.lastIndexOf("/")).replace("src/", '')) != -1){1145 found = true;1146 var parsedLineNumber = (parseInt(lineNumber,10)-1).toString();1147 newTrace += ",\r\n<a style= 'color: blue;' href='javascript:openScript(""+ file +"",""+ parsedLineNumber +"")'>" + line +"</a>";1148 }1149 }1150 count++;1151 if (count == sourceCache.length){1152 if (found == false){1153 if (line.indexOf("[") == 0){1154 newTrace += line;1155 }1156 else{1157 newTrace += ",\r\n"+line;1158 }1159 }1160 if (traceCount == traces.length){1161 callback(newTrace);1162 }1163 }1164 });1165 }1166 else{1167 if (traceCount == traces.length){1168 callback(newTrace);1169 }1170 }1171 });1172}1173function markFinishedResults(results,sourceCache,callback){1174 var count = 0;1175 var result = "Passed";1176 var status = "Finished";1177 results.forEach(function(action){1178 if (action.status == "Not Run"){1179 if (action.children.length != 0){1180 markFinishedResults(action.children,sourceCache,function(childStatus,childResult,markFinished){1181 action.expanded = false;1182 if (markFinished === true){1183 action.status = "Finished";1184 action.result = "Failed";1185 action.expanded = true;1186 callback("Finished","Failed",true);1187 return;1188 }1189 count++;1190 if (childStatus == "Not Run"){1191 status = "Not Run";1192 result = "";1193 }1194 if((childStatus == "Finished") && (childResult == "Failed")){1195 result = "Failed";1196 action.expanded = true;1197 }1198 if(count == action.children.length){1199 action.result = result;1200 action.status = status;1201 if (status == "Finished"){1202 if ((action.executionflow == "Record Error Stop Test Case")&&(result == "Failed")){1203 callback(status,result,true)1204 }1205 else{1206 callback(status,result)1207 }1208 }1209 else{1210 callback(status,"")1211 }1212 }1213 })1214 }1215 else{1216 callback("Not Run","")1217 }1218 }1219 else{1220 var returnValue;1221 if ((action.executionflow == "Record Error Stop Test Case")&&(action.result == "Failed")){1222 returnValue = function(){callback("Finished","Failed",true)}1223 }1224 else{1225 returnValue = function(){callback("Finished",action.result)}1226 }1227 if(action.result == "Failed"){1228 action.expanded = true;1229 }1230 if(action.trace){1231 formatTrace(action.trace,sourceCache,function(trace){1232 if(trace != "") action.trace = trace;1233 returnValue();1234 })1235 }1236 else{1237 returnValue();1238 }1239 }1240 });1241}1242exports.agentBaseState = function(project,executionID,agentHost,port,threadID,callback){agentBaseState(project,executionID,agentHost,port,threadID,callback)};1243function agentBaseState(project,executionID,agentHost,port,threadID,callback){1244 sendAgentCommand(agentHost,port,{command:"cleanup",executionID:executionID},3,function(message){1245 if (message.error){1246 callback(message.error);1247 return;1248 }1249 syncFilesWithAgent(agentHost,port,path.join(__dirname, '../public/automationscripts/'+project+"/bin"),"executionfiles/"+executionID+"/bin",function(error){1250 if(error) {callback(error);return}1251 syncFilesWithAgent(agentHost,port,path.join(__dirname, '../launcher'),"executionfiles/"+executionID+"/launcher",function(){1252 syncFilesWithAgent(agentHost,port,path.join(__dirname, '../public/automationscripts/'+project+"/External Libraries"),"executionfiles/"+executionID+"/lib",function(){1253 //syncFilesWithAgent(agentHost,port,path.join(__dirname, '../public/automationscripts/'+project+"/build/jar_"+executionID),"executionfiles/"+executionID+"/lib",function(){1254 syncFilesWithAgent(agentHost,port,os.tmpDir()+"/jar_"+executionID,"executionfiles/"+executionID+"/lib",function(){1255 sendAgentCommand(agentHost,port,{command:"start launcher",executionID:executionID,threadID:threadID},3,function(message){1256 if ((message) && (message.error)){1257 callback(message.error);1258 }1259 else{1260 callback();1261 }1262 });1263 })1264 })1265 })1266 });1267 });1268}1269function syncFilesWithAgent_old(agentHost,port,rootPath,destDir,callback){1270 var walker = walk.walkSync(rootPath);1271 var fileCount = 0;1272 walker.on("file", function (root, fileStats, next) {1273 fileCount++;1274 var path = root.replace(rootPath,"");1275 var dest = "";1276 if (path == ""){1277 dest = destDir +"/"+ fileStats.name;1278 }1279 else{1280 dest = destDir + path+"/"+fileStats.name1281 }1282 sendFileToAgent(root+"/"+fileStats.name,dest,agentHost,port,3,function(){1283 fileCount--;1284 if(fileCount == 0){1285 callback();1286 }1287 });1288 });1289 walker.on("end",function(){1290 if (fileCount == 0) callback();1291 });1292}1293function syncFilesWithAgent(agentHost,port,rootPath,destDir,callback){1294 var walker = walk.walkSync(rootPath);1295 var fileCount = 0;1296 var files = [];1297 var foundError = false;1298 var sendFiles = function(){1299 if(foundError) return;1300 fileCount++;1301 if (!files[fileCount-1]){1302 callback();1303 return;1304 }1305 sendFileToAgent(files[fileCount-1].file,files[fileCount-1].dest,agentHost,port,3,function(error){1306 if(error){1307 foundError = true;1308 callback(error);1309 return;1310 }1311 if(fileCount === files.length){1312 callback();1313 }1314 else{1315 sendFiles()1316 }1317 });1318 };1319 walker.on("file", function (root, fileStats, next) {1320 var path = root.replace(rootPath,"");1321 var dest = "";1322 if (path == ""){1323 dest = destDir +"/"+ fileStats.name;1324 }1325 else{1326 dest = destDir + path+"/"+fileStats.name1327 }1328 files.push({file:root+"/"+fileStats.name,dest:dest});1329 });1330 walker.on("end",function(){1331 sendFiles()1332 });1333}1334function sendFileToAgent(file,dest,agentHost,port,retryCount,callback){1335 var stat = fs.statSync(file);1336 var readStream = fs.createReadStream(file);1337 var boundary = '--------------------------';1338 for (var i = 0; i < 24; i++) {1339 boundary += Math.floor(Math.random() * 10).toString(16);1340 }1341 var message = '------' + boundary + '\r\n'1342 // use your file's mime type here, if known1343 + 'Content-Disposition: form-data; name="file"; filename="'+dest+'"\r\n'1344 + 'Content-Type: application/octet-stream\r\n'1345 // "name" is the name of the form field1346 // "filename" is the name of the original file1347 + 'Content-Transfer-Encoding: binary\r\n\r\n';1348 var options = {1349 hostname: agentHost,1350 port: port,1351 path: '/fileupload',1352 method: 'POST',1353 headers: {1354 //'Content-Type': 'text/plain'//,1355 'Content-Type': 'multipart/form-data; boundary=----'+boundary,1356 //'Content-Disposition': 'form-data; name="file"; filename="ProjectName.jar"',1357 //'Content-Length': 33601358 //'Content-Length': stat.size + message.length + 30 + boundary.length1359 'Content-Length': stat.size + message.length + boundary.length + 141360 }1361 };1362 var req = http.request(options, function(res) {1363 //res.setEncoding('utf8');1364 res.on('data', function (chunk) {1365 if (callback) callback();1366 });1367 });1368 req.on('error', function(e) {1369 if(retryCount <= 0){1370 if (callback) callback({error:'sendFileToAgent problem with request: ' + e.message+ ' file:'+file});1371 common.logger.error('sendFileToAgent problem with request: ' + e.message+ ' file:'+file);1372 }1373 else{1374 retryCount--;1375 setTimeout(sendFileToAgent(file,dest,agentHost,port,retryCount,callback),1000)1376 }1377 });1378 req.write(message);1379 readStream.pipe(req, { end: false });1380 readStream.on("end", function(){1381 req.end('\r\n------' + boundary + '--\r\n');1382 });1383}1384exports.sendAgentCommand = function(agentHost,port,command,retryCount,callback){sendAgentCommand(agentHost,port,command,retryCount,callback)};1385function sendAgentCommand(agentHost,port,command,retryCount,callback){1386 common.logger.info(command);1387 var options = {1388 hostname: agentHost,1389 port: port,1390 path: '/command',1391 method: 'POST',1392 headers: {1393 'Content-Type': 'application/json'1394 }1395 };1396 var req = http.request(options, function(res) {1397 res.setEncoding('utf8');1398 res.on('data', function (chunk) {1399 try{1400 var msg = JSON.parse(chunk);1401 }1402 catch(err){1403 if (callback) callback(err);1404 }1405 if((msg )&&(msg.error != null)){1406 if (callback) callback(msg.error);1407 }1408 else if (msg){1409 if(callback) callback(msg);1410 }1411 else{1412 if(callback) callback();1413 }1414 });1415 });1416 req.setTimeout(50000, function(){1417 //when timeout, this callback will be called1418 });1419 req.on('error', function(e) {1420 retryCount = 0;1421 if(retryCount <= 0){1422 if (callback) callback("Unable to connect to machine: "+agentHost + " error: " + e.message);1423 common.logger.error('sendAgentCommand problem with request: ' + e.message+ ' ');1424 }1425 else{1426 retryCount--;1427 setTimeout(sendAgentCommand(agentHost,port,command,retryCount,callback),1000)1428 }1429 });1430 // write data to request body1431 req.write(JSON.stringify(command));1432 req.end();1433}1434function resolveParamValue(value,variables){1435 var returnNULL = false;1436 if(Object.prototype.toString.call(value) == '[object Array]'){1437 if((value.length == 1) && (value[0] === "<NULL>")){1438 return [];1439 }1440 else{1441 return value;1442 }1443 }1444 else if (typeof value != "string"){1445 return value;1446 }1447 if (value.length > 4){1448 if ((value.indexOf("$\{") == 0) &&(value.charAt(value.length -1) == "}") && (value.split("}").length > 1))1449 {1450 returnNULL = true;1451 }1452 }1453 //var result = value.replace(new RegExp("\\$\\{([\\w_.-\\s*]+)\\}", "g" ),function(a,b){1454 var result = value.replace(new RegExp("\\$\\{([\\s\\w_.-]+)\\}", "g" ),function(a,b){1455 if(b in variables){1456 if (variables[b] == "<NULL>"){1457 if (returnNULL == true){1458 return "<NULL>"1459 }1460 else{1461 return "";1462 }1463 }1464 else{1465 return variables[b];1466 }1467 }1468 else{1469 return a;1470 }1471 });1472 return result;1473}1474function createResult(result,callback){1475 db.collection('testcaseresults', function(err, collection) {1476 result._id = db.bson_serializer.ObjectID(result._id);1477 collection.insert(result, {safe:true},function(err,returnData){1478 callback(returnData);1479 });1480 });1481}1482function updateResult(result,callback){1483 db.collection('testcaseresults', function(err, collection) {1484 collection.save(result,{safe:true},function(err){1485 if (callback){1486 callback(err);1487 }1488 //realtime.emitMessage("UpdateResult",result);1489 realtime.emitMessage("UpdateResult"+result._id.__id,result);1490 });1491 });1492}1493function updateExecutionTestCase(query,update,machineHost,vncport,callback){1494 db.collection('executiontestcases', function(err, collection) {1495 collection.findAndModify(query,{},update,{safe:true,new:true},function(err,data){1496 if (data == null){1497 if (callback){1498 callback(err);1499 }1500 return;1501 }1502 if (machineHost){1503 data.host = machineHost;1504 data.vncport = vncport;1505 }1506 realtime.emitMessage("UpdateExecutionTestCase",data);1507 if (callback){1508 callback(err);1509 }1510 });1511 });1512}1513function updateExecution(query,update,finished,callback){1514 db.collection('executions', function(err, collection) {1515 collection.findAndModify(query,{},update,{safe:true,new:true},function(err,data){1516 if(err) common.logger.error("ERROR updating execution: "+err);1517 realtime.emitMessage("UpdateExecutions",data);1518 if(finished === true){1519 realtime.emitMessage("FinishExecution",data);1520 }1521 if (callback){1522 callback(err);1523 }1524 });1525 });1526}1527function updateExecutionMachine(executionID,machineID,result,resultID,callback){1528 db.collection('executions', function(err, collection) {1529 collection.update({_id:executionID,machines:{$elemMatch:{_id:machineID}}},{$set:{'machines.$.result':result,'machines.$.resultID':resultID}},{safe:true,new:true},function(err,data){1530 //realtime.emitMessage("UpdateExecutions",data);1531 if (callback){1532 callback(err);1533 }1534 });1535 });1536}1537function cleanExecutionMachines(executionID,callback){1538 db.collection('executions', function(err, collection) {1539 collection.findOne({_id:executionID},function(err,data){1540 //realtime.emitMessage("UpdateExecutions",data);1541 if(data != null){1542 data.machines.forEach(function(machine){1543 machine.result = "";1544 machine.resultID = "";1545 });1546 collection.save(data,{safe:true},function(err){1547 //realtime.emitMessage("UpdateExecutions",data);1548 if (callback) callback();1549 });1550 }1551 });...
Using AI Code Generation
1var redwood = require('redwood');2var machines = ['machine1', 'machine2', 'machine3'];3redwood.cleanExecutionMachines(machines, function(err, result) {4 if (err) {5 console.log('Error: ' + err);6 }7 console.log('Result: ' + result);8});9Copyright (c) 2015, RedwoodHQ
Using AI Code Generation
1var redwood = require('redwood');2var path = require('path');3var configPath = path.join(__dirname, 'config.json');4redwood.cleanExecutionMachines(configPath, function (err) {5 if (err) {6 console.log(err);7 }8});9{10 "executionMachines": {11 "default": {12 }13 }14}
Using AI Code Generation
1var redwood = require('redwood');2redwood.cleanExecutionMachines(1, function(err, data) {3 console.log(err, data);4});5var redwood = require('redwood');6redwood.cleanExecutionMachines(2, function(err, data) {7 console.log(err, data);8});9var redwood = require('redwood');10redwood.cleanExecutionMachines(3, function(err, data) {11 console.log(err, data);12});13var redwood = require('redwood');14redwood.cleanExecutionMachines(4, function(err, data) {15 console.log(err, data);16});17var redwood = require('redwood');18redwood.cleanExecutionMachines(5, function(err, data) {19 console.log(err, data);20});21var redwood = require('redwood');22redwood.cleanExecutionMachines(6, function(err, data) {23 console.log(err, data);24});25var redwood = require('redwood');26redwood.cleanExecutionMachines(7, function(err, data) {27 console.log(err, data);28});29var redwood = require('redwood');30redwood.cleanExecutionMachines(8, function(err, data) {31 console.log(err, data);32});33var redwood = require('redwood');34redwood.cleanExecutionMachines(9, function(err, data) {35 console.log(err, data);36});37var redwood = require('redwood');38redwood.cleanExecutionMachines(10, function(err, data) {39 console.log(err, data);40})
Using AI Code Generation
1var redwood = require('redwood');2var redwoodConfig = {3 {4 },5 {6 }7};8redwood.init(redwoodConfig);9redwood.cleanExecutionMachines(function(err) {10 console.log(err);11});
Using AI Code Generation
1var redwood = require('../../redwood');2var test = new redwood.Test();3test.cleanExecutionMachines(function(err, result) {4 if (err) {5 console.log(err);6 } else {7 console.log(result);8 }9});10var redwood = require('../../redwood');11var test = new redwood.Test();12test.cleanExecutionMachines(function(err, result) {13 if (err) {14 console.log(err);15 } else {16 console.log(result);17 }18});19var redwood = require('../../redwood');20var test = new redwood.Test();21test.cleanExecutionMachines(function(err, result) {22 if (err) {23 console.log(err);24 } else {25 console.log(result);26 }27});28var redwood = require('../../redwood');29var test = new redwood.Test();30test.cleanExecutionMachines(function(err, result) {31 if (err) {32 console.log(err);33 } else {34 console.log(result);35 }36});37var redwood = require('../../redwood');38var test = new redwood.Test();39test.cleanExecutionMachines(function(err, result) {40 if (err) {41 console.log(err);42 } else {43 console.log(result);44 }45});46var redwood = require('../../redwood');47var test = new redwood.Test();48test.cleanExecutionMachines(function(err, result) {49 if (err) {50 console.log(err);51 } else {52 console.log(result);53 }54});55var redwood = require('../../redwood
Using AI Code Generation
1var redwood = require('redwood');2var machineList = redwood.cleanExecutionMachines();3console.log(machineList);4var redwood = require('redwood');5var machineList = redwood.cleanExecutionMachines();6console.log(machineList);7var redwood = require('redwood');8var machineList = redwood.cleanExecutionMachines();9console.log(machineList);10var redwood = require('redwood');11var machineList = redwood.cleanExecutionMachines();12console.log(machineList);13var redwood = require('redwood');14var machineList = redwood.cleanExecutionMachines();15console.log(machineList);16var redwood = require('redwood');17var machineList = redwood.cleanExecutionMachines();18console.log(machineList);19var redwood = require('redwood');20var machineList = redwood.cleanExecutionMachines();21console.log(machineList);22var redwood = require('redwood');23var machineList = redwood.cleanExecutionMachines();24console.log(machineList);25var redwood = require('redwood');26var machineList = redwood.cleanExecutionMachines();27console.log(machineList);28var redwood = require('redwood');29var machineList = redwood.cleanExecutionMachines();30console.log(machineList);31var redwood = require('redwood');
Using AI Code Generation
1var redwood = require('redwood');2var cleanExecutionMachines = redwood.cleanExecutionMachines;3cleanExecutionMachines();4var redwood = require('redwood');5var statusExecutionMachines = redwood.statusExecutionMachines;6statusExecutionMachines();7var redwood = require('redwood');8var statusExecutionMachines = redwood.statusExecutionMachines;9statusExecutionMachines();10var redwood = require('redwood');11var statusExecutionMachines = redwood.statusExecutionMachines;12statusExecutionMachines();13var redwood = require('redwood');14var statusExecutionMachines = redwood.statusExecutionMachines;15statusExecutionMachines();16var redwood = require('redwood');17var statusExecutionMachines = redwood.statusExecutionMachines;18statusExecutionMachines();19var redwood = require('redwood');20var statusExecutionMachines = redwood.statusExecutionMachines;21statusExecutionMachines();
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!