Can't run tests if password contains /

Created on 6 July 2020, almost 4 years ago
Updated 18 February 2023, over 1 year ago

Problem/Motivation

If a mysql password contains a slash (or presumably other special characters), you can't run tests from the command line. Instead you get an error like this:

1)
Drupal\Tests\rs\Kernel\Form\PurgeBlockFormTest::testPrefixInvalidationsData
InvalidArgumentException: Minimum requirement: driver://host/database

That error ultimately maps back to: Drupal\Core\Database\Connection:: createConnectionOptionsFromUrl ():

  public static function createConnectionOptionsFromUrl($url, $root) {
    $url_components = parse_url($url);
    if (!isset($url_components['scheme'], $url_components['host'], $url_components['path'])) {
      throw new \InvalidArgumentException('Minimum requirement: driver://host/database');
    }

Compare these two string:

  • 'mysql://my_user:SOMEPASS@my.db.host.name:3306/my_db_name' - parse_url() properly parses
  • 'mysql://my_user:SOME/PASS@my.db.host.name:3306/my_db_name' - parse_url() fails to process

^ Now while this may be a little bit obvious when you explicitly pass a --dburl into run-tests.sh, when it's loading the default password from a settings.php file, it becomes less obvious what is happening there.

Proposed resolution

As it may be hard to accurately parse that string (hence the native parse_url() function being unable to do it), it might just be worth noting in the settings.php file, and possibly the UI when you're setting up a new site/password, that /'s may not work with PHPUnit tests. Alternatively, modifying the exception message (Minimum requirement: driver://host/database) to include some sort of notice about passwords containing special characters, would probably make sense as well.

Note: I've only tested this on D8.9 (not on D9 yet). I'm unsure if the removal of simpletest from core renders this bug moot or not. But it does appear the code is the same in D9, so a slightly more expressive error message probably wouldn't hurt in either case.

Remaining tasks

Approve exception saying.

User interface changes

TBD

API changes

None

Data model changes

None

Release notes snippet

TBD

🐛 Bug report
Status

Needs work

Version

10.1

Component
PHPUnit 

Last updated about 2 hours ago

Created by

🇺🇸United States WidgetsBurritos San Antonio, TX

Live updates comments and jobs are added and updated live.
  • Needs issue summary update

    Issue summaries save everyone time if they are kept up-to-date. See Update issue summary task instructions.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇺🇸United States smustgrave

    ('Seriously malformed connection URL provided');
    Not sure about this saying. If an exception is thrown is that not already "serious"
    This error doesn't really tell me what the problem was. How is a user suppose to know it was '/'?

    Tagging for usability for their thoughts also.

    There's a #ux channel we can post if this doesn't get traction eventually.

    Thanks!

  • Status changed to Needs review over 1 year ago
  • 🇨🇭Switzerland stefanos.petrakis Biel, Switzerland

    Good point.
    However, we are not gonna get more information out of parse_url; there is more info about that and references in #6
    The wording itself comes from PHP's manual and ultimately I don't see any options for wording and/or UX enhancements here.

  • 🇫🇮Finland simohell

    To me this feels like an issue of technical implementation.

    Looking at the example strings I feel that relaying on parse_url and failing what is not compatible with a chosen function is something to fix by error messages. It needs annoyingly more work but if I look at the example URLs they would be splitable with something like explode using ":" the one part with "@" and the one with port and db with "/". Some cases you can go around this kind of problems by base64 encoding stuff before passing it as URL and the decoding after splitting. These kind of workarounds probably sound silly and are prone to create other issues but the point is the example cases are manageable. We shouldn't report a valid URL as malformed to user if we just check it against a single function response and not against the definition.

    The least thing would be to return "Seriously malformed or unsupported connection URL provided". For debugging purposes of course it would be usable to be told what was submitted and how it was understood (split by the function) and the solution would be more or less obvious.

    (This reminds me a bit of all the failed domain transfers where the automation didn't accept autogenerated EEP keys that had "'" in them.)

  • 🇫🇮Finland simohell

    We talked about this in usability meeting today, but didn't have time to come into a conclusion about final recommendation.

    I did however notice another thing:

    Does this issue actually affect also /core/modules/sqlite/src/Driver/Database/sqlite/Connection.php where $url is parsed with parse_url() even if the username and password are after that unset?

    PGSQL doesn't seem to override the createUrlFromConnectionOptions function.

  • 🇫🇮Finland simohell

    Sorry for posting a lot of comments while digging deeper. I noticed that Database.php before it calls createConnectionOptionsFromURL in concertDbURLConnectionInfo already does some validation for the URL. For instance a preg_match to check if schema exists in $url and if not, throwing

    throw new \InvalidArgumentException("Missing scheme in URL '$url'");

    Thus I think the validation for password and other possible issues should happen already there prior to calling createConnectionOptionsFromURL. Then I think we would also cover the SQLite version without duplicating code.

    In concertDbURLConnectionInfo() the error messages seem include the $url variable which is in my opinion helpful for the administrator/sitebuilder to fix the issue.

  • Status changed to Needs work over 1 year ago
  • 🇺🇸United States smustgrave

    Moving to NW as it doesn't seem the remaining task has been achieved.

  • 🇺🇸United States benjifisher Boston area

    @smustgrave:

    When you tag an issue for usability review, please make it easy for the usability team to review the issue. I am removing the tag for now. If you still want usability review after updating the issue summary, then you can add the tag again.

    In #9, you mentioned the string Seriously malformed connection URL provided. If that is shown to the user, even when running texts, then it needs attention. The issue summary does not include any steps to reproduce, so I am not sure if that is why you asked for usability review.

    I can give general advice for error messages: they should be descriptive and actionable. In this case, the "descriptive" part should be an explanation that some characters, although valid for MySQL, are not supported by Drupal. The "actionable" part should suggest using a different password.

    I am adding the tag for an issue summary update. Since this issue is a bug report, it should include steps to reproduce. The Proposed resolution should be more specific. For example, if we are adding a comment to settings.php, then what is the proposed text? If one of the Remaining tasks is to finalize the text of an exception message, then include a draft version of the text in the Proposed resolution.

Production build 0.69.0 2024