Package: release.debian.org
Severity: normal
User: release.debian....@packages.debian.org
Usertags: unblock

Hello,
BTS 861511 was reported yesterday against mysql-connector-python stating the new
upstream version (2.1.6) fixes CVE-2017-3590.

The upstream versions diff (attached) is quite important, so i would understand
if you decide not to accept a potential upload of this new version aiming for an
unblock to strech, but i would still like you to have a look and decide on it.

Thanks,
Sandro

-- System Information:
Debian Release: stretch/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: amd64
 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.2.0-1-amd64 (SMP w/8 CPU cores)
Locale: LANG=en_US.utf8, LC_CTYPE=en_US.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
diff --git a/CHANGES.txt b/CHANGES.txt
index 18112d1..6e2c797 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -3,11 +3,23 @@ MySQL Connector/Python 2.1 - Release Notes & Changes
 ====================================================
 
 MySQL Connector/Python
-Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
 
 Full release notes:
  http://dev.mysql.com/doc/relnotes/connector-python/en/
 
+v2.1.6
+======
+
+- BUG#25726671: Fix compatibility issues with the latest Django versions
+- BUG#25558885: Set default connection timeout to pure connector/python
+- BUG#25397650: Verify server certificate only if ssl_verify_cert is True
+- BUG#25589496: Don't convert to unicode if non-ascii data is present
+- BUG#25383644: Add connection back to pool on exception
+- BUG#22476689: Importing world.sql fails with cext enabled
+- BUG#20736339: Expect multiple include directories from mysql_config
+- BUG#19685386: C extension tests are failing using MySQL 5.7.4
+
 v2.1.5
 ======
 
diff --git a/PKG-INFO b/PKG-INFO
index 4af4d6f..9ab448d 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: mysql-connector-python
-Version: 2.1.5
+Version: 2.1.6
 Summary: MySQL driver written in Python
 Home-page: http://dev.mysql.com/doc/connector-python/en/index.html
 Author: Oracle and/or its affiliates
@@ -27,6 +27,8 @@ Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.1
 Classifier: Programming Language :: Python :: 3.2
 Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
 Classifier: Topic :: Database
 Classifier: Topic :: Software Development
 Classifier: Topic :: Software Development :: Libraries :: Application 
Frameworks
diff --git a/README.txt b/README.txt
index 773af0b..46cce18 100644
--- a/README.txt
+++ b/README.txt
@@ -3,7 +3,7 @@ MySQL Connector/Python 2.1
 ==========================
 
 MySQL Connector/Python
-Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
 
 License information can be found in the LICENSE.txt file.
 
@@ -28,7 +28,7 @@ doubt, this particular copy of the software is released
 under the version 2 of the GNU General Public License.
 MySQL Connector/Python is brought to you by Oracle.
 
-Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
 
 License information can be found in the LICENSE.txt file.
 
diff --git a/lib/cpy_distutils.py b/lib/cpy_distutils.py
index e944ce6..04741ea 100644
--- a/lib/cpy_distutils.py
+++ b/lib/cpy_distutils.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -136,21 +136,7 @@ def unix_lib_is64bit(lib_file):
     return False
 
 
-def get_mysql_config_info(mysql_config):
-    """Get MySQL information using mysql_config tool
-
-    Returns a dict.
-    """
-    options = ['cflags', 'include', 'libs', 'libs_r', 'plugindir', 'version']
-
-    cmd = [mysql_config] + [ "--{0}".format(opt) for opt in options ]
-
-    try:
-        proc = Popen(cmd, stdout=PIPE, universal_newlines=True)
-        stdout, _ = proc.communicate()
-    except OSError as exc:
-        raise DistutilsExecError("Failed executing mysql_config: {0}".format(
-            str(exc)))
+def parse_mysql_config_info(options, stdout):
     log.debug("# stdout: {0}".format(stdout))
     info = {}
     for option, line in zip(options, stdout.split('\n')):
@@ -173,7 +159,28 @@ def get_mysql_config_info(mysql_config):
     info['lib_r_dir'] = libs[0].replace('-L', '')
     info['libs_r'] = [ lib.replace('-l', '') for lib in libs[1:] ]
 
-    info['include'] = info['include'].replace('-I', '')
+    info['include'] = [x.strip() for x in info['include'].split('-I')[1:]]
+
+    return info
+
+
+def get_mysql_config_info(mysql_config):
+    """Get MySQL information using mysql_config tool
+
+    Returns a dict.
+    """
+    options = ['cflags', 'include', 'libs', 'libs_r', 'plugindir', 'version']
+
+    cmd = [mysql_config] + [ "--{0}".format(opt) for opt in options ]
+
+    try:
+        proc = Popen(cmd, stdout=PIPE, universal_newlines=True)
+        stdout, _ = proc.communicate()
+    except OSError as exc:
+        raise DistutilsExecError("Failed executing mysql_config: {0}".format(
+            str(exc)))
+
+    info = parse_mysql_config_info(options, stdout)
 
     # Try to figure out the architecture
     info['arch'] = None
@@ -316,7 +323,7 @@ class BuildExtDynamic(build_ext):
                 else:
                     raise OSError("Unsupported platform: %s" % os.name)
 
-                include_dir = os.path.join(connc_loc, 'include')
+                include_dirs = [os.path.join(connc_loc, 'include')]
                 if os.name == 'nt':
                     libraries = ['libmysql']
                 else:
@@ -341,19 +348,20 @@ class BuildExtDynamic(build_ext):
                 log.error(err_version)
                 sys.exit(1)
 
-            include_dir = myc_info['include']
+            include_dirs = myc_info['include']
             libraries = myc_info['libs']
             library_dirs = myc_info['lib_dir']
             self._mysql_config_info = myc_info
             self.arch = self._mysql_config_info['arch']
             connc_64bit = self.arch == 'x86_64'
 
-        if not os.path.exists(include_dir):
-            log.error(err_invalid_loc, connc_loc)
-            sys.exit(1)
+        for include_dir in include_dirs:
+            if not os.path.exists(include_dir):
+                log.error(err_invalid_loc, connc_loc)
+                sys.exit(1)
 
         # Set up the build_ext class
-        self.include_dirs.append(include_dir)
+        self.include_dirs.extend(include_dirs)
         self.libraries.extend(libraries)
         self.library_dirs.append(library_dirs)
 
diff --git a/lib/mysql/connector/abstracts.py b/lib/mysql/connector/abstracts.py
index c83a527..928bd8c 100644
--- a/lib/mysql/connector/abstracts.py
+++ b/lib/mysql/connector/abstracts.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -62,7 +62,7 @@ class MySQLConnectionAbstract(object):
         self._use_unicode = True
         self._get_warnings = False
         self._raise_on_warnings = False
-        self._connection_timeout = None
+        self._connection_timeout = DEFAULT_CONFIGURATION["connect_timeout"]
         self._buffered = False
         self._unread_result = False
         self._have_next_result = False
@@ -231,6 +231,13 @@ class MySQLConnectionAbstract(object):
         except KeyError:
             self._consume_results = False
 
+        # Configure auth_plugin
+        try:
+            self._auth_plugin = config['auth_plugin']
+            del config['auth_plugin']
+        except KeyError:
+            self._auth_plugin = ''
+
         # Configure character set and collation
         if 'charset' in config or 'collation' in config:
             try:
diff --git a/lib/mysql/connector/connection.py 
b/lib/mysql/connector/connection.py
index 453c73e..ebf0c38 100644
--- a/lib/mysql/connector/connection.py
+++ b/lib/mysql/connector/connection.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -78,7 +78,6 @@ class MySQLConnection(MySQLConnectionAbstract):
         self._use_unicode = True
         self._get_warnings = False
         self._raise_on_warnings = False
-        self._connection_timeout = None
         self._buffered = False
         self._unread_result = False
         self._have_next_result = False
@@ -184,6 +183,7 @@ class MySQLConnection(MySQLConnectionAbstract):
 
         Returns subclass of MySQLBaseSocket.
         """
+        # pylint: disable=R0204
         conn = None
         if self.unix_socket and os.name != 'nt':
             conn = MySQLUnixSocket(unix_socket=self.unix_socket)
@@ -191,6 +191,7 @@ class MySQLConnection(MySQLConnectionAbstract):
             conn = MySQLTCPSocket(host=self.server_host,
                                   port=self.server_port,
                                   force_ipv6=self._force_ipv6)
+        # pylint: enable=R0204
         conn.set_connection_timeout(self._connection_timeout)
         return conn
 
@@ -440,14 +441,17 @@ class MySQLConnection(MySQLConnectionAbstract):
                 rows = self._protocol.read_binary_result(
                     self._socket, columns, count)
             else:
-                rows = self._protocol.read_text_result(self._socket, 
self._server_version, count=count)
+                rows = self._protocol.read_text_result(self._socket,
+                                                       self._server_version,
+                                                       count=count)
         except errors.Error as err:
             self.unread_result = False
             raise err
 
         if rows[-1] is not None:
-            ek = rows[-1] # OK or EOF
-            self._handle_server_status(ek['status_flag'] if 'status_flag' in 
ek else ek['server_status'])
+            row = rows[-1]  # OK or EOF
+            self._handle_server_status(row['status_flag'] if 'status_flag' in
+                                       row else row['server_status'])
             self.unread_result = False
 
         return rows
diff --git a/lib/mysql/connector/connection_cext.py 
b/lib/mysql/connector/connection_cext.py
index 9c00a9a..cf29c3b 100644
--- a/lib/mysql/connector/connection_cext.py
+++ b/lib/mysql/connector/connection_cext.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -54,6 +54,7 @@ else:
     HAVE_CMYSQL = True
 # pylint: enable=F0401,C0413
 
+
 class CMySQLConnection(MySQLConnectionAbstract):
 
     """Class initiating a MySQL Connection using Connector/C"""
@@ -64,7 +65,6 @@ class CMySQLConnection(MySQLConnectionAbstract):
             raise RuntimeError(
                 "MySQL Connector/Python C Extension not available")
         self._cmysql = None
-        self._connection_timeout = 2
         self._columns = []
         self.converter = None
         super(CMySQLConnection, self).__init__(**kwargs)
@@ -139,12 +139,11 @@ class CMySQLConnection(MySQLConnectionAbstract):
 
     def _open_connection(self):
         charset_name = CharacterSet.get_info(self._charset_id)[0]
-
-        self._cmysql = _mysql_connector.MySQL(
+        self._cmysql = _mysql_connector.MySQL(  # pylint: disable=E1101
             buffered=self._buffered,
             raw=self._raw,
             charset_name=charset_name,
-            connection_timeout=int(self._connection_timeout or 10),
+            connection_timeout=(self._connection_timeout or 0),
             use_unicode=self._use_unicode,
             auth_plugin=self._auth_plugin)
 
@@ -260,6 +259,7 @@ class CMySQLConnection(MySQLConnectionAbstract):
             raise AttributeError("count should be 1 or higher, or None")
 
         counter = 0
+        # pylint: disable=R0204
         try:
             row = self._cmysql.fetch_row()
             while row:
@@ -278,7 +278,7 @@ class CMySQLConnection(MySQLConnectionAbstract):
             self.free_result()
             raise errors.get_mysql_exception(msg=exc.msg, errno=exc.errno,
                                              sqlstate=exc.sqlstate)
-
+        # pylint: enable=R0204
         return rows
 
     def get_row(self, binary=False, columns=None):
diff --git a/lib/mysql/connector/constants.py b/lib/mysql/connector/constants.py
index 8d27cb0..709e675 100644
--- a/lib/mysql/connector/constants.py
+++ b/lib/mysql/connector/constants.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -686,7 +686,7 @@ class CharacterSet(_Constants):
         return tuple(res)
 
 
-class SQLMode(_Constants):  # pylint: disable=R0921
+class SQLMode(_Constants):
     """MySQL SQL Modes
 
     The numeric values of SQL Modes are not interesting, only the names
diff --git a/lib/mysql/connector/cursor.py b/lib/mysql/connector/cursor.py
index 09b7b54..3002192 100644
--- a/lib/mysql/connector/cursor.py
+++ b/lib/mysql/connector/cursor.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -41,7 +41,7 @@ RE_SQL_ON_DUPLICATE = re.compile(
     re.I | re.M | re.S)
 RE_SQL_INSERT_STMT = re.compile(
     r"({0}|\s)*INSERT({0}|\s)*INTO\s+[`'\"]?.+[`'\"]?(?:\.[`'\"]?.+[`'\"]?)"
-     "{{0,2}}\s+VALUES\s*\(.+(?:\s*,.+)*\)".format(SQL_COMMENT),
+    r"{{0,2}}\s+VALUES\s*\(.+(?:\s*,.+)*\)".format(SQL_COMMENT),
     re.I | re.M | re.S)
 RE_SQL_INSERT_VALUES = re.compile(r'.*VALUES\s*(\(.*\)).*', re.I | re.M | re.S)
 RE_PY_PARAM = re.compile(b'(%s)')
