<?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>Brain Matters &#187; Python</title>
	<atom:link href="http://blog.agoragames.com/category/engineering/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.agoragames.com</link>
	<description></description>
	<lastBuildDate>Thu, 29 Jul 2010 19:13:58 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Lifting the Tail: Inside Agora Skunk Works</title>
		<link>http://blog.agoragames.com/2010/06/28/lifting-the-tail-inside-agora-skunk-works/</link>
		<comments>http://blog.agoragames.com/2010/06/28/lifting-the-tail-inside-agora-skunk-works/#comments</comments>
		<pubDate>Mon, 28 Jun 2010 13:08:25 +0000</pubDate>
		<dc:creator>Aaron Westendorf</dc:creator>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.agoragames.com/?p=623</guid>
		<description><![CDATA[We&#8217;ve been hard at work for over a year developing the next generation of game integration technology here at Agora, and over the next few months we&#8217;ll be releasing some of the code that we&#8217;ve developed, discussing some of the challenges we face and how we&#8217;re using all the new technology to build the best [...]]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste">We&#8217;ve been hard at work for over a year developing the next generation of game integration technology here at Agora, and over the next few months we&#8217;ll be releasing some of the code that we&#8217;ve developed, discussing some of the challenges we face and how we&#8217;re using all the new technology to build the best gaming experience around.</div>
<p></p>
<div id="_mcePaste">To start, a brief explanation of the challenges we face.  As you might imagine, we deal with a lot of data.  The volume is only increasing, and with our friends at MLG, we expect significantly more of it.  Along with the volume of data, it also comes to us in many different forms and protocols; sometimes it&#8217;s pushed to us, and sometimes we have to go fetch it.  We have to respond to any number of business decisions made by developers and publishers, adapt to developers&#8217; needs in a manner which does not negatively impact their schedule, and be a consistent and reliable partner to all our clients.  We have to deliver comprehensive documentation to both game and website developers, and our business relationships are aided by a consistent offering.</div>
<p></p>
<div id="_mcePaste">In the past, each game&#8217;s services would be its own Rails application.  We built a suite of re-usable components, but for each title we would have to re-write a lot of boiler-plate code and set up an entirely new suite of servers, complete with application hosts, web and caching proxies, databases and so on.  As our data throughput grew, we found that we needed to add additional components to our stack, such as Sparrow, to turn synchronous workloads into asynchronous ones.  Each project required extensive monitoring and reporting, an interactive console for viewing production data and testing staging code.</div>
<p></p>
<div id="_mcePaste">We were very successful, but found the business costs too high and that we were missing several features that were important to our long term strategy of being the best in the industry at game integration.  Our experience with a virtualized hosting environment opened our eyes to the possibilities of turning our data processing and web services loose on a commoditized, shared platform.</div>
<p></p>
<div id="_mcePaste">With a general set of requirements in hand, we set forth, and what we came away with has been incubating, gestating and flowering into a powerful toolset that has met all our expectations, and then some.</div>
<p></p>
<div id="_mcePaste">Our first task was to choose the core set of technologies and the basic processing scheme that we would be using.  After an exhaustive search, lots of hacking and whiteboard scribblings, we settled on the following key features:</div>
<p></p>
<div id="_mcePaste">
<ul style="list-style-type:circle;">
<li>Python for all application code</li>
<li><a href="http://www.amqp.org">AMQP</a>, via <a href="http://www.rabbitmq.com">RabbitMQ</a>, for all inter-process communication</li>
<li>MySQL, Tokyo Tyrant and memcache for data storage services</li>
<li>Protocol translators to bridge external traffic to AMQP via a simple binary protocol</li>
<li>libevent for as many as IO operation as possible</li>
</ul>
</div>
<p></p>
<div id="_mcePaste"><img class="alignnone" title="lifting the tail" src="http://blog.agoragames.com/wp-content/uploads/2010/06/lifting_the_tail.png " alt="" width="357" height="193" /></div>
<p></p>
<div>We chose Python from the suitable dyanmic languages primarily for its memory management and speed.  We were shifting to a single-threaded multi-process environment where memory costs are high and performance paramount, and Python has an extensive pedigree in this area.  We did choose to sacrifice some memory by adhering to a single-threaded model in order to keep the application stack simple and use the kernel for all context switching.</div>
<p></p>
<div id="_mcePaste">AMQP&#8217;s routing scheme gives us powerful tools to shard and aggregate traffic across our cluster.  We chose RabbitMQ because of its Erlang heritage, its performance, reliability, clustering capabilities and commercial support.  By splitting up each game&#8217;s services into discrete packages which can each run numerous instances, we can readily divide traffic across a cluster of RabbitMQ hosts and attach listeners for monitoring, diagnostics and metrics.  The dotted-notation of AMQP&#8217;s topic exchanges allow for routing traffic between titles, environments, services and even specific commands.</div>
<p></p>
<div>To get the most out of the kernel and reduce latency, we use <a href="http://monkey.org/~provos/libevent/">libevent</a> for all of our AMQP traffic and in our protocol translators.  We extensively patched the <a href="http://barryp.org/software/py-amqplib/">py-amqplib</a> to work within this asynchronous environment.  This fork has been in production use for some time now but is slated for a ground-up re-write and release into the wild.</div>
<p></p>
<div id="_mcePaste">We considered many other database solutions, but at the time that we had to make our decision, felt that Tokyo Tyrant was the best NoSQL database to introduce into our stack because of its sparse table capabilities, high performance, low resource usage and simple setup.  We&#8217;re very excited with all the new development that is taking place in this field, and will be writing more about our experience with these tools over the coming years.</div>
<p></p>
<div id="_mcePaste">What we ended up with has met all of the goals that we set out to achieve.  We have successfully abstracted scaling, monitoring, protocol presentation and metric aggregation, allowing us to focus entirely on delivering functionality to our customers.  Now that our customers include MLG, this means that we&#8217;ll be rolling out some of the biggest and baddest applications in the gaming community, with confidence and reliability.</div>

<div class="sociable">

<ul>
	<li class="sociablefirst"><a rel="nofollow"  target="_blank" href="http://reddit.com/submit?url=http%3A%2F%2Fblog.agoragames.com%2F2010%2F06%2F28%2Flifting-the-tail-inside-agora-skunk-works%2F&amp;title=Lifting%20the%20Tail%3A%20Inside%20Agora%20Skunk%20Works" title="Reddit"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  target="_blank" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.agoragames.com%2F2010%2F06%2F28%2Flifting-the-tail-inside-agora-skunk-works%2F&amp;title=Lifting%20the%20Tail%3A%20Inside%20Agora%20Skunk%20Works&amp;bodytext=We%27ve%20been%20hard%20at%20work%20for%20over%20a%20year%20developing%20the%20next%20generation%20of%20game%20integration%20technology%20here%20at%20Agora%2C%20and%20over%20the%20next%20few%20months%20we%27ll%20be%20releasing%20some%20of%20the%20code%20that%20we%27ve%20developed%2C%20discussing%20some%20of%20the%20challenges%20we%20face%20and%20" title="Digg"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  target="_blank" href="http://delicious.com/post?url=http%3A%2F%2Fblog.agoragames.com%2F2010%2F06%2F28%2Flifting-the-tail-inside-agora-skunk-works%2F&amp;title=Lifting%20the%20Tail%3A%20Inside%20Agora%20Skunk%20Works&amp;notes=We%27ve%20been%20hard%20at%20work%20for%20over%20a%20year%20developing%20the%20next%20generation%20of%20game%20integration%20technology%20here%20at%20Agora%2C%20and%20over%20the%20next%20few%20months%20we%27ll%20be%20releasing%20some%20of%20the%20code%20that%20we%27ve%20developed%2C%20discussing%20some%20of%20the%20challenges%20we%20face%20and%20" title="del.icio.us"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a></li>
	<li class="sociablelast"><a rel="nofollow"  target="_blank" href="http://technorati.com/faves?add=http%3A%2F%2Fblog.agoragames.com%2F2010%2F06%2F28%2Flifting-the-tail-inside-agora-skunk-works%2F" title="Technorati"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /></a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.agoragames.com/2010/06/28/lifting-the-tail-inside-agora-skunk-works/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mocking HTTP request and response with Python and Mox</title>
		<link>http://blog.agoragames.com/2009/10/01/mocking-http-request-and-response-with-python-and-mox/</link>
		<comments>http://blog.agoragames.com/2009/10/01/mocking-http-request-and-response-with-python-and-mox/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 13:55:56 +0000</pubDate>
		<dc:creator>David Czarnecki</dc:creator>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[mocking]]></category>
		<category><![CDATA[mox]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[urllib2]]></category>

		<guid isPermaLink="false">http://blog.agoragames.com/?p=368</guid>
		<description><![CDATA[I recently started integrating with some web services in Python and wanted to be able to test all the requests and responses with valid and invalid data. However, I need to be able to do this without actually hitting the web service when testing. And of course I don&#8217;t want to change my web service [...]]]></description>
			<content:encoded><![CDATA[<p>I recently started integrating with some web services in Python and wanted to be able to test all the requests and responses with valid and invalid data. However, I need to be able to do this without actually hitting the web service when testing. And of course I don&#8217;t want to change my web service code to conditionally do things if running in a test environment. Enter mocking and Mox.</p>
<p>One of our engineers, Tim, has written an excellent post on his adventures as a Ruby programmer getting up to speed on <a href="http://blog.agoragames.com/2009/02/23/python-is-mocking-me-a-ruby-programmers-adventures-with-pythonmox/">testing and mocking in Python using Mox</a>. You should read it.</p>
<p>Back to my issue with mocking the HTTP request and response.</p>
<p>Here is what I came up with. I first created a MockResponse class that adds a read() method to the string class.</p>
<p><code>
<pre class="brush: python">&lt;/code&gt;

class MockResponse(str):
&#039;&#039;&#039;
Mock response class with a method called read which will be used similar to the response from an HTTP request to a URL
&#039;&#039;&#039;
def read(self):
return self
</pre>
<p>And here is a test in which I mock out the request and response for the urllib2.OpenerDirector.open method. I don't so much care what the request string is passed to the open call, so I use IgnoreArg(). And I return the XML that would be returned by the actual web service to indicate the username and/or password were incorrect.</p>
<pre class="brush: python">

def test_logging_in_to_network_with_bad_username_and_password(self):
my_network_service = MyNetworkService(&#039;foo&#039;, &#039;bar&#039;)
self.mock(urllib2.OpenerDirector, &#039;open&#039;)
urllib2.OpenerDirector.open(mox.IgnoreArg()).AndReturn(MockResponse(&#039;&#039;&#039;
&lt; ?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;login&gt;
&lt;status&gt;
&lt;id&gt;30000&lt;/id&gt;
&lt;message&gt;ACCT_LOGIN_FAILED&lt;/message&gt;
&lt;/status&gt;
&lt;accountid&gt;7&lt;/accountid&gt;
&lt;/login&gt;
&#039;&#039;&#039;))
self.replay_all()

self.assertEqual(False, my_network_service.login())
self.mox.UnsetStubs()
self.mox.VerifyAll()
</pre>
<p>If there's a better way, I'd love to hear your suggestions.</p>

<div class="sociable">

<ul>
	<li class="sociablefirst"><a rel="nofollow"  target="_blank" href="http://reddit.com/submit?url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F10%2F01%2Fmocking-http-request-and-response-with-python-and-mox%2F&amp;title=Mocking%20HTTP%20request%20and%20response%20with%20Python%20and%20Mox" title="Reddit"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  target="_blank" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F10%2F01%2Fmocking-http-request-and-response-with-python-and-mox%2F&amp;title=Mocking%20HTTP%20request%20and%20response%20with%20Python%20and%20Mox&amp;bodytext=I%20recently%20started%20integrating%20with%20some%20web%20services%20in%20Python%20and%20wanted%20to%20be%20able%20to%20test%20all%20the%20requests%20and%20responses%20with%20valid%20and%20invalid%20data.%20However%2C%20I%20need%20to%20be%20able%20to%20do%20this%20without%20actually%20hitting%20the%20web%20service%20when%20testing.%20And" title="Digg"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  target="_blank" href="http://delicious.com/post?url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F10%2F01%2Fmocking-http-request-and-response-with-python-and-mox%2F&amp;title=Mocking%20HTTP%20request%20and%20response%20with%20Python%20and%20Mox&amp;notes=I%20recently%20started%20integrating%20with%20some%20web%20services%20in%20Python%20and%20wanted%20to%20be%20able%20to%20test%20all%20the%20requests%20and%20responses%20with%20valid%20and%20invalid%20data.%20However%2C%20I%20need%20to%20be%20able%20to%20do%20this%20without%20actually%20hitting%20the%20web%20service%20when%20testing.%20And" title="del.icio.us"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a></li>
	<li class="sociablelast"><a rel="nofollow"  target="_blank" href="http://technorati.com/faves?add=http%3A%2F%2Fblog.agoragames.com%2F2009%2F10%2F01%2Fmocking-http-request-and-response-with-python-and-mox%2F" title="Technorati"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /></a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.agoragames.com/2009/10/01/mocking-http-request-and-response-with-python-and-mox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Suh-weet</title>
		<link>http://blog.agoragames.com/2009/03/22/suh-weet/</link>
		<comments>http://blog.agoragames.com/2009/03/22/suh-weet/#comments</comments>
		<pubDate>Sun, 22 Mar 2009 14:12:10 +0000</pubDate>
		<dc:creator>Brian Corrigan</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[python rrd engineering]]></category>

		<guid isPermaLink="false">http://blog.agoragames.com/?p=241</guid>
		<description><![CDATA[One of our engineers has been doing some work with RRDTool (Round Robin Database); and more specifically PYRRD.  He&#8217;s using it to combine real time usage stats with a prediction algorithm so that we can pre-emptively allocate resources to different parts of the system.  Its real spiffy.
His additions to the PYRRD library just got commited [...]]]></description>
			<content:encoded><![CDATA[<p>One of our engineers has been doing some work with RRDTool (Round Robin Database); and more specifically PYRRD.  He&#8217;s using it to combine real time usage stats with a prediction algorithm so that we can pre-emptively allocate resources to different parts of the system.  Its real spiffy.</p>
<p>His additions to the PYRRD library just got commited to the trunk build, and he&#8217;s credited in the readme.</p>
<p><a href="http://code.google.com/p/pyrrd/source/browse/trunk/ChangeLog" target="_blank">http://code.google.com/p/pyrrd/source/browse/trunk/ChangeLog</a><br />
<a href="http://code.google.com/p/pyrrd/source/browse/trunk/README" target="_blank">http://code.google.com/p/pyrrd/source/browse/trunk/README</a></p>

<div class="sociable">

<ul>
	<li class="sociablefirst"><a rel="nofollow"  target="_blank" href="http://reddit.com/submit?url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F03%2F22%2Fsuh-weet%2F&amp;title=Suh-weet" title="Reddit"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  target="_blank" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F03%2F22%2Fsuh-weet%2F&amp;title=Suh-weet&amp;bodytext=One%20of%20our%20engineers%20has%20been%20doing%20some%20work%20with%20RRDTool%20%28Round%20Robin%20Database%29%3B%20and%20more%20specifically%20PYRRD.%C2%A0%20He%27s%20using%20it%20to%20combine%20real%20time%20usage%20stats%20with%20a%20prediction%20algorithm%20so%20that%20we%20can%20pre-emptively%20allocate%20resources%20to%20different%20" title="Digg"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  target="_blank" href="http://delicious.com/post?url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F03%2F22%2Fsuh-weet%2F&amp;title=Suh-weet&amp;notes=One%20of%20our%20engineers%20has%20been%20doing%20some%20work%20with%20RRDTool%20%28Round%20Robin%20Database%29%3B%20and%20more%20specifically%20PYRRD.%C2%A0%20He%27s%20using%20it%20to%20combine%20real%20time%20usage%20stats%20with%20a%20prediction%20algorithm%20so%20that%20we%20can%20pre-emptively%20allocate%20resources%20to%20different%20" title="del.icio.us"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a></li>
	<li class="sociablelast"><a rel="nofollow"  target="_blank" href="http://technorati.com/faves?add=http%3A%2F%2Fblog.agoragames.com%2F2009%2F03%2F22%2Fsuh-weet%2F" title="Technorati"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /></a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.agoragames.com/2009/03/22/suh-weet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python Is Mocking Me: A Ruby Programmer&#8217;s Adventures With Python/Mox</title>
		<link>http://blog.agoragames.com/2009/02/23/python-is-mocking-me-a-ruby-programmers-adventures-with-pythonmox/</link>
		<comments>http://blog.agoragames.com/2009/02/23/python-is-mocking-me-a-ruby-programmers-adventures-with-pythonmox/#comments</comments>
		<pubDate>Mon, 23 Feb 2009 17:16:39 +0000</pubDate>
		<dc:creator>Tim Jones</dc:creator>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.agoragames.com/?p=201</guid>
		<description><![CDATA[Overview
Much of Agora&#8217;s work over the last few years has been done in Ruby.  Recently though, we&#8217;re migrating major components to Python in order to enjoy the benefits of cross platform compatibility with Windows.  The purpose of this post is to discuss testing in Python; specifically mocking.

Coming from Ruby I&#8217;ve so far found [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Overview</strong></p>
<p>Much of Agora&#8217;s work over the last few years has been done in Ruby.  Recently though, we&#8217;re migrating major components to Python in order to enjoy the benefits of cross platform compatibility with Windows.  The purpose of this post is to discuss testing in Python; specifically mocking.<br />
<span id="more-201"></span><br />
Coming from Ruby I&#8217;ve so far found the mocking frameworks in Python somewhat lacking.  I haven&#8217;t found a case where I&#8217;ve been unable to implement a particular test in Python but I&#8217;ve certainly found myself doing a lot more typing than I would in Ruby/Mocha.  Perhaps this is just a sign that the Python libraries need further abstraction to provide higher-level interfaces.  I think it also points to the fact that metaprogramming magic is much simpler in Ruby.</p>
<p>A quick and dirty list of some available mocking frameworks can be found here (<a href="http://pycheesecake.org/wiki/PythonTestingToolsTaxonomy#MockTestingTools">http://pycheesecake.org/wiki/PythonTestingToolsTaxonomy#MockTestingTools</a>).  We chose Mox primarily because it presented most of the functionality we were used to with Mocha and the interface was concise (relatively speaking&#8230;).</p>
<p><strong>The Basics</strong></p>
<p>Mox uses a record/replay format for creating mocks.  Mocks are initialized with the system in record mode.  All method calls executed on the mocks are recorded in order to be played back later.  This is similar to Mocha, although Mocha makes this less explicit and does not enforce order.  For comparison:</p>
<p>Ruby/Mocha:<br />
<code></p>
<pre class="brush: ruby">
class Foo
  def do_something
    self.first_thing
    self.second_thing
  end
end

f = Foo.new
f.expects(:second_thing).once
f.expects(:first_thing).once

f.do_something
</pre>
<p></code><br />
Python/Mox:<br />
<code></p>
<pre class="brush: python">
class Foo(object):
  def do_something(self):
    self.first_thing()
    self.second_thing()

self.mox = mox.Mox()
f = self.mox.CreateMock(Foo)

f.first_thing()
f.second_thing()
self.mox.ReplayAll()

f.do_something()
self.mox.VerifyAll()
</pre>
<p></code></p>
<p>Note, these are not complete examples and they will not run by themselves.  We&#8217;ll get to that in a bit.  The important thing is that, in the Python/Mox version, we&#8217;re doing a bit of recording until we get to ReplayAll().  At that point we stop recording and start executing the methods that will cause the recorded portion to be repeated by our running code.  Mox checks off each method as it&#8217;s called and raises exceptions if a call is not expected.</p>
<p><strong>The Complete Example</strong></p>
<p>Mox provides a handy subclass of unittest.TestCase that takes care of a few things for you.  First, self.mox is instantiated in setUp method so you don&#8217;t have to worry about doing that yourself.  Second, and this is left out of the example above, it introduces some metaclass magic that unsets stubs and executes VerifyAll() to confirm that all expectations were met during execution (see the Mox documentation for an explanation of unsetting stubs).  The complete code would look something like this:</p>
<p><code></p>
<pre class="brush: python">
import mox
from foo import Foo

class FooTest(mox.MoxTestBase):
  def test_do_something(self):
    f = self.mox.CreateMock(Foo)

    f.first_thing()
    f.second_thing()
    self.mox.ReplayAll()

    f.do_something()
</pre>
<p></code></p>
<p>If you want to mock an entire object this is great.  It&#8217;s relatively clean and gets the job done.  But what if I want to stub out a single method of an already instantiated object?  Enter StubOutWithMock.</p>
<p><code></p>
<pre class="brush: python">
class FooTest(mox.MoxTestBase):
  def test_do_something(self):
    f = Foo()
    self.mox.StubOutWithMock(f, &#039;second_thing&#039;)

    f.second_thing()
    self.mox.ReplayAll()

    f.do_something()
</pre>
<p></code></p>
<p>In this example I&#8217;ve instantiated my own instance of Foo and allowed the first_thing method to get called normally.  The second_thing method is mocked out.  I could add return values and whatnot to the mock here if necessary.</p>
<p>These are just two simple examples but they&#8217;ll cover a lot of cases.  Mox really handles them quite well.  Where I think it starts to fall behind Mocha is when it comes to dealing with more complex tasks such as introducing mocks for locally instantiated objects.  Ultimately I think the Mox library just needs a bit more abstraction to handle these cases.</p>
<p><strong>The Hard(er) Stuff</strong></p>
<p>Some folks <a href="(http://googletesting.blogspot.com/2008/08/by-miko-hevery-so-you-decided-to.html">(http://googletesting.blogspot.com/2008/08/by-miko-hevery-so-you-decided-to.html</a>) are of the opinion that your code should be written with testing in mind.  I couldn&#8217;t disagree more (although I think there are many good points that can be taken from that article for reasons outside of testing).  I should _not_ have to change the way I write code to make up for flaws in my testing framework.  In some languages it may not be possible to support every test case without some extra consideration (compiled, strongly-typed, minimal-reflection languages come to mind although I&#8217;ve had excellent luck with MockItNow (<a href="http://code.google.com/p/mockitnow/">http://code.google.com/p/mockitnow/</a>) for C++ under Visual Studio) but we&#8217;re working with highly abstracted scripting languages here!  There really shouldn&#8217;t be a reason to change the way you code just to support testing.  Let&#8217;s see what we can do.</p>
<p><strong>Local Object Construction</strong></p>
<p style="border: 1px dashed red; padding: 5px;">Note: Since this post was original written I&#8217;ve been shown a much more elegant way to mock local object construction.  See comment #6 for details.</p>
<p>In the everything&#8217;s-an-object land of Python and Ruby objects are instantiated left and right.  Most are created in local scopes.  What happens when you want to mock out methods of an object that&#8217;s instantiated inside of a function?  Take the following code:</p>
<p><code></p>
<pre class="brush: python">
class Bar(object):
  def do_something(self, something):
  o = SomeOtherClass()
  result = o.crazy_thing_not_to_be_tested(something)
  return self.do_something_else(result)
</pre>
<p></code></p>
<p>In our unit test what we really want to do is make sure that the result of crazy_thing_not_to_be_tested is being passed to do_something_else.  Since the implementation of crazy_thing_not_to_be_tested is crazy (and because this is a unit test, not a functional one) we want to mock it out and return something simple.  With Mocha I could use SomeOtherClass.any_instance but there&#8217;s no such abstraction in Mox.  An alternative might be to change our implementation so that the SomeOtherClass instance is passed to our method instead of being instantiated by it.  In some cases this may work but what if the SomeOtherClass object needs to be initialized with private members of Bar?  Furthermore this means you&#8217;re writing your code for your tests and not vice versa (there are other reasons, unrelated to testing, for why you might be better off passing in the object rather than instantiating it locally but that&#8217;s outside the scope of this post).  It turns out that the Python solution is to mock out the class method that actually instantiates the object.</p>
<p>Object allocation in Python is a two step process.  First the instance is allocated and then the constructor (__init__) is called.  This is similar to Ruby&#8217;s allocate/initialize setup.  The allocate equivalent for Python is __new__.  This method can be mocked like any other.</p>
<pre class="brush: python">
bar = Bar()
self.mox.StubOutWithMock(bar, &#039;do_something_else&#039;)
self.mox.StubOutWithMock(SomeOtherClass, &#039;__new__&#039;)

mocked_some_other_class = self.mox.CreateMockAnything()
SomeOtherClass.__new__(SomeOtherClass, &lt;__init__ args&gt;).AndReturn(mocked_some_other_class)
mocked_some_other_class.crazy_thing_not_to_be_tested(&#039;something&#039;).AndReturn(&#039;something_else&#039;)
mocked_bar.do_something_else(&#039;something_else&#039;)
self.mox.ReplayAll()

mocked_bar.do_something_else(&#039;something&#039;)
</pre>
<p><strong>Skipping Constructors</strong></p>
<p>With our new knowledge of __new__ it becomes easier to take care of a few more problems.  Say your constructor does something that you really don&#8217;t want to have executed for every test.  There&#8217;s a good argument here that you shouldn&#8217;t be doing real work in your constructor anyway but in some cases it is desirable.  At any rate, one solution is to instantiate the object using __new__ without calling __init__.  This could be done in your setUp method so that you have the object available for every test in your test case.</p>
<p><code></p>
<pre class="brush: python">
class SomethingTest(mox.MoxTestBase):
  def setUp(self):
    mox.MoxTestBase.setUp(self)

    self.something = Something.__new__(Something)
</pre>
<p></code></p>
<p>Note that the __new__ method takes the class object as its first argument.  You may need to pass in additional arguments for __init__ (although it&#8217;s never called) to match the function definition.</p>
<p>Later, if you actually want the constructor to be called, you can do so explicitly.</p>
<p><code></p>
<pre class="brush: python">
def a_test(self):
  self.something.__init__(*args)
</pre>
<p></code></p>
<p><strong>Mocking Modules</strong></p>
<p>Modules are nothing special, including those that are part of standard libraries.  Mock away!</p>
<pre class="brush: python">
import os

self.mox.StubOutWithMock(os, &#039;listdir&#039;)
os.listdir(&quot;.&quot;).AndReturn([&quot;a_dir&quot;, &quot;a_link&quot;, &quot;cat.py&quot;, &quot;dog.py&quot;, &quot;goat.txt&quot;, &quot;.svn&quot;])
</pre>
<p><strong>Mocking Builtin Methods</strong></p>
<p>The route to mocking builtin methods is a bit more involved but not terribly so.  The first question is how to access the methods to mock them.  StubOutWithMock takes an object and the name of the method to mock.  We know the name of the method but what&#8217;s the object?  For those with Python experience it will seem obvious that the answer is the __builtin__ module which houses all of Python&#8217;s builtin methods.  The way I found to access that module was via sys.modules:</p>
<pre class="brush: python">
import sys

self.mox.StubOutWithMock(sys.modules[&#039;__builtin__&#039;], &#039;open&#039;)

stream = self.mox.CreateMockAnything()
sys.modules[&#039;__builtin__&#039;].open(&#039;foo.yml&#039;, &#039;r&#039;).AndReturn(stream)
</pre>
<p><strong>Mocking Your Parents</strong></p>
<p>Sometimes its necessary to prevent the super class implementation of a method from being called during a test.  This is actually very easy to accomplish and the implementation is relatively intuitive.</p>
<p>To call a parent class implementation in Python you&#8217;d do something like this:</p>
<p><code></p>
<pre class="brush: python">
class HouseCat(Feline):
  def walk(self):
    self.act_crazy()
    Feline.walk(self)
</pre>
<p></code></p>
<p>All we&#8217;re doing is passing self directly to the Feline implementation of the walk method.  So, all we need to do to mock out the Feline version is:</p>
<pre class="brush: python">
self.mox.StubOutWithMock(Feline, &#039;walk&#039;)

cat = HouseCat()
Feline.walk(cat)
self.mox.ReplayAll()

cat.walk()
</pre>
<p>Now self.act_crazy will be executed but the super class implementation of walk will be mocked out.</p>
<p><strong>Sorting Out Errors With MockAnything</strong></p>
<p>There&#8217;s a bug of sorts when using the MockAnything class that causes fun problems (<a href="http://code.google.com/p/pymox/issues/detail?id=3">http://code.google.com/p/pymox/issues/detail?id=3</a>) when Mox attempts to print out results of a failed method call.  The output from Mox usually consists of a series of &#8220;Expected X.  Got Y&#8221; statements.  Well when X or Y includes a MockAnything object we run into a bit of a catch 22.  Python attempts to convert the instance to a string using __repr__ but, since we&#8217;re mocking anything, we don&#8217;t have a real implementation for that method and the object raises an exception to say that the method call for __repr__ was unexpected.  Currently the authors of Mox have not submitted a solution to this problem but there&#8217;s a relatively naive one you can use yourself&#8230;  Just implement the __repr__ method explicitly for MockAnything objects.  Be aware that this will likely (I haven&#8217;t tried it) block attempts to mock the __repr__ method itself and may cause unexpected issues later on.</p>
<p>In the class definition for MockAnything (roughly ln 265 in mox.py) add the following:</p>
<p><code></p>
<pre class="brush: python">
def __str__(self):
  return &quot;&quot;

def __repr__(self):
  return self.__str__()
</pre>
<p></code></p>
<p>MockAnything instances will then be rendered as  in your error output.</p>
<p><strong>Misc Trivia/Pointers/Gotchas</strong></p>
<ul>
<li>Everything is an object in Python so there&#8217;s probably some way to mock everything</li>
<li>Use mox.MoxTestBase as the parent class for all your tests where mocking will be used</li>
<li>If you do this and you have your own setUp method declaration be sure to call the parent class implementation!</li>
<li>Don&#8217;t forget to call self.mox.ReplayAll() before you actually kick off the replay portion of your test<!--__init__--><!--__init__--></li>
</ul>
<p><!--__init__--><!--__init__--><!--__init__--><!--__init__--></__init__></p>

<div class="sociable">

<ul>
	<li class="sociablefirst"><a rel="nofollow"  target="_blank" href="http://reddit.com/submit?url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F02%2F23%2Fpython-is-mocking-me-a-ruby-programmers-adventures-with-pythonmox%2F&amp;title=Python%20Is%20Mocking%20Me%3A%20A%20Ruby%20Programmer%27s%20Adventures%20With%20Python%2FMox" title="Reddit"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/reddit.png" title="Reddit" alt="Reddit" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  target="_blank" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F02%2F23%2Fpython-is-mocking-me-a-ruby-programmers-adventures-with-pythonmox%2F&amp;title=Python%20Is%20Mocking%20Me%3A%20A%20Ruby%20Programmer%27s%20Adventures%20With%20Python%2FMox&amp;bodytext=Overview%0D%0A%0D%0AMuch%20of%20Agora%27s%20work%20over%20the%20last%20few%20years%20has%20been%20done%20in%20Ruby.%20%20Recently%20though%2C%20we%27re%20migrating%20major%20components%20to%20Python%20in%20order%20to%20enjoy%20the%20benefits%20of%20cross%20platform%20compatibility%20with%20Windows.%20%20The%20purpose%20of%20this%20post%20is%20to%20" title="Digg"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/digg.png" title="Digg" alt="Digg" class="sociable-hovers" /></a></li>
	<li><a rel="nofollow"  target="_blank" href="http://delicious.com/post?url=http%3A%2F%2Fblog.agoragames.com%2F2009%2F02%2F23%2Fpython-is-mocking-me-a-ruby-programmers-adventures-with-pythonmox%2F&amp;title=Python%20Is%20Mocking%20Me%3A%20A%20Ruby%20Programmer%27s%20Adventures%20With%20Python%2FMox&amp;notes=Overview%0D%0A%0D%0AMuch%20of%20Agora%27s%20work%20over%20the%20last%20few%20years%20has%20been%20done%20in%20Ruby.%20%20Recently%20though%2C%20we%27re%20migrating%20major%20components%20to%20Python%20in%20order%20to%20enjoy%20the%20benefits%20of%20cross%20platform%20compatibility%20with%20Windows.%20%20The%20purpose%20of%20this%20post%20is%20to%20" title="del.icio.us"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/delicious.png" title="del.icio.us" alt="del.icio.us" class="sociable-hovers" /></a></li>
	<li class="sociablelast"><a rel="nofollow"  target="_blank" href="http://technorati.com/faves?add=http%3A%2F%2Fblog.agoragames.com%2F2009%2F02%2F23%2Fpython-is-mocking-me-a-ruby-programmers-adventures-with-pythonmox%2F" title="Technorati"><img src="http://blog.agoragames.com/wp-content/plugins/var/www/waxer-blog/shared/wp-content/plugins/sociable/images/technorati.png" title="Technorati" alt="Technorati" class="sociable-hovers" /></a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.agoragames.com/2009/02/23/python-is-mocking-me-a-ruby-programmers-adventures-with-pythonmox/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->