How to unit test a queue with a stream

I need a simple data structure with these requirements:

  • he should behave like a line
  • all enqueue operations must be atomic.

I have very limited multithreading experience, but this is where I came to:

public class Tickets { private ConcurrentQueue<uint> _tickets; public Tickets(uint from, uint to) { Initialize(from, to); } private readonly object _lock = new object(); public void Initialize(uint from, uint to) { lock(_lock) { _tickets = new ConcurrentQueue<uint>(); for (uint i = from; i <= to; i++) { _tickets.Enqueue(i); } } } public uint Dequeue() { uint number; if (_tickets.TryDequeue(out number)) { return number; } throw new ArgumentException("Ticket queue empty!"); } } 

First question: is this code ok?

Secod question: how can I unit test this class (for example, with two threads that periodically perform a decompression operation in a queue with elements (1, 2, 3, 4, 5, 6), and the first thread should get only odd numbers, and second stream - only even numbers)? I tried this, but the statements fail:

 [Test] public void Test() { var tickets = new Tickets(1, 4); var t1 = new Thread(() => { Assert.AreEqual(1, tickets.Dequeue()); Thread.Sleep(100); Assert.AreEqual(3, tickets.Dequeue()); }); var t2 = new Thread(() => { Assert.AreEqual(2, tickets.Dequeue()); Thread.Sleep(100); Assert.AreEqual(4, tickets.Dequeue()); }); t1.Start(); t2.Start(); } 
+4
source share
2 answers

The problem with multithreaded and unit tests is one of the deadlines. When you try to introduce multiple threads for unit tests, you run the risk of irreproducible test results that pass sometimes, but not at other times.

But to explain why your statements cannot be executed, the unit test completes before the threads. He needs to wait for the threads to finish, and not just let them go and continue. It is also possible that the unit test structure itself is not thread safe or is capable of making calls from other threads.

It’s a pity that this is not a solution, but I don’t know a single automated test solution for multithreaded code.

See also: How do I unit test code with a thread?

+4
source

I would use chess: http://research.microsoft.com/en-us/projects/chess

CHESS is a tool for searching and playing Heisenbugs in parallel programs. CHESS runs a parallel test multiple times, ensuring that each run takes a different rotation. If interleaving results in an error, CHESS can replay the interlace to improve debugging. CHESS is available for both managed and native programs.

+5
source

Source: https://habr.com/ru/post/1480724/


All Articles