views:

77

answers:

4

I have an odd problem. I have a unit test that keeps getting stuck in Run Mode. When I run the same test in Debug, with no breakpoints, the test passes every time.

Basically, it is a socket connection test. I first disconnect a socket, and then try to reconnect, and I am trying to check if the reconnection was successful.

Somewhere in the connect code, I check if there was a socket exception. When this happens, the user is presented with some choices in a dialog, while the connection code hangs via an AutoResetEvent, waiting for a decision.

It is this AutoResetEvent that hangs the system. It must be provided by code in the unit test. But my question is, how come this passes in Debug mode? Is there something special about debug mode whereby AutoResetEvents are automatically set by Visual Studio?

EDIT

It was indeed a race condition. I added a delay in the code after my disconnect code, and it works now. But it still strikes me as odd that there is a race condition to begin with. Let me elaborate by pasting some of the code.

This is the test code:

MySystem.FindEquipment(new List<string>(1) { "192.1.1.243:28000" });
MySystem.ConstructSystem();
MySystem.IsConstructedFlag.WaitOne();
Assert.AreEqual(1, MySystem.CommunicationController.HardwareIPList.Count);

PFFrame frame1 = MySystem.Frames["0.x.x"];

Assert.IsTrue(frame1.Disconnect());
Thread.Sleep(100);
Assert.IsTrue(frame1.Connect());

The reason this strikes me, is that I am waiting for a return on the diconnect code, before calling the connect code. The last part of the disconnect code looks like this:

lclSocket.Shutdown(SocketShutdown.Both);
lclSocket.Close();
OnSocketDisconnected(new PFSocketConnectionEventArgs(ipEp));
return true;

Is it be because Socket.Shutdown(), and/or Socket.Close() methods run it threads? Thus, even though I am returning a value from my disconnect code, the socket isn't actually truly disconnected?

+2  A: 

It sounds like a race condition. Debug code usually runs a lot of extra stuff 'under the hood', and that difference in timing is probably throwing your tests off.

Of course without seeing code, we really can't help you very much.

C Johnson
It was indeed a race condition..but I still have one more question, please see me edit.
sbenderli
+2  A: 

Most likely because of a threading race. They are very sensitive to timing and the timing in the Debug build will be different. You can use a tool like CHESS to exercise bugs like that.

But use Tools + Attach to Process first. Debug + Break All, Debug + Windows + Threads and look at the thread call stacks. You might be able to see the cause of the race or deadlock.

Hans Passant
+1  A: 

Had a similar issue once where I compared two dates, and expected one date after the other, but because it was executed that fast, they received the same timestamp.

bertolami
A: 

This test is telling you that your code is not properly isolated from the socket library you are using. The code that you are testing should not have to depend upon certain artifacts with-in this library. You need to add an abstraction between the socket library that takes the artifacts into acoount.

The reason I say this is, is what if the socket actually disconnects 123,251 times < 100 mSecs, but the 123,252nd time disconnecting takes 101 mSecs.

I would highly recommend that almost all your unit-testing code not use threading. I look at threading calls of any type in my unit tests as a code smell. usually where I want to see threading issues is at the integration level.

Gutzofter
I know, I hd to add Thread.Sleep in order to make sure that I was trying to reconnect after a complete disconnect. In my disconnect code, I call Shutdown first, then Close. However, I do not yet know of any way to check whether or not the Socket is completely disconnected, and ready for another connection attempt. Any ideas?
sbenderli