Skip to content

Commit ddbf0e8

Browse files
authored
Use docker on Travis for testing MySQL versions
2 parents 9c1b0d8 + f15dd42 commit ddbf0e8

File tree

6 files changed

+131
-154
lines changed

6 files changed

+131
-154
lines changed

.travis.yml

+14-34
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# vim: sw=2 ts=2 sts=2 expandtab
2+
13
sudo: required
24
language: python
35
python:
@@ -21,51 +23,29 @@ matrix:
2123
python: "2.7"
2224

2325
- env:
24-
- DB=5.6.37
25-
python: "3.3"
26-
addons:
27-
apt:
28-
packages:
29-
- libaio-dev
30-
- libnuma-dev
31-
32-
- env:
33-
- DB=5.7.19
26+
- DB=5.7
3427
python: "3.4"
35-
addons:
36-
apt:
37-
packages:
38-
- libaio-dev
39-
- libnuma-dev
40-
28+
services:
29+
- docker
4130

4231

4332
# different py version from 5.6 and 5.7 as cache seems to be based on py version
4433
# http://dev.mysql.com/downloads/mysql/5.7.html has latest development release version
4534
# really only need libaio1 for DB builds however libaio-dev is whitelisted for container builds and liaio1 isn't
4635
install:
47-
- export PASSWORD=travis;
48-
- pip install -U coveralls unittest2 coverage
36+
- pip install -U coveralls unittest2 coverage
4937

5038
before_script:
51-
- ./.travis/initializedb.sh
52-
- mysql -e 'create database test_pymysql DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;'
53-
- mysql -e 'create database test_pymysql2 DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;'
54-
- mysql -u root -e "create user travis_pymysql2 identified by 'some password'; grant all on test_pymysql2.* to travis_pymysql2;"
55-
- mysql -u root -e "create user travis_pymysql2@localhost identified by 'some password'; grant all on test_pymysql2.* to travis_pymysql2@localhost;"
56-
- mysql -e 'select VERSION()'
57-
- python -VV
58-
- rm -f ~/.my.cnf # set in .travis.initialize.db.sh for the above commands - we should be using database.json however
59-
- export COVERALLS_PARALLEL=true
39+
- ./.travis/initializedb.sh
40+
- python -VV
41+
- rm -f ~/.my.cnf # set in .travis.initialize.db.sh for the above commands - we should be using database.json however
42+
- export COVERALLS_PARALLEL=true
6043

6144
script:
6245
- coverage run ./runtests.py
46+
- if [ ! -z "${DB}" ];
47+
then docker logs mysqld;
48+
fi
6349

6450
after_success:
65-
- coveralls
66-
- cat /tmp/mysql.err
67-
68-
after_failure:
69-
- cat /tmp/mysql.err
70-
71-
# vim: sw=2 ts=2 sts=2 expandtab
51+
- coveralls

.travis/database.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
[
2-
{"host": "localhost", "unix_socket": "/var/run/mysqld/mysqld.sock", "user": "root", "passwd": "", "db": "test_pymysql", "use_unicode": true, "local_infile": true},
3-
{"host": "127.0.0.1", "port": 3306, "user": "travis_pymysql2", "password": "some password", "db": "test_pymysql2" }
2+
{"host": "localhost", "unix_socket": "/var/run/mysqld/mysqld.sock", "user": "root", "passwd": "", "db": "test1", "use_unicode": true, "local_infile": true},
3+
{"host": "127.0.0.1", "port": 3306, "user": "test2", "password": "some password", "db": "test2" }
44
]

.travis/docker.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[
2+
{"host": "127.0.0.1", "port": 3306, "user": "root", "passwd": "", "db": "test1", "use_unicode": true, "local_infile": true},
3+
{"host": "127.0.0.1", "port": 3306, "user": "test2", "password": "some password", "db": "test2" }
4+
]

.travis/initializedb.sh

+35-40
Original file line numberDiff line numberDiff line change
@@ -7,47 +7,42 @@ set -v
77

