blob: dca100e9945b6d7147b7549c0a8f7c3d823aa553 [file] [log] [blame]
Christophe Favergeon2942a332020-01-20 14:18:48 +01001import os
2import os.path
3import subprocess
4import colorama
5from colorama import init,Fore, Back, Style
6import argparse
Christophe Favergeon512b1482020-02-07 11:25:11 +01007from TestScripts.Regression.Commands import *
8import yaml
9import sys
10import itertools
11from pathlib import Path
Christophe Favergeon8cb37302020-05-13 13:06:58 +020012import sqlite3
Christophe Favergeon512b1482020-02-07 11:25:11 +010013
Christophe Favergeon8cb37302020-05-13 13:06:58 +020014# Command to get last runid
15lastID="""SELECT runid FROM RUN ORDER BY runid DESC LIMIT 1
16"""
17
18addNewIDCmd="""INSERT INTO RUN VALUES(?,date('now'))
19"""
20
21benchID = 0
22regID = 0
23
24def getLastRunID(c):
25 r=c.execute(lastID)
26 result=r.fetchone()
27 if result is None:
28 return(0)
29 else:
30 return(int(result[0]))
31
32def addNewID(c,newid):
33 c.execute(addNewIDCmd,(newid,))
34 c.commit()
Christophe Favergeon512b1482020-02-07 11:25:11 +010035
36# Small state machine
37def updateTestStatus(testStatusForThisBuild,newTestStatus):
38 if testStatusForThisBuild == NOTESTFAILED:
39 if newTestStatus == NOTESTFAILED:
40 return(NOTESTFAILED)
41 if newTestStatus == MAKEFAILED:
42 return(MAKEFAILED)
43 if newTestStatus == TESTFAILED:
44 return(TESTFAILED)
45 if testStatusForThisBuild == MAKEFAILED:
46 if newTestStatus == NOTESTFAILED:
47 return(MAKEFAILED)
48 if newTestStatus == MAKEFAILED:
49 return(MAKEFAILED)
50 if newTestStatus == TESTFAILED:
51 return(TESTFAILED)
52 if testStatusForThisBuild == TESTFAILED:
53 if newTestStatus == NOTESTFAILED:
54 return(TESTFAILED)
55 if newTestStatus == MAKEFAILED:
56 return(TESTFAILED)
57 if newTestStatus == TESTFAILED:
58 return(TESTFAILED)
59 if testStatusForThisBuild == FLOWFAILURE:
60 return(testStatusForThisBuild)
61 if testStatusForThisBuild == CALLFAILURE:
62 return(testStatusForThisBuild)
63
Christophe Favergeon830283b2020-04-27 14:51:08 +020064# Analyze the configuration flags (like loopunroll etc ...)
65def analyzeFlags(flags):
66
67 onoffFlags = []
68 for f in flags:
69 if type(f) is dict:
70 for var in f:
71 if type(f[var]) is bool:
72 if f[var]:
73 onoffFlags.append(["-D%s=ON" % (var)])
74 else:
75 onoffFlags.append(["-D%s=OFF" % (var)])
76 else:
77 onoffFlags.append(["-D%s=%s" % (var,f[var])])
78 else:
79 onoffFlags.append(["-D" + f +"=ON","-D" + f +"=OFF"])
80
81 allConfigs=cartesian(*onoffFlags)
82 return(allConfigs)
83
84# Extract the cmake for a specific compiler
85# and the flag configuration to use for this compiler.
86# This flags configuration will override the global one
87def analyzeToolchain(toolchain, globalConfig):
88 config=globalConfig
89 cmake=""
90 sim=True
91 if type(toolchain) is str:
92 cmake=toolchain
93 else:
94 for t in toolchain:
95 if type(t) is dict:
96 if "FLAGS" in t:
97 hasConfig=True
98 config = analyzeFlags(t["FLAGS"])
99 if "SIM" in t:
100 sim = t["SIM"]
101 if type(t) is str:
102 cmake=t
103 return(cmake,config,sim)
104
Christophe Favergeon512b1482020-02-07 11:25:11 +0100105
106
107def cartesian(*somelists):
108 r=[]
109 for element in itertools.product(*somelists):
110 r.append(list(element))
111 return(r)
112
Christophe Favergeon830283b2020-04-27 14:51:08 +0200113root = Path(os.getcwd()).parent.parent.parent
114
115
Christophe Favergeon512b1482020-02-07 11:25:11 +0100116testFailed = 0
Christophe Favergeon2942a332020-01-20 14:18:48 +0100117
118init()
119
Christophe Favergeon2942a332020-01-20 14:18:48 +0100120parser = argparse.ArgumentParser(description='Parse test description')
Christophe Favergeon512b1482020-02-07 11:25:11 +0100121parser.add_argument('-i', nargs='?',type = str, default="testrunConfig.yaml",help="Config file")
122parser.add_argument('-r', nargs='?',type = str, default=root, help="Root folder")
Christophe Favergeon830283b2020-04-27 14:51:08 +0200123parser.add_argument('-n', nargs='?',type = int, default=0, help="ID value when launching in parallel")
124parser.add_argument('-b', action='store_true', help="Benchmark mode")
125parser.add_argument('-f', nargs='?',type = str, default="desc.txt",help="Test description file")
126parser.add_argument('-p', nargs='?',type = str, default="FVP",help="Platform for running")
Christophe Favergeon2942a332020-01-20 14:18:48 +0100127
Christophe Favergeon1a668e02020-05-06 12:45:50 +0200128parser.add_argument('-db', nargs='?',type = str,help="Benchmark database")
129parser.add_argument('-regdb', nargs='?',type = str,help="Regression database")
130parser.add_argument('-sqlite', nargs='?',default="/usr/bin/sqlite3",type = str,help="Regression database")
131
132parser.add_argument('-debug', action='store_true', help="Debug mode")
Christophe Favergeonc7169b22020-07-08 08:17:52 +0200133parser.add_argument('-keep', action='store_true', help="Keep build folder")
Christophe Favergeon1a668e02020-05-06 12:45:50 +0200134
Christophe Favergeon2942a332020-01-20 14:18:48 +0100135args = parser.parse_args()
136
Christophe Favergeon1a668e02020-05-06 12:45:50 +0200137if args.debug:
138 setDebugMode()
139
Christophe Favergeonc7169b22020-07-08 08:17:52 +0200140if args.keep:
141 setKeepBuildFolder()
142
Christophe Favergeon1a668e02020-05-06 12:45:50 +0200143# Create missing database files
144# if the db arguments are specified
145if args.db is not None:
146 if not os.path.exists(args.db):
147 createDb(args.sqlite,args.db)
148
Christophe Favergeon8cb37302020-05-13 13:06:58 +0200149 conn = sqlite3.connect(args.db)
150 try:
151 currentID = getLastRunID(conn)
152 benchID = currentID + 1
153 addNewID(conn,benchID)
154 finally:
155 conn.close()
156
Christophe Favergeon1a668e02020-05-06 12:45:50 +0200157if args.regdb is not None:
158 if not os.path.exists(args.regdb):
159 createDb(args.sqlite,args.regdb)
160
Christophe Favergeon8cb37302020-05-13 13:06:58 +0200161 conn = sqlite3.connect(args.regdb)
162 try:
163 currentID = getLastRunID(conn)
164 regID = currentID + 1
165 addNewID(conn,regID)
166 finally:
167 conn.close()
168
Christophe Favergeon1a668e02020-05-06 12:45:50 +0200169
Christophe Favergeon512b1482020-02-07 11:25:11 +0100170with open(args.i,"r") as f:
171 config=yaml.safe_load(f)
172
173#print(config)
174
175#print(config["IMPLIEDFLAGS"])
176
Christophe Favergeon512b1482020-02-07 11:25:11 +0100177
Christophe Favergeon830283b2020-04-27 14:51:08 +0200178
179
180flags = config["FLAGS"]
181allConfigs = analyzeFlags(flags)
Christophe Favergeon512b1482020-02-07 11:25:11 +0100182
Christophe Favergeon1a668e02020-05-06 12:45:50 +0200183if isDebugMode():
Christophe Favergeon512b1482020-02-07 11:25:11 +0100184 allConfigs=[allConfigs[0]]
Christophe Favergeon512b1482020-02-07 11:25:11 +0100185
186failedBuild = {}
187# Test all builds
188
189folderCreated=False
190
191def logFailedBuild(root,f):
192 with open(os.path.join(fullTestFolder(root),"buildStatus_%d.txt" % args.n),"w") as status:
193 for build in f:
194 s = f[build]
195 if s == MAKEFAILED:
196 status.write("%s : Make failure\n" % build)
197 if s == TESTFAILED:
198 status.write("%s : Test failure\n" % build)
199 if s == FLOWFAILURE:
200 status.write("%s : Flow failure\n" % build)
201 if s == CALLFAILURE:
202 status.write("%s : Subprocess failure\n" % build)
Christophe Favergeon2942a332020-01-20 14:18:48 +0100203
Christophe Favergeon00e50db2020-01-21 07:10:26 +0100204
Christophe Favergeon830283b2020-04-27 14:51:08 +0200205def buildAndTest(compiler,theConfig,cmake,sim):
Christophe Favergeon512b1482020-02-07 11:25:11 +0100206 # Run all tests for AC6
207 try:
208 for core in config['CORES']:
209 configNb = 0
210 if compiler in config['CORES'][core]:
Christophe Favergeon830283b2020-04-27 14:51:08 +0200211 msg("Testing Core %s\n" % core)
212 for flagConfig in theConfig:
Christophe Favergeon512b1482020-02-07 11:25:11 +0100213 folderCreated = False
214 configNb = configNb + 1
215 buildStr = "build_%s_%s_%d" % (compiler,core,configNb)
216 toUnset = None
Christophe Favergeon64b748b2020-02-20 08:58:06 +0000217 toSet = None
218
Christophe Favergeon830283b2020-04-27 14:51:08 +0200219 if 'UNSET' in config:
220 if compiler in config['UNSET']:
221 if core in config['UNSET'][compiler]:
222 toUnset = config['UNSET'][compiler][core]
Christophe Favergeon64b748b2020-02-20 08:58:06 +0000223
Christophe Favergeon830283b2020-04-27 14:51:08 +0200224 if 'SET' in config:
225 if compiler in config['SET']:
226 if core in config['SET'][compiler]:
227 toSet = config['SET'][compiler][core]
Christophe Favergeon64b748b2020-02-20 08:58:06 +0000228
229 build = BuildConfig(toUnset,toSet,args.r,
Christophe Favergeon512b1482020-02-07 11:25:11 +0100230 buildStr,
231 config['COMPILERS'][core][compiler],
Christophe Favergeon830283b2020-04-27 14:51:08 +0200232 cmake,
Christophe Favergeon512b1482020-02-07 11:25:11 +0100233 config['CORES'][core][compiler],
234 config["CMAKE"]
235 )
236
237 flags = []
238 if core in config["IMPLIEDFLAGS"]:
239 flags += config["IMPLIEDFLAGS"][core]
240 flags += flagConfig
241
242 if compiler in config["IMPLIEDFLAGS"]:
243 flags += config["IMPLIEDFLAGS"][compiler]
244
245 build.createFolder()
246 # Run all tests for the build
247 testStatusForThisBuild = NOTESTFAILED
248 try:
249 # This is saving the flag configuration
250 build.createArchive(flags)
Christophe Favergeon830283b2020-04-27 14:51:08 +0200251 msg("Config " + str(flagConfig) + "\n")
252
Christophe Favergeon8cb37302020-05-13 13:06:58 +0200253 build.createCMake(core,flags,args.b,args.p)
Christophe Favergeon512b1482020-02-07 11:25:11 +0100254 for test in config["TESTS"]:
255 msg(test["testName"]+"\n")
256 testClass=test["testClass"]
257 test = build.getTest(testClass)
258 fvp = None
Christophe Favergeon830283b2020-04-27 14:51:08 +0200259 if 'FVP' in config:
260 if core in config['FVP']:
261 fvp = config['FVP'][core]
262 if 'SIM' in config:
263 if core in config['SIM']:
264 fvp = config['SIM'][core]
Christophe Favergeon8cb37302020-05-13 13:06:58 +0200265 newTestStatus = test.runAndProcess(compiler,fvp,sim,args.b,args.db,args.regdb,benchID,regID)
Christophe Favergeon512b1482020-02-07 11:25:11 +0100266 testStatusForThisBuild = updateTestStatus(testStatusForThisBuild,newTestStatus)
267 if testStatusForThisBuild != NOTESTFAILED:
268 failedBuild[buildStr] = testStatusForThisBuild
269 # Final script status
270 testFailed = 1
271 build.archiveResults()
272 finally:
273 build.cleanFolder()
274 else:
275 msg("No toolchain %s for core %s" % (compiler,core))
276
277 except TestFlowFailure as flow:
278 errorMsg("Error flow id %d\n" % flow.errorCode())
279 failedBuild[buildStr] = FLOWFAILURE
280 logFailedBuild(args.r,failedBuild)
281 sys.exit(1)
282 except CallFailure:
283 errorMsg("Call failure\n")
284 failedBuild[buildStr] = CALLFAILURE
285 logFailedBuild(args.r,failedBuild)
286 sys.exit(1)
Christophe Favergeon00e50db2020-01-21 07:10:26 +0100287
Christophe Favergeon512b1482020-02-07 11:25:11 +0100288############## Builds for all toolchains
Christophe Favergeon2942a332020-01-20 14:18:48 +0100289
Christophe Favergeon1a668e02020-05-06 12:45:50 +0200290if not isDebugMode():
Christophe Favergeon830283b2020-04-27 14:51:08 +0200291 preprocess(args.f)
Christophe Favergeon512b1482020-02-07 11:25:11 +0100292 generateAllCCode()
Christophe Favergeon1a668e02020-05-06 12:45:50 +0200293else:
294 msg("Debug Mode\n")
Christophe Favergeon2942a332020-01-20 14:18:48 +0100295
Christophe Favergeon512b1482020-02-07 11:25:11 +0100296for t in config["TOOLCHAINS"]:
Christophe Favergeon830283b2020-04-27 14:51:08 +0200297 cmake,localConfig,sim = analyzeToolchain(config["TOOLCHAINS"][t],allConfigs)
Christophe Favergeon72f1d9e2020-08-12 10:39:33 +0200298 msg("Testing toolchain %s\n" % t)
Christophe Favergeon830283b2020-04-27 14:51:08 +0200299 buildAndTest(t,localConfig,cmake,sim)
300
Christophe Favergeon2942a332020-01-20 14:18:48 +0100301
Christophe Favergeon512b1482020-02-07 11:25:11 +0100302logFailedBuild(args.r,failedBuild)
303sys.exit(testFailed)
304