09 August, 2016

Code coverage

A powerful tool that will help you write better quality code is measuring code coverage. This post will explain the basics how I use this in my foundation library project (https://github.com/rampantpixels/foundation_lib) written in C, but the principles apply to other languages and toolchains as well. All code I publish is released under public domain and free to use for any purpose.

Code coverage measures how many times each line of code is executed while running your test suite. By looking at the lines that have not been executed you can find potential errors in your code or learn which test cases that needs to be improved in order to test all code paths. I use the free service at https://codecov.io to visualize the results.

For an example, look at https://goo.gl/TtNJl1 to see the coverage results of a module in the library. The lines that have been executed at least once are marked in green, the lines that have never been executed are marked in red, and the lines that are not generating any instructions are unmarked.

Coverage is pretty good, but in the function profile_end_block there is a while loop marked with the comment "Walk sibling list backwards" that is never executed.



Is this dead code that can be removed (as in, will this case never happen due to logic in other parts of the code) or are the test cases lacking the proper tests? If the latter, we have no idea if the code actually works or not, since it has not been executed. Finding these untested parts of the code is that goal of code coverage analysis.

If you have an already existing code base it might seem a daunting task to start using code coverage as you will most likely find many parts of the code which is not covered. But once you find an fix the first bug in one of these dark areas of the code it will be worth it! It's gamification at its best, you will work hard to reach that elusive 100% coverage, and your code quality will rise quickly.

In order to generate the code coverage measurements I use the built-in functionality of the clang compiler by passing the "--coverage" argument to compiler and linker. When the code is compiled a .gcno metadata file is generated by the compiler for each object file, and once the final test case binary is executed it will generate a corresponding .gcda coverage data file.



These files can then be parsed together with the corresponding source file to find the execution count per line per file using the llvm-cov tool. This tool can output a gcov text file with the wanted data (similar/compatible to what the gcc toolchain also uses).

I wrote two python scripts to do the job invoking llvm-cov, parsing these gcov files and upload the results to codecov.io. Read a gcov file at https://goo.gl/bH4AUm, invoke llvm-cov and build a report for codecov.io at https://goo.gl/bH4AUm.

As a closing remark also note that code coverage can be used with profile guided optimization by feeding the coverage data from your final executable back to the compiler. But this is a topic for another post.

31 July, 2014

Heroines


A good friend of mine is creating a touchpad game and chose to change the main character from a passive anonymous guy to an active girl. Awesome!

I love the design and its a great example on how you can create an obviously female character without resorting to using stereotypic design choices such as broken armor.

Take the time to check out the game in it’s current state at gnbw.com

(Reblogged from my tumblr: maniccoder.tumblr.com)

07 June, 2014

Rampant Kittens

Just promoting myself a bit here. We finally managed to get our little block drop game Rampant Kittens published on all our major platforms. Try it out!


iPhone/iPad: iTunes App Store
Android: Google Play
MacOS X: Mac App Store
Windows: Our website

10 May, 2014

Rovio Game Jam

I participated in the 12 hour Rovio Game Jam yesterday together with a friend, and the theme of the jam was "eqality". So we created a game called Agenda about distributing wealth and resources between cities. The end result was good enough to earn us a second place in the competition, and we'll polish it up and release on Android/iOS tablets at some point.

26 April, 2014

SublimeText & clang on Windows

After getting Intel compiler to play nice with SublimeText and SCons on Windows, the next target was getting it to use clang. The LLVM environment on Windows requires the MinGW base package for headers and libs, and I decided to use the MinGW-x64 prebuilt mingw-builds distribution from http://mingw-w64.sourceforge.net/download.php#mingw-builds

However, the headers do not play nice with clang and -Wall, with a bunch of typedef and macro redefinitions. I ended up adding

env.Append( CFLAGS=['-Wno-ignored-attributes', '-Wno-typedef-redefinition', '-Wno-undef',
'-Wno-unknown-pragmas', '-Wno-redundant-decls', '-Wno-shadow'] )

to my SConscript environment setup in order to get it to build, only to be greeted with a bunch of alignmen cast compilation warnings and then multiple definition errors when linking

lib\win64\debug/libfoundation.a(log.o): In function `GetCurrentFiber':
D:\dev\mingw\include/winnt.h:8139: multiple definition of `GetCurrentFiber'
lib\win64\debug/libfoundation.a(main.o):D:\dev\mingw\include/winnt.h:8139: first defined here
lib\win64\debug/libfoundation.a(log.o): In function `GetFiberData':
D:\dev\mingw\include/winnt.h:8140: multiple definition of `GetFiberData'

More to follow

22 April, 2014

Rampant Kittens

My block-drop game Rampant Kittens is now available on Google Play. Give it a shot! https://play.google.com/store/apps/details?id=com.rampantpixels.p1



I'm slowly cleaning up, refactoring and releasing the code for the game as well, available on github. To begin with the platform abstraction foundation: https://github.com/rampantpixels/foundation_lib

13 April, 2014

SCons & SublimeText - Intel compiler

In order to get SCons to play nice with the Intel compiler suite version 14 (or later) on Windows it seems the intelc.py tool definition in SCons needs to be updated a bit. The layout of keys in the registry have changed and the directory layout as well.

The registry keys are now chained, so first it needs to look in
HKLM/Software/Wow6432Node/Intel/Suites/<version>/Defaults/C++/<abi> 
to find the UUID of the instance to use, then look in
HKLM/Software/Wow6432Node/Intel/Suites/<version>/<uuid>/C++/<abi>
for the various values to use for locating compiler binaries. I modified the abi strings used in the SCons intelc.py tools match the EM64T_NATIVE and IA32 strings in the 14.0 compiler release, and rewrote the get_all_compiler_versions and get_intel_registry_value functions to use this chained default -> uuid registry lookup. You can get the final modified intelc.py tool from http://www.rampantpixels.com/pub/intelc.py.

This together with the default and mslib tools (basically passing tools=['default','intelc','mslib'] to the Environment construction) allows my SCons construction environment to compile my foundation library with the Intel compiler suite within SublimeText 3. Great success!