| #!/usr/bin/env python3 |
| |
| # This file is part of the Collabora Office project. |
| # |
| # This Source Code Form is subject to the terms of the Mozilla Public |
| # License, v. 2.0. If a copy of the MPL was not distributed with this |
| # file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| |
| import re |
| import os |
| from subprocess import Popen, DEVNULL, PIPE |
| import logging |
| import sys |
| |
| def start_logger(): |
| rootLogger = logging.getLogger() |
| rootLogger.setLevel(os.environ.get("LOGLEVEL", "INFO")) |
| |
| logFormatter = logging.Formatter("%(asctime)s - %(message)s") |
| fileHandler = logging.FileHandler("log.txt") |
| fileHandler.setFormatter(logFormatter) |
| rootLogger.addHandler(fileHandler) |
| |
| streamHandler = logging.StreamHandler(sys.stdout) |
| rootLogger.addHandler(streamHandler) |
| |
| return rootLogger |
| |
| def checkout_file(repoPath, filePath): |
| p = Popen(['git', '-C', repoPath, 'checkout', repoPath + filePath], |
| stdout=DEVNULL, stderr=DEVNULL) |
| p.communicate() |
| |
| |
| def execute_make_and_parse_output(fileName, makeName): |
| os.environ["CPPUNITTRACE"] = "gdb -ex=run -ex=quit --args" |
| p = Popen(['make', makeName], |
| stdout=DEVNULL, stderr=PIPE) |
| logger.info('Executing ' + makeName) |
| |
| err = "" |
| while True: |
| errout = p.stderr.readline().decode('utf-8').strip() |
| if errout.startswith('debug:'): |
| info = errout.split(': ')[1] |
| err += info + '\n' |
| logger.info(info) |
| if errout == '' or p.poll(): |
| break |
| |
| logger.info('Parsing output from ' + makeName) |
| |
| results = {} |
| for line in err.strip().split('\n'): |
| if not line: |
| continue |
| splitLine = line.split(' - ') |
| typeCheck = splitLine[0] |
| testName = splitLine[1] |
| importNumber = splitLine[2] |
| exportNumber = splitLine[3].strip() |
| if importNumber != exportNumber: |
| logger.info("WARNING: " + testName + " has different number of " + typeCheck + ". Import: " + \ |
| importNumber + " Export: " + exportNumber) |
| else: |
| if testName.endswith('.odt') or testName.endswith('.ott'): |
| if testName not in results: |
| results[testName] = {'pages': 0, 'checkPages': False, 'index': 0, |
| 'shapes': 0, 'checkShapes': False} |
| if typeCheck == 'PAGES': |
| results[testName]['pages'] = importNumber |
| elif typeCheck == 'SHAPES': |
| results[testName]['shapes'] = importNumber |
| |
| cxxFile = open(fileName, 'r') |
| lines = cxxFile.readlines() |
| cxxFile.close() |
| |
| for i in range(len(lines)): |
| line = lines[i] |
| |
| if line.startswith('DECLARE'): |
| try: |
| testName = re.findall('"([^"]*)"', line)[0] |
| except Exception: |
| #check in the next line when line is broken into 2 lines |
| testName = re.findall('"([^"]*)"', lines[i + 1])[0] |
| |
| if testName in results: |
| results[testName]['index'] = i |
| |
| elif 'getPages' in line: |
| if testName in results: |
| results[testName]['checkPages'] = True |
| elif 'getShapes' in line: |
| if testName in results: |
| results[testName]['checkShapes'] = True |
| |
| total = 0 |
| for i in results.values(): |
| if not i['checkPages'] and int(i['pages']) >= 1: |
| total += 1 |
| lines.insert(i['index'] + 2, " CPPUNIT_ASSERT_EQUAL(" + str(i['pages']) + ", getPages());\n") |
| |
| if not i['checkShapes'] and int(i['shapes']) >= 1: |
| total += 1 |
| lines.insert(i['index'] + 2, " CPPUNIT_ASSERT_EQUAL(" + str(i['shapes']) + ", getShapes());\n") |
| |
| logger.info(str(total) + ' missing asserts added in ' + fileName) |
| |
| cxxFile = open(fileName, "w") |
| cxxFile.write("".join(lines)) |
| cxxFile.close() |
| |
| def insert_code_in_sw_model(repoPath, modelTestRelPath): |
| modelTestPath = repoPath + modelTestRelPath |
| modelTestFile = open(modelTestPath, 'r') |
| modelTestLines = modelTestFile.readlines() |
| modelTestFile.close() |
| |
| addText = False |
| # Add code to check import and export pages |
| for i in range(len(modelTestLines)): |
| line = modelTestLines[i] |
| if line.strip().startswith('void'): |
| if 'executeLoadVerifyReloadVerify' in line or \ |
| 'executeLoadReloadVerify' in line: |
| addText = True |
| else: |
| addText = False |
| |
| if addText and 'reload' in line: |
| modelTestLines.insert( i - 1, 'int nImportPages = getPages();int nImportShapes = getShapes();\n') |
| modelTestLines.insert( i + 2, 'int nExportPages = getPages();int nExportShapes = getShapes();SAL_' + \ |
| 'DEBUG("PAGES - " << filename << " - " << nImportPages << " - " << nExportPages);SAL_' + \ |
| 'DEBUG("SHAPES - " << filename << " - " << nImportShapes << " - " << nExportShapes);\n') |
| addText = False |
| |
| modelTestFile = open(modelTestPath, 'w') |
| modelTestFile.write("".join(modelTestLines)) |
| modelTestFile.close() |
| |
| def check_sw(repoPath): |
| modelTestRelPath = '/sw/qa/unit/swmodeltestbase.cxx' |
| |
| checkout_file(repoPath, modelTestRelPath) |
| insert_code_in_sw_model(repoPath, modelTestRelPath) |
| |
| os.chdir(repoPath) |
| |
| qaDir = os.path.join(repoPath, 'sw/qa/extras/') |
| for dirName in os.listdir(qaDir): |
| subdirName = os.path.join(qaDir, dirName) |
| if not os.path.isdir(subdirName): |
| continue |
| |
| for fileName in os.listdir(subdirName): |
| if 'export' in fileName and fileName.endswith('.cxx'): |
| fileNamePath = os.path.join(subdirName, fileName) |
| |
| p = Popen(['git', '-C', repoPath, 'diff', fileNamePath], |
| stdout=PIPE, stderr=DEVNULL) |
| stdout = p.communicate()[0] |
| if stdout != b'': |
| logger.info( fileNamePath + " has unstaged changes. Ignoring...") |
| continue |
| makeName = 'CppunitTest_sw_' + os.path.basename(fileNamePath).split('.')[0] |
| execute_make_and_parse_output(fileNamePath, makeName) |
| |
| checkout_file(repoPath, modelTestRelPath) |
| |
| if __name__ == '__main__': |
| logger = start_logger() |
| |
| repoPath = os.path.dirname(os.path.abspath(__file__)) + '/..' |
| |
| check_sw(repoPath) |