summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/CMakeLists.txt14
-rw-r--r--tests/OffscreenContext.mm9
-rw-r--r--tests/OffscreenContextGLX.cc (renamed from tests/OffscreenContext.cc)11
-rw-r--r--tests/OffscreenContextWGL.cc6
-rw-r--r--tests/OffscreenView.cc32
-rw-r--r--tests/csgtestcore.cc28
-rwxr-xr-xtests/ctest_pretty_print.py254
-rwxr-xr-xtests/test_cmdline_tool.py9
-rwxr-xr-xtests/test_pretty_print.py266
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 &center)
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()
+
contact: Jan Huwald // Impressum