diff options
-rw-r--r-- | tests/CMakeLists.txt | 14 | ||||
-rw-r--r-- | tests/OffscreenContext.mm | 9 | ||||
-rw-r--r-- | tests/OffscreenContextGLX.cc (renamed from tests/OffscreenContext.cc) | 11 | ||||
-rw-r--r-- | tests/OffscreenContextWGL.cc | 6 | ||||
-rw-r--r-- | tests/OffscreenView.cc | 32 | ||||
-rw-r--r-- | tests/csgtestcore.cc | 28 | ||||
-rwxr-xr-x | tests/ctest_pretty_print.py | 254 | ||||
-rwxr-xr-x | tests/test_cmdline_tool.py | 9 | ||||
-rwxr-xr-x | tests/test_pretty_print.py | 266 |
9 files changed, 330 insertions, 299 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 85c4f21..5315c01 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -265,7 +265,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(OFFSCREEN_CTX_SOURCE "OffscreenContext.mm" CACHE TYPE STRING) elseif(UNIX) message(STATUS "Offscreen OpenGL Context - using Unix GLX") - set(OFFSCREEN_CTX_SOURCE "OffscreenContext.cc" CACHE TYPE STRING) + set(OFFSCREEN_CTX_SOURCE "OffscreenContextGLX.cc" CACHE TYPE STRING) elseif(WIN32) message(STATUS "Offscreen OpenGL Context - using Microsoft WGL") set(OFFSCREEN_CTX_SOURCE "OffscreenContextWGL.cc" CACHE TYPE STRING) @@ -367,16 +367,20 @@ enable_testing() # set up custom pretty printing of results set(INFOCMD "execute_process(COMMAND ${CMAKE_CURRENT_BINARY_DIR}/opencsgtest --info OUTPUT_FILE sysinfo.txt)") -set(PRETTYCMD "\"${PYTHON_EXECUTABLE} ctest_pretty_print.py\"") +set(PRETTYCMD "\"${PYTHON_EXECUTABLE} test_pretty_print.py\"") set(CTEST_CUSTOM_FILE ${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake) set(CTEST_CUSTOM_TXT "\n message(\"running 'opencsgtest --info' to generate sysinfo.txt\")\n ${INFOCMD}\n - set(CTEST_CUSTOM_POST_TEST ${PRETTYCMD})\n + # set(CTEST_CUSTOM_POST_TEST ${PRETTYCMD})\n # doesn't work. log is written + # after all tests run. ") file(WRITE ${CTEST_CUSTOM_FILE} ${CTEST_CUSTOM_TXT}) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ctest_pretty_print.py - ${CMAKE_CURRENT_BINARY_DIR}/ctest_pretty_print.py COPYONLY) + +foreach(FILE test_pretty_print.py) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${FILE} + ${CMAKE_CURRENT_BINARY_DIR}/${FILE} COPYONLY) +endforeach() # Find all scad files file(GLOB MINIMAL_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/minimal/*.scad) diff --git a/tests/OffscreenContext.mm b/tests/OffscreenContext.mm index baa39e0..7d95481 100644 --- a/tests/OffscreenContext.mm +++ b/tests/OffscreenContext.mm @@ -18,10 +18,11 @@ struct OffscreenContext string offscreen_context_getinfo(OffscreenContext *ctx) { - sstream result; - result << "OS info: Mac OSX\n"; - result << "Machine: Apple(TM) Mac(TM)\n"; - return result.str(); + stringstream out; + out << "GL context creator: Cocoa / CGL\n" + << "OS info: Mac OSX\n" + << "Machine: Apple(TM) Mac(TM)\n"; + return out.str(); } OffscreenContext *create_offscreen_context(int w, int h) diff --git a/tests/OffscreenContext.cc b/tests/OffscreenContextGLX.cc index 994a74d..ed9ef46 100644 --- a/tests/OffscreenContext.cc +++ b/tests/OffscreenContextGLX.cc @@ -52,7 +52,7 @@ See Also using namespace std; struct OffscreenContext - { +{ GLXContext openGLContext; Display *xdisplay; Window xwindow; @@ -71,7 +71,7 @@ void offscreen_context_init(OffscreenContext &ctx, int width, int height) ctx.fbo = NULL; } -string get_unix_info() +string get_os_info() { struct utsname u; stringstream out; @@ -99,10 +99,9 @@ string offscreen_context_getinfo(OffscreenContext *ctx) glXQueryVersion(ctx->xdisplay, &major, &minor); stringstream out; - out << "GLX version: " << major << "." << minor << "\n"; - out << glew_dump(false); - - out << get_unix_info(); + out << "GL context creator: GLX\n" + << "GLX version: " << major << "." << minor << "\n" + << get_os_info(); return out.str(); } diff --git a/tests/OffscreenContextWGL.cc b/tests/OffscreenContextWGL.cc index 3756a82..4deaf2a 100644 --- a/tests/OffscreenContextWGL.cc +++ b/tests/OffscreenContextWGL.cc @@ -48,7 +48,7 @@ void offscreen_context_init(OffscreenContext &ctx, int width, int height) ctx.fbo = NULL; } -string get_windows_info() +string get_os_info() { OSVERSIONINFO osvi; @@ -81,8 +81,8 @@ string get_windows_info() string offscreen_context_getinfo(OffscreenContext *ctx) { stringstream out; - out << glew_dump(false); - out << get_windows_info(); + out << "GL context creator: WGL\n" + << get_windows_info(); return out.str(); } diff --git a/tests/OffscreenView.cc b/tests/OffscreenView.cc index 2a4a27e..9c8964c 100644 --- a/tests/OffscreenView.cc +++ b/tests/OffscreenView.cc @@ -1,11 +1,13 @@ #include <GL/glew.h> #include "OffscreenView.h" +#include "system-gl.h" #include <opencsg.h> #include "renderer.h" #include <math.h> #include <stdio.h> #include <string.h> #include <cstdlib> +#include <sstream> #define FAR_FAR_AWAY 100000.0 @@ -17,19 +19,6 @@ OffscreenView::OffscreenView(size_t width, size_t height) this->ctx = create_offscreen_context(width, height); if ( this->ctx == NULL ) throw -1; -#ifdef DEBUG - GLint rbits, gbits, bbits, abits, dbits, sbits; - glGetIntegerv(GL_RED_BITS, &rbits); - glGetIntegerv(GL_GREEN_BITS, &gbits); - glGetIntegerv(GL_BLUE_BITS, &bbits); - glGetIntegerv(GL_ALPHA_BITS, &abits); - glGetIntegerv(GL_DEPTH_BITS, &dbits); - glGetIntegerv(GL_STENCIL_BITS, &sbits); - - fprintf(stderr, "FBO: RGBA(%d%d%d%d), depth(%d), stencil(%d)\n", - rbits, gbits, bbits, abits, dbits, sbits); -#endif - initializeGL(); resizeGL(width, height); } @@ -251,7 +240,22 @@ bool OffscreenView::save(const char *filename) std::string OffscreenView::getInfo() { - return offscreen_context_getinfo(this->ctx); + std::stringstream out; + GLint rbits, gbits, bbits, abits, dbits, sbits; + glGetIntegerv(GL_RED_BITS, &rbits); + glGetIntegerv(GL_GREEN_BITS, &gbits); + glGetIntegerv(GL_BLUE_BITS, &bbits); + glGetIntegerv(GL_ALPHA_BITS, &abits); + glGetIntegerv(GL_DEPTH_BITS, &dbits); + glGetIntegerv(GL_STENCIL_BITS, &sbits); + + out << glew_dump(false) + << "FBO: RGBA(" << rbits << gbits << bbits << abits + << "), depth(" << dbits + << "), stencil(" << sbits << ")\n" + << offscreen_context_getinfo(this->ctx); + + return out.str(); } void OffscreenView::setCamera(const Eigen::Vector3d &pos, const Eigen::Vector3d ¢er) diff --git a/tests/csgtestcore.cc b/tests/csgtestcore.cc index 5866346..9511688 100644 --- a/tests/csgtestcore.cc +++ b/tests/csgtestcore.cc @@ -76,8 +76,8 @@ AbstractNode *find_root_tag(AbstractNode *n) string info_dump(OffscreenView *glview) { -#define STRINGIFY(x) #x -#define TOSTRING(x) STRINGIFY(x) + assert(glview); + #ifdef __GNUG__ #define compiler_info "GCC " << __VERSION__ #elif defined(_MSC_VER) @@ -85,18 +85,26 @@ string info_dump(OffscreenView *glview) #else #define compiler_info "unknown compiler" #endif - assert(glview); + std::stringstream out; out << "OpenSCAD info dump:" - << "\nOpenSCAD Year/Month/Day: " << int(OPENSCAD_YEAR) << "." - << int(OPENSCAD_MONTH) << "." + << "\nOpenSCAD Year/Month/Day: " << int(OPENSCAD_YEAR) << "." + << int(OPENSCAD_MONTH) << "." #ifdef OPENSCAD_DAY - << int(OPENSCAD_DAY) + << int(OPENSCAD_DAY); #endif - << "\nOpenSCAD Version: " << TOSTRING(OPENSCAD_VERSION) - << "\nCompiled with: " << compiler_info - << "\nGL Context info: \n" << glview->getInfo() - << "\n"; +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) + << "\nOpenSCAD Version: " << TOSTRING(OPENSCAD_VERSION) + << "\nCompiled by: " << compiler_info + << "\nBoost version: " << BOOST_LIB_VERSION + << "\nEigen version: " << EIGEN_WORLD_VERSION << "." + << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION + // << "\nCGAL version: " << CGAL_VERSION ??? + // << "\nOpenCSG" << ??? + << "\n" << glview->getInfo() + << "\n"; + return out.str(); } diff --git a/tests/ctest_pretty_print.py b/tests/ctest_pretty_print.py deleted file mode 100755 index 430f106..0000000 --- a/tests/ctest_pretty_print.py +++ /dev/null @@ -1,254 +0,0 @@ -#!/usr/bin/python -import string,platform,sys,re,os - -wiki_basepath = 'OpenSCAD' -logfilename = 'LastTest.log' -builddir = os.getcwd() -logpath = os.path.join(builddir,'Testing','Temporary',logfilename) -NO_END = False -if logfilename.endswith('.tmp'): NO_END = True - -def read_sysinfo(): - try: - f=open('sysinfo.txt') - except: - return '' - data=f.read() - machine_str, osplain_str, renderer_str = '','','' - machine = re.search('Machine:(.*?)\n',data) - osinfo = re.search('OS info:(.*?)\n',data) - renderer = re.search('GL Renderer:(.*?)\n',data) - if machine: machine_str = machine.group(1).strip().replace(' ','-').replace('/','-') - if osinfo: - osplain_str = osinfo.group(1).strip().split(' ')[0].strip().replace('/','-') - if 'windows' in osinfo.group(1).lower(): osplain_str = 'win' - if renderer: - tmp = renderer.group(1).strip().split(' ') - tmp = string.join(tmp[0:3],'-') - if '/' in tmp: tmp = tmp.split('/')[0] - renderer_str = tmp - platform = osplain_str + '_' + machine_str + '_' + renderer_str - platform = platform.lower() - return data, platform - -def readlog(): - try: - print 'reading',logpath - f = open(logpath) - except: - print 'couldnt open ',logpath - return None - - data = f.read() - return data - -class Test: - def __init__(self,fullname,time,passed,output,type,outputfile,expectedfile): - self.fullname,self.time,self.passed,self.output = \ - fullname, time, passed, output - self.type = type - self.outputfile = outputfile - self.expectedfile = expectedfile - - def __str__(self): - x = 'fullname: ' + self.fullname - x+= '\noutputfile: ' + self.outputfile - x+= '\nexpectedfile: ' + self.expectedfile - x+= '\ntesttime: ' + self.time - x+= '\ntesttype: ' + self.type - x+= '\npassfail: ' + self.passfail - x+= '\noutput: \n' + self.output - x+= '\n' - return x - -def gettest_strings(data): - chunks = data.split('----------------------------------------------------------') - print 'read',len(chunks), 'chunks' - if NO_END: - enddate = 'n/a (cancelled)' - chunks.pop() - else: - enddate = chunks.pop().replace('End testing: ','').strip() - chunks.reverse() - startdate = chunks.pop().replace('Start testing: ','').strip() - chunks.reverse() - tests=[] - chunksize = 3 - for i in range(0,len(chunks),chunksize): - testchunks = chunks[i:i+chunksize] - test = string.join(testchunks,'-----') - tests += [test] - #print '----------<<<<<<<<<<<<<<<<' - #print test - #print '----------<<<<<<<<<<<<<<<<' - test = '' - sysinfo, platform = read_sysinfo() - return startdate, tests, enddate, sysinfo, platform - -def parsetest(teststring): - s = teststring - def regex(pat,str): - x=re.search(pat,str,re.DOTALL|re.MULTILINE) - if x: - if len(x.groups())>0: - return x.group(1).strip() - return '' - testfullname = regex("Test:(.*?)\n",s) - testtime = regex("Test time =(.*?)\n",s).replace(' sec','') - passfail = regex("Test time.*?Test (Passed)",s) - command = regex("Command:(.*?)\n",s) - tmp = command.split(' "') - testtype = '' - try: - testtype = tmp[3].strip('"') - except: - print 'failed to parse log', teststring - goodimg = regex("expected image:(.*?)\n",s) - actualimg = regex("actual image:(.*?)\n",s) - if passfail=='Passed': passed = True - else: passed = False - output = regex("Output:(.*?)<end of output>",s).replace('-----','') - test = Test(testfullname, testtime, passed, output, testtype, actualimg, goodimg ) - return test - -def parse(data): - startdate, test_strs, enddate, sysinfo, platform = gettest_strings(data) - print 'found', len(test_strs),'test results' - tests = [] - for i in range(len(test_strs)): - test = parsetest(test_strs[i]) - tests += [test] - return startdate, tests, enddate, sysinfo, platform - -def towiki(startdate, tests, enddate, sysinfo, platform): - def convert_path(fulltestname,platform,path): - # convert system path name (image file) to wiki path name - testprogram = fulltestname[0:fulltestname.rfind('_')] - testprogram = testprogram.replace('test','') - filename = os.path.basename(path) - filename = filename.replace('-tests-actual.png','.png') - filename = filename.replace('-tests-expected.png','.png') - try: - platform = platform[0].upper() + platform[1:] - except: - platform = 'error' - newpath = testprogram + '_' + filename - # must use _ not / b/c of wikinet.org weird name mangling - newpath = wiki_basepath + '_' + platform + '_' + newpath - return newpath - - x=''' -<h3>OpenSCAD test run</h3> - -platform: PLATFORM - -detailed system info: -<pre> -SYSINFO -</pre> - -start time: STARTDATE -end time : ENDDATE - -Failed tests - -{|TABLESTYLE -! Testname !! expected output !! actual output -|- -| FTESTNAME || [[File:EXPECTEDIMG|thumb|250px]] || [[File:ACTUALIMG|thumb|250px]] -|} - -Passed tests - -{|TABLESTYLE -! Testname -|- -| PTESTNAME -|} - -''' - - repeat1=''' -|- -| FTESTNAME || [[File:EXPECTEDIMG|thumb|250px]] || [[File:ACTUALIMG|thumb|250px]] -''' - - repeat2=''' -|- -| PTESTNAME -''' - - x = x.replace('TABLESTYLE','border=1 cellspacing=0 cellpadding=1 align="center"') - x = x.replace('STARTDATE',startdate) - x = x.replace('ENDDATE',enddate) - x = x.replace('SYSINFO',sysinfo) - x = x.replace('PLATFORM',platform) - - for t in tests: - print t.type, t.fullname, t.expectedfile, t.outputfile - if t.passed: - tmp = str(repeat2) - tmp = tmp.replace('PTESTNAME',t.fullname) - x = x.replace(repeat2,tmp + repeat2) - elif not t.passed and t.type=='png': - tmp = str(repeat1) - tmp = tmp.replace('FTESTNAME',t.fullname) - - wiki_imgpath1 = convert_path(t.fullname,'expected',t.expectedfile) - if t.type!='png': wiki_imgpath1 = '' - if t.expectedfile=='': wiki_imgpath2 = '' - tmp = tmp.replace('EXPECTEDIMG',wiki_imgpath1) - - wiki_imgpath2 = convert_path(t.fullname,platform,t.outputfile) - if t.type!='png': wiki_imgpath2 = '' - if t.outputfile=='': wiki_imgpath2 = '' - tmp = tmp.replace('ACTUALIMG',wiki_imgpath2) - - x = x.replace(repeat1,tmp + repeat1) - - x = x.replace(repeat1,'') - x = x.replace(repeat2,'') - return x - -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 testsort(tests): - passed = [] - failed = [] - for t in tests: - if t.passed: passed+=[t] - else: failed +=[t] - return failed+passed - -def save(data,filename): - try: - f=open(filename,'w') - except: - print 'couldnt open ',filename, 'for writing' - return None - print 'writing',len(data),'bytes to',filename - f.write(data) - f.close() - -def main(): - data = readlog() - startdate, tests, enddate, sysinfo, platform = parse(data) - tests = testsort(tests) - wikidata = towiki(startdate, tests, enddate, sysinfo, platform) - htmldata = wikitohtml(wikidata) - save(wikidata, platform+'.wiki') - save(htmldata, platform+'.html') - -main() - diff --git a/tests/test_cmdline_tool.py b/tests/test_cmdline_tool.py index 485a821..3e9f45a 100755 --- a/tests/test_cmdline_tool.py +++ b/tests/test_cmdline_tool.py @@ -64,17 +64,20 @@ def compare_text(expected, actual): return get_normalized_text(expected) == get_normalized_text(actual) def compare_default(resultfilename): + print >> sys.stderr, 'diff text compare: ' + print >> sys.stderr, ' expected textfile: ', expectedfilename + print >> sys.stderr, ' actual textfile: ', resultfilename if not compare_text(expectedfilename, resultfilename): execute_and_redirect("diff", [expectedfilename, resultfilename], sys.stderr) return False return True def compare_png(resultfilename): + print >> sys.stderr, 'Yee image compare:' + print >> sys.stderr, ' expected image: ', expectedfilename if not resultfilename: - print >> sys.stderr, "Error: OpenSCAD did not generate an image" + print >> sys.stderr, "Error: OpenSCAD did not generate an image to test" return False - print >> sys.stderr, 'Yee image compare: ' - print >> sys.stderr, ' expected image: ', expectedfilename print >> sys.stderr, ' actual image: ', resultfilename if execute_and_redirect("./yee_compare", [expectedfilename, resultfilename, "-downsample", "2", "-threshold", "300"], sys.stderr) != 0: return False diff --git a/tests/test_pretty_print.py b/tests/test_pretty_print.py new file mode 100755 index 0000000..6bc3f54 --- /dev/null +++ b/tests/test_pretty_print.py @@ -0,0 +1,266 @@ +#!/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: +# +# 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 + + +# todo +# 1. add sysinfo about ... git branch +# 2. consolidate image flip +# 3. uploading, can it be done in one file +# 4. consolidate pretty print + +import string,sys,re,os,hashlib,subprocess + +def tryread(filename): + data = None + try: + print 'reading', filename + f = open(filename) + data = f.read() + f.close() + except: + print 'couldn\'t open ',filename + return data + +def trysave(data,filename): + try: + f=open(filename,'w') + print 'writing',len(data),'bytes to',filename + f.write(data) + f.close() + except: + print 'problem writing to',filename + return None + return True + +def ezsearch(pattern,str): + x = re.search(pattern,str,re.DOTALL|re.MULTILINE) + if x and len(x.groups())>0: return x.group(1).strip() + return '' + +def read_gitinfo(): + # won't work if run from outside of branch. + data = subprocess.Popen(['git','remote','-v'],stdout=subprocess.PIPE).stdout.read() + origin = ezsearch('^origin *?(.*?)\(fetch.*?$',data) + upstream = ezsearch('^upstream *?(.*?)\(fetch.*?$',data) + data = subprocess.Popen(['git','branch'],stdout=subprocess.PIPE).stdout.read() + branch = ezsearch('^\*(.*?)$',data) + out = 'Git branch: ' + branch + ' from origin ' + origin + '\n' + out += 'Git upstream: ' + upstream + '\n' + return out + +def read_sysinfo(filename): + data = tryread(filename) + if not data: return 'sysinfo: unknown' + + machine = ezsearch('Machine:(.*?)\n',data) + machine = machine.replace(' ','-').replace('/','-') + + osinfo = ezsearch('OS info:(.*?)\n',data) + osplain = osinfo.split(' ')[0].strip().replace('/','-') + if 'windows' in osinfo.lower(): osplain = 'win' + + renderer = ezsearch('GL Renderer:(.*?)\n',data) + tmp = renderer.split(' ') + tmp = string.join(tmp[0:3],'-') + tmp = tmp.split('/')[0] + renderer = tmp + + hasher = hashlib.md5() + hasher.update(data) + hexhash = hasher.hexdigest()[-4:].upper() + # make all letters for aesthetic reasons + hash = '' + for c in hexhash: hash += chr(ord(c)+97-48) + + sysid = osplain + '_' + machine + '_' + renderer + '_' + hash + sysid = sysid.lower() + + data += read_gitinfo() + + return data, sysid + +class Test: + def __init__(self,fullname,time,passed,output,type,actualfile,expectedfile,scadfile): + self.fullname,self.time,self.passed,self.output = \ + fullname, time, passed, output + self.type, self.actualfile, self.expectedfile, self.scadfile = \ + type, actualfile, expectedfile, scadfile + + def __str__(self): + x = 'fullname: ' + self.fullname + x+= '\nactualfile: ' + self.actualfile + x+= '\nexpectedfile: ' + self.expectedfile + x+= '\ntesttime: ' + self.time + x+= '\ntesttype: ' + self.type + x+= '\npassed: ' + str(self.passed) + x+= '\nscadfile: ' + self.scadfile + x+= '\noutput bytes: ' + str(len(self.output)) + x+= '\n' + return x + +def parsetest(teststring): + patterns = ["Test:(.*?)\n", # fullname + "Test time =(.*?) sec\n", + "Test time.*?Test (Passed)", + "Output:(.*?)<end of output>", + 'Command:.*?-s" "(.*?)"', # type + "actual .*?:(.*?)\n", + "expected .*?:(.*?)\n", + '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]) + return test + +def parselog(data): + startdate = ezsearch('Start testing: (.*?)\n',data) + enddate = ezsearch('End testing: (.*?)\n',data) + pattern = '([0-9]*/[0-9]* Testing:.*?time elapsed.*?\n)' + test_chunks = re.findall(pattern,data,re.S) + tests = map( parsetest, test_chunks ) + print 'found', len(tests),'test results' + return startdate, tests, enddate + +def wikify_filename(testname,filename,sysid): + # translate from local system to wiki style filename. + result = wiki_rootpath+'_'+testname+'_' + expected = ezsearch('(expected....$)',filename) + if expected!='': result += expected + actual = ezsearch(os.sep+'.*?-output.*?(actual.*)',filename) + if actual!='': + result += sysid+'_'+actual + return result.replace('/','_') + + +def towiki(wiki_rootpath, startdate, tests, enddate, sysinfo, sysid, testlog): + wiki_template = ''' +<h3>OpenSCAD test run</h3> + +sysid: SYSID + +detailed system info: +<pre> +SYSINFO +</pre> + +start time: STARTDATE +end time : ENDDATE + +Failed image tests + +{|border=1 cellspacing=0 cellpadding=1 align="center" +! Testname !! expected output !! actual output +<REPEAT1> +|- +| FTESTNAME || [[File:EXPECTEDFILE|thumb|250px]] || ACTUALFILE_WIKI +</REPEAT1> +|} + +Failed text tests (see test log, below, for diff output) + +{|border=1 cellspacing=0 cellpadding=1 align="center" +<REPEAT2> +|- +| FTESTNAME +</REPEAT2> +|} + +Passed tests + +{|border=1 cellspacing=0 cellpadding=1 align="center" +! Testname +<REPEAT3> +|- +| PTESTNAME +</REPEAT3> +|} + +LastTest.log + +<pre> +LASTTESTLOG +</pre> + +''' + 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 } + for key in dic.keys(): + s = re.sub(key,dic[key],s) + 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) + 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 + +wiki_rootpath = 'OpenSCAD' +builddir = os.getcwd() +logpath = os.path.join(builddir,'Testing','Temporary') +logfilename = os.path.join(logpath,'LastTest.log') + +def main(): + testlog = tryread(logfilename) + startdate, tests, enddate = parselog(testlog) + 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') + +main() + |