0029077: Tests - improve command testfile
[occt.git] / dox / dev_guides / tests / tests.md
1  Automated Testing System  {#occt_dev_guides__tests}
2 ======================================
3
4 @tableofcontents
5
6 @section testmanual_intro Introduction
7
8 This document provides OCCT developers and contributors with an overview and practical guidelines for work with OCCT automatic testing system.
9
10 Reading the Introduction should be sufficient for developers to use the test system to control non-regression of the modifications they implement in OCCT. Other sections provide a more in-depth description of the test system, required for modifying the tests and adding new test cases. 
11
12 @subsection testmanual_intro_basic Basic Information
13
14 OCCT automatic testing system is organized around @ref occt_user_guides__test_harness "DRAW Test Harness", a console application based on Tcl (a scripting language) interpreter extended by OCCT-related commands.
15
16 Standard OCCT tests are included with OCCT sources and are located in subdirectory *tests* of the OCCT root folder. Other test folders can be included in the test system, e.g. for testing applications based on OCCT.
17
18 The tests are organized in three levels:
19
20   * Group: a group of related test grids, usually testing a particular OCCT functionality (e.g. blend);
21   * Grid: a set of test cases within a group, usually aimed at testing some particular aspect or mode of execution of the relevant functionality (e.g. buildevol);
22   * Test case: a script implementing an individual test (e.g. K4).
23   
24 See @ref testmanual_5_1 "Test Groups" chapter for the current list of available test groups and grids.
25
26 @note Many tests involve data files (typically CAD models) which are located separately and (except a few) are not included with OCCT code. 
27 These tests will be skipped if data files are not available.
28
29 @subsection testmanual_1_2 Intended Use of Automatic Tests
30
31 Each modification made in OCCT code must be checked for non-regression 
32 by running the whole set of tests. The developer who makes the modification 
33 is responsible for running and ensuring non-regression for the tests available to him.
34
35 Note that many tests are based on data files that are confidential and thus available only at OPEN CASCADE. 
36 The official certification testing of each change before its integration to master branch of official OCCT Git repository (and finally to the official release) is performed by OPEN CASCADE to ensure non-regression on all existing test cases and supported platforms.
37
38 Each new non-trivial modification (improvement, bug fix, new feature) in OCCT should be accompanied by a relevant test case suitable for verifying that modification. This test case is to be added by the developer who provides the modification.
39
40 If a modification affects the result of an existing test case, either the modification should be corrected (if it causes regression) or the affected test cases should be updated to account for the modification. 
41
42 The modifications made in the OCCT code and related test scripts should be included in the same integration to the master branch.
43
44 @subsection testmanual_1_3 Quick Start
45
46 @subsubsection testmanual_1_3_1 Setup
47
48 Before running tests, make sure to define environment variable *CSF_TestDataPath* pointing to the directory containing test data files. 
49
50 For this it is recommended to add a file *DrawAppliInit* in the directory which is current at the moment of starting DRAWEXE (normally it is OCCT root directory, <i>$CASROOT </i>). This file is evaluated automatically at the DRAW start. 
51
52 Example (Windows)
53
54 ~~~~~{.tcl}
55 set env(CSF_TestDataPath) $env(CSF_TestDataPath)\;d:/occt/test-data
56 ~~~~~
57
58 Note that variable *CSF_TestDataPath* is set to default value at DRAW start, pointing at the folder <i>$CASROOT/data</i>. 
59 In this example, subdirectory <i>d:/occt/test-data</i> is added to this path. Similar code could be used on Linux and Mac OS X except that on non-Windows platforms colon ":" should be used as path separator instead of semicolon ";".
60
61 All tests are run from DRAW command prompt (run *draw.bat* or *draw.sh* to start it).
62
63 @subsubsection testmanual_1_3_2 Running Tests
64
65 To run all tests, type command *testgrid* 
66
67 Example:
68
69 ~~~~~
70 Draw[]> testgrid
71 ~~~~~
72
73 To run only a subset of test cases, give masks for group, grid, and test case names to be executed.
74 Each argument is a list of file masks separated with commas or spaces; by default "*" is assumed.
75
76 Example:
77
78 ~~~~~
79 Draw[]> testgrid bugs caf,moddata*,xde
80 ~~~~~
81
82 As the tests progress, the result of each test case is reported. 
83 At the end of the log a summary of test cases is output, 
84 including the list of detected regressions and improvements, if any. 
85
86
87 Example:
88
89 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.tcl}
90     Tests summary
91
92     CASE 3rdparty export A1: OK 
93     ...
94     CASE pipe standard B1: BAD (known problem)
95     CASE pipe standard C1: OK
96     No regressions 
97     Total cases: 208 BAD, 31 SKIPPED, 3 IMPROVEMENT, 1791 OK
98     Elapsed time: 1 Hours 14 Minutes 33.7384512019 Seconds
99     Detailed logs are saved in D:/occt/results_2012-06-04T0919
100 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
101
102 The tests are considered as non-regressive if only OK, BAD (i.e. known problem), and SKIPPED (i.e. not executed, typically because of lack of a data file) statuses are reported. See @ref testmanual_details_results "Interpretation of test results" for details.
103
104 The results and detailed logs of the tests are saved by default to a new subdirectory of the subdirectory *results* in the current folder, whose name is generated automatically using the current date and time, prefixed by Git branch name (if Git is available and current sources are managed by Git).
105 If necessary, a non-default output directory can be specified using option <i> -outdir</i> followed by a path to the directory. This directory should be new or empty; use option <i>-overwrite</i> to allow writing results in the existing non-empty directory. 
106
107 Example:
108 ~~~~~
109 Draw[]> testgrid -outdir d:/occt/last_results -overwrite
110 ~~~~~
111 In the output directory, a cumulative HTML report <i>summary.html</i> provides links to reports on each test case. An additional report in JUnit-style XML format can be output for use in Jenkins or other continuous integration system.
112
113 To re-run the test cases, which were detected as regressions on the previous run, option <i>-regress dirname</i> should be used.
114 <i>dirname</i> is a path to the directory containing the results of the previous run. Only the test cases with *FAILED* and *IMPROVEMENT* statuses will be tested.
115
116 Example:
117 ~~~~~
118 Draw[]> testgrid -regress d:/occt/last_results
119 ~~~~~
120
121 Type <i>help testgrid</i> in DRAW prompt to get help on options supported by *testgrid* command:
122
123 ~~~~~
124 Draw[3]> help testgrid
125 testgrid: Run all tests, or specified group, or one grid
126     Use: testgrid [groupmask [gridmask [casemask]]] [options...]
127     Allowed options are:
128     -parallel N: run N parallel processes (default is number of CPUs, 0 to disable)
129     -refresh N: save summary logs every N seconds (default 60, minimal 1, 0 to disable)
130     -outdir dirname: set log directory (should be empty or non-existing)
131     -overwrite: force writing logs in existing non-empty directory
132     -xml filename: write XML report for Jenkins (in JUnit-like format)
133     -beep: play sound signal at the end of the tests
134     -regress dirname: re-run only a set of tests that have been detected as regressions on the previous run.
135                       Here "dirname" is a path to the directory containing the results of the previous run.
136     Groups, grids, and test cases to be executed can be specified by the list of file 
137     masks separated by spaces or commas; default is all (*).
138 ~~~~~
139
140 @subsubsection testmanual_1_3_3 Running a Single Test
141
142 To run a single test, type command *test* followed by names of group, grid, and test case. 
143
144 Example:
145
146 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.tcl}
147     Draw[1]> test blend simple A1
148     CASE blend simple A1: OK
149     Draw[2]>
150 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
151
152 Note that normally an intermediate output of the script is not shown. The detailed log of the test can be obtained after the test execution by running command <i>"dlog get"</i>. 
153
154 To see intermediate commands and their output during the test execution, add one more argument 
155 <i>"echo"</i> at the end of the command line. Note that with this option the log is not collected and summary is not produced.
156
157 Type <i>help test</i> in DRAW prompt to get help on options supported by *test* command:
158
159 ~~~~~
160 Draw[3]> help test
161 test: Run specified test case
162  Use: test group grid casename [options...]
163  Allowed options are:
164  -echo: all commands and results are echoed immediately,
165         but log is not saved and summary is not produced
166         It is also possible to use "1" instead of "-echo"
167         If echo is OFF, log is stored in memory and only summary
168         is output (the log can be obtained with command "dlog get")
169  -outfile filename: set log file (should be non-existing),
170         it is possible to save log file in text file or
171         in html file(with snapshot), for that "filename"
172         should have ".html" extension
173  -overwrite: force writing log in existing file
174  -beep: play sound signal at the end of the test
175  -errors: show all lines from the log report that are recognized as errors
176         This key will be ignored if the "-echo" key is already set.
177 ~~~~~
178
179 @subsubsection testmanual_intro_quick_create Creating a New Test
180
181 The detailed rules of creation of new tests are given in @ref testmanual_3 "Creation and modification of tests" chapter. The following short description covers the most typical situations:
182
183 Use prefix <i>bug</i> followed by Mantis issue ID and, if necessary, additional suffixes, for naming the test script, data files, and DRAW commands specific for this test case.
184
185 1.      If the test requires C++ code, add it as new DRAW command(s) in one of files in *QABugs* package. 
186 2.      Add script(s) for the test case in the subfolder corresponding to the relevant OCCT module of the group *bugs* <i>($CASROOT/tests/bugs)</i>. See @ref testmanual_5_2 "the correspondence map".
187 3.      In the test script:
188         *       Load all necessary DRAW modules by command *pload*.
189         *       Use command *locate_data_file* to get a path to data files used by test script. (Make sure to have this command not inside catch statement if it is used.)
190         *       Use DRAW commands to reproduce the tested situation.
191         *       Make sure that in case of failure the test produces a message containing word "Error" or other recognized by the test system as error (add new error patterns in file parse.rules if necessary).
192         *       If the test case reports error due to an existing problem and the fix is not available, add @ref testmanual_3_6 "TODO" statement for each error to mark it as a known problem. The TODO statements must be specific so as to match the actually generated messages but not all similar errors.
193         *       To check expected output which should be obtained as the test result, add @ref testmanual_3_7 "REQUIRED" statement for each line of output to mark it as required.
194         *       If the test case produces error messages (contained in parse.rules), which are expected in that test and should not be considered as its failure (e.g. test for *checkshape* command), add REQUIRED statement for each error to mark it as required output.
195 4.      To check whether the data files needed for the test are already present in the database, use DRAW command *testfile* (see below).
196     If the data file is already present, use it for new test instead of adding a duplicate.
197     If the data file(s) are not yet present in the test database, put them to some folder and add it to the environment variable *CSF_TestDataPath* to be found by the test system.
198     Information on where the data files can be accessed by OCC team for putting to official database should be provided in comment to Mantis issue, clearly indicating how names of the files used by the test script match the actual names of the files.
199     The simplest way is to attach the data files to the Mantis issue, with the same names as used by the test script.
200 5.      Check that the test case runs as expected (test for fix: OK with the fix, FAILED without the fix; test for existing problem: BAD), and integrate it to the Git branch created for the issue.
201
202 Example:
203
204 * Added files:
205
206 ~~~~~
207 git status -short
208 A tests/bugs/heal/data/bug210_a.brep
209 A tests/bugs/heal/data/bug210_b.brep
210 A tests/bugs/heal/bug210_1
211 A tests/bugs/heal/bug210_2
212 ~~~~~
213
214 * Test script
215
216 ~~~~~{.tcl}
217 puts "OCC210 (case 1): Improve FixShape for touching wires"
218
219 restore [locate_data_file bug210_a.brep] a 
220
221 fixshape result a 0.01 0.01
222 checkshape result
223 ~~~~~
224
225 DRAW command testfile should be used to check the data files being used by the test for possible duplication of content or names.
226 The command accepts list of paths to files being checked as single argument, and will give conclusion on each of the files, for instance:
227
228 ~~~~~
229 Draw[1]> testfile [glob /my/data/path/bug12345*]
230 Collecting info on test data files repository...
231 Checking new file(s)...
232
233 * /my/data/path/bug12345.brep: duplicate
234   already present under name bug28773_1.brep
235   --> //server/occt_tests_data/public/brep/bug28773_1.brep
236
237 * /my/data/path/cadso.brep: new file
238   Warning: DOS encoding detected, consider converting to
239            UNIX unless DOS line ends are needed for the test
240   Warning: shape contains triangulation (946 triangles),
241            consider removing them unless they are needed for the test!
242   BREP size=201 KiB, nbfaces=33, nbedges=94 -> private
243
244 * /my/data/path/case_8_wire3.brep: already present
245   --> //server/occt_tests_data/public/brep/case_8_wire3.brep
246
247 * /my/data/path/case_8_wire4.brep: error
248   name is already used by existing file
249   --> //server/occt_tests_data/public/brep/case_8_wire4.brep
250 ~~~~~
251
252 @section testmanual_2 Organization of Test Scripts
253
254 @subsection testmanual_2_1 General Layout
255
256 Standard OCCT tests are located in subdirectory tests of the OCCT root folder ($CASROOT).
257
258 Additional test folders can be added to the test system by defining environment variable *CSF_TestScriptsPath*. This should be list of paths separated by semicolons (*;*) on Windows 
259 or colons (*:*) on Linux or Mac. Upon DRAW launch, path to *tests* subfolder of OCCT is added at the end of this variable automatically. 
260
261 Each test folder is expected to contain:
262   * Optional file *parse.rules* defining patterns for interpretation of test results, common for all groups in this folder
263   * One or several test group directories. 
264
265 Each group directory contains:
266
267   * File *grids.list* that identifies this test group and defines list of test grids in it.
268   * Test grids (sub-directories), each containing set of scripts for test cases, and optional files *cases.list*, *parse.rules*, *begin* and *end*.
269   * Optional sub-directory data
270
271 By convention, names of test groups, grids, and cases should contain no spaces and be lower-case. 
272 The names *begin, end, data, parse.rules, grids.list* and *cases.list* are reserved. 
273
274 General layout of test scripts is shown in Figure 1.
275
276 @figure{/dev_guides/tests/images/tests_image001.png,"Layout of tests folder",400}
277
278
279 @subsection testmanual_2_2 Test Groups
280
281 @subsubsection testmanual_2_2_1 Group Names
282
283 The names of directories of test groups containing systematic test grids correspond to the functionality tested by each group.
284
285 Example:
286
287 ~~~~~
288   caf
289   mesh
290   offset
291 ~~~~~
292
293 Test group *bugs* is used to collect the tests coming from bug reports. Group *demo* collects tests of the test system, DRAW, samples, etc.
294
295 @subsubsection testmanual_2_2_2 File "grids.list" 
296
297 This test group contains file *grids.list*, which defines an ordered list of grids in this group in the following format:
298
299 ~~~~~~~~~~~~~~~~~
300 001 gridname1
301 002 gridname2
302 ...
303 NNN gridnameN
304 ~~~~~~~~~~~~~~~~~
305
306 Example:
307
308 ~~~~~~~~~~~~~~~~~
309     001 basic
310     002 advanced
311 ~~~~~~~~~~~~~~~~~
312
313 @subsubsection testmanual_2_2_3 File "begin"
314
315 This file is a Tcl script. It is executed before every test in the current group. 
316 Usually it loads necessary Draw commands, sets common parameters and defines 
317 additional Tcl functions used in test scripts.
318
319 Example:
320
321 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.tcl}
322     pload TOPTEST ;# load topological command
323     set cpulimit 300 ;# set maximum time allowed for script execution
324 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
325
326 @subsubsection testmanual_2_2_4 File "end"
327
328 This file is a TCL script. It is executed after every test in the current group. Usually it checks the results of script work, makes a snap-shot of the viewer and writes *TEST COMPLETED* to the output.
329
330 Note: *TEST COMPLETED* string should be present in the output to indicate that the test is finished without crash. 
331
332 See @ref testmanual_3 "Creation and modification of tests" chapter for more information.
333
334 Example:
335 ~~~~~
336     if { [isdraw result] } {
337         checkshape result
338     } else {
339         puts "Error: The result shape can not be built"
340     }
341     puts "TEST COMPLETED"
342 ~~~~~
343
344 @subsubsection testmanual_2_2_5 File "parse.rules"
345
346 The test group may contain *parse.rules* file. This file defines patterns used for analysis of the test execution log and deciding the status of the test run. 
347
348 Each line in the file should specify a status (single word), followed by a regular expression delimited by slashes (*/*) that will be matched against lines in the test output log to check if it corresponds to this status.
349
350 The regular expressions should follow <a href="http://www.tcl.tk/man/tcl/TclCmd/re_syntax.htm">Tcl syntax</a>, with a special exception that "\b" is considered as word limit (Perl-style), in addition to "\y" used in Tcl.
351
352 The rest of the line can contain a comment message, which will be added to the test report when this status is detected.
353
354 Example:
355
356 ~~~~~
357     FAILED /\b[Ee]xception\b/ exception
358     FAILED /\bError\b/ error
359     SKIPPED /Cannot open file for reading/ data file is missing
360     SKIPPED /Could not read file .*, abandon/ data file is missing
361 ~~~~~
362
363 Lines starting with a *#* character and blank lines are ignored to allow comments and spacing.
364
365 See @ref testmanual_details_results "Interpretation of test results" chapter for details.
366
367 If a line matches several rules, the first one applies. Rules defined in the grid are checked first, then rules in the group, then rules in the test root directory. This allows defining some rules on the grid level with status *IGNORE* to ignore messages that would otherwise be treated as errors due to the group level rules.
368
369 Example:
370
371 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.tcl}
372     FAILED /\\bFaulty\\b/ bad shape
373     IGNORE /^Error [23]d = [\d.-]+/ debug output of blend command
374     IGNORE /^Tcl Exception: tolerance ang : [\d.-]+/ blend failure
375 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
376
377 @subsubsection testmanual_2_2_6  Directory "data"
378 The test group may contain subdirectory *data*, where test scripts shared by different test grids can be put. See also @ref testmanual_2_3_5 "Directory data".
379
380 @subsection testmanual_2_3 Test Grids
381
382 @subsubsection testmanual_2_3_1 Grid Names
383
384 The folder of a test group  can have several sub-directories (Grid 1… Grid N) defining test grids. 
385 Each directory contains a set of related test cases. The name of a directory should correspond to its contents.
386
387 Example:
388
389 ~~~~~
390 caf
391    basic
392    bugs
393    presentation
394 ~~~~~
395
396 Here *caf* is the name of the test group and *basic*, *bugs*, *presentation*, etc. are the names of grids.
397
398 @subsubsection testmanual_2_3_2 File "begin"
399
400 This file is a TCL script executed before every test in the current grid. 
401
402 Usually it sets variables specific for the current grid.
403
404 Example:
405
406 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.tcl}
407     set command bopfuse ;# command tested in this grid
408 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
409
410 @subsubsection testmanual_2_3_3 File "end"
411
412 This file is a TCL script executed after every test in current grid. 
413
414 Usually it executes a specific sequence of commands common for all tests in the grid.
415
416 Example:
417
418 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.tcl}
419     vdump $imagedir/${casename}.png ;# makes a snap-shot of AIS viewer
420 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
421
422 @subsubsection testmanual_2_3_4 File "cases.list"
423
424 The grid directory can contain an optional file cases.list 
425 defining an alternative location of the test cases. 
426 This file should contain a single line defining the relative path to the collection of test cases.
427
428 Example:
429
430 ~~~~~
431 ../data/simple
432 ~~~~~
433
434 This option is used for creation of several grids of tests with the same data files and operations but performed with differing parameters. The common scripts are usually located place in the common 
435 subdirectory of the test group, <i>data/simple</i> for example.
436
437 If file *cases.list*  exists, the grid directory should not contain any test cases. 
438 The specific parameters and pre- and post-processing commands 
439 for test execution in this grid should be defined in the files *begin* and *end*.
440
441
442 @subsubsection testmanual_2_3_5  Directory "data"
443
444 The test grid may contain subdirectory *data*, containing data files used in tests (BREP, IGES, STEP, etc.) of this grid.
445
446 @subsection testmanual_2_4 Test Cases
447
448 The test case is a TCL script, which performs some operations using DRAW commands 
449 and produces meaningful messages that can be used to check the validity of the result.
450
451 Example:
452
453 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.tcl}
454     pcylinder c1 10 20 ;# create first cylinder
455     pcylinder c2 5 20 ;# create second cylinder
456     ttranslate c2 5 0 10 ;# translate second cylinder to x,y,z
457     bsection result c1 c2 ;# create a section of two cylinders
458     checksection result ;# will output error message if result is bad
459 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
460
461 The test case can have any name (except for the reserved names *begin, end, data, cases.list* and  *parse.rules*). 
462 For systematic grids it is usually a capital English letter followed by a number.
463
464 Example:
465
466 ~~~~~
467     A1
468     A2
469     B1
470     B2
471 ~~~~~
472
473 Such naming facilitates compact representation of tests execution results in tabular format within HTML reports.
474
475
476 @section testmanual_3 Creation And Modification Of Tests
477
478 This section describes how to add new tests and update existing ones.
479
480 @subsection testmanual_3_1 Choosing Group, Grid, and Test Case Name
481
482 The new tests are usually added in the frame of processing issues in OCCT Mantis tracker. 
483 Such tests in general should be added to group bugs, in the grid 
484 corresponding to the affected OCCT functionality. See @ref testmanual_5_2 "Mapping of OCCT functionality to grid names in group bugs".
485
486 New grids can be added as necessary to contain tests for the functionality not yet covered by existing test grids. 
487 The test case name in the bugs group should be prefixed by the ID of the corresponding issue in Mantis (without leading zeroes) with prefix *bug*. It is recommended to add a suffix providing a hint on the tested situation. If more than one test is added for a bug, they should be distinguished by suffixes; either meaningful or just ordinal numbers.
488
489 Example:
490
491 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.tcl}
492     bug12345_coaxial
493     bug12345_orthogonal_1
494     bug12345_orthogonal_2
495 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
496
497 If the new test corresponds to a functionality already covered by the existing systematic test grid (e.g. group *mesh* for *BRepMesh* issues), this test can be added (or moved later by OCC team) to that grid. 
498
499 @subsection testmanual_3_2 Adding Data Files Required for a Test
500
501 It is advisable to make self-contained test scripts whenever possible, so as they could be used in the  environments where data files are not available. For that simple geometric objects and shapes can be created using DRAW commands in the test script itself.
502
503 If the test requires a data file, it should be put to the directory listed in environment variable *CSF_TestDataPath*.
504 Alternatively, it can be put to subdirectory *data* of the test grid. 
505 It is recommended to prefix the data file with the corresponding issue id prefixed by *bug*, e.g. *bug12345_face1.brep*, to avoid possible conflicts with names of existing data files. 
506
507 Note that when the test is integrated to the master branch, OCC team will move the data file to the data files repository, to keep OCCT sources repository clean from data files.
508
509 When you prepare a test script, try to minimize the size of involved data model. For instance, if the problem detected on a big shape can be reproduced on a single face extracted from that shape, use only that face in the test.
510
511
512 @subsection testmanual_3_3 Adding new DRAW commands
513
514 If the test cannot be implemented using available DRAW commands, consider the following possibilities:
515 * If the existing DRAW command can be extended to enable possibility required for a test in a natural way (e.g. by adding an option to activate a specific mode of the algorithm), this way is recommended. This change should be appropriately documented in a relevant Mantis issue.
516 * If the new command is needed to access OCCT functionality not exposed to DRAW previously, and this command can be potentially reused (for other tests), it should be added to the package where similar commands are implemented (use *getsource* DRAW command to get the package name). The name and arguments of the new command should be chosen to keep similarity with the existing commands. This change should be documented in a relevant Mantis issue.
517 * Otherwise the new command implementing the actions needed for this particular test should be added in *QABugs* package. The command name should be formed by the Mantis issue ID prefixed by *bug*, e.g. *bug12345*.
518
519 Note that a DRAW command is expected to return 0 in case of a normal completion, and 1 (Tcl exception) if it is incorrectly used (e.g. a wrong number of input arguments). Thus if the new command needs to report a test error, this should be done by outputting an appropriate error message rather than by returning a non-zero value.
520 File names must be encoded in the script rather than in the DRAW command and passed to the DRAW command as an argument.
521
522 @subsection testmanual_3_4 Script Implementation
523
524 The test should run commands necessary to perform the tested operations, in general assuming a clean DRAW session. The required DRAW modules should be loaded by *pload* command, if it is not done by *begin* script. The messages produced by commands in a standard output should include identifiable messages on the discovered problems if any. 
525
526 Usually the script represents a set of commands that a person would run interactively to perform the operation and see its results, with additional comments to explain what happens.
527
528 Example:
529 ~~~~~
530 # Simple test of fusing box and sphere
531 box b 10 10 10 
532 sphere s 5
533 bfuse result b s
534 checkshape result
535 ~~~~~
536
537 Make sure that file *parse.rules* in the grid or group directory contains a regular expression to catch possible messages indicating the failure of the test. 
538
539 For instance, for catching errors reported by *checkshape* command relevant grids define a rule to recognize its report by the word *Faulty*:
540
541 ~~~~~
542 FAILED /\bFaulty\b/ bad shape
543 ~~~~~
544
545 For the messages generated in the script it is recommended to use the word 'Error' in the error message.
546
547 Example:
548
549 ~~~~~
550 set expected_length 11
551 if { [expr $actual_length - $expected_length] > 0.001 } {
552     puts "Error: The length of the edge should be $expected_length"
553 }
554 ~~~~~
555
556 At the end, the test script should output *TEST COMPLETED* string to mark a successful completion of the script. This is often done by the *end* script in the grid.
557
558 When the test script requires a data file, use Tcl procedure *locate_data_file* to get a path to it, instead of putting the path explicitly. This will allow easy move of the data file from OCCT sources repository to the data files repository without the need to update the test script.
559
560 Example:
561
562 ~~~~~
563 stepread [locate_data_file CAROSKI_COUPELLE.step] a *
564 ~~~~~
565
566 When the test needs to produce some snapshots or other artefacts, use Tcl variable *imagedir* as the location where such files should be put. 
567 * Command *testgrid* sets this variable to the subdirectory of the results folder corresponding to the grid. 
568 * Command *test* by default creates a dedicated temporary directory in the system temporary folder (normally the one specified by environment variable *TempDir*, *TEMP*, or *TMP*) for each execution, and sets *imagedir* to that location. 
569
570 However if variable *imagedir* is defined on the top level of Tcl interpretor, command *test* will use it instead of creating a new directory.
571
572 Use Tcl variable *casename* to prefix all files produced by the test. 
573 This variable is set to the name of the test case.
574
575 The test system can recognize an image file (snapshot) and include it in HTML log and differences if its name starts with the name of the test case (use variable *casename*), optionally followed by underscore or dash and arbitrary suffix.
576
577 The image format (defined by extension) should be *png*.
578
579 Example:
580 ~~~~~
581 xwd $imagedir/${casename}.png
582 vdisplay result; vfit
583 vdump $imagedir/${casename}-axo.png
584 vfront; vfit
585 vdump $imagedir/${casename}-front.png
586 ~~~~~
587
588 would produce:
589 ~~~~~
590 A1.png
591 A1-axo.png
592 A1-front.png
593 ~~~~~
594
595 Note that OCCT must be built with FreeImage support to be able to produce usable images.
596
597 Other Tcl variables defined during the test execution are:
598 - *groupname*: name of the test group;
599 - *gridname*: name of the test grid;
600 - *dirname*: path to the root directory of the current set of test scripts.
601
602 In order to ensure that the test works as expected in different environments, observe the following additional rules:
603 * Avoid using external commands such as *grep, rm,* etc., as these commands can be absent on another system (e.g. on Windows); use facilities provided by Tcl instead.
604 * Do not put call to *locate_data_file* in catch statement -- this can prevent correct interpretation of the missing data file by the test system.
605 * Do not use commands *decho* and *dlog* in the test script, to avoid interference with use of these commands by the test system.
606
607 @subsection testmanual_details_results Interpretation of test results
608
609 The result of the test is evaluated by checking its output against patterns defined in the files *parse.rules* of the grid and group.
610
611 The OCCT test system recognizes five statuses of the test execution:
612 * SKIPPED: reported if a line matching SKIPPED pattern is found (prior to any FAILED pattern). This indicates that the test cannot be run in the current environment; the most typical case is the absence of the required data file.
613 * FAILED: reported if a line matching pattern with status FAILED is found (unless it is masked by the preceding IGNORE pattern or a TODO or REQUIRED statement), or if message TEST COMPLETED or at least one of REQUIRED patterns is not found. This indicates that the test has produced a bad or unexpected result, and usually means a regression.
614 * BAD: reported if the test script output contains one or several TODO statements and the corresponding number of matching lines in the log. This indicates a known problem. The lines matching TODO statements are not checked against other patterns and thus will not cause a FAILED status.  
615 * IMPROVEMENT: reported if the test script output contains a TODO statement for which no corresponding line is found. This is a possible indication of improvement (a known problem has disappeared).
616 * OK: reported if none of the above statuses have been assigned. This means that the test has passed without problems.
617
618 Other statuses can be specified in *parse.rules* files, these will be classified as FAILED.
619
620 For integration of the change to OCCT repository, all tests should return either OK or BAD status.
621 The new test created for an unsolved problem should return BAD. The new test created for a fixed problem should return FAILED without the fix, and OK with the fix.
622
623 @subsection testmanual_3_6 Marking BAD cases
624
625 If the test produces an invalid result at a certain moment then the corresponding bug should be created in the OCCT issue tracker located at http://tracker.dev.opencascade.org, and the problem should be marked as TODO in the test script.
626
627 The following statement should be added to such a test script:
628 ~~~~~
629 puts "TODO BugNumber ListOfPlatforms: RegularExpression"
630 ~~~~~
631
632 Here:
633 * *BugNumber* is the bug ID in the tracker. For example: #12345.
634 * *ListOfPlatforms* is a list of platforms, at which the bug is reproduced (Linux, Windows, MacOS, or All). Note that the platform name is custom for the OCCT test system; Use procedure *checkplatform* to get the platform name.
635
636 Example:
637 ~~~~~
638 Draw[2]> checkplatform
639 Windows
640 ~~~~~
641
642 * RegularExpression is a regular expression, which should be matched against the line indicating the problem in the script output. 
643
644 Example:
645 ~~~~~
646 puts "TODO #22622 Mandriva2008: Abort .* an exception was raised"
647 ~~~~~
648
649 The parser checks the test output and if an output line matches the *RegularExpression* then it will be assigned a BAD status instead of FAILED.
650
651 A separate TODO line must be added for each output line matching an error expression to mark the test as BAD. If not all TODO messages are found in the test log, the test will be considered as possible improvement.
652
653 To mark the test as BAD for an incomplete case (when the final *TEST COMPLETE* message is missing) the expression *TEST INCOMPLETE* should be used instead of the regular expression. 
654
655 Example:
656
657 ~~~~~
658 puts "TODO OCC22817 All: exception.+There are no suitable edges"
659 puts "TODO OCC22817 All: \\*\\* Exception \\*\\*"
660 puts "TODO OCC22817 All: TEST INCOMPLETE"
661 ~~~~~
662
663 @subsection testmanual_3_7 Marking required output
664
665 To check the obtained test output matches the expected results considered correct, add REQUIRED statement for each specific message.
666 For that, the following statement should be added to the corresponding test script:
667
668 ~~~~~
669 puts "REQUIRED ListOfPlatforms: RegularExpression"
670 ~~~~~
671
672 Here *ListOfPlatforms* and *RegularExpression* have the same meaning as in TODO statements described above.
673
674 The REQUIRED statement can also be used to mask the message that would normally be interpreted as error (according to the rules defined in *parse.rules*) but should not be considered as such within the current test.
675
676 Example:
677 ~~~~~
678 puts "REQUIRED Linux: Faulty shapes in variables faulty_1 to faulty_5"
679 ~~~~~
680
681 This statement notifies test system that errors reported by *checkshape* command are expected in that test case, and test should be considered as OK if this message appears, despite of presence of general rule stating that 'Faulty' signals failure.
682
683 If output does not contain required statement, test case will be marked as FAILED.
684
685 @section testmanual_4 Advanced Use
686
687 @subsection testmanual_4_1 Running Tests on Older Versions of OCCT
688
689 Sometimes it might be necessary to run tests on the previous versions of OCCT (<= 6.5.4) that do not include this test system. This can be done by adding DRAW configuration file *DrawAppliInit* in the directory, which is current by the moment of DRAW start-up, to load test commands and to define the necessary environment.
690
691 Note: in OCCT 6.5.3, file *DrawAppliInit* already exists in <i>$CASROOT/src/DrawResources</i>, new commands should be added to this file instead of a new one in the current directory.
692
693 For example, let us assume that *d:/occt* contains an up-to-date version of OCCT sources with tests, and the test data archive is unpacked to *d:/test-data*):
694
695 ~~~~~
696 set env(CASROOT) d:/occt
697 set env(CSF_TestScriptsPath) $env(CASROOT)/tests
698 source $env(CASROOT)/src/DrawResources/TestCommands.tcl
699 set env(CSF_TestDataPath) $env(CASROOT)/data;d:/test-data
700 return
701 ~~~~~
702
703 Note that on older versions of OCCT the tests are run in compatibility mode and thus not all output of the test command can be captured; this can lead to absence of some error messages (can be reported as either a failure or an improvement).
704
705 @subsection testmanual_4_2 Adding custom tests
706
707 You can extend the test system by adding your own tests. For that it is necessary to add paths to the directory where these tests are located, and one or more additional data directories, to the environment variables *CSF_TestScriptsPath* and *CSF_TestDataPath*. The recommended way for doing this is using DRAW configuration file *DrawAppliInit* located in the directory which is current by the moment of DRAW start-up.
708
709 Use Tcl command <i>_path_separator</i> to insert a platform-dependent separator to the path list.
710
711 For example:
712 ~~~~~
713 set env(CSF_TestScriptsPath) \
714   $env(TestScriptsPath)[_path_separator]d:/MyOCCTProject/tests
715 set env(CSF_TestDataPath) \
716   d:/occt/test-data[_path_separator]d:/MyOCCTProject/data
717 return ;# this is to avoid an echo of the last command above in cout
718 ~~~~~
719
720 @subsection testmanual_4_3 Parallel execution of tests
721
722 For better efficiency, on computers with multiple CPUs the tests can be run in parallel mode. This is default behavior for command *testgrid* : the tests are executed in parallel processes (their number is equal to the number of CPUs available on the system). In order to change this behavior, use option  parallel followed by the number of processes to be used (1 or 0 to run sequentially).
723
724 Note that the parallel execution is only possible if Tcl extension package *Thread* is installed. 
725 If this package is not available, *testgrid* command will output a warning message.
726
727 @subsection testmanual_4_4 Checking non-regression of performance, memory, and visualization
728
729 Some test results are very dependent on the characteristics of the workstation, where they are performed, and thus cannot be checked by comparison with some predefined values. These results can be checked for non-regression (after a change in OCCT code) by comparing them with the results produced by the version without this change. The most typical case is comparing the result obtained in a branch created for integration of a fix (CR***) with the results obtained on the master branch before that change is made.
730
731 OCCT test system provides a dedicated command *testdiff* for comparing CPU time of execution, memory usage, and images produced by the tests.
732
733 ~~~~~
734 testdiff dir1 dir2 [groupname [gridname]] [options...]
735 ~~~~~
736 Here *dir1* and *dir2* are directories containing logs of two test runs.
737
738 Possible options are:
739 * <i>-save \<filename\> </i> -- saves the resulting log in a specified file (<i>$dir1/diff-$dir2.log</i> by default). HTML log is saved with the same name and extension .html;
740 * <i>-status {same|ok|all}</i> -- allows filtering compared cases by their status:
741         * *same* -- only cases with same status are compared (default);
742         * *ok*   -- only cases with OK status in both logs are compared;
743         * *all*  -- results are compared regardless of status;
744 * <i>-verbose \<level\> </i> -- defines the scope of output data:
745         * 1 -- outputs only differences;
746         * 2 -- additionally outputs the list of logs and directories present in one of directories only;
747         * 3 -- (by default) additionally outputs progress messages;
748 * <i>-image [filename]</i> - compare images and save the resulting log in specified file (<i>$dir1/diffimage-$dir2.log</i> by default)
749 * <i>-cpu [filename]</i> - compare overall CPU and save the resulting log in specified file (<i>$dir1/diffcpu-$dir2.log</i> by default)
750 * <i>-memory [filename]</i> - compare memory delta and save the resulting log in specified file (<i>$dir1/diffmemory-$dir2.log</i> by default)
751 * <i>-highlight_percent \<value\></i> - highlight considerable (>value in %) deviations of CPU and memory (default value is 5%)
752
753 Example:
754
755 ~~~~~
756 Draw[]> testdiff results/CR12345-2012-10-10T08:00 results/master-2012-10-09T21:20 
757 ~~~~~
758
759 Particular tests can generate additional data that need to be compared by *testdiff* command.
760 For that, for each parameter to be controlled, the test should produce the line containing keyword "COUNTER* followed by arbitrary name of the parameter, then colon and numeric value of the parameter.
761
762 Example of test code:
763
764 ~~~~~
765 puts "COUNTER Memory heap usage at step 5: [meminfo h]"
766 ~~~~~
767
768 @section testmanual_5 APPENDIX
769
770 @subsection testmanual_5_1 Test groups
771
772 @subsubsection testmanual_5_1_1 3rdparty
773
774 This group allows testing the interaction of OCCT and 3rdparty products.
775
776 DRAW module: VISUALIZATION.
777
778 | Grid  | Commands      | Functionality |
779 | :---- | :----- | :------- | 
780 | export        | vexport       | export of images to different formats |
781 | fonts  | vtrihedron, vcolorscale, vdrawtext   | display of fonts |
782
783
784 @subsubsection testmanual_5_1_2 blend
785
786 This group allows testing blends (fillets) and related operations.
787
788 DRAW module: MODELING.
789
790 | Grid  | Commands      | Functionality |
791 | :---- | :----- | :------- | 
792 | simple        | blend | fillets on simple shapes |
793 | complex       | blend         | fillets on complex shapes, non-trivial geometry |
794 | tolblend_simple       | tolblend, blend | |
795 | buildevol     | buildevol     | |
796 | tolblend_buildvol |   tolblend, buildevol |   use of additional command tolblend |
797 | bfuseblend    | bfuseblend    | | 
798 | encoderegularity      | encoderegularity      | | 
799
800 @subsubsection testmanual_5_1_3 boolean
801
802 This group allows testing Boolean operations.
803
804 DRAW module: MODELING (packages *BOPTest* and *BRepTest*).
805
806 Grids names are based on name of the command used, with suffixes: 
807 * <i>_2d</i> -- for tests operating with 2d objects (wires, wires, 3d objects, etc.); 
808 * <i>_simple</i> -- for tests operating on simple shapes (boxes, cylinders, toruses, etc.);
809 * <i>_complex</i> -- for tests dealing with complex shapes.
810
811 | Grid  | Commands      | Functionality |
812 | :---- | :----- | :------- | 
813 | bcommon_2d    | bcommon       | Common operation (old algorithm), 2d |
814 | bcommon_complex       | bcommon       | Common operation (old algorithm), complex shapes |
815 | bcommon_simple        | bcommon       | Common operation (old algorithm), simple shapes |
816 | bcut_2d       | bcut | Cut operation (old algorithm), 2d |
817 | bcut_complex  | bcut  | Cut operation (old algorithm), complex shapes |
818 | bcut_simple   | bcut |        Cut operation (old algorithm), simple shapes |
819 | bcutblend     | bcutblend     | | 
820 | bfuse_2d      | bfuse | Fuse operation (old algorithm), 2d |
821 | bfuse_complex | bfuse |       Fuse operation (old algorithm), complex shapes |
822 | bfuse_simple  | bfuse | Fuse operation (old algorithm), simple shapes |
823 | bopcommon_2d  | bopcommon |   Common operation, 2d |
824 | bopcommon_complex     | bopcommon     | Common operation, complex shapes | 
825 | bopcommon_simple      | bopcommon     | Common operation, simple shapes |
826 | bopcut_2d |   bopcut |        Cut operation, 2d |
827 | bopcut_complex |      bopcut |        Cut operation, complex shapes |
828 | bopcut_simple | bopcut        | Cut operation, simple shapes |
829 | bopfuse_2d    | bopfuse       | Fuse operation, 2d |
830 | bopfuse_complex       | bopfuse       | Fuse operation, complex shapes |
831 | bopfuse_simple        | bopfuse       | Fuse operation, simple shapes |
832 | bopsection    | bopsection    | Section |
833 | boptuc_2d     | boptuc        | |
834 | boptuc_complex        | boptuc        | |
835 | boptuc_simple | boptuc        | |
836 | bsection |    bsection        | Section (old algorithm) |
837
838 @subsubsection testmanual_5_1_4 bugs
839
840 This group allows testing cases coming from Mantis issues.
841
842 The grids are organized following OCCT module and category set for the issue in the Mantis tracker. 
843 See @ref testmanual_5_2 "Mapping of OCCT functionality to grid names in group bugs" chapter for details.
844
845 @subsubsection testmanual_5_1_5 caf
846
847 This group allows testing OCAF functionality.
848
849 DRAW module: OCAFKERNEL.
850
851 | Grid  | Commands      | Functionality |
852 | :---- | :----- | :------- | 
853 | basic | |     Basic attributes |
854 | bugs  | |     Saving and restoring of document |
855 | driver        | |     OCAF drivers |
856 | named_shape   | |     *TNaming_NamedShape* attribute |
857 | presentation  | | *AISPresentation* attributes |
858 | tree  | |     Tree construction attributes |
859 | xlink  | |    XLink attributes |
860
861 @subsubsection testmanual_5_1_6 chamfer
862
863 This group allows testing chamfer operations.
864
865 DRAW module: MODELING.
866
867 The test grid name is constructed depending on the type of the tested chamfers. Additional suffix <i>_complex</i> is used for test cases involving complex geometry (e.g. intersections of edges forming a chamfer); suffix <i>_sequence</i> is used for grids where chamfers are computed sequentially.
868
869 | Grid  | Commands      | Functionality |
870 | :---- | :----- | :------- | 
871 | equal_dist    | |     Equal distances from edge |
872 | equal_dist_complex    | |     Equal distances from edge, complex shapes |
873 | equal_dist_sequence   | |     Equal distances from edge, sequential operations |
874 | dist_dist     | |     Two distances from edge |
875 | dist_dist_complex     | |     Two distances from edge, complex shapes |
876 | dist_dist_sequence    | |     Two distances from edge, sequential operations |
877 | dist_angle    | |     Distance from edge and given angle |
878 | dist_angle_complex    | |     Distance from edge and given angle |
879 | dist_angle_sequence   | |     Distance from edge and given angle |
880
881 @subsubsection testmanual_5_1_7 demo
882
883 This group allows demonstrating how testing cases are created, and testing DRAW commands and the test system as a whole.
884
885 | Grid  | Commands      | Functionality |
886 | :---- | :----- | :------- | 
887 | draw  |  getsource, restore   | Basic DRAW commands |
888 | testsystem    | |     Testing system |
889 | samples       | |     OCCT samples | 
890
891
892 @subsubsection testmanual_5_1_8 draft
893
894 This group allows testing draft operations.
895
896 DRAW module: MODELING.
897
898 | Grid  | Commands      | Functionality |
899 | :---- | :----- | :------- | 
900 | Angle | depouille     | Drafts with angle (inclined walls) |
901
902
903 @subsubsection testmanual_5_1_9 feat
904
905 This group allows testing creation of features on a shape.
906
907 DRAW module: MODELING (package *BRepTest*).
908
909 | Grid  | Commands      | Functionality |
910 | :---- | :----- | :------- | 
911 | featdprism            | | |
912 | featlf                | | |
913 | featprism             | | |
914 | featrevol             | | | 
915 | featrf                | | |
916
917 @subsubsection testmanual_5_1_10 heal
918
919 This group allows testing the functionality provided by *ShapeHealing* toolkit.
920
921 DRAW module: XSDRAW
922
923 | Grid  | Commands      | Functionality |
924 | :---- | :----- | :------- | 
925 | fix_shape     | fixshape      | Shape healing | 
926 | fix_gaps      | fixwgaps      | Fixing gaps between edges on a wire |
927 | same_parameter        | sameparameter | Fixing non-sameparameter edges |
928 | same_parameter_locked | sameparameter | Fixing non-sameparameter edges |
929 | fix_face_size | DT_ApplySeq   | Removal of small faces |
930 | elementary_to_revolution      | DT_ApplySeq   | Conversion of elementary surfaces to revolution |
931 | direct_faces  | directfaces   | Correction of axis of elementary surfaces | 
932 | drop_small_edges      | fixsmall      | Removal of small edges | 
933 | split_angle   | DT_SplitAngle |       Splitting periodic surfaces by angle |
934 | split_angle_advanced | DT_SplitAngle  | Splitting periodic surfaces by angle |
935 | split_angle_standard | DT_SplitAngle  | Splitting periodic surfaces by angle |
936 | split_closed_faces |  DT_ClosedSplit  | Splitting of closed faces |
937 | surface_to_bspline |  DT_ToBspl       | Conversion of surfaces to b-splines |
938 | surface_to_bezier | DT_ShapeConvert | Conversion of surfaces to bezier |
939 | split_continuity      | DT_ShapeDivide | Split surfaces by continuity criterion |
940 | split_continuity_advanced | DT_ShapeDivide | Split surfaces by continuity criterion |
941 | split_continuity_standard | DT_ShapeDivide | Split surfaces by continuity criterion |
942 | surface_to_revolution_advanced |      DT_ShapeConvertRev      | Convert elementary surfaces to revolutions, complex cases |
943 | surface_to_revolution_standard |      DT_ShapeConvertRev      | Convert elementary surfaces to revolutions, simple cases |
944 | update_tolerance_locked       | updatetolerance       | Update the tolerance of shape so that it satisfy the rule: toler(face)<=toler(edge)<=toler(vertex) |
945
946 @subsubsection testmanual_5_1_11 mesh
947
948 This group allows testing shape tessellation (*BRepMesh*) and shading.
949
950 DRAW modules: MODELING (package *MeshTest*), VISUALIZATION (package *ViewerTest*)
951
952 | Grid  | Commands      | Functionality |
953 | :---- | :----- | :------- | 
954 | advanced_shading      | vdisplay      | Shading, complex shapes |
955 | standard_shading      | vdisplay      | Shading, simple shapes |
956 | advanced_mesh | mesh |        Meshing of complex shapes |
957 | standard_mesh | mesh |        Meshing of simple shapes |
958 | advanced_incmesh      | incmesh       | Meshing of complex shapes |
959 | standard_incmesh      | incmesh       | Meshing of simple shapes |
960 | advanced_incmesh_parallel | incmesh | Meshing of complex shapes, parallel mode |
961 | standard_incmesh_parallel | incmesh | Meshing of simple shapes, parallel mode |
962
963 @subsubsection testmanual_5_1_12 mkface
964
965 This group allows testing creation of simple surfaces.
966
967 DRAW module: MODELING (package *BRepTest*)
968
969 | Grid  | Commands      | Functionality |
970 | :---- | :----- | :------- | 
971 | after_trim | mkface   | |
972 | after_offset | mkface | |
973 | after_extsurf_and_offset      | mkface  | |   
974 | after_extsurf_and_trim | mkface       | | 
975 | after_revsurf_and_offset | mkface     | | 
976 | mkplane | mkplane     | |
977
978 @subsubsection testmanual_5_1_13 nproject
979
980 This group allows testing normal projection of edges and wires onto a face.
981
982 DRAW module: MODELING (package *BRepTest*) 
983
984 | Grid  | Commands      | Functionality |
985 | :---- | :----- | :------- | 
986 | Base  | nproject      |  |
987
988 @subsubsection testmanual_5_1_14 offset
989
990 This group allows testing offset functionality for curves and surfaces.
991
992 DRAW module: MODELING (package *BRepTest*) 
993
994 | Grid  | Commands      | Functionality |
995 | :---- | :----- | :------- | 
996 | compshape     | offsetcompshape       | Offset of shapes with removal of some faces | 
997 | faces_type_a  | offsetparameter, offsetload, offsetperform | Offset on a subset of faces with a fillet |
998 | faces_type_i  | offsetparameter, offsetload, offsetperform |  Offset on a subset of faces with a sharp edge |
999 | shape_type_a  | offsetparameter, offsetload, offsetperform |  Offset on a whole shape with a fillet |
1000 | shape_type_i  | offsetparameter, offsetload, offsetperform |  Offset on a whole shape with a fillet |
1001 | shape  | offsetshape  | |
1002 | wire_closed_outside_0_005, wire_closed_outside_0_025, wire_closed_outside_0_075, wire_closed_inside_0_005, wire_closed_inside_0_025, wire_closed_inside_0_075, wire_unclosed_outside_0_005, wire_unclosed_outside_0_025, wire_unclosed_outside_0_075  |       mkoffset | 2d offset of closed and unclosed planar wires with different offset step and directions of offset ( inside / outside ) |
1003         
1004 @subsubsection testmanual_5_1_15 pipe
1005
1006 This group allows testing construction of pipes (sweeping of a contour along profile).
1007
1008 DRAW module: MODELING (package *BRepTest*) 
1009
1010 | Grid  | Commands      | Functionality |
1011 | :---- | :----- | :------- | 
1012 | Standard      | pipe  | |
1013
1014 @subsubsection testmanual_5_1_16 prism
1015
1016 This group allows testing construction of prisms.
1017
1018 DRAW module: MODELING (package *BRepTest*) 
1019
1020 | Grid  | Commands      | Functionality |
1021 | :---- | :----- | :------- | 
1022 | seminf | prism        | |
1023
1024 @subsubsection testmanual_5_1_17 sewing
1025
1026 This group allows testing sewing of faces by connecting edges.
1027
1028 DRAW module: MODELING (package *BRepTest*) 
1029
1030 | Grid  | Commands      | Functionality |
1031 | :---- | :----- | :------- | 
1032 | tol_0_01      | sewing | Sewing faces with tolerance 0.01 |
1033 | tol_1 | sewing | Sewing faces with tolerance 1 |
1034 | tol_100 | sewing | Sewing faces with tolerance 100 | 
1035
1036 @subsubsection testmanual_5_1_18 thrusection
1037
1038 This group allows testing construction of shell or a solid passing through a set of sections in a given sequence (loft).
1039
1040 | Grid  | Commands      | Functionality |
1041 | :---- | :----- | :------- | 
1042 | solids        | thrusection | Lofting with resulting solid | 
1043 | not_solids | thrusection      | Lofting with resulting shell or face | 
1044
1045 @subsubsection testmanual_5_1_19 xcaf
1046
1047 This group allows  testing extended data exchange packages.
1048
1049 | Grid  | Commands      | Functionality |
1050 | :---- | :----- | :------- | 
1051 | dxc, dxc_add_ACL, dxc_add_CL, igs_to_dxc, igs_add_ACL, brep_to_igs_add_CL, stp_to_dxc, stp_add_ACL, brep_to_stp_add_CL, brep_to_dxc, add_ACL_brep, brep_add_CL        | | Subgroups are divided by format of source file, by format of result file and by type of document modification. For example, *brep_to_igs* means that the source shape in brep format was added to the document, which was saved into igs format after that. The postfix *add_CL* means that colors and layers were initialized in the document before saving and the postfix *add_ACL* corresponds to the creation of assembly and initialization of colors and layers in a document before saving. |
1052         
1053
1054 @subsection testmanual_5_2 Mapping of OCCT functionality to grid names in group *bugs*
1055
1056 | OCCT Module / Mantis category | Toolkits      | Test grid in group bugs |
1057 | :---------- | :--------- | :---------- | 
1058 | Application Framework | PTKernel, TKPShape, TKCDF, TKLCAF, TKCAF, TKBinL, TKXmlL, TKShapeSchema, TKPLCAF, TKBin, TKXml, TKPCAF, FWOSPlugin, TKStdLSchema, TKStdSchema, TKTObj, TKBinTObj, TKXmlTObj | caf |
1059 | Draw  | TKDraw, TKTopTest, TKViewerTest, TKXSDRAW, TKDCAF, TKXDEDRAW, TKTObjDRAW, TKQADraw, DRAWEXE, Problems of testing system |     draw | 
1060 | Shape Healing | TKShHealing | heal |
1061 | Mesh  | TKMesh, TKXMesh | mesh |
1062 | Data Exchange | TKIGES        | iges |
1063 | Data Exchange |       TKSTEPBase, TKSTEPAttr, TKSTEP209, TKSTEP |     step |
1064 | Data Exchange |       TKSTL, TKVRML   | stlvrml |
1065 | Data Exchange | TKXSBase, TKXCAF, TKXCAFSchema, TKXDEIGES, TKXDESTEP, TKXmlXCAF, TKBinXCAF | xde |
1066 | Foundation Classes |  TKernel, TKMath | fclasses |
1067 | Modeling_algorithms | TKGeomAlgo, TKTopAlgo, TKPrim, TKBO, TKBool, TKHLR, TKFillet, TKOffset, TKFeat, TKXMesh |       modalg |
1068 | Modeling Data | TKG2d, TKG3d, TKGeomBase, TKBRep      | moddata |
1069 | Visualization | TKService, TKV2d, TKV3d, TKOpenGl, TKMeshVS, TKNIS    | vis |
1070
1071
1072 @subsection testmanual_5_3 Recommended approaches to checking test results
1073
1074 @subsubsection testmanual_5_3_1 Shape validity
1075
1076 Run command *checkshape* on the result (or intermediate) shape and make sure that *parse.rules* of the test grid or group reports bad shapes (usually recognized by word "Faulty") as error.
1077
1078 Example
1079 ~~~~~
1080 checkshape result
1081 ~~~~~
1082
1083 To check the number of faults in the shape command *checkfaults* can be used.
1084
1085 Use: checkfaults shape source_shape [ref_value=0]
1086
1087 The default syntax of *checkfaults* command:
1088 ~~~~~
1089 checkfaults results a_1
1090 ~~~~~
1091
1092 The command will check the number of faults in the source shape (*a_1*) and compare it
1093 with number of faults in the resulting shape (*result*). If shape *result* contains
1094 more faults, you will get an error:
1095 ~~~~~
1096 checkfaults results a_1
1097 Error : Number of faults is 5
1098 ~~~~~
1099 It is possible to set the reference value for comparison (reference value is 4):
1100
1101 ~~~~~
1102 checkfaults results a_1 4
1103 ~~~~~
1104
1105 If number of faults in the resulting shape is unstable, reference value should be set to "-1".
1106 As a result command *checkfaults* will return the following error:
1107
1108 ~~~~~
1109 checkfaults results a_1 -1
1110 Error : Number of faults is UNSTABLE
1111 ~~~~~
1112
1113 @subsubsection testmanual_5_3_2 Shape tolerance
1114
1115 The maximal tolerance of sub-shapes of each kind of the resulting shape can be extracted from output of tolerance command as follows:
1116
1117 ~~~~~
1118 set tolerance [tolerance result]
1119 regexp { *FACE +: +MAX=([-0-9.+eE]+)} $tolerance dummy max_face
1120 regexp { *EDGE +: +MAX=([-0-9.+eE]+)} $tolerance dummy max_edgee
1121 regexp { *VERTEX +: +MAX=([-0-9.+eE]+)} $tolerance dummy max_vertex
1122 ~~~~~
1123
1124 It is possible to use command *checkmaxtol* to check maximal tolerance of shape and compare it with reference value.
1125
1126 Use: checkmaxtol shape [options...]
1127
1128 Allowed options are:
1129  *   <i>-ref</i> -- reference value of maximum tolerance;
1130  *   <i>-source</i> -- list of shapes to compare with;
1131  *   <i>-min_tol</i> -- minimum tolerance for comparison;
1132  *   <i>-multi_tol</i> -- tolerance multiplier.
1133
1134 The default syntax of *checkmaxtol* command for comparison with the reference value:
1135 ~~~~~
1136 checkmaxtol result -ref 0.00001
1137 ~~~~~
1138
1139 There is an opportunity to compare max tolerance of resulting shape with max tolerance of source shape.
1140 In the following example command *checkmaxtol* gets max tolerance among objects *a_1* and *a_2*.
1141 Then it chooses the maximum value between founded tolerance and value -min_tol (0.000001)
1142 and multiply it on the coefficient -multi_tol (i.e. 2):
1143
1144 ~~~~~
1145 checkmaxtol result -source {a_1 a_2} -min_tol 0.000001 -multi_tol 2
1146 ~~~~~
1147
1148 If the value of maximum tolerance more than founded tolerance for comparison, the command will return an error.
1149
1150 Also, command *checkmaxtol* can be used to get max tolerance of the shape:
1151
1152 ~~~~~
1153 set maxtol [checkmaxtol result]
1154 ~~~~~
1155
1156 @subsubsection testmanual_5_3_3 Shape volume, area, or length
1157
1158 Use command *vprops, sprops,* or *lprops* to correspondingly measure volume, area, or length of the shape produced by the test. The value can be extracted from the result of the command by *regexp*.
1159
1160 Example:
1161 ~~~~~
1162 # check area of shape result with 1% tolerance
1163 regexp {Mass +: +([-0-9.+eE]+)} [sprops result] dummy area
1164 if { abs($area - $expected) > 0.1 + 0.01 * abs ($area) } {
1165     puts "Error: The area of result shape is $area, while expected $expected"
1166 }
1167 ~~~~~
1168
1169 @subsubsection testmanual_5_3_4 Memory leaks
1170
1171 The test system measures the amount of memory used by each test case. Considerable deviations (as well as the overall difference) in comparison with reference results can be reported by command *testdiff*  (see @ref testmanual_4_4).
1172
1173 To check memory leak on a particular operation, run it in a cycle, measure the memory consumption at each step and compare it with a threshold value.
1174 The command *checktrend* (defined in *tests/bugs/begin*) can be used to analyze a sequence of memory measurements and to get a statistically based evaluation of the leak presence.
1175
1176 Example: 
1177 ~~~~~
1178 set listmem {}
1179 for {set i 1} {$i < 100} {incr i} {
1180     # run suspect operation 
1181     …
1182     # check memory usage (with tolerance equal to half page size)
1183     lappend listmem [expr [meminfo w] / 1024]
1184     if { [checktrend $listmem 0 256 "Memory leak detected"] } {
1185         puts "No memory leak, $i iterations"
1186         break
1187     }
1188 }
1189 ~~~~~
1190
1191 @subsubsection testmanual_5_3_5 Visualization
1192
1193 The following command sequence allows you to take a snapshot of the viewer, give it the name of the test case, and save in the directory indicated by Tcl variable *imagedir*. 
1194
1195 ~~~~~
1196 vinit
1197 vclear
1198 vdisplay result
1199 vsetdispmode 1
1200 vfit
1201 vzfit
1202 vdump $imagedir/${casename}_shading.png
1203 ~~~~~
1204
1205 This image will be included in the HTML log produced by *testgrid* command and will be checked for non-regression through comparison of images by command *testdiff*.
1206
1207 Also it is possible to use command *checkview* to make a snapshot of the viewer.
1208
1209 Use: checkview [options...]
1210 Allowed options are:
1211 *   <i>-display shapename </i>  -- displays shape with name *shapename*;
1212 *   <i>-3d </i> -- displays shape in 3d viewer;
1213 *   <i>-2d [ v2d / smallview ] </i> - displays shape in 2d viewer (the default viewer is *smallview*);
1214 *   <i>-path PATH</i> -- sets the location of the saved viewer screenshot;
1215 *   <i>-vdispmode N</i> -- sets *vdispmode* for 3d viewer (default value is 1)
1216 *   <i>-screenshot</i> -- makes a screenshot of already created viewer
1217 *   The procedure can check a property of shape (length, area or volume) and compare it with value *N*:
1218         * <i>-l [N]</i>
1219         * <i>-s [N]</i>
1220         * <i>-v [N]</i>
1221         * If the current property is equal to value *N*, the shape is marked as valid in the procedure.
1222         * If value *N* is not given, the procedure will mark the shape as valid if the current property is non-zero.
1223 *   <i>-with {a b c}</i> -- displays shapes *a, b* and *c* together with the shape (if the shape is valid)
1224 *   <i>-otherwise {d e f}</i> -- displays shapes *d, e* and *f* instead of the shape (if the shape is NOT valid)
1225
1226 Note that is required to use either option <i> -2d </i> or option <i> -3d</i>.
1227
1228 Examples:
1229 ~~~~~
1230 checkview -display result -2d -path ${imagedir}/${test_image}.png
1231 checkview -display result -3d -path ${imagedir}/${test_image}.png
1232 checkview -display result_2d -2d v2d -path ${imagedir}/${test_image}.png
1233 ~~~~~
1234
1235 ~~~~~
1236 box a 10 10 10
1237 box b 5 5 5 10 10 10
1238 bcut result b a
1239 set result_vertices [explode result v]
1240 checkview -display result -2d -with ${result_vertices} -otherwise { a b } -l -path ${imagedir}/${test_image}.png
1241 ~~~~~
1242
1243 ~~~~~
1244 box a 10 10 10
1245 box b 5 5 5 10 10 10
1246 bcut result b a
1247 vinit
1248 vdisplay a b
1249 vfit
1250 checkview -screenshot -3d -path ${imagedir}/${test_image}.png
1251 ~~~~~
1252
1253 @subsubsection testmanual_5_3_6 Number of free edges
1254
1255 Procedure *checkfreebounds* compares the number of free edges with a reference value.
1256
1257 Use: checkfreebounds shape ref_value [options...]
1258
1259 Allowed options are:
1260  * <i>-tol N</i> -- used tolerance (default -0.01);
1261  * <i>-type N</i> -- used type, possible values are "closed" and "opened" (default "closed").
1262
1263 ~~~~~
1264 checkfreebounds result 13
1265 ~~~~~
1266
1267 Option <i>-tol N</i> defines tolerance for command *freebounds*, which is used within command *checkfreebounds*.
1268
1269 Option <i>-type N</i> is used to select the type of counted free edges: closed or open.
1270
1271 If the number of free edges in the resulting shape is unstable, the reference value should be set to "-1".
1272 As a result command *checkfreebounds* will return the following error:
1273
1274 ~~~~~
1275 checkfreebounds result -1
1276 Error : Number of free edges is UNSTABLE
1277 ~~~~~
1278
1279 @subsubsection testmanual_5_3_7 Compare numbers
1280
1281 Procedure *checkreal* checks the equality of two reals with a tolerance (relative and absolute).
1282
1283 Use: checkreal name value expected tol_abs tol_rel
1284
1285 ~~~~~
1286 checkreal "Some important value" $value 5 0.0001 0.01
1287 ~~~~~
1288
1289 @subsubsection testmanual_5_3_8 Check number of sub-shapes
1290
1291 Procedure *checknbshapes* compares the number of sub-shapes in "shape" with the given reference data.
1292
1293 Use: checknbshapes shape [options...]
1294
1295 Allowed options are:
1296  * <i>-vertex N
1297  * -edge N
1298  * -wire N
1299  * -face N
1300  * -shell N
1301  * -solid N
1302  * -compsolid N
1303  * -compound N
1304  * -shape N
1305  * -t</i> -- compares the number of sub-shapes in "shape" counting
1306       the same sub-shapes with different location as different sub-shapes.
1307  * <i>-m msg</i> -- prints "msg" in case of error
1308
1309 ~~~~~
1310 checknbshapes result -vertex 8 -edge 4
1311 ~~~~~
1312
1313 @subsubsection testmanual_5_3_9 Check pixel color
1314
1315 Command *checkcolor* can be used to check pixel color.
1316
1317 Use: checkcolor x y red green blue
1318
1319 where:
1320  * <i>x, y</i> -- pixel coordinates;
1321  * <i>red green blue</i> -- expected pixel color (values from 0 to 1).
1322
1323 This procedure checks color with tolerance (5x5 area).
1324
1325 Next example will compare color of point with coordinates x=100 y=100 with RGB color R=1 G=0 B=0.
1326 If colors are not equal, procedure will check the nearest ones points (5x5 area)
1327 ~~~~~
1328 checkcolor 100 100 1 0 0
1329 ~~~~~
1330
1331 @subsubsection testmanual_5_3_10 Compute length, area and volume of input shape
1332
1333 Procedure *checkprops* computes length, area and volume of the input shape.
1334
1335 Use: checkprops shapename [options...]
1336
1337 Allowed options are:
1338  * <i>-l LENGTH</i> -- command *lprops*, computes the mass properties of all edges in the shape with a linear density of 1;
1339  * <i>-s AREA</i> -- command *sprops*, computes the mass properties of all faces with a surface density of 1; 
1340  * <i>-v VOLUME</i> -- command *vprops*, computes the mass properties of all solids with a density of 1;
1341  * <i>-eps EPSILON</i> -- the epsilon defines relative precision of computation;
1342  * <i>-deps DEPSILON</i> -- the epsilon defines relative precision to compare corresponding values;
1343  * <i>-equal SHAPE</i> -- compares area, volume and length of input shapes. Puts error if they are not equal;
1344  * <i>-notequal SHAPE</i> -- compares area, volume and length of input shapes. Puts error if they are equal.
1345
1346 Options <i> -l, -s </i> and <i> -v</i> are independent and can be used in any order. Tolerance *epsilon* is the same for all options.
1347
1348 ~~~~~
1349 checkprops result -s 6265.68 
1350 checkprops result -s -equal FaceBrep
1351 ~~~~~
1352
1353 @subsubsection testmanual_5_3_11 Parse output dump and compare it with reference values
1354
1355 Procedure *checkdump* is used to parse output dump and compare it with reference values.
1356
1357 Use: checkdump shapename [options...]
1358
1359 Allowed options are:
1360  * <i>-name NAME</i> -- list of parsing parameters (e.g. Center, Axis, etc.);
1361  * <i>-ref VALUE</i> -- list of reference values for each parameter in *NAME*; 
1362  * <i>-eps EPSILON</i> -- the epsilon defines relative precision of computation.
1363
1364 ~~~~~
1365 checkdump result -name {Center Axis XAxis YAxis Radii} -ref {{-70 0} {-1 -0} {-1 -0} {0 -1} {20 10}} -eps 0.01
1366 ~~~~~
1367
1368 @subsubsection testmanual_5_3_12 Compute length of input curve
1369
1370 Procedure *checklength* computes length of the input curve.
1371
1372 Use: checklength curvename [options...]
1373   
1374 Allowed options are:
1375  * <i>-l LENGTH</i> -- command *length*, computes the length of the input curve with precision of computation;
1376  * <i>-eps EPSILON</i> -- the epsilon defines a relative precision of computation;
1377  * <i>-equal CURVE</i> -- compares the length of input curves. Puts error if they are not equal;
1378  * <i>-notequal CURVE</i> -- compares the length of input curves. Puts error if they are equal.
1379
1380 ~~~~~
1381 checklength cp1 -l 7.278
1382 checklength res -l -equal ext_1
1383 ~~~~~
1384 @subsubsection testmanual_5_3_13 Check maximum deflection, number of triangles and nodes in mesh
1385
1386 Command *checktrinfo* can be used to to check the maximum deflection, as well as the number of nodes and triangles in mesh.
1387
1388 Use: checktrinfo shapename [options...]
1389
1390 Allowed options are:
1391  * <i>-tri [N]</i> --  compares the current number of triangles in *shapename* mesh with the given reference data.
1392       If reference value N is not given and the current number of triangles is equal to 0, procedure *checktrinfo* will print an error.
1393  * <i>-nod [N]</i> --  compares the current number of nodes in *shapename* mesh with the given reference data.
1394       If reference value N is not given and the current number of nodes is equal to 0, procedure *checktrinfo* will print an error.
1395  * <i>-defl [N]</i> -- compares the current value of maximum deflection in *shapename* mesh with the given reference data.
1396       If reference value N is not given and current maximum deflection is equal to 0, procedure *checktrinfo* will print an error.
1397  * <i>-max_defl N</i> --     compares the current value of maximum deflection in *shapename* mesh with the max possible value.
1398  * <i>-tol_abs_tri N</i> --  absolute tolerance for comparison of number of triangles (default value 0).
1399  * <i>-tol_rel_tri N</i> --  relative tolerance for comparison of number of triangles (default value 0).
1400  * <i>-tol_abs_nod N</i> --  absolute tolerance for comparison of number of nodes (default value 0).
1401  * <i>-tol_rel_nod N</i> --  relative tolerance for comparison of number of nodes (default value 0).
1402  * <i>-tol_abs_defl N</i> -- absolute tolerance for deflection comparison (default value 0).
1403  * <i>-tol_rel_defl N</i> -- relative tolerance for deflection comparison (default value 0).
1404  * <i>-ref [trinfo a]</i> -- compares deflection, number of triangles and nodes in *shapename* and *a*.
1405
1406 Note that options <i> -tri, -nod </i> and <i> -defl </i> do not work together with option <i> -ref</i>.
1407
1408 Examples:
1409
1410 Comparison with some reference values:
1411 ~~~~~
1412 checktrinfo result -tri 129 -nod 131 -defl 0.01
1413 ~~~~~
1414
1415 Comparison with another mesh:
1416 ~~~~~
1417 checktrinfo result -ref [tringo a]
1418 ~~~~~
1419
1420 Comparison of deflection with the max possible value:
1421 ~~~~~
1422 checktrinfo result -max_defl 1
1423 ~~~~~
1424
1425 Check that the current values are not equal to zero:
1426 ~~~~~
1427 checktrinfo result -tri -nod -defl
1428 ~~~~~
1429
1430 Check that the number of triangles and the number of nodes are not equal to some specific values:
1431 ~~~~~
1432 checktrinfo result -tri !10 -nod !8
1433 ~~~~~
1434
1435 It is possible to compare current values with reference values with some tolerances.
1436 Use options <i>-tol_\* </i> for that.
1437 ~~~~~
1438 checktrinfo result -defl 1 -tol_abs_defl 0.001
1439 ~~~~~
1440