PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/tool/admin/app/testbot/testing.py

http://github.com/qooxdoo/qooxdoo
Python | 717 lines | 692 code | 5 blank | 20 comment | 12 complexity | 9dd4800dc257247d31cc05447a6267db MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-3.0, MIT
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. ################################################################################
  4. #
  5. # qooxdoo - the new era of web development
  6. #
  7. # http://qooxdoo.org
  8. #
  9. # Copyright:
  10. # 2006-2010 1&1 Internet AG, Germany, http://www.1und1.de
  11. #
  12. # License:
  13. # LGPL: http://www.gnu.org/licenses/lgpl.html
  14. # EPL: http://www.eclipse.org/org/documents/epl-v10.php
  15. # See the LICENSE file in the project's top-level directory for details.
  16. #
  17. # Authors:
  18. # * Daniel Wagner (d_wagner)
  19. #
  20. ################################################################################
  21. import sys, os, re, random, codecs, urllib
  22. import qxenviron
  23. import util
  24. import reporting
  25. from seleniumserver import SeleniumServer
  26. from build import Builder
  27. from lint import Lint
  28. binPath = os.path.abspath(os.path.join(os.pardir, os.pardir, "bin"))
  29. sys.path.append(binPath)
  30. from logFormatter import QxLogFormat
  31. from simulationLogParser import SimulationLogParser
  32. from generator.runtime.Log import Log
  33. log = Log(None, "debug")
  34. class TestRun:
  35. def __init__(self, config, simulate=False, logger=log):
  36. self.configuration = config
  37. if self.getConfigSetting("base/type", "") == "standalone-generator":
  38. self.configuration = self.getConfigFromGenerator()
  39. self.log = logger
  40. self.simulate = simulate
  41. self.startDate = util.getTimestamp()
  42. self.buildStatus = {}
  43. if "base" in self.configuration:
  44. self.configuration["base"]["testHostName"] = util.getHostName()
  45. self.log.info("New test run started on %s" %self.startDate)
  46. def getConfigSetting(self, path="", default=False, config=False):
  47. if not config:
  48. config = self.configuration
  49. pathParts = path.split("/")
  50. dict = config
  51. while dict:
  52. for keyName in pathParts:
  53. # invalid node name
  54. if not keyName in dict:
  55. return default
  56. # final search path node, so we've found the right setting
  57. if keyName == pathParts[len(pathParts) - 1]:
  58. return dict[keyName]
  59. # haven't reached the final step yet, but the current value is no dict so
  60. # we've nowhere else to look
  61. if type(dict[keyName]).__name__ != "dict":
  62. return default
  63. # keep looking
  64. dict = dict[keyName]
  65. return default
  66. def getConfigFromGenerator(self):
  67. jobConfig = self.configuration
  68. seleniumPath = os.path.abspath(jobConfig["selenium-java-client"])
  69. testConfig = {
  70. "base" : {
  71. "type" : "standalone",
  72. },
  73. "selenium" : {
  74. "seleniumHost" : jobConfig["selenium-host"],
  75. "seleniumPort" : jobConfig["selenium-port"],
  76. "rhinoJar" : jobConfig["rhino"],
  77. "seleniumDir" : os.path.dirname(seleniumPath),
  78. "seleniumClientDriverJar" : os.path.basename(seleniumPath),
  79. },
  80. "browsers" : {
  81. "Browser" : jobConfig["browser"]
  82. },
  83. "testRun" : {
  84. "runType" : "",
  85. "simulatorDirectory" : jobConfig["simulator"],
  86. "host" : jobConfig["aut-host"],
  87. "applications" : {}
  88. }
  89. }
  90. autName = jobConfig["aut-name"]
  91. testConfig["testRun"]["applications"][autName] = {
  92. "path" : jobConfig["aut-path"],
  93. "simulationScript" : jobConfig["simulator"] + "/simpleTest.js",
  94. "processLog" : True,
  95. "browsers" : [
  96. {
  97. "browserId" : "Browser"
  98. }
  99. ]
  100. }
  101. simulationOptions = ["logger=console"]
  102. simulationOptions.append("testClasspath=" + jobConfig["test-classpath"])
  103. testClasses = ",".join(jobConfig["test-include"])
  104. simulationOptions.append("testClasses=" + testClasses)
  105. if "simulation-options" in jobConfig:
  106. simulationOptions.extend(jobConfig["simulation-options"])
  107. testConfig["testRun"]["applications"][autName]["simulationOptions"] = simulationOptions
  108. if "java-classpath-separator" in jobConfig:
  109. testConfig["base"]["classPathSeparator"] = jobConfig["java-classpath-separator"]
  110. return testConfig
  111. def runPackage(self):
  112. self.log.indent()
  113. testType = self.getConfigSetting("base/type", "standalone")
  114. if testType == "remote" and "testRun" in self.configuration:
  115. jUrl = self.getConfigSetting("testRun/host", "")
  116. jUrl += self.getConfigSetting("testRun/qxPath", "")
  117. jUrl += "buildStatus.json"
  118. try:
  119. self.buildStatus = util.getJsonFromUrl(jUrl)
  120. except Exception, e:
  121. self.log.error("Error while getting remote build status: " + str(e))
  122. if testType == "local":
  123. try:
  124. buildStatusFile = os.path.join(self.config["build"]["stageDir"], "trunk", "qooxdoo", "buildStatus.json")
  125. self.buildStatus = Builder.getBuildStatusFromFile(buildStatusFile)
  126. except Exception, e:
  127. pass
  128. if "lint" in self.configuration:
  129. self.runLint(self.configuration["lint"])
  130. if "build" in self.configuration:
  131. buildConfig = self.configuration["build"]
  132. #buildConfig["buildLogDir"] = self.getConfigSetting("base/logDirectory", "") + "/" + buildConfig["buildLogDir"]
  133. builder = Builder(buildConfig, self.log)
  134. builder.buildAll()
  135. self.buildStatus = builder.buildStatus
  136. if "generator" in self.configuration:
  137. self.log.info("Starting Generator test run")
  138. self.log.indent()
  139. generatorResults = Builder.testGenerator(self.configuration["generator"], self.log)
  140. reportServer = self.getConfigSetting("reporting/reportServer", False)
  141. if reportServer:
  142. self.log.info("Sending Generator test results to report server")
  143. response = reporting.sendResultToReportServer(reportServer, generatorResults, "generatorRun")
  144. self.log.info("Report Server response: %s" %response)
  145. self.log.outdent()
  146. if not "testRun" in self.configuration:
  147. return
  148. if self.getConfigSetting("testRun/updateSimulator", False):
  149. util.svnUpdate(self.getConfigSetting("testRun/simulatorDirectory"))
  150. if "applications" in self.configuration["testRun"]:
  151. for app in self.getConfigSetting("testRun/applications", {}):
  152. #appConf = self.configuration["testRun"]["applications"][app]
  153. appConf = self.getConfigSetting("testRun/applications/" + app)
  154. self.runSimsForApp(app, appConf)
  155. if "collections" in self.configuration["testRun"]:
  156. for coll in self.getConfigSetting("testRun/collections", {}):
  157. collConf = self.getConfigSetting("testRun/collections/" + coll)
  158. self.runSimsForCollection(coll, collConf, self.getConfigSetting("testRun/simulatorDirectory"))
  159. self.log.outdent()
  160. def runSimsForCollection(self, collection, collConf, simulatorBaseDir):
  161. seleniumConfig = self.getConfigSetting("selenium")
  162. simulatorDirectory = os.path.join(simulatorBaseDir, "trunk", "tool", "selenium", "simulation", "demobrowser", "demo")
  163. #print "running simulations for demos: " + repr(collConf)
  164. #testReportFile = self.prepareTestReport(self.getConfigSetting("base/reportDirectory", ""), collection)
  165. scanDir = collConf["scanDir"]
  166. appList = util.locate(scanDir, "*.html")
  167. for appDir in appList:
  168. dir, file = os.path.split(appDir)
  169. category = os.path.basename(dir)
  170. appName, ext = os.path.splitext(file)
  171. #print category + " - " + appName
  172. scriptFile = os.path.join(simulatorDirectory, category, appName + ".js")
  173. if os.path.isfile(scriptFile):
  174. #print "got a test script for " + category + "-" + appName
  175. self.log.info("Running simulations for %s" %category + "." + appName)
  176. for browser in collConf["browsers"]:
  177. seleniumServer = SeleniumServer(seleniumConfig, logger = self.log)
  178. seleniumServer.start()
  179. simConf = self.getSimulationConfig(collection, "collections", browser)
  180. simConf["autPath"] = appDir
  181. simConf["simulationScript"] = scriptFile
  182. #print repr(simConf)
  183. sim = Simulation(simConf)
  184. sim.run()
  185. seleniumServer.stop()
  186. def runSimsForApp(self, app, appConf):
  187. testReportFile = self.prepareTestReport(self.getConfigSetting("base/reportDirectory", ""), app)
  188. logDirectory = self.getConfigSetting("base/logDirectory", False)
  189. if logDirectory:
  190. testLogFile = "%s/%s/%s.log" %(logDirectory,app,util.getTimestamp())
  191. seleniumConfig = self.getConfigSetting("selenium")
  192. manageSeleniumServer = self.getConfigSetting("selenium/seleniumServerJar", False)
  193. individualServer = self.getConfigSetting("individualServer", True, appConf)
  194. if manageSeleniumServer and not individualServer:
  195. self.log.info("Using one Selenium server instance for all %s simulations." %app)
  196. seleniumOptions = self.getConfigSetting("seleniumServerOptions", None, appConf)
  197. if seleniumOptions:
  198. seleniumConfig["options"] = seleniumOptions
  199. seleniumServer = SeleniumServer(seleniumConfig, logger=self.log)
  200. seleniumServer.start()
  201. if app in self.buildStatus:
  202. if self.buildStatus[app]["BuildError"]:
  203. self.sendDummyReport(app, appConf, testReportFile)
  204. return
  205. self.log.info("Running simulations for %s" %app)
  206. for browser in appConf["browsers"]:
  207. if manageSeleniumServer and individualServer:
  208. seleniumServer = SeleniumServer(seleniumConfig, logger=self.log)
  209. seleniumServer.start()
  210. simConf = self.getSimulationConfig(app, "applications", browser)
  211. if testLogFile:
  212. simConf["testLogFile"] = testLogFile
  213. sim = Simulation(simConf, logger=self.log)
  214. sim.run()
  215. if manageSeleniumServer and individualServer:
  216. seleniumServer.stop()
  217. if manageSeleniumServer and not individualServer:
  218. seleniumServer = SeleniumServer(seleniumConfig, logger=self.log)
  219. seleniumServer.stop()
  220. if self.getConfigSetting("reporting/mailTo", False):
  221. self.formatLog(simConf["testLogFile"], testReportFile, None)
  222. self.sendReport(app, testReportFile, self.getConfigSetting("reporting"))
  223. reportServer = self.getConfigSetting("reporting/reportServer", False)
  224. if reportServer:
  225. reportConf = {
  226. "runType" : self.getConfigSetting("testRun/runType", ""),
  227. "autName" : app,
  228. "autHost" : self.getConfigSetting("testRun/host", ""),
  229. "autQxPath" : self.getConfigSetting("testRun/qxPath", ""),
  230. "autPath" : appConf["path"],
  231. "startDate" : self.startDate,
  232. "testHostName" : self.getConfigSetting("base/testHostName", ""),
  233. "testHostId" : self.getConfigSetting("base/testHostId", ""),
  234. }
  235. try:
  236. self.reportResults(reportServer, simConf["testLogFile"], reportConf, simConf["ignoreLogEntries"])
  237. except Exception, e:
  238. self.log.error("Error sending report: " + str(e))
  239. def getSimulationConfig(self, autName, configKey, browserConf):
  240. self.log.info("Getting configuration for %s on %s" %(autName,browserConf["browserId"]))
  241. #currentAppConf = self.configuration["testRun"][configKey][autName]
  242. currentAppConf = self.getConfigSetting("testRun/%s/%s" %(configKey,autName))
  243. simConf = {
  244. "javaBin" : self.getConfigSetting("base/javaBin", "java"),
  245. "classPathSeparator" : self.getConfigSetting("base/classPathSeparator", ";"),
  246. "rhinoJar" : self.getConfigSetting("selenium/rhinoJar", None),
  247. "simulatorSvn" : self.getConfigSetting("testRun/simulatorDirectory", None),
  248. "autName" : autName,
  249. "autHost" : self.getConfigSetting("testRun/host", "http://localhost"),
  250. "browserId" : browserConf["browserId"],
  251. "browserLauncher" : self.configuration["browsers"][browserConf["browserId"]],
  252. "processLog" : self.getConfigSetting("processLog", None, currentAppConf)
  253. }
  254. seleniumDir = self.getConfigSetting("selenium/seleniumDir", "")
  255. seleniumClientDriverJar = self.getConfigSetting("selenium/seleniumClientDriverJar", "")
  256. seleniumVersion = self.getConfigSetting("seleniumVersion", None, browserConf)
  257. if not seleniumVersion:
  258. seleniumVersion = self.getConfigSetting("seleniumVersion", None, currentAppConf)
  259. if not seleniumVersion:
  260. seleniumVersion = self.getConfigSetting("testRun/seleniumVersion", "current")
  261. simConf["seleniumClientDriverJar"] = seleniumDir + "/" + seleniumVersion + "/" + seleniumClientDriverJar
  262. autPath = self.getConfigSetting("path", "", currentAppConf)
  263. autQxPath = self.getConfigSetting("testRun/qxPath", "")
  264. simConf["autPath"] = autQxPath + autPath
  265. simulationOptions = self.getConfigSetting("simulationOptions", None, browserConf)
  266. if not simulationOptions:
  267. simulationOptions = self.getConfigSetting("simulationOptions", None, currentAppConf)
  268. if not simulationOptions:
  269. simulationOptions = self.getConfigSetting("testRun/simulationOptions", [])
  270. simulationOptions.append("branch=%s" %self.getConfigSetting("testRun/branch", "unknown branch"))
  271. simConf["simulationOptions"] = simulationOptions
  272. simulationScript = self.getConfigSetting("simulationScript", None, browserConf)
  273. if not simulationScript:
  274. simulationScript = self.getConfigSetting("simulationScript", None, currentAppConf)
  275. if not simulationScript:
  276. simulationScript = self.getConfigSetting("testRun/simulationScript", None)
  277. simConf["simulationScript"] = simulationScript
  278. ignoreLogEntries = self.getConfigSetting("ignoreLogEntries", None, browserConf)
  279. if not ignoreLogEntries:
  280. ignoreLogEntries = self.getConfigSetting("ignoreLogEntries", None, currentAppConf)
  281. if not ignoreLogEntries:
  282. ignoreLogEntries = self.getConfigSetting("testRun/ignoreLogEntries", None)
  283. simConf["ignoreLogEntries"] = ignoreLogEntries
  284. return simConf
  285. def sendDummyReport(self, app, appConf, testReportFile):
  286. self.log.debug("%s built with errors" %app)
  287. browserList = []
  288. for browser in appConf["browsers"]:
  289. browserList.append(browser["browserId"])
  290. startDate = util.getTimestamp()
  291. dummyLogFile = self.getDummyLog(self.getConfigSetting("base/logDirectory", None), app, browserList, self.buildStatus[app]["BuildError"])
  292. #TODO: ignore
  293. ignore = None
  294. if self.getConfigSetting("reporting/mailTo", False):
  295. logFormatted = self.formatLog(dummyLogFile, testReportFile, ignore)
  296. if logFormatted:
  297. self.sendReport(app, testReportFile, self.configuration["reporting"])
  298. else:
  299. self.log.warn("No report HTML to send.")
  300. reportServer = self.getConfigSetting("reporting/reportServer", False)
  301. if reportServer:
  302. reportConf = {
  303. "runType" : self.getConfigSetting("testRun/runType", ""),
  304. "autName" : app,
  305. "autHost" : self.getConfigSetting("testRun/host"),
  306. "autQxPath" : self.getConfigSetting("testRun/qxPath", ""),
  307. "autPath" : appConf["path"],
  308. "startDate" : startDate,
  309. "testHostName" : self.getConfigSetting("base/testHostName", ""),
  310. "testHostId" : self.getConfigSetting("base/testHostId", ""),
  311. }
  312. try:
  313. self.reportResults(reportServer, dummyLogFile, reportConf)
  314. except Exception, e:
  315. self.log.error("Error sending dummy report: " + str(e))
  316. def prepareTestLog(self, logDir=os.getcwd(), appName="Unknown"):
  317. logPath = os.path.join(logDir, appName)
  318. if not os.path.isdir(logPath):
  319. os.mkdir(logPath)
  320. return os.path.join(logPath, self.startDate + ".log")
  321. def prepareTestReport(self, reportDir=os.getcwd(), appName="Unknown"):
  322. reportPath = os.path.join(reportDir, appName)
  323. if not os.path.isdir(reportPath):
  324. os.mkdir(reportPath)
  325. return os.path.join( reportPath, self.startDate + '.html')
  326. def getDummyLog(self, testLogDir, autName, browserList, buildError):
  327. self.log.info("Generating dummy log file for %s" %autName)
  328. dummyLogFile = os.path.join(testLogDir, autName, "DUMMY_%s.log" %(autName + self.startDate))
  329. dummyLog = codecs.open(dummyLogFile, "w", "utf-8")
  330. for browser in browserList:
  331. prefix = "qxSimulator_%s: " %str(random.randint(100000, 999999))
  332. dummyLog.write(prefix + "<h1>%s results from %s</h1>\n" %(autName, self.startDate))
  333. platform = util.getOperatingSystemName()
  334. if platform == "Windows":
  335. platform = "Win32"
  336. dummyLog.write(prefix + "<p>Platform: %s</p>\n" %platform)
  337. dummyLog.write(prefix + "<p>User agent: %s</p>\n" %browser)
  338. dummyLog.write(prefix + "<div class=\"qxappender\"><div class=\"level-error\">BUILD ERROR: %s</div></div>\n" %buildError)
  339. dummyLog.close()
  340. self.log.info("Created dummy log file %s" %dummyLogFile)
  341. return dummyLogFile
  342. def formatLog(self, inputfile=None, reportfile=None, ignore=None):
  343. class FormatterOpts:
  344. def __init__(self,logfile,htmlfile,ignore=None):
  345. self.logfile = logfile
  346. self.htmlfile = htmlfile
  347. self.ignore = ignore
  348. if not inputfile:
  349. raise RuntimeError, "No input file specified!"
  350. if not os.path.isfile(inputfile):
  351. raise RuntimeError, "%s is not a file!" %inputfile
  352. if os.path.getsize(inputfile) == "0L":
  353. self.log.warn("log file is empty!")
  354. options = FormatterOpts(inputfile, reportfile, ignore)
  355. if (self.simulate):
  356. self.log.info("SIMULATION: Formatting log file %s" %inputfile)
  357. else:
  358. self.log.info("Formatting log file %s" %inputfile)
  359. logformat = QxLogFormat(options)
  360. logformat.writeHtmlReport()
  361. def sendReport(self, autName, file, mailConf):
  362. self.log.info("Preparing to send %s report: %s" %(autName, file))
  363. if ( not(os.path.exists(file)) ):
  364. self.log.error("Report file %s not found!" %file)
  365. return
  366. mailConf["subject"] = "[qooxdoo-test] " + autName
  367. reportFile = open(file, 'rb')
  368. mailConf['html'] = reportFile.read()
  369. reportFile.seek(0)
  370. osRe = re.compile('<p>Platform: (.*)</p>')
  371. failedTestsRe = re.compile('<p class="failedtests">([\d]*)')
  372. totalErrorsRe = re.compile('<p class="totalerrors">Total errors in report: ([\d]*)</p>')
  373. osystem = ""
  374. failed = False
  375. totalE = ""
  376. for line in reportFile:
  377. osys = osRe.search(line)
  378. if (osys):
  379. osystem = osys.group(1)
  380. # Some browsers return "Linux i686" as the platform
  381. if "Linux" in osystem:
  382. osystem = "Linux"
  383. else:
  384. if "Win" in osystem:
  385. osystem = "Win32"
  386. failedTests = failedTestsRe.search(line)
  387. if (failedTests):
  388. failed = failedTests.group(1)
  389. totalErrors = totalErrorsRe.search(line)
  390. if (totalErrors):
  391. totalE = totalErrors.group(1)
  392. mailConf['subject'] += " " + osystem
  393. if ('hostId' in mailConf):
  394. mailConf['subject'] += " " + mailConf['hostId']
  395. if autName in self.buildStatus:
  396. branch = "unknown"
  397. if "branch" in self.buildStatus[autName]:
  398. branch = self.buildStatus[autName]["branch"]
  399. if "SVNRevision" in self.buildStatus[autName]:
  400. revision = self.buildStatus[autName]["SVNRevision"]
  401. mailConf['subject'] += " (%s r%s)" %(branch,revision)
  402. if (self.buildStatus[autName]["BuildError"]):
  403. self.mailConf['subject'] += " BUILD ERROR"
  404. if (failed):
  405. mailConf['subject'] += ": %s test run(s) failed!" %failed
  406. else:
  407. mailConf['subject'] += ": %s issues" %totalE
  408. # Send mail
  409. if (self.simulate):
  410. self.log.info("SIMULATION: Sending report email: Subject: %s Recipient: %s" %(mailConf['subject'], mailConf['mailTo']))
  411. if (osystem !=""):
  412. try:
  413. self.log.info("Sending report email: Subject: %s Recipient: %s" %(mailConf['subject'], mailConf['mailTo']))
  414. util.sendMultipartMail(mailConf)
  415. except Exception, e:
  416. self.log.error("Failed to send report email: " + str(e))
  417. else:
  418. self.log.info("Report email sent successfully")
  419. else:
  420. self.log.error("Report file seems incomplete, report not sent.")
  421. def reportResults(self, reportServerUrl, logFile, config, ignore=None):
  422. if (self.simulate):
  423. self.log.info("SIMULATION: Getting report data for %s" %config["autName"])
  424. return
  425. else:
  426. self.log.info("Getting report data for %s" %config["autName"])
  427. testRunDict = self.getTestRunDict(config)
  428. slp = SimulationLogParser(logFile, ignore)
  429. simulationData = slp.getSimulationData()
  430. testRunDict["simulations"] = simulationData
  431. try:
  432. if simulationData[0]["platform"] != "Unknown":
  433. testRunDict["test_hostos"] = simulationData[0]["platform"]
  434. except Exception:
  435. pass
  436. self.log.info("Report data aggregated, sending request")
  437. try:
  438. response = reporting.sendResultToReportServer(reportServerUrl, testRunDict, "testRun")
  439. self.log.info("Report server response: %s" %response)
  440. except Exception, e:
  441. self.log.error("Error sending test report to server: " + str(e))
  442. def getTestRunDict(self, config):
  443. autName = config["autName"]
  444. if "Source" in config["autName"]:
  445. autName = config["autName"][0:config["autName"].find("Source")]
  446. testRunDict = {
  447. "test_type" : config["runType"],
  448. "revision" : "",
  449. "aut_name" : autName,
  450. "aut_host" : config["autHost"],
  451. "aut_qxpath" : "",
  452. "aut_path" : config["autPath"],
  453. "test_host" : config["testHostName"],
  454. "test_hostos" : util.getOperatingSystemName(),
  455. "test_hostid" : "",
  456. "start_date" : config["startDate"],
  457. "end_date" : util.getTimestamp(),
  458. "simulations": [],
  459. "dev_run" : False
  460. }
  461. if config["autName"] in self.buildStatus:
  462. if "SVNRevision" in self.buildStatus[config["autName"]]:
  463. revision = self.buildStatus[config["autName"]]["SVNRevision"]
  464. testRunDict["revision"] = revision
  465. if "autQxPath" in config:
  466. testRunDict["aut_qxpath"] = config["autQxPath"]
  467. if "testHostId" in config:
  468. testRunDict["test_hostid"] = config["testHostId"]
  469. if "devRun" in config:
  470. testRunDict["dev_run"] = config["devRun"]
  471. return testRunDict
  472. def runLint(self, config):
  473. class LintOptions:
  474. def __init__(self, workdir = None):
  475. self.workdir = workdir
  476. for target in config["targets"]:
  477. options = LintOptions(target["path"])
  478. if "ignoreClasses" in target:
  479. setattr(options, "ignoreclasses", target["ignoreClasses"])
  480. elif "ignoreClasses" in config:
  481. setattr(options, "ignoreclasses", config["ignoreClasses"])
  482. if "ignoreMessages" in target:
  483. setattr(options, "ignoremessages", target["ignoreMessages"])
  484. elif "ignoreMessages" in config:
  485. setattr(options, "ignoremessages", config["ignoreMessages"])
  486. lint = Lint(options, self.log)
  487. reportServer = self.getConfigSetting("reporting/reportServer", False)
  488. if reportServer:
  489. lintResult = lint.getFlatResult()
  490. lintResult = self.getEnhancedLintResult(lintResult, target)
  491. self.log.info("Sending Lint results to report server")
  492. response = reporting.sendResultToReportServer(reportServer, lintResult, "lintRun")
  493. self.log.info("Report Server response: %s" %response)
  494. def getEnhancedLintResult(self, lintResult, target):
  495. for message in lintResult:
  496. message["target"] = target["name"]
  497. message["branch"] = "unknown"
  498. message["revision"] = "unknown"
  499. if target["name"] in self.buildStatus:
  500. if "branch" in self.buildStatus[target["name"]]:
  501. message["branch"] = self.buildStatus[target["name"]]["branch"]
  502. if "revision" in self.buildStatus[target["name"]]:
  503. message["revision"] = self.buildStatus[target["name"]]["revision"]
  504. elif "Testrunner" in self.buildStatus:
  505. if "branch" in self.buildStatus["Testrunner"]:
  506. message["branch"] = self.buildStatus["Testrunner"]["branch"]
  507. if "revision" in self.buildStatus["Testrunner"]:
  508. message["revision"] = self.buildStatus["Testrunner"]["revision"]
  509. return lintResult
  510. class Simulation:
  511. def __init__(self, config, simulate=False, logger=None):
  512. self.configuration = config
  513. self.simulate = simulate
  514. if not logger:
  515. self.log = Logger()
  516. else:
  517. self.log = logger
  518. self.startCmd = self.getStartCmd()
  519. def getStartCmd(self):
  520. conf = self.configuration
  521. cmd = conf["javaBin"]
  522. if "rhinoJar" in conf:
  523. cmd += " -cp %s%s%s" %(conf["seleniumClientDriverJar"], conf["classPathSeparator"], conf["rhinoJar"])
  524. if "rhinoMainClass" in conf:
  525. cmd += " %s" %conf["rhinoMainClass"]
  526. else:
  527. cmd += " org.mozilla.javascript.tools.shell.Main"
  528. cmd += " %s" %conf["simulationScript"]
  529. cmd += " autHost=%s" %conf["autHost"]
  530. cmd += " autPath="
  531. # Encode any URL parameters
  532. autPathList = conf['autPath'].split("?")
  533. if len(autPathList) == 1:
  534. cmd += autPathList[0]
  535. else:
  536. cmd += autPathList[0] + "%3F" + urllib.quote(autPathList[1])
  537. cmd += " simulatorSvn=%s" %conf['simulatorSvn']
  538. if (util.getOperatingSystemName() == "Windows"):
  539. cmd += " testBrowser=%s" %conf["browserLauncher"]
  540. else:
  541. cmd += " testBrowser='%s'" %conf["browserLauncher"]
  542. cmd += " browserId=\"%s\"" %conf["browserId"]
  543. if conf["simulationOptions"]:
  544. for opt in conf["simulationOptions"]:
  545. cmd += ' "%s"' %opt
  546. if "testLogFile" in conf:
  547. cmd += " logFile=%s" %conf["testLogFile"]
  548. return cmd
  549. def run(self):
  550. conf = self.configuration
  551. infoMsg = "Testing %s in %s" %(conf['autName'], conf["browserId"])
  552. debugMsg = "Selenium command line: %s" %self.startCmd
  553. if (self.simulate):
  554. self.log.info("SIMULATION: %s" %infoMsg)
  555. self.log.debug(debugMsg)
  556. else:
  557. self.log.info(infoMsg)
  558. self.log.debug(debugMsg)
  559. #TODO: out.split("\n")
  560. if self.configuration["processLog"]:
  561. util.invokeLog(self.startCmd, self.log, True)
  562. else:
  563. util.invokeExternal(self.startCmd)
  564. if __name__ == "__main__":
  565. try:
  566. rc = 0
  567. if not len(sys.argv) > 1:
  568. print "Usage: testing.py testconfig.json"
  569. sys.exit(rc)
  570. import demjson
  571. configFile = codecs.open(sys.argv[1], "r", "UTF-8")
  572. config = configFile.read()
  573. config = demjson.decode(config, allow_comments=True)
  574. testRun = TestRun(config)
  575. testRun.runPackage()
  576. except KeyboardInterrupt:
  577. print
  578. print " * Keyboard Interrupt"
  579. rc = 1
  580. sys.exit(rc)