@@ -97,20 +97,27 @@ def _bytestr_format_dict(bytestr, value_dict):
     b'x=%(y)s y=%(x)s'
     """
     def replace(matchobj):
+        """Replace pattern."""
         value = None
         groups = matchobj.groupdict()
         if groups["conversion_type"] == b"%":
             value = b"%"
         if groups["conversion_type"] == b"s":
-            key = groups["mapping_key"].encode("utf-8") \
-                  if PY2 else groups["mapping_key"]
+            key = groups["mapping_key"]
             value = value_dict[key]
         if value is None:
             raise ValueError("Unsupported conversion_type: {0}"
                              "".format(groups["conversion_type"]))
-        return value.decode("utf-8") if PY2 else value
-    return RE_PY_MAPPING_PARAM.sub(replace, bytestr.decode("utf-8")
-                                   if PY2 else bytestr)
+        return bytes(value) if PY2 else value
+
+    stmt = RE_PY_MAPPING_PARAM.sub(replace, bytestr)
+    if PY2:
+        try:
+            return stmt.decode("utf-8")
+        except UnicodeDecodeError:
+            pass
+    return stmt
+
 
 class CursorBase(MySQLCursorAbstract):
     """
@@ -749,10 +756,12 @@ class MySQLCursor(CursorBase):
             can_consume_results = self._connection._consume_results
             for result in self._connection.cmd_query_iter(call):
                 self._connection._consume_results = False
+                # pylint: disable=R0204
                 if self._raw:
                     tmp = MySQLCursorBufferedRaw(self._connection._get_self())
                 else:
                     tmp = MySQLCursorBuffered(self._connection._get_self())
+                # pylint: enable=R0204
                 tmp._executed = "(a result of {0})".format(call)
                 tmp._handle_result(result)
                 if tmp._warnings is not None:
@@ -760,7 +769,7 @@ class MySQLCursor(CursorBase):
                 if 'columns' in result:
                     results.append(tmp)
             self._connection._consume_results = can_consume_results
-            #pylint: enable=W0212
+            # pylint: enable=W0212
 
             if argnames:
                 select = "SELECT {0}".format(','.join(argtypes))
diff --git a/lib/mysql/connector/cursor_cext.py 
b/lib/mysql/connector/cursor_cext.py
index 4dd6e9a..df5fed3 100644
--- a/lib/mysql/connector/cursor_cext.py
+++ b/lib/mysql/connector/cursor_cext.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -28,6 +28,8 @@ from collections import namedtuple
 import re
 import weakref
 
+from _mysql_connector import MySQLInterfaceError  # pylint: disable=F0401,E0611
+
 from .abstracts import MySQLConnectionAbstract, MySQLCursorAbstract
 from .catch23 import PY2, isunicode
 from . import errors
@@ -39,7 +41,6 @@ from .cursor import (
     RE_SQL_SPLIT_STMTS
 )
 
-from _mysql_connector import MySQLInterfaceError  # pylint: disable=F0401
 
 class _ParamSubstitutor(object):
 
@@ -204,7 +205,10 @@ class CMySQLCursor(MySQLCursorAbstract):
                 if exc.errno != CR_NO_RESULT_SET:
                     raise
             i += 1
-            self._executed = executed_list[i].strip()
+            try:
+                self._executed = executed_list[i].strip()
+            except IndexError:
+                self._executed = executed_list[0]
             yield self
         return
 
@@ -429,14 +433,14 @@ class CMySQLCursor(MySQLCursorAbstract):
             results = []
             while self._cnx.result_set_available:
                 result = self._cnx.fetch_eof_columns()
-                # pylint: disable=W0212
+                # pylint: disable=W0212,R0204
                 if self._raw:
                     cur = CMySQLCursorBufferedRaw(self._cnx._get_self())
                 else:
                     cur = CMySQLCursorBuffered(self._cnx._get_self())
                 cur._executed = "(a result of {0})".format(call)
                 cur._handle_result(result)
-                # pylint: enable=W0212
+                # pylint: enable=W0212,R0204
                 results.append(cur)
                 self._cnx.next_result()
             self._stored_results = results
@@ -807,4 +811,3 @@ class CMySQLCursorPrepared(CMySQLCursor):
         super(CMySQLCursorPrepared, self).__init__(connection)
         raise NotImplementedError(
             "Alternative: Use connection.MySQLCursorPrepared")
-
diff --git a/lib/mysql/connector/django/introspection.py 
b/lib/mysql/connector/django/introspection.py
index 77e5503..35b3018 100644
--- a/lib/mysql/connector/django/introspection.py
+++ b/lib/mysql/connector/django/introspection.py
@@ -279,9 +279,8 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
                     'unique': False,
                     'index': False,
                     'check': False,
-                    'foreign_key': (
-                        (ref_table, ref_column) if ref_column else None,
-                    )
+                    'foreign_key': \
+                        (ref_table, ref_column) if ref_column else None
                 }
             constraints[constraint]['columns'].add(column)
         # Now get the constraint types
diff --git a/lib/mysql/connector/django/operations.py 
b/lib/mysql/connector/django/operations.py
index 127750d..8b23290 100644
--- a/lib/mysql/connector/django/operations.py
+++ b/lib/mysql/connector/django/operations.py
@@ -185,6 +185,10 @@ class DatabaseOperations(BaseDatabaseOperations):
                              'value for AutoField.')
         return value
 
+    if django.VERSION > (1, 8):
+        def adapt_datetimefield_value(self, value):
+            return self.value_to_db_datetime(value)
+
     def value_to_db_datetime(self, value):
         if value is None:
             return None
@@ -202,6 +206,10 @@ class DatabaseOperations(BaseDatabaseOperations):
             return datetime_to_mysql(value)
         return self.connection.converter.to_mysql(value)
 
+    if django.VERSION > (1, 8):
+        def adapt_timefield_value(self, value):
+            return self.value_to_db_time(value)
+
     def value_to_db_time(self, value):
         if value is None:
             return None
@@ -218,9 +226,15 @@ class DatabaseOperations(BaseDatabaseOperations):
     def max_name_length(self):
         return 64
 
-    def bulk_insert_sql(self, fields, num_values):
-        items_sql = "({0})".format(", ".join(["%s"] * len(fields)))
-        return "VALUES " + ", ".join([items_sql] * num_values)
+    if django.VERSION < (1, 9):
+        def bulk_insert_sql(self, fields, num_values):
+            items_sql = "({0})".format(", ".join(["%s"] * len(fields)))
+            return "VALUES " + ", ".join([items_sql] * num_values)
+    else:
+        def bulk_insert_sql(self, fields, placeholder_rows):
+            placeholder_rows_sql = (", ".join(row) for row in placeholder_rows)
+            values_sql = ", ".join("({0})".format(sql) for sql in 
placeholder_rows_sql)
+            return "VALUES " + values_sql
 
     if django.VERSION < (1, 8):
         def year_lookup_bounds(self, value):
diff --git a/lib/mysql/connector/errors.py b/lib/mysql/connector/errors.py
index ea354f2..d2eedfb 100644
--- a/lib/mysql/connector/errors.py
+++ b/lib/mysql/connector/errors.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -301,4 +301,5 @@ _ERROR_EXCEPTIONS = {
     2049: NotSupportedError,
     2055: OperationalError,
     2061: InterfaceError,
+    2026: InterfaceError,
 }
diff --git a/lib/mysql/connector/fabric/__init__.py 
b/lib/mysql/connector/fabric/__init__.py
index b3d6a06..c88fe03 100644
--- a/lib/mysql/connector/fabric/__init__.py
+++ b/lib/mysql/connector/fabric/__init__.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -26,6 +26,15 @@
 
 from collections import namedtuple
 
+from .connection import (
+    MODE_READONLY, MODE_READWRITE,
+    STATUS_PRIMARY, STATUS_SECONDARY,
+    SCOPE_GLOBAL, SCOPE_LOCAL,
+    Fabric, FabricConnection,
+    MySQLFabricConnection,
+    FabricSet,
+)
+
 # Order of field_names must match how Fabric is returning the data
 FabricMySQLServer = namedtuple(
     'FabricMySQLServer',
@@ -39,15 +48,6 @@ FabricShard = namedtuple(
      'shard', 'shard_type', 'group', 'global_group']
     )
 
-from .connection import (
-    MODE_READONLY, MODE_READWRITE,
-    STATUS_PRIMARY, STATUS_SECONDARY,
-    SCOPE_GLOBAL, SCOPE_LOCAL,
-    Fabric, FabricConnection,
-    MySQLFabricConnection,
-    FabricSet,
-)
-
 
 def connect(**kwargs):
     """Create a MySQLFabricConnection object"""
diff --git a/lib/mysql/connector/fabric/caching.py 
b/lib/mysql/connector/fabric/caching.py
index a24d6b1..9073498 100644
--- a/lib/mysql/connector/fabric/caching.py
+++ b/lib/mysql/connector/fabric/caching.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -116,32 +116,33 @@ class CacheShardTable(CacheEntry):
     def add_partition(self, key, group):
         """Add sharding information for a group"""
         if self.shard_type == 'RANGE':
-            key = int(key)
+            _key = int(key)
         elif self.shard_type == 'RANGE_DATETIME':
             try:
                 if ':' in key:
-                    key = datetime.strptime(key, "%Y-%m-%d %H:%M:%S")
+                    # pylint: disable=R0204
+                    _key = datetime.strptime(key, "%Y-%m-%d %H:%M:%S")
                 else:
-                    key = datetime.strptime(key, "%Y-%m-%d").date()
+                    _key = datetime.strptime(key, "%Y-%m-%d").date()
             except:
                 raise ValueError(
                     "RANGE_DATETIME key could not be parsed, was: {0}".format(
                         key
                     ))
         elif self.shard_type == 'RANGE_STRING':
-            pass
+            _key = key
         elif self.shard_type == "HASH":
-            pass
+            _key = key
         else:
             raise ValueError("Unsupported sharding type {0}".format(
                 self.shard_type
             ))
-        self.partitioning[key] = {
+        self.partitioning[_key] = {
             'group': group,
         }
         self.reset_ttl()
-        bisect.insort_right(self.keys, key)
-        insort_right_rev(self.keys_reversed, key)
+        bisect.insort_right(self.keys, _key)
+        insort_right_rev(self.keys_reversed, _key)
 
     @classmethod
     def hash_index(cls, part1, part2=None):
@@ -175,6 +176,7 @@ class CacheGroup(CacheEntry):
             group=self.group_name,
         )
 
+
 class FabricCache(object):
     """Singleton class for caching Fabric data
 
diff --git a/lib/mysql/connector/fabric/connection.py 
b/lib/mysql/connector/fabric/connection.py
index 44da175..7e2f657 100644
--- a/lib/mysql/connector/fabric/connection.py
+++ b/lib/mysql/connector/fabric/connection.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -27,13 +27,34 @@ import sys
 import datetime
 import time
 import uuid
-from base64 import b16decode
-from bisect import bisect
-from hashlib import md5
 import logging
 import socket
 import collections
 
+from base64 import b16decode
+from bisect import bisect
+from hashlib import md5
+
+import mysql.connector
+
+from ..connection import MySQLConnection
+from ..conversion import MySQLConverter
+from ..pooling import MySQLConnectionPool
+from ..errors import (
+    Error, InterfaceError, NotSupportedError, MySQLFabricError, InternalError,
+    DatabaseError
+)
+from ..cursor import (
+    MySQLCursor, MySQLCursorBuffered,
+    MySQLCursorRaw, MySQLCursorBufferedRaw
+)
+from .. import errorcode
+from . import FabricMySQLServer, FabricShard
+from .caching import FabricCache
+from .balancing import WeightedRoundRobin
+from .. import version
+from ..catch23 import PY2, isunicode, UNICODE_TYPES
+
 # pylint: disable=F0401,E0611
 try:
     from xmlrpclib import Fault, ServerProxy, Transport
@@ -47,7 +68,7 @@ except ImportError:
 
 if sys.version_info[0] == 2:
     try:
-        from httplib import HTTPSConnection
+        from httplib import HTTPSConnection  # pylint: disable=C0412
     except ImportError:
         HAVE_SSL = False
     else:
@@ -59,26 +80,7 @@ else:
         HAVE_SSL = False
     else:
         HAVE_SSL = True
-# pylint: enable=F0401,E0611
 
-import mysql.connector
-from ..connection import MySQLConnection
-from ..conversion import MySQLConverter
-from ..pooling import MySQLConnectionPool
-from ..errors import (
-    Error, InterfaceError, NotSupportedError, MySQLFabricError, InternalError,
-    DatabaseError
-)
-from ..cursor import (
-    MySQLCursor, MySQLCursorBuffered,
-    MySQLCursorRaw, MySQLCursorBufferedRaw
-)
-from .. import errorcode
-from . import FabricMySQLServer, FabricShard
-from .caching import FabricCache
-from .balancing import WeightedRoundRobin
-from .. import version
-from ..catch23 import PY2, isunicode, UNICODE_TYPES
 
 RESET_CACHE_ON_ERROR = (
     errorcode.CR_SERVER_LOST,
@@ -213,8 +215,7 @@ class MySQLRPCProtocol(object):
             kwargs = self._process_params_dict(kwargs)
             params.extend(kwargs)
 
-        params = ', '.join(params)
-        return params
+        return ', '.join(params)
 
     def execute(self, group, command, *args, **kwargs):
         """Executes the given command with MySQL protocol
