<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>HanLHo. - Fractional Architect &amp; Software Product Engineer - rust</title>
    <link rel="self" type="application/atom+xml" href="https://hanlho.com/tags/rust/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://hanlho.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-06-27T00:00:00+00:00</updated>
    <id>https://hanlho.com/tags/rust/atom.xml</id>
    <entry xml:lang="en">
        <title>Rust code coverage: use &#x27;llvm-cov&#x27; over &#x27;tarpaulin&#x27;</title>
        <published>2025-06-27T00:00:00+00:00</published>
        <updated>2025-06-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://hanlho.com/p/rust-code-coverage-use-llvm-cov-over-tarpaulin/"/>
        <id>https://hanlho.com/p/rust-code-coverage-use-llvm-cov-over-tarpaulin/</id>
        
        <content type="html" xml:base="https://hanlho.com/p/rust-code-coverage-use-llvm-cov-over-tarpaulin/">&lt;p&gt;A few days ago, I wrote about an issue I encountered where the code coverage for one of my projects failed on CI but worked fine locally. &lt;a href=&quot;&#x2F;p&#x2F;rust-when-cargo-code-coverage-works-locally-but-fails-in-ci&#x2F;&quot;&gt;I also discussed a solution&lt;&#x2F;a&gt;. It turns out there&#x27;s an even better alternative: switch code coverage tools entirely and use &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;taiki-e&#x2F;cargo-llvm-cov&quot;&gt;llvm-cov&lt;&#x2F;a&gt; instead of &lt;code&gt;tarpaulin&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The main reasons I switched to &lt;code&gt;llvm-cov&lt;&#x2F;code&gt; are that it feels more modern, and more importantly, the time required to run code coverage improved dramatically—from 4 minutes down to just 1 minute and 30 seconds. One contributing factor was an OpenSSL build dependency in my Cargo configuration, introduced by tarpaulin, which took a long time to compile. (To be fair, I probably could have installed OpenSSL as a binary, but I didn&#x27;t want to introduce another program just for a coverage tool.) Switching to llvm-cov allowed me to remove this redundant dependency, which my project didn&#x27;t really need in the first place.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s it—just a short update I thought was worth sharing.&lt;&#x2F;p&gt;
&lt;p&gt;Thank you for reading,&lt;br &#x2F;&gt;
Hans&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rust: When Cargo Code Coverage Works Locally But Fails in CI</title>
        <published>2025-06-26T00:00:00+00:00</published>
        <updated>2025-06-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://hanlho.com/p/rust-when-cargo-code-coverage-works-locally-but-fails-in-ci/"/>
        <id>https://hanlho.com/p/rust-when-cargo-code-coverage-works-locally-but-fails-in-ci/</id>
        
        <content type="html" xml:base="https://hanlho.com/p/rust-when-cargo-code-coverage-works-locally-but-fails-in-ci/">&lt;p&gt;A short post to help if you run into the same issue.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;TLDR:&lt;&#x2F;strong&gt; If your code coverage reports show vastly different results between local development and CI, explicitly set &lt;code&gt;--engine llvm&lt;&#x2F;code&gt; in your cargo tarpaulin command.&lt;&#x2F;p&gt;
&lt;p&gt;I recently ran into a frustration you may be familiar with: your code works perfectly on your machine, but fails on CI. The most annoying part are the waiting times for CI to finish. You context-switch to other work, if you do not forget, return to debug. It breaks flow and wastes time. Stuff you do not want to be spending time on.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-issue&quot;&gt;The issue&lt;&#x2F;h2&gt;
&lt;p&gt;My Rust code coverage reports were showing different results between local development (94%) and CI (22%). Same codebase, same test suite.&lt;&#x2F;p&gt;
&lt;p&gt;The original cargo command:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#eff1f5;color:#4f5b66;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cargo&lt;&#x2F;span&gt;&lt;span&gt; tarpaulin&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; --out&lt;&#x2F;span&gt;&lt;span&gt; xml
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Relevant in this case: I test most of my functionality in the &lt;code&gt;tests&lt;&#x2F;code&gt; directory (integration&#x2F;acceptance tests) and this is the coverage that seemed to be missing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-solution&quot;&gt;The Solution&lt;&#x2F;h2&gt;
&lt;p&gt;Add the &lt;code&gt;--engine llvm&lt;&#x2F;code&gt; flag to your cargo tarpaulin command:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#eff1f5;color:#4f5b66;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cargo&lt;&#x2F;span&gt;&lt;span&gt; tarpaulin&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; --engine&lt;&#x2F;span&gt;&lt;span&gt; llvm&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; --out&lt;&#x2F;span&gt;&lt;span&gt; xml
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This forces &lt;code&gt;tarpaulin&lt;&#x2F;code&gt; to use the coverage engine &lt;em&gt;that works&lt;&#x2F;em&gt; in all environments.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;explanation&quot;&gt;Explanation&lt;&#x2F;h2&gt;
&lt;p&gt;Cargo tarpaulin uses different default engines on different platforms. On Linux (CI), it defaults to the &lt;code&gt;ptrace&lt;&#x2F;code&gt; engine. On macOS (my local machine), it uses the &lt;code&gt;llvm&lt;&#x2F;code&gt; engine.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;ptrace&lt;&#x2F;code&gt; engine traces system calls to measure coverage. The &lt;code&gt;ptrace&lt;&#x2F;code&gt; engine struggles with tests that spawn subprocesses (like acceptance tests running your compiled binary), whilst the &lt;code&gt;llvm&lt;&#x2F;code&gt; engine handles this correctly.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
