Update git submodules
[LibreOffice.git] / bin / check-missing-export-asserts.py
blob9f0fb52da516ca1301b10a7f66967a1ae506f716
1 #!/usr/bin/env python3
3 # This file is part of the LibreOffice project.
5 # This Source Code Form is subject to the terms of the Mozilla Public
6 # License, v. 2.0. If a copy of the MPL was not distributed with this
7 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 import re
10 import os
11 from subprocess import Popen, DEVNULL, PIPE
12 import logging
13 import sys
15 def start_logger():
16 rootLogger = logging.getLogger()
17 rootLogger.setLevel(os.environ.get("LOGLEVEL", "INFO"))
19 logFormatter = logging.Formatter("%(asctime)s - %(message)s")
20 fileHandler = logging.FileHandler("log.txt")
21 fileHandler.setFormatter(logFormatter)
22 rootLogger.addHandler(fileHandler)
24 streamHandler = logging.StreamHandler(sys.stdout)
25 rootLogger.addHandler(streamHandler)
27 return rootLogger
29 def checkout_file(repoPath, filePath):
30 p = Popen(['git', '-C', repoPath, 'checkout', repoPath + filePath],
31 stdout=DEVNULL, stderr=DEVNULL)
32 p.communicate()
35 def execute_make_and_parse_output(fileName, makeName):
36 os.environ["CPPUNITTRACE"] = "gdb -ex=run -ex=quit --args"
37 p = Popen(['make', makeName],
38 stdout=DEVNULL, stderr=PIPE)
39 logger.info('Executing ' + makeName)
41 err = ""
42 while True:
43 errout = p.stderr.readline().decode('utf-8').strip()
44 if errout.startswith('debug:'):
45 info = errout.split(': ')[1]
46 err += info + '\n'
47 logger.info(info)
48 if errout == '' or p.poll():
49 break
51 logger.info('Parsing output from ' + makeName)
53 results = {}
54 for line in err.strip().split('\n'):
55 if not line:
56 continue
57 splitLine = line.split(' - ')
58 typeCheck = splitLine[0]
59 testName = splitLine[1]
60 importNumber = splitLine[2]
61 exportNumber = splitLine[3].strip()
62 if importNumber != exportNumber:
63 logger.info("WARNING: " + testName + " has different number of " + typeCheck + ". Import: " + \
64 importNumber + " Export: " + exportNumber)
65 else:
66 if testName.endswith('.odt') or testName.endswith('.ott'):
67 if testName not in results:
68 results[testName] = {'pages': 0, 'checkPages': False, 'index': 0,
69 'shapes': 0, 'checkShapes': False}
70 if typeCheck == 'PAGES':
71 results[testName]['pages'] = importNumber
72 elif typeCheck == 'SHAPES':
73 results[testName]['shapes'] = importNumber
75 cxxFile = open(fileName, 'r')
76 lines = cxxFile.readlines()
77 cxxFile.close()
79 for i in range(len(lines)):
80 line = lines[i]
82 if line.startswith('DECLARE'):
83 try:
84 testName = re.findall('"([^"]*)"', line)[0]
85 except:
86 #check in the next line when line is broken into 2 lines
87 testName = re.findall('"([^"]*)"', lines[i + 1])[0]
89 if testName in results:
90 results[testName]['index'] = i
92 elif 'getPages' in line:
93 if testName in results:
94 results[testName]['checkPages'] = True
95 elif 'getShapes' in line:
96 if testName in results:
97 results[testName]['checkShapes'] = True
99 total = 0
100 for i in results.values():
101 if not i['checkPages'] and int(i['pages']) >= 1:
102 total += 1
103 lines.insert(i['index'] + 2, " CPPUNIT_ASSERT_EQUAL(" + str(i['pages']) + ", getPages());\n")
105 if not i['checkShapes'] and int(i['shapes']) >= 1:
106 total += 1
107 lines.insert(i['index'] + 2, " CPPUNIT_ASSERT_EQUAL(" + str(i['shapes']) + ", getShapes());\n")
109 logger.info(str(total) + ' missing asserts added in ' + fileName)
111 cxxFile = open(fileName, "w")
112 cxxFile.write("".join(lines))
113 cxxFile.close()
115 def insert_code_in_sw_model(repoPath, modelTestRelPath):
116 modelTestPath = repoPath + modelTestRelPath
117 modelTestFile = open(modelTestPath, 'r')
118 modelTestLines = modelTestFile.readlines()
119 modelTestFile.close()
121 addText = False
122 # Add code to check import and export pages
123 for i in range(len(modelTestLines)):
124 line = modelTestLines[i]
125 if line.strip().startswith('void'):
126 if 'executeLoadVerifyReloadVerify' in line or \
127 'executeLoadReloadVerify' in line:
128 addText = True
129 else:
130 addText = False
132 if addText and 'reload' in line:
133 modelTestLines.insert( i - 1, 'int nImportPages = getPages();int nImportShapes = getShapes();\n')
134 modelTestLines.insert( i + 2, 'int nExportPages = getPages();int nExportShapes = getShapes();SAL_' + \
135 'DEBUG("PAGES - " << filename << " - " << nImportPages << " - " << nExportPages);SAL_' + \
136 'DEBUG("SHAPES - " << filename << " - " << nImportShapes << " - " << nExportShapes);\n')
137 addText = False
139 modelTestFile = open(modelTestPath, 'w')
140 modelTestFile.write("".join(modelTestLines))
141 modelTestFile.close()
143 def check_sw(repoPath):
144 modelTestRelPath = '/sw/qa/unit/swmodeltestbase.cxx'
146 checkout_file(repoPath, modelTestRelPath)
147 insert_code_in_sw_model(repoPath, modelTestRelPath)
149 os.chdir(repoPath)
151 qaDir = os.path.join(repoPath, 'sw/qa/extras/')
152 for dirName in os.listdir(qaDir):
153 subdirName = os.path.join(qaDir, dirName)
154 if not os.path.isdir(subdirName):
155 continue
157 for fileName in os.listdir(subdirName):
158 if 'export' in fileName and fileName.endswith('.cxx'):
159 fileNamePath = os.path.join(subdirName, fileName)
161 p = Popen(['git', '-C', repoPath, 'diff', fileNamePath],
162 stdout=PIPE, stderr=DEVNULL)
163 stdout = p.communicate()[0]
164 if stdout != b'':
165 logger.info( fileNamePath + " has unstaged changes. Ignoring...")
166 continue
167 makeName = 'CppunitTest_sw_' + os.path.basename(fileNamePath).split('.')[0]
168 execute_make_and_parse_output(fileNamePath, makeName)
170 checkout_file(repoPath, modelTestRelPath)
172 if __name__ == '__main__':
173 logger = start_logger()
175 repoPath = os.path.dirname(os.path.abspath(__file__)) + '/..'
177 check_sw(repoPath)