<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Made of Bugs &#187; testing</title>
	<atom:link href="http://blog.nelhage.com/tag/testing/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.nelhage.com</link>
	<description>It's software. It's made of bugs.</description>
	<lastBuildDate>Thu, 18 Aug 2011 21:57:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Configuring dnsmasq with VMware Workstation</title>
		<link>http://blog.nelhage.com/2010/10/dnsmasq-and-vmware/</link>
		<comments>http://blog.nelhage.com/2010/10/dnsmasq-and-vmware/#comments</comments>
		<pubDate>Mon, 25 Oct 2010 03:15:23 +0000</pubDate>
		<dc:creator>nelhage</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[dhcp]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[vmware]]></category>

		<guid isPermaLink="false">http://blog.nelhage.com/?p=383</guid>
		<description><![CDATA[I love VMware workstation. I keep VMs around for basically every version of every major Linux distribution, and use them heavily for all kinds of kernel testing and development. This post is a quick writeup of my networking setup with VMware Workstation, using dnsmasq to assign my VMs addresses and provide a DNS server to [...]]]></description>
			<content:encoded><![CDATA[<p>I love VMware workstation. I keep VMs around for basically every
version of every major Linux distribution, and use them heavily for
all kinds of kernel testing and development.</p>

<p>This post is a quick writeup of my networking setup with VMware
Workstation, using dnsmasq to assign my VMs addresses and provide a
DNS server to resolve VM addresses.</p>

<h2>The objective</h2>

<p>I want to be able to resolve my VM&#8217;s hostnames so that I can ssh to
them, or run other network services and access them from the host. I
could just assign static addresses and put them in <code>/etc/hosts</code>, but
that&#8217;s totally lame, and liable to be a source of error and
frustration, because I have dozens of VMs, and add and remove them
frequently.</p>

<p>We&#8217;re going to set things up so that when VMs get addresses from DHCP,
their hostnames automatically become resolvable, using the <code>.vmware</code>
domain. To do this, we&#8217;re going to set up a piece of software called
<code>dnsmasq</code>, which is a flexible DNS and DHCP server, designed for
basically exactly this purpose.</p>

<h2>The setup</h2>

<p>Because I use my VMs for local testing, I just keep most of them on a
local NAT on my machine. I configure that virtual network inside
VMware as follows (run <code>vmware-netconfig</code>, or follow the appropriate
menus):</p>

<p><a href="http://blog.nelhage.com/wp-content/uploads/2010/10/vmw.png"><img src="http://blog.nelhage.com/wp-content/uploads/2010/10/vmw.png" alt="" title="VMware workstation network configuration" width="512" height="576" class="aligncenter size-full wp-image-388" /></a></p>

<p>Note how I <strong>disable</strong> &#8220;Use local DHCP service to distribute IP
addresses to VMs&#8221; &#8212; we&#8217;re going to set up dnsmasq to prove DHCP, so
we don&#8217;t want it fighting with VMware&#8217;s.</p>

<p>Notice that the subnet I&#8217;m using here is <code>172.16.37.*</code> &#8212; if you
choose a different one, you&#8217;ll need to adjust accordingly later.</p>

<h2>Configuring <code>dnsmasq</code></h2>

<p>Then, I install <code>dnsmasq</code>, and configure <code>/etc/dnsmasq.conf</code> as
follows:</p>

<pre><code>listen-address=172.16.37.1
listen-address=127.0.0.1
no-dhcp-interface=lo

server=192.168.1.1
local=/vmware/

no-hosts
no-resolv

domain=vmware
dhcp-fqdn

dhcp-range=172.16.37.3,172.16.37.200,12h
dhcp-authoritative
dhcp-option=option:router,172.16.37.2
</code></pre>

<p>Here&#8217;s what each of those lines mean, in order:</p>

<pre><code>listen-address=172.16.37.1
listen-address=127.0.0.1
no-dhcp-interface=lo
</code></pre>

<p>We don&#8217;t want <code>dnsmasq</code> serving DHCP or DNS to the outside world or
other virtual networks, so we only tell it to listen on the local
interface &#8212; so that we can talk to it from the host &#8212; and to the
virtual network we set up in the previous step. We don&#8217;t want it
serving DHCP to <code>localhost</code>, though, so we tell it not to.</p>

<pre><code>server=192.168.1.1
local=/vmware/
</code></pre>

<p>Here we tell <code>dnsmasq</code> how to forward DNS requests to the outside
world. We&#8217;re going to be using <code>dnsmasq</code> as our primary nameserver,
and having it forward requests for things it doesn&#8217;t understand to a
real DNS server. In my case, that&#8217;s my LAN&#8217;s router, at
<code>192.168.1.1</code>. The <code>local</code> line tells <code>dnsmasq</code> that the <code>.vmware</code>
domain is local, and it should never forward requests to resolve
things in that domain.</p>

<p>If I needed something more complicated, it might be possible to use
the <code>resolv-file</code> option or similar, but I don&#8217;t, personally.</p>

<pre><code>no-hosts
no-resolv
</code></pre>

<p>These options tell <code>dnsmasq</code> not to look at <code>resolv.conf</code> or
<code>/etc/hosts</code> when resolving names &#8212; we want it only to resolve VMs
itself, and to forward everything else.</p>

<pre><code>domain=vmware
dhcp-fqdn
</code></pre>

<p>This tells dnsmasq to assign the <code>.vmware</code> domain to hosts it hands
out DHCP to, so that we can resolve VMs in the <code>.vmware</code> domain.</p>

<pre><code>dhcp-range=172.16.37.3,172.16.37.200,12h
dhcp-authoritative
</code></pre>

<p>And finally, we configure the DHCP server. We give it a range of
addresses to assign on the subnet we created earlier. I stop at
<code>.200</code>, so that I can leave the last few open for static IPs if I need
for some reason, and we start at <code>.3</code> &#8212; <code>.1</code> is the host, and <code>.2</code> is
the address of VMware&#8217;s router. <code>dhcp-authoritative</code> enables some
optimizations when <code>dnsmasq</code> knows it is the only DHCP server around.</p>

<pre><code>dhcp-option=option:router,172.16.37.2
</code></pre>

<p>Finally, we need <code>dhcp-option</code> to tell DHCP clients to use the
VMware-provided router at <code>.2</code> as their gateway, instead of using the
host, at <code>.1</code>. We could configure the host to be a NAT server using
Linux&#8217;s NAT, but that&#8217;s outside the scope of this document.</p>

<h2>Configuring the host</h2>

<p>Now, we need to configure the host to use dnsmasq as our DNS
server. This is a simple matter of telling the host to use <code>127.0.0.1</code>
as our DNS server, and to add <code>.vmware</code> to our search path. If we&#8217;re
editing <code>resolv.conf</code> directly, it would look like:</p>

<pre><code>search vmware
nameserver 127.0.0.1
</code></pre>

<h2>Configuring guests</h2>

<p>We need to configure our guests to send a hostname along with their
DHCP requests, so that <code>dnsmasq</code> can add them to its address
table. How to do this varies by OS, but most modern OSes do it
automatically. If they don&#8217;t, here are a few hints:</p>

<p>For RHEL-based distros, edit <code>/etc/sysconfig/network-scripts/ifcfg-INTERFACE</code>, and add a line like</p>

<pre><code> DHCP_HOSTNAME=centos-5-amd64
</code></pre>

<p>For most other Linux distributions, you can often edit <code>dhclient.conf</code>
(usually in <code>/etc/</code> or <code>/etc/dhclient/</code>) to include:</p>

<pre><code> send host-name "centos-5-amd64";
</code></pre>

<p>Or, with a recent <code>dhclient</code>,</p>

<pre><code> send host-name "&lt;hostname&gt;";
</code></pre>

<p>will make it look up the machine&#8217;s actual hostname.</p>

<h2>Conclusions</h2>

<p>That&#8217;s all there is to it. This is a pretty simple setup, but
hopefully someone else will find this useful. If you need <code>dnsmasq</code> to
do something more subtle, the <a href="http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html">documentation</a> is mostly quite
good.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nelhage.com/2010/10/dnsmasq-and-vmware/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Check Plus: An EDSL for writing unit tests in C</title>
		<link>http://blog.nelhage.com/2010/06/check-plus-an-edsl-for-writing-unit-tests-in-c/</link>
		<comments>http://blog.nelhage.com/2010/06/check-plus-an-edsl-for-writing-unit-tests-in-c/#comments</comments>
		<pubDate>Sat, 26 Jun 2010 19:54:53 +0000</pubDate>
		<dc:creator>nelhage</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[check]]></category>
		<category><![CDATA[macros]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://blog.nelhage.com/?p=263</guid>
		<description><![CDATA[Check is an excellent unit-testing framework for C code, used by a number of relatively well-known projects. It includes features such as running all tests in separate address spaces (using fork(2)), which means that the test suite can properly report segfaults or similar crashes without the test runner crashes. My main complaint about Check is [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://check.sourceforge.net/">Check</a> is an excellent unit-testing framework for C code, used
by a number of relatively well-known projects. It includes features
such as running all tests in separate address spaces (using
<code>fork(2)</code>), which means that the test suite can properly report
segfaults or similar crashes without the test runner crashes.</p>

<p>My main complaint about Check is that (unsurprisingly for a framework
written in C), it&#8217;s not very declarative. After you define all your
tests as separate functions, you need to write code to manually
collect them into &#8220;test cases&#8221;, which you then collect into &#8220;test
suites&#8221;, which you can then run. While this is an understandable
interface for a C library to provide, as a user I found that it
rapidly annoyed me, and so I wrote Check Plus.</p>

<p><a href="http://github.com/nelhage/check-plus">Check Plus</a> is a simple library I wrote that uses some preprocessor
tricks and GNU C extensions to provide a declarative EDSL within C for
declaring and collecting your test cases. Check-Plus is a single
self-contained header file distributed under the LGPL (like Check), so
it should be easy to pull into your project.</p>

<h2>Example</h2>

<p>Check-Plus lets you declare your Check suites and test cases in a
declarative manner. A simple example, shipped with Check-Plus, would
look like:</p>

<pre><code>#include &lt;string.h&gt;
#include &lt;stdlib.h&gt;

#include "check-plus.h"

#define SUITE_NAME example
BEGIN_SUITE("Example test suite");

#define TEST_CASE core
BEGIN_TEST_CASE("Core tests");

TEST(strcmp)
{
    fail_unless(strcmp("hello", "HELLO") != 0);
    fail_unless(strcasecmp("hello", "HELLO") == 0);
}
END_TEST

TEST(strcat)
{
    char buf[1024] = {0};
    strcat(buf, "Hello, ");
    strcat(buf, "World.");
    fail_unless(strcmp(buf, "Hello, World.") == 0);
}
END_TEST

END_TEST_CASE;
#undef TEST_CASE
END_SUITE;
#undef SUITE_NAME
</code></pre>

<p>Having done that, you can extract the declared test suite using
<code>construct_test_suite(example)</code>, and run it using the standard Check
test runner tools.</p>

<p>You can, of course, define multiple test cases within a single suite,
and you can even define test fixtures using</p>

<pre><code>DEFINE_FIXTURE(setup, teardown);
</code></pre>

<p>within the <code>BEGIN_TEST_CASE</code> &#8230; <code>END_TEST_CASE</code> block.</p>

<p>The equivalent code, without Check-Plus, would look similar, but
instead of the <code>BEGIN_</code> and <code>END_</code> blocks to define the suite and test case, you&#8217;d have to write
something like:</p>

<pre><code>Suite *
example_suite (void)
{
  Suite *s = suite_create ("Example test suite");

  /* Core test case */
  TCase *tc_core = tcase_create ("Core tests");
  tcase_add_test (tc_core, test_strcmp);
  tcase_add_test (tc_core, test_strcat);
  suite_add_tcase (s, tc_core);

  return s;
}
</code></pre>

<p>It&#8217;s not a huge difference, but it&#8217;s big enough that I really
appreciate it once the test suite gets large. For more documentation on Check, check out <a href="http://check.sourceforge.net/doc/check_html/index.html">its manual</a>.</p>

<p>Let me know if you find this useful for anything. Next week, I&#8217;ll do a
writeup on the tricks behind the implementation.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nelhage.com/2010/06/check-plus-an-edsl-for-writing-unit-tests-in-c/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

