darraghc
darraghc

Reputation: 58

testing Socket#connect timeout in java

I was investigating an operational issue with a java application recently. There are two processes, processA and processB, running on the same host.

processA makes socket connections to processB. processB restarted, but somehow after restart, all the Socket#connect calls from processA blocked (for minutes).

I think that processB somehow had it's socket in a broken state (receiving SYN's but never responding). The problem fixed itself (automated restarts), so I couldn't capture tcp traffic to be sure.

I know our socket client should have a short timeout on connect (os default seems massive in this case).

I was just curious about how to write a failing test for my socket client.

Is it possible to do something like this:

@Test
public void testClientTimeoutOnConnectionAttempt() {
    startBrokenSocketServer()
    assertConnectionExceptionWithinOneSecond(myClient);
}

I figured out how to manually create these conditions using ipfw and netcat.

 sudo ipfw add 100 drop ip from 127.0.0.1 6969 to any
 nc -l -p 6969

nc listened on 6969, (preventing os from sending rst,ack), and ipfw prevented my java process receiving any syn_ack from nc.

Without any timeout in Socket#connect calls it took 75 seconds (on mac os) before a SocketException. If I specify a timeout, it fails earlier.

The client I need to modify belongs to another team. I'd like to ship them a fix along with an automated test that demonstrates it. Any ideas on how to do that?

Upvotes: 3

Views: 2413

Answers (1)

Gray
Gray

Reputation: 116878

I was just curious about how to write a failing test for my socket client.

I don't think this is possible in Java. You can certainly simulate at lot of netcat's functionality but not ipfw. I'm not even certain it's possible in C unless you do some very OS specific kernel calls.

I think the best you can do from Java is to connect to a non-existant host. You can't just try to connect to an IP on your local network that doesn't exist because the local ethernet hardware may fail it faster. What you want is to connect to an invalid IP on a remote network that you know doesn't exist. Picking a 10-net address which does not correspond to your local network might work.

Lame answer but I don't see any other way offhand.

Upvotes: 2

Related Questions