With Bitbucket Pipelines you can ramp up Continuous Integration for your project quite fast. At least for the usual setup. But if you need multiple databases on bitbucket pipelines for your tests, you have to be creative.
Why would you need to have multiple test databases on bitbucket pipelines in the first place? Well, in my case I wanted to write functional tests for Typo3. “Shouldn’t be too hard”, I thought, until I found out that the testing framework requires the possibility to create a database for each functional test class (yes, for each class).
I found out that this is not possible on Bitbucket. One MySQL service, one database. Now surely you could add more MySQL services, but it would lead to configuration hell (e.g. one port for each), and you would run out of services very soon since the amount of services is limited. Even worse, you can’t configure the testing framework to use different ports per test class, so why bother at all 🙂
Ok, so how about out using multiple databases on one MySQL service? This would require managing the permissions on a database level, which is also not possible with the existing configuration options. There seems to be no way to use the docker-entrypoint-initdb, or to just drop a command in the service definition like you would do with docker-compose.
The only option I found was to drop a GRANT statement during build times to change the permissions. Here is how it looks:
image: php:7.2.26 pipelines: default: - step: caches: - composer services: - mysql script: - apt-get update -y - apt-get install -y mariadb-client-10.3 # ... and all the other setup stuff ... # The used nimut/testing-framework will generate databases for each test class, so we need to extend permissions - mysql -uroot -plet_me_in -h127.0.0.1 -e 'GRANT ALL ON *.* TO email@example.com IDENTIFIED BY "test_user_password";' - build/run_tests.sh definitions: services: mysql: image: mysql:5.7 variables: MYSQL_DATABASE: 'mydatabase' MYSQL_ROOT_PASSWORD: 'let_me_in' MYSQL_USER: 'test_user' MYSQL_PASSWORD: 'test_user_password'
The most important part here is the
mysql command. We simply grant all permissions to all users on all databases – this service is only used during build time for our CI, so no security risk here. Wait, wait – just to go sure: you wouldn’t do this on production, would you? Alright, great.
Also worth noting is the
apt-get install -y mariadb-client-10.3. The Docker Hub PHP image doesn’t have the mysql client installed. I’m using MariaDB here since I couldn’t find a MySQL package for this distribution.
The testing framework now can generate as many databases as it wants, and still we only use on MySQL service. No further configuration needed if we add more test cases. Sweet.