summaryrefslogtreecommitdiffstats
path: root/bin/check-missing-export-asserts.py
diff options
context:
space:
mode:
Diffstat (limited to 'bin/check-missing-export-asserts.py')
-rwxr-xr-xbin/check-missing-export-asserts.py177
1 files changed, 177 insertions, 0 deletions
diff --git a/bin/check-missing-export-asserts.py b/bin/check-missing-export-asserts.py
new file mode 100755
index 0000000000..2e181027d9
--- /dev/null
+++ b/bin/check-missing-export-asserts.py
@@ -0,0 +1,177 @@
+#!/usr/bin/env python3
+
+# This file is part of the LibreOffice 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:
+ #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)