Jekyll2023-12-01T12:01:45+00:00/feed.xmlxd009642Software engineer with a keen interest in C++ and Rust. Using this as a place to talk about my current projects including the Rust code coverage tool tarpaulin
Povception2023-11-30T00:00:00+00:002023-11-30T00:00:00+00:00/2023/11/30/povception<p><em>This is a rehosting of a blog originally on www.rs-online.com where our team won a £1,500 prize for the below project. As it’s now been taken offline I’m preserving it here!</em></p>
<p><em>We also won a single desk calendar to share between 3 people at our employer</em></p>
<p>This project was created by a three-man team comprising of two hardware
engineers and a software engineer. From the very beginning, we knew we
wanted to do something unique and challenging for a Christmas competition. The
idea of trying to get a persistence of vision globe inside another was proposed
and after finding no existing implementations of the idea we began the project.</p>
<p>We already had some of the necessary materials available when we started the
project, including an STM32F469i discovery board and motors borrowed from a
quadcopter. We also had tools and software available to aid in the design and
manufacture of the POVception. These included a laser cutter, metal lathe, 3D
printers, MathWorks Simulink, SolidWorks and a Root3 CNC for milling wood and
etching a PCB.</p>
<p>When designing the mechanical assembly, the need for a front area where the user
would interact and have an unobstructed view of the globes was required. The
globes could not be mounted from the bottom alone due to the size. Therefore,
transparent frames would be at the back and curve up and mount to the top of the
globes to keep it stable and allow people to still view it from the back. Another
initial decision was for the rings to rotate in opposite directions meaning two
motors were required. There wasn’t an engineering reason for this choice, we felt
that it would look impressive when it started spinning up with the LEDs on.</p>
<p><img src="/assets/20231130/schematic.jpg" alt="The PCB Schematic" /></p>
<p>With the assembly modelled we started with milling the baseboards and the rings
out of 18mm thick softwood plywood. We decided to paint these dark grey to
accentuate the lights. We designed the mounts for the boards, motors and power
supply for 3D printing and printed them in ABS using 1.75mm RS Pro filament.
Red was chosen to keep with the Christmas theme and add a nice accent colour to
the finished design. For the transparent frames, we laser cut 3mm acrylic using
two arms for each frame for some added rigidity. Mild steel was used for all the
metal work on the project. This included the axles mounted to the rings and
stand-offs for the two baseboards that sandwiched the electronics. To allow the
inner axle to nicely pass through the outer a metal lathe was used to change
the bore. For the stand-offs, the lathe was used to cut the rods to size and add
a thread to them.</p>
<p>The final part of the assembly was the two game controllers, each one would
have a single joystick to enable the users to play basic games like Pong. To
keep things simple and save time we utilised one of the AdaFruit 2 axis thumb
joystick breakout boards and 3D printed a case for it we found on Thingiverse.
Two existing cables with DE-9 connectors were used with one end of the cable
removed and the wires soldered to the breakout board and the other end remaining
intact to plug into the POVception.</p>
<p>Initially, when thinking about the software, we had concerns with latency and
resolution of the globes. The LED density of the LED strips determines the
vertical resolution and the speed the LEDs can be changed combined with the
motor speed determines the horizontal resolution. For the LED strip solution, we
initially investigated using AdaFruit NeoPixel strips, they were very affordable
but had some flaws. Namely, the strips weren’t clocked and had strict timing
requirements. Because of this, part of the feasibility was whether the timing
could be met with enough slack to perform other software tasks. If timing wasn’t
met the image would end up corrupted and there would be no guarantees about
what was displayed. Another issue with the NeoPixels was the spacing between the
LEDs would restrict the vertical resolution.</p>
<p><img src="/assets/20231130/under.jpg" alt="The view of the electronics from beneath" /></p>
<p>After some experimentation, the NeoPixels were found unsuitable in terms of
throughput, and the SPI driven DotStar LED strips were chosen instead. The
DotStar LED strips had an LED density of 144 LEDs per metre and as they were
driven by SPI the software could asynchronously drive them via DMA transfers.
Looking online we could find no upper limit to the clock speed for the DotStars
and after experimentation found they could be driven at the SPIs maximum speed
of 10MHz with no issue.</p>
<p>Both sides of each ring were also rendered and with only two SPI lines on the
board we had to run the strips from the bottom of one ring going upwards then
from the top of the opposite face running down. The DotStar SPI also ran at 5V
compared to the STM32 running at 3.3V, so to prevent signal integrity issues an
additional PCB was designed and etched to drive the LEDs as well as provide
power to the motors.</p>
<p><img src="/assets/20231130/pcb.jpg" alt="The etched PCB" /></p>
<p>On the software side, it was important the microcontroller didn’t spend time on
blocking calls. The STM32 was responsible for: motor control for two motors,
updating the display frames and rendering the two rings. Additionally, the
discovery board had a touchscreen display featuring a simple GUI which had to
be polled and updated accordingly. The majority of the code was done in C++ with
the STM32 HAL and some ARM Mbed API functions used for interacting with the
hardware.</p>
<p>MathWorks Simulink was utilised in the creation of the project. Given previous
experience with Simulink in control systems, it was decided that it would be used
for the motor control with the main C++ code base providing an interface
between Simulink and the hardware. Using Simulink for control is a natural fit,
however, integrating the generated code into a project involved reading the code
to find the names for functions and structs you need to use. It would have been
preferable and easier to write the code in C++ like the rest of the project –
but then we wouldn’t have met all the requirements.</p>
<p><img src="/assets/20231130/gui.jpg" alt="The POVception with an early version of the GUI" /></p>
<p>With the hardware and assembly done and software being integrated and refined in
the final week some interesting traits were observed. When tracking which column
was being rendered initially a modulus operator was used to ensure the index
never went out of bounds. However, modulus is quite a slow operator so this would
cause the last column to appear wider than the others and cause the display to
jitter left and right. Replacing the modulus with an if statement to check the
bounds and a subtract to move back into the range removed this effect.
Additionally, adding new applications and icons for them in the GUI took up a lot
of flash memory. The touchscreen HAL library supports bitmaps but only if they
were stored in flash, with the POVception finished around 90% of the flash memory
was being used by a mixture of code and resources.</p>
<p>The finished POVception had the following applications:</p>
<ul>
<li>Pong – the most important a classic Pong game. Pong on the inner ring, snowfall effect on outer</li>
<li>Baubles – show a bauble pattern on both rings</li>
<li>Calibration – use the joysticks and set the first column of the displays</li>
<li>Globe – showed the globe on the inner ring with the snowfall effect on the outer ring</li>
</ul>
<p>Of course, no project is ever perfect and there are some obvious things we would have
changed and improved – had we had time. The first thing that comes to mind is that
the HAL library for the touchscreen display only supported one landscape orientation.
We didn’t realise this until after it was fitted and I had to flip all the bitmaps
180 degrees and remove any text printed to the screen. Also, there were some
sporadic software bugs that were discovered for the first time on the demonstration
day. In terms of the physical side, the DotStar strips got very hot and began to
slightly peel off so better thermal management or a better adhesive would have
improved the design.</p>
<p><img src="/assets/20231130/snow.jpg" alt="The globe demo with snowfall on the outer ring" /></p>
<p>Overall, the project was a success and the team was awarded an innovation prize.
We’re all proud of what we managed to achieve in such a small amount of time and
the project met all its aims. The project is largely open-source with the code
currently available on GitHub (link at the end), eventually, the mechanical and
hardware designs will also be uploaded to either GitHub or Thingiverse.</p>
<p>Here’s the code <a href="https://github.com/xd009642/POVception">link</a></p>
<p>Here’s the finished project in action</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/aDJjjcXbvNg?si=QQlcgCp2_kfxbobG" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen=""></iframe>This is a rehosting of a blog originally on www.rs-online.com where our team won a £1,500 prize for the below project. As it’s now been taken offline I’m preserving it here!Tarpaulin And The Futures2019-10-02T00:00:00+00:002019-10-02T00:00:00+00:00/2019/10/02/Tarpaulin-and-the-futures<p><a href="https://github.com/xd009642/tarpaulin">Tarpaulin</a> (or cargo-tarpaulin) is a
code coverage tool for Rust, and anyone who’s used it might know that until
recently it had an issue with code that used futures.</p>
<p>This post is going to go into that issue a bit and the eventual fix. For anyone
who wants the deeper story there’s also the github
<a href="https://github.com/xd009642/tarpaulin/190">issue</a>.</p>
<p>This issue has also existed since January and has had a lot of work so if I
skirt over anything or don’t provide nice logs it’s genuinely because they’ve
been lost in the annals of time and my organisational skills.</p>
<h2 id="a-bit-of-background">A bit of background</h2>
<p>So how does Tarpaulin work? Simply it builds your project with a few special
flags to ensure it can get the necessary information to instrument the binaries.
Then for each binary it will get the lines it can instrument, filter out some
lines based on analysis of the source code and add some extra lines for things
other coverage tools miss i.e. unused generic code.</p>
<p>It then forks, launches the test via <code class="language-plaintext highlighter-rouge">execve</code> so the test starts with the child
PID and uses <code class="language-plaintext highlighter-rouge">ptrace</code> to add breakpoints to the code and uses <code class="language-plaintext highlighter-rouge">waitpid</code> and
<code class="language-plaintext highlighter-rouge">ptrace</code> to follow what the binary is doing and collect the relevant coverage
statistics. After hitting a breakpoint Tarpaulin would count the line, disable
the breakpoint so the program counter can progress, single step and then
re-enable the breakpoint. This was so we could get the hit-rate for a line.</p>
<p>This has all sorts of issues involved, when a test has multiple threads each
thread can be in different places. And sometimes they can be in the same place
(which is where some of the initial issues started). My very first fix was
setting <code class="language-plaintext highlighter-rouge">--test-threads 1</code> when the test executables were launched by Tarpaulin.</p>
<p>The first threading issue found was much older than this one but is the same
general problem. If a thread stops at a breakpoint we know
it’s set so we can disable it, count the hit, single step the thread and
re-enable the breakpoint so we can get the number of line hits.</p>
<p>If two threads hit the same breakpoint at the same time this caused issues
initially. Especially, if the next instruction was also instrumented.</p>
<p>The main reason why was because when you send a continue, or a step command
via ptrace, all the threads in the process react to that signal. Even if you
specify which TID you want to move on!</p>
<p>The first version of tarpaulin didn’t consider how other threads were causing
the instructions to change and would frequently freeze or stall as a result.
This was fixed and not counting line hits was also made default to minimise
other threading quirks and speed up runs.</p>
<p>But there was something else lurking.</p>
<h2 id="the-issue-being-fixed">The issue being fixed</h2>
<p>So an issue is a lot easier when you have a minimal reproducible example, and
for the issue we’re tackling there was this one:</p>
<pre><code class="language-Rust">#[test]
pub fn a() {
futures::executor::ThreadPool::new();
}
#[test]
pub fn b() {
futures::executor::ThreadPool::new();
}
</code></pre>
<p>If we ran this Tarpaulin was guaranteed to report a segfault from the test
binary. After spending a while stumped on this I added a <code class="language-plaintext highlighter-rouge">--debug</code> flag to
tarpaulin that gives any user very detailed logs on all the signals received
and Tarpaulin’s response.</p>
<p>From this I realised something, if all the threads are stopped and step causes
them to all step and execute what they’re doing. If we have a MOV instruction
as below with it’s opcode:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>MOV r/m8,r8 : 88 /r
</code></pre></div></div>
<p>The Opcode would turn into <code class="language-plaintext highlighter-rouge">CC /r</code> and as we have to move the program counter
back one byte reenable the instruction and step to execute it to execute a
valid instruction there’s a potential issue. Any thread that is also stopped on
a breakpoint will be 1 byte ahead of it and will execute a potentially illformed
instruction. Either way this is definitely undefined behaviour.</p>
<p>From this realisation the solution seemed simple, at the start of the Tarpaulin
update loop call <code class="language-plaintext highlighter-rouge">waitpid</code> as many times as it will deliver signals and create a
signal queue. Then for every element of the queue collect the coverage data,
update the breakpoints and push a recommended action onto an action list.</p>
<p>Another foible with ptrace is that when you get a signal from a PID you need to
respond to it in the order you get it. So then I go through the action queue
carrying out the recommended action for every signal.</p>
<p>This was implemented (<code class="language-plaintext highlighter-rouge">src/statemachine/mod.rs</code> and <code class="language-plaintext highlighter-rouge">src/statemachine/linux.rs</code>
for interested parties). I ran it on the test program 10 times and saw no errors
and then ran it on a real world project that had the issue and got the expected
coverage. So that’s it fixed then?</p>
<p>Wrong. Users started reporting the issue persisted. After running for 100 times
I found this occurred 10% of the time on my home machine.</p>
<h2 id="changes-in-rustc">Changes in rustc</h2>
<p>So here’s the point where things slowed down considerably. I was stumped and
also I was in the process of changing job and moving so I had a lot on my plate.
Additionally, debugging from the logs was tedious and I often found myself
drawing long sprawling graphs with the lifetime of a program.</p>
<p>To try and speed up my debugging process I took the code for the update loop
and removed everything else. Used a toml file to specify addresses to instrument
and a path to a binary and made <a href="https://github.com/xd009642/minitarp">minitarp</a>
to generate graphs showing the lifetime of the test. This also let me take the
instrumentation points Tarpaulin derived as a starting point and tweak them
removing some, adding others from reading the dissassembly or DWARF dumps of a
program.</p>
<p>And here is our failing minimal example (but with 4 tests doing the same thing
not 2). <em>Open all images in a new tab, they’re 4K resolution to fit all the
information</em></p>
<p><img src="/assets/20191002/fail.png" alt="A failing test" /></p>
<p>Here the bottom line is the tests PID, all the IDs above are for new threads
spawned. When a thread ends in <code class="language-plaintext highlighter-rouge"><TID>: EXITED 0</code> it’s exited successfully,
otherwise it’s failed. The colours were default from gnuplot so don’t attach
any meaning to them.</p>
<p>We can also see the printouts show any signals tarpaulin received, actions it
received and if it stopped at a breakpoint the breakpoint address.</p>
<p>We can see from this image the 8 threads we expect our first <code class="language-plaintext highlighter-rouge">ThreadPool</code> to
create were created and exited correctly. But then the second test occurs and
we catch the threads being created but none of them exit. Some of them we
also don’t catch the creation event, others we only catch creation and nothing
afterwards.</p>
<p>Eventually, after all 8 threads are created we end up getting our segfault and
the whole thing comes to a halt.</p>
<p>Why is this? Spoiler alert it’s because of <code class="language-plaintext highlighter-rouge">--test-threads 1</code>, and I discovered
it completely by accident. I thought removing the test thread limit would
exacerbate the problem further and help me figure out why I couldn’t see some
threads come into existence. I’d noticed from the test PID line that the first
line of the second test was hit before the threads all exited - eagle eyed
readers can see this point around sample 92 on the timeline.</p>
<p>This is the time to note <code class="language-plaintext highlighter-rouge">TryContinue</code> as an action exists for two reasons.
Sometimes after a thread exits you can get a signal from it which is no longer
valid. It’s best to respond to it to keep everything balanced but if it fails
it’s not an issue. The other instance is for moments when Tarpaulin has reached
a state I didn’t expect so tries to continue to see if it’s a blip.</p>
<p>But none of this explains why <code class="language-plaintext highlighter-rouge">--test-threads 1</code> would cause this! The answer is
naturally in libtest in the rust compiler.</p>
<pre><code class="language-Rust"> if concurrency == 1 {
while !remaining.is_empty() {
let test = remaining.pop().unwrap();
callback(TeWait(test.desc.clone()))?;
run_test(opts, !opts.run_tests, test, run_strategy, tx.clone(), Concurrent::No);
let (test, result, exec_time, stdout) = rx.recv().unwrap();
callback(TeResult(test, result, exec_time, stdout))?;
}
} else {
while pending > 0 || !remaining.is_empty() {
while pending < concurrency && !remaining.is_empty() {
let test = remaining.pop().unwrap();
let timeout = Instant::now() + Duration::from_secs(TEST_WARN_TIMEOUT_S);
running_tests.insert(test.desc.clone(), timeout);
callback(TeWait(test.desc.clone()))?; //here no pad
run_test(opts, !opts.run_tests, test, run_strategy, tx.clone(), Concurrent::Yes);
pending += 1;
}
// More code handling timeouts etc
}
</code></pre>
<p>This code in <code class="language-plaintext highlighter-rouge">libtest/lib.rs</code> at line 1201 (existing as of f2023ac). Is
different from when I first read libtest to figure out some issues. When I first
looked the <code class="language-plaintext highlighter-rouge">if concurrency == 1</code> didn’t exist instead the logic in the <code class="language-plaintext highlighter-rouge">else</code>
statement was used for all the instances. There’s also code further down that
launches tests in a subcommand or in-process. I haven’t quite narrowed down
the exact reasoning behind why it doesn’t work so if anyone has any insight
I’d appreciate it!</p>
<p>To avoid an anti-climatic ending I’ll close with the news that Tarpaulin now
seems to work perfectly with projects using futures and the removal of
<code class="language-plaintext highlighter-rouge">--test-threads 1</code> should see a speedup for all projects. I’ll also add a
picture of the graph minitarp generated once the issue was fixed:</p>
<p><img src="/assets/20191002/pass.png" alt="A failing test" /></p>Tarpaulin (or cargo-tarpaulin) is a code coverage tool for Rust, and anyone who’s used it might know that until recently it had an issue with code that used futures.Tarpaulin Past Present Future2018-06-11T00:00:00+00:002018-06-11T00:00:00+00:00/2018/06/11/Tarpaulin-past-present-future<p><a href="https://github.com/xd009642/tarpaulin">Tarpaulin</a> (or cargo-tarpaulin) is a
code coverage tool for Rust. Last year was pretty busy with the launch of the
project and the rush of issues as people started to use it so this is just a
chance to look at what’s new with version 0.6.0 and what’s planned for the rest
of this year.</p>
<h2 id="2017-a-year-in-review">2017 A year in review</h2>
<p>So in 2017 I started tarpaulin, largely because I realised it’s probably the
best project name I’ve came up with, but mainly because I found the process of
using kcov with Rust frustrating. Language agnostic coverage tools tend to only
work properly with C, struggle with abstractions, and setup is fiddly.
Whereas building a coverage tool targeted at a specific language means you can
utilise tooling in that language to make things easier - Cargo for example.</p>
<p>So after my initial May release tarpaulin can now:</p>
<ul>
<li>Send coverage reports to popular coverage sites (coveralls and codecov)</li>
<li>Generate cobertural xml reports</li>
<li>Include unused templated code in results (kcov doesn’t do this for Rust or C++)</li>
<li>Handle unused inlined functions</li>
<li>Trim out a lot of false positives that show up such as module imports and <code class="language-plaintext highlighter-rouge">using</code> aliases</li>
<li>Include or exclude packages</li>
<li>Ignore certain tests</li>
<li>Work on multithreaded code (with the <code class="language-plaintext highlighter-rouge">--no-count</code> option, now a default)</li>
<li>Tarpaulin ran on Windows via docker and new releases are now available on
<a href="https://hub.docker.com/r/xd009642/tarpaulin">docker-hub</a></li>
</ul>
<h3 id="syntex_syntax-to-syn">syntex_syntax to syn</h3>
<p>As syntex_syntax is unmaintained the introduction of nested import statements
wasn’t able to be handled and caused a panic. Because of this tarpaulin had to
move to syn for syntax analysis. It also had to make use of semver exempt code
to get the source positions from syn.</p>
<p>Because of this you may need <code class="language-plaintext highlighter-rouge">RUSTFLAGS="--cfg procmacro2_semver_exempt"</code> when
running <code class="language-plaintext highlighter-rouge">cargo install</code> for tarpaulin 0.6.0. So just type the following:</p>
<p><code class="language-plaintext highlighter-rouge">RUSTFLAGS="--cfg procmacro2_semver_exempt" cargo install cargo-tarpaulin</code></p>
<p>Another alternative is to use the install script to download the binary from the
github releases for travis or one of the <a href="https://hub.docker.com/r/xd009642/tarpaulin">docker images available</a>.</p>
<h2 id="2018-whats-planned">2018 What’s planned</h2>
<p>So in 2018 there’s a few different features and improvements planned but I’ll
focus on the big ones.</p>
<h3 id="html-reports">HTML Reports</h3>
<p>Tarpaulin will have it’s own HTML report format it can generate for people
who aren’t using codecov or coveralls as a web interface to their coverage
results. These reports will be able to show coverage at a folder level, individual
file level and also let you inspect the source and see it annotated with the results.</p>
<h3 id="branch-and-condition-coverage">Branch and condition coverage</h3>
<p>So a couple of open source tools provide branch coverage, none provide condition
coverage. I’m aiming straight for a technical solution that works for condition
coverage, this is harder than just branch coverage but has some benefits.
It means tarpaulin will be capable of branch coverage and open the door to
Modified Condition Decision Coverage (MCDC) something I’ve only seen in expensive
closed source tools. MCDC coverage is significantly more useful as a metric and
mandated in some safety critical software projects.</p>
<p>Currently, I’m deciding between attempting to tackle all three at once or start
with branch coverage. Because of the need to analyse boolean subconditions for
condition and MCDC coverage they’re harder to implement than branch coverage.
However, implementing a system that can provide condition coverage can provide
branch and MCDC without extra complexity in the tracing and interpretation of
the programs.</p>
<p>There may also be a blog post in the future going into the different types of
coverage and explaining the pros and cons of them!</p>
<h3 id="performance">Performance</h3>
<p>Instrumenting code with breakpoints and stepping through logging the coverage
is obviously a slow process. There are a number of flags in tarpaulin to mitigate
the performance issues and by using syn I’ve aimed to remove
unnecessary breakpoints to speed up runs. In 2018 I’d like to improve the
performance further, potentially by running test executables in parallel or
simpler means.</p>
<h2 id="other-improvements">Other Improvements</h2>
<p>As the year goes on I’d like to continue to close issues improving accuracy and
consistency across projects of different types and different distros. And a lot
of that work will be by closing issues.</p>
<p>One issue I’d really like to see closed is
<a href="https://github.com/xd009642/tarpaulin/issues/23">#23</a>, although that might be
reliant on <a href="https://github.com/rust-lang/rust/issues/35061">rust#35061</a>. Likewise,
<a href="https://github.com/xd009642/tarpaulin/issues/13">#13</a> coverage of doctests will
be another tricky one to close.</p>
<h2 id="community-contributions">Community contributions</h2>
<p>In 2018 the aim is to remove any barriers to entry for people interested in
contributing and I’m going to try and start having mentored issues among other
initiatives. I’ve already made some significant headway into this by refactoring
the code to abstract away some of the details of ptrace and adding more tests
and docs. This work will continue as the year goes on.</p>
<p>Any help is appreciated and with that in mind I’d like to thank
people who have contributed this year. So thanks to:</p>
<ul>
<li>Robinst</li>
<li>Andy128k</li>
<li>llogiq</li>
<li>tafia</li>
<li>rep-nop</li>
<li>vberger</li>
<li>alex-mckenna</li>
<li>quodlibetor</li>
<li>yodaldevoid</li>
<li>mathstuf</li>
<li>philipc</li>
<li>bbigras</li>
<li>jean553</li>
<li>apeduru</li>
<li>mgeisler</li>
</ul>Tarpaulin (or cargo-tarpaulin) is a code coverage tool for Rust. Last year was pretty busy with the launch of the project and the rush of issues as people started to use it so this is just a chance to look at what’s new with version 0.6.0 and what’s planned for the rest of this year.Introducing Tarpaulin2017-07-20T00:00:00+00:002017-07-20T00:00:00+00:00/2017/07/20/introducing-tarpaulin<h1 id="code-coverage">Code coverage</h1>
<p>When people talk about code coverage, they’re referring to metrics which show
how much of their source code is “covered” by their tests. Now covering the code
is of course only the first step, the tests actually have to test the
functionality in a meaningful way, but coverage is a good way of finding areas
in your code which you haven’t tested as thoroughly.</p>
<p>So how do we define coverage? Well there are numerous metrics, Wikipedia lists
these methods as the simplest ways of measuring coverage.</p>
<ul>
<li>Function coverage - how many functions have been executed?</li>
<li>Statement (line) coverage - how many statements have been executed?</li>
<li>Branch coverage - how many of the possible paths have been executed?</li>
<li>Condition coverage - how many boolean subconditions have been executed?</li>
</ul>
<p>Currently, open source coverage tools (bcov, gcov, kcov) only offer statement
coverage. They also require some effort to execute depending on your language
and project setup. This is the motivation for tarpaulin, a code coverage tool
created specifically for rust as a cargo subcommand.</p>
<h1 id="why-tarpaulin">Why tarpaulin?</h1>
<p><a href="https://github.com/xd009642/tarpaulin">Tarpaulin</a> uses cargo as a library
meaning it can automatically identify files in your project. It can also
generate and identify the test executables and run coverage on all of them.</p>
<p>Compare this to kcov where you need to clean the project area, build the test
executables then iterate over the executables in target/debug running kcov on
each one and merging the reports at the end. Additionally, kcov will include
extern crate definitions and module statements (<code class="language-plaintext highlighter-rouge">pub mod foo</code>) in it’s coverage
results. Tarpaulin is designed for rust and aims to remove lines which are
“uncoverable” from the coverage results.</p>
<p>Below is some example output for tarpaulin ran on one of the example projects.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cargo tarpaulin
Launching test
running 1 test
test tests::bad_test ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
Coverage Results
src/lib.rs: 7/8
src/unused.rs: 0/4
58.33% coverage, 7/12 lines covered
</code></pre></div></div>
<p>Currently, tarpaulin implements line coverage and has
<a href="https://coveralls.io">coveralls.io</a> integration. It is linux only and only
designed with x86_64 support (so 64 bit AMD and Intel processors). Wider
support is planned for future expansion, but this should work for the majority
of users.</p>
<p>By focusing on Rust only and it’s build system tarpaulin can potentially provide
better results by being able to extend information derived from the test
binaries with information from cargo and the source code itself. By having
access to crates like <a href="https://github.com/serde-rs/syntex">syntex</a>, tarpaulin
aims to become the first open source code coverage tool to offer a solution for
condition coverage.</p>
<p>That’s all for this relatively short introduction,
check out the <a href="https://github.com/xd009642/tarpaulin">github repository</a> for
more information as well as the roadmap! If you find any issues please raise
them and I should get back to you fairly sharpish.</p>Code coverageHello world!2017-06-29T14:48:41+00:002017-06-29T14:48:41+00:00/jekyll/update/2017/06/29/welcome-to-jekyll<p>Well here is the obligatory hello world post. My current plan is using this blog to talk about my code coverage tool for the rust language <a href="https://github.com/xd009642/tarpaulin">cargo-tarpaulin</a>.</p>Well here is the obligatory hello world post. My current plan is using this blog to talk about my code coverage tool for the rust language cargo-tarpaulin.