88
if [ ! -z "${DB}" ]; then
99
# disable existing database server in case of accidential connection
10-
mysql -u root -e 'drop user travis@localhost; drop user root@localhost; drop user travis; create user super@localhost; grant all on *.* to super@localhost with grant option'
11-
mysql -u super -e 'drop user root'
12-
13-
F=mysql-${DB}-linux-glibc2.12-x86_64
14-
mkdir -p ${HOME}/mysql
15-
P=${HOME}/mysql/${F}
16-
if [ ! -d "${P}" ]; then
17-
wget https://cdn.mysql.com//Downloads/MySQL-${DB%.*}/${F}.tar.gz -O - | tar -zxf - --directory=${HOME}/mysql
18-
fi
19-
if [ -f "${P}"/my.cnf ]; then
20-
O="--defaults-file=${P}/my.cnf"
21-
fi
22-
if [ -x "${P}"/scripts/mysql_install_db ]; then
23-
I=${P}/scripts/mysql_install_db
24-
O="--defaults-file=${P}/my.cnf"
25-
else
26-
I=${P}/bin/mysqld
27-
IO=" --initialize "
28-
O="--no-defaults "
29-
fi
30-
${I} ${O} ${IO} --basedir=${P} --datadir=${HOME}/db-"${DB}" --log-error=/tmp/mysql.err
31-
PWLINE=$(grep 'A temporary password is generated for root@localhost:' /tmp/mysql.err)
32-
PASSWD=${PWLINE##* }
33-
if [ -x ${P}/bin/mysql_ssl_rsa_setup ]; then
34-
${P}/bin/mysql_ssl_rsa_setup --datadir=${HOME}/db-"${DB}"
35-
fi
36-
# sha256 password auth keys:
37-
openssl genrsa -out "${P}"/private_key.pem 2048
38-
openssl rsa -in "${P}"/private_key.pem -pubout -out "${P}"/public_key.pem
39-
${P}/bin/mysqld_safe ${O} --ledir=/ --mysqld=${P}/bin/mysqld --datadir=${HOME}/db-${DB} --socket=/tmp/mysql.sock --port 3307 --innodb-buffer-pool-size=200M --lc-messages-dir=${P}/share --plugin-dir=${P}/lib/plugin/ --log-error=/tmp/mysql.err &
40-
while [ ! -S /tmp/mysql.sock ]; do
41-
sleep 3
42-
tail /tmp/mysql.err
10+
sudo service mysql stop
11+
12+
docker pull mysql:${DB}
13+
docker run -it --name=mysqld -d -e MYSQL_ALLOW_EMPTY_PASSWORD=yes -p 3306:3306 mysql:${DB}
14+
sleep 10
15+
16+
while :
17+
do
18+
sleep 5
19+
mysql -uroot -h 127.0.0.1 -P 3306 -e 'select version()'
20+
if [ $? = 0 ]; then
21+
break
22+
fi
23+
echo "server logs"
24+
docker logs --tail 5 mysqld
4325
done
44-
tail /tmp/mysql.err
45-
if [ ! -z "${PASSWD}" ]; then
46-
${P}/bin/mysql -S /tmp/mysql.sock -u root -p"${PASSWD}" --connect-expired-password -e "SET PASSWORD = PASSWORD('')"
47-
fi
48-
mysql -S /tmp/mysql.sock -u root -e "create user ${USER}@localhost; create user ${USER}@'%'; grant all on *.* to ${USER}@localhost WITH GRANT OPTION;grant all on *.* to ${USER}@'%' WITH GRANT OPTION;"
49-
sed -e 's/3306/3307/g' -e 's:/var/run/mysqld/mysqld.sock:/tmp/mysql.sock:g' .travis/database.json > pymysql/tests/databases.json
50-
echo -e "[client]\nsocket = /tmp/mysql.sock\n" > "${HOME}"/.my.cnf
26+
27+
echo -e "[client]\nhost = 127.0.0.1\n" > "${HOME}"/.my.cnf
28+
29+
mysql -e 'select VERSION()'
30+
mysql -uroot -e 'create database test1 DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;'
31+
mysql -uroot -e 'create database test2 DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;'
32+
33+
mysql -u root -e "create user test2 identified by 'some password'; grant all on test2.* to test2;"
34+
mysql -u root -e "create user test2@localhost identified by 'some password'; grant all on test2.* to test2@localhost;"
35+
36+
cp .travis/docker.json pymysql/tests/databases.json
5137
else
38+
cat ~/.my.cnf
39+
40+
mysql -e 'select VERSION()'
41+
mysql -e 'create database test1 DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;'
42+
mysql -e 'create database test2 DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;'
43+
44+
mysql -u root -e "create user test2 identified by 'some password'; grant all on test2.* to test2;"
45+
mysql -u root -e "create user test2@localhost identified by 'some password'; grant all on test2.* to test2@localhost;"
46+
5247
cp .travis/database.json pymysql/tests/databases.json
5348
fi

pymysql/tests/base.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ class PyMySQLTestCase(unittest2.TestCase):
2020
else:
2121
databases = [
2222
{"host":"localhost","user":"root",
23-
"passwd":"","db":"test_pymysql", "use_unicode": True, 'local_infile': True},
24-
{"host":"localhost","user":"root","passwd":"","db":"test_pymysql2"}]
23+
"passwd":"","db":"test1", "use_unicode": True, 'local_infile': True},
24+
{"host":"localhost","user":"root","passwd":"","db":"test2"}]
2525

