Testing

Unit Tests

A unit test framework is provided, with the goal that all (nontrivial) classes will have unit tests. At the very least, each new class should have a corresponding unit test file stubbed in, even if there aren’t any tests yet.

  • Our unit tests also include testing of the command line Applications and (known) plugins.
  • We use the Google C++ Test Framework, but a local copy of it is embedded in the PDAL source tree, and you don’t have to have it available as a dependency.
  • Unit tests for features that are configuration-dependent, e.g. laszip compression, should be put under the same #ifdef guards as the classes being tested.
  • The Support class, in the ./test/unit directory, provides some functions for comparing files, etc, that are useful in writing test cases.
  • Unit tests should not be long-running.

Running the Tests

To run all unit tests, issue the following command from your build directory:

$ ctest

make test or ninja test should still work as well.

Depending on the which optional components you’ve chose to build, your output should resemble the following:

Test project /Users/hobu/dev/git/pdal
      Start  1: pdal_bounds_test
 1/61 Test  #1: pdal_bounds_test ...................   Passed    0.02 sec
      Start  2: pdal_config_test
 2/61 Test  #2: pdal_config_test ...................   Passed    0.02 sec
      Start  3: pdal_file_utils_test
 3/61 Test  #3: pdal_file_utils_test ...............   Passed    0.02 sec
      Start  4: pdal_georeference_test
 4/61 Test  #4: pdal_georeference_test .............   Passed    0.02 sec
      Start  5: pdal_kdindex_test
 5/61 Test  #5: pdal_kdindex_test ..................   Passed    0.03 sec
      Start  6: pdal_log_test
 6/61 Test  #6: pdal_log_test ......................   Passed    0.03 sec
      Start  7: pdal_metadata_test
 7/61 Test  #7: pdal_metadata_test .................   Passed    0.02 sec
      Start  8: pdal_options_test
 8/61 Test  #8: pdal_options_test ..................   Passed    0.02 sec
      Start  9: pdal_pdalutils_test
 9/61 Test  #9: pdal_pdalutils_test ................   Passed    0.02 sec
      Start 10: pdal_pipeline_manager_test
10/61 Test #10: pdal_pipeline_manager_test .........   Passed    0.03 sec
      Start 11: pdal_point_view_test
11/61 Test #11: pdal_point_view_test ...............   Passed    2.03 sec
      Start 12: pdal_point_table_test
12/61 Test #12: pdal_point_table_test ..............   Passed    0.03 sec
      Start 13: pdal_spatial_reference_test
13/61 Test #13: pdal_spatial_reference_test ........   Passed    0.07 sec
      Start 14: pdal_support_test
14/61 Test #14: pdal_support_test ..................   Passed    0.02 sec
      Start 15: pdal_user_callback_test
15/61 Test #15: pdal_user_callback_test ............   Passed    0.02 sec
      Start 16: pdal_utils_test
16/61 Test #16: pdal_utils_test ....................   Passed    0.02 sec
      Start 17: pdal_lazperf_test
17/61 Test #17: pdal_lazperf_test ..................   Passed    0.04 sec
      Start 18: pdal_io_bpf_test
18/61 Test #18: pdal_io_bpf_test ...................   Passed    0.20 sec
      Start 19: pdal_io_buffer_test
19/61 Test #19: pdal_io_buffer_test ................   Passed    0.02 sec
      Start 20: pdal_io_faux_test
20/61 Test #20: pdal_io_faux_test ..................   Passed    0.04 sec
      Start 21: pdal_io_ilvis2_test
21/61 Test #21: pdal_io_ilvis2_test ................   Passed    0.06 sec
      Start 22: pdal_io_las_reader_test
22/61 Test #22: pdal_io_las_reader_test ............   Passed    0.49 sec
      Start 23: pdal_io_las_writer_test
23/61 Test #23: pdal_io_las_writer_test ............   Passed    2.27 sec
      Start 24: pdal_io_optech_test
24/61 Test #24: pdal_io_optech_test ................   Passed    0.03 sec
      Start 25: pdal_io_ply_reader_test
25/61 Test #25: pdal_io_ply_reader_test ............   Passed    0.03 sec
      Start 26: pdal_io_ply_writer_test
