While testing my iPhone application, I realized there is no way to test out my worst-case scenario, when there is no disk space. How do we do that? This StackOverflow post lays it out conceptually:
I bet you could also create your own .dmg file with file system of size … say 2Mb and write to it. If this works, then it is super-easy for testing – you just mount it and switch the path for testing. If the dmg is small enough, you could probably even upload it to the source control.
Let’s do this “in practice”.
Creating and Mounting a New Disk Image in OSX
It doesn’t get easier than this post. Basically open Disk Utility, click on “New Image”. The smallest size you can create is 10.5 MB (we’ll just fill it up). I named mine “iossim”.
Fill It Up to 100%
The Unix command dd can be used to fill up your disk. Against the advice of this post, I’m going to use /dev/urandom, because we’re only filling 10.5MB.
First, though, we need to find the parameters for dd by running df:
$ df Filesystem 512-blocks Used Available Capacity Mounted on /dev/disk2 20480 1544 18936 8% /Volumes/iossim
So, we have 18936 512-K blocks available (I guess the system uses 1544 blocks). Great. Next we run dd to fill up the filesytstem and test using “touch” to see if it really is full:
$ dd if=/dev/urandom of=./test bs=512 count=18936 $ touch hello touch: hello: No space left on device
We are set. Let’s break the iOS simulator now.
Testing the writeToFile method
My program writes strings to a file, and tests if the file write has been successful. With the above modification, I should be able to exercise that flow:
NSString *path = [@"/Volumes/iossim" stringByAppendingPathComponent:[NSString stringWithFormat:@"%f.txt", [date timeIntervalSince1970]] ]; NSError *err = nil; BOOL success = [saveString writeToFile:path atomically:YES encoding:NSASCIIStringEncoding error:&err]; NSLog(@"write to file %@, successful? %i", path, success);
Indeed, success is now set to “NO”.
Final Note: A lot of examples online call these types of functions with error set to nil. But you should set the error parameter to receive meaningful messages (for example, handling NSFileWriteOutOfSpaceError or NSFileWriteVolumeReadOnlyError).
Now set forth and write your Unit Tests!