We should enable more unit testing in TripleO projects to allow better test coverage of code paths not included in CI, make it easier for reviewers to verify that a code change does what it is supposed to, and avoid wasting reviewer and developer time resolving style issues.
Right now there is very little unit testing of the code in most of the TripleO projects. This has a few negative effects:
Additionally, because there are few/no hacking-style checks in the TripleO projects, many patches get -1’d for style issues that could be caught by an automated tool. This causes unnecessary delay in merging changes.
I would like to build out a unit testing framework that simplifies the process of unit testing in TripleO. Once that is done, we should start requiring unit tests for new and changed features like the other OpenStack projects do. At that point we can also begin adding test coverage for existing code.
The current plan is to make use of Python unit testing libraries to be as consistent as possible with the rest of OpenStack and make use of the test infrastructure that already exists. This will reduce the amount of new code required and make it easier for developers to begin writing unit tests.
For style checking, the dib-lint tool has already been created to catch common errors in image elements. More rules should be added to it as we find problems that can be automatically found. It should also be applied to the tripleo-image-elements project.
The bashate project also provides some general style checks that would be useful in TripleO, so we should begin making use of it as well. We should also contribute additional checks when possible and provide feedback on any checks we disagree with.
Any unit tests added should be able to run in parallel. This both speeds up testing and helps find race bugs.
Because of the quantity of bash code used in TripleO, we may want to investigate using a shell unit test framework in addition to Python. I think this can be revisited once we are further along in the process and have a better understanding of how difficult it will be to unit test our scripts with Python. I still think we should start with Python for the reasons above and only add other options if we find something that Python unit tests can’t satisfy.
One possible benefit of a shell-specific unit testing framework is that it could provide test coverage stats so we know exactly what code is and isn’t being tested.
If we determine that a shell unit test framework is needed, we should try to choose a widely-used one with well-understood workflows to ease adoption.
I have done some initial experimentation with using fakeroot/fakechroot to sandbox scripts that expect to have access to the root filesystem. I was able to run a script that writes to root-owned files as a regular user, making it think it was writing to the real files, but I haven’t gotten this working with tox for running unit tests that way.
Another option would be to use real chroots. This would provide isolation and is probably more common than fakeroots. The drawback would be that chrooting requires root access on the host machine, so running the unit tests would as well.
Many scripts in elements assume they will be running as root. We obviously don’t want to do that in unit tests, so we need a way to sandbox those scripts to allow them to run but not affect the test system’s root filesystem.
Adding more tests will increase the amount of time Jenkins gate jobs take. This should have minimal real impact though, because unit tests should run in significantly less time than the integration tests.
Developers will need to implement unit tests for their code changes, which will require learning the unit testing tools we adopt.
goneri has begun some work to enable dib-lint in tripleo-image-elements
These changes should leverage the existing test infrastructure as much as possible, so the only thing needed to enable the new tests would be changes to the infra config for the affected projects.
None of this work should be user-visible, but we may need developer documentation to help with writing unit tests.
There are some notes related to this spec at the bottom of the Summit etherpad: https://etherpad.openstack.org/p/juno-summit-tripleo-ci