Remix.run Logo
teraflop 4 days ago

You can't easily, automatically test concurrent code for correctness without testing all possible interleavings of instructions, and that state space is usually galactically huge.

It is very easy to write multithreaded code that is incorrect (buggy), but where the window of time for the incorrectness to manifest is only a few CPU instructions at a time, sprinkled occasionally throughout the flow of execution.

Such a bug is unlikely to be found by test cases in a short period of time, even if you have 1000 concurrent threads running. And yet it'll show up in production eventually if you keep running the code long enough. And of course, when it does show up, you won't be able to reproduce it.

That is, I think, what the parent commenter means by "luck".

This is similar to the problem you'll run into when testing code that explicitly uses randomness. If you have a program that calls rand(), and it works perfectly almost all the time but fails when rand() returns the specific number 12345678, and you don't know ahead of time to test that value, then your automated test suite is unlikely to ever catch the problem. And testing all possible return values of rand() is usually impractical.

nick__m 4 days ago | parent | next [-]

There is a cost benefit ratio and context that matters.

The repeat the concurent operations 1000times technique is adequate for a CRUD API but it's whofully inadequate for a database engine or garbage collector.

wubrr 4 days ago | parent | prev | next [-]

It will obviously not catch all bugs. Nothing will. But it is a relatively easy and reliable way to catch many of them. It works.

nijave 3 days ago | parent | prev | next [-]

There's still value in eliminating ways your program can wrong even if you can't eliminate all of them.

Using your logic, why bother testing at all.

afiori 4 days ago | parent | prev [-]

and if you have too many threads running you could have slowdowns in the system that prevent the race condition from happening