We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Upgrade db image to newer version
Upgrade following images:

- MySQL 8.0.20
- PostgreSQL 12.2
- MariaDB 10.4.12

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `contrib/travis-ci/testrunner.py`
Content:
```
1 #!/usr/bin/env python3
2 #
3 # Nitrate is a test case management system.
4 # Copyright (C) 2019  Nitrate Team
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License along
17 # with this program; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 
20 import argparse
21 import logging
22 import os
23 import re
24 import subprocess
25 
26 from typing import Dict, List
27 
28 logging.basicConfig(level=logging.DEBUG)
29 log = logging.getLogger(__name__)
30 
31 DB_CONTAINER_NAME = 'nitrate-test-db'
32 TEST_DB_NAME = 'nitrate'
33 TEST_BOX_IMAGE = 'quay.io/nitrate/testbox:latest'
34 VALID_NITRATE_DB_NAMES = ['mysql', 'mariadb', 'postgres', 'sqlite']
35 # Since this script was written originally to work inside Travis-CI, using
36 # Python version 3.6 and 3.7 would be much easier to match the value of
37 # environment variable TRAVIS_PYTHON_VERSION.
38 VALID_PYTHON_VERSIONS = ['3.6', '3.7']
39 DB_CONTAINER_INFO = {
40     'mysql': {
41         'db_engine': 'mysql',
42         'db_image': 'mysql:5.7',
43     },
44     'mariadb': {
45         'db_engine': 'mysql',
46         'db_image': 'mariadb:10.2.21',
47     },
48     'sqlite': {
49         'db_engine': 'sqlite',
50         'db_image': '',
51     },
52     'postgres': {
53         'db_engine': 'pgsql',
54         'db_image': 'postgres:10.6',
55     },
56 }
57 
58 
59 def validate_django_ver(value):
60     regex = r'^django(>|>=|<|<=)[0-9]+\.[0-9]+,(>|>=|<|<=)[0-9]+\.[0-9]+$'
61     if not re.match(regex, value):
62         raise argparse.ArgumentTypeError(
63             f"Invalid django version specifier '{value}'.")
64     return value
65 
66 
67 def validate_project_dir(value):
68     if os.path.exists(value):
69         return value
70     return argparse.ArgumentTypeError(
71         'Invalid project root directory. It might not exist.')
72 
73 
74 def docker_run(image,
75                rm: bool = False,
76                detach: bool = False,
77                interactive: bool = False,
78                tty: bool = False,
79                name: str = None,
80                link: str = None,
81                volumes: List[str] = None,
82                envs: Dict[str, str] = None,
83                cmd_args: List[str] = None
84                ) -> None:
85     cmd = ['docker', 'run']
86     if rm:
87         cmd.append('--rm')
88     if detach:
89         cmd.append('--detach')
90     if interactive:
91         cmd.append('-i')
92     if tty:
93         cmd.append('-t')
94     if name:
95         cmd.append('--name')
96         cmd.append(name)
97     if link:
98         cmd.append('--link')
99         cmd.append(link)
100     if volumes:
101         for item in volumes:
102             cmd.append('--volume')
103             cmd.append(item)
104     if envs:
105         for var_name, var_value in envs.items():
106             cmd.append('--env')
107             cmd.append(f'{var_name}={var_value}')
108     cmd.append(image)
109     if cmd_args:
110         cmd.extend(cmd_args)
111 
112     log.debug('Run: %r', cmd)
113     subprocess.check_call(cmd)
114 
115 
116 def docker_ps(all_: bool = False,
117               filter_: List[str] = None,
118               quiet: bool = False) -> str:
119     cmd = ['docker', 'ps']
120     if all_:
121         cmd.append('--all')
122     if filter_:
123         for item in filter_:
124             cmd.append('--filter')
125             cmd.append(item)
126     if quiet:
127         cmd.append('--quiet')
128 
129     log.debug('Run: %r', cmd)
130     return subprocess.check_output(cmd, universal_newlines=True)
131 
132 
133 def docker_stop(name: str) -> None:
134     cmd = ['docker', 'stop', name]
135     log.debug('Run: %r', cmd)
136     subprocess.check_call(cmd)
137 
138 
139 def stop_container(name: str) -> None:
140     c_hash = docker_ps(all_=True, filter_=[f'name={name}'], quiet=True)
141     if c_hash:
142         docker_stop(name)
143 
144 
145 def main():
146     parser = argparse.ArgumentParser(
147         description='Run tests matrix inside containers. This is particularly '
148                     'useful for running tests in Travis-CI.'
149     )
150     parser.add_argument(
151         '--python-ver',
152         choices=VALID_PYTHON_VERSIONS,
153         default='3.7',
154         help='Specify Python version')
155     parser.add_argument(
156         '--django-ver',
157         type=validate_django_ver,
158         default='django<2.3,>=2.2',
159         help='Specify django version specifier')
160     parser.add_argument(
161         '--nitrate-db',
162         choices=VALID_NITRATE_DB_NAMES,
163         default='sqlite',
164         help='Database engine name')
165     parser.add_argument(
166         '--project-dir',
167         metavar='DIR',
168         type=validate_project_dir,
169         default=os.path.abspath(os.curdir),
170         help='Project root directory. Default to current working directory')
171     parser.add_argument(
172         'targets', nargs='+', help='Test targets')
173 
174     args = parser.parse_args()
175 
176     container_info = DB_CONTAINER_INFO[args.nitrate_db]
177     db_engine = container_info['db_engine']
178     db_image = container_info['db_image']
179 
180     stop_container(DB_CONTAINER_NAME)
181 
182     test_box_run_opts = None
183 
184     if db_engine == 'mysql':
185         docker_run(
186             db_image,
187             rm=True,
188             name=DB_CONTAINER_NAME,
189             detach=True,
190             envs={
191                'MYSQL_ALLOW_EMPTY_PASSWORD': 'yes',
192                'MYSQL_DATABASE': 'nitrate'
193             },
194             cmd_args=[
195                '--character-set-server=utf8mb4',
196                '--collation-server=utf8mb4_unicode_ci'
197             ])
198         test_box_run_opts = {
199             'link': f'{DB_CONTAINER_NAME}:mysql',
200             'envs': {
201                 'NITRATE_DB_ENGINE': db_engine,
202                 'NITRATE_DB_NAME': TEST_DB_NAME,
203                 'NITRATE_DB_HOST': DB_CONTAINER_NAME,
204             }
205         }
206     elif db_engine == 'pgsql':
207         docker_run(
208             db_image,
209             rm=True,
210             detach=True,
211             name=DB_CONTAINER_NAME,
212             envs={'POSTGRES_PASSWORD': 'admin'}
213         )
214         test_box_run_opts = {
215             'link': f'{DB_CONTAINER_NAME}:postgres',
216             'envs': {
217                 'NITRATE_DB_ENGINE': db_engine,
218                 'NITRATE_DB_HOST': DB_CONTAINER_NAME,
219                 'NITRATE_DB_NAME': TEST_DB_NAME,
220                 'NITRATE_DB_USER': 'postgres',
221                 'NITRATE_DB_PASSWORD': 'admin',
222             }
223         }
224     elif db_engine == 'sqlite':
225         # No need to launch a SQLite docker image
226         test_box_run_opts = {
227             'envs': {
228                 'NITRATE_DB_ENGINE': db_engine,
229                 'NITRATE_DB_NAME': "file::memory:",
230             }
231         }
232 
233     test_box_container_name = f'nitrate-testbox-py{args.python_ver.replace(".", "")}'
234     test_box_run_opts.update({
235         'rm': True,
236         'interactive': True,
237         'tty': True,
238         'name': test_box_container_name,
239         'volumes': [f'{args.project_dir}:/code:Z'],
240     })
241     test_box_run_opts['envs'].update({
242         'PYTHON_VER': f'py{args.python_ver.replace(".", "")}',
243         'DJANGO_VER': args.django_ver,
244         'TEST_TARGETS': '"{}"'.format(' '.join(args.targets)),
245     })
246 
247     try:
248         log.debug('Start testbox to run tests')
249         docker_run(TEST_BOX_IMAGE, **test_box_run_opts)
250     finally:
251         log.debug('Stop container: %s', DB_CONTAINER_NAME)
252         stop_container(DB_CONTAINER_NAME)
253 
254 
255 if __name__ == '__main__':
256     main()
257
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/contrib/travis-ci/testrunner.py b/contrib/travis-ci/testrunner.py
--- a/contrib/travis-ci/testrunner.py
+++ b/contrib/travis-ci/testrunner.py
@@ -39,11 +39,11 @@
 DB_CONTAINER_INFO = {
     'mysql': {
         'db_engine': 'mysql',
-        'db_image': 'mysql:5.7',
+        'db_image': 'mysql:8.0.20',
     },
     'mariadb': {
         'db_engine': 'mysql',
-        'db_image': 'mariadb:10.2.21',
+        'db_image': 'mariadb:10.4.12',
     },
     'sqlite': {
         'db_engine': 'sqlite',
@@ -51,7 +51,7 @@
     },
     'postgres': {
         'db_engine': 'pgsql',
-        'db_image': 'postgres:10.6',
+        'db_image': 'postgres:12.2',
     },
 }

{"golden_diff": "diff --git a/contrib/travis-ci/testrunner.py b/contrib/travis-ci/testrunner.py\n--- a/contrib/travis-ci/testrunner.py\n+++ b/contrib/travis-ci/testrunner.py\n@@ -39,11 +39,11 @@\n DB_CONTAINER_INFO = {\n     'mysql': {\n         'db_engine': 'mysql',\n-        'db_image': 'mysql:5.7',\n+        'db_image': 'mysql:8.0.20',\n     },\n     'mariadb': {\n         'db_engine': 'mysql',\n-        'db_image': 'mariadb:10.2.21',\n+        'db_image': 'mariadb:10.4.12',\n     },\n     'sqlite': {\n         'db_engine': 'sqlite',\n@@ -51,7 +51,7 @@\n     },\n     'postgres': {\n         'db_engine': 'pgsql',\n-        'db_image': 'postgres:10.6',\n+        'db_image': 'postgres:12.2',\n     },\n }\n", "issue": "Upgrade db image to newer version\nUpgrade following images:\r\n\r\n- MySQL 8.0.20\r\n- PostgreSQL 12.2\r\n- MariaDB 10.4.12\n", "before_files": [{"content": "#!/usr/bin/env python3\n#\n# Nitrate is a test case management system.\n# Copyright (C) 2019  Nitrate Team\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License along\n# with this program; if not, write to the Free Software Foundation, Inc.,\n# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nimport argparse\nimport logging\nimport os\nimport re\nimport subprocess\n\nfrom typing import Dict, List\n\nlogging.basicConfig(level=logging.DEBUG)\nlog = logging.getLogger(__name__)\n\nDB_CONTAINER_NAME = 'nitrate-test-db'\nTEST_DB_NAME = 'nitrate'\nTEST_BOX_IMAGE = 'quay.io/nitrate/testbox:latest'\nVALID_NITRATE_DB_NAMES = ['mysql', 'mariadb', 'postgres', 'sqlite']\n# Since this script was written originally to work inside Travis-CI, using\n# Python version 3.6 and 3.7 would be much easier to match the value of\n# environment variable TRAVIS_PYTHON_VERSION.\nVALID_PYTHON_VERSIONS = ['3.6', '3.7']\nDB_CONTAINER_INFO = {\n    'mysql': {\n        'db_engine': 'mysql',\n        'db_image': 'mysql:5.7',\n    },\n    'mariadb': {\n        'db_engine': 'mysql',\n        'db_image': 'mariadb:10.2.21',\n    },\n    'sqlite': {\n        'db_engine': 'sqlite',\n        'db_image': '',\n    },\n    'postgres': {\n        'db_engine': 'pgsql',\n        'db_image': 'postgres:10.6',\n    },\n}\n\n\ndef validate_django_ver(value):\n    regex = r'^django(>|>=|<|<=)[0-9]+\\.[0-9]+,(>|>=|<|<=)[0-9]+\\.[0-9]+$'\n    if not re.match(regex, value):\n        raise argparse.ArgumentTypeError(\n            f\"Invalid django version specifier '{value}'.\")\n    return value\n\n\ndef validate_project_dir(value):\n    if os.path.exists(value):\n        return value\n    return argparse.ArgumentTypeError(\n        'Invalid project root directory. It might not exist.')\n\n\ndef docker_run(image,\n               rm: bool = False,\n               detach: bool = False,\n               interactive: bool = False,\n               tty: bool = False,\n               name: str = None,\n               link: str = None,\n               volumes: List[str] = None,\n               envs: Dict[str, str] = None,\n               cmd_args: List[str] = None\n               ) -> None:\n    cmd = ['docker', 'run']\n    if rm:\n        cmd.append('--rm')\n    if detach:\n        cmd.append('--detach')\n    if interactive:\n        cmd.append('-i')\n    if tty:\n        cmd.append('-t')\n    if name:\n        cmd.append('--name')\n        cmd.append(name)\n    if link:\n        cmd.append('--link')\n        cmd.append(link)\n    if volumes:\n        for item in volumes:\n            cmd.append('--volume')\n            cmd.append(item)\n    if envs:\n        for var_name, var_value in envs.items():\n            cmd.append('--env')\n            cmd.append(f'{var_name}={var_value}')\n    cmd.append(image)\n    if cmd_args:\n        cmd.extend(cmd_args)\n\n    log.debug('Run: %r', cmd)\n    subprocess.check_call(cmd)\n\n\ndef docker_ps(all_: bool = False,\n              filter_: List[str] = None,\n              quiet: bool = False) -> str:\n    cmd = ['docker', 'ps']\n    if all_:\n        cmd.append('--all')\n    if filter_:\n        for item in filter_:\n            cmd.append('--filter')\n            cmd.append(item)\n    if quiet:\n        cmd.append('--quiet')\n\n    log.debug('Run: %r', cmd)\n    return subprocess.check_output(cmd, universal_newlines=True)\n\n\ndef docker_stop(name: str) -> None:\n    cmd = ['docker', 'stop', name]\n    log.debug('Run: %r', cmd)\n    subprocess.check_call(cmd)\n\n\ndef stop_container(name: str) -> None:\n    c_hash = docker_ps(all_=True, filter_=[f'name={name}'], quiet=True)\n    if c_hash:\n        docker_stop(name)\n\n\ndef main():\n    parser = argparse.ArgumentParser(\n        description='Run tests matrix inside containers. This is particularly '\n                    'useful for running tests in Travis-CI.'\n    )\n    parser.add_argument(\n        '--python-ver',\n        choices=VALID_PYTHON_VERSIONS,\n        default='3.7',\n        help='Specify Python version')\n    parser.add_argument(\n        '--django-ver',\n        type=validate_django_ver,\n        default='django<2.3,>=2.2',\n        help='Specify django version specifier')\n    parser.add_argument(\n        '--nitrate-db',\n        choices=VALID_NITRATE_DB_NAMES,\n        default='sqlite',\n        help='Database engine name')\n    parser.add_argument(\n        '--project-dir',\n        metavar='DIR',\n        type=validate_project_dir,\n        default=os.path.abspath(os.curdir),\n        help='Project root directory. Default to current working directory')\n    parser.add_argument(\n        'targets', nargs='+', help='Test targets')\n\n    args = parser.parse_args()\n\n    container_info = DB_CONTAINER_INFO[args.nitrate_db]\n    db_engine = container_info['db_engine']\n    db_image = container_info['db_image']\n\n    stop_container(DB_CONTAINER_NAME)\n\n    test_box_run_opts = None\n\n    if db_engine == 'mysql':\n        docker_run(\n            db_image,\n            rm=True,\n            name=DB_CONTAINER_NAME,\n            detach=True,\n            envs={\n               'MYSQL_ALLOW_EMPTY_PASSWORD': 'yes',\n               'MYSQL_DATABASE': 'nitrate'\n            },\n            cmd_args=[\n               '--character-set-server=utf8mb4',\n               '--collation-server=utf8mb4_unicode_ci'\n            ])\n        test_box_run_opts = {\n            'link': f'{DB_CONTAINER_NAME}:mysql',\n            'envs': {\n                'NITRATE_DB_ENGINE': db_engine,\n                'NITRATE_DB_NAME': TEST_DB_NAME,\n                'NITRATE_DB_HOST': DB_CONTAINER_NAME,\n            }\n        }\n    elif db_engine == 'pgsql':\n        docker_run(\n            db_image,\n            rm=True,\n            detach=True,\n            name=DB_CONTAINER_NAME,\n            envs={'POSTGRES_PASSWORD': 'admin'}\n        )\n        test_box_run_opts = {\n            'link': f'{DB_CONTAINER_NAME}:postgres',\n            'envs': {\n                'NITRATE_DB_ENGINE': db_engine,\n                'NITRATE_DB_HOST': DB_CONTAINER_NAME,\n                'NITRATE_DB_NAME': TEST_DB_NAME,\n                'NITRATE_DB_USER': 'postgres',\n                'NITRATE_DB_PASSWORD': 'admin',\n            }\n        }\n    elif db_engine == 'sqlite':\n        # No need to launch a SQLite docker image\n        test_box_run_opts = {\n            'envs': {\n                'NITRATE_DB_ENGINE': db_engine,\n                'NITRATE_DB_NAME': \"file::memory:\",\n            }\n        }\n\n    test_box_container_name = f'nitrate-testbox-py{args.python_ver.replace(\".\", \"\")}'\n    test_box_run_opts.update({\n        'rm': True,\n        'interactive': True,\n        'tty': True,\n        'name': test_box_container_name,\n        'volumes': [f'{args.project_dir}:/code:Z'],\n    })\n    test_box_run_opts['envs'].update({\n        'PYTHON_VER': f'py{args.python_ver.replace(\".\", \"\")}',\n        'DJANGO_VER': args.django_ver,\n        'TEST_TARGETS': '\"{}\"'.format(' '.join(args.targets)),\n    })\n\n    try:\n        log.debug('Start testbox to run tests')\n        docker_run(TEST_BOX_IMAGE, **test_box_run_opts)\n    finally:\n        log.debug('Stop container: %s', DB_CONTAINER_NAME)\n        stop_container(DB_CONTAINER_NAME)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "contrib/travis-ci/testrunner.py"}], "after_files": [{"content": "#!/usr/bin/env python3\n#\n# Nitrate is a test case management system.\n# Copyright (C) 2019  Nitrate Team\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License along\n# with this program; if not, write to the Free Software Foundation, Inc.,\n# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nimport argparse\nimport logging\nimport os\nimport re\nimport subprocess\n\nfrom typing import Dict, List\n\nlogging.basicConfig(level=logging.DEBUG)\nlog = logging.getLogger(__name__)\n\nDB_CONTAINER_NAME = 'nitrate-test-db'\nTEST_DB_NAME = 'nitrate'\nTEST_BOX_IMAGE = 'quay.io/nitrate/testbox:latest'\nVALID_NITRATE_DB_NAMES = ['mysql', 'mariadb', 'postgres', 'sqlite']\n# Since this script was written originally to work inside Travis-CI, using\n# Python version 3.6 and 3.7 would be much easier to match the value of\n# environment variable TRAVIS_PYTHON_VERSION.\nVALID_PYTHON_VERSIONS = ['3.6', '3.7']\nDB_CONTAINER_INFO = {\n    'mysql': {\n        'db_engine': 'mysql',\n        'db_image': 'mysql:8.0.20',\n    },\n    'mariadb': {\n        'db_engine': 'mysql',\n        'db_image': 'mariadb:10.4.12',\n    },\n    'sqlite': {\n        'db_engine': 'sqlite',\n        'db_image': '',\n    },\n    'postgres': {\n        'db_engine': 'pgsql',\n        'db_image': 'postgres:12.2',\n    },\n}\n\n\ndef validate_django_ver(value):\n    regex = r'^django(>|>=|<|<=)[0-9]+\\.[0-9]+,(>|>=|<|<=)[0-9]+\\.[0-9]+$'\n    if not re.match(regex, value):\n        raise argparse.ArgumentTypeError(\n            f\"Invalid django version specifier '{value}'.\")\n    return value\n\n\ndef validate_project_dir(value):\n    if os.path.exists(value):\n        return value\n    return argparse.ArgumentTypeError(\n        'Invalid project root directory. It might not exist.')\n\n\ndef docker_run(image,\n               rm: bool = False,\n               detach: bool = False,\n               interactive: bool = False,\n               tty: bool = False,\n               name: str = None,\n               link: str = None,\n               volumes: List[str] = None,\n               envs: Dict[str, str] = None,\n               cmd_args: List[str] = None\n               ) -> None:\n    cmd = ['docker', 'run']\n    if rm:\n        cmd.append('--rm')\n    if detach:\n        cmd.append('--detach')\n    if interactive:\n        cmd.append('-i')\n    if tty:\n        cmd.append('-t')\n    if name:\n        cmd.append('--name')\n        cmd.append(name)\n    if link:\n        cmd.append('--link')\n        cmd.append(link)\n    if volumes:\n        for item in volumes:\n            cmd.append('--volume')\n            cmd.append(item)\n    if envs:\n        for var_name, var_value in envs.items():\n            cmd.append('--env')\n            cmd.append(f'{var_name}={var_value}')\n    cmd.append(image)\n    if cmd_args:\n        cmd.extend(cmd_args)\n\n    log.debug('Run: %r', cmd)\n    subprocess.check_call(cmd)\n\n\ndef docker_ps(all_: bool = False,\n              filter_: List[str] = None,\n              quiet: bool = False) -> str:\n    cmd = ['docker', 'ps']\n    if all_:\n        cmd.append('--all')\n    if filter_:\n        for item in filter_:\n            cmd.append('--filter')\n            cmd.append(item)\n    if quiet:\n        cmd.append('--quiet')\n\n    log.debug('Run: %r', cmd)\n    return subprocess.check_output(cmd, universal_newlines=True)\n\n\ndef docker_stop(name: str) -> None:\n    cmd = ['docker', 'stop', name]\n    log.debug('Run: %r', cmd)\n    subprocess.check_call(cmd)\n\n\ndef stop_container(name: str) -> None:\n    c_hash = docker_ps(all_=True, filter_=[f'name={name}'], quiet=True)\n    if c_hash:\n        docker_stop(name)\n\n\ndef main():\n    parser = argparse.ArgumentParser(\n        description='Run tests matrix inside containers. This is particularly '\n                    'useful for running tests in Travis-CI.'\n    )\n    parser.add_argument(\n        '--python-ver',\n        choices=VALID_PYTHON_VERSIONS,\n        default='3.7',\n        help='Specify Python version')\n    parser.add_argument(\n        '--django-ver',\n        type=validate_django_ver,\n        default='django<2.3,>=2.2',\n        help='Specify django version specifier')\n    parser.add_argument(\n        '--nitrate-db',\n        choices=VALID_NITRATE_DB_NAMES,\n        default='sqlite',\n        help='Database engine name')\n    parser.add_argument(\n        '--project-dir',\n        metavar='DIR',\n        type=validate_project_dir,\n        default=os.path.abspath(os.curdir),\n        help='Project root directory. Default to current working directory')\n    parser.add_argument(\n        'targets', nargs='+', help='Test targets')\n\n    args = parser.parse_args()\n\n    container_info = DB_CONTAINER_INFO[args.nitrate_db]\n    db_engine = container_info['db_engine']\n    db_image = container_info['db_image']\n\n    stop_container(DB_CONTAINER_NAME)\n\n    test_box_run_opts = None\n\n    if db_engine == 'mysql':\n        docker_run(\n            db_image,\n            rm=True,\n            name=DB_CONTAINER_NAME,\n            detach=True,\n            envs={\n               'MYSQL_ALLOW_EMPTY_PASSWORD': 'yes',\n               'MYSQL_DATABASE': 'nitrate'\n            },\n            cmd_args=[\n               '--character-set-server=utf8mb4',\n               '--collation-server=utf8mb4_unicode_ci'\n            ])\n        test_box_run_opts = {\n            'link': f'{DB_CONTAINER_NAME}:mysql',\n            'envs': {\n                'NITRATE_DB_ENGINE': db_engine,\n                'NITRATE_DB_NAME': TEST_DB_NAME,\n                'NITRATE_DB_HOST': DB_CONTAINER_NAME,\n            }\n        }\n    elif db_engine == 'pgsql':\n        docker_run(\n            db_image,\n            rm=True,\n            detach=True,\n            name=DB_CONTAINER_NAME,\n            envs={'POSTGRES_PASSWORD': 'admin'}\n        )\n        test_box_run_opts = {\n            'link': f'{DB_CONTAINER_NAME}:postgres',\n            'envs': {\n                'NITRATE_DB_ENGINE': db_engine,\n                'NITRATE_DB_HOST': DB_CONTAINER_NAME,\n                'NITRATE_DB_NAME': TEST_DB_NAME,\n                'NITRATE_DB_USER': 'postgres',\n                'NITRATE_DB_PASSWORD': 'admin',\n            }\n        }\n    elif db_engine == 'sqlite':\n        # No need to launch a SQLite docker image\n        test_box_run_opts = {\n            'envs': {\n                'NITRATE_DB_ENGINE': db_engine,\n                'NITRATE_DB_NAME': \"file::memory:\",\n            }\n        }\n\n    test_box_container_name = f'nitrate-testbox-py{args.python_ver.replace(\".\", \"\")}'\n    test_box_run_opts.update({\n        'rm': True,\n        'interactive': True,\n        'tty': True,\n        'name': test_box_container_name,\n        'volumes': [f'{args.project_dir}:/code:Z'],\n    })\n    test_box_run_opts['envs'].update({\n        'PYTHON_VER': f'py{args.python_ver.replace(\".\", \"\")}',\n        'DJANGO_VER': args.django_ver,\n        'TEST_TARGETS': '\"{}\"'.format(' '.join(args.targets)),\n    })\n\n    try:\n        log.debug('Start testbox to run tests')\n        docker_run(TEST_BOX_IMAGE, **test_box_run_opts)\n    finally:\n        log.debug('Stop container: %s', DB_CONTAINER_NAME)\n        stop_container(DB_CONTAINER_NAME)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "contrib/travis-ci/testrunner.py"}]}