Unstable unit test result - mock message queue behavior and parallel loop

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
<span style="font-family:Arial,Liberation Sans,DejaVu Sans,sans-serif; font-size:14px I am building a class to use parallel loop to access messages from message queue, in order to explain my issue I created a simplified version of code:
<pre class="prettyprint public class Worker
{
private IMessageQueue mq;
public Worker(IMessageQueue mq)
{
this.mq = mq;
}

public int Concurrency
{
get
{
return 5;
}
}

public void DoWork()
{
int totalFoundMessage = 0;

do
{
// reset for every loop
totalFoundMessage = 0;

Parallel.For&lt;int&gt;(
0,
this.Concurrency,
() =&gt; 0,
(i, loopState, localState) =&gt;
{
Message data = this.mq.GetFromMessageQueue(&quot;MessageQueueName&quot;);

if (data != null)
{
return localState &#43; 1;
}
else
{
return localState &#43; 0;
}
},
localState =&gt;
{
Interlocked.Add(ref totalFoundMessage, localState);
});
}
while (totalFoundMessage &gt;= this.Concurrency);
}
}[/code]
<br/>
<p style="padding-right:0px; font-size:14px; vertical-align:baseline; clear:both; word-wrap:break-word; font-family:Arial,Liberation Sans,DejaVu Sans,sans-serif
The idea is to set the worker class a concurrency value to control the parallel loop. If after each loop the number of message to retrieve from message queue equals to the concurrency number I assume there are potential more messages in the queue and continue
to fetch from queue until the message number is smaller than the concurrency. The TPL code is also inspired by  http://stackoverflow.com/questions/14364374/tpl-data-parallelism-issue" style="margin:0px; padding:0px; border:0px; vertical-align:baseline; background-color:transparent; color:#4a6b82; text-decoration:initial TPL
Data Parallelism Issue  post.
<p style="padding-right:0px; font-size:14px; vertical-align:baseline; clear:both; word-wrap:break-word; font-family:Arial,Liberation Sans,DejaVu Sans,sans-serif
I have the interface to message queue and message object.
<pre class="prettyprint public interface IMessageQueue
{
Message GetFromMessageQueue(string queueName);
}

public class Message
{
}[/code]
<br/>
<p style="padding-right:0px; font-size:14px; vertical-align:baseline; clear:both; word-wrap:break-word; font-family:Arial,Liberation Sans,DejaVu Sans,sans-serif
<span style="font-family:Arial,Liberation Sans,DejaVu Sans,sans-serif; font-size:14px Thus I created my unit test codes and I used Moq to mock the <code style="margin:0px; padding:1px 5px; border:0px; font-size:14px; vertical-align:baseline; background-color:#eeeeee; font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif IMessageQueue[/code]<span style="font-family:Arial,Liberation Sans,DejaVu Sans,sans-serif; font-size:14px  interface
<pre class="prettyprint [TestMethod()]
public void DoWorkTest()
{
Mock&lt;IMessageQueue&gt; mqMock = new Mock&lt;IMessageQueue&gt;();

Message data = new Message();

Worker w = new Worker(mqMock.Object);

int callCounter = 0;
int messageNumber = 11;
mqMock.Setup(x =&gt; x.GetFromMessageQueue(&quot;MessageQueueName&quot;)).Returns(() =&gt;
{
callCounter&#43;&#43;;
if (callCounter &lt; messageNumber)
{
return data;
}
else
{
// simulate MSMQs behavior last call to empty queue returns null
return (Message)null;
}
}
);

w.DoWork();

int expectedCallTimes = w.Concurrency * (messageNumber / w.Concurrency);
if (messageNumber % w.Concurrency &gt; 0)
{
expectedCallTimes &#43;= w.Concurrency;
}

mqMock.Verify(x =&gt; x.GetFromMessageQueue(&quot;MessageQueueName&quot;), Times.Exactly(expectedCallTimes));
}[/code]
<br/>
<p style="padding-right:0px; font-size:14px; vertical-align:baseline; clear:both; word-wrap:break-word; font-family:Arial,Liberation Sans,DejaVu Sans,sans-serif
I used the idea from  http://stackoverflow.com/questions/14368380/moq-to-set-up-a-function-return-based-on-called-times" style="margin:0px; padding:0px; border:0px; vertical-align:baseline; background-color:transparent; color:#4a6b82; text-decoration:initial Moq
to set up a function return based on called times  to set up call times based response.
<p style="padding-right:0px; font-size:14px; vertical-align:baseline; clear:both; word-wrap:break-word; font-family:Arial,Liberation Sans,DejaVu Sans,sans-serif
During the unit testing I noticed the testing result is unstable, if you run it multiple times you will see in most cases the test passes, but occasionally the test fails for various reasons.
<p style="padding-right:0px; font-size:14px; vertical-align:baseline; clear:both; word-wrap:break-word; font-family:Arial,Liberation Sans,DejaVu Sans,sans-serif
I have no clue what caused the situation and look for some input from you. Thanks
<
Welcome to help me with my open source project at http://code.google.com/p/batch-image-watermark-processor/

View the full article
 
Back
Top