26/61 Test #26: pdal_io_ply_writer_test ............   Passed    0.02 sec
      Start 27: pdal_io_qfit_test
27/61 Test #27: pdal_io_qfit_test ..................   Passed    0.03 sec
      Start 28: pdal_io_sbet_reader_test
28/61 Test #28: pdal_io_sbet_reader_test ...........   Passed    0.04 sec
      Start 29: pdal_io_sbet_writer_test
29/61 Test #29: pdal_io_sbet_writer_test ...........   Passed    0.03 sec
      Start 30: pdal_io_terrasolid_test
30/61 Test #30: pdal_io_terrasolid_test ............   Passed    0.03 sec
      Start 31: pdal_filters_chipper_test
31/61 Test #31: pdal_filters_chipper_test ..........   Passed    0.03 sec
      Start 32: pdal_filters_colorization_test
32/61 Test #32: pdal_filters_colorization_test .....   Passed   11.40 sec
      Start 33: pdal_filters_crop_test
33/61 Test #33: pdal_filters_crop_test .............   Passed    0.04 sec
      Start 34: pdal_filters_decimation_test
34/61 Test #34: pdal_filters_decimation_test .......   Passed    0.02 sec
      Start 35: pdal_filters_divider_test
35/61 Test #35: pdal_filters_divider_test ..........   Passed    0.03 sec
      Start 36: pdal_filters_ferry_test
36/61 Test #36: pdal_filters_ferry_test ............   Passed    0.04 sec
      Start 37: pdal_filters_merge_test
37/61 Test #37: pdal_filters_merge_test ............   Passed    0.03 sec
      Start 38: pdal_filters_reprojection_test
38/61 Test #38: pdal_filters_reprojection_test .....   Passed    0.03 sec
      Start 39: pdal_filters_range_test
39/61 Test #39: pdal_filters_range_test ............   Passed    0.05 sec
      Start 40: pdal_filters_randomize_test
40/61 Test #40: pdal_filters_randomize_test ........   Passed    0.02 sec
      Start 41: pdal_filters_sort_test
41/61 Test #41: pdal_filters_sort_test .............   Passed    0.39 sec
      Start 42: pdal_filters_splitter_test
42/61 Test #42: pdal_filters_splitter_test .........   Passed    0.03 sec
      Start 43: pdal_filters_stats_test
43/61 Test #43: pdal_filters_stats_test ............   Passed    0.03 sec
      Start 44: pdal_filters_transformation_test
44/61 Test #44: pdal_filters_transformation_test ...   Passed    0.03 sec
      Start 45: pdal_merge_test
45/61 Test #45: pdal_merge_test ....................   Passed    0.07 sec
      Start 46: pc2pc_test
46/61 Test #46: pc2pc_test .........................   Passed    0.15 sec
      Start 47: xml_schema_test
47/61 Test #47: xml_schema_test ....................   Passed    0.02 sec
      Start 48: pdal_filters_attribute_test
48/61 Test #48: pdal_filters_attribute_test ........   Passed    0.09 sec
      Start 49: pdal_plugins_cpd_kernel_test
49/61 Test #49: pdal_plugins_cpd_kernel_test .......***Exception: Other  0.08 sec
      Start 50: hexbintest
50/61 Test #50: hexbintest .........................   Passed    0.03 sec
      Start 51: icetest
51/61 Test #51: icetest ............................   Passed    0.04 sec
      Start 52: mrsidtest
52/61 Test #52: mrsidtest ..........................   Passed    0.06 sec
      Start 53: pdal_io_nitf_writer_test
53/61 Test #53: pdal_io_nitf_writer_test ...........   Passed    0.08 sec
      Start 54: pdal_io_nitf_reader_test
54/61 Test #54: pdal_io_nitf_reader_test ...........   Passed    0.04 sec
      Start 55: ocitest
55/61 Test #55: ocitest ............................***Failed    0.06 sec
      Start 56: pcltest
56/61 Test #56: pcltest ............................   Passed    0.28 sec
      Start 57: pgpointcloudtest
57/61 Test #57: pgpointcloudtest ...................   Passed    1.66 sec
      Start 58: plangtest
58/61 Test #58: plangtest ..........................   Passed    0.14 sec
      Start 59: python_predicate_test
