Skip to content

Commit a0c34eb

Browse files
committed
WL14306: Integrate QA tests into Connector/Python test suite
1 parent 9e2881d commit a0c34eb

35 files changed

+14687
-0
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ v8.0.26
1414
- WL#14634: Running unit tests against external server
1515
- WL#14542: Deprecate TLS 1.0 and 1.1
1616
- WL#14440: Support for authentication_kerberos_client authentication plugin
17+
- WL#14306: Integrate QA tests into Connector/Python test suite
1718
- WL#14237: Support query attributes
1819
- BUG#32947160: Remove MySQLdb module dependency from Django backend
1920
- BUG#32838010: Fix option files parsing with include directive

tests/__init__.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import unittest
4141
import logging
4242
import shutil
43+
import struct
4344
import subprocess
4445
import errno
4546
import traceback
@@ -71,6 +72,7 @@ def memoized_func(*args, **kwargs):
7172
except ImportError:
7273
pass
7374

75+
ARCH_64BIT = struct.calcsize("P") * 8 == 64
7476
LOGGER_NAME = "myconnpy_tests"
7577
LOGGER = logging.getLogger(LOGGER_NAME)
7678
_CACHED_TESTCASES = []
@@ -510,15 +512,43 @@ def wrapper(self, *args, **kwargs):
510512
return _use_cnx
511513

512514

515+
def foreach_session(**extra_config):
516+
def _use_cnx(func):
517+
@wraps(func)
518+
def wrapper(self, *args, **kwargs):
519+
import mysqlx
520+
if not hasattr(self, "config"):
521+
self.config = get_mysqlx_config()
522+
if extra_config:
523+
for key, value in extra_config.items():
524+
self.config[key] = value
525+
for use_pure in self.use_pure_options:
526+
config = self.config.copy()
527+
config["use_pure"] = use_pure
528+
self.session = mysqlx.get_session(config)
529+
self.schema = self.session.get_default_schema()
530+
try:
531+
func(self, *args, **kwargs)
532+
except Exception as exc:
533+
traceback.print_exc(file=sys.stdout)
534+
raise exc
535+
finally:
536+
self.session.close()
537+
return wrapper
538+
return _use_cnx
539+
540+
513541
class MySQLConnectorTests(unittest.TestCase):
514542

515543
def __init__(self, methodName='runTest'):
516544
from mysql.connector import connection
517545
self.all_cnx_classes = [connection.MySQLConnection]
546+
self.use_pure_options = [True]
518547
self.maxDiff = 64
519548
try:
520549
import _mysql_connector
521550
from mysql.connector import connection_cext
551+
self.use_pure_options.append(False)
522552
except ImportError:
523553
self.have_cext = False
524554
else:
@@ -625,6 +655,13 @@ def check_namedtuple(self, tocheck, attrs):
625655
self.fail("Attribute '{0}' not part of namedtuple {1}".format(
626656
attr, tocheck))
627657

658+
def get_clean_mysql_config(self):
659+
config = get_mysql_config()
660+
return {
661+
opt: config[opt]
662+
for opt in ["host", "port", "user", "password", "database"]
663+
}
664+
628665

629666
class TestsCursor(MySQLConnectorTests):
630667

@@ -745,6 +782,8 @@ class MySQLxTests(MySQLConnectorTests):
745782

746783
def __init__(self, methodName="runTest"):
747784
super(MySQLxTests, self).__init__(methodName=methodName)
785+
from mysqlx.protobuf import HAVE_MYSQLXPB_CEXT
786+
self.use_pure_options = [True, False] if HAVE_MYSQLXPB_CEXT else [True]
748787

749788
def run(self, result=None):
750789
if sys.version_info[0:2] == (2, 6):

tests/data/qa/option/my_cli.cnf

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
[client]
2+
3+
user=root
4+
password=
5+
database=cli_data
6+
join_buffer_size = 128M
7+
sort_buffer_size = 2M
8+
read_rnd_buffer_size = 2M
9+
use_unicode=True
10+
charset=latin7
11+
collation= latin7_general_ci
12+
autocommit=True
13+
sql_mode=ANSI
14+
get_warnings=True
15+
raise_on_warnings=True
16+
buffered=True
17+
raw=True
18+
force_ipv6=False
19+
20+
21+
22+
23+
24+
25+
26+
27+

tests/data/qa/option/my_duplicate.cnf

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
3+
[connector_python]
4+
user=root
5+
password=
6+
database=cpy_data
7+
host=localhost
8+
port=3306
9+
[connector_python]
10+
user=root
11+
password=
12+
database=mygroup_data
13+
14+
15+
16+
17+
18+

