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.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.