@@ -460,7 +461,7 @@ if HAVE_SSL:
             if PY2:
                 urllib2.HTTPSHandler.__init__(self)
             else:
-                super().__init__()  # pylint: disable=W0104
+                super().__init__()  # pylint: disable=W0104,E1004
             self._ssl_config = ssl_config
 
         def https_open(self, req):
@@ -488,7 +489,7 @@ class FabricTransport(Transport):
         if PY2:
             Transport.__init__(self, use_datetime=False)
         else:
-            super().__init__(use_datetime=False)
+            super().__init__(use_datetime=False)  # pylint: disable=E1004
         self._username = username
         self._password = password
         self._use_datetime = use_datetime
diff --git a/lib/mysql/connector/locales/__init__.py 
b/lib/mysql/connector/locales/__init__.py
index ad784e6..cd5e54f 100644
--- a/lib/mysql/connector/locales/__init__.py
+++ b/lib/mysql/connector/locales/__init__.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -68,4 +68,3 @@ def get_client_error(error, language='eng'):
             return None
 
     raise ValueError("error argument needs to be either an integer or string")
-
diff --git a/lib/mysql/connector/network.py b/lib/mysql/connector/network.py
index 1ef55a3..7c097b7 100644
--- a/lib/mysql/connector/network.py
+++ b/lib/mysql/connector/network.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -168,9 +168,9 @@ class BaseMySQLSocket(object):
                 tmpbuf = bytearray()
                 for pkt in pkts:
                     tmpbuf += pkt
-                tmpbuf = buffer(tmpbuf)  # pylint: disable=E0602
+                tmpbuf = buffer(tmpbuf)  # pylint: disable=E0602,R0204
             else:
