views:

100

answers:

5

Are there any 'good' ways to cause a thread waiting on a recvfrom() call to become unblocked and return with an error?

The motivation for this is to write unit tests for a system which includes a unit that reads UDP datagrams. One of the branches handles errors on the recvfrom call itself. The code isn't required to distinguish between different types of errors, it just has to set a flag.

I've thought of closing the socket from another thread, or do a shutdown on it, to cause recvfrom to return with an error, but this seems a bit heavy handed. I've seen mention elsewhere that sending an over-sized packet would do it, and so set up an experiment where a 16K buffer was sent to a recvfrom waiting for just 4K, but that didn't result in an error. The recvfrom just return 4096, to indicate it had gotten that many bytes.

+1  A: 

You could create a class around the network library and sometimes fail it based on some criteria. You could for example have this network layer fail based on a certain network performance levels, where you emulate errors at certain frequencies.

I have asked a similar question in the past that may help too.

Brian R. Bondy
part of the problem is I've inherited an already existing design, and adding classes would probably ruffle too many feathers, though it may yet come to that
JustJeff
@JustJeff: To minimize code changes you could have a use #define to redefine the functions that you want to emulate errors in. Then you compile with an option on that does all those defines only in your test suite code.
Brian R. Bondy
@Brian R. Bondy - yeah, ideally the unit under test would be deliverable code, and while #defining recvfrom out from under it makes it non-deliverable, I may be able to pitch the argument that "at least the .cpp file isn't mod'd"
JustJeff
@JustJeff or you could do it I guess via compile time defines.
Brian R. Bondy
@Brian R. Bondy - yeah, in that last comment of mine, I was basically saying I liked your suggestion in your 1st comment.
JustJeff
@JustJeff: Ah OK sorry I thought you were saying you would modify the header file but you weren't sure if you were allowed to make any code changes whatsoever. I understand now.
Brian R. Bondy
A: 

I think that a somewhat heavy handed or tricky approach is probably necessary.

Have you tried using ioctl(sock, FIONBIO, to switch the socket into non-blocking mode?

nategoose
A: 

The easiest would probably be sending a signal, though that depends on whether the original code has handlers setup.

Nikolai N Fetissov
A: 

I have never done this in C, but in C#/Java I create wrapper classes around Sockets, TCPClient, etc. Each wrapper class implements an interface I create that represents the methods I'm interested in using. This allows me to use the dependency injection pattern to inject Mocked or stubbed Sockets. Maybe this pattern can help, although you would have to translate for your language.

JoeGeeky
+2  A: 

If the class you're testing is well isolated from the rest of your application, perhaps you could wholesale #include the .c source file from your unit test. Then you can use a macro to #define recvfrom(...) to your own private function solely within the test.

Note that this will expose your private implementation to the unit test; you should still test against the public interface and pretend you can't see the guts. It's pretty hacky, but it at least contains all the ugliness to your unit test, without disrupting the deliverable code.

Matt B.