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/.
11 from subprocess
import Popen
, DEVNULL
, PIPE
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
)
29 def checkout_file(repoPath
, filePath
):
30 p
= Popen(['git', '-C', repoPath
, 'checkout', repoPath
+ filePath
],
31 stdout
=DEVNULL
, stderr
=DEVNULL
)
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
)
43 errout
= p
.stderr
.readline().decode('utf-8').strip()
44 if errout
.startswith('debug:'):
45 info
= errout
.split(': ')[1]
48 if errout
== '' or p
.poll():
51 logger
.info('Parsing output from ' + makeName
)
54 for line
in err
.strip().split('\n'):
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
)
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()
79 for i
in range(len(lines
)):
82 if line
.startswith('DECLARE'):
84 testName
= re
.findall('"([^"]*)"', line
)[0]
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
100 for i
in results
.values():
101 if not i
['checkPages'] and int(i
['pages']) >= 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:
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
))
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()
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
:
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');
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
)
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
):
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]
165 logger
.info( fileNamePath
+ " has unstaged changes. Ignoring...")
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__
)) + '/..'