I am trying to run Drupal browsertests/functional-tests in a Bitbucket pipeline, but always get the following error while doing so:
Exception: Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[HY000]: General error: 8 attempt to write a readonly database: INSERT INTO "test35378103"."watchdog"...
The repository is just an empty/clean Drupal install as we were already facing the same issue on our actual repo. So we thought we would give it a try on a clean install so we could rule out any custom changes we have done.
Did anyone encounter a similar problem before? What is/could be the solution? I am out of ideas...
Happy to provide extra info if needed (and if I am able to share it).
bitbucket-pipelines.yml
image: php:8.2-apache
pipelines:
default:
- step:
name: Run Drupal phpunit (unit and functional)
caches:
- composer
- drush
script:
# Change the docroot of apache to match the bitbucket directory.
- sed -i 's#DocumentRoot /var/www/html#DocumentRoot /opt/atlassian/pipelines/agent/build/web#g' /etc/apache2/sites-available/000-default.conf
- cat /etc/apache2/sites-available/000-default.conf
- sed -i 's#<Directory /var/www/>#<Directory /opt/atlassian/pipelines/agent/build/>#g' /etc/apache2/apache2.conf
# Make sure .htaccess file are taken into account. We are changing this here for all directories listed in the .conf,
# but that is not an issue for this usecase.
- sed -i 's#AllowOverride None#AllowOverride All#g' /etc/apache2/apache2.conf
# Install gd
- apt-get update && apt-get install -y libfreetype-dev libjpeg62-turbo-dev libpng-dev && docker-php-ext-configure gd --with-freetype --with-jpeg && docker-php-ext-install -j$(nproc) gd
# Update the container and install zip so composer can
# use zip to unpack the dependencies.
- apt update -y
- apt install -y zip unzip
# Install dependencies
- curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
- export COMPOSER_ALLOW_SUPERUSER=1
- composer install -o
# Create the folder for the browser-output
- mkdir $(pwd)/web/sites/simpletest
- mkdir $(pwd)/web/sites/simpletest/browser_output
# For testing only: create an empty db-file
- touch $(pwd)/web/sites/simpletest/phpunit.sqlite
# For testing only: set all permissions open
- chown -R www-data:www-data $(pwd)/web/sites/simpletest
- chmod -R 777 $(pwd)/web/sites/simpletest
# Start Apache
- apachectl restart
# Wait for a few seconds to ensure the server starts
- sleep 5
# Check if the server is running and serving the expected content
# This should give a redirect to install.php
- curl -vk http://localhost
# This should also give a redirect to install.php
- curl -vk http://localhost/user
# This should give some output using a sqlite-db
- curl -vk http://localhost/sqlite.php
# Run tests
# Create a link from phpunit.xml to phpunit.xml.dist (as the first one
# is not a part of the repo).
- ln -s phpunit.xml.dist phpunit.xml
# For testing only: set all permissions open
- chown -R www-data:www-data /opt/atlassian/pipelines/agent/build
- chmod -R 777 /opt/atlassian/pipelines/agent/build
# Run tests
- ./vendor/bin/phpunit --debug -v -c $(pwd)/phpunit.xml web/modules/custom/sandbox/Tests/src/Unit
- ./vendor/bin/phpunit --debug -v -c $(pwd)/phpunit.xml web/modules/custom/sandbox/Tests/src/Functional
definitions:
caches:
composer: /root/.composer/cache
drush: ~/.drush/cache
partial content of phpunit.xml(.dist)
<env name="SIMPLETEST_BASE_URL" value="http://localhost"/>
<env name="SIMPLETEST_DB" value="sqlite://localhost//opt/atlassian/pipelines/agent/build/web/sites/simpletest/phpunit.sqlite"/>
<env name="BROWSERTEST_OUTPUT_DIRECTORY" value="/opt/atlassian/pipelines/agent/build/web/sites/simpletest/browser_output"/>
output of the exception in the pipeline
./vendor/bin/phpunit --debug -v -c $(pwd)/phpunit.xml web/modules/custom/sandbox/Tests/src/Functional
PHPUnit 9.6.19 by Sebastian Bergmann and contributors.
Runtime: PHP 8.2.20
Configuration: /opt/atlassian/pipelines/agent/build/phpunit.xml
Testing /opt/atlassian/pipelines/agent/build/web/modules/custom/sandbox/Tests/src/Functional
Test 'Drupal\Tests\sandbox\Functional\SampleTest::testSample' started
Test 'Drupal\Tests\sandbox\Functional\SampleTest::testSample' ended
Time: 00:02.810, Memory: 10.00 MB
There was 1 error:
1) Drupal\Tests\sandbox\Functional\SampleTest::testSample
Exception: Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[HY000]: General error: 8 attempt to write a readonly database: INSERT INTO "test69483024"."watchdog" ("uid", "type", "message", "variables", "severity", "link", "location", "referer", "hostname", "timestamp") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?); Array
(
[0] => 0
[1] => php
[2] => %type: @message in %function (line %line of %file).
[3] => a:6:{s:5:"%type";s:45:"Drupal\Core\Database\DatabaseExceptionWrapper";s:8:"@message";s:4384:"SQLSTATE[HY000]: General error: 8 attempt to write a readonly database: INSERT INTO "test69483024"."cache_data" ("cid", "expire", "created", "tags", "checksum", "data", "serialized") VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6) ON CONFLICT ("cid") DO UPDATE SET "cid" = EXCLUDED."cid", "expire" = EXCLUDED."expire", "created" = EXCLUDED."created", "tags" = EXCLUDED."tags", "checksum" = EXCLUDED."checksum", "data" = EXCLUDED."data", "serialized" = EXCLUDED."serialized"; Array
(
[:db_insert_placeholder_0] => route:[language]=en:/:
[:db_insert_placeholder_1] => -1
[:db_insert_placeholder_2] => 1720006065.735
[:db_insert_placeholder_3] => route_match
[:db_insert_placeholder_4] => 1
[:db_insert_placeholder_5] => a:3:{s:4:"path";s:11:"/user/login";s:5:"query";a:0:{}s:6:"routes";O:41:"Symfony\Component\Routing\RouteCollection":4:{s:49:"Symfony\Component\Routing\RouteCollectionroutes";a:3:{s:10:"user.login";O:31:"Symfony\Component\Routing\Route":9:{s:4:"path";s:11:"/user/login";s:4:"host";s:0:"";s:8:"defaults";a:2:{s:5:"_form";s:31:"\Drupal\user\Form\UserLoginForm";s:6:"_title";s:6:"Log in";}s:12:"requirements";a:1:{s:18:"_user_is_logged_in";s:5:"FALSE";}s:7:"options";a:4:{s:14:"compiler_class";s:33:"Drupal\Core\Routing\RouteCompiler";s:19:"_maintenance_access";b:1;s:4:"utf8";b:1;s:14:"_access_checks";a:1:{i:0;s:30:"access_check.user.login_status";}}s:7:"schemes";a:0:{}s:7:"methods";a:2:{i:0;s:3:"GET";i:1;s:4:"POST";}s:9:"condition";s:0:"";s:8:"compiled";O:33:"Drupal\Core\Routing\CompiledRoute":11:{s:4:"vars";a:0:{}s:11:"path_prefix";s:0:"";s:10:"path_regex";s:18:"{^/user/login$}sDu";s:11:"path_tokens";a:1:{i:0;a:2:{i:0;s:4:"text";i:1;s:11:"/user/login";}}s:9:"path_vars";a:0:{}s:10:"host_regex";N;s:11:"host_tokens";a:0:{}s:9:"host_vars";a:0:{}s:3:"fit";i:3;s:14:"patternOutline";s:11:"/user/login";s:8:"numParts";i:2;}}s:15:"user.login.http";O:31:"Symfony\Component\Routing\Route":9:{s:4:"path";s:11:"/user/login";s:4:"host";s:0:"";s:8:"defaults";a:1:{s:11:"_controller";s:59:"\Drupal\user\Controller\UserAuthenticationController::login";}s:12:"requirements";a:2:{s:18:"_user_is_logged_in";s:5:"FALSE";s:7:"_format";s:4:"json";}s:7:"options";a:3:{s:14:"compiler_class";s:33:"Drupal\Core\Routing\RouteCompiler";s:4:"utf8";b:1;s:14:"_access_checks";a:1:{i:0;s:30:"access_check.user.login_status";}}s:7:"schemes";a:0:{}s:7:"methods";a:1:{i:0;s:4:"POST";}s:9:"condition";s:0:"";s:8:"compiled";O:33:"Drupal\Core\Routing\CompiledRoute":11:{s:4:"vars";a:0:{}s:11:"path_prefix";s:0:"";s:10:"path_regex";s:18:"{^/user/login$}sDu";s:11:"path_tokens";a:1:{i:0;a:2:{i:0;s:4:"text";i:1;s:11:"/user/login";}}s:9:"path_vars";a:0:{}s:10:"host_regex";N;s:11:"host_tokens";a:0:{}s:9:"host_vars";a:0:{}s:3:"fit";i:3;s:14:"patternOutline";s:11:"/user/login";s:8:"numParts";i:2;}}s:21:"entity.user.canonical";O:31:"Symfony\Component\Routing\Route":9:{s:4:"path";s:12:"/user/{user}";s:4:"host";s:0:"";s:8:"defaults";a:2:{s:12:"_entity_view";s:9:"user.full";s:15:"_title_callback";s:48:"Drupal\user\Controller\UserController::userTitle";}s:12:"requirements";a:2:{s:4:"user";s:3:"\d+";s:14:"_entity_access";s:9:"user.view";}s:7:"options";a:4:{s:14:"compiler_class";s:33:"Drupal\Core\Routing\RouteCompiler";s:10:"parameters";a:1:{s:4:"user";a:2:{s:4:"type";s:11:"entity:user";s:9:"converter";s:21:"paramconverter.entity";}}s:14:"_access_checks";a:1:{i:0;s:19:"access_check.entity";}s:4:"utf8";b:1;}s:7:"schemes";a:0:{}s:7:"methods";a:2:{i:0;s:3:"GET";i:1;s:4:"POST";}s:9:"condition";s:0:"";s:8:"compiled";O:33:"Drupal\Core\Routing\CompiledRoute":11:{s:4:"vars";a:1:{i:0;s:4:"user";}s:11:"path_prefix";s:0:"";s:10:"path_regex";s:26:"{^/user/(?P<user>\d+)$}sDu";s:11:"path_tokens";a:2:{i:0;a:5:{i:0;s:8:"variable";i:1;s:1:"/";i:2;s:3:"\d+";i:3;s:4:"user";i:4;b:1;}i:1;a:2:{i:0;s:4:"text";i:1;s:5:"/user";}}s:9:"path_vars";a:1:{i:0;s:4:"user";}s:10:"host_regex";N;s:11:"host_tokens";a:0:{}s:9:"host_vars";a:0:{}s:3:"fit";i:2;s:14:"patternOutline";s:7:"/user/%";s:8:"numParts";i:2;}}}s:50:"Symfony\Component\Routing\RouteCollectionaliases";a:0:{}s:52:"Symfony\Component\Routing\RouteCollectionresources";a:0:{}s:53:"Symfony\Component\Routing\RouteCollectionpriorities";a:0:{}}}
[:db_insert_placeholder_6] => 1
)...
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
(cannot put all info in post: adding here in replies instead)
SampleTest
<?php
namespace Drupal\Tests\sandbox\Functional;
use Drupal\Tests\BrowserTestBase;
class SampleTest extends BrowserTestBase {
protected static $modules = [
'system',
'node',
'dblog',
];
protected $defaultTheme = 'olivero';
protected function setUp(): void {
parent::setUp();
}
public function testSample() {
$this->drupalGet('user');
$this->assertSession()->pageTextContains('Log in');
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.