2626
def mysql_server_is(self, conn, version_tuple):
2727
"""Return True if the given connection is on the version given or

pymysql/tests/test_SSCursor.py

+74-76
Original file line numberDiff line numberDiff line change
@@ -28,82 +28,80 @@ def test_SSCursor(self):
2828
('America', '', 'America/Denver'),
2929
('America', '', 'America/Detroit'),]
3030

31-
try:
32-
cursor = conn.cursor(pymysql.cursors.SSCursor)
33-
34-
# Create table
35-
cursor.execute('CREATE TABLE tz_data ('
36-
'region VARCHAR(64),'
37-
'zone VARCHAR(64),'
38-
'name VARCHAR(64))')
39-
40-
conn.begin()
41-
# Test INSERT
42-
for i in data:
43-
cursor.execute('INSERT INTO tz_data VALUES (%s, %s, %s)', i)
44-
self.assertEqual(conn.affected_rows(), 1, 'affected_rows does not match')
45-
conn.commit()
46-
47-
# Test fetchone()
48-
iter = 0
49-
cursor.execute('SELECT * FROM tz_data')
50-
while True:
51-
row = cursor.fetchone()
52-
if row is None:
53-
break
54-
iter += 1
55-
56-
# Test cursor.rowcount
57-
self.assertEqual(cursor.rowcount, affected_rows,
58-
'cursor.rowcount != %s' % (str(affected_rows)))
59-
60-
# Test cursor.rownumber
61-
self.assertEqual(cursor.rownumber, iter,
62-
'cursor.rowcount != %s' % (str(iter)))
63-
64-
# Test row came out the same as it went in
65-
self.assertEqual((row in data), True,
66-
'Row not found in source data')
67-
68-
# Test fetchall
69-
cursor.execute('SELECT * FROM tz_data')
70-
self.assertEqual(len(cursor.fetchall()), len(data),
71-
'fetchall failed. Number of rows does not match')
72-
73-
# Test fetchmany
74-
cursor.execute('SELECT * FROM tz_data')
75-
self.assertEqual(len(cursor.fetchmany(2)), 2,
76-
'fetchmany failed. Number of rows does not match')
77-
78-
# So MySQLdb won't throw "Commands out of sync"
79-
while True:
80-
res = cursor.fetchone()
81-
if res is None:
82-
break
83-
84-
# Test update, affected_rows()
85-
cursor.execute('UPDATE tz_data SET zone = %s', ['Foo'])
86-
conn.commit()
87-
self.assertEqual(cursor.rowcount, len(data),
88-
'Update failed. affected_rows != %s' % (str(len(data))))
89-
90-
# Test executemany
91-
cursor.executemany('INSERT INTO tz_data VALUES (%s, %s, %s)', data)
92-
self.assertEqual(cursor.rowcount, len(data),
93-
'executemany failed. cursor.rowcount != %s' % (str(len(data))))
94-
95-
# Test multiple datasets
96-
cursor.execute('SELECT 1; SELECT 2; SELECT 3')
97-
self.assertListEqual(list(cursor), [(1, )])
98-
self.assertTrue(cursor.nextset())
99-
self.assertListEqual(list(cursor), [(2, )])
100-
self.assertTrue(cursor.nextset())
101-
self.assertListEqual(list(cursor), [(3, )])
102-
self.assertFalse(cursor.nextset())
103-
104-
finally:
105-
cursor.execute('DROP TABLE IF EXISTS tz_data')
106-
cursor.close()
31+
cursor = conn.cursor(pymysql.cursors.SSCursor)
32+
33+
# Create table
34+
cursor.execute('CREATE TABLE tz_data ('
35+
'region VARCHAR(64),'
36+
'zone VARCHAR(64),'
37+
'name VARCHAR(64))')
38+
39+
conn.begin()
40+
# Test INSERT
41+
for i in data:
42+
cursor.execute('INSERT INTO tz_data VALUES (%s, %s, %s)', i)
43+
self.assertEqual(conn.affected_rows(), 1, 'affected_rows does not match')
44+
conn.commit()
45+
46+
# Test fetchone()
47+
iter = 0
48+
cursor.execute('SELECT * FROM tz_data')
49+
while True:
50+
row = cursor.fetchone()
51+
if row is None:
52+
break
53+
iter += 1
54+
55+
# Test cursor.rowcount
56+
self.assertEqual(cursor.rowcount, affected_rows,
57+
'cursor.rowcount != %s' % (str(affected_rows)))
58+
59+
# Test cursor.rownumber
60+
self.assertEqual(cursor.rownumber, iter,
61+
'cursor.rowcount != %s' % (str(iter)))
62+
63+
# Test row came out the same as it went in
64+
self.assertEqual((row in data), True,
65+
'Row not found in source data')
66+
67+
# Test fetchall
68+
cursor.execute('SELECT * FROM tz_data')
69+
self.assertEqual(len(cursor.fetchall()), len(data),
70+
'fetchall failed. Number of rows does not match')
71+
72+
# Test fetchmany
73+
cursor.execute('SELECT * FROM tz_data')
74+
self.assertEqual(len(cursor.fetchmany(2)), 2,
75+
'fetchmany failed. Number of rows does not match')
76+
77+
# So MySQLdb won't throw "Commands out of sync"
78+
while True:
79+
res = cursor.fetchone()
80+
if res is None:
81+
break
82+
83+
# Test update, affected_rows()
84+
cursor.execute('UPDATE tz_data SET zone = %s', ['Foo'])
85+
conn.commit()
86+
self.assertEqual(cursor.rowcount, len(data),
87+
'Update failed. affected_rows != %s' % (str(len(data))))
88+
89+
# Test executemany
90+
cursor.executemany('INSERT INTO tz_data VALUES (%s, %s, %s)', data)
91+
self.assertEqual(cursor.rowcount, len(data),
92+
'executemany failed. cursor.rowcount != %s' % (str(len(data))))
93+
94+
# Test multiple datasets
95+
cursor.execute('SELECT 1; SELECT 2; SELECT 3')
96+
self.assertListEqual(list(cursor), [(1, )])
97+
self.assertTrue(cursor.nextset())
98+
self.assertListEqual(list(cursor), [(2, )])
99+
self.assertTrue(cursor.nextset())
100+
self.assertListEqual(list(cursor), [(3, )])
101+
self.assertFalse(cursor.nextset())
102+
103+
cursor.execute('DROP TABLE IF EXISTS tz_data')
104+
cursor.close()
107105

108106
__all__ = ["TestSSCursor"]
109107

0 commit comments

Comments
 (0)