-
Notifications
You must be signed in to change notification settings - Fork 781
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Experiment, parallelize some tests #17662
base: main
Are you sure you want to change the base?
Conversation
❗ Release notes required
|
Yeah this will not do much. A lot of test cases write to stdout. We do This needs a systemic approach to deal with stdout capture, maybe xUnit have some mechanism to do this in parallel. |
@majocha guess what, I was going to try the same today :) Thanks for looking into that. Indeed, it seems like we should just damn stop printing everything to the console, it's likely an artifact of older testing approaches. I cannot see any reason to do this instead of just in memory processing. |
xUnit does not run tests from the same module in parallel. It also does not parallelize This can be mitigated by customizing xUnit in code, I think? |
By customizing xUnit you mean setting up some special runner settings and assembly attributes? We can do that. However - I am not a fan of this idea. xUnit's philosophy is really to apply good coding practices to tests. As in, write tests as you write code. Hence, e.g. compared to Nunit, it offers a very limited test platform voodoo (think fixtures, setup/teardown and so on), instead making as much as possible of the builtin language capabilities. And so I would instead prefer keeping up with this philosophy. If, by default, xUnit parallelizes execution on the module level, then we should actually split modules into smaller ones - thereby it will improve code clarity and will generally add to better code organization :) What do you think? |
By customizing I meant something like https://www.meziantou.net/parallelize-test-cases-execution-in-xunit.htm But this is not the most pressing thing and probably not needed if splitting modules would do. The biggest hurdle for now is correctly isolating the console when running tests in parallel. Redirecting with Console writes come from multiple sources:
While we can manage 1. and 2., 3. is a bit harder. |
I've been chatting with Bing / Copilot about it, and it actually proposed a not bad idea: Don't redirect the Console at all for individual tests. Instead install a custom thread splitting |
37918b1
to
932d12c
Compare
Thanks for the further investigations here. In the spirit of my comment above - I just vote for reinventing as few wheels as possible and removing those we've already reinvented here :) Unit tests rarely need any output at all, but if they do - it's good to use those few means that xUnit provides for this, which are basically "plug in the writer if and when you need to". I think it aligns with your thoughts above? It's important to make gradual changes here, probably actually in the way you outline it above. The current direction you're taking (removing stuff) looks promising! Note, I am off until Monday with limited internet connection so cannot play with the code myself. Also, we've discussed this PR internally yesterday and were all very happy that things are moving in this space! |
This is at a state that can be run locally in VS test explorer or from the console with In the CI there's that weird Still, there are some minor fixes here that I'll try to extract to another PR. |
Wow! That was just about an hour! |
That's super promising :) |
Yes, I'm not giving up on that. There's still a lot of room for improvement: In build script it seems we launch test projects in sequence, apart from FSharpSuite that runs in a background task? So the CI run does not get all the benefits yet, but the local runs are much more intense now on the CPU. |
That's correct - one of relatively low hanging fruits is to parallelize stuff on the CI level. The CI matrix is already a bit complex and confusing tho, so this should not be making things even more complex. And yeah, it's PowerShell programming 👀 |
Lines 603 to 614 in f4860a4
Now I think this might have something to do with those OOM exceptions in CI that were happening in this PR. |
That's definitely worth giving a shot :) I don't think this is related to the OOMs. In fact, Tomas made this change to speed up the CI back in a day, it's the only paralellelization we have there really therefore. |
There are two classes of errors that still remain to be dealt with: 1.Timing: timeouts tripping in tests that rely on hardcoded delays like fsharp/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncModule.fs Lines 471 to 481 in 52133d0
Now what the plan is?
|
badecb5
to
3e24367
Compare
I think it's a reasonable direction.
Yes, definitely no need to rewrite all the tests properly. Since those tests don't fail all the time but tend to fail, I'd probably just proactively mark all of them to not run in parallel. Bonus points for creating an item and referencing it in the code - because one of things we are doing here is explaining why things are the way the are :)
Explicit is indeed better than implicit here, reflection is already obscure enough. |
I went for it and modified the Locally, on a i5 13gen I see runtimes around 4 minutes for |
Note that since the matters are very subtle here, I'd probably separate CI parallelization also into a separate PR :) |
Just to see if it works and if it's worth it.