A key part of building reliable software is handling the unexpected gracefully—be it invalid input, failing services, or infrastructure failures like power outages. Most bad situations can be simulated with unit tests, fault injection or integration tests, but how do you test that your system preserves data and recovers gracefully in the face of a power outage? Killing your service forcibly doesn’t really do it because your server’s drives will still have power to flush their buffers. The only way to really test how you do in a power outage is to somehow kill power to the server. But how to do so programmatically without combining Twilio and an intern?
One simple, cost-effective way is with Belkin WeMo insight switches ($59 from Amazon). Each switch exposes a series of UPnP services via WiFi that can turn the switch on and off, measure power usage, and query usage history. This means that with our simple wrapper library you can do things like simulate a power failure during a sensitive operation, examine the impact of periodic failures on a workload and measure power draw during demanding workloads.
Using power effeciently is essential to making a successful app. Not only is it rude to drain your users’ batteries but if their phones run out of battery quickly they physically can’t use your app. Sadly, the built-in Instruments energy diagnostics are fairly limited. You can see which major power draws (GPS, screen, cell radio, etc) are currently on but there’s no way to see how much current the device is currently drawing. This is the crucial piece of information because ultimately you want to be able to answer two basic questions:
- How long will the battery last when running my app?
- How much is the battery life extended when I perform a particular optimization?
Powergremlin leverages private APIs to measure the battery’s current capacity over time and determine current draw. Using this information you can easily answer these questions.
Note: Powergremlin only works with iOS 6 and below
The only annoyance is that it’s not immediately clear from the documentation how to enable the WebKit Inspector. Fortunately, this is relatively straightforward.
When you download an application on OS X, the browser sets an extended attribute on the bundle that marks it as being quarantined. Starting in Mountain Lion, non-sandboxed apps with the quarantine flag set must be signed with a Developer ID. In practice, this means that if a user downloads an unsigned application from the internet and runs it, they’ll get an error message much like this one:
Developers who can’t sandbox their app because it needs extensive access to the system, or don’t want to for other reasons, can avoid this problem by getting a Developer ID certificate and signing their app before releasing it.
Signing an app
The first step is to get access to a machine running Mountain Lion. If you don’t have a physical machine with Mountain Lion, you can use VMWare Fusion and run Mountain Lion in a VM. This works quite well and it’s what we use here at Palomino Labs for making sure our apps work on non-developer machines.
Next you’ll need to get a Mac Developer account and generate a Developer ID in the web-based Developer Certificate Utility. Note that if you have a company ADC account, only the team agent can request Developer ID certificates.
Fans of the Mac OS X Activity Monitor might have noticed that it allows you to inspect a process and see which files it has open. Being able to get this information programmatically is useful because it lets you do things like:
- Provide better error messages: instead of saying “File (x) is in use” you can say “File (x) is in use by (some program)”.
- Infer things about what a program is doing: if Textedit has somedocument.rtf open then you know the user is probably
editing somedocument.rtf without having to resort to using the accessibility API.
- Detect suspicious behavior: If a process has a bunch of system files open or a bunch of sockets open that might indicate
it’s up to no good.
This post will walk you through writing
get_process_handles which implements a small subset of the functionality in lsof. You can fork/clone the code at https://github.com/palominolabs/get_process_handles and follow along.
The first step is to make the skeleton app. It does nothing but display the PID requested by the user on the command line and print an error message if the user didn’t supply a valid PID.
Once that’s working we come to the tasty meat of the problem. The key method we’ll use is
proc_pidinfo. Its prototype is
int proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize)