786 lines
62 KiB
HTML
786 lines
62 KiB
HTML
<!DOCTYPE html>
|
||
<html class="writer-html5" lang="en" >
|
||
<head>
|
||
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>4.12. Adding tests for unit testing — LAMMPS documentation</title>
|
||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
||
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
|
||
<link rel="stylesheet" href="_static/sphinx-design.min.css" type="text/css" />
|
||
<link rel="stylesheet" href="_static/css/lammps.css" type="text/css" />
|
||
<link rel="shortcut icon" href="_static/lammps.ico"/>
|
||
<link rel="canonical" href="https://docs.lammps.org/Developer_unittest.html" />
|
||
<!--[if lt IE 9]>
|
||
<script src="_static/js/html5shiv.min.js"></script>
|
||
<![endif]-->
|
||
|
||
<script src="_static/jquery.js?v=5d32c60e"></script>
|
||
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
|
||
<script src="_static/documentation_options.js?v=5929fcd5"></script>
|
||
<script src="_static/doctools.js?v=9bcbadda"></script>
|
||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||
<script src="_static/design-tabs.js?v=f930bc37"></script>
|
||
<script async="async" src="_static/mathjax/es5/tex-mml-chtml.js?v=cadf963e"></script>
|
||
<script src="_static/js/theme.js"></script>
|
||
<link rel="index" title="Index" href="genindex.html" />
|
||
<link rel="search" title="Search" href="search.html" />
|
||
<link rel="next" title="4.13. C++ base classes" href="Classes.html" />
|
||
<link rel="prev" title="4.11. Writing plugins" href="Developer_plugins.html" />
|
||
</head>
|
||
|
||
<body class="wy-body-for-nav">
|
||
<div class="wy-grid-for-nav">
|
||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||
<div class="wy-side-scroll">
|
||
<div class="wy-side-nav-search" >
|
||
|
||
|
||
|
||
<a href="Manual.html">
|
||
|
||
<img src="_static/lammps-logo.png" class="logo" alt="Logo"/>
|
||
</a>
|
||
<div class="lammps_version">Version: <b>19 Nov 2024</b></div>
|
||
<div class="lammps_release">git info: </div>
|
||
<div role="search">
|
||
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
|
||
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
|
||
<input type="hidden" name="check_keywords" value="yes" />
|
||
<input type="hidden" name="area" value="default" />
|
||
</form>
|
||
</div>
|
||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||
<p class="caption" role="heading"><span class="caption-text">User Guide</span></p>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="Intro.html">1. Introduction</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="Install.html">2. Install LAMMPS</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="Build.html">3. Build LAMMPS</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="Run_head.html">4. Run LAMMPS</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="Commands.html">5. Commands</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="Packages.html">6. Optional packages</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="Speed.html">7. Accelerate performance</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="Howto.html">8. Howto discussions</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="Examples.html">9. Example scripts</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="Tools.html">10. Auxiliary tools</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="Errors.html">11. Errors</a></li>
|
||
</ul>
|
||
<p class="caption" role="heading"><span class="caption-text">Programmer Guide</span></p>
|
||
<ul class="current">
|
||
<li class="toctree-l1"><a class="reference internal" href="Library.html">1. LAMMPS Library Interfaces</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="Python_head.html">2. Use Python with LAMMPS</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="Modify.html">3. Modifying & extending LAMMPS</a></li>
|
||
<li class="toctree-l1 current"><a class="reference internal" href="Developer.html">4. Information for Developers</a><ul class="current">
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_org.html">4.1. Source files</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_org.html#class-topology">4.2. Class topology</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_code_design.html">4.3. Code design</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_parallel.html">4.4. Parallel algorithms</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_atom.html">4.5. Accessing per-atom data</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_comm_ops.html">4.6. Communication patterns</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_flow.html">4.7. How a timestep works</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_write.html">4.8. Writing new styles</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_notes.html">4.9. Notes for developers and code maintainers</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_updating.html">4.10. Notes for updating code written for older LAMMPS versions</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_plugins.html">4.11. Writing plugins</a></li>
|
||
<li class="toctree-l2 current"><a class="current reference internal" href="#">4.12. Adding tests for unit testing</a><ul>
|
||
<li class="toctree-l3"><a class="reference internal" href="#tests-for-utility-functions">4.12.1. Tests for utility functions</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="#tests-for-individual-lammps-commands">4.12.2. Tests for individual LAMMPS commands</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="#tests-for-the-c-style-library-interface">4.12.3. Tests for the C-style library interface</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="#tests-for-the-python-module-and-package">4.12.4. Tests for the Python module and package</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="#tests-for-the-fortran-interface">4.12.5. Tests for the Fortran interface</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="#id1">4.12.6. Tests for the C++-style library interface</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="#tests-for-reading-and-writing-file-formats">4.12.7. Tests for reading and writing file formats</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="#tests-for-styles-computing-or-modifying-forces">4.12.8. Tests for styles computing or modifying forces</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="#tests-for-programs-in-the-tools-folder">4.12.9. Tests for programs in the tools folder</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="#troubleshooting-failed-unit-tests">4.12.10. Troubleshooting failed unit tests</a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Classes.html">4.13. C++ base classes</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_platform.html">4.14. Platform abstraction functions</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_utils.html">4.15. Utility functions</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_utils.html#special-math-functions">4.16. Special Math functions</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_utils.html#tokenizer-classes">4.17. Tokenizer classes</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_utils.html#argument-parsing-classes">4.18. Argument parsing classes</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_utils.html#file-reader-classes">4.19. File reader classes</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_utils.html#memory-pool-classes">4.20. Memory pool classes</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_utils.html#eigensolver-functions">4.21. Eigensolver functions</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_utils.html#communication-buffer-coding-with-ubuf">4.22. Communication buffer coding with <em>ubuf</em></a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="Developer_grid.html">4.23. Use of distributed grids within style classes</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<p class="caption" role="heading"><span class="caption-text">Command Reference</span></p>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="commands_list.html">Commands</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="fixes.html">Fix Styles</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="computes.html">Compute Styles</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="pairs.html">Pair Styles</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="bonds.html">Bond Styles</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="angles.html">Angle Styles</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="dihedrals.html">Dihedral Styles</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="impropers.html">Improper Styles</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="dumps.html">Dump Styles</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="fix_modify_atc_commands.html">fix_modify AtC commands</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="Bibliography.html">Bibliography</a></li>
|
||
</ul>
|
||
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
|
||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||
<a href="Manual.html">LAMMPS</a>
|
||
</nav>
|
||
|
||
<div class="wy-nav-content">
|
||
<div class="rst-content style-external-links">
|
||
<div role="navigation" aria-label="Page navigation">
|
||
<ul class="wy-breadcrumbs">
|
||
<li><a href="Manual.html" class="icon icon-home" aria-label="Home"></a></li>
|
||
<li class="breadcrumb-item"><a href="Developer.html"><span class="section-number">4. </span>Information for Developers</a></li>
|
||
<li class="breadcrumb-item active"><span class="section-number">4.12. </span>Adding tests for unit testing</li>
|
||
<li class="wy-breadcrumbs-aside">
|
||
<a href="https://www.lammps.org"><img src="_static/lammps-logo.png" width="64" height="16" alt="LAMMPS Homepage"></a> | <a href="Commands_all.html">Commands</a>
|
||
</li>
|
||
</ul><div class="rst-breadcrumbs-buttons" role="navigation" aria-label="Sequential page navigation">
|
||
<a href="Developer_plugins.html" class="btn btn-neutral float-left" title="4.11. Writing plugins" accesskey="p"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
|
||
<a href="Classes.html" class="btn btn-neutral float-right" title="4.13. C++ base classes" accesskey="n">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
|
||
</div>
|
||
<hr/>
|
||
</div>
|
||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||
<div itemprop="articleBody">
|
||
|
||
<p><span class="math notranslate nohighlight">\(\renewcommand{\AA}{\text{Å}}\)</span></p>
|
||
<section id="adding-tests-for-unit-testing">
|
||
<h1><span class="section-number">4.12. </span>Adding tests for unit testing<a class="headerlink" href="#adding-tests-for-unit-testing" title="Link to this heading"></a></h1>
|
||
<p>This section discusses adding or expanding tests for the unit test
|
||
infrastructure included into the LAMMPS source code distribution.
|
||
Unlike example inputs, unit tests focus on testing the “local” behavior
|
||
of individual features, tend to run fast, and should be set up to cover
|
||
as much of the added code as possible. When contributing code to the
|
||
distribution, the LAMMPS developers will appreciate if additions to the
|
||
integrated unit test facility are included.</p>
|
||
<p>Given the complex nature of MD simulations where many operations can
|
||
only be performed when suitable “real” simulation environment has been
|
||
set up, not all tests will be unit tests in the strict definition of
|
||
the term. They are rather executed on a more abstract level by issuing
|
||
LAMMPS script commands and then inspecting the changes to the internal
|
||
data. For some classes of tests, generic test programs have been
|
||
written that can be applied to parts of LAMMPS that use the same
|
||
interface (via polymorphism) and those are driven by input files, so
|
||
tests can be added by simply adding more of those input files. Those
|
||
tests should be seen more as a hybrid between unit and regression tests.</p>
|
||
<p>When adding tests it is recommended to also <a class="reference internal" href="Build_development.html#testing"><span class="std std-ref">enable support for
|
||
code coverage reporting</span></a>, and study the coverage reports
|
||
so that it is possible to monitor which parts of the code of a given
|
||
file are executed during the tests and which tests would need to be
|
||
added to increase the coverage.</p>
|
||
<p>The tests are grouped into categories and corresponding folders.
|
||
The following sections describe how the tests are implemented and
|
||
executed in those categories with increasing complexity of tests
|
||
and implementation.</p>
|
||
<section id="tests-for-utility-functions">
|
||
<h2><span class="section-number">4.12.1. </span>Tests for utility functions<a class="headerlink" href="#tests-for-utility-functions" title="Link to this heading"></a></h2>
|
||
<p>These tests are driven by programs in the <code class="docutils literal notranslate"><span class="pre">unittest/utils</span></code> folder
|
||
and most closely resemble conventional unit tests. There is one test
|
||
program for each namespace or group of classes or file. The naming
|
||
convention for the sources and executables is that they start with
|
||
with <code class="docutils literal notranslate"><span class="pre">test_</span></code>. The following sources and groups of tests are currently
|
||
available:</p>
|
||
<table class="docutils align-left">
|
||
<colgroup>
|
||
<col style="width: 32.0%" />
|
||
<col style="width: 18.0%" />
|
||
<col style="width: 50.0%" />
|
||
</colgroup>
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>File name:</p></th>
|
||
<th class="head"><p>Test name:</p></th>
|
||
<th class="head"><p>Description:</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">test_argutils.cpp</span></code></p></td>
|
||
<td><p>ArgInfo</p></td>
|
||
<td><p>Tests for <code class="docutils literal notranslate"><span class="pre">ArgInfo</span></code> class used by LAMMPS</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">test_fmtlib.cpp</span></code></p></td>
|
||
<td><p>FmtLib</p></td>
|
||
<td><p>Tests for <code class="docutils literal notranslate"><span class="pre">fmtlib::</span></code> functions used by LAMMPS</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">test_math_eigen_impl.cpp</span></code></p></td>
|
||
<td><p>MathEigen</p></td>
|
||
<td><p>Tests for <code class="docutils literal notranslate"><span class="pre">MathEigen::</span></code> classes and functions</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">test_mempool.cpp</span></code></p></td>
|
||
<td><p>MemPool</p></td>
|
||
<td><p>Tests for <a class="reference internal" href="Developer_utils.html#_CPPv4N9LAMMPS_NS6MyPageE" title="LAMMPS_NS::MyPage"><code class="xref cpp cpp-class docutils literal notranslate"><span class="pre">MyPage</span></code></a> and <a class="reference internal" href="Developer_utils.html#_CPPv4N9LAMMPS_NS11MyPoolChunkE" title="LAMMPS_NS::MyPoolChunk"><code class="xref cpp cpp-class docutils literal notranslate"><span class="pre">MyPoolChunk</span></code></a></p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">test_tokenizer.cpp</span></code></p></td>
|
||
<td><p>Tokenizer</p></td>
|
||
<td><p>Tests for <a class="reference internal" href="Developer_utils.html#_CPPv4N9LAMMPS_NS9TokenizerE" title="LAMMPS_NS::Tokenizer"><code class="xref cpp cpp-class docutils literal notranslate"><span class="pre">Tokenizer</span></code></a> and <a class="reference internal" href="Developer_utils.html#_CPPv4N9LAMMPS_NS14ValueTokenizerE" title="LAMMPS_NS::ValueTokenizer"><code class="xref cpp cpp-class docutils literal notranslate"><span class="pre">ValueTokenizer</span></code></a></p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">test_utils.cpp</span></code></p></td>
|
||
<td><p>Utils</p></td>
|
||
<td><p>Tests for <code class="docutils literal notranslate"><span class="pre">utils::</span></code> <a class="reference internal" href="Developer_utils.html"><span class="doc">functions</span></a></p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>To add tests either an existing source file needs to be modified or a
|
||
new source file needs to be added to the distribution and enabled for
|
||
testing. To add a new file suitable CMake script code needs to be added
|
||
to the <code class="docutils literal notranslate"><span class="pre">CMakeLists.txt</span></code> file in the <code class="docutils literal notranslate"><span class="pre">unittest/utils</span></code> folder. Example:</p>
|
||
<div class="highlight-cmake notranslate"><div class="highlight"><pre><span></span><span class="nb">add_executable</span><span class="p">(</span><span class="s">test_tokenizer</span><span class="w"> </span><span class="s">test_tokenizer.cpp</span><span class="p">)</span>
|
||
<span class="nb">target_link_libraries</span><span class="p">(</span><span class="s">test_tokenizer</span><span class="w"> </span><span class="s">PRIVATE</span><span class="w"> </span><span class="s">lammps</span><span class="w"> </span><span class="s">GTest::GMockMain</span><span class="w"> </span><span class="s">GTest::GMock</span><span class="w"> </span><span class="s">GTest::GTest</span><span class="p">)</span>
|
||
<span class="nb">add_test</span><span class="p">(</span><span class="s">Tokenizer</span><span class="w"> </span><span class="s">test_tokenizer</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This adds instructions to build the <code class="docutils literal notranslate"><span class="pre">test_tokenizer</span></code> executable from
|
||
<code class="docutils literal notranslate"><span class="pre">test_tokenizer.cpp</span></code> and links it with the GoogleTest libraries and the
|
||
LAMMPS library as well as it uses the <code class="docutils literal notranslate"><span class="pre">main()</span></code> function from the
|
||
GoogleMock library of GoogleTest. The third line registers the executable
|
||
as a test program to be run from <code class="docutils literal notranslate"><span class="pre">ctest</span></code> under the name <code class="docutils literal notranslate"><span class="pre">Tokenizer</span></code>.</p>
|
||
<p>The test executable itself will execute multiple individual tests
|
||
through the GoogleTest framework. In this case each test consists of
|
||
creating a tokenizer class instance with a given string and explicit or
|
||
default separator choice, and then executing member functions of the
|
||
class and comparing their results with expected values. A few examples:</p>
|
||
<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">TEST</span><span class="p">(</span><span class="n">Tokenizer</span><span class="p">,</span><span class="w"> </span><span class="n">empty_string</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="w"> </span><span class="n">Tokenizer</span><span class="w"> </span><span class="n">t</span><span class="p">(</span><span class="s">""</span><span class="p">,</span><span class="w"> </span><span class="s">" "</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="n">ASSERT_EQ</span><span class="p">(</span><span class="n">t</span><span class="p">.</span><span class="n">count</span><span class="p">(),</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="n">TEST</span><span class="p">(</span><span class="n">Tokenizer</span><span class="p">,</span><span class="w"> </span><span class="n">two_words</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="w"> </span><span class="n">Tokenizer</span><span class="w"> </span><span class="n">t</span><span class="p">(</span><span class="s">"test word"</span><span class="p">,</span><span class="w"> </span><span class="s">" "</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="n">ASSERT_EQ</span><span class="p">(</span><span class="n">t</span><span class="p">.</span><span class="n">count</span><span class="p">(),</span><span class="w"> </span><span class="mi">2</span><span class="p">);</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="n">TEST</span><span class="p">(</span><span class="n">Tokenizer</span><span class="p">,</span><span class="w"> </span><span class="n">default_separators</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="w"> </span><span class="n">Tokenizer</span><span class="w"> </span><span class="n">t</span><span class="p">(</span><span class="s">" </span><span class="se">\r\n</span><span class="s"> test </span><span class="se">\t</span><span class="s"> word </span><span class="se">\f</span><span class="s">"</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="n">ASSERT_THAT</span><span class="p">(</span><span class="n">t</span><span class="p">.</span><span class="n">next</span><span class="p">(),</span><span class="w"> </span><span class="n">Eq</span><span class="p">(</span><span class="s">"test"</span><span class="p">));</span>
|
||
<span class="w"> </span><span class="n">ASSERT_THAT</span><span class="p">(</span><span class="n">t</span><span class="p">.</span><span class="n">next</span><span class="p">(),</span><span class="w"> </span><span class="n">Eq</span><span class="p">(</span><span class="s">"word"</span><span class="p">));</span>
|
||
<span class="w"> </span><span class="n">ASSERT_EQ</span><span class="p">(</span><span class="n">t</span><span class="p">.</span><span class="n">count</span><span class="p">(),</span><span class="w"> </span><span class="mi">2</span><span class="p">);</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Each of these TEST functions will become an individual
|
||
test run by the test program. When using the <code class="docutils literal notranslate"><span class="pre">ctest</span></code>
|
||
command as a front end to run the tests, their output
|
||
will be suppressed and only a summary printed, but adding
|
||
the ‘-V’ option will then produce output from the tests
|
||
above like the following:</p>
|
||
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">[...]</span>
|
||
<span class="go">1: [ RUN ] Tokenizer.empty_string</span>
|
||
<span class="go">1: [ OK ] Tokenizer.empty_string (0 ms)</span>
|
||
<span class="go">1: [ RUN ] Tokenizer.two_words</span>
|
||
<span class="go">1: [ OK ] Tokenizer.two_words (0 ms)</span>
|
||
<span class="go">1: [ RUN ] Tokenizer.default_separators</span>
|
||
<span class="go">1: [ OK ] Tokenizer.default_separators (0 ms)</span>
|
||
<span class="go">[...]</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The MathEigen test collection has been adapted from a standalone test
|
||
and does not use the GoogleTest framework and thus not representative.
|
||
The other test sources, however, can serve as guiding examples for
|
||
additional tests.</p>
|
||
</section>
|
||
<section id="tests-for-individual-lammps-commands">
|
||
<h2><span class="section-number">4.12.2. </span>Tests for individual LAMMPS commands<a class="headerlink" href="#tests-for-individual-lammps-commands" title="Link to this heading"></a></h2>
|
||
<p>The tests <code class="docutils literal notranslate"><span class="pre">unittest/commands</span></code> are a bit more complex as they require
|
||
to first create a <a class="reference internal" href="Classes_lammps.html#_CPPv4N9LAMMPS_NS6LAMMPSE" title="LAMMPS_NS::LAMMPS"><code class="xref cpp cpp-class docutils literal notranslate"><span class="pre">LAMMPS</span></code></a> class instance
|
||
and then use the <a class="reference internal" href="Cplusplus.html"><span class="doc">C++ API</span></a> to pass individual commands
|
||
to that LAMMPS instance. For that reason these tests use a GoogleTest
|
||
“test fixture”, i.e. a class derived from <code class="docutils literal notranslate"><span class="pre">testing::Test</span></code> that will
|
||
create (and delete) the required LAMMPS class instance for each set of
|
||
tests in a <code class="docutils literal notranslate"><span class="pre">TEST_F()</span></code> function. Please see the individual source files
|
||
for different examples of setting up suitable test fixtures. Here is an
|
||
example for implementing a test using a fixture by first checking the
|
||
default value and then issuing LAMMPS commands and checking whether they
|
||
have the desired effect:</p>
|
||
<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">TEST_F</span><span class="p">(</span><span class="n">SimpleCommandsTest</span><span class="p">,</span><span class="w"> </span><span class="n">ResetTimestep</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="w"> </span><span class="n">ASSERT_EQ</span><span class="p">(</span><span class="n">lmp</span><span class="o">-></span><span class="n">update</span><span class="o">-></span><span class="n">ntimestep</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
|
||
|
||
<span class="w"> </span><span class="n">BEGIN_HIDE_OUTPUT</span><span class="p">();</span>
|
||
<span class="w"> </span><span class="n">command</span><span class="p">(</span><span class="s">"reset_timestep 10"</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="n">END_HIDE_OUTPUT</span><span class="p">();</span>
|
||
<span class="w"> </span><span class="n">ASSERT_EQ</span><span class="p">(</span><span class="n">lmp</span><span class="o">-></span><span class="n">update</span><span class="o">-></span><span class="n">ntimestep</span><span class="p">,</span><span class="w"> </span><span class="mi">10</span><span class="p">);</span>
|
||
|
||
<span class="w"> </span><span class="n">BEGIN_HIDE_OUTPUT</span><span class="p">();</span>
|
||
<span class="w"> </span><span class="n">command</span><span class="p">(</span><span class="s">"reset_timestep 0"</span><span class="p">);</span>
|
||
<span class="w"> </span><span class="n">END_HIDE_OUTPUT</span><span class="p">();</span>
|
||
<span class="w"> </span><span class="n">ASSERT_EQ</span><span class="p">(</span><span class="n">lmp</span><span class="o">-></span><span class="n">update</span><span class="o">-></span><span class="n">ntimestep</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
|
||
|
||
<span class="w"> </span><span class="n">TEST_FAILURE</span><span class="p">(</span><span class="s">".*ERROR: Timestep must be >= 0.*"</span><span class="p">,</span><span class="w"> </span><span class="n">command</span><span class="p">(</span><span class="s">"reset_timestep -10"</span><span class="p">););</span>
|
||
<span class="w"> </span><span class="n">TEST_FAILURE</span><span class="p">(</span><span class="s">".*ERROR: Illegal reset_timestep .*"</span><span class="p">,</span><span class="w"> </span><span class="n">command</span><span class="p">(</span><span class="s">"reset_timestep"</span><span class="p">););</span>
|
||
<span class="w"> </span><span class="n">TEST_FAILURE</span><span class="p">(</span><span class="s">".*ERROR: Illegal reset_timestep .*"</span><span class="p">,</span><span class="w"> </span><span class="n">command</span><span class="p">(</span><span class="s">"reset_timestep 10 10"</span><span class="p">););</span>
|
||
<span class="w"> </span><span class="n">TEST_FAILURE</span><span class="p">(</span><span class="s">".*ERROR: Expected integer .*"</span><span class="p">,</span><span class="w"> </span><span class="n">command</span><span class="p">(</span><span class="s">"reset_timestep xxx"</span><span class="p">););</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Please note the use of the <code class="docutils literal notranslate"><span class="pre">BEGIN_HIDE_OUTPUT</span></code> and <code class="docutils literal notranslate"><span class="pre">END_HIDE_OUTPUT</span></code>
|
||
functions that will capture output from running LAMMPS. This is normally
|
||
discarded but by setting the verbose flag (via setting the <code class="docutils literal notranslate"><span class="pre">TEST_ARGS</span></code>
|
||
environment variable, <code class="docutils literal notranslate"><span class="pre">TEST_ARGS=-v</span></code>) it can be printed and used to
|
||
understand why tests fail unexpectedly.</p>
|
||
<p>The specifics of so-called “death tests”, i.e. conditions where LAMMPS
|
||
should fail and throw an exception, are implemented in the
|
||
<code class="docutils literal notranslate"><span class="pre">TEST_FAILURE()</span></code> macro. These tests operate by capturing the screen
|
||
output when executing the failing command and then comparing that with a
|
||
provided regular expression string pattern. Example:</p>
|
||
<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">TEST_F</span><span class="p">(</span><span class="n">SimpleCommandsTest</span><span class="p">,</span><span class="w"> </span><span class="n">UnknownCommand</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="w"> </span><span class="n">TEST_FAILURE</span><span class="p">(</span><span class="s">".*ERROR: Unknown command.*"</span><span class="p">,</span><span class="w"> </span><span class="n">lmp</span><span class="o">-></span><span class="n">input</span><span class="o">-></span><span class="n">one</span><span class="p">(</span><span class="s">"XXX one two"</span><span class="p">););</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The following test programs are currently available:</p>
|
||
<table class="docutils align-left">
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>File name:</p></th>
|
||
<th class="head"><p>Test name:</p></th>
|
||
<th class="head"><p>Description:</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">test_simple_commands.cpp</span></code></p></td>
|
||
<td><p>SimpleCommands</p></td>
|
||
<td><p>Tests for LAMMPS commands that do not require a box</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">test_lattice_region.cpp</span></code></p></td>
|
||
<td><p>LatticeRegion</p></td>
|
||
<td><p>Tests to validate the <a class="reference internal" href="lattice.html"><span class="doc">lattice</span></a> and <a class="reference internal" href="region.html"><span class="doc">region</span></a> commands</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">test_groups.cpp</span></code></p></td>
|
||
<td><p>GroupTest</p></td>
|
||
<td><p>Tests to validate the <a class="reference internal" href="group.html"><span class="doc">group</span></a> command</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">test_variables.cpp</span></code></p></td>
|
||
<td><p>VariableTest</p></td>
|
||
<td><p>Tests to validate the <a class="reference internal" href="variable.html"><span class="doc">variable</span></a> command</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">test_kim_commands.cpp</span></code></p></td>
|
||
<td><p>KimCommands</p></td>
|
||
<td><p>Tests for several commands from the <a class="reference internal" href="Packages_details.html#pkg-kim"><span class="std std-ref">KIM package</span></a></p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">test_reset_atoms.cpp</span></code></p></td>
|
||
<td><p>ResetAtoms</p></td>
|
||
<td><p>Tests to validate the <a class="reference internal" href="reset_atoms.html"><span class="doc">reset_atoms</span></a> sub-commands</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
<section id="tests-for-the-c-style-library-interface">
|
||
<h2><span class="section-number">4.12.3. </span>Tests for the C-style library interface<a class="headerlink" href="#tests-for-the-c-style-library-interface" title="Link to this heading"></a></h2>
|
||
<p>Tests for validating the LAMMPS C-style library interface are in the
|
||
<code class="docutils literal notranslate"><span class="pre">unittest/c-library</span></code> folder. They are implemented either to be used
|
||
for utility functions or for LAMMPS commands, but use the functions
|
||
implemented in the <code class="docutils literal notranslate"><span class="pre">src/library.cpp</span></code> file as much as possible. There
|
||
may be some overlap with other tests, but only in as much as is required
|
||
to test the C-style library API. The tests are distributed over
|
||
multiple test programs which try to match the grouping of the
|
||
functions in the source code and <a class="reference internal" href="Library.html#lammps-c-api"><span class="std std-ref">in the manual</span></a>.</p>
|
||
<p>This group of tests also includes tests invoking LAMMPS in parallel
|
||
through the library interface, provided that LAMMPS was compiled with
|
||
MPI support. These include tests where LAMMPS is run in multi-partition
|
||
mode or only on a subset of the MPI world communicator. The CMake
|
||
script code for adding this kind of test looks like this:</p>
|
||
<div class="highlight-cmake notranslate"><div class="highlight"><pre><span></span><span class="nb">if</span><span class="w"> </span><span class="p">(</span><span class="s">BUILD_MPI</span><span class="p">)</span>
|
||
<span class="w"> </span><span class="nb">add_executable</span><span class="p">(</span><span class="s">test_library_mpi</span><span class="w"> </span><span class="s">test_library_mpi.cpp</span><span class="p">)</span>
|
||
<span class="w"> </span><span class="nb">target_link_libraries</span><span class="p">(</span><span class="s">test_library_mpi</span><span class="w"> </span><span class="s">PRIVATE</span><span class="w"> </span><span class="s">lammps</span><span class="w"> </span><span class="s">GTest::GTest</span><span class="w"> </span><span class="s">GTest::GMock</span><span class="p">)</span>
|
||
<span class="w"> </span><span class="nb">target_compile_definitions</span><span class="p">(</span><span class="s">test_library_mpi</span><span class="w"> </span><span class="s">PRIVATE</span><span class="w"> </span><span class="o">${</span><span class="nv">TEST_CONFIG_DEFS</span><span class="o">}</span><span class="p">)</span>
|
||
<span class="w"> </span><span class="nb">add_mpi_test</span><span class="p">(</span><span class="s">NAME</span><span class="w"> </span><span class="s">LibraryMPI</span><span class="w"> </span><span class="s">NUM_PROCS</span><span class="w"> </span><span class="s">4</span><span class="w"> </span><span class="s">COMMAND</span><span class="w"> </span><span class="o">$<</span><span class="nv">TARGET_FILE:test_library_mpi</span><span class="o">></span><span class="p">)</span>
|
||
<span class="nb">endif</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Note the custom function <code class="docutils literal notranslate"><span class="pre">add_mpi_test()</span></code> which adapts how <code class="docutils literal notranslate"><span class="pre">ctest</span></code>
|
||
will execute the test so it is launched in parallel (with 4 MPI ranks).</p>
|
||
</section>
|
||
<section id="tests-for-the-python-module-and-package">
|
||
<h2><span class="section-number">4.12.4. </span>Tests for the Python module and package<a class="headerlink" href="#tests-for-the-python-module-and-package" title="Link to this heading"></a></h2>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">unittest/python</span></code> folder contains primarily tests for classes and
|
||
functions in the LAMMPS python module but also for commands in the
|
||
PYTHON package. These tests are only enabled if the necessary
|
||
prerequisites are detected or enabled during configuration and
|
||
compilation of LAMMPS (shared library build enabled, Python interpreter
|
||
found, Python development files found).</p>
|
||
<p>The Python tests are implemented using the <code class="docutils literal notranslate"><span class="pre">unittest</span></code> standard Python
|
||
module and split into multiple files with similar categories as the
|
||
tests for the C-style library interface.</p>
|
||
</section>
|
||
<section id="tests-for-the-fortran-interface">
|
||
<h2><span class="section-number">4.12.5. </span>Tests for the Fortran interface<a class="headerlink" href="#tests-for-the-fortran-interface" title="Link to this heading"></a></h2>
|
||
<p>Tests for using the Fortran module are in the <code class="docutils literal notranslate"><span class="pre">unittest/fortran</span></code>
|
||
folder. Since they are also using the GoogleTest library, they require
|
||
implementing test wrappers in C++ that will call fortran functions
|
||
which provide a C function interface through ISO_C_BINDINGS that will in
|
||
turn call the functions in the LAMMPS Fortran module.</p>
|
||
</section>
|
||
<section id="id1">
|
||
<h2><span class="section-number">4.12.6. </span>Tests for the C++-style library interface<a class="headerlink" href="#id1" title="Link to this heading"></a></h2>
|
||
<p>The tests in the <code class="docutils literal notranslate"><span class="pre">unittest/cplusplus</span></code> folder are somewhat similar to
|
||
the tests for the C-style library interface, but do not need to test the
|
||
several convenience and utility functions that are only available through
|
||
the C-style interface. Instead it can focus on the more generic features
|
||
that are used internally. This part of the unit tests is currently still
|
||
mostly in the planning stage.</p>
|
||
</section>
|
||
<section id="tests-for-reading-and-writing-file-formats">
|
||
<h2><span class="section-number">4.12.7. </span>Tests for reading and writing file formats<a class="headerlink" href="#tests-for-reading-and-writing-file-formats" title="Link to this heading"></a></h2>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">unittest/formats</span></code> folder contains test programs for reading and
|
||
writing files like data files, restart files, potential files or dump files.
|
||
This covers simple things like the file i/o convenience functions in the
|
||
<code class="docutils literal notranslate"><span class="pre">utils::</span></code> namespace to complex tests of atom styles where creating and
|
||
deleting atoms with different properties is tested in different ways
|
||
and through script commands or reading and writing of data or restart files.</p>
|
||
</section>
|
||
<section id="tests-for-styles-computing-or-modifying-forces">
|
||
<h2><span class="section-number">4.12.8. </span>Tests for styles computing or modifying forces<a class="headerlink" href="#tests-for-styles-computing-or-modifying-forces" title="Link to this heading"></a></h2>
|
||
<p>These are tests common configurations for pair styles, bond styles,
|
||
angle styles, kspace styles and certain fix styles. Those are tests
|
||
driven by some test executables build from sources in the
|
||
<code class="docutils literal notranslate"><span class="pre">unittest/force-styles</span></code> folder and use LAMMPS input template and data
|
||
files as well as input files in YAML format from the
|
||
<code class="docutils literal notranslate"><span class="pre">unittest/force-styles/tests</span></code> folder. The YAML file names have to
|
||
follow some naming conventions so they get associated with the test
|
||
programs and categorized and listed with canonical names in the list
|
||
of tests as displayed by <code class="docutils literal notranslate"><span class="pre">ctest</span> <span class="pre">-N</span></code>. If you add a new YAML file,
|
||
you need to re-run CMake to update the corresponding list of tests.</p>
|
||
<p>A minimal YAML file for a (molecular) pair style test will looks
|
||
something like the following (see <code class="docutils literal notranslate"><span class="pre">mol-pair-zero.yaml</span></code>):</p>
|
||
<div class="highlight-yaml notranslate"><div class="highlight"><pre><span></span><span class="nn">---</span>
|
||
<span class="nt">lammps_version</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">24 Aug 2020</span>
|
||
<span class="nt">date_generated</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Tue Sep 15 09:44:21 202</span>
|
||
<span class="nt">epsilon</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">1e-14</span>
|
||
<span class="nt">prerequisites</span><span class="p">:</span><span class="w"> </span><span class="kt">!</span><span class="w"> </span><span class="p p-Indicator">|</span>
|
||
<span class="w"> </span><span class="no">atom full</span>
|
||
<span class="w"> </span><span class="no">pair zero</span>
|
||
<span class="nt">pre_commands</span><span class="p">:</span><span class="w"> </span><span class="kt">!</span><span class="w"> </span><span class="s">""</span>
|
||
<span class="nt">post_commands</span><span class="p">:</span><span class="w"> </span><span class="kt">!</span><span class="w"> </span><span class="s">""</span>
|
||
<span class="nt">input_file</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">in.fourmol</span>
|
||
<span class="nt">pair_style</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">zero 8.0</span>
|
||
<span class="nt">pair_coeff</span><span class="p">:</span><span class="w"> </span><span class="kt">!</span><span class="w"> </span><span class="p p-Indicator">|</span>
|
||
<span class="w"> </span><span class="no">* *</span>
|
||
<span class="nt">extract</span><span class="p">:</span><span class="w"> </span><span class="kt">!</span><span class="w"> </span><span class="s">""</span>
|
||
<span class="nt">natoms</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">29</span>
|
||
<span class="nt">init_vdwl</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">0</span>
|
||
<span class="nt">init_coul</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">0</span>
|
||
|
||
<span class="p p-Indicator">[</span><span class="nv">...</span><span class="p p-Indicator">]</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The following table describes the available keys and their purpose for
|
||
testing pair styles:</p>
|
||
<table class="docutils align-default">
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>Key:</p></th>
|
||
<th class="head"><p>Description:</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p>lammps_version</p></td>
|
||
<td><p>LAMMPS version used to last update the reference data</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p>date_generated</p></td>
|
||
<td><p>date when the file was last updated</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p>epsilon</p></td>
|
||
<td><p>base value for the relative precision required for tests to pass</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p>prerequisites</p></td>
|
||
<td><p>list of style kind / style name pairs required to run the test</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p>pre_commands</p></td>
|
||
<td><p>LAMMPS commands to be executed before the input template file is read</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p>post_commands</p></td>
|
||
<td><p>LAMMPS commands to be executed right before the actual tests</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p>input_file</p></td>
|
||
<td><p>LAMMPS input file template based on pair style zero</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p>pair_style</p></td>
|
||
<td><p>arguments to the pair_style command to be tested</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p>pair_coeff</p></td>
|
||
<td><p>list of pair_coeff arguments to set parameters for the input template</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p>extract</p></td>
|
||
<td><p>list of keywords supported by <code class="docutils literal notranslate"><span class="pre">Pair::extract()</span></code> and their dimension</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p>natoms</p></td>
|
||
<td><p>number of atoms in the input file template</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p>init_vdwl</p></td>
|
||
<td><p>non-Coulomb pair energy after “run 0”</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p>init_coul</p></td>
|
||
<td><p>Coulomb pair energy after “run 0”</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p>init_stress</p></td>
|
||
<td><p>stress tensor after “run 0”</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p>init_forces</p></td>
|
||
<td><p>forces on atoms after “run 0”</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p>run_vdwl</p></td>
|
||
<td><p>non-Coulomb pair energy after “run 4”</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p>run_coul</p></td>
|
||
<td><p>Coulomb pair energy after “run 4”</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p>run_stress</p></td>
|
||
<td><p>stress tensor after “run 4”</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p>run_forces</p></td>
|
||
<td><p>forces on atoms after “run 4”</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>The test program will read all this data from the YAML file and then
|
||
create a LAMMPS instance, apply the settings/commands from the YAML file
|
||
as needed and then issue a “run 0” command, write out a restart file, a
|
||
data file and a coeff file. The actual test will then compare computed
|
||
energies, stresses, and forces with the reference data, issue a “run 4”
|
||
command and compare to the second set of reference data. This will be
|
||
run with both the newton_pair setting enabled and disabled and is
|
||
expected to generate the same results (allowing for some numerical
|
||
noise). Then it will restart from the previously generated restart and
|
||
compare with the reference and also start from the data file. A final
|
||
check will use multi-cutoff r-RESPA (if supported by the pair style) at
|
||
a 1:1 split and compare to the Verlet results. These sets of tests are
|
||
run with multiple test fixtures for accelerated styles (OPT, OPENMP,
|
||
INTEL, KOKKOS (OpenMP only)) and for the latter three with 4 OpenMP
|
||
threads enabled. For these tests the relative error (epsilon) is lowered
|
||
by a common factor due to the additional numerical noise, but the tests
|
||
are still comparing to the same reference data.</p>
|
||
<p>Additional tests will check whether all listed extract keywords are
|
||
supported and have the correct dimensionality and the final set of tests
|
||
will set up a few pairs of atoms explicitly and in such a fashion that
|
||
the forces on the atoms computed from <code class="docutils literal notranslate"><span class="pre">Pair::compute()</span></code> will match
|
||
individually with the results from <code class="docutils literal notranslate"><span class="pre">Pair::single()</span></code>, if the pair style
|
||
does support that functionality.</p>
|
||
<p>With this scheme a large fraction of the code of any tested pair style
|
||
will be executed and consistent results are required for different
|
||
settings and between different accelerated pair style variants and the
|
||
base class, as well as for computing individual pairs through the
|
||
<code class="docutils literal notranslate"><span class="pre">Pair::single()</span></code> method where supported.</p>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">test_pair_style</span></code> tester is used with 4 categories of test inputs:</p>
|
||
<ul class="simple">
|
||
<li><p>pair styles compatible with molecular systems using bonded
|
||
interactions and exclusions. For pair styles requiring a KSpace style
|
||
the KSpace computations are disabled. The YAML files match the
|
||
pattern “mol-pair-*.yaml” and the tests are correspondingly labeled
|
||
with “MolPairStyle:*”</p></li>
|
||
<li><p>pair styles not compatible with the previous input template.
|
||
The YAML files match the pattern “atomic-pair-*.yaml” and the tests are
|
||
correspondingly labeled with “AtomicPairStyle:*”</p></li>
|
||
<li><p>manybody pair styles.
|
||
The YAML files match the pattern “atomic-pair-*.yaml” and the tests are
|
||
correspondingly labeled with “AtomicPairStyle:*”</p></li>
|
||
<li><p>kspace styles.
|
||
The YAML files match the pattern “kspace-*.yaml” and the tests are
|
||
correspondingly labeled with “KSpaceStyle:*”. In these cases a compatible
|
||
pair style is defined, but the computation of the pair style contributions
|
||
is disabled.</p></li>
|
||
</ul>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">test_bond_style</span></code>, <code class="docutils literal notranslate"><span class="pre">test_angle_style</span></code>, <code class="docutils literal notranslate"><span class="pre">test_dihedral_style</span></code>, and
|
||
<code class="docutils literal notranslate"><span class="pre">test_improper_style</span></code> tester programs are set up in a similar fashion and
|
||
share support functions with the pair style tester. The final group of
|
||
tests in this section is for fix styles that add/manipulate forces and
|
||
velocities, e.g. for time integration, thermostats and more.</p>
|
||
<p>Adding a new test is easiest done by copying and modifying an existing YAML
|
||
file for a style that is similar to one to be tested. The file name should
|
||
follow the naming conventions described above and after copying the file,
|
||
the first step is to replace the style names where needed. The coefficient
|
||
values do not have to be meaningful, just in a reasonable range for the
|
||
given system. It does not matter if some forces are large, as long as
|
||
they do not diverge.</p>
|
||
<p>The template input files define a large number of index variables at the top
|
||
that can be modified inside the YAML file to control the behavior. For example,
|
||
if a pair style requires a “newton on” setting, the following can be used in
|
||
as the “pre_commands” section:</p>
|
||
<div class="highlight-yaml notranslate"><div class="highlight"><pre><span></span><span class="nt">pre_commands</span><span class="p">:</span><span class="w"> </span><span class="kt">!</span><span class="w"> </span><span class="p p-Indicator">|</span>
|
||
<span class="w"> </span><span class="no">variable newton_pair delete</span>
|
||
<span class="w"> </span><span class="no">variable newton_pair index on</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>And for a pair style requiring a kspace solver the following would be used as
|
||
the “post_commands” section:</p>
|
||
<div class="highlight-yaml notranslate"><div class="highlight"><pre><span></span><span class="nt">post_commands</span><span class="p">:</span><span class="w"> </span><span class="kt">!</span><span class="w"> </span><span class="p p-Indicator">|</span>
|
||
<span class="w"> </span><span class="no">pair_modify table 0</span>
|
||
<span class="w"> </span><span class="no">kspace_style pppm/tip4p 1.0e-6</span>
|
||
<span class="w"> </span><span class="no">kspace_modify gewald 0.3</span>
|
||
<span class="w"> </span><span class="no">kspace_modify compute no</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Note that this disables computing the kspace contribution, but still will run
|
||
the setup. The “gewald” parameter should be set explicitly to speed up the run.
|
||
For styles with long-range electrostatics, typically two tests are added one using
|
||
the (slower) analytic approximation of the erfc() function and the other using
|
||
the tabulated coulomb, to test both code paths. The reference results in the YAML
|
||
files then should be compared manually, if they agree well enough within the limits
|
||
of those two approximations.</p>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">test_pair_style</span></code> and equivalent programs have special command-line options
|
||
to update the YAML files. Running a command like</p>
|
||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>test_pair_style<span class="w"> </span>mol-pair-lennard_mdf.yaml<span class="w"> </span>-g<span class="w"> </span>new.yaml
|
||
</pre></div>
|
||
</div>
|
||
<p>will read the settings from the <code class="docutils literal notranslate"><span class="pre">mol-pair-lennard_mdf.yaml</span></code> file and then compute
|
||
the reference data and write a new file with to <code class="docutils literal notranslate"><span class="pre">new.yaml</span></code>. If this step fails,
|
||
there are likely some (LAMMPS or YAML) syntax issues in the YAML file that need to
|
||
be resolved and then one can compare the two files to see if the output is as expected.</p>
|
||
<p>It is also possible to do an update in place with:</p>
|
||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>test_pair_style<span class="w"> </span>mol-pair-lennard_mdf.yaml<span class="w"> </span>-u
|
||
</pre></div>
|
||
</div>
|
||
<p>And one can finally run the full set of tests with:</p>
|
||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>test_pair_style<span class="w"> </span>mol-pair-lennard_mdf.yaml
|
||
</pre></div>
|
||
</div>
|
||
<p>This will just print a summary of the groups of tests. When using the “-v” flag
|
||
the test will also keep any LAMMPS output and when using the “-s” flag, there
|
||
will be some statistics reported on the relative errors for the individual checks
|
||
which can help to figure out what would be a good choice of the epsilon parameter.
|
||
It should be as small as possible to catch any unintended side effects from changes
|
||
elsewhere, but large enough to accommodate the numerical noise due to the implementation
|
||
of the potentials and differences in compilers.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>These kinds of tests can be very sensitive to compiler optimization and
|
||
thus the expectation is that they pass with compiler optimization turned
|
||
off. When compiler optimization is enabled, there may be some failures, but
|
||
one has to carefully check whether those are acceptable due to the enhanced
|
||
numerical noise from reordering floating-point math operations or due to
|
||
the compiler mis-compiling the code. That is not always obvious.</p>
|
||
</div>
|
||
</section>
|
||
<section id="tests-for-programs-in-the-tools-folder">
|
||
<h2><span class="section-number">4.12.9. </span>Tests for programs in the tools folder<a class="headerlink" href="#tests-for-programs-in-the-tools-folder" title="Link to this heading"></a></h2>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">unittest/tools</span></code> folder contains tests for programs in the
|
||
<code class="docutils literal notranslate"><span class="pre">tools</span></code> folder. This currently only contains tests for the LAMMPS
|
||
shell, which are implemented as a python scripts using the <code class="docutils literal notranslate"><span class="pre">unittest</span></code>
|
||
Python module and launching the tool commands through the <code class="docutils literal notranslate"><span class="pre">subprocess</span></code>
|
||
Python module.</p>
|
||
</section>
|
||
<section id="troubleshooting-failed-unit-tests">
|
||
<h2><span class="section-number">4.12.10. </span>Troubleshooting failed unit tests<a class="headerlink" href="#troubleshooting-failed-unit-tests" title="Link to this heading"></a></h2>
|
||
<p>The are by default no unit tests for newly added features (e.g. pair, fix,
|
||
or compute styles) unless your pull request also includes tests for the
|
||
added features. If you are modifying some features, you may see failures
|
||
for existing tests, if your modifications have some unexpected side effects
|
||
or your changes render the existing test invalid. If you are adding an
|
||
accelerated version of an existing style, then only tests for INTEL,
|
||
KOKKOS (with OpenMP only), OPENMP, and OPT will be run automatically.
|
||
Tests for the GPU package are time consuming and thus are only run
|
||
<em>after</em> a merge, or when a special label, <code class="docutils literal notranslate"><span class="pre">gpu_unit_tests</span></code> is added
|
||
to the pull request. After the test has started, it is often best to
|
||
remove the label since every PR activity will re-trigger the test (that
|
||
is a limitation of triggering a test with a label). Support for unit
|
||
tests when using KOKKOS with GPU acceleration is currently not supported.</p>
|
||
<p>When you see a failed build on GitHub, click on <code class="docutils literal notranslate"><span class="pre">Details</span></code> to be taken
|
||
to the corresponding LAMMPS Jenkins CI web page. Click on the “Exit”
|
||
symbol near the <code class="docutils literal notranslate"><span class="pre">Logout</span></code> button on the top right of that page to go to
|
||
the “classic view”. In the classic view, there is a list of the
|
||
individual runs that make up this test run (they are shown but cannot be
|
||
inspected in the default view). You can click on any of those.
|
||
Clicking on <code class="docutils literal notranslate"><span class="pre">Test</span> <span class="pre">Result</span></code> will display the list of failed tests. Click
|
||
on the “Status” column to sort the tests based on their Failed or Passed
|
||
status. Then click on the failed test to expand its output.</p>
|
||
<p>For example, the following output snippet shows the failed unit test</p>
|
||
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">[ RUN ] PairStyle.gpu</span>
|
||
<span class="go">/home/builder/workspace/dev/pull_requests/ubuntu_gpu/unit_tests/cmake_gpu_opencl_mixed_smallbig_clang_static/unittest/force-styles/test_main.cpp:63: Failure</span>
|
||
<span class="go">Expected: (err) <= (epsilon)</span>
|
||
<span class="go">Actual: 0.00018957912910606503 vs 0.0001</span>
|
||
<span class="go">Google Test trace:</span>
|
||
<span class="go">/home/builder/workspace/dev/pull_requests/ubuntu_gpu/unit_tests/cmake_gpu_opencl_mixed_smallbig_clang_static/unittest/force-styles/test_main.cpp:56: EXPECT_FORCES: init_forces (newton off)</span>
|
||
<span class="go">/home/builder/workspace/dev/pull_requests/ubuntu_gpu/unit_tests/cmake_gpu_opencl_mixed_smallbig_clang_static/unittest/force-styles/test_main.cpp:64: Failure</span>
|
||
<span class="go">Expected: (err) <= (epsilon)</span>
|
||
<span class="go">Actual: 0.00022892713393549854 vs 0.0001</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The failed assertions provide line numbers in the test source
|
||
(e.g. <code class="docutils literal notranslate"><span class="pre">test_main.cpp:56</span></code>), from which one can understand what
|
||
specific assertion failed.</p>
|
||
<p>Note that the force style engine runs one of a small number of systems
|
||
in a rather off-equilibrium configuration with a few atoms for a few
|
||
steps, writes data and restart files, uses <a class="reference internal" href="clear.html"><span class="doc">the clear command</span></a> to reset LAMMPS, and then runs from those files with different
|
||
settings (e.g. newton on/off) and integrators (e.g. verlet vs. respa).
|
||
Beyond potential issues/bugs in the source code, the mismatch between
|
||
the expected and actual values could be that force arrays are not
|
||
properly cleared between multiple run commands or that class members are
|
||
not correctly initialized or written to or read from a data or restart
|
||
file.</p>
|
||
<p>While the epsilon (relative precision) for a single, <a class="reference external" href="https://en.wikipedia.org/wiki/IEEE_754">IEEE 754 compliant</a>, double precision floating
|
||
point operation is at about 2.2e-16, the achievable precision for the
|
||
tests is lower due to most numbers being sums over intermediate results
|
||
and the non-associativity of floating point math leading to larger
|
||
errors. As a rule of thumb, the test epsilon can often be in the range
|
||
5.0e-14 to 1.0e-13. But for “noisy” force kernels, e.g. those a larger
|
||
amount of arithmetic operations involving <cite>exp()</cite>, <cite>log()</cite> or <cite>sin()</cite>
|
||
functions, and also due to the effect of compiler optimization or differences
|
||
between compilers or platforms, epsilon may need to be further relaxed,
|
||
sometimes epsilon can be relaxed to 1.0e-12. If interpolation or lookup
|
||
tables are used, epsilon may need to be set to 1.0e-10 or even higher.
|
||
For tests of accelerated styles, the per-test epsilon is multiplied
|
||
by empirical factors that take into account the differences in the order
|
||
of floating point operations or that some or most intermediate operations
|
||
may be done using approximations or with single precision floating point
|
||
math.</p>
|
||
<p>To rerun the failed unit test individually, change to the <code class="docutils literal notranslate"><span class="pre">build</span></code> directory
|
||
and run the test with verbose output. For example,</p>
|
||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>env<span class="w"> </span><span class="nv">TEST_ARGS</span><span class="o">=</span>-v<span class="w"> </span>ctest<span class="w"> </span>-R<span class="w"> </span>^MolPairStyle:lj_cut_coul_long<span class="w"> </span>-V
|
||
</pre></div>
|
||
</div>
|
||
<p><code class="docutils literal notranslate"><span class="pre">ctest</span></code> with the <code class="docutils literal notranslate"><span class="pre">-V</span></code> flag also shows the exact command
|
||
of the test. One can then use <code class="docutils literal notranslate"><span class="pre">gdb</span> <span class="pre">--args</span></code> to further debug and
|
||
catch exceptions with the test command, for example,</p>
|
||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>gdb<span class="w"> </span>--args<span class="w"> </span>/path/to/lammps/build/test_pair_style<span class="w"> </span>/path/to/lammps/unittest/force-styles/tests/mol-pair-lj_cut_coul_long.yaml
|
||
</pre></div>
|
||
</div>
|
||
<p>It is recommended to configure the build with <code class="docutils literal notranslate"><span class="pre">-D</span>
|
||
<span class="pre">BUILD_SHARED_LIBS=on</span></code> and use a custom linker to shorten the build time
|
||
during recompilation. Installing <cite>ccache</cite> in your development
|
||
environment helps speed up recompilation by caching previous
|
||
compilations and detecting when the same compilation is being done
|
||
again. Please see <a class="reference internal" href="Build_development.html"><span class="doc">Development build options</span></a> for further details.</p>
|
||
</section>
|
||
</section>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
|
||
<a href="Developer_plugins.html" class="btn btn-neutral float-left" title="4.11. Writing plugins" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
|
||
<a href="Classes.html" class="btn btn-neutral float-right" title="4.13. C++ base classes" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
|
||
</div>
|
||
|
||
<hr/>
|
||
|
||
<div role="contentinfo">
|
||
<p>© Copyright 2003-2025 Sandia Corporation.</p>
|
||
</div>
|
||
|
||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||
|
||
|
||
</footer>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
<script>
|
||
jQuery(function () {
|
||
SphinxRtdTheme.Navigation.enable(false);
|
||
});
|
||
</script>
|
||
|
||
</body>
|
||
</html> |