```{py:currentmodule} cantera ``` # Running Tests and Debugging ## Using Cantera from the Build Directory After compiling Cantera from source, it is convenient to use the Cantera Python module directly without fully installing Cantera. Doing this requires some special configuration to make sure your operating system and Python installation can find all the relevant files. ### Temporary Configuration To use the Python module from the build directory for the duration of the current shell session, run the following commands from the root of the Cantera source directory: ::::{tab-set} :::{tab-item} Linux :sync: linux ```sh export LD_LIBRARY_PATH=$(pwd)/build/lib export PYTHONPATH=$(pwd)/build/python ``` ::: :::{tab-item} macOS :sync: macos ```sh export DYLD_LIBRARY_PATH=$(pwd)/build/lib export PYTHONPATH=$(pwd)/build/python ``` ::: :::{tab-item} Windows (PowerShell) :sync: windows ```pwsh $Env:PYTHONPATH = (Get-Location).Path + '\build\python' ``` ::: :::: After this, you will be able to use the Cantera Python module from the terminal where these commands were executed. For example: ```sh # start an interactive shell and then import Cantera ipython # convert a mechanism python -m cantera.ck2yaml --inp=... # run an example python samples/python/onedim/adiabatic_flame.py ``` ### Permanent Configuration Using Conda The following commands will make the Cantera Python module in the build directory available within the current Conda environment. ::::{tab-set} :::{tab-item} Linux :sync: linux ```sh conda env config vars set LD_LIBRARY_PATH=$(pwd)/build/lib conda env config vars set PYTHONPATH=$(pwd)/build/python ``` ::: :::{tab-item} macOS :sync: macos ```sh conda env config vars set DYLD_LIBRARY_PATH=$(pwd)/build/lib conda env config vars set PYTHONPATH=$(pwd)/build/python ``` ::: :::{tab-item} Windows (PowerShell) :sync: windows ```pwsh New-Item -Type Junction -Target ((Get-Location).Path + '\build\python\cantera') -Path ($Env:CONDA_PREFIX + '\lib\site-packages\cantera') ``` ::: :::: Setting up the paths this way can be useful if you're using an IDE such as VS Code that is aware of Conda environments and will help with running tests within the IDE. ## Running Individual Python Tests and Test Subsets To run the full Python test suite: ```sh pytest -raP --verbose test/python ``` To run tests from a specific file: ```sh pytest -raP --verbose test/python/test_composite.py ``` To run tests where the name matches a specific pattern: ```sh pytest -raP --verbose test/python -k 'add_rxn' ``` To have the test runner activate a PDB shell after a failed assertion: ```sh pytest -raP --verbose --pdb test/python ``` ```{important} Remember to run `scons build` after any code change before running tests directly with `pytest`. ``` (sec-pytest-vscode)= ## Running Python Tests Using VS Code To allow running the Python unit tests through VS Code, add the following options to `.vscode/settings.json`: ```json "python.testing.unittestEnabled": false, "python.testing.pytestEnabled": true, "python.testing.cwd": "test/python", "python.testing.unittestArgs": [ "-v", "-s", "-p" ], ``` Once you have done this, you should be able to run and debug individual Python tests directly from VS Code using the controls in the gutter to the left of the editor window. (sec-gtest-vscode)= ## Debugging C++ Tests Using VS Code To allow running the C++ unit tests through the [VS Code interactive debugger](https://code.visualstudio.com/docs/editor/debugging), edit or create the file `.vscode/launch.json` with contents based on the following template. Some substitutions are needed for paths specific to your computer. ::::{tab-set} :::{tab-item} Linux :sync: linux ```json { "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch test/thermo", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/test/thermo/thermo", "cwd": "${workspaceFolder}/test/work", "environment": [ { "name": "LD_LIBRARY_PATH", "value": "${workspaceFolder}/build/lib" }, { "name": "CANTERA_DATA", "value": "${workspaceFolder}/data:${workspaceFolder}/test/data" }, { "name": "PYTHONPATH", "value": "${workspaceFolder}/test/python:${workspaceFolder}/build/python:CONDAROOT/lib/python3.11/site-packages" } ], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] }, { "name": "(gdb) Launch test/kinetics", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/test/kinetics/kinetics", // Optional configuration to run a specific test or subset of tests "args": [ // "--gtest_filter=KineticsFromScratch.add_falloff_reaction" ], "cwd": "${workspaceFolder}/test/work", "environment": [ { "name": "LD_LIBRARY_PATH", "value": "${workspaceFolder}/build/lib" }, { "name": "CANTERA_DATA", "value": "${workspaceFolder}/data:${workspaceFolder}/test/data" }, { "name": "PYTHONPATH", "value": "${workspaceFolder}/test/python:${workspaceFolder}/build/python:CONDAROOT/lib/python3.11/site-packages" } ], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] } ] } ``` ::: :::{tab-item} macOS :sync: macos Install the [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb) extension for VS Code. ```json { "version": "0.2.0", "configurations": [ { "name": "Thermo GTest", "type": "lldb", "request": "launch", "program": "${workspaceFolder}/build/test/thermo/thermo", "cwd": "${workspaceFolder}/test/work", "env": { "DYLD_LIBRARY_PATH": "${workspaceFolder}/build/lib", "CANTERA_DATA": "${workspaceFolder}/data:${workspaceFolder}/test/data", "PYTHONPATH": "${workspaceFolder}/test/python:${workspaceFolder}/build/python:CONDAROOT/lib/python3.11/site-packages" }, }, { "name": "Kinetics GTest", "type": "lldb", "request": "launch", "program": "${workspaceFolder}/build/test/kinetics/kinetics", // Optional configuration to run a specific test or subset of tests "args": [ // "--gtest_filter=KineticsFromScratch.add_falloff_reaction" ], "cwd": "${workspaceFolder}/test/work", "env": { "DYLD_LIBRARY_PATH": "${workspaceFolder}/build/lib", "CANTERA_DATA": "${workspaceFolder}/data:${workspaceFolder}/test/data", "PYTHONPATH": "${workspaceFolder}/test/python:${workspaceFolder}/build/python:CONDAROOT/lib/python3.11/site-packages" }, } ] } ``` ::: :::{tab-item} Windows :sync: windows ```json { "version": "0.2.0", "configurations": [ { "type": "cppvsdbg", "request": "launch", "name": "Thermo GTest", "program": "${workspaceFolder}/build/test/thermo/thermo.exe", "cwd": "${workspaceFolder}/test/work", "environment": [ { "name": "Path", "value": "${env:Path};${workspaceFolder}/build/lib;CONDAROOT;CONDAROOT/Library/bin" }, { "name": "CANTERA_DATA", "value": "${workspaceFolder}/data;${workspaceFolder}/test/data" }, { "name": "PYTHONPATH", "value": "${workspaceFolder}/build/python;${workspaceFolder}/test/python" } ] }, { "type": "cppvsdbg", "request": "launch", "name": "Kinetics GTest", "program": "${workspaceFolder}/build/test/kinetics/kinetics.exe", "cwd": "${workspaceFolder}/test/work", // Optional configuration to run a specific test or subset of tests "args": [ // "--gtest_filter=KineticsFromScratch.add_falloff_reaction" ], "environment": [ { "name": "Path", "value": "${env:Path};${workspaceFolder}/build/lib;CONDAROOT;CONDAROOT/Library/bin" }, { "name": "CANTERA_DATA", "value": "${workspaceFolder}/data;${workspaceFolder}/test/data" }, { "name": "PYTHONPATH", "value": "${workspaceFolder}/build/python;${workspaceFolder}/test/python" } ] } ] } ``` ::: :::: In the above, replace `CONDAROOT` with your Conda environment's root directory. To determine this path, run `conda env list`. For example, if you see output like ``` conda env list # conda environments: # base C:\Users\speth\mambaforge ctdev * C:\Users\speth\mambaforge\envs\ctdev ``` then use `C:/Users/speth/mambaforge/envs/ctdev` as `CONDAROOT`, replacing forward slashes with backslashes since the backslash is used as an escape character in JSON. You will also need to replace any instances of `python3.11` in the above to refer to the version of Python in your Conda environment. You can create additional configurations for any of the test executables that are part of the GTest test suite by changing the `program` name above. :::{note} Before running any of the GTest programs through VS Code, you will first need to use SCons to compile the corresponding test program, for example by running ```sh scons build-thermo ``` If you make any changes to the test program or the Cantera library code, re-run this command before starting the debugger again to ensure that the changes take effect. ::: ## Running tests through GDB If you are trying to debug a problem that results in a segmentation fault (crash) during the test, you can try running it inside the debugger. The following notes may help with running either the C++ or Python tests through GDB on Linux. - Build the source code with debugging information enabled and optimizations disabled. It can also help to enable certain bounds checks available in the standard library: ```sh scons build optimize=n debug=y debug_flags='-g -D_GLIBCXX_ASSERTIONS' ``` ### Running C++ (GoogleTest) Tests First, build the target test through SCons to make sure the Cantera library and the test executable are up to date. We'll use the `kinetics` test subset as an example, with the goal of debugging the `PlogLowPressure` test. ```sh scons build-kinetics ``` Next, you need to set some environment variables that specify where the test program can find files needed to run the tests. Normally, setting these would be handled by SCons. ```sh export CANTERA_DATA=test/data:data export PYTHONPATH=test/python:$PYTHONPATH ``` To start the debugger and enable only the desired test: ```sh gdb --args build/test/kinetics/kinetics --gtest_filter="*PlogLowPressure" ``` Then at the `(gdb)` prompt, type `run` and press Enter. After the debugger reaches the error, the most useful command is the `where` command, which will print a stack trace. The `up` command will move up the stack each time it is called and print the corresponding line of the source code. ## Accessing Stack Traces Before resorting to running in the debugger, it can sometimes be helpful to get the stack trace associated with an error from within a normal workflow. To enable printing a stacktrace after an unhandled exception or segmentation fault, you can call the C++ function {ct}`printStackTraceOnSegfault` or the Python function {py:func}`print_stack_trace_on_segfault`. To add stack trace information to the error message printed by any `CanteraError` exceptions, you can call the C++ method {ct}`CanteraError::setStackTraceDepth` with a depth of 20 to print the top 20 frames of the call stack, or similarly the Python method {py:meth}`CanteraError.set_stack_trace_depth`.