| 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | ## |
|---|
| 3 | ## $Id$ |
|---|
| 4 | ## |
|---|
| 5 | ## This file is part of CDS Indico. |
|---|
| 6 | ## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN. |
|---|
| 7 | ## |
|---|
| 8 | ## CDS Indico is free software; you can redistribute it and/or |
|---|
| 9 | ## modify it under the terms of the GNU General Public License as |
|---|
| 10 | ## published by the Free Software Foundation; either version 2 of the |
|---|
| 11 | ## License, or (at your option) any later version. |
|---|
| 12 | ## |
|---|
| 13 | ## CDS Indico is distributed in the hope that it will be useful, but |
|---|
| 14 | ## WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 15 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 16 | ## General Public License for more details. |
|---|
| 17 | ## |
|---|
| 18 | ## You should have received a copy of the GNU General Public License |
|---|
| 19 | ## along with CDS Indico; if not, write to the Free Software Foundation, Inc., |
|---|
| 20 | ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. |
|---|
| 21 | |
|---|
| 22 | |
|---|
| 23 | import os |
|---|
| 24 | import unittest |
|---|
| 25 | import sys |
|---|
| 26 | import glob |
|---|
| 27 | import re |
|---|
| 28 | import nose |
|---|
| 29 | import figleaf |
|---|
| 30 | import figleaf.annotate_html |
|---|
| 31 | import subprocess |
|---|
| 32 | import socket |
|---|
| 33 | import time |
|---|
| 34 | import commands |
|---|
| 35 | import StringIO |
|---|
| 36 | from selenium import selenium |
|---|
| 37 | |
|---|
| 38 | class Indicop(): |
|---|
| 39 | |
|---|
| 40 | def unit(self): |
|---|
| 41 | #capturing the stderr |
|---|
| 42 | outerr = StringIO.StringIO() |
|---|
| 43 | sys.stderr = outerr |
|---|
| 44 | |
|---|
| 45 | result = nose.run(argv=['nose','-v', os.path.join(self.setupDir, 'python', 'unit', 'MaKaC_tests')]) |
|---|
| 46 | |
|---|
| 47 | #restoring the stderr |
|---|
| 48 | sys.stderr = sys.__stderr__ |
|---|
| 49 | |
|---|
| 50 | s = outerr.getvalue() |
|---|
| 51 | self.writeReport("pyunit", s) |
|---|
| 52 | |
|---|
| 53 | if result: |
|---|
| 54 | return "PY Unit tests succeeded\n" |
|---|
| 55 | else: |
|---|
| 56 | return "[FAIL] Unit tests - report in indicop/report/pyunit.txt\n" |
|---|
| 57 | |
|---|
| 58 | |
|---|
| 59 | def functional(self): |
|---|
| 60 | try: |
|---|
| 61 | #Starting Selenium server |
|---|
| 62 | child = subprocess.Popen(["java", "-jar", os.path.join(self.setupDir, 'python', 'functional', 'selenium-server.jar')], |
|---|
| 63 | stdout=subprocess.PIPE) |
|---|
| 64 | except OSError: |
|---|
| 65 | print "[ERR] Could not start selenium server - command \"java\" needs to be in your PATH." |
|---|
| 66 | sys.exit(1) |
|---|
| 67 | |
|---|
| 68 | sel = selenium("localhost", 4444, "*chrome", "http://www.cern.ch/") |
|---|
| 69 | for i in range(5): |
|---|
| 70 | try: |
|---|
| 71 | #testing if the selenium server has started |
|---|
| 72 | time.sleep(1) |
|---|
| 73 | sel.start() |
|---|
| 74 | sel.stop() |
|---|
| 75 | |
|---|
| 76 | #server has started |
|---|
| 77 | break |
|---|
| 78 | except socket.error: |
|---|
| 79 | print 'Selenium has not started yet. Attempt #%s' % (i+1) |
|---|
| 80 | time.sleep(5) |
|---|
| 81 | else: |
|---|
| 82 | print '[ERR] Could not start functional tests because selenium server cannot be started.' |
|---|
| 83 | sys.exit(1) |
|---|
| 84 | |
|---|
| 85 | #capturing the stderr |
|---|
| 86 | outerr = StringIO.StringIO() |
|---|
| 87 | sys.stderr = outerr |
|---|
| 88 | |
|---|
| 89 | result = nose.run(argv=['nose','-v', os.path.join(self.setupDir, 'python', 'functional')]) |
|---|
| 90 | |
|---|
| 91 | #restoring the stderr |
|---|
| 92 | sys.stderr = sys.__stderr__ |
|---|
| 93 | |
|---|
| 94 | s = outerr.getvalue() |
|---|
| 95 | self.writeReport("pyfunctional", s) |
|---|
| 96 | |
|---|
| 97 | report = "" |
|---|
| 98 | if result: |
|---|
| 99 | report = "PY Functional tests succeeded\n" |
|---|
| 100 | else: |
|---|
| 101 | report = "[FAIL] Functional tests - report in indicop/report/pyfunctional.txt\n" |
|---|
| 102 | |
|---|
| 103 | #Stopping Selenium Server |
|---|
| 104 | child.kill() |
|---|
| 105 | |
|---|
| 106 | return report |
|---|
| 107 | |
|---|
| 108 | |
|---|
| 109 | def pylint(self): |
|---|
| 110 | statusOutput = commands.getstatusoutput("pylint --rcfile=%s %s" % |
|---|
| 111 | (os.path.join(self.setupDir, 'python', 'pylint', 'pylint.conf'), |
|---|
| 112 | os.path.join(self.setupDir, '..', 'indico', 'MaKaC'))) |
|---|
| 113 | if statusOutput[1].find("pylint: not found") > -1: |
|---|
| 114 | print "[ERR] Could not start Source Analysis - command \"pylint\" needs to be in your PATH." |
|---|
| 115 | sys.exit(1) |
|---|
| 116 | else: |
|---|
| 117 | self.writeReport("pylint", statusOutput[1]) |
|---|
| 118 | return "PY Lint - report in indicop/report/pylint.txt\n" |
|---|
| 119 | |
|---|
| 120 | |
|---|
| 121 | def jsUnit(self, coverage, specify): |
|---|
| 122 | try: |
|---|
| 123 | #Starting js-test-driver server |
|---|
| 124 | server = subprocess.Popen(["java", "-jar", os.path.join(self.setupDir, 'javascript', 'unit', 'JsTestDriver-1.2.jar'), "--port", "9876", "--browser", "firefox"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
|---|
| 125 | time.sleep(2) |
|---|
| 126 | |
|---|
| 127 | #switching directory to run the tests |
|---|
| 128 | rootDir = os.getcwd() |
|---|
| 129 | os.chdir(os.path.join(self.setupDir, 'javascript', 'unit')) |
|---|
| 130 | |
|---|
| 131 | #check if server is ready |
|---|
| 132 | for i in range(5): |
|---|
| 133 | if coverage: |
|---|
| 134 | jsDryRun = commands.getstatusoutput("java -jar JsTestDriver-1.2.jar --tests Fake.dryRun --testOutput %s" % os.path.join('..', '..', 'report', 'jscoverage')) |
|---|
| 135 | else: |
|---|
| 136 | jsDryRun = commands.getstatusoutput("java -jar JsTestDriver-1.2.jar --config jsTestDriverNoCoverage.conf --tests Fake.dryRun") |
|---|
| 137 | if jsDryRun[1].startswith("No browsers were captured, nothing to run..."): |
|---|
| 138 | print "Js-test-driver server has not started yet. Attempt #%s" % (i+1) |
|---|
| 139 | time.sleep(5) |
|---|
| 140 | else: |
|---|
| 141 | #server is ready |
|---|
| 142 | break |
|---|
| 143 | else: |
|---|
| 144 | print '[ERR] Could not start js unit tests because js-test-driver server cannot be started.' |
|---|
| 145 | sys.exit(1) |
|---|
| 146 | |
|---|
| 147 | #setting tests to run |
|---|
| 148 | toTest = "" |
|---|
| 149 | if specify: |
|---|
| 150 | toTest = specify |
|---|
| 151 | else: |
|---|
| 152 | toTest = "all" |
|---|
| 153 | |
|---|
| 154 | |
|---|
| 155 | coverageReport = "" |
|---|
| 156 | if coverage: |
|---|
| 157 | jsTest = commands.getstatusoutput("java -jar JsTestDriver-1.2.jar --tests %s --testOutput %s" % (toTest, os.path.join('..', '..', 'report', 'jscoverage'))) |
|---|
| 158 | |
|---|
| 159 | #generate html for coverage |
|---|
| 160 | genOutput = commands.getstatusoutput("genhtml -o %s %s" % |
|---|
| 161 | (os.path.join('..', '..', 'report', 'jscoverage'), |
|---|
| 162 | os.path.join('..', '..', 'report', 'jscoverage', 'jsTestDriver.conf-coverage.dat'))) |
|---|
| 163 | |
|---|
| 164 | if genOutput[1].find("genhtml") > -1: |
|---|
| 165 | coverageReport = "[ERR] JS Unit Tests - html coverage generation failed, genhtml needs to be in your PATH.\n" |
|---|
| 166 | else: |
|---|
| 167 | coverageReport = "JS Unit Tests - coverage generated in indicop/report/jscoverage/index.html\n" |
|---|
| 168 | |
|---|
| 169 | else: |
|---|
| 170 | jsTest = commands.getstatusoutput("java -jar JsTestDriver-1.2.jar --config jsTestDriverNoCoverage.conf --tests %s --testOutput coverage" % toTest) |
|---|
| 171 | |
|---|
| 172 | #restoring directory |
|---|
| 173 | os.chdir(rootDir) |
|---|
| 174 | |
|---|
| 175 | report = "" |
|---|
| 176 | if specify: |
|---|
| 177 | #ouputing directly in the console |
|---|
| 178 | print jsTest[1] |
|---|
| 179 | report = "JS Unit Tests - Output in console\n" |
|---|
| 180 | else: |
|---|
| 181 | self.writeReport("jsunit", jsTest[1]) |
|---|
| 182 | report = "JS Unit Tests - report in indicop/report/jsunit.txt\n" |
|---|
| 183 | except OSError: |
|---|
| 184 | print "[ERR] Could not start js-test-driver server - command \"java\" needs to be in your PATH." |
|---|
| 185 | sys.exit(1) |
|---|
| 186 | |
|---|
| 187 | #stopping the server |
|---|
| 188 | server.kill() |
|---|
| 189 | return coverageReport + report |
|---|
| 190 | |
|---|
| 191 | |
|---|
| 192 | def jsLint(self): |
|---|
| 193 | #Folders which are going to be scanned. |
|---|
| 194 | #Files are going to be find recursively in these folders |
|---|
| 195 | folderNames=['Admin', 'Collaboration', 'Core', 'Display', 'Legacy', 'Management', |
|---|
| 196 | 'MaterialEditor', 'Timetable'] |
|---|
| 197 | |
|---|
| 198 | outputString = "" |
|---|
| 199 | |
|---|
| 200 | #checking if rhino is accessible |
|---|
| 201 | statusOutput = commands.getstatusoutput("rhino -?") |
|---|
| 202 | if statusOutput[1].find("rhino: not found") > -1: |
|---|
| 203 | print "[ERR] Could not start JS Source Analysis - command \"rhino\" needs to be in your PATH." |
|---|
| 204 | sys.exit(1) |
|---|
| 205 | |
|---|
| 206 | for folderName in folderNames: |
|---|
| 207 | #for root, dirs, files in os.walk("%s/indico/htdocs/js/indico/%s" % (os.getcwd(), folderName)): |
|---|
| 208 | for root, dirs, files in os.walk(os.path.join(self.setupDir, '..', 'indico', 'htdocs', 'js', 'indico', folderName)): |
|---|
| 209 | for name in files: |
|---|
| 210 | filename = os.path.join(root, name) |
|---|
| 211 | outputString += "\n================== Scanning %s ==================\n" % filename |
|---|
| 212 | output = commands.getstatusoutput("rhino %s %s" % (os.path.join(self.setupDir, 'javascript', 'jslint', 'jslint.js'), filename)) |
|---|
| 213 | outputString += output[1] |
|---|
| 214 | |
|---|
| 215 | self.writeReport("jslint", outputString) |
|---|
| 216 | return "JS Lint - report in indicop/report/jslint.txt\n" |
|---|
| 217 | |
|---|
| 218 | |
|---|
| 219 | def writeReport(self, filename, content): |
|---|
| 220 | f = open(os.path.join(self.setupDir, 'report', filename + ".txt"), 'w') |
|---|
| 221 | f.write(content) |
|---|
| 222 | f.close() |
|---|
| 223 | |
|---|
| 224 | def main(self, specify, coverage, unitTest, functionalTest, pylint, jsunit, jslint, jsCoverage, jsSpecify): |
|---|
| 225 | #path where this file is |
|---|
| 226 | self.setupDir = os.path.dirname(__file__) |
|---|
| 227 | |
|---|
| 228 | returnString="\n\n=============== ~INDICOP SAYS~ ===============\n\n" |
|---|
| 229 | |
|---|
| 230 | if coverage: |
|---|
| 231 | figleaf.start() |
|---|
| 232 | |
|---|
| 233 | if specify: |
|---|
| 234 | #running directly the test here and ouputing in the console |
|---|
| 235 | result = nose.run(argv=['nose','-v', os.path.join(self.setupDir, 'python', specify)]) |
|---|
| 236 | if result: |
|---|
| 237 | returnString += "Specified Test - Succeeded\n" |
|---|
| 238 | else: |
|---|
| 239 | returnString += "[FAIL] Specified Test - read output from console\n" |
|---|
| 240 | elif pylint: |
|---|
| 241 | returnString += self.pylint() |
|---|
| 242 | elif unitTest: |
|---|
| 243 | returnString += self.unit() |
|---|
| 244 | elif functionalTest: |
|---|
| 245 | returnString += self.functional() |
|---|
| 246 | elif jsunit or jsSpecify: |
|---|
| 247 | returnString += self.jsUnit(jsCoverage, jsSpecify) |
|---|
| 248 | elif jslint: |
|---|
| 249 | returnString += self.jsLint() |
|---|
| 250 | else: |
|---|
| 251 | returnString += self.unit() |
|---|
| 252 | returnString += self.functional() |
|---|
| 253 | returnString += self.pylint() |
|---|
| 254 | returnString += self.jsUnit(jsCoverage, jsSpecify) |
|---|
| 255 | returnString += self.jsLint() |
|---|
| 256 | |
|---|
| 257 | if coverage: |
|---|
| 258 | figleaf.stop() |
|---|
| 259 | coverageOutput = figleaf.get_data().gather_files() |
|---|
| 260 | coverageDir = os.path.join(self.setupDir, 'report', 'pycoverage') |
|---|
| 261 | try: |
|---|
| 262 | figleaf.annotate_html.report_as_html(coverageOutput, coverageDir, [], {}) |
|---|
| 263 | except IOError: |
|---|
| 264 | os.mkdir(coverageDir) |
|---|
| 265 | figleaf.annotate_html.report_as_html(coverageOutput, coverageDir, [], {}) |
|---|
| 266 | returnString += "PY Unit Test - Report generated in report/pycoverage/index.html\n" |
|---|
| 267 | |
|---|
| 268 | |
|---|
| 269 | return returnString |
|---|