|
1 | 1 | """ |
2 | | -Tests using a MySQL-based record store. |
| 2 | +Tests using a MariaDB/MySQL-based record store. |
3 | 3 |
|
4 | | -
|
5 | | -Usage: |
6 | | - nosetests -v test_mysql.py |
7 | | -or: |
8 | | - python test_mysql.py |
9 | 4 | """ |
10 | | -from __future__ import print_function |
11 | | -from __future__ import unicode_literals |
12 | | -from future import standard_library |
13 | | -standard_library.install_aliases() |
14 | | -from builtins import input |
15 | 5 |
|
16 | 6 | import os |
17 | | -from urllib.parse import urlparse |
| 7 | +import shutil |
| 8 | +import tempfile |
18 | 9 | try: |
19 | 10 | import docker |
20 | | - if "DOCKER_HOST" in os.environ: |
21 | | - have_docker = True |
22 | | - else: |
23 | | - have_docker = False |
| 11 | + have_docker = True |
24 | 12 | except ImportError: |
25 | 13 | have_docker = False |
26 | | -from unittest import SkipTest |
27 | | -import utils |
28 | | -from utils import setup, teardown as default_teardown, run_test, build_command |
| 14 | +try: |
| 15 | + import mysqlclient |
| 16 | + have_mysql = True |
| 17 | +except ImportError: |
| 18 | + have_mysql = False |
29 | 19 |
|
30 | | -ctr = None |
31 | | -dkr = None |
32 | | -image = "mysql_test" |
33 | 20 |
|
| 21 | +from utils import run_test, build_command |
34 | 22 |
|
35 | | -def create_script(): |
36 | | - with open(os.path.join(utils.working_dir, "main.py"), "w") as fp: |
37 | | - fp.write("print('Hello world!')\n") |
| 23 | +import pytest |
38 | 24 |
|
| 25 | +DOCKER_IMAGE = "mariadb:latest" |
39 | 26 |
|
40 | | -def get_url(): |
41 | | - info = dkr.containers()[0] |
42 | | - assert info["Image"] == image |
43 | | - host = urlparse(dkr.base_url).hostname |
44 | | - return "{0}:{1}".format(host, info["Ports"][0]["PublicPort"]) |
45 | 27 |
|
| 28 | +def get_url(ctr): |
| 29 | + ctr.reload() # required to get auto-assigned ports |
| 30 | + info = ctr.ports["3306/tcp"][0] |
| 31 | + return f"{info['HostIp']}:{info['HostPort']}" |
46 | 32 |
|
47 | | -def start_pg_container(): |
48 | | - """ |
49 | | - Launch a Docker container running MySQL, return the URL. |
50 | 33 |
|
51 | | - Requires the "mysql_test" image. If this does not yet exist, run |
| 34 | +@pytest.fixture(scope="module") |
| 35 | +def mysql_container(): |
| 36 | + """ |
| 37 | + Launch a Docker container running MariaDB, return the URL. |
52 | 38 |
|
53 | | - docker build -t mysql_test - < fixtures/Dockerfile.mysql |
54 | 39 | """ |
55 | | - global ctr, dkr |
56 | | - env = docker.utils.kwargs_from_env(assert_hostname=False) |
57 | | - dkr = docker.Client(timeout=60, **env) |
58 | | - |
59 | | - host_config = dkr.create_host_config(publish_all_ports=True) |
60 | | - # docker run -rm -P -name ms_test mysql_test |
61 | | - ctr = dkr.create_container(image, command=None, hostname=None, user=None, |
62 | | - detach=False, stdin_open=False, tty=False, |
63 | | - ports=None, environment=None, dns=None, |
64 | | - volumes=None, volumes_from=None, |
65 | | - network_disabled=False, name=None, |
66 | | - entrypoint=None, cpu_shares=None, |
67 | | - working_dir=None, host_config=host_config) |
68 | | - dkr.start(ctr) |
69 | | - utils.env["url"] = get_url() |
70 | | - |
71 | | - |
72 | | -def teardown(): |
73 | | - global ctr, dkr |
74 | | - default_teardown() |
75 | | - if dkr is not None: |
76 | | - dkr.stop(ctr) |
77 | | - |
78 | | - |
79 | | -test_steps = [ |
80 | | - create_script, |
81 | | - ("Create repository", "git init"), |
82 | | - ("Add main file", "git add main.py"), |
83 | | - ("Commit main file", "git commit -m 'initial'"), |
84 | | - start_pg_container, |
85 | | - ("Set up a Sumatra project", |
86 | | - build_command("smt init --store=mysql://docker:docker@{}/sumatra_test -m main.py -e python MyProject", "url")), |
87 | | - ("Show project configuration", "smt info"), # TODO: add assert |
88 | | - ("Run a computation", "smt run") |
89 | | -] |
90 | | - |
91 | | - |
92 | | -# TODO: add test skips where docker not found |
93 | | - |
94 | | - |
95 | | -def test_all(): |
96 | | - """Test generator for Nose.""" |
97 | | - if not have_docker: |
98 | | - raise SkipTest("Tests require docker") |
| 40 | + dkr = docker.from_env() |
| 41 | + |
| 42 | + ctr = dkr.containers.run( |
| 43 | + DOCKER_IMAGE, detach=True, publish_all_ports=True, |
| 44 | + environment={ |
| 45 | + "MARIADB_ROOT_PASSWORD": "the_root_password", |
| 46 | + "MARIADB_DATABASE": "sumatra_test", |
| 47 | + "MARIADB_USER": "docker", |
| 48 | + "MARIADB_PASSWORD": "docker" |
| 49 | + } |
| 50 | + ) |
| 51 | + container_url = get_url(ctr) |
| 52 | + yield container_url |
| 53 | + ctr.stop() |
| 54 | + |
| 55 | + |
| 56 | +@pytest.mark.skipif(not have_docker, reason="Tests require docker Python package") |
| 57 | +@pytest.mark.skipif(not have_mysql, reason="Tests require mysqlclient") |
| 58 | +def test_all(mysql_container): |
| 59 | + """Run a series of Sumatra commands""" |
| 60 | + temporary_dir = os.path.realpath(tempfile.mkdtemp()) |
| 61 | + working_dir = os.path.join(temporary_dir, "sumatra_exercise") |
| 62 | + os.mkdir(working_dir) |
| 63 | + env = { |
| 64 | + "labels": [], |
| 65 | + "working_dir": working_dir, |
| 66 | + "url": mysql_container |
| 67 | + } |
| 68 | + |
| 69 | + def create_script(): |
| 70 | + with open(os.path.join(working_dir, "main.py"), "w") as fp: |
| 71 | + fp.write("print('Hello world!')\n") |
| 72 | + |
| 73 | + test_steps = [ |
| 74 | + create_script, |
| 75 | + ("Create repository", "git init"), |
| 76 | + ("Add main file", "git add main.py"), |
| 77 | + ("Commit main file", "git commit -m 'initial'"), |
| 78 | + ("Set up a Sumatra project", |
| 79 | + build_command("smt init --store=mysql://docker:docker@{}/sumatra_test -m main.py -e python MyProject", "url")), |
| 80 | + #"smt init -m main.py -e python MyProject"), |
| 81 | + ("Show project configuration", "smt info"), # TODO: add assert |
| 82 | + ("Run a computation", "smt run") |
| 83 | + ] |
99 | 84 | for step in test_steps: |
100 | 85 | if callable(step): |
101 | 86 | step() |
102 | 87 | else: |
103 | | - run_test.description = step[0] |
104 | | - yield tuple([run_test] + list(step[1:])) |
| 88 | + run_test(*step[1:], env=env) |
105 | 89 |
|
106 | | - |
107 | | -if __name__ == '__main__': |
108 | | - # Run the tests without using Nose. |
109 | | - setup() |
110 | | - for step in test_steps: |
111 | | - if callable(step): |
112 | | - step() |
113 | | - else: |
114 | | - print(step[0]) # description |
115 | | - run_test(*step[1:]) |
116 | | - response = input("Do you want to delete the temporary directory (default: yes)? ") |
117 | | - if response not in ["n", "N", "no", "No"]: |
118 | | - teardown() |
119 | | - else: |
120 | | - print("Temporary directory %s not removed" % utils.temporary_dir) |
| 90 | + shutil.rmtree(temporary_dir) |
0 commit comments