diff options
| -rw-r--r-- | tests/OffscreenContext.mm | 1 | ||||
| -rw-r--r-- | tests/OffscreenContextGLX.cc | 5 | ||||
| -rw-r--r-- | tests/OffscreenContextWGL.cc | 1 | ||||
| -rw-r--r-- | tests/csgtestcore.cc | 9 | ||||
| -rwxr-xr-x | tests/test_pretty_print.py | 220 | 
5 files changed, 139 insertions, 97 deletions
diff --git a/tests/OffscreenContext.mm b/tests/OffscreenContext.mm index 7d95481..5a6a8ec 100644 --- a/tests/OffscreenContext.mm +++ b/tests/OffscreenContext.mm @@ -20,6 +20,7 @@ string offscreen_context_getinfo(OffscreenContext *ctx)  {    stringstream out;    out << "GL context creator: Cocoa / CGL\n" +      << "PNG generator: Core Foundation\n"        << "OS info: Mac OSX\n"        << "Machine: Apple(TM) Mac(TM)\n";    return out.str(); diff --git a/tests/OffscreenContextGLX.cc b/tests/OffscreenContextGLX.cc index ed9ef46..0817ce2 100644 --- a/tests/OffscreenContextGLX.cc +++ b/tests/OffscreenContextGLX.cc @@ -100,6 +100,7 @@ string offscreen_context_getinfo(OffscreenContext *ctx)    stringstream out;    out << "GL context creator: GLX\n" +      << "PNG generator: lodepng\n"        << "GLX version: " << major << "." << minor << "\n"        << get_os_info(); @@ -139,7 +140,8 @@ bool create_glx_dummy_window(OffscreenContext &ctx)      GLX_RED_SIZE, 1,      GLX_GREEN_SIZE, 1,      GLX_BLUE_SIZE, 1, -    GLX_DEPTH_SIZE, 1, +    GLX_ALPHA_SIZE, 1, // extra stuff for fbo-disbaled on-screen testing. +    GLX_DEPTH_SIZE, 24,      None    }; @@ -178,7 +180,6 @@ bool create_glx_dummy_window(OffscreenContext &ctx)    // Window xWin = XCreateSimpleWindow( dpy, DefaultRootWindow(dpy), 0,0,42,42, 0,0,0 ); -    XSync( dpy, false );    if ( XCreateWindow_failed ) {      XFree( visinfo ); diff --git a/tests/OffscreenContextWGL.cc b/tests/OffscreenContextWGL.cc index 4deaf2a..ba12a4f 100644 --- a/tests/OffscreenContextWGL.cc +++ b/tests/OffscreenContextWGL.cc @@ -82,6 +82,7 @@ string offscreen_context_getinfo(OffscreenContext *ctx)  {    stringstream out;    out << "GL context creator: WGL\n" +  out << "PNG generator: lodepng\n"        << get_windows_info();    return out.str();  } diff --git a/tests/csgtestcore.cc b/tests/csgtestcore.cc index 9511688..a3d5097 100644 --- a/tests/csgtestcore.cc +++ b/tests/csgtestcore.cc @@ -87,16 +87,11 @@ string info_dump(OffscreenView *glview)  #endif  	std::stringstream out; -	out << "OpenSCAD info dump:" -	    << "\nOpenSCAD Year/Month/Day: " << int(OPENSCAD_YEAR) << "." -	    << int(OPENSCAD_MONTH) << "." -#ifdef OPENSCAD_DAY -	    << int(OPENSCAD_DAY); -#endif  #define STRINGIFY(x) #x  #define TOSTRING(x) STRINGIFY(x) -	    << "\nOpenSCAD Version: " << TOSTRING(OPENSCAD_VERSION) +	out << "\nOpenSCAD Version: " << TOSTRING(OPENSCAD_VERSION)              << "\nCompiled by: " << compiler_info +	    << "\nCompile date: " << __DATE__  	    << "\nBoost version: " << BOOST_LIB_VERSION  	    << "\nEigen version: " << EIGEN_WORLD_VERSION << "."  	    << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION diff --git a/tests/test_pretty_print.py b/tests/test_pretty_print.py index 6bc3f54..c4b5c6c 100755 --- a/tests/test_pretty_print.py +++ b/tests/test_pretty_print.py @@ -1,26 +1,14 @@  #!/usr/bin/python  # -# this program reads the ctest logfiles from builddir/Testing/Temporary -# and generates two 'pretty printed' outputs in that directory: -# -# 1. mediawiki format, for uploading to a wiki. -#    automated uploading is available by following these steps: +# This program 'pretty prints' the ctest output, namely +# files from builddir/Testing/Temporary.  +# html & wiki output are produced +# wiki uploading is available by running   #  -#  download mwclient -#  python ctest_pretty_print.py --upload  -# -# 2. html format, for easy local viewing -# -# sysinfo.txt: -#   sysinfo.txt should have been created by ctest by the main test run.  -#   it is the output of opencsgtest --info  - +#  python test_pretty_print.py --upload  # todo -# 1. add sysinfo about ... git branch -# 2. consolidate image flip -# 3. uploading, can it be done in one file -# 4. consolidate pretty print +# ban opencsg<2.0 from opencsgtest  import string,sys,re,os,hashlib,subprocess @@ -79,10 +67,9 @@ def read_sysinfo(filename):  	tmp = tmp.split('/')[0]  	renderer = tmp -	hasher = hashlib.md5() -	hasher.update(data) -	hexhash = hasher.hexdigest()[-4:].upper() -	# make all letters for aesthetic reasons +	hexhash = hashlib.md5() +	hexhash.update(data) +	hexhash = hexhash.hexdigest()[-4:].upper()  	hash = ''  	for c in hexhash: hash += chr(ord(c)+97-48)  @@ -91,14 +78,16 @@ def read_sysinfo(filename):  	data += read_gitinfo() +	data += 'Image comparison: PerceptualDiff'  	return data, sysid  class Test: -	def __init__(self,fullname,time,passed,output,type,actualfile,expectedfile,scadfile): +	def __init__(self,fullname,time,passed,output,type,actualfile,expectedfile,scadfile,log):  		self.fullname,self.time,self.passed,self.output = \  			fullname, time, passed, output  		self.type, self.actualfile, self.expectedfile, self.scadfile = \  			type, actualfile, expectedfile, scadfile +		self.fulltestlog = log  	def __str__(self):  		x = 'fullname: ' + self.fullname @@ -109,6 +98,7 @@ class Test:  		x+= '\npassed: ' + str(self.passed)  		x+= '\nscadfile: ' + self.scadfile  		x+= '\noutput bytes: ' + str(len(self.output)) +		x+= '\ntestlog bytes: ' + str(len(self.fulltestlog))  		x+= '\n'  		return x @@ -123,7 +113,7 @@ def parsetest(teststring):  		'Command:.*?(testdata.*?)"' # scadfile   		]  	hits = map( lambda pattern: ezsearch(pattern,teststring), patterns ) -	test = Test(hits[0],hits[1],hits[2]=='Passed',hits[3],hits[4],hits[5],hits[6],hits[7]) +	test = Test(hits[0],hits[1],hits[2]=='Passed',hits[3],hits[4],hits[5],hits[6],hits[7],teststring)  	return test  def parselog(data): @@ -147,22 +137,24 @@ def wikify_filename(testname,filename,sysid):  def towiki(wiki_rootpath, startdate, tests, enddate, sysinfo, sysid, testlog): -	wiki_template = ''' -<h3>OpenSCAD test run</h3> +	wiki_template = """ +<h3>[[WIKI_ROOTPATH]] test run report</h3> -sysid: SYSID +'''Sysid''': SYSID -detailed system info:  +'''Result summary''': NUMPASSED / NUMTESTS tests passed ( PERCENTPASSED % ) <br> + +'''System info''':  <pre>  SYSINFO  </pre> -start time: STARTDATE  -end time  : ENDDATE +start time: STARTDATE <br> +end time  : ENDDATE <br> -Failed image tests +'''Failed image tests''' -{|border=1 cellspacing=0 cellpadding=1 align="center" +{| border=1 cellspacing=0 cellpadding=1  ! Testname !! expected output !! actual output  <REPEAT1>  |- @@ -170,81 +162,134 @@ Failed image tests  </REPEAT1>  |} -Failed text tests (see test log, below, for diff output) +'''Failed text tests''' -{|border=1 cellspacing=0 cellpadding=1 align="center" +{|border=1 cellspacing=0 cellpadding=1 +! Testname   <REPEAT2>  |-  | FTESTNAME  </REPEAT2>  |} -Passed tests +'''Test logs''' -{|border=1 cellspacing=0 cellpadding=1 align="center" -! Testname  -<REPEAT3> -|- -| PTESTNAME -</REPEAT3> -|} - -LastTest.log +(excerpted from Testing/Temporary/LastTest.Log)  <pre> -LASTTESTLOG +FAILED_TESTLOGS  </pre> -''' +""" +	numpassed = len(filter(lambda x: x.passed, tests)) +	percent = str(int(100.0*numpassed / len(tests)))  	manifest = {}  	s = wiki_template  	repeat1 = ezsearch('(<REPEAT1>.*?</REPEAT1>)',s)  	repeat2 = ezsearch('(<REPEAT2>.*?</REPEAT2>)',s) -	repeat3 = ezsearch('(<REPEAT3>.*?</REPEAT3>)',s) -	dic = { 'STARTDATE': startdate, 'ENDDATE': enddate, -		'SYSINFO': sysinfo, 'SYSID':sysid, 'LASTTESTLOG':testlog } +	dic = { 'STARTDATE': startdate, 'ENDDATE': enddate, 'WIKI_ROOTPATH': wiki_rootpath, +		'SYSINFO': sysinfo, 'SYSID':sysid, 'LASTTESTLOG':testlog,  +		'NUMTESTS':len(tests), 'NUMPASSED':numpassed, 'PERCENTPASSED':percent }  	for key in dic.keys(): -		s = re.sub(key,dic[key],s) +		s = re.sub(key,str(dic[key]),s) +	testlogs = ''  	for t in tests: -		print t.passed, t.type, t.fullname, t.expectedfile, t.actualfile -		manifest[t.actualfile] = wikify_filename(t.fullname,t.actualfile,sysid) -		manifest[t.expectedfile] = wikify_filename(t.fullname,t.expectedfile,sysid) -		if t.passed: -			newchunk = re.sub('PTESTNAME',t.fullname,repeat3) -			s = s.replace(repeat3, newchunk+repeat3) -		elif not t.passed and t.type=='txt': -			newchunk = re.sub('FTEST_OUTPUTFILE',t.fullname,repeat2) -			newchunk = re.sub('FTESTNAME',t.fullname,repeat2) -			s = s.replace(repeat2, newchunk+repeat2) -		elif not t.passed and t.type=='png': -			if t.actualfile:  -				actualfile_wiki = '[[File:'+manifest[t.actualfile]+'|thumb|250px]]' -			else: -				actualfile_wiki = 'No file generated. See test output for more info' -			newchunk = re.sub('FTESTNAME',t.fullname,repeat1) -			newchunk = newchunk.replace('ACTUALFILE_WIKI',actualfile_wiki) -			newchunk = newchunk.replace('EXPECTEDFILE',manifest[t.expectedfile]) -			s = s.replace(repeat1, newchunk+repeat1) +		# if t.passed: noop +		if not t.passed: +			testlogs += '\n\n'+t.fulltestlog +			if t.type=='txt': +				newchunk = re.sub('FTEST_OUTPUTFILE',t.fullname,repeat2) +				newchunk = re.sub('FTESTNAME',t.fullname,repeat2) +				s = s.replace(repeat2, newchunk+repeat2) +			elif t.type=='png': +				manifest[t.actualfile] = wikify_filename(t.fullname,t.actualfile,sysid) +				manifest[t.expectedfile] = wikify_filename(t.fullname,t.expectedfile,sysid) +				if t.actualfile:  +					actualfile_wiki = '[[File:'+manifest[t.actualfile]+'|thumb|250px]]' +				else: +					actualfile_wiki = 'No file generated.<br/>See log for details' +				newchunk = re.sub('FTESTNAME',t.fullname,repeat1) +				newchunk = newchunk.replace('ACTUALFILE_WIKI',actualfile_wiki) +				newchunk = newchunk.replace('EXPECTEDFILE',manifest[t.expectedfile]) +				s = s.replace(repeat1, newchunk+repeat1) +	s = s.replace('FAILED_TESTLOGS',testlogs)  	s = s.replace(repeat1,'')  	s = s.replace(repeat2,'') -	s = s.replace(repeat3,'')  	s = re.sub('<REPEAT.*?>\n','',s)  	s = re.sub('</REPEAT.*?>','',s)  	return manifest, s -def wikitohtml(data): -	# not pretty  -	data = data.replace('\n\n','\n<p>\n') -	data = re.sub('\{\|.*?\n','<table border=1>\n',data) -	data = re.sub('\n\! ','\n<tr>\n<td>',data) -	data = data.replace(' !! ','<td>') -	data = data.replace('|-','<tr>') -	data = re.sub('\n\| ','\n<td>',data) -	data = data.replace(' || ','<td>') -	data = data.replace('|}','\n</table>') -	data = re.sub('[[File:(.*?)|.*?]]','<img src="(\1)">',data) -	return data +def wikitohtml(wiki_rootpath, sysid, wikidata, manifest): +	head = '<html><head><title>'+wiki_rootpath+' test run for '+sysid +'</title></head><body>' +	revmanifest = dict((val,key) for key, val in manifest.iteritems()) +	x=re.sub('\{\|(.*?)\n','<table \\1>\n',wikidata) +	x=re.sub("'''(.*?)'''","<b>\\1</b>",x) +	filestrs=re.findall('\[\[File\:(.*?)\|.*?\]\]',x) +	for f in filestrs: +		newfile_html='<img src="'+revmanifest[f]+'" width=250/>' +		x=re.sub('\[\[File\:'+f+'\|.*?\]\]',newfile_html,x) +	dic = { '|}':'</table>', '|-':'<tr>', '||':'<td>', '|':'<td>',  +		'!!':'<th>', '!':'<tr><th>', '\n\n':'\n<p>\n'} #order matters +	for key in dic: x=x.replace(key,dic[key]) +	x=re.sub("\[\[(.*?)\]\]","\\1",x) +	return head + x + '</body></html>' + +def upload_dryrun(wikiurl,api_php_path,wikidata,manifest,wiki_rootpath,sysid,botname,botpass): +	print 'dry run. no files to be uploaded' +	print 'log in', wikiurl, api_php_path, botname, botpass +	print 'save ' + '*[['+wiki_rootpath+sysid+']]' + ' to page ' + wiki_rootpath +	print 'save ', len(wikidata), ' bytes to page ',wiki_rootpath+sysid +	for localfile in manifest.keys(): +		if localfile: +			localf=open(localfile) +			wikifile = manifest[localfile] +			print 'upload',localfile,wikifile + +def upload(wikiurl,api_php_path,wikidata,manifest,wiki_rootpath,sysid,botname,botpass,dryrun=True): +	if dryrun:  +		upload_dryrun(wikiurl,api_php_path,wikidata,manifest,wiki_rootpath,sysid,botname,botpass) +		return None +	try: +		import mwclient +	except: +		print 'please download mwclient and unpack here:', os.cwd() +	print 'open site',wikiurl +	if not api_php_path == '': +		site = mwclient.Site(wikiurl,api_php_path) +	else: +		site = mwclient.Site(wikiurl) +		 +	print 'bot login' +	site.login(botname,botpass) + +	print 'edit ',wiki_rootpath +	page = site.Pages[wiki_rootpath] +	text = page.edit() +	rootpage = wiki_rootpath + sysid +	if not '[['+rootpage+']]' in text: +		page.save(text +'\n*[['+rootpage+']]\n') + +	print 'upload wiki data to',rootpage +	page = site.Pages[rootpage] +	text = page.edit() +	page.save(wikidata) + +	print 'upload images' +	for localfile in sorted(manifest.keys()): +		if localfile: +			localf=open(localfile) +			wikifile = manifest[localfile] +			skip=False +			if 'expected.png' in wikifile.lower(): +				image = site.Images[wikifile] +				if image.exists:  +					print 'skipping ',wikifile, '(expected image, already on wiki)' +					skip=True +			if not skip: +				print wikifile,'...' +				site.upload(localf,wikifile,wiki_rootpath + ' test') +wikisite = 'cakebaby.referata.com'  wiki_rootpath = 'OpenSCAD'  builddir = os.getcwd()  logpath = os.path.join(builddir,'Testing','Temporary') @@ -256,11 +301,10 @@ def main():  	tests = sorted(tests, key = lambda t:t.passed)  	sysinfo, sysid = read_sysinfo('sysinfo.txt')  	manifest, wikidata = towiki(wiki_rootpath, startdate, tests, enddate, sysinfo, sysid, testlog) -	htmldata = wikitohtml(wikidata)  -	#save(wikidata, os.path.join(logpath,sysid+'.wiki')) -	#save(htmldata, os.path.join(logpath,sysid+'.html')) -	trysave(wikidata, sysid+'.wiki') -	trysave(htmldata, sysid+'.html') - +	trysave(wikidata, os.path.join(logpath,sysid+'.wiki')) +	htmldata = wikitohtml(wiki_rootpath, sysid, wikidata, manifest) +	trysave(htmldata, os.path.join(logpath,sysid+'.html')) +	if '--upload' in sys.argv: +		upload(wikisite,'',wikidata,manifest,wiki_rootpath,sysid,'openscadbot','tobdacsnepo',dryrun=False)  main()  | 
