Repository: ClearcodeHQ/pytest-mysql (language: python)

Issue:
Run tests on OSX
Run tests and see if there are any issues with running tests on osx


Discussion / hints:
Tests failing on macOS 11.6

```
ERROR tests/test_mysql.py::test_mysql - MySQLdb._exceptions.OperationalError: (2002, "Can't connect to local MySQL server through socket '/private/var/folders/rj/jsz7qk590z1dmrn8x6zbczb00000gn/T/pytest-of-ramazan/pytest-11/pytest-mysql-my' (2)")
ERROR tests/test_mysql.py::test_mysql_test_without_cursor - MySQLdb._exceptions.OperationalError: (2002, "Can't connect to local MySQL server through socket '/private/var/folders/rj/jsz7qk590z1dmrn8x6zbczb00000gn/T/pytest-of-ramazan/pytest-11/pytest-mysql-my' (2)")
ERROR tests/test_mysql.py::test_mysql_newfixture - MySQLdb._exceptions.OperationalError: (2002, "Can't connect to local MySQL server through socket '/private/var/folders/rj/jsz7qk590z1dmrn8x6zbczb00000gn/T/pytest-of-ramazan/pytest-11/pytest-mysql-my' (2)")
ERROR tests/test_mysql.py::test_random_port - MySQLdb._exceptions.OperationalError: (2002, "Can't connect to local MySQL server through socket '/private/var/folders/rj/jsz7qk590z1dmrn8x6zbczb00000gn/T/pytest-of-ramazan/pytest-11/pytest-mysql-my' (2)")
ERROR tests/test_mysqlnoproc.py::test_mysql_noproc - MySQLdb._exceptions.OperationalError: (1045, "Access denied for user 'root'@'localhost' (using password: NO)")
ERROR tests/test_mysqlnoproc.py::test_mysql_noproc - subprocess.CalledProcessError: Command 'mysqladmin --socket=/private/var/folders/rj/jsz7qk590z1dmrn8x6zbczb00000gn/T/pytest-of-ramazan/pytest-11/pytest-mysql-mysql_rand_proc0/mysql.47031.sock --user=root shutdown' returned non-zero exit status 1.
```
in my case the overly long path that osx uses by default as a tempdir caused the mysql server to fail to start. 

you can work around this by running `pytest --basetemp=/tmp/pytest`

```
2022-01-05T00:05:59.792572Z 0 [ERROR] [MY-010267] [Server] The socket file path is too long (> 103): /private/var/folders/ks/w4v3szn557z1vkxyt8j52nzh0000gn/T/pytest-of-ben/pytest-18/pytest-mysql-mysql_proc_wg_static_db0/mysql.33307.sock
```

Fix patch:
diff --git a/newsfragments/345.bugfix.rst b/newsfragments/345.bugfix.rst
new file mode 100644
index 00000000..79c0ed5b
--- /dev/null
+++ b/newsfragments/345.bugfix.rst
@@ -0,0 +1,6 @@
+Raise exception with helpful message if unixsocket is too long on FreeBSD or MacOS system
+
+OSX gives out super long temp directories.  This isn't a problem until
+we run into an odd 103-character limit on the names of unix sockets
+`see this stackoverflow thread <https://unix.stackexchange.com/questions/367008/why-is-socket-path-length-limited-to-a-hundred-chars/367012#367012>`_.
+Here we warn and give the user a way out of it.


Test patch:
diff --git a/pytest_mysql/exceptions.py b/pytest_mysql/exceptions.py
index dbf9290b..f85ade8d 100644
--- a/pytest_mysql/exceptions.py
+++ b/pytest_mysql/exceptions.py
@@ -17,5 +17,13 @@ def __init__(self, output: str) -> None:
         super().__init__("Could not detect version in {}".format(output))
 
 
+class SocketPathTooLong(PytestMySQLException):
+    """
+    Exception raised the socket path is over 103 chars.
+
+    Raised on BSD/MacOS as Mysql will fail to start.
+    """
+
+
 class DatabaseExists(PytestMySQLException):
     """Raise this exception, when the database already exists."""
diff --git a/pytest_mysql/executor.py b/pytest_mysql/executor.py
index 68c62798..2747250b 100644
--- a/pytest_mysql/executor.py
+++ b/pytest_mysql/executor.py
@@ -1,15 +1,19 @@
 """Specified MySQL Executor."""
+import platform
 import re
 import subprocess
 from pathlib import Path
 from typing import Optional, Union, Literal, Any
 
-from mirakuru.base import SimpleExecutorType
 from pkg_resources import parse_version
 
 from mirakuru import TCPExecutor
 
-from pytest_mysql.exceptions import MySQLUnsupported, VersionNotDetected
+from pytest_mysql.exceptions import (
+    MySQLUnsupported,
+    VersionNotDetected,
+    SocketPathTooLong,
+)
 
 
 class MySQLExecutor(TCPExecutor):
@@ -42,7 +46,7 @@ def __init__(
         :param params: string containing additional starting parameters
         :param base_directory: base directory where the temporary files,
             database files, socket and pid will be placed in.
-        :param user: mysql user name
+        :param user: mysql username
         :param host: server's host
         :param port: server's port
         :param timeout: executor's timeout for start and stop actions
@@ -138,6 +142,8 @@ def initialise_mysql_db_install(self) -> None:
 
     def start(self) -> "MySQLExecutor":
         """Trigger initialisation during start."""
+        self._check_socket_path()
+
         implementation = self.implementation()
         if implementation == "mysql" and parse_version(
             self.version()
@@ -174,3 +180,13 @@ def stop(self, *args: Any, **kwargs: Any) -> "MySQLExecutor":
         """Stop the server."""
         self.shutdown()
         return super().stop(*args, **kwargs)
+
+    def _check_socket_path(self) -> None:
+        if (
+            platform.system() in ["Darwin", "FreeBSD]"]
+            and len(self.unixsocket) > 103
+        ):
+            raise SocketPathTooLong(
+                f"Socket path '{self.unixsocket}' is too long, "
+                f"please pass ie. `--basetemp=/tmp/pytest_mysql` to pytest"
+            )