Closed abrokenjester closed 3 years ago
A possible thing to look into once #2876 has been completed, is to use JUnit 5's Conditional Execution mechanism (see https://junit.org/junit5/docs/current/user-guide/#extensions-conditions) to give us more control. For example by introducing our own condition extension that we can trigger via some cusom annotation on slow tests we could make enabling/disabling the running of these tests easier to deal with than manually adding/removing @Ignore
annotations everywhere.
@hmottestad and @barthanssens I need some opinions from you both.
We clearly have a need to organize the test suite better, so that we can better distinguish between longer-running (integration/compliance) tests and quick/simple (unit) tests. The main need we have is that we can easily distinguish them as part of the build workflow, so that we do not have to run certain expensive/slow tests for every build.
Before we dive into the particulars of that need, a quick overview of how things are currently organized: we currently have a hard distinction between unit tests and compliance/integration tests.
The reason for the separate compliance modules is twofold:
However, in several modules, such as most of the sails, this model has been let go: all tests, both integration and unit tests, are all co-located directly in the main module, instead of in the compliance module. This technically works because they need no downstream dependencies, but it breaks the assumption about using the failsafe plugin to run larger integration/compliance tests, in the integration-test phase.
One way we could address this is to start using file naming conventions to distinguish between integration and unit tests.
We could reconfigure the surefire and failsafe plugins so that they only pick up tests meant for them by means of file name patterns. The default for surefire could be Test.java, and for failsafe IT.java (this is actually the default pattern of the plugin, we override it in the project setup).
If we do this it will allow having integration tests alongside the unit tests in the same module, while still being able to execute them in different phases of the build cycle (and optionally skipping one or the other).
Note that we would still have separate compliance modules for some parts of the framework, but really only for the purpose of avoid circular dependencies.
This setup goes some way towards giving us more control over build/test times, but I think we need something on top of this, to be able to identify particular integration/compliance tests as "slow" or "long-running". The need we have here is that we can disable those specific tests in a normal build (independently from whether we run unit / integration tests or not), but still be able to easily choose to run them, either from the command line, or as part of a separate github action. This is possibly where those conditional executions from Junit 5 might help.
Finally: I believe there is a lot of redundancy in testing, in particular in the SHACL module, and some of the tests in there conflate what is being tested. If I understand correctly, some of these tests are supposed to be checks on native store behavior. Clearly, such tests should not be in the shacl module, but in either the nativestore module itself, or part of a separate compliance module. This needs a cleanup. I'd be grateful, @hmottestad, if you could make an effort in creating some clarity, and perhaps simplifying or removing a few tests that are redundant. Surely, it is not necessary that every single build spends 22 minutes running just the ShaclSail tests.
As an aside: I have long dreamt of a setup where only the tests downstream from code changes are executed - I mean it's ridiculous that I make a change in the Rio parser and all SPARQL compliance tests get executed. But as far as I'm aware there is just no easy way to set that up in combination with Github Actions. If anyone has ideas on how that could be done I'd love to hear it.
We could reconfigure the surefire and failsafe plugins so that they only pick up tests meant for them by means of file name patterns. The default for surefire could be Test.java, and for failsafe IT.java (this is actually the default pattern of the plugin, we override it in the project setup).
Let's do that!
And configure GitHub CI so that there is a new PR action for failsafe tests. That action can be optional, so you can merge without it having finished.
I know the SHACL tests are slow. It is mainly the fuzzing tests that take time. Without those the total test time is what 5 min maybe? Can you point me to the fuzzing tests we have for the NativeStore?
We clearly have a need to organize the test suite better, so that we can better distinguish between longer-running (integration/compliance) tests and quick/simple (unit) tests. The main need we have is that we can easily distinguish them as part of the build workflow, so that we do not have to run certain expensive/slow tests for every build.
Good idea indeed
We could reconfigure the surefire and failsafe plugins so that they only pick up tests meant for them by means of file name patterns. The default for surefire could be Test.java, and for failsafe IT.java (this is actually the default pattern of the plugin, we override it in the project setup).
That's a nice way of handling it... and this distinction is IMHO also useful for developers who are new to (a part of the) codebase
Finally: I believe there is a lot of redundancy in testing, in particular in the SHACL module, and some of the tests in there conflate what is being tested. If I understand correctly, some of these tests are supposed to be checks on native store behavior. Clearly, such tests should not be in the shacl module, but in either the nativestore module itself, or part of a separate compliance module. This needs a cleanup. I'd be grateful, @hmottestad, if you could make an effort in creating some clarity, and perhaps simplifying or removing a few tests that are redundant. Surely, it is not necessary that every single build spends 22 minutes running just the ShaclSail tests.
There isn't actually much redundancy. The slow tests that you point to in the SHACL module are pretty much integration tests. They check what happens when you bombard the ShaclSail with lots of parallel transactions. Unfortunately I've found it to be the case that for some bugs the MemoryStore backed tests will fail more rapidly and for others the NativeStore tests will fail. Most recently there was a deadlock issue in the ShaclSail against the RDFS reasoner which only failed when it was backed by the NativeStore, since the MemoryStore one was too "fast" to get stuck.
The current full validation test cycle runs at close to an hour, 22 minutes of which are taken up by ShaclSail-related tests:
This needs to be cleaned up and reduced:
Apart from the Shacl tests, there are other possible places where the test suite can be cleaned up, e.g. for Elasticsearch.