diff options
-rw-r--r-- | tests/CMakeLists.txt | 49 | ||||
-rw-r--r-- | tests/OffscreenContext.cc | 11 | ||||
-rw-r--r-- | tests/csgtestcore.cc | 63 | ||||
-rwxr-xr-x | tests/ctest_pretty_print.py | 202 | ||||
-rwxr-xr-x | tests/test_cmdline_tool.py | 4 |
5 files changed, 294 insertions, 35 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 31420b3..393055b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -75,24 +75,20 @@ if (NOT $ENV{MACOSX_DEPLOY_DIR} STREQUAL "") set(BOOST_ROOT "$ENV{MACOSX_DEPLOY_DIR}") endif() -if(BOOST_ROOT) - #set(Boost_DEBUG TRUE) - set(Boost_NO_SYSTEM_PATHS TRUE) - set(Boost_ADDITIONAL_VERSIONS "1.47.0") - find_package( Boost 1.35.0 COMPONENTS thread program_options ) - if(Boost_FOUND) - message(STATUS "Boost includes found: " ${Boost_INCLUDE_DIRS}) - message(STATUS "Boost libraries found:") - foreach(boostlib ${Boost_LIBRARIES}) - message(STATUS " " ${boostlib}) - endforeach() - include_directories(${Boost_INCLUDE_DIRS}) - else() - message(STATUS "BOOST_ROOT:" ${BOOST_ROOT}) - message(FATAL_ERROR "BOOST_ROOT specified but no boost found") - endif() +#set(Boost_DEBUG TRUE) +set(Boost_NO_SYSTEM_PATHS TRUE) +set(Boost_ADDITIONAL_VERSIONS "1.47.0") +find_package( Boost 1.35.0 COMPONENTS thread program_options ) +if(Boost_FOUND) + message(STATUS "Boost includes found: " ${Boost_INCLUDE_DIRS}) + message(STATUS "Boost libraries found:") + foreach(boostlib ${Boost_LIBRARIES}) + message(STATUS " " ${boostlib}) + endforeach() + include_directories(${Boost_INCLUDE_DIRS}) else() - message(STATUS "BOOST_ROOT unset. Assuming it will be found automatically.") + message(STATUS "BOOST_ROOT: ${BOOST_ROOT}") + message(FATAL_ERROR "Boost not found.") endif() # Mac OS X @@ -260,13 +256,13 @@ set(COMMON_SOURCES # if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") message(STATUS "Offscreen OpenGL Context - using Apple CGL") - set(OFFSCREEN_CTX_SOURCE "OffscreenContext.mm") + 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") + set(OFFSCREEN_CTX_SOURCE "OffscreenContext.cc" CACHE TYPE STRING) elseif(WIN32) message(STATUS "Offscreen OpenGL Context - using Microsoft WGL") - set(OFFSCREEN_CTX_SOURCE "OffscreenContextWGL.cc") + set(OFFSCREEN_CTX_SOURCE "OffscreenContextWGL.cc" CACHE TYPE STRING) endif() set(OFFSCREEN_SOURCES @@ -362,6 +358,19 @@ endfunction() 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(CTEST_CUSTOM_FILE ${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake) +set(CTEST_CUSTOM_TXT "\n + ${INFOCMD}\n + set(CTEST_CUSTOM_POST_TEST ${PRETTYCMD})\n +") +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) + # Find all scad files file(GLOB MINIMAL_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/minimal/*.scad) file(GLOB FEATURES_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/features/*.scad) diff --git a/tests/OffscreenContext.cc b/tests/OffscreenContext.cc index 839eea9..e2b28e5 100644 --- a/tests/OffscreenContext.cc +++ b/tests/OffscreenContext.cc @@ -99,6 +99,7 @@ bool create_glx_dummy_window(OffscreenContext &ctx) GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, + GLX_DEPTH_SIZE, 1, None }; @@ -123,8 +124,8 @@ bool create_glx_dummy_window(OffscreenContext &ctx) Window root = DefaultRootWindow( dpy ); XSetWindowAttributes xwin_attr; - int width = 42; - int height = 42; + int width = ctx.width; + int height = ctx.height; xwin_attr.background_pixel = 0; xwin_attr.border_pixel = 0; xwin_attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone); @@ -147,7 +148,7 @@ bool create_glx_dummy_window(OffscreenContext &ctx) XSetErrorHandler( original_xlib_handler ); // Most programs would call XMapWindow here. But we don't, to keep the window hidden - // XMapWindow( dpy, xWin ); + XMapWindow( dpy, xWin ); GLXContext context = glXCreateNewContext( dpy, fbconfigs[0], GLX_RGBA_TYPE, NULL, True ); if ( context == NULL ) { @@ -229,11 +230,11 @@ OffscreenContext *create_offscreen_context(int w, int h) } glew_dump(); - ctx->fbo = fbo_new(); +/* ctx->fbo = fbo_new(); if (!fbo_init(ctx->fbo, w, h)) { cerr << "GL Framebuffer Object init failed; dumping GLEW info" << endl; return NULL; - } + }*/ return ctx; } diff --git a/tests/csgtestcore.cc b/tests/csgtestcore.cc index 034084c..a6e3747 100644 --- a/tests/csgtestcore.cc +++ b/tests/csgtestcore.cc @@ -25,8 +25,15 @@ #include <QDir> #include <QSet> #include <QTimer> + #include <sstream> +#include <vector> + +#include <boost/program_options.hpp> +namespace po = boost::program_options; +using std::string; +using std::vector; using std::cerr; using std::cout; @@ -41,9 +48,9 @@ public: CsgInfo(); CSGTerm *root_norm_term; // Normalized CSG products class CSGChain *root_chain; - std::vector<CSGTerm*> highlight_terms; + vector<CSGTerm*> highlight_terms; CSGChain *highlights_chain; - std::vector<CSGTerm*> background_terms; + vector<CSGTerm*> background_terms; CSGChain *background_chain; OffscreenView *glview; }; @@ -51,9 +58,9 @@ public: CsgInfo::CsgInfo() { root_norm_term = NULL; root_chain = NULL; - highlight_terms = std::vector<CSGTerm*>(); + highlight_terms = vector<CSGTerm*>(); highlights_chain = NULL; - background_terms = std::vector<CSGTerm*>(); + background_terms = vector<CSGTerm*>(); background_chain = NULL; glview = NULL; } @@ -67,15 +74,52 @@ AbstractNode *find_root_tag(AbstractNode *n) return NULL; } +string info_dump(OffscreenView *glview) +{ + std::stringstream out; + out << "test"; + return out.str(); +} + +po::variables_map parse_options(int argc, char *argv[]) +{ + po::options_description desc("Allowed options"); + desc.add_options() + ("info,i", "information on GLEW, OpenGL, OpenSCAD, and OS"); + + po::options_description hidden("Hidden options"); + hidden.add_options() + ("input-file", po::value< vector<string> >(), "input file"); + ("output-file", po::value< vector<string> >(), "ouput file"); + + po::positional_options_description p; + p.add("input-file", -1); + p.add("output-file", -1); + + po::options_description all_options; + all_options.add(desc).add(hidden); + + po::variables_map vm; + po::store(po::command_line_parser(argc, argv).options(all_options).positional(p).run(), vm); + + return vm; +} + int csgtestcore(int argc, char *argv[], test_type_e test_type) { - if (argc != 3) { - fprintf(stderr, "Usage: %s <file.scad> <output.png>\n", argv[0]); - exit(1); + bool sysinfo_dump = false; + const char *filename, *outfilename = NULL; + po::variables_map vm = parse_options(argc, argv); + if (vm.count("info")) sysinfo_dump = true; + if (vm.count("input-file") && vm.count("output-file")) { + filename = vm["input-file"].as< vector<string> >().begin()->c_str(); + outfilename = vm["output-file"].as< vector<string> >().begin()->c_str(); } - const char *filename = argv[1]; - const char *outfilename = argv[2]; + if (!filename || !outfilename || !sysinfo_dump) { + cerr << "Usage: " << argv[0] << " <file.scad> <output.png>\n"; + exit(1); + } Builtins::instance()->initialize(); @@ -194,6 +238,7 @@ int csgtestcore(int argc, char *argv[], test_type_e test_type) fprintf(stderr,"Can't create OpenGL OffscreenView. Code: %i. Exiting.\n", error); exit(1); } + if (sysinfo_dump) cout << info_dump(csgInfo.glview); BoundingBox bbox = csgInfo.root_chain->getBoundingBox(); Vector3d center = (bbox.min() + bbox.max()) / 2; diff --git a/tests/ctest_pretty_print.py b/tests/ctest_pretty_print.py new file mode 100755 index 0000000..a58b6bc --- /dev/null +++ b/tests/ctest_pretty_print.py @@ -0,0 +1,202 @@ +#!/usr/bin/python +import string,platform,sys,re,os + +wiki_basepath = 'OpenSCAD' +platform = 'ubuntu linux i686'.replace(' ','_') + '_abcd' +logfilename = 'LastTest.log.tmp' +builddir = 'build' +logpath = os.path.join(builddir,'Testing','Temporary',logfilename) +NO_END = False +if logfilename.endswith('.tmp'): NO_END = True + +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 = '' + return startdate, tests, enddate, 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, 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, platform + +def towiki(startdate, tests, enddate, platform): + def convert_path(fulltestname,platform,path): + # convert system path name (image file) to wiki path name + testprogram = fulltestname[0:fulltestname.find('_')] + testprogram = testprogram.replace('test','') + filename = os.path.basename(path) + filename = filename.replace('-actual','') + filename = filename.replace('-tests','') + filename = filename.replace('-expected','') + 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 + +runtime: STARTDATE to 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('PLATFORM',platform) + + for t in tests: + if t.passed: + tmp = str(repeat2) + tmp = tmp.replace('PTESTNAME',t.fullname) + x = x.replace(repeat2,tmp + repeat2) + else: + tmp = str(repeat1) + tmp = tmp.replace('FTESTNAME',t.fullname) + wiki_imgpath1 = convert_path(t.fullname,'expected',t.expectedfile) + tmp = tmp.replace('EXPECTEDIMG',wiki_imgpath1) + wiki_imgpath2 = convert_path(t.fullname,platform,t.outputfile) + tmp = tmp.replace('ACTUALIMG',wiki_imgpath2) + x = x.replace(repeat1,tmp + repeat1) + + x = x.replace(repeat1,'') + x = x.replace(repeat2,'') + return x + +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, platform = parse(data) + tests = testsort(tests) + out = towiki(startdate, tests, enddate, platform) + save(out, platform+'.wiki') + +main() + diff --git a/tests/test_cmdline_tool.py b/tests/test_cmdline_tool.py index 688026e..485a821 100755 --- a/tests/test_cmdline_tool.py +++ b/tests/test_cmdline_tool.py @@ -73,7 +73,9 @@ def compare_png(resultfilename): if not resultfilename: print >> sys.stderr, "Error: OpenSCAD did not generate an image" return False - print >> sys.stderr, 'Yee image compare: ', expectedfilename, ' ', resultfilename + 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 return True |