Mock Objects in Python
January 6th, 2012
I’ve never liked mock object frameworks. Especially in Java, they were cumbersome to set up and never let me do all the things I wanted to. I always found it quicker just to roll my own mock.
Even in Python I had adopted this practice. Recently, Pulp settled on the Mock framework (http://www.voidspace.org.uk/python/mock/), so I decided to give mock frameworks another shot.
Installation
Installation is nice and simple:
$ easy_install mock
Setup
Even simpler, there’s nothing global you have to do in your unit test setup. When you’re ready to use the mock, instantiate it and go.
Usage
Creating a mock instance is as simple as importing the package and instantiating it. There’s no need to provide any sort of description of what should or should not be supported by the object. For instance:
In [1]: import mock In [2]: m = mock.Mock() In [3]: m.foo() Out[3]: <Mock name='mock.foo()' id='22148496'>
That aspect alone is really cool. There’s no arcane setup I need to remember to do when writing my unit test. I want a mock, I create it, and go on with life.
Behavior
Of course, as cool as such little setup is, it also doesn’t really give us all that much on its own.
Modifications to the behavior of an individual method on the mock are done by setting attributes on the method itself. Again, there’s no setup step to let the mock know it should support a method. You just set the behavior on the method and the mock magically remembers it.
For example, to simulate a return value to the foo method above:
In [4]: m.foo.return_value = 'fus ro dah' In [5]: m.foo() Out[5]: 'fus ro dah'
All good unit tests should exercise error conditions too, which is done through the side_effect attribute:
In [7]: m.foo.side_effect = Exception() In [8]: m.foo() --------------------------------------------------------------------------- Exception Traceback (most recent call last) /home/jdob/<ipython-input-8-518df19c1ba0> in <module>() ----> 1 m.foo() [snip]
Assertions
Chances are, your mock is being called deep within another method that’s being tested. You’ll want to know that the method being tested is actually calling the mock and that it’s passing the correct values. Again, this information is provided as attributes on the mock’s method object.
If I want to make sure my method is actually calling the mock, I can determine how many times a particular method has been invoked:
In [6]: m.foo.call_count Out[6]: 2
If I’m really careful in my tests, I want to make sure the proper values are being passed to the mock. This is especially important in Python where it’s all too easy to reverse the order of parameters in the invocation. This check is a bit tricker since it returns the call arguments in a tuple. The first entry in the tuple is any ordered arguments and the second is any keyword arguments.
In [12]: m.bar('wombat', 'zombie', blah='blargh') Out[12]: <Mock name='mock.bar()' id='23023760'> In [13]: m.bar.call_args[0] Out[13]: ('wombat', 'zombie') In [14]: m.bar.call_args[1] Out[14]: {'blah': 'blargh'}
Clean Up
If you’re doing multiple runs that use the same mock, you’ll want to reset the state of the mock between runs. The thing to remember here is that it doesn’t reset the return value or side effects of any methods you’ve configured. That’s important to keep in mind if your tests individually pass but when run as a suite start to fail; chances are you have a rogue side effect on a method that hasn’t been cleaned up.
Resetting the mock is done through the reset_mock method on the mock itself:
In [15]: m.foo.call_count Out[15]: 3 In [16]: m.reset_mock() In [17]: m.foo.call_count Out[17]: 0
And Beyond
There’s obviously more to the Mock framework than I’ve outlined. I’ve covered the basics and things I use on a regular basis. Their documentation is pretty solid; in particular I have the Mock class documentation (http://www.voidspace.org.uk/python/mock/mock.html) bookmarked to quickly refer to.
Go forth and test
Summer Project: Painting
July 1st, 2010
I wasn’t too thrilled about starting on the painting. I used to paint miniatures, so my sense of scale is drastically different. It’s also a massive mentality shift. When painting miniatures, if I messed up I could just put another coat of paint on the error. RC cars, on the other hand, are painted on the inside to protect the paint, which means the first paint on a spot wins.
The first step was easy: clean the mold.
I started with the wheels so I could attach them and take it for a test drive (I’ll comment more on the test drive later, but suffice it to say there were lessons learned at the expense of my wife’s garden). After playing around with the fitting of the spokes, I figured I could do a two color approach if I offset the inner and outer pieces. The inner pieces were sprayed green:
One thing I didn’t expect was for the spray paint smell to be so strong. We have a two car garage, so I expected to be able to leave the garage door closed. I was woozy before I finished the first side. Once they dried, getting them into the tire was a challenge. Twenty minutes and a lot of cursing later, I had the wheels assembled and attached.
Now that the easy part was done, I had to wrap my head around the masking process. Thankfully, the model came with window masks, so I didn’t need to fit them myself to keep the windows transparent.
The flame masks weren’t quite as tricky as I expected. There were some little bubbles around the edges I couldn’t completely get out, but again I needed to get out of the miniatures mentality and start to think more in terms of the project at hand. Plus, I’ll inevitably drive the damn thing into a wall the first time I drive it and mess the body up anyway, so being anal retentive about barely visible paint blurs is a bit of a moot point.
The body spray was fun. And by fun, I mean there was enough in the air that I was tripping balls by the end of it.
A few coats later and a few braincells less, I removed the masks and got ready for the green.
After that, it wasn’t too much more to finish assembly:
At that point, it was time for a test drive, but I’ll post about that later.
Summer Project: Body Finished
June 6th, 2010
“Did your kit come with a speed controller?”
“Um…”
I hadn’t actually looked at any of the electronics that came with my car, I just knew I needed a radio for it. Luckily, the guys at Hobbytown are patient. Equipped with the all important steering servo in hand, I was ready to get back to work.
I’m the kind of geek that buys computer cases with windows on the side and is compulsive about hiding all the wires, so when I took a look at the electrical system in the car I felt confident I was in an area I knew.
As much as I want to brag that the wiring was really simple, I haven’t yet actually put a battery on it and tried it out. So for all I know, this thing is gonna go up in flames the first time I try to drive it.
The other interesting components were the rear dampeners. There was a lot of room to play around here between spacers and choice of oil. I went with a softer oil figuring I’ll need it since our streets still haven’t been top coated and look like a damn mine field. I made note of how to unattach them if I ever decide to go back and change that.
For the most part, the body is done. I want to paint the hubcaps (I am from NJ afterall) before I put the tires on, so once that’s done I can take the naked car for a quick ride around my basement to make sure everything is wired correctly and there’s nothing grinding. The next big step is painting, which I’ll admit is intimidating. I’m pretty sure I’m set on a color scheme and the masks I want to use, so it’s just a matter of another trip to the hobby store to pick them up.
Summit 2010 Lab
June 4th, 2010
Only just over 2 weeks left until Red Hat Summit 2010. Be sure to check out my lab on Wednesday afternoon:
Cloud Computing with Red Hat Enterprise Linux on Amazon EC2
Cloud computing is fast becoming a core component of both Web and enterprise IT infrastructure architectures. With Red Hat Enterprise Linux on Amazon EC2, you are able to experience both the dynamic scalability of the Amazon EC2 cloud combined with the enterprise stability and security of Red Hat Enterprise Linux.Presented by Red Hat and sponsored by Amazon Web Services, this lab tutorial will walk participants through a complete lifecycle process of setting up Red Hat Enterprise Linux on Amazon EC2, accessing running images, and terminating those instances using both Red Hat and Amazon tools.
Guaranteed to be 100% awesome.
Summer Project: First Steps
June 2nd, 2010
For the last few weeks I have been looking around for a summer hobby. I wanted something non-computer, creative, and that would give me something to show for it at the end. Wired’s Geek Dad blog mentioned RC cars in a post and a few google searches later, I had found my muse. As fate would have it there is a Hobbytown about 30 minutes away, so a Memorial Day weekend trip later I was home with my first project.
Since I don’t know squat about neither RC cars nor real ones, my criteria was simply what I thought looked cool at the time. Like any good (read: compulsive) geek, I’ve been researching the hell out of the topic, so I’m sure my next purchase will be a bit more educated. That said, so far I’m not at all disappointed in my choice.
I actually expected to be more intimidated at the unboxing. It’s definitely not a 45 minute project, but it’s also not impossible. I took a spare table from the garage and set up my new “pit table” portion of my man cave.
The first assembly was the gearbox. My hands were covered in grease so I didn’t take any good pictures of the process, which sucks since it’s much cooler to see the inside than the finished product. So far, so good though; I’m able to turn the axel without hearing any grinding (just some kinda disturbing grease squishing as it settles in).
Once I got the gearbox and motor attached, I hit my first roadblock. I’m at the step where I attach the radio and steering to it. The problem? I don’t have them yet. This also happened on Memorial Day Monday which meant Hobbytown was closed, so this is where things stand for now.
I’m hoping to get the radio attached pretty soon so I can make sure everything is happy between the motor and gearbox. The programmer geek in me lamented the fact that I have to go pretty far before I can actually test to see if my earlier assemblies work, but I may just be taking an unreasonable approach. I’m also starting to think through painting ideas for the body, which will probably end up either really cool or a complete disaster. More pictures on that when I get to it.
Geek of the Caribbean
May 4th, 2010
In a few weeks, we’re heading to Disney World for a much needed vacation. We’re bringing my parents to help with my 3 year old daughter (read: so grandma can buy her ice cream while we go on the good rides).
When we were young, my dad would bring a pager from work in case they needed to contact him. If they did, he’d look around for a public phone to call in and help fix whatever problem they stumbled into.
Never missing an opportunity to make him feel old, I felt obligated to point out to him how things have changed:
Me: ya know, in theory, i could SSH from my phone into a server while waiting on line for Pirates of the Caribbean
Me: actually, even without that i could blog/tweet/facebook status from my phone that I’m at Disney, waiting for Pirates of the Caribbean
Me: that’s after I text message my friends to brag that I’m about to go on Pirates of the Caribbean
Me: and if I want to go low tech, I could always email my team at work to piss them off by pointing out that I’m about to go on Pirates of the Caribbean
Dad: couldn’t you just call them to say that?
Me: oh ya, forgot about that
Dad: so will your job be using all those ways to get in touch with you on vacation?
Me: no, I lied and gave them the wrong number
Getting Started with Amazon EC2 using Python
April 27th, 2010
With the announcement of RHEL’s offering on Amazon Web Services, I wanted to write up some notes from the work I’ve done with EC2 and python. Amazon provides a capable web console, but (not surprisingly) I’d rather do most of my work through a programmable API. The rest of this blog covers the steps necessary to launch an instance, along with some other random notes from my experience.
Boto
The first step is to grab the boto library. Boto is a python interface to Amazon’s web services (not just EC2 but S3 as well). Their site provides downloads, installation instructions, and source, so I won’t go into any more detail besides saying I use it.
Gather Amazon Information
There are a few things needed from your Amazon AWS account in order create and connect to instances, all of which can be retrieved from the AWS web console.
Account Access Keys
The account access keys are effectively your username/password when connecting through boto. From the AWS console, click the Account tab at the top and navigate to Security Credentials. In the middle of the page you’ll find “Access Key ID” and “Secret Access Key”. Make note of these but be sure to keep them safe; these pretty much give full access to your environment.
Key Pairs
The key pairs are used for SSH authentication when connecting to your instances. These are generated through the AWS console itself (the Account tab from the previous section will simply link you back to the AWS console). It’s pretty self-explanatory how to generate a key pair, just be sure to download and then keep the private key safe; there is no way to retrieve a private key from Amazon other than that initial download link.
Image ID
To create an instance, you have to specify which Amazon Machine Image (AMI) to base the instance on. These can be found under the AMIs section of the web console. Determine which image you want based on what it provides and make a note of the ID. It will look something like “ami-12345678″.
Existing Red Hat customers can find more information on Red Hat’s Cloud Access page.
Connect to Amazon
There are two ways of passing your AWS Key and Secret Key to boto, either through environment variables or as arguments to the connect calls. If you choose the environment variable route, they must be named:
AWS_ACCESS_KEY_ID=foo AWS_SECRET_ACCESS_KEY=bar
Once those are set, create a connection to EC2 in python with the following snippet:
import boto ec2conn = boto.connect_ec2()
If you choose to skip the environment variables, the keys can be passed directly to the connect call:
import boto ec2conn = boto.connect_ec2(aws_access_key_id='foo', aws_secret_access_key='bar')
In either case, it is important to realize that these calls default to the US east EC2 region. If you want to make this explicit or, more likely, connect to one of the other two regions, you can pass the optional region argument:
region = # one of 'us-east', 'us-west', 'eu-west' ec2conn = boto.connect_ec2(region=region)
That’s the main connection to EC2 and the one we’ll use for creating instances. There are others with different purposes, such as connecting to S3, the AWS load balancer features, and so on. They are all named “connect_”, so looking through the help for boto will give you a good idea of what’s available.
Create a new Security Group
A security group is basically Amazon’s firewall to your instances. The default security group is pretty restrictive, so we’ll create a new one that allows us access to SSH and HTTP:
name = 'SSH and HTTP Security Group' description = 'Test security group' ec2conn.create_security_group(name, description) group = ec2conn.get_all_security_groups(groupnames=[name])[0] group.authorize(ip_protocol='tcp', from_port='22', to_port='22', cidr_ip='0.0.0.0/0') group.authorize(ip_protocol='tcp', from_port='80', to_port='80', cidr_ip='0.0.0.0/0')
Note: The create_security_group call returns a handle to the group, but I wanted to demonstrate retrieving an existing group as well.
The above should be pretty self-explanatory. The biggest thing to note is the line where the group is retrieved. Since a list is passed to groupnames we get back a list of matching groups. I can’t tell you how many times I attempted to act on the returned result without indexing a specific group inside of it. This is a common pattern all over boto, so you’d think I’d have learned after the first 30 times.
After this is complete, the web console will show a new security group with the firewall holes we created. This will come in handy when we want to SSH into our instance to, ya know, actually do stuff.
Create the Instance
We’re now ready to actually create an instance.
ami_id = 'ami-12345678' ami = ec2conn.get_all_images([ami_id])[0] ssh_key_name = # name of the key pair created above security_groups = # name of the security group created above; must be a list instance_size = # 'm1.large', 'm1.xlarge', etc. see amazon docs for more info reservation = ami.run(key_name=ssh_key_name, security_groups=security_groups, instance_type=instance_size) print('New instance [%s]' % reservation.instances[0].public_dns_name)
The call is pretty simple at this point, we just need to pass in the data we’ve been collecting. Remember the security_groups argument must be a list. Also, keep in mind a reservation is returned from the create call, not the instance itself. The boto documentation can provide more information on the distinction.
SSH into the Instance
The above code should have output the public DNS name of the newly created instance. Once it’s finished starting (you can watch the progress in the web console or there are ways to do it in boto, I just haven’t included them here) you can SSH into it by passing the SSH key created earlier (substitute in the relevant information):
ssh -i $SSH_KEY root@$INSTANCE_DNS
Conclusion
As you’d expect, there is a lot more to boto than just creating instances, such as creating/attaching Elastic Block Storage (EBS) volumes, creating/configuring Elastic Load Balancers (ELB), and adding Autoscaling Groups to load balancers. Many of the APIs look similar to the code used in creating an instance, so it’s just a matter of figuring out what you want to do.

