-                tmpbuf = b''.join(pkts)
+                tmpbuf = b''.join(pkts)  # pylint: disable=R0204
             del pkts
             zbuf = zlib.compress(tmpbuf[:16384])
             header = (struct.pack('<I', len(zbuf))[0:3]
@@ -181,7 +181,7 @@ class BaseMySQLSocket(object):
             zpkts.append(header + zbuf)
             tmpbuf = tmpbuf[16384:]
             pllen = len(tmpbuf)
-            self.next_compressed_packet_number
+            self.next_compressed_packet_number  # pylint: disable=W0104
             while pllen > maxpktlen:
                 zbuf = zlib.compress(tmpbuf[:maxpktlen])
                 header = (struct.pack('<I', len(zbuf))[0:3]
@@ -192,7 +192,7 @@ class BaseMySQLSocket(object):
                 zpkts.append(header + zbuf)
                 tmpbuf = tmpbuf[maxpktlen:]
                 pllen = len(tmpbuf)
-                self.next_compressed_packet_number
+                self.next_compressed_packet_number  # pylint: disable=W0104
             if tmpbuf:
                 zbuf = zlib.compress(tmpbuf)
                 header = (struct.pack('<I', len(zbuf))[0:3]
diff --git a/lib/mysql/connector/pooling.py b/lib/mysql/connector/pooling.py
index 17d2f59..b671120 100644
--- a/lib/mysql/connector/pooling.py
+++ b/lib/mysql/connector/pooling.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -112,12 +112,13 @@ class PooledMySQLConnection(object):
         When the pool is configured to reset the session, the session
         state will be cleared by re-authenticating the user.
         """
-        cnx = self._cnx
-        if self._cnx_pool.reset_session:
-            cnx.reset_session()
-
-        self._cnx_pool.add_connection(cnx)
-        self._cnx = None
+        try:
+            cnx = self._cnx
+            if self._cnx_pool.reset_session:
+                cnx.reset_session()
+        finally:
+            self._cnx_pool.add_connection(cnx)
+            self._cnx = None
 
     def config(self, **kwargs):
         """Configuration is done through the pool"""
diff --git a/lib/mysql/connector/protocol.py b/lib/mysql/connector/protocol.py
index 6c75a0a..9014897 100644
--- a/lib/mysql/connector/protocol.py
+++ b/lib/mysql/connector/protocol.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -29,7 +29,7 @@ import datetime
 from decimal import Decimal
 
 from .constants import (
-    FieldFlag, ServerCmd, FieldType, ClientFlag, MAX_MYSQL_TABLE_COLUMNS)
+    FieldFlag, ServerCmd, FieldType, ClientFlag)
 from . import errors, utils
 from .authentication import get_auth_plugin
 from .catch23 import PY2, struct_unpack
@@ -61,7 +61,7 @@ class MySQLProtocol(object):
                 ssl_enabled=ssl_enabled)
             plugin_auth_response = auth.auth_response()
         except (TypeError, errors.InterfaceError) as exc:
-            raise errors.ProgrammingError(
+            raise errors.InterfaceError(
                 "Failed authentication: {0}".format(str(exc)))
 
         if client_flags & ClientFlag.SECURE_CONNECTION:
@@ -90,7 +90,7 @@ class MySQLProtocol(object):
             username_bytes = username.encode('utf8')  # pylint: disable=E1103
         except AttributeError:
             # Username is already bytes
-            username_bytes = username
+            username_bytes = username  # pylint: disable=R0204
         packet = struct.pack('<IIB{filler}{usrlen}sx'.format(
             filler='x' * 23, usrlen=len(username_bytes)),
                              client_flags, max_allowed_packet, charset,
@@ -141,7 +141,7 @@ class MySQLProtocol(object):
             username_bytes = username.encode('utf8')  # pylint: disable=E1103
         except AttributeError:
             # Username is already bytes
-            username_bytes = username
+            username_bytes = username  # pylint: disable=R0204
         packet = struct.pack('<B{usrlen}sx'.format(usrlen=len(username_bytes)),
                              ServerCmd.CHANGE_USER, username_bytes)
 
@@ -328,7 +328,7 @@ class MySQLProtocol(object):
                     packet = sock.recv()
                 datas.append(packet[4:])
                 rowdata = utils.read_lc_string_list(bytearray(b'').join(datas))
-            elif (packet[4] == 254 and packet[0] < 7):
+            elif packet[4] == 254 and packet[0] < 7:
                 eof = self.parse_eof(packet)
                 rowdata = None
             else:
@@ -385,7 +385,7 @@ class MySQLProtocol(object):
             mcs = 0
             if length == 11:
                 mcs = struct_unpack('I', packet[8:length + 1])[0]
-            value = datetime.datetime(
+            value = datetime.datetime(  # pylint: disable=R0204
                 year=struct_unpack('H', packet[1:3])[0],
                 month=packet[3],
                 day=packet[4],
diff --git a/lib/mysql/connector/version.py b/lib/mysql/connector/version.py
index a3c311c..f6b49d5 100644
--- a/lib/mysql/connector/version.py
+++ b/lib/mysql/connector/version.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -26,7 +26,7 @@ The file version.py gets installed and is available after 
installation
 as mysql.connector.version.
 """
 
-VERSION = (2, 1, 5, '', 0)
+VERSION = (2, 1, 6, '', 0)
 
 if VERSION[3] and VERSION[4]:
     VERSION_TEXT = '{0}.{1}.{2}{3}{4}'.format(*VERSION)
diff --git a/setupinfo.py b/setupinfo.py
index 6784a38..18998ae 100644
--- a/setupinfo.py
+++ b/setupinfo.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -88,8 +88,8 @@ libraries and implements the DB API v2.0 specification 
(PEP-249).
 """
 author = 'Oracle and/or its affiliates'
 author_email = ''
-maintainer = 'Geert Vanderkelen'
-maintainer_email = 'geert.vanderke...@oracle.com'
+maintainer = 'Nuno Mariz'
+maintainer_email = 'nuno.ma...@oracle.com'
 cpy_gpl_license = "GNU GPLv2 (with FOSS License Exception)"
 keywords = "mysql db",
 url = 'http://dev.mysql.com/doc/connector-python/en/index.html'
@@ -109,6 +109,8 @@ classifiers = [
     'Programming Language :: Python :: 3.1',
     'Programming Language :: Python :: 3.2',
     'Programming Language :: Python :: 3.3',
+    'Programming Language :: Python :: 3.4',
+    'Programming Language :: Python :: 3.5',
     'Topic :: Database',
     'Topic :: Software Development',
     'Topic :: Software Development :: Libraries :: Application Frameworks',
diff --git a/src/mysql_capi.c b/src/mysql_capi.c
index e1f995b..370cceb 100644
--- a/src/mysql_capi.c
+++ b/src/mysql_capi.c
@@ -1,6 +1,6 @@
 /*
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -363,7 +363,7 @@ MySQL_init(MySQL *self, PyObject *args, PyObject *kwds)
 
     // Initialization expect -1 when parsing arguments failed
     if (!PyArg_ParseTupleAndKeywords(args, kwds,
-                                     "|O!O!O!O!O!O", kwlist,
+                                     "|O!O!O!O!O!O!", kwlist,
                                      &PyBool_Type, &self->buffered_at_connect,
                                      &PyBool_Type, &self->raw_at_connect,
                                      &PyStringType, &self->charset_name,
@@ -393,6 +393,10 @@ MySQL_init(MySQL *self, PyObject *args, PyObject *kwds)
 
     if (auth_plugin)
     {
+        if (strcmp(PyStringAsString(auth_plugin), "") == 0)
+        {
+            auth_plugin= Py_None;
+        }
         if (auth_plugin != Py_None)
         {
             tmp= self->auth_plugin;
@@ -1036,6 +1040,7 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
        unsigned int ssl_mode;
 #endif
        my_bool abool;
+       my_bool ssl_enabled= 0;
        MYSQL *res;
 
        static char *kwlist[]=
@@ -1112,8 +1117,8 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
     mysql_options(&self->session, MYSQL_OPT_WRITE_TIMEOUT, (char*)&tmp_uint);
 
     if (ssl_ca || ssl_cert || ssl_key) {
+        ssl_enabled= 1;
 #if MYSQL_VERSION_ID > 50703 && MYSQL_VERSION_ID < 50711
-        printf(">>>> %d\n", MYSQL_VERSION_ID);
         {
             abool= 1;
             mysql_options(&self->session, MYSQL_OPT_SSL_ENFORCE, 
(char*)&abool);
@@ -1140,8 +1145,10 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject 
*kwds)
                               MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (char*)&abool);
             }
 #endif
+          mysql_ssl_set(&self->session, ssl_key, ssl_cert, ssl_ca, NULL, NULL);
+        } else {
+          mysql_ssl_set(&self->session, ssl_key, ssl_cert, NULL, NULL, NULL); 
         }
-        mysql_ssl_set(&self->session, ssl_key, ssl_cert, ssl_ca, NULL, NULL);
     } else {
         // Make sure to not enforce SSL
 #if MYSQL_VERSION_ID > 50703 && MYSQL_VERSION_ID < 50711
@@ -1158,9 +1165,27 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject 
*kwds)
 #endif
     }
 
+    Py_END_ALLOW_THREADS
     if (PyString_Check(self->auth_plugin)) {
         auth_plugin= PyStringAsString(self->auth_plugin);
         mysql_options(&self->session, MYSQL_DEFAULT_AUTH, auth_plugin);
+        if (strcmp(auth_plugin, "sha256_password") == 0 && !ssl_enabled)
+        {
+            PyObject *exc_type= MySQLInterfaceError;
+            PyObject *err_no= PyInt_FromLong(2002);
+            PyObject *err_msg= PyStringFromString("sha256_password requires 
SSL");
+            PyObject *err_obj= NULL;
+            err_obj= PyObject_CallFunctionObjArgs(exc_type, err_msg, NULL);
+            PyObject_SetAttr(err_obj, PyStringFromString("sqlstate"), Py_None);
+            PyObject_SetAttr(err_obj, PyStringFromString("errno"), err_no);
+            PyObject_SetAttr(err_obj, PyStringFromString("msg"), err_msg);
+            PyErr_SetObject(exc_type, err_obj);
+            Py_XDECREF(exc_type);
+            Py_XDECREF(err_no);
+            Py_XDECREF(err_msg);
+            return NULL;
+        }
+
         if (strcmp(auth_plugin, "mysql_clear_password") == 0)
         {
             abool= 1;
@@ -1168,6 +1193,7 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
                           (char*)&abool);
         }
     }
+    Py_BEGIN_ALLOW_THREADS
 
     if (database && strlen(database) == 0)
     {
diff --git a/tests/cext/test_cext_api.py b/tests/cext/test_cext_api.py
index fff08ed..3a2cf74 100644
--- a/tests/cext/test_cext_api.py
+++ b/tests/cext/test_cext_api.py
@@ -529,6 +529,8 @@ class CExtMySQLTests(tests.MySQLConnectorTests):
         cmy1.set_character_set('big5')
         self.assertEqual(exp, get_variables(cmy1, variables=variables))
 
+    @unittest.skipIf(tests.MYSQL_VERSION == (5, 7, 4),
+                     "test_get_ssl_cipher not tested with MySQL version 5.7.4")
     def test_get_ssl_cipher(self):
         cmy1 = MySQL(buffered=True)
         self.assertRaises(MySQLInterfaceError, cmy1.get_ssl_cipher)
diff --git a/tests/cext/test_cext_cursor.py b/tests/cext/test_cext_cursor.py
index 2584c57..ea809ee 100644
--- a/tests/cext/test_cext_cursor.py
+++ b/tests/cext/test_cext_cursor.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -29,6 +29,7 @@ import logging
 import unittest
 
 from mysql.connector import errors, errorcode
+from .. import PY2
 
 import tests
 
@@ -516,6 +517,28 @@ class CExtMySQLCursorTests(tests.CMySQLCursorTests):
         cur.close()
         self.cnx.rollback()
 
+        cur = self._get_cursor(self.cnx)
+        cur.execute("DROP PROCEDURE IF EXISTS multi_results")
+        procedure = (
+            "CREATE PROCEDURE multi_results () "
+            "BEGIN SELECT 1; SELECT 'ham'; END"
+        )
+        cur.execute(procedure)
+        stmt = "CALL multi_results()"
+        if not PY2:
+            stmt = b"CALL multi_results()"
+        exp_result = [[(1,)], [(u'ham',)]]
+        results = []
+        for result in cur.execute(stmt, multi=True):
+            if result.with_rows:
+                self.assertEqual(stmt, result._executed)
+                results.append(result.fetchall())
+
+        self.assertEqual(exp_result, results)
+        cur.execute("DROP PROCEDURE multi_results")
+
+        cur.close()
+
 
 class CExtMySQLCursorBufferedTests(tests.CMySQLCursorTests):
 
diff --git a/tests/data/ssl/tests_CA_cert.pem b/tests/data/ssl/tests_CA_cert.pem
index b2032c0..6ce8c47 100644
--- a/tests/data/ssl/tests_CA_cert.pem
+++ b/tests/data/ssl/tests_CA_cert.pem
@@ -1,20 +1,19 @@
 -----BEGIN CERTIFICATE-----
-MIIDVzCCAj+gAwIBAgIJAIUsZ/vX9kOGMA0GCSqGSIb3DQEBBQUAMEIxJTAjBgNV
-BAsMHE15U1FMQ29ubmVjdG9yUHl0aG9uIFJvb3QgQ0ExGTAXBgNVBAMMEE15Q29u
-blB5IFJvb3QgQ0EwHhcNMTMwMzI2MTUzNTUyWhcNMjIwNDE0MTUzNTUyWjBCMSUw
-IwYDVQQLDBxNeVNRTENvbm5lY3RvclB5dGhvbiBSb290IENBMRkwFwYDVQQDDBBN
-eUNvbm5QeSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
-qWcX9kD+b8c3hkPtPlIgwTsfGvhm/bJ64RHjCtQc2pi/fv9hlcryor8tWmdCCcw7
-ajg5n/QAIJ8crD5D0kheGEnWVI7dyVxZVfT3CiKuS+GBxuQP2ejJi4aDGh2McVv4
-aq1dXRqf2YWkM8PUjM0lzUD9MC9S4APtP6ux0TBhz5rv2ZWdg2EAjAl7Q56KM5m6
-odpF+Z1ExnfVpNzWnpvlYHJ+GhbVWb2F0NbqBTmz4OLEAxU/O2fo43dwVlHp+yNd
-ib2V+VxeeyZmTt1CIeK6DStAiKdNLN5/N/+2FHZ9/XcA6qqxLFLeuTIySlPmuaX6
-u2C8tmOWp99TCUL+GZ2iBwIDAQABo1AwTjAdBgNVHQ4EFgQU1objOGh5rgtBTmjK
-gPkN6SgXl64wHwYDVR0jBBgwFoAU1objOGh5rgtBTmjKgPkN6SgXl64wDAYDVR0T
-BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAWgHZzUo8oGP7YxMn9YACdbipTRYU
-IzGF+Cf0ueXktcEDbq7AIa6MsxXTp8pFOObvLiiecrMngYlqfHlYPL2HG+zOLDig
-nmkO4pGwTqCDZHO4aYBdiVMlaxSpxMX9R/kFYRP1P4AGLOp66FirNO5iLNlTIjpf
-PGebF+k0B1zUSUPsrZfa/d29XcJxBaw7aEOhARQYsymItasnTdcKvjZp1ahGnZYz
-yCDtJjVbXK/4qEtiSA4qcV1HrNuHmhZEwWahntLqo++x3oLK7DrWfHwTX5gHMyv2
-DGTggnNfB8uzzNe3giT0j6ie9DJEnvv1hB0GpUToUNECusrKsYnWLdJkIA==
+MIIDADCCAegCCQDmOCndJJOWFjANBgkqhkiG9w0BAQsFADBCMSUwIwYDVQQLDBxN
+eVNRTENvbm5lY3RvclB5dGhvbiBSb290IENBMRkwFwYDVQQDDBBNeUNvbm5QeSBS
+b290IENBMB4XDTE3MDMxNzE1NTAzNloXDTI2MDQwNTE1NTAzNlowQjElMCMGA1UE
+CwwcTXlTUUxDb25uZWN0b3JQeXRob24gUm9vdCBDQTEZMBcGA1UEAwwQTXlDb25u
+UHkgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANex2fME
+DGfFk6KIIjsCpXQ6Rsv7nClZ+H7iT/xBMDHtQbqVYX1HIDYGRApWIi0Mmg3hosri
+6TO5wJIMMEwcSurVStyLXPpCT4Dg3iDuKToYfNNGtuH9DFWh1fnkeni0gbEh+/yT
+PIe3FLZCHD+F12ST1z88i4LXOG4NuozKI2cmQcHxdVkYYzknMX4IKdP4AniPgMq0
+9YmQJjXH6y7lPzDXeUuG8YrOSuvfl4W2bjht4mGP6YUUQkwZ5qbRQfrkduQB3+pa
++7P6ckd3q91j1+H1kRCn4a1S28xzPOaey6cLQ/DRVKP9EwPVV9H3/Wm8BdTr0ZMs
+1s2VQtocmzcp35kCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAGvUp9Du79gpN/pBD
+8eG7ZX/YMpK1cbzUwD+TqmP7QnXItRrZalbmadzZ6P161ff0QOEQPxL181+EEXFe
+yC8f33EGu9n6ZlSnj/HrdMZ2sjv8QA8M4Vg2vn81qUT/EsJQOjJA6n30ybncZHWB
+ovmFgBlq9miX2gDCMRosiRkzm4HAETdWQhiQ/jU4RV+pgP3/sd/mk/u2D5nqMeuT
+Ni61ke1CfskuCar5knXTdw7PYfCVXrD1ndgpf7e+qdz534GMkHcFKQkEvWE+ZuWj
+CHx9t32JFekCSzJCYs5YuAfuIJc0aC+RmA/lF7UUGyj++wWFAMnkmVEf5MM3WGjM
+HRerEg==
 -----END CERTIFICATE-----
diff --git a/tests/data/ssl/tests_CA_key.pem b/tests/data/ssl/tests_CA_key.pem
index bfccf21..1941850 100644
--- a/tests/data/ssl/tests_CA_key.pem
+++ b/tests/data/ssl/tests_CA_key.pem
@@ -1,27 +1,27 @@
 -----BEGIN RSA PRIVATE KEY-----
-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
+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
 -----END RSA PRIVATE KEY-----
diff --git a/tests/data/ssl/tests_client_cert.pem 
b/tests/data/ssl/tests_client_cert.pem
index 82fcf77..05ae516 100644
--- a/tests/data/ssl/tests_client_cert.pem
+++ b/tests/data/ssl/tests_client_cert.pem
@@ -1,18 +1,67 @@
+Certificate:
+    Data:
+        Version: 1 (0x0)
+        Serial Number: 3 (0x3)
+    Signature Algorithm: md5WithRSAEncryption
+        Issuer: OU=MySQLConnectorPython Root CA, CN=MyConnPy Root CA
+        Validity
+            Not Before: Mar 17 15:50:37 2017 GMT
+            Not After : Mar 17 15:50:37 2018 GMT
+        Subject: OU=MySQLConnectorPython Client Cert, CN=localhost
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:b0:7b:da:61:20:7c:13:97:fa:1e:20:83:e0:40:
+                    e8:94:4a:ea:1c:62:22:09:4e:d3:cd:30:66:73:28:
+                    f4:ff:2d:79:a4:b6:0b:c7:b7:20:c8:f6:c0:98:66:
+                    3d:46:ec:f1:8c:04:8b:d7:3c:b4:fa:69:6c:c5:47:
+                    1b:04:a4:a3:53:5a:0a:f2:a4:f7:94:d5:2c:d7:b6:
+                    24:81:e0:c2:ea:51:d1:6e:8e:d4:58:dc:5b:fc:b9:
+                    1b:6b:7c:52:cc:17:36:85:63:ca:f0:1f:75:2f:b8:
+                    97:96:d1:08:ab:46:31:31:e6:9c:8b:26:a1:1b:df:
+                    35:66:36:d9:ba:e1:a4:3d:88:25:7a:9d:68:d3:62:
+                    20:ec:14:b0:59:2c:33:40:11:cf:03:70:17:1c:de:
+                    65:ca:0c:2e:26:2d:f0:33:13:52:d7:0f:69:d7:c0:
+                    d6:f8:71:03:19:f4:79:3d:66:98:56:d2:44:db:bf:
+                    aa:a7:d6:fc:2d:0b:29:63:0a:d4:3d:5e:7e:a7:2c:
+                    6c:b8:2f:32:6f:51:ce:4a:2d:6a:35:54:21:33:76:
+                    a2:64:4a:8c:1d:30:73:47:3e:90:19:68:c9:07:8f:
+                    14:c5:ff:93:c7:ec:b4:08:d7:30:11:f6:67:3f:7a:
+                    8a:57:2c:87:63:34:ff:ff:79:2b:6b:70:88:21:ca:
+                    4e:53
+                Exponent: 65537 (0x10001)
+    Signature Algorithm: md5WithRSAEncryption
+         2e:d2:37:97:8b:aa:05:47:8d:b4:c6:87:7d:b8:41:d6:55:12:
+         84:14:8d:91:de:4f:84:15:89:a2:90:5a:0a:94:a1:c2:41:42:
+         18:3c:b7:10:c7:19:b5:01:96:2e:51:83:14:2f:64:0a:96:bb:
+         ce:f8:28:df:ab:fe:72:05:e8:6a:fd:1d:7b:09:22:eb:26:e7:
+         64:a7:a7:fe:fb:e8:e0:2f:91:e4:9e:fa:f6:ab:0b:5b:f3:82:
+         e0:54:d5:07:d2:05:ae:99:fd:22:d8:23:ba:e5:16:21:d7:b0:
+         82:98:4a:f0:87:36:ca:1e:4e:c0:c3:6a:22:a4:37:18:5f:6f:
+         6f:7b:92:e9:bb:15:77:55:6b:9a:57:35:95:4c:64:e9:bb:12:
+         cb:ab:67:4b:23:27:41:d3:71:15:5e:cf:6b:d6:13:05:f0:7a:
+         df:0f:f9:fd:bc:0d:8b:e4:cb:e7:62:67:9e:10:00:c9:9d:ea:
+         a7:cb:3f:ec:47:04:06:96:7f:b3:74:be:3c:cc:bd:72:05:d8:
+         91:b7:d6:b1:9a:40:79:bd:eb:cb:7a:49:bc:a6:e7:61:4f:1d:
+         68:79:21:ad:18:f6:13:6e:87:b6:13:a6:31:1e:f9:73:4c:ec:
+         04:b4:f2:83:5a:25:ae:9c:2e:8e:3a:0a:1d:0a:fd:34:dd:d4:
+         12:cc:4f:47
 -----BEGIN CERTIFICATE-----
-MIIC9TCCAd0CAQEwDQYJKoZIhvcNAQEFBQAwQjElMCMGA1UECwwcTXlTUUxDb25u
+MIIC9TCCAd0CAQMwDQYJKoZIhvcNAQEEBQAwQjElMCMGA1UECwwcTXlTUUxDb25u
 ZWN0b3JQeXRob24gUm9vdCBDQTEZMBcGA1UEAwwQTXlDb25uUHkgUm9vdCBDQTAe
-Fw0xMzAzMjYxNTM1NTJaFw0yMjA0MTQxNTM1NTJaMD8xKTAnBgNVBAsMIE15U1FM
+Fw0xNzAzMTcxNTUwMzdaFw0xODAzMTcxNTUwMzdaMD8xKTAnBgNVBAsMIE15U1FM
 Q29ubmVjdG9yUHl0aG9uIENsaWVudCBDZXJ0MRIwEAYDVQQDDAlsb2NhbGhvc3Qw
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDXbL7sr/k/W4LwwzTKJj5i
-1QtcZL0tMyBhAwuI7XQVyJBVvY7dRUM+G30ADOcUw5DscYbkkVu3L2NtsnmuyB8o
-0Y5bbHpTv4xTrVfsQuDkMLe+/LwFfL7XrY1Bm13xdEn345b6edfvhre7eatCgIaG
-IKfFr5JDv5oN4faGEJpqYahE/WdxM7zv6xb7Wx+yqLlezldU34VcLcghi8zfDkxb
-Fb4cZSgko/9RT7lTUGBJSSgITnq3Re0qANah7UbqFkTM2wfltoXGerbWMYuzOfQo
-5r0FiScjuvACkDALHAdUbX4UbXasArqpGovyVqHp4OWu3FWRfcCUnxAxfj3G3x79
-AgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAFi+U6Fyc1L0qCTCiMvUMQuXacnOMH4q
-rHm7qDKkHHcMMGsspNXvLcVKEwJrX3dhP3dZ52eKyFsOjuTkO9eU5H8V2alO8iGD
-Zb6vHT/pQRInoc39SVDFx1QnJ7RlC2Z99xzncHMQChSlDCC+Lft/K5am7vXFwQ3e
-icfLqmR5hz6nc+opnPc7WbQu/cc7PesP5uroyKScYoqAiDJ2cKQJQFPM4Cvt/KZ3
-22H/yCyQNkplIcrlQRF+l+sInNlJZr36INF0o91GcucyuLQzOXUn0L5eAyFzA9RQ
-8xkVztqRN++CgbGAhqIt8ERBtxBvCpNxuFpgm4dPKCTLm+r7fJcKwDI=
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwe9phIHwTl/oeIIPgQOiU
+SuocYiIJTtPNMGZzKPT/LXmktgvHtyDI9sCYZj1G7PGMBIvXPLT6aWzFRxsEpKNT
+WgrypPeU1SzXtiSB4MLqUdFujtRY3Fv8uRtrfFLMFzaFY8rwH3UvuJeW0QirRjEx
+5pyLJqEb3zVmNtm64aQ9iCV6nWjTYiDsFLBZLDNAEc8DcBcc3mXKDC4mLfAzE1LX
+D2nXwNb4cQMZ9Hk9ZphW0kTbv6qn1vwtCyljCtQ9Xn6nLGy4LzJvUc5KLWo1VCEz
+dqJkSowdMHNHPpAZaMkHjxTF/5PH7LQI1zAR9mc/eopXLIdjNP//eStrcIghyk5T
+AgMBAAEwDQYJKoZIhvcNAQEEBQADggEBAC7SN5eLqgVHjbTGh324QdZVEoQUjZHe
+T4QViaKQWgqUocJBQhg8txDHGbUBli5RgxQvZAqWu874KN+r/nIF6Gr9HXsJIusm
+52Snp/776OAvkeSe+varC1vzguBU1QfSBa6Z/SLYI7rlFiHXsIKYSvCHNsoeTsDD
+aiKkNxhfb297kum7FXdVa5pXNZVMZOm7EsurZ0sjJ0HTcRVez2vWEwXwet8P+f28
+DYvky+diZ54QAMmd6qfLP+xHBAaWf7N0vjzMvXIF2JG31rGaQHm968t6Sbym52FP
+HWh5Ia0Y9hNuh7YTpjEe+XNM7AS08oNaJa6cLo46Ch0K/TTd1BLMT0c=
 -----END CERTIFICATE-----
diff --git a/tests/data/ssl/tests_client_key.pem 
b/tests/data/ssl/tests_client_key.pem
index 3c2b5c9..787bd4b 100644
--- a/tests/data/ssl/tests_client_key.pem
+++ b/tests/data/ssl/tests_client_key.pem
@@ -1,27 +1,27 @@
 -----BEGIN RSA PRIVATE KEY-----
-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
+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
 -----END RSA PRIVATE KEY-----
diff --git a/tests/data/ssl/tests_expired_server_cert.pem 
b/tests/data/ssl/tests_expired_server_cert.pem
new file mode 100644
index 0000000..cfba302
--- /dev/null
+++ b/tests/data/ssl/tests_expired_server_cert.pem
@@ -0,0 +1,68 @@
+Certificate:
+    Data:
+        Version: 1 (0x0)
+        Serial Number: 2 (0x2)
+    Signature Algorithm: md5WithRSAEncryption
+        Issuer: OU=MySQLConnectorPython Root CA, CN=MyConnPy Root CA
+        Validity
+            Not Before: Aug 15 08:00:00 2012 GMT
+            Not After : Aug 15 09:00:00 2012 GMT
+        Subject: OU=MySQLConnectorPython Expired Server Cert, CN=localhost
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:df:5a:5b:72:42:5f:46:e5:bb:6c:e5:76:2e:6f:
+                    fd:b8:10:2f:04:10:55:43:0c:bf:af:f1:eb:f0:4f:
+                    6f:6b:d9:61:9f:2a:39:35:2d:cc:0c:05:5c:88:cc:
+                    98:a3:5c:78:9e:8c:6b:ba:33:3f:f2:46:96:f2:bb:
+                    78:63:ca:bd:72:2c:70:34:56:8b:12:e5:e9:ff:82:
+                    d5:50:bb:28:c2:99:83:af:3f:f1:67:77:b4:41:66:
+                    79:ee:f7:3a:93:8c:55:da:c3:d5:3a:44:40:82:e8:
+                    fa:4c:11:a7:13:20:31:78:48:1d:2e:95:8c:0f:4c:
+                    ea:ac:96:9d:9e:2a:37:c5:7a:42:f2:b1:8f:9b:15:
+                    69:9d:1c:19:26:69:84:a9:c6:9e:08:65:c0:7c:bf:
+                    72:a7:b0:ae:60:78:ad:7d:ea:0b:ed:ff:45:fc:24:
+                    56:f5:c6:f4:b5:00:0f:90:76:3e:52:08:ec:06:c4:
+                    30:51:66:60:f9:c6:0b:b9:f2:96:6a:c2:39:b8:b7:
+                    48:b8:3f:02:26:b5:95:f8:55:8d:d3:23:f1:dc:d0:
+                    ab:2c:05:3b:b5:99:4d:9a:81:78:27:60:0d:da:2e:
+                    23:e8:38:26:0b:6d:6c:f6:fd:a7:42:95:4c:d2:a5:
+                    7c:05:13:21:7b:c7:6d:ca:f1:e3:3d:ad:d4:32:79:
+                    5a:d3
+                Exponent: 65537 (0x10001)
+    Signature Algorithm: md5WithRSAEncryption
+         36:e4:ba:6c:3b:99:29:ba:33:8b:da:ef:07:b8:7e:f6:07:b6:
+         79:7b:c7:b2:0c:0c:48:ff:52:25:05:34:f4:d9:f6:0a:0c:77:
+         10:a7:e5:40:f4:47:bf:4c:06:7b:8a:22:53:5a:91:dd:75:32:
+         d3:58:97:4f:d4:01:e8:b5:8d:ca:52:23:7f:72:1b:e2:c5:9a:
+         89:a4:be:e4:17:9b:fa:1f:c0:26:93:5f:c2:d2:1b:e0:c2:9e:
+         36:d1:3f:95:bd:6f:af:cd:f3:8f:6a:c6:5c:b0:6b:ae:07:60:
+         59:be:fa:fd:f8:43:5b:20:38:02:b8:a6:f5:eb:35:be:46:55:
+         7b:84:9f:e5:cb:5d:6b:af:2a:28:d1:af:32:1f:e3:71:d8:f8:
+         96:4a:f1:88:f3:10:27:ed:c5:a2:65:f4:b5:2b:58:77:93:25:
+         e7:36:e1:4b:cb:18:10:cd:81:fc:80:e6:24:0f:27:4c:33:22:
+         af:36:88:ee:f8:0d:ef:ff:47:74:87:50:e8:ea:03:da:71:a1:
+         65:fd:00:8c:c8:a8:27:fa:e0:40:43:60:8f:aa:1f:25:4f:05:
+         d7:a5:fe:9b:a3:82:90:0b:50:bf:bd:62:a3:9e:14:20:80:18:
+         8b:8c:5e:f7:97:b8:b7:a5:63:d8:22:1a:98:6c:32:da:38:7b:
+         fc:e6:2c:f3
+-----BEGIN CERTIFICATE-----
+MIIC/TCCAeUCAQIwDQYJKoZIhvcNAQEEBQAwQjElMCMGA1UECwwcTXlTUUxDb25u
+ZWN0b3JQeXRob24gUm9vdCBDQTEZMBcGA1UEAwwQTXlDb25uUHkgUm9vdCBDQTAe
+Fw0xMjA4MTUwODAwMDBaFw0xMjA4MTUwOTAwMDBaMEcxMTAvBgNVBAsMKE15U1FM
+Q29ubmVjdG9yUHl0aG9uIEV4cGlyZWQgU2VydmVyIENlcnQxEjAQBgNVBAMMCWxv
+Y2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN9aW3JCX0bl
+u2zldi5v/bgQLwQQVUMMv6/x6/BPb2vZYZ8qOTUtzAwFXIjMmKNceJ6Ma7ozP/JG
+lvK7eGPKvXIscDRWixLl6f+C1VC7KMKZg68/8Wd3tEFmee73OpOMVdrD1TpEQILo
++kwRpxMgMXhIHS6VjA9M6qyWnZ4qN8V6QvKxj5sVaZ0cGSZphKnGnghlwHy/cqew
+rmB4rX3qC+3/RfwkVvXG9LUAD5B2PlII7AbEMFFmYPnGC7nylmrCObi3SLg/Aia1
+lfhVjdMj8dzQqywFO7WZTZqBeCdgDdouI+g4JgttbPb9p0KVTNKlfAUTIXvHbcrx
+4z2t1DJ5WtMCAwEAATANBgkqhkiG9w0BAQQFAAOCAQEANuS6bDuZKbozi9rvB7h+
+9ge2eXvHsgwMSP9SJQU09Nn2Cgx3EKflQPRHv0wGe4oiU1qR3XUy01iXT9QB6LWN
+ylIjf3Ib4sWaiaS+5Beb+h/AJpNfwtIb4MKeNtE/lb1vr83zj2rGXLBrrgdgWb76
+/fhDWyA4Arim9es1vkZVe4Sf5ctda68qKNGvMh/jcdj4lkrxiPMQJ+3FomX0tStY
+d5Ml5zbhS8sYEM2B/IDmJA8nTDMirzaI7vgN7/9HdIdQ6OoD2nGhZf0AjMioJ/rg
+QENgj6ofJU8F16X+m6OCkAtQv71io54UIIAYi4xe95e4t6Vj2CIamGwy2jh7/OYs
+8w==
+-----END CERTIFICATE-----
diff --git a/tests/data/ssl/tests_expired_server_key.pem 
b/tests/data/ssl/tests_expired_server_key.pem
new file mode 100644
index 0000000..6b68fe2
--- /dev/null
+++ b/tests/data/ssl/tests_expired_server_key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA31pbckJfRuW7bOV2Lm/9uBAvBBBVQwy/r/Hr8E9va9lhnyo5
+NS3MDAVciMyYo1x4noxrujM/8kaW8rt4Y8q9cixwNFaLEuXp/4LVULsowpmDrz/x
+Z3e0QWZ57vc6k4xV2sPVOkRAguj6TBGnEyAxeEgdLpWMD0zqrJadnio3xXpC8rGP
+mxVpnRwZJmmEqcaeCGXAfL9yp7CuYHitfeoL7f9F/CRW9cb0tQAPkHY+UgjsBsQw
+UWZg+cYLufKWasI5uLdIuD8CJrWV+FWN0yPx3NCrLAU7tZlNmoF4J2AN2i4j6Dgm
+C21s9v2nQpVM0qV8BRMhe8dtyvHjPa3UMnla0wIDAQABAoIBAC7IP0U0b75q2hIa
+EeHyJSOLiD2Cqkkr/2577p5cFQty8caj0m24FPgjm1kv+XymHsGeyeWrXGaDsJRQ
+/gtw6LNkaXAc/G5N5/BT2Bhby1LPUsy/SPISGZhlPX73G7bR+x2iTSQyLYz9/Yc3
+X1ZbNOFrwWkDe92sj67ssUDyuNHMwLpw35/OWX2W7YsGzi7j2zbZdmhp2c3E0/bD
+NL2217BsPMLD1/f0og6Ix9kvSt+2Z3XW6RlhP7LDNDRI7F8oRRVvYgQGHBHibvlG
+I4n07lycLo0dPsc08PcUvJ5UyhI7VYk/MZACLNhrjgPxYz1HdL7deVoQbW6z4q19
+g1JjI2kCgYEA+eOIvGkz9wga74VVKMZIqXPaMmccNkwbzUb7Ay1CM50pdYLk6E6R
+LdEIx0/qQC8Zpw47NhSFzZT8sakHqmK7VIJRdMJWSTKu/4QMooigRasFJXPWwJVa
+LsTE1gg3LGL+RkuoQNIlPle6nTGcCLGfnB8Js1GA3/SunFQCoJr+stcCgYEA5NCx
+BSmZz07Rso3FWzRMjR52m2JDWvMm4+eU/HxXGrPdYfBQEowxzesORRBRIlp8Z5ki
+929ayJ5qONLjMFx1l/QguT9BNkbzO3gpbH3/G187wFQ0v8jXmDRjU7ftgyL6PAD+
+eJsj39+TfA+Hua6m6VkLH5XUpy3Vl8nBkM2cFGUCgYEAl1zEiWOsD1lAf48i2zTn
+9IRxSZB9XUJSoM/64Zy7eeobn8tufmyAseDpUVlNyhz9i9wp74MU3Ub+nVqGgyWU
+1Qau8mt4upPRvoIs6RKbCjgiQOJe1X5iBuw3UnHdgaxg2xGe08y2tIGNTwQqwHVe
++cEvLggTaRSb46NbiA76cjcCgYBGkWZG5VGecfySSM75FeQWEbMasO98+UihOSbl
+x6NFhPtd3TOUxNAHZdr8yc97/NQpTz1NenZRMSopZEDVBW7u8ke1WiDOkIsraB++
+ag1nb7OJ2W57R4HWWzHW+/6wVvU91ECnCZHC1b0yoceGKKsphGC92QPAm44oRf0A
+n6jnUQKBgD0MqIjngDIRMwGpkXpsJJDt9/dw6izz3sWhBDkBLKCt63nwT3pykDDF
+qJ8dq9TSGwO6H1c/obKdFlx53PBDUpZV9txI8ScF2YNlfs3Ts4+oElkU/jCMJPKi
+M73I0Jgg+GwToDcjC4d7oREIBlfXjBLBjCcHx1315NMUW42QkrNo
+-----END RSA PRIVATE KEY-----
diff --git a/tests/data/ssl/tests_server_cert.pem 
b/tests/data/ssl/tests_server_cert.pem
index dc7938c..3276dea 100644
--- a/tests/data/ssl/tests_server_cert.pem
+++ b/tests/data/ssl/tests_server_cert.pem
@@ -1,18 +1,67 @@
+Certificate:
+    Data:
+        Version: 1 (0x0)
+        Serial Number: 1 (0x1)
+    Signature Algorithm: md5WithRSAEncryption
+        Issuer: OU=MySQLConnectorPython Root CA, CN=MyConnPy Root CA
+        Validity
+            Not Before: Mar 17 15:50:37 2017 GMT
+            Not After : Mar 17 15:50:37 2018 GMT
+        Subject: OU=MySQLConnectorPython Server Cert, CN=localhost
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:a3:0d:e6:bd:d7:5e:1e:0f:b2:0a:83:43:50:fe:
+                    7c:bc:32:dc:04:fd:38:97:86:1e:e0:9c:46:08:65:
+                    ac:76:6f:0d:93:33:31:4e:02:8a:a7:e9:9a:b9:4f:
+                    f9:d3:66:56:29:1a:e5:0f:df:7b:61:e5:3c:06:db:
+                    ea:cd:d6:71:9d:63:b2:f9:e1:c1:ed:9a:6e:2f:2f:
+                    be:94:76:aa:ee:24:b3:58:f0:82:25:00:ef:c8:19:
+                    4f:15:6f:f2:3b:b4:e4:9b:0d:36:c7:17:39:7d:35:
+                    45:e8:76:62:94:19:ab:64:d8:89:78:75:92:29:e2:
+                    35:79:dd:e1:bf:3f:52:bf:ef:4c:d1:c1:fc:d0:a6:
+                    ee:b8:01:39:26:28:67:40:73:46:5e:55:65:3b:56:
+                    c9:c0:e1:7a:a4:a1:0c:46:d2:1e:b3:af:c5:cc:5b:
+                    07:81:79:c5:d0:44:57:ed:ea:ad:d9:c2:45:70:72:
+                    46:d3:e2:a3:f4:d0:49:33:ac:66:89:9b:83:65:f9:
+                    92:07:4e:9c:bf:b0:59:90:f8:35:8f:19:d2:82:d7:
+                    49:46:f5:4b:6a:c0:bd:5c:5d:0f:a0:fb:29:15:a7:
+                    68:5e:e1:48:20:c8:14:eb:fc:17:29:d6:95:4a:27:
+                    70:f3:c3:52:3d:1c:a5:d4:cf:3c:87:81:d7:d9:bb:
+                    dc:49
+                Exponent: 65537 (0x10001)
+    Signature Algorithm: md5WithRSAEncryption
+         36:58:2f:f4:95:e6:8b:ef:5b:59:91:2e:31:c2:21:64:b7:ac:
+         e6:bf:4e:b7:12:06:7d:8b:74:eb:82:88:65:00:4c:12:5e:6b:
+         dd:8b:d5:5e:cd:74:92:8a:dd:eb:fb:5b:1d:46:b0:e4:7d:55:
+         1a:01:9a:82:0c:4d:91:05:e2:92:f5:17:0f:a5:8b:d9:8e:8f:
+         17:55:19:83:07:2b:ea:2b:16:15:30:f7:31:7e:84:cc:b7:e0:
+         b1:b1:53:5d:e9:40:87:19:98:d5:f8:eb:ae:ef:b4:e7:85:12:
+         38:e7:12:f4:44:03:08:a6:fc:3b:aa:26:1c:52:95:e0:7b:93:
+         92:00:e2:21:b8:09:00:7d:e5:08:b4:c8:53:1d:2c:11:ea:86:
+         5c:f9:14:c6:3f:73:0a:bc:e7:96:cb:e9:39:23:d7:50:0f:7d:
+         2e:04:be:e9:5b:0b:bf:99:85:8c:ed:32:14:1d:09:c5:d5:d1:
+         e6:db:f2:54:51:3f:5f:0e:e0:06:58:c8:52:68:4e:39:25:bd:
+         b5:1b:8b:b2:1d:95:cb:cb:22:18:b5:d7:27:3d:32:c4:79:c4:
+         fa:e1:6f:00:1c:63:da:4a:ce:9e:de:0c:a4:dd:bd:d3:d6:cb:
+         51:d7:e6:32:5f:5f:31:1f:a5:9d:5f:d5:2c:21:72:a7:ed:f1:
+         d8:31:c8:b4
 -----BEGIN CERTIFICATE-----
-MIIC9TCCAd0CAQEwDQYJKoZIhvcNAQEFBQAwQjElMCMGA1UECwwcTXlTUUxDb25u
+MIIC9TCCAd0CAQEwDQYJKoZIhvcNAQEEBQAwQjElMCMGA1UECwwcTXlTUUxDb25u
 ZWN0b3JQeXRob24gUm9vdCBDQTEZMBcGA1UEAwwQTXlDb25uUHkgUm9vdCBDQTAe
-Fw0xMzAzMjYxNTM1NTJaFw0yMjA0MTQxNTM1NTJaMD8xKTAnBgNVBAsMIE15U1FM
+Fw0xNzAzMTcxNTUwMzdaFw0xODAzMTcxNTUwMzdaMD8xKTAnBgNVBAsMIE15U1FM
 Q29ubmVjdG9yUHl0aG9uIFNlcnZlciBDZXJ0MRIwEAYDVQQDDAlsb2NhbGhvc3Qw
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDv6WQ/Ssum4RchjXSlwbcB
-au3WNccfodThBOAM27AOnJQWIjG4e5s9H7lLznI+VF5MgUbgbp/yz4D+CrSFvLgU
-4xxzd1/SVbnzRJ5iD2EmaZPjoMkBmvDRd4ow6IdFN80Fpwxij6fUBHdRkyXyiYsG
-FE94PQCyD1R47LSubd/gfcjXw8Bt5cWqcopiolZ01bYuMzeZIw0et9gf6Iih2Zh1
-bs9RthHfL3BfN4knljF3XmRQhfsc4w3MvdulX4mcfzS+E+keOOgPjfjo9KVCD1Zl
-F00wQdbSCWzf9uCP4OpKJGURyMQEmGMFPBOP98kqns1CqaE0PxKOpbcTX86nSEO5
-AgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAFy4ONx0zFYgVNL046lfRmimyRf1gbmB
-pyyug9eW6QuuTfqbzFWOYZY8pG2lzKnHNUMmgzMNMpiRLRJ38Dj5rApg+7OkiTT+
-l4DMIR/YblJryEvx6tNUq2Cu9GXKW2qrGJO3XVniuBpmg1srugdwyxS+LdFofgBc
-I4cKIDuXYATUpOFhEsFbMY6tGVeOXQN2jSWtUj6+mKiUWMyr+5NYD8xhjDV7q4GH
-JfQqWFzw7prtSYzwB8lc0PM2SLwxeE9cQUYN/UkW8HRxM7Ft5KyyXUk+2Jg61sZ2
-QxMCV6NAGYMX40WRDqIZbs9AbHWoCxEwoXWtcmNb0GInsk39lFMJqw4=
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCjDea9114eD7IKg0NQ/ny8
+MtwE/TiXhh7gnEYIZax2bw2TMzFOAoqn6Zq5T/nTZlYpGuUP33th5TwG2+rN1nGd
+Y7L54cHtmm4vL76UdqruJLNY8IIlAO/IGU8Vb/I7tOSbDTbHFzl9NUXodmKUGatk
+2Il4dZIp4jV53eG/P1K/70zRwfzQpu64ATkmKGdAc0ZeVWU7VsnA4XqkoQxG0h6z
+r8XMWweBecXQRFft6q3ZwkVwckbT4qP00EkzrGaJm4Nl+ZIHTpy/sFmQ+DWPGdKC
+10lG9UtqwL1cXQ+g+ykVp2he4UggyBTr/Bcp1pVKJ3Dzw1I9HKXUzzyHgdfZu9xJ
+AgMBAAEwDQYJKoZIhvcNAQEEBQADggEBADZYL/SV5ovvW1mRLjHCIWS3rOa/TrcS
+Bn2LdOuCiGUATBJea92L1V7NdJKK3ev7Wx1GsOR9VRoBmoIMTZEF4pL1Fw+li9mO
+jxdVGYMHK+orFhUw9zF+hMy34LGxU13pQIcZmNX4667vtOeFEjjnEvREAwim/Duq
+JhxSleB7k5IA4iG4CQB95Qi0yFMdLBHqhlz5FMY/cwq855bL6Tkj11APfS4Evulb
+C7+ZhYztMhQdCcXV0ebb8lRRP18O4AZYyFJoTjklvbUbi7IdlcvLIhi11yc9MsR5
+xPrhbwAcY9pKzp7eDKTdvdPWy1HX5jJfXzEfpZ1f1Swhcqft8dgxyLQ=
 -----END CERTIFICATE-----
diff --git a/tests/data/ssl/tests_server_key.pem 
b/tests/data/ssl/tests_server_key.pem
index 13c39fe..466fc97 100644
--- a/tests/data/ssl/tests_server_key.pem
+++ b/tests/data/ssl/tests_server_key.pem
@@ -1,27 +1,27 @@
 -----BEGIN RSA PRIVATE KEY-----
-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
+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
 -----END RSA PRIVATE KEY-----
diff --git a/tests/mysqld.py b/tests/mysqld.py
index 6d6463d..e007361 100644
--- a/tests/mysqld.py
+++ b/tests/mysqld.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -343,9 +343,10 @@ class MySQLServerBase(object):
 class MySQLServer(MySQLServerBase):
     """Class for managing a MySQL server"""
 
-    def __init__(self, basedir, topdir, cnf, bind_address, port,
-                 name, datadir=None, tmpdir=None,
-                 unix_socket_folder=None, ssl_folder=None, sharedir=None):
+    def __init__(self, basedir, topdir, cnf, bind_address, port, name,
+                 datadir=None, tmpdir=None, unix_socket_folder=None,
+                 ssl_folder=None, ssl_ca=None, ssl_cert=None, ssl_key=None,
+                 sharedir=None):
         self._cnf = cnf
         self._option_file = os.path.join(topdir, 'my.cnf')
         self._bind_address = bind_address
@@ -353,6 +354,9 @@ class MySQLServer(MySQLServerBase):
         self._topdir = topdir
         self._basedir = basedir
         self._ssldir = ssl_folder or topdir
+        self._ssl_ca = os.path.join(self._ssldir, ssl_ca)
+        self._ssl_cert = os.path.join(self._ssldir, ssl_cert)
+        self._ssl_key = os.path.join(self._ssldir, ssl_key)
         self._datadir = datadir or os.path.join(topdir, 'data')
         self._tmpdir = tmpdir or os.path.join(topdir, 'tmp')
         self._name = name
@@ -540,13 +544,7 @@ class MySQLServer(MySQLServerBase):
         """Return the unix socket of the server"""
         return self._unix_socket
 
-    def start(self):
-        """Start a MySQL server"""
-        if self.check_running():
-            LOGGER.error("MySQL server '{name}' already running".format(
-                name=self.name))
-            return
-
+    def update_config(self, **kwargs):
         options = {
             'name': self._name,
             'basedir': _convert_forward_slash(self._basedir),
@@ -555,16 +553,31 @@ class MySQLServer(MySQLServerBase):
             'bind_address': self._bind_address,
             'port': self._port,
             'unix_socket': _convert_forward_slash(self._unix_socket),
-            'ssl_dir': _convert_forward_slash(self._ssldir),
+            'ssl_ca': _convert_forward_slash(self._ssl_ca),
+            'ssl_cert': _convert_forward_slash(self._ssl_cert),
+            'ssl_key': _convert_forward_slash(self._ssl_key),
             'pid_file': _convert_forward_slash(self._pid_file),
             'serverid': self._serverid,
             'lc_messages_dir': _convert_forward_slash(
                 self._lc_messages_dir),
         }
+        options.update(**kwargs)
         try:
             fp = open(self._option_file, 'w')
             fp.write(self._cnf.format(**options))
             fp.close()
+        except Exception as ex:
+            LOGGER.error("Failed to write config file {0}".format(ex))
+            sys.exit(1)
+
+    def start(self, **kwargs):
+        if self.check_running():
+            LOGGER.error("MySQL server '{name}' already running".format(
+                name=self.name))
+            return
+
+        self.update_config(**kwargs)
+        try:
             self._start_server()
             for i in range(10):
                 if self.check_running():
diff --git a/tests/test_abstracts.py b/tests/test_abstracts.py
index ca376e4..662ac22 100644
--- a/tests/test_abstracts.py
+++ b/tests/test_abstracts.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -194,7 +194,13 @@ class ConnectionSubclasses(tests.MySQLConnectorTests):
         exp = {'insert_id': 0, 'affected_rows': 0,
                'field_count': 0, 'warning_count': 0,
                'status_flag': 0}
-        self.assertEqual(exp, self.cnx.cmd_refresh(refresh))
+        result = self.cnx.cmd_refresh(refresh)
+        for key in set(result.keys()) ^ set(exp.keys()):
+            try:
+                del result[key]
+            except KeyError:
+                del exp[key]
+        self.assertEqual(exp, result)
 
         query = "SHOW GLOBAL STATUS LIKE 'Uptime_since_flush_status'"
         pre_flush = int(self.cnx.info_query(query)[1])
diff --git a/tests/test_bugs.py b/tests/test_bugs.py
index 390b1b8..fc26488 100644
--- a/tests/test_bugs.py
+++ b/tests/test_bugs.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -44,6 +44,7 @@ from threading import Thread
 import traceback
 import time
 import unittest
+import pickle
 
 import tests
 from tests import foreach_cnx, cnx_config
@@ -52,6 +53,7 @@ from mysql.connector import (connection, cursor, conversion, 
protocol,
                              errors, constants, pooling)
 from mysql.connector.optionfiles import read_option_files
 import mysql.connector
+import cpy_distutils
 
 try:
     from mysql.connector.connection_cext import CMySQLConnection
@@ -62,6 +64,8 @@ except ImportError:
 ERR_NO_CEXT = "C Extension not available"
 
 
+@unittest.skipIf(tests.MYSQL_VERSION == (5, 7, 4),
+                 "Bug328998 not tested with MySQL version 5.7.4")
 class Bug328998Tests(tests.MySQLConnectorTests):
     """Tests where connection timeout has been set"""
 
@@ -2381,6 +2385,7 @@ class BugOra16217765(tests.MySQLConnectorTests):
         user = self.users['sha256user']
         config['user'] = user['username']
         config['password'] = user['password']
+        config['auth_plugin'] = user['auth_plugin']
         self.assertRaises(errors.InterfaceError, connection.MySQLConnection,
                           **config)
         if CMySQLConnection:
@@ -4196,3 +4201,200 @@ class BugOra21530841(tests.MySQLConnectorTests):
         cur.execute(query)
         cur.fetchone()
         cur.close()
+
+
+class BugOra25397650(tests.MySQLConnectorTests):
+    """BUG#25397650: CERTIFICATE VALIDITY NOT VERIFIED 
+    """
+    def setUp(self):
+        self.config = tests.get_mysql_config()
+        self.config = tests.get_mysql_config()
+        self.config.update({
+            'ssl_ca': os.path.abspath(
+                os.path.join(tests.SSL_DIR, 'tests_CA_cert.pem')),
+            'ssl_cert': os.path.abspath(
+                os.path.join(tests.SSL_DIR, 'tests_client_cert.pem')),
+            'ssl_key': os.path.abspath(
+                os.path.join(tests.SSL_DIR, 'tests_client_key.pem')),
+        })
+        self.mysql_server = tests.MYSQL_SERVERS[0]
+        self._use_expired_cert()
+
+    def tearDown(self):
+        self._use_original_cert()
+        self._ensure_up()
+
+    def _ensure_up(self):
+        # Start the MySQL server again
+        if not self.mysql_server.check_running():
+            self.mysql_server.start()
+
+            if not self.mysql_server.wait_up():
+                self.fail("Failed restarting MySQL server after test")
+
+    def _use_original_cert(self):
+        self.mysql_server.stop()
+        self.mysql_server.wait_down()
+
+        self.mysql_server.start()
+        self.mysql_server.wait_up()
+        time.sleep(2)
+
+    def _use_expired_cert(self):
+        self.mysql_server.stop()
+        self.mysql_server.wait_down()
+
+        cert = os.path.abspath(
+            os.path.join(tests.SSL_DIR, 'tests_expired_server_cert.pem'))
+        key = os.path.abspath(
+            os.path.join(tests.SSL_DIR, 'tests_expired_server_key.pem'))
+        if os.name == 'nt':
+            cert = os.path.normpath(cert)
+            cert = cert.replace('\\', '\\\\')
+            key = os.path.normpath(key)
+            key = key.replace('\\', '\\\\')
+        self.mysql_server.start(ssl_cert=cert, ssl_key=key)
+        self.mysql_server.wait_up()
+        time.sleep(2)
+
+    def test_pure_verify_server_certifcate(self):
+        self.config["use_pure"] = True
+        self.config['ssl_verify_cert'] = True
+        self.assertRaises(errors.InterfaceError,
+            mysql.connector.connect, **self.config)
+        self.config['ssl_verify_cert'] = False
+        mysql.connector.connect(**self.config)
+
+    def test_cext_verify_server_certifcate(self):
+        self.config["use_pure"] = False
+        self.config['ssl_verify_cert'] = True
+        self.assertRaises(errors.InterfaceError,
+            mysql.connector.connect, **self.config)
+        self.config['ssl_verify_cert'] = False
+        mysql.connector.connect(**self.config)
+
+
+class BugOra25589496(tests.MySQLConnectorTests):
+    """BUG#25589496: COMMITS RELATED TO "BUG22529828" BROKE BINARY DATA
+    HANDLING FOR PYTHON 2.7
+    """
+    def setUp(self):
+        config = tests.get_mysql_config()
+        self.cnx = connection.MySQLConnection(**config)
+        self.tbl = "Bug25589496"
+        self.cnx.cmd_query("DROP TABLE IF EXISTS {0}".format(self.tbl))
+
+    def tearDown(self):
+        self.cnx.cmd_query("DROP TABLE IF EXISTS {0}".format(self.tbl))
+        self.cnx.close()
+
+    def test_insert_binary(self):
+        table = """
+        CREATE TABLE {0} (
+            `id` int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
+            `section` VARCHAR(50) NOT NULL,
+            `pickled` LONGBLOB NOT NULL
+        )
+        """.format(self.tbl)
+        cursor = self.cnx.cursor()
+        cursor.execute(table)
+
+        pickled = pickle.dumps({'a': 'b'}, pickle.HIGHEST_PROTOCOL)
+        add_row_q = "INSERT INTO {0} (section, pickled) " \
+                    "VALUES (%(section)s, %(pickled)s)".format(self.tbl)
+
+        new_row = cursor.execute(add_row_q, {'section': 'foo',
+                                             'pickled': pickled})
+        self.cnx.commit()
+        self.assertEqual(1, cursor.lastrowid)
+        cursor.close()
+
+
+class BugOra25383644(tests.MySQLConnectorTests):
+    """BUG#25383644: LOST SERVER CONNECTION LEAKS POOLED CONNECTIONS
+    """
+    def setUp(self):
+        config = tests.get_mysql_config()
+        config["pool_size"] = 3
+        self.cnxpool = pooling.MySQLConnectionPool(**config)
+        self.mysql_server = tests.MYSQL_SERVERS[0]
+
+    def test_pool_exhaustion(self):
+        sql = "SELECT * FROM dummy"
+
+        i = 4
+        while i > 0:
+            cnx = self.cnxpool.get_connection()
+            cur = cnx.cursor()
+            try:
+                self.mysql_server.stop()
+                self.mysql_server.wait_down()
+                cur.execute(sql)
+            except mysql.connector.errors.OperationalError:
+                try:
+                    cur.close()
+                    cnx.close()
+                except mysql.connector.errors.OperationalError:
+                    pass
+            finally:
+                i -= 1
+                if not self.mysql_server.check_running():
+                    self.mysql_server.start()
+                    self.mysql_server.wait_up()
+
+
+class BugOra25558885(tests.MySQLConnectorTests):
+    """BUG#25558885: ERROR 2013 (LOST CONNECTION TO MYSQL SERVER) USING C
+    EXTENSIONS
+    """
+    def setUp(self):
+        pass
+
+    def _long_query(self, config, cursor_class):
+        db_conn = mysql.connector.connect(**config)
+        cur = db_conn.cursor(cursor_class=cursor_class)
+        cur.execute("select sleep(15)")
+        cur.close()
+        db_conn.disconnect()
+
+    def test_cext_cnx(self):
+        config = tests.get_mysql_config()
+        config["use_pure"] = False
+        del config["connection_timeout"]
+        cursor_class = mysql.connector.cursor_cext.CMySQLCursorBufferedRaw
+        self._long_query(config, cursor_class)
+
+    def test_pure_cnx(self):
+        config = tests.get_mysql_config()
+        config["use_pure"] = True
+        del config["connection_timeout"]
+        cursor_class = mysql.connector.cursor.MySQLCursorBufferedRaw
+        self._long_query(config, cursor_class)
+
+
+class BugOra20736339(tests.MySQLConnectorTests):
+    """BUG#20736339: C EXTENSION FAILS TO COMPILE IF MYSQL_CONFIG RETURN MORE
+    THAN ONE INCLUDE DIR
+    """
+    def test_parse_mysql_config(self):
+        options = ['cflags', 'include', 'libs', 'libs_r', 'plugindir', 
'version']
+        includes = ["/mysql/include", "/mysql/another_include"]
+        config = """
+        -I/mysql/include -fabi-version=2 -fno-omit-frame-pointer
+        -I{0}
+        -L/mysql/lib -lmysqlclient -lpthread -lm -lrt -lssl -lcrypto -ldl
+        -L/mysql/lib -lmysqlclient -lpthread -lm -lrt -lssl -lcrypto -ldl
+        /mysql/lib/plugin
+        5.7.17
+        """
+
+        info = cpy_distutils.parse_mysql_config_info(options,
+            config.strip().format(includes[0]))
+        self.assertEqual(1, len(info["include"]))
+        self.assertEqual(includes[0], info["include"][0])
+
+        info = cpy_distutils.parse_mysql_config_info(options,
+            config.strip().format(" -I".join(includes)))
+        self.assertEqual(2, len(info["include"]))
+        self.assertEqual(includes[0], info["include"][0])
+        self.assertEqual(includes[1], info["include"][1])
diff --git a/tests/test_django.py b/tests/test_django.py
index 45c2b13..6a94f3b 100644
--- a/tests/test_django.py
+++ b/tests/test_django.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -60,6 +60,7 @@ if DJANGO_AVAILABLE:
             'TEST_COLLATION': 'utf8_general_ci',
             'CONN_MAX_AGE': 0,
             'AUTOCOMMIT': True,
+            'TIME_ZONE': None,
         },
     }
     settings.SECRET_KEY = "django_tests_secret_key"
@@ -92,15 +93,11 @@ FOREIGN KEY (id_t1) REFERENCES django_t1(id) ON DELETE 
CASCADE
 
 # Have to load django.db to make importing db backend work for Django < 1.6
 import django.db  # pylint: disable=W0611
-if tests.DJANGO_VERSION >= (1, 6):
-    if tests.DJANGO_VERSION >= (1, 8):
-        from django.db.backends.base.introspection import FieldInfo
-    else:
-        from django.db.backends import FieldInfo
 from django.db.backends.signals import connection_created
 from django.utils.safestring import SafeBytes, SafeText
 
 import mysql.connector
+from mysql.connector.django.introspection import FieldInfo
 
 if DJANGO_AVAILABLE:
     from mysql.connector.django.base import (
@@ -147,14 +144,14 @@ class DjangoIntrospection(tests.MySQLConnectorTests):
 
     def test_get_table_list(self):
         cur = self.cnx.cursor()
-        exp = list(TABLES.keys())
-        for exp in list(TABLES.keys()):
+        for exp in TABLES.keys():
             if sys.version_info < (2, 7):
                 self.assertTrue(exp in self.introspect.get_table_list(cur))
             else:
-                self.assertIn(exp, self.introspect.get_table_list(cur),
-                              "Table {table_name} not in table list".format(
-                                  table_name=exp))
+                res = any(table.name == exp
+                          for table in self.introspect.get_table_list(cur))
+                self.assertTrue(res, "Table {table_name} not in table list"
+                                     "".format(table_name=exp))
 
     def test_get_table_description(self):
         cur = self.cnx.cursor()
@@ -165,24 +162,39 @@ class DjangoIntrospection(tests.MySQLConnectorTests):
                 ('c1', 3, None, None, None, None, 1, 16392),
                 ('c2', 253, None, 20, None, None, 1, 16388)
             ]
-        else:
+        elif tests.DJANGO_VERSION < (1, 8):
             exp = [
-                FieldInfo(name='id', type_code=3, display_size=None,
+                FieldInfo(name=u'id', type_code=3, display_size=None,
                           internal_size=None, precision=None, scale=None,
                           null_ok=0),
-                FieldInfo(name='c1', type_code=3, display_size=None,
+                FieldInfo(name=u'c1', type_code=3, display_size=None,
                           internal_size=None, precision=None, scale=None,
                           null_ok=1),
-                FieldInfo(name='c2', type_code=253, display_size=None,
+                FieldInfo(name=u'c2', type_code=253, display_size=None,
                           internal_size=20, precision=None, scale=None,
                           null_ok=1)
             ]
+        else:
+            exp = [
+                FieldInfo(name=u'id', type_code=3, display_size=None,
+                          internal_size=None, precision=10, scale=None,
+                          null_ok=0, extra=u'auto_increment'),
+                FieldInfo(name=u'c1', type_code=3, display_size=None,
+                          internal_size=None, precision=10, scale=None,
+                          null_ok=1, extra=u''),
+                FieldInfo(name=u'c2', type_code=253, display_size=None,
+                          internal_size=20, precision=None, scale=None,
+                          null_ok=1, extra=u'')
+            ]
         res = self.introspect.get_table_description(cur, 'django_t1')
         self.assertEqual(exp, res)
 
     def test_get_relations(self):
         cur = self.cnx.cursor()
-        exp = {1: (0, 'django_t1')}
+        if tests.DJANGO_VERSION < (1, 8):
+            exp = {1: (0, 'django_t1')}
+        else:
+            exp = {u'id_t1': (u'id', u'django_t1')}
         self.assertEqual(exp, self.introspect.get_relations(cur, 'django_t2'))
 
     def test_get_key_columns(self):
@@ -204,6 +216,30 @@ class DjangoIntrospection(tests.MySQLConnectorTests):
         res = self.introspect.get_primary_key_column(cur, 'django_t1')
         self.assertEqual('id', res)
 
+    def test_get_constraints(self):
+        cur = self.cnx.cursor()
+        exp = {
+            'PRIMARY': {'check': False,
+                        'columns': ['id'],
+                        'foreign_key': None,
+                        'index': True,
+                        'primary_key': True,
+                        'unique': True},
+            'django_t2_ibfk_1': {'check': False,
+                                 'columns': ['id_t1'],
+                                 'foreign_key': ('django_t1', 'id'),
+                                 'index': False,
+                                 'primary_key': False,
+                                 'unique': False},
+            'id_t1': {'check': False,
+                      'columns': ['id_t1'],
+                      'foreign_key': None,
+                      'index': True,
+                      'primary_key': False,
+                      'unique': False}
+        }
+        self.assertEqual(
+            exp, self.introspect.get_constraints(cur, 'django_t2'))
 
 @unittest.skipIf(not DJANGO_AVAILABLE, "Django not available")
 class DjangoDatabaseWrapper(tests.MySQLConnectorTests):
@@ -277,26 +313,49 @@ class DjangoDatabaseOperations(tests.MySQLConnectorTests):
         self.dbo = DatabaseOperations(self.cnx)
 
     def test_value_to_db_time(self):
-        self.assertEqual(None, self.dbo.value_to_db_time(None))
+        if tests.DJANGO_VERSION < (1, 9):
+            value_to_db_time = self.dbo.value_to_db_time
+        else:
+            value_to_db_time = self.dbo.adapt_timefield_value
+
+        self.assertEqual(None, value_to_db_time(None))
 
         value = datetime.time(0, 0, 0)
         exp = self.conn.converter._time_to_mysql(value)
-        self.assertEqual(exp, self.dbo.value_to_db_time(value))
+        self.assertEqual(exp, value_to_db_time(value))
 
         value = datetime.time(2, 5, 7)
         exp = self.conn.converter._time_to_mysql(value)
-        self.assertEqual(exp, self.dbo.value_to_db_time(value))
+        self.assertEqual(exp, value_to_db_time(value))
 
     def test_value_to_db_datetime(self):
-        self.assertEqual(None, self.dbo.value_to_db_datetime(None))
+        if tests.DJANGO_VERSION < (1, 9):
+            value_to_db_datetime = self.dbo.value_to_db_datetime
+        else:
+            value_to_db_datetime = self.dbo.adapt_datetimefield_value
+
+        self.assertEqual(None, value_to_db_datetime(None))
 
         value = datetime.datetime(1, 1, 1)
         exp = self.conn.converter._datetime_to_mysql(value)
-        self.assertEqual(exp, self.dbo.value_to_db_datetime(value))
+        self.assertEqual(exp, value_to_db_datetime(value))
 
         value = datetime.datetime(2, 5, 7, 10, 10)
         exp = self.conn.converter._datetime_to_mysql(value)
-        self.assertEqual(exp, self.dbo.value_to_db_datetime(value))
+        self.assertEqual(exp, value_to_db_datetime(value))
+
+    def test_bulk_insert_sql(self):
+        num_values = 5
+        fields = ["col1", "col2", "col3"]
+        placeholder_rows = [["%s"] * len(fields) for _ in range(num_values)]
+        exp = "VALUES {0}".format(", ".join(
+            ["({0})".format(", ".join(["%s"] * len(fields)))] * num_values))
+        if tests.DJANGO_VERSION < (1, 9):
+            self.assertEqual(
+                exp, self.dbo.bulk_insert_sql(fields, num_values))
+        else:
+            self.assertEqual(
+                exp, self.dbo.bulk_insert_sql(fields, placeholder_rows))
 
 
 class DjangoMySQLConverterTests(tests.MySQLConnectorTests):
diff --git a/tests/test_setup.py b/tests/test_setup.py
index 11d0362..74a0313 100644
--- a/tests/test_setup.py
+++ b/tests/test_setup.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -132,7 +132,8 @@ class SetupInfoTests(tests.MySQLConnectorTests):
         for clsfr in setupinfo.classifiers:
             if 'Programming Language :: Python' in clsfr:
                 ver = clsfr.replace('Programming Language :: Python :: ', '')
-                if ver not in ('2.6', '2.7', '3', '3.1', '3.2', '3.3'):
+                if ver not in ('2.6', '2.7', '3', '3.1', '3.2', '3.3', '3.4',
+                               '3.5'):
                     self.fail('Unsupported version in classifiers')
             if 'Development Status ::' in clsfr:
                 status = clsfr.replace('Development Status :: ', '')
diff --git a/unittests.py b/unittests.py
index bb852e0..bfcc19a 100644
--- a/unittests.py
+++ b/unittests.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -144,17 +144,17 @@ ssl
 # Platform specifics
 if os.name == 'nt':
     MY_CNF += '\n'.join((
-        "ssl-ca = {ssl_dir}\\\\tests_CA_cert.pem",
-        "ssl-cert = {ssl_dir}\\\\tests_server_cert.pem",
-        "ssl-key = {ssl_dir}\\\\tests_server_key.pem",
+        "ssl-ca = {ssl_ca}",
+        "ssl-cert = {ssl_cert}",
+        "ssl-key = {ssl_key}",
     ))
     MYSQL_DEFAULT_BASE = os.path.join(
         "C:/", "Program Files", "MySQL", "MySQL Server 5.6")
 else:
     MY_CNF += '\n'.join((
-        "ssl-ca = {ssl_dir}/tests_CA_cert.pem",
-        "ssl-cert = {ssl_dir}/tests_server_cert.pem",
-        "ssl-key = {ssl_dir}/tests_server_key.pem",
+        "ssl-ca = {ssl_ca}",
+        "ssl-cert = {ssl_cert}",
+        "ssl-key = {ssl_key}",
         "innodb_flush_method = O_DIRECT",
     ))
     MYSQL_DEFAULT_BASE = os.path.join('/', 'usr', 'local', 'mysql')
@@ -603,6 +603,9 @@ def init_mysql_server(port, options):
             port=port,
             unix_socket_folder=options.unix_socket_folder,
             ssl_folder=os.path.abspath(tests.SSL_DIR),
+            ssl_ca="tests_CA_cert.pem",
+            ssl_cert="tests_server_cert.pem",
+            ssl_key="tests_server_key.pem",
             name=name,
             sharedir=options.mysql_sharedir)
     except tests.mysqld.MySQLBootstrapError as err:

Reply via email to