59/61 Test #59: python_predicate_test ..............   Passed    0.16 sec
      Start 60: python_programmable_test
60/61 Test #60: python_programmable_test ...........   Passed    0.15 sec
      Start 61: sqlitetest
61/61 Test #61: sqlitetest .........................   Passed    0.55 sec

97% tests passed, 2 tests failed out of 61

Total Test time (real) =  21.57 sec

The following tests FAILED:
     49 - pdal_plugins_cpd_kernel_test (OTHER_FAULT)
     55 - ocitest (Failed)

For a more verbose output, use the -V flag. Or, to run an individual test suite, use -R <suite name>. For example:

$ ctest -V -R pdal_io_bpf_test

Should produce output similar to:

  UpdateCTestConfiguration  from :/Users/hobu/dev/git/pdal/DartConfiguration.tcl
  UpdateCTestConfiguration  from :/Users/hobu/dev/git/pdal/DartConfiguration.tcl
  Test project /Users/hobu/dev/git/pdal
  Constructing a list of tests
  Done constructing a list of tests
  Checking test dependency graph...
  Checking test dependency graph end
  test 18
      Start 18: pdal_io_bpf_test

  18: Test command: /Users/hobu/dev/git/pdal/bin/pdal_io_bpf_test
  18: Environment variables:
  18:  PDAL_DRIVER_PATH=/Users/hobu/dev/git/pdal/lib
  18: Test timeout computed to be: 9.99988e+06
  18: [==========] Running 20 tests from 1 test case.
  18: [----------] Global test environment set-up.
  18: [----------] 20 tests from BPFTest
  18: [ RUN      ] BPFTest.test_point_major
  18: [       OK ] BPFTest.test_point_major (8 ms)
  18: [ RUN      ] BPFTest.test_dim_major
  18: [       OK ] BPFTest.test_dim_major (3 ms)
  18: [ RUN      ] BPFTest.test_byte_major
  18: [       OK ] BPFTest.test_byte_major (4 ms)
  18: [ RUN      ] BPFTest.test_point_major_zlib
  18: [       OK ] BPFTest.test_point_major_zlib (6 ms)
  18: [ RUN      ] BPFTest.test_dim_major_zlib
  18: [       OK ] BPFTest.test_dim_major_zlib (4 ms)
  18: [ RUN      ] BPFTest.test_byte_major_zlib
  18: [       OK ] BPFTest.test_byte_major_zlib (5 ms)
  18: [ RUN      ] BPFTest.roundtrip_byte
  18: [       OK ] BPFTest.roundtrip_byte (15 ms)
  18: [ RUN      ] BPFTest.roundtrip_dimension
  18: [       OK ] BPFTest.roundtrip_dimension (10 ms)
  18: [ RUN      ] BPFTest.roundtrip_point
  18: [       OK ] BPFTest.roundtrip_point (11 ms)
  18: [ RUN      ] BPFTest.roundtrip_byte_compression
  18: [       OK ] BPFTest.roundtrip_byte_compression (16 ms)
  18: [ RUN      ] BPFTest.roundtrip_dimension_compression
  18: [       OK ] BPFTest.roundtrip_dimension_compression (13 ms)
  18: [ RUN      ] BPFTest.roundtrip_point_compression
  18: [       OK ] BPFTest.roundtrip_point_compression (14 ms)
  18: [ RUN      ] BPFTest.roundtrip_scaling
  18: [       OK ] BPFTest.roundtrip_scaling (10 ms)
  18: [ RUN      ] BPFTest.extra_bytes
  18: [       OK ] BPFTest.extra_bytes (15 ms)
  18: [ RUN      ] BPFTest.bundled
  18: [       OK ] BPFTest.bundled (17 ms)
  18: [ RUN      ] BPFTest.inspect
  18: [       OK ] BPFTest.inspect (1 ms)
  18: [ RUN      ] BPFTest.mueller
  18: [       OK ] BPFTest.mueller (0 ms)
  18: [ RUN      ] BPFTest.flex
  18: [       OK ] BPFTest.flex (9 ms)
  18: [ RUN      ] BPFTest.flex2
  18: [       OK ] BPFTest.flex2 (7 ms)
  18: [ RUN      ] BPFTest.outputdims
  18: [       OK ] BPFTest.outputdims (14 ms)
  18: [----------] 20 tests from BPFTest (182 ms total)
  18:
  18: [----------] Global test environment tear-down
  18: [==========] 20 tests from 1 test case ran. (182 ms total)
  18: [  PASSED  ] 20 tests.
  1/1 Test #18: pdal_io_bpf_test .................   Passed    0.20 sec

  The following tests passed:
      pdal_io_bpf_test

  100% tests passed, 0 tests failed out of 1


