Blob Blame History Raw
From ae7414c8af759685eea0c17bf7174de71395b917 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Wed, 1 Apr 2020 16:23:05 +0200
Subject: [PATCH] Use UNIX socket authentication with MariaDB 10.4.3
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

MariaDB 10.4.3 changed a default authentication mechanism for UNIX
socket connections. As a result tests stated to fail on failed
authentication.

This patch adjusts dsn() computation and a test to omit the erroneous
user=root parameter.

The same MariaDB also started to enforce setting root password. Since
there is no password management in Test::mysqld, skipped fixing this
part of the code. I only left a comment there.

https://github.com/kazuho/p5-test-mysqld/issues/32
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
 lib/Test/mysqld.pm | 23 +++++++++++++++++++++--
 t/01-raii.t        |  4 +++-
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/lib/Test/mysqld.pm b/lib/Test/mysqld.pm
index 483cf1f..a3fdc10 100644
--- a/lib/Test/mysqld.pm
+++ b/lib/Test/mysqld.pm
@@ -85,10 +85,17 @@ sub dsn {
         if $self->my_cnf->{port};
     if (defined $args{port}) {
         $args{host} ||= $self->my_cnf->{'bind-address'} || '127.0.0.1';
+        $args{user} ||= 'root';
+        if ($self->_use_unix_socket_auth) {
+            # TODO: Set a password,
+            # <https://mariadb.com/kb/en/authentication-from-mariadb-104/>
+        }
     } else {
         $args{mysql_socket} ||= $self->my_cnf->{socket};
+        if (!$self->_use_unix_socket_auth) {
+            $args{user} ||= 'root';
+        }
     }
-    $args{user} ||= 'root';
     $args{dbname} ||= 'test';
     return 'DBI:mysql:' . join(';', map { "$_=$args{$_}" } sort keys %args);
 }
@@ -314,6 +321,18 @@ sub _mysql_version {
     $self->{_mysql_version};
 }
 
+# https://mariadb.com/kb/en/authentication-plugin-unix-socket/
+sub _use_unix_socket_auth {
+    my $self = shift;
+    $self->{_use_unix_socket_auth} = 0;
+    if ($self->_is_maria && defined $self->_mysql_version()) {
+        my ($x, $y, $z) = $self->_mysql_version() =~ /([0-9]+)\.([0-9]+)\.([0-9]+)/;
+        $self->{_use_unix_socket_auth} = ($x > 10 || ($x == 10 && $y > 4)
+            || ($x == 10 && $y == 4 && $z >= 3));
+    }
+    $self->{_use_unix_socket_auth};
+}
+
 sub _mysql_major_version {
     my $ver = shift->_mysql_version;
     return unless $ver;
@@ -427,7 +446,7 @@ Path to C<mysql_install_db> script or C<mysqld> program bundled to the mysqld di
 
 =head2 dsn
 
-Builds and returns dsn by using given parameters (if any).  Default username is 'root', and dbname is 'test'.
+Builds and returns dsn by using given parameters (if any).  Default username depends on a server version and a socket family.  Default dbname is 'test'.
 
 =head2 pid
 
diff --git a/t/01-raii.t b/t/01-raii.t
index 010c119..af5f67b 100644
--- a/t/01-raii.t
+++ b/t/01-raii.t
@@ -18,7 +18,9 @@ my $dsn = $mysqld->dsn;
 
 is(
     $dsn,
-    "DBI:mysql:dbname=test;mysql_socket=$base_dir/tmp/mysql.sock;user=root",
+    $mysqld->_use_unix_socket_auth ?
+        "DBI:mysql:dbname=test;mysql_socket=$base_dir/tmp/mysql.sock" :
+        "DBI:mysql:dbname=test;mysql_socket=$base_dir/tmp/mysql.sock;user=root",
     'check dsn',
 );
 
-- 
2.21.1