tests/data/qa/option/my_option.cnf

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
[client]
2+
3+
user=root
4+
password=mypass
5+
database=cli_data
6+
join_buffer_size = 128M
7+
sort_buffer_size = 2M
8+
read_rnd_buffer_size = 2M
9+
10+
[connector_python]
11+
user=root
12+
password=
13+
database=cpy_data
14+
use_unicode=True
15+
charset=latin7
16+
collation= latin7_general_ci
17+
autocommit=True
18+
pool_size=1
19+
pool_name=mypool
20+
sql_mode=ANSI
21+
get_warnings=True
22+
raise_on_warnings=True
23+
connection_timeout=10
24+
buffered=True
25+
raw=True
26+
force_ipv6=False
27+
28+
[my_group]
29+
30+
user=root
31+
password=
32+
database=mygroup_data
33+
use_unicode=True
34+
charset=latin7
35+
collation= latin7_general_ci
36+
autocommit=True
37+
sql_mode=ANSI
38+
get_warnings=True
39+
raise_on_warnings=True
40+
connection_timeout=10
41+
buffered=True
42+
raw=True
43+
force_ipv6=False
44+
45+
[my_explicit]
46+
user=root
47+
password=
48+
database=cpy_data
49+
use_unicode=True
50+
charset=latin7
51+
collation= latin7_general_ci
52+
autocommit=True
53+
sql_mode=ANSI
54+
get_warnings=True
55+
raise_on_warnings=True
56+
connection_timeout=10
57+
buffered=True
58+
raw=True
59+
force_ipv6=False
60+
61+
62+
63+
[invalid_group]
64+
65+
user=root
66+
password=mypass
67+
database=mygroup_data
68+
host=localhost
69+
use_unicode=True
70+
charse=latin7
71+
72+
73+
74+

tests/qa/__init__.py

Whitespace-only changes.

tests/qa/test_qa_bug16217743.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Copyright (c) 2013, 2021, Oracle and/or its affiliates.
2+
#
3+
# This program is free software; you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License, version 2.0, as
5+
# published by the Free Software Foundation.
6+
#
7+
# This program is also distributed with certain software (including
8+
# but not limited to OpenSSL) that is licensed under separate terms,
9+
# as designated in a particular file or component or in included license
10+
# documentation. The authors of MySQL hereby grant you an
11+
# additional permission to link the program and your derivative works
12+
# with the separately licensed software that they have included with
13+
# MySQL.
14+
#
15+
# Without limiting anything contained in the foregoing, this file,
16+
# which is part of MySQL Connector/Python, is also subject to the
17+
# Universal FOSS Exception, version 1.0, a copy of which can be found at
18+
# http://oss.oracle.com/licenses/universal-foss-exception.
19+
#
20+
# This program is distributed in the hope that it will be useful, but
21+
# WITHOUT ANY WARRANTY; without even the implied warranty of
22+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23+
# See the GNU General Public License, version 2.0, for more details.
24+
#
25+
# You should have received a copy of the GNU General Public License
26+
# along with this program; if not, write to the Free Software Foundation, Inc.,
27+
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28+
29+
import datetime
30+
import mysql.connector
31+
import tests
32+
33+
34+
class BUG1617743(tests.MySQLConnectorTests):
35+
"""Test for fix for Bug 16217743."""
36+
@tests.foreach_cnx()
37+
def test_bug(self):
38+
with self.cnx.cursor() as cur:
39+
cur.execute("drop table if exists varTable")
40+
cur.execute("create table varTable(f1 varchar(255))")
41+
# Create Procedure
42+
cur.execute("drop procedure if exists varProc")
43+
cur.execute(
44+
"create procedure varProc(v1 varchar(255)) "
45+
"begin insert into varTable values(v1); end"
46+
)
47+
cur.execute("drop procedure if exists dateProc")
48+
cur.execute(
49+
"create procedure dateProc(v1 DATE) "
50+
"begin insert into varTable values(v1); end"
51+
)
52+
cur.execute("drop procedure if exists timestampProc")
53+
cur.execute(
54+
"create procedure timestampProc(v1 TIMESTAMP) "
55+
"begin insert into varTable values(v1); end"
56+
)
57+
58+
# Create a table with VARCHAR column type
59+
exp = (
60+
"&^$%J()@%EW*##^@!!!!*~*#&$*****#&@(!",
61+
"Derek O'Brien",
62+
"Readable Data",
63+
)
64+
for value in exp:
65+
cur.callproc("varProc", (value,))
66+
67+
cur.execute("select f1 from varTable")
68+
for row in cur.fetchall():
69+
self.assertIn(row[0], exp)
70+
71+
# Create a table with DATE column type
72+
cur.execute("drop table if exists varTable")
73+
cur.execute("create table varTable(f1 DATE)")
74+
cur.callproc("dateProc", ("1978-10-18",))
75+
cur.execute("select f1 from varTable")
76+
res = cur.fetchone()
77+
self.assertEqual(res[0], datetime.date(1978, 10, 18))
78+
79+
# Create a table with TIMESTAMP column type
80+
cur.execute("drop table if exists varTable")
81+
cur.execute("create table varTable(f1 TIMESTAMP)")
82+
cur.callproc("timestampProc", ("2013-01-01 00:00:01",))
83+
cur.execute("select f1 from varTable")
84+
res = cur.fetchone()
85+
self.assertEqual(res[0], datetime.datetime(2013, 1, 1, 0, 0, 1))
86+
87+
cur.execute("drop procedure if exists varProc")
88+
cur.execute("drop procedure if exists dateProc")
89+
cur.execute("drop procedure if exists timestampProc")
90+
self.cnx.commit()

0 commit comments

Comments
 (0)