$ bin/pdal_io_test

Again, the output should resemble the following:

[==========] Running 20 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 20 tests from BPFTest
[ RUN      ] BPFTest.test_point_major
[       OK ] BPFTest.test_point_major (7 ms)
[ RUN      ] BPFTest.test_dim_major
[       OK ] BPFTest.test_dim_major (3 ms)
[ RUN      ] BPFTest.test_byte_major
[       OK ] BPFTest.test_byte_major (4 ms)
[ RUN      ] BPFTest.test_point_major_zlib
[       OK ] BPFTest.test_point_major_zlib (5 ms)
[ RUN      ] BPFTest.test_dim_major_zlib
[       OK ] BPFTest.test_dim_major_zlib (5 ms)
[ RUN      ] BPFTest.test_byte_major_zlib
[       OK ] BPFTest.test_byte_major_zlib (6 ms)
[ RUN      ] BPFTest.roundtrip_byte
[       OK ] BPFTest.roundtrip_byte (17 ms)
[ RUN      ] BPFTest.roundtrip_dimension
[       OK ] BPFTest.roundtrip_dimension (10 ms)
[ RUN      ] BPFTest.roundtrip_point
[       OK ] BPFTest.roundtrip_point (11 ms)
[ RUN      ] BPFTest.roundtrip_byte_compression
[       OK ] BPFTest.roundtrip_byte_compression (15 ms)
[ RUN      ] BPFTest.roundtrip_dimension_compression
[       OK ] BPFTest.roundtrip_dimension_compression (14 ms)
[ RUN      ] BPFTest.roundtrip_point_compression
[       OK ] BPFTest.roundtrip_point_compression (14 ms)
[ RUN      ] BPFTest.roundtrip_scaling
[       OK ] BPFTest.roundtrip_scaling (11 ms)
[ RUN      ] BPFTest.extra_bytes
[       OK ] BPFTest.extra_bytes (16 ms)
[ RUN      ] BPFTest.bundled
[       OK ] BPFTest.bundled (17 ms)
[ RUN      ] BPFTest.inspect
[       OK ] BPFTest.inspect (1 ms)
[ RUN      ] BPFTest.mueller
[       OK ] BPFTest.mueller (0 ms)
[ RUN      ] BPFTest.flex
[       OK ] BPFTest.flex (8 ms)
[ RUN      ] BPFTest.flex2
[       OK ] BPFTest.flex2 (7 ms)
[ RUN      ] BPFTest.outputdims
[       OK ] BPFTest.outputdims (14 ms)
[----------] 20 tests from BPFTest (185 ms total)

[----------] Global test environment tear-down
[==========] 20 tests from 1 test case ran. (185 ms total)
[  PASSED  ] 20 tests.

This invocation allows us to alter Google Test’s default behavior. For more on the available flags type:

$ bin/<test_name> --help

Key among these flags are the ability to list tests (--gtest_list_tests) and to run only select tests (--gtest_filter).

Note

If the PostgreSQL PointCloud plugin was enabled on the CMake command line (with -DBUILD_PLUGIN_PGPOINTCLOUD=ON) then ctest will attempt to run the pgpointcloud tests. And you will get PostgreSQL connection errors if the libpq environment variables are not correctly set in your shell. This is for example how you can run the pgpointcloud tests:

$ PGUSER=pdal PGPASSWORD=pdal PGHOST=localhost ctest -R pgpointcloudtest

Test Data

Use the directory ./test/data to store files used for unit tests. A vfunction is provided in the Support class for referencing that directory in a configuration-independent manner.

Temporary output files from unit tests should go into the ./test/temp directory. A Support function is provided for referencing this directory as well.

Unit tests should always clean up and remove any files that they create (except perhaps in case of a failed test, in which case leaving the output around might be helpful for debugging).