1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
|
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Test Coverage — Cyrus IMAP 3.12.1 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/graphviz.css" type="text/css" />
<link rel="stylesheet" href="../../_static/cyrus.css" type="text/css" />
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
<script src="../../_static/doctools.js"></script>
<script src="../../_static/sphinx_highlight.js"></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="JMAP support" href="jmap.html" />
<link rel="prev" title="Developer Test Environment" href="developer-testing.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="../../index.html" class="icon icon-home">
Cyrus IMAP
</a>
<div class="version">
3.12.1
</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">Cyrus IMAP</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../download.html">Download</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../quickstart.html">Quickstart Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../setup.html">Setup</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../operations.html">Operations</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../../developers.html">Developers</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../../contribute.html">We need your help</a></li>
<li class="toctree-l2"><a class="reference internal" href="documentation.html">Contribute docs</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="../developer.html">Contribute code and tests</a><ul class="current">
<li class="toctree-l3 current"><a class="reference internal" href="../developer.html#getting-started">Getting Started</a><ul class="current">
<li class="toctree-l4"><a class="reference internal" href="process.html">Development Process</a></li>
<li class="toctree-l4"><a class="reference internal" href="overview.html">Overview of Cyrus development environment</a></li>
<li class="toctree-l4"><a class="reference internal" href="github-guide.html">GitHub guide</a></li>
<li class="toctree-l4"><a class="reference internal" href="compiling.html">Compiling</a></li>
<li class="toctree-l4"><a class="reference internal" href="../installing.html">Installing Cyrus</a></li>
<li class="toctree-l4"><a class="reference internal" href="developer-testing.html">Developer Test Environment</a></li>
<li class="toctree-l4 current"><a class="current reference internal" href="#">Test Coverage</a></li>
<li class="toctree-l4"><a class="reference internal" href="jmap.html">JMAP support</a></li>
<li class="toctree-l4"><a class="reference internal" href="install-xapian.html">Xapian for searching</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../developer.html#system-files-and-databases">System files and Databases</a></li>
<li class="toctree-l3"><a class="reference internal" href="../developer.html#resources">Resources</a></li>
<li class="toctree-l3"><a class="reference internal" href="../developer.html#releasing">Releasing</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="cyrusworks.html">Cyrus.Works</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../developers.html#cyrus-internals">Cyrus Internals</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../developers.html#unit-tests">Unit Tests</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../support.html">Support/Community</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Cyrus SASL</span></p>
<ul>
<li class="toctree-l1"><a class="reference external" href="http://www.cyrusimap.org/sasl">Cyrus SASL</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="../../index.html">Cyrus IMAP</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="../../index.html" class="icon icon-home" aria-label="Home"></a></li>
<li class="breadcrumb-item"><a href="../../developers.html">Developers</a></li>
<li class="breadcrumb-item"><a href="../developer.html">IMAP Developer Guide</a></li>
<li class="breadcrumb-item active">Test Coverage</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/cyrusimap/cyrus-imapd/blob/master/docsrc/imap/developer/coverage.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="test-coverage">
<span id="coverage"></span><h1>Test Coverage<a class="headerlink" href="#test-coverage" title="Permalink to this heading"></a></h1>
<p>This assumes you have a single user development environment where you can
already build and install Cyrus, and run the CUnit and Cassandane tests. It
also assumes your Cyrus install and Cassandane setup do not use "destdir",
and that your compiler is GCC.</p>
<p>We'll be tinkering with group membership and file permissions, so proceed
with caution on multi-user systems.</p>
<p>When a coverage-enabled binary runs, it writes coverage data into <code class="docutils literal notranslate"><span class="pre">foo.gcda</span></code>
files alongside the source files. CUnit runs as you, but Cassandane runs as
cyrus, so we need to arrange for both these users to be able to write to the
source directory. We'll do that using group memberships and the
group-writeable file mode bit.</p>
<section id="one-time-setup">
<h2>One-time setup<a class="headerlink" href="#one-time-setup" title="Permalink to this heading"></a></h2>
<section id="group-membership">
<h3>Group membership<a class="headerlink" href="#group-membership" title="Permalink to this heading"></a></h3>
<ol class="arabic simple">
<li><p>Add the "cyrus" user account to your own user group</p></li>
<li><p>Perhaps: also add your user account to the "cyrus" user's group. This might
be "cyrus" or "mail" depending on how you set your system up. I can't
remember if this is actually necessary for coverage, or if I have it for
something else, so skip it unless it becomes necessary (and update this
doc!)</p></li>
</ol>
</section>
<section id="file-permissions">
<h3>File permissions<a class="headerlink" href="#file-permissions" title="Permalink to this heading"></a></h3>
<ol class="arabic simple">
<li><p>Change into your cyrus-imapd directory: <code class="docutils literal notranslate"><span class="pre">cd</span> <span class="pre">~/path/to/cyrus-imapd</span></code></p></li>
<li><p>Start from a clean state: <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">clean</span> <span class="pre">-xfd</span></code></p></li>
<li><p>Set the group-writeable bit on everything: <code class="docutils literal notranslate"><span class="pre">chmod</span> <span class="pre">-R</span> <span class="pre">g+w</span> <span class="pre">.</span></code></p></li>
<li><p>Allow the group-writeable bit on new files you create: <code class="docutils literal notranslate"><span class="pre">umask</span> <span class="pre">0002</span></code></p></li>
<li><p>Add that <code class="docutils literal notranslate"><span class="pre">umask</span> <span class="pre">0002</span></code> line to your .bashrc or equivalent too, otherwise
you'll have to remember to fix up file permissions every time you want to
make a coverage report</p></li>
</ol>
</section>
<section id="dependencies">
<h3>Dependencies<a class="headerlink" href="#dependencies" title="Permalink to this heading"></a></h3>
<p>You'll need the <code class="docutils literal notranslate"><span class="pre">lcov</span></code> and <code class="docutils literal notranslate"><span class="pre">genhtml</span></code> tools for producing human-readable
reports. On Debian, these are both found in the <code class="docutils literal notranslate"><span class="pre">lcov</span></code> package.</p>
</section>
</section>
<section id="preparing-a-coverage-report">
<h2>Preparing a coverage report<a class="headerlink" href="#preparing-a-coverage-report" title="Permalink to this heading"></a></h2>
<section id="compile-cyrus-and-run-cunit-tests">
<h3>Compile Cyrus and run CUnit tests<a class="headerlink" href="#compile-cyrus-and-run-cunit-tests" title="Permalink to this heading"></a></h3>
<p>The collection of coverage data slows things down, and it might also log a lot
of complaints about overwriting old coverage data, or being unable to. So I
do not recommend routinely compiling with coverage enabled -- only do this when
you're preparing a coverage report.</p>
<ol class="arabic simple">
<li><p>Change into your cyrus-imapd directory: <code class="docutils literal notranslate"><span class="pre">cd</span> <span class="pre">~/path/to/cyrus-imapd</span></code></p></li>
<li><p>Start from a clean state: <code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">clean</span> <span class="pre">-xfd</span></code></p></li>
<li><p>Configure Cyrus, using your usual configure options, plus
<code class="docutils literal notranslate"><span class="pre">--enable-coverage</span></code></p></li>
<li><p>Compile Cyrus: <code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">-j4</span></code></p></li>
<li><p>Run the CUnit tests: <code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">-j4</span> <span class="pre">check</span></code></p></li>
<li><p>Install Cyrus (might need sudo): <code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">install</span></code></p></li>
</ol>
</section>
<section id="run-cassandane">
<h3>Run Cassandane<a class="headerlink" href="#run-cassandane" title="Permalink to this heading"></a></h3>
<ol class="arabic simple">
<li><p>Run Cassandane on the installed Cyrus as you usually would</p></li>
</ol>
</section>
<section id="generate-report">
<h3>Generate report<a class="headerlink" href="#generate-report" title="Permalink to this heading"></a></h3>
<p>I'd suggest making a script to automate this part. I use one like <a class="reference external" href="https://github.com/elliefm/cyrus-build-tools/blob/master/cyrus-coverage">this</a></p>
<ol class="arabic">
<li><p>Change into your cyrus-imapd directory: <code class="docutils literal notranslate"><span class="pre">cd</span> <span class="pre">~/path/to/cyrus-imapd</span></code></p></li>
<li><p>Some of the <code class="docutils literal notranslate"><span class="pre">foo.gcda</span></code> files will be owned by your user (from the CUnit
run), some will be owned by the cyrus user (from the Cassandane run).
You can use something like this to reclaim the ownership (if your user:group
is ellie:ellie):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">find</span> <span class="o">.</span> <span class="o">-</span><span class="n">name</span> \<span class="o">*.</span><span class="n">gcda</span> <span class="o">-</span><span class="ow">not</span> <span class="o">-</span><span class="n">user</span> <span class="n">ellie</span> <span class="o">-</span><span class="n">execdir</span> <span class="n">sudo</span> <span class="n">chown</span> <span class="n">ellie</span><span class="p">:</span><span class="n">ellie</span> <span class="s2">"</span><span class="si">{}</span><span class="s2">"</span> <span class="o">+</span>
</pre></div>
</div>
</li>
<li><p>If you want to keep accumulating results, you'll need to ensure the Cyrus
user can still write to those files. I don't know if this is useful, but
something like this will do it:
<code class="docutils literal notranslate"><span class="pre">find</span> <span class="pre">.</span> <span class="pre">-name</span> <span class="pre">\*.gcda</span> <span class="pre">-execdir</span> <span class="pre">chmod</span> <span class="pre">g+rw</span> <span class="pre">"{}"</span> <span class="pre">+</span></code></p></li>
<li><p>Process all those <code class="docutils literal notranslate"><span class="pre">foo.gcda</span></code> files into an intermediate form:
<code class="docutils literal notranslate"><span class="pre">lcov</span> <span class="pre">--directory</span> <span class="pre">.</span> <span class="pre">-c</span> <span class="pre">-o</span> <span class="pre">coverage.info</span></code></p></li>
<li><p>Strip out unit test and external library clutter:
<code class="docutils literal notranslate"><span class="pre">lcov</span> <span class="pre">--remove</span> <span class="pre">coverage.info</span> <span class="pre">"cunit/*"</span> <span class="pre">"/usr/*"</span> <span class="pre">-o</span> <span class="pre">coverage.info</span></code></p></li>
<li><p>Generate HTML:
<code class="docutils literal notranslate"><span class="pre">genhtml</span> <span class="pre">-o</span> <span class="pre">coverage</span> <span class="pre">coverage.info</span></code></p></li>
<li><p>You can now open that report in your browser. Something like this will
give you a link to copy and paste:
<code class="docutils literal notranslate"><span class="pre">echo</span> <span class="pre">file://$PWD/coverage/index.html</span></code></p></li>
</ol>
</section>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="developer-testing.html" class="btn btn-neutral float-left" title="Developer Test Environment" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="jmap.html" class="btn btn-neutral float-right" title="JMAP support" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>© Copyright 1993–2025, The Cyrus Team.</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(true);
});
</script>
</body>
</html>
|