Mercurial > libervia-backend
annotate tests/e2e/conftest.py @ 3913:944f51f9c2b4
core (xmpp): make `send` a blocking method, fix `sendMessageData` calls:
original `send` method is blocking, and it is used as such by Wokkel and thus can't be
changed to an async method easily. However, an Async method is necessary to have an async
trigger at the very end of the send workflow for end-to-end encryption. To workaround
that, `send` is an async method which call `a_send`, an async method which actually does
the sending. This way legacy method can still call `send` while `a_send` can be await
otherwise.
Fix calls to `sendMessageData`: the method now being an `async` one, `ensureDeferred` had
to be used in some calls.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 24 Sep 2022 16:31:39 +0200 |
parents | d78b5eae912a |
children | 4cd4922de876 |
rev | line source |
---|---|
3415 | 1 #!/usr/bin/env python3 |
2 | |
3480
7550ae9cfbac
Renamed the project from "Salut à Toi" to "Libervia":
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
3 # Libervia: an XMPP client |
3479 | 4 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) |
3415 | 5 |
6 # This program is free software: you can redistribute it and/or modify | |
7 # it under the terms of the GNU Affero General Public License as published by | |
8 # the Free Software Foundation, either version 3 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 Affero General Public License for more details. | |
15 | |
16 # You should have received a copy of the GNU Affero General Public License | |
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | |
19 import os | |
20 import tempfile | |
21 import string | |
22 import hashlib | |
23 import random | |
24 from pathlib import Path | |
3429
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
25 from aiosmtpd.controller import Controller |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
26 from aiosmtpd.handlers import Message |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
27 from email.message import EmailMessage |
3436
f9011d62a87a
tests (e2e/conftest): check new exit code for conflict to avoid crashing if test accounts already exist
Goffi <goffi@goffi.org>
parents:
3429
diff
changeset
|
28 import sh |
3498
d78b5eae912a
tests: update following names change
Goffi <goffi@goffi.org>
parents:
3480
diff
changeset
|
29 from sh import li |
3429
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
30 import pytest |
3415 | 31 |
32 | |
33 class FakeFile: | |
34 ALPHABET = f"{string.ascii_letters}{string.digits}_" | |
35 BUF_SIZE = 65535 | |
36 | |
37 def __init__(self): | |
3498
d78b5eae912a
tests: update following names change
Goffi <goffi@goffi.org>
parents:
3480
diff
changeset
|
38 self.tmp_dir_obj = tempfile.TemporaryDirectory(prefix="libervia_e2e_test_files_") |
3415 | 39 self.tmp_dir_path = Path(self.tmp_dir_obj.name) |
40 self.source_files = self.tmp_dir_path / "source" | |
41 self.source_files.mkdir() | |
42 self.dest_files = self.tmp_dir_path / "dest" | |
43 self.dest_files.mkdir() | |
44 self.hashes = {} | |
45 | |
46 @property | |
47 def dest_path(self): | |
48 """Path of a directory where files can be received | |
49 | |
50 The directory will be deleted at the end of session. | |
51 Files from other test can be present, be sure to create a unique subdirectory or | |
52 to use a unique destination file name | |
53 """ | |
54 return self.dest_files | |
55 | |
56 def new_dest_file(self) -> Path: | |
57 """Path to a randomly named destination file | |
58 | |
59 The file will be in self.dest_path. | |
60 The file should be deleted after use. If not, it will be deleted at the end of | |
61 session with the whole temporary test files directory. | |
62 """ | |
63 name = ''.join(random.choices(self.ALPHABET, k=8)) | |
64 return self.dest_files / name | |
65 | |
66 def size(self, size: int, use_cache: bool = True): | |
67 """Create a file of requested size, and returns its path | |
68 | |
69 @param use_cache: if True and a file of this size already exists, it is re-used | |
70 """ | |
71 dest_path = self.source_files / str(size) | |
72 if not use_cache or not dest_path.exists(): | |
73 hash_ = hashlib.sha256() | |
74 remaining = size | |
75 with dest_path.open('wb') as f: | |
76 while remaining: | |
77 if remaining > self.BUF_SIZE: | |
78 to_get = self.BUF_SIZE | |
79 else: | |
80 to_get = remaining | |
81 buf = os.urandom(to_get) | |
82 f.write(buf) | |
83 hash_.update(buf) | |
84 remaining -= to_get | |
85 self.hashes[dest_path] = hash_.hexdigest() | |
86 return dest_path | |
87 | |
88 def get_source_hash(self, source_file: Path) -> str: | |
89 """Retrieve hash calculated for a generated source file""" | |
90 return self.hashes[source_file] | |
91 | |
92 def get_dest_hash(self, dest_file: Path) -> str: | |
93 """Calculate hash of file at given path""" | |
94 hash_ = hashlib.sha256() | |
95 with dest_file.open('rb') as f: | |
96 while True: | |
97 buf = f.read(self.BUF_SIZE) | |
98 if not buf: | |
99 break | |
100 hash_.update(buf) | |
101 return hash_.hexdigest() | |
102 | |
103 | |
3429
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
104 class TestMessage(EmailMessage): |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
105 |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
106 @property |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
107 def subject(self): |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
108 return self['subject'] |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
109 |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
110 @property |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
111 def from_(self): |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
112 return self['from'] |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
113 |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
114 @property |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
115 def to(self): |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
116 return self['to'] |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
117 |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
118 @property |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
119 def body(self): |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
120 return self.get_payload(decode=True).decode() |
3415 | 121 |
122 | |
3429
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
123 class SMTPMessageHandler(Message): |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
124 messages = [] |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
125 |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
126 def __init__(self): |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
127 super().__init__(message_class=TestMessage) |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
128 |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
129 def handle_message(self, message): |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
130 self.messages.append(message) |
3415 | 131 |
132 | |
133 @pytest.fixture(scope="session") | |
134 def test_profiles(): | |
135 """Test accounts created using in-band registration | |
136 | |
137 They will be removed at the end of session. | |
138 The number of account per servers is set in the "accounts_by_servers" dict. | |
139 Jids are in the form "account[x]@server[y].test". | |
140 The profiles used are in the form "account[x]" for server1.test, and | |
141 "account[x]_s[y]" for other servers. | |
142 Password is "test" for all profiles and XMPP accounts. | |
143 "account1" is connected and set as default profile | |
144 Profiles created are returned as a tuple | |
145 """ | |
146 profiles = [] | |
147 nb_servers = 3 | |
148 accounts_by_servers = { | |
149 1: 1, | |
150 2: 1, | |
3437
42d6d00e4e8a
tests (e2e/conftest): create a test account on server3.test
Goffi <goffi@goffi.org>
parents:
3436
diff
changeset
|
151 3: 1, |
3415 | 152 } |
153 for server_idx in range(1, nb_servers+1): | |
154 account_stop = accounts_by_servers[server_idx] + 1 | |
155 for account_idx in range(1, account_stop): | |
156 profile_suff = f"_s{server_idx}" if server_idx>1 else "" | |
157 profile = f"account{account_idx}{profile_suff}" | |
158 profiles.append(profile) | |
3436
f9011d62a87a
tests (e2e/conftest): check new exit code for conflict to avoid crashing if test accounts already exist
Goffi <goffi@goffi.org>
parents:
3429
diff
changeset
|
159 try: |
3498
d78b5eae912a
tests: update following names change
Goffi <goffi@goffi.org>
parents:
3480
diff
changeset
|
160 li.account.create( |
3436
f9011d62a87a
tests (e2e/conftest): check new exit code for conflict to avoid crashing if test accounts already exist
Goffi <goffi@goffi.org>
parents:
3429
diff
changeset
|
161 f"account{account_idx}@server{server_idx}.test", |
f9011d62a87a
tests (e2e/conftest): check new exit code for conflict to avoid crashing if test accounts already exist
Goffi <goffi@goffi.org>
parents:
3429
diff
changeset
|
162 "test", |
f9011d62a87a
tests (e2e/conftest): check new exit code for conflict to avoid crashing if test accounts already exist
Goffi <goffi@goffi.org>
parents:
3429
diff
changeset
|
163 profile=profile, |
f9011d62a87a
tests (e2e/conftest): check new exit code for conflict to avoid crashing if test accounts already exist
Goffi <goffi@goffi.org>
parents:
3429
diff
changeset
|
164 host=f"server{server_idx}.test" |
f9011d62a87a
tests (e2e/conftest): check new exit code for conflict to avoid crashing if test accounts already exist
Goffi <goffi@goffi.org>
parents:
3429
diff
changeset
|
165 ) |
f9011d62a87a
tests (e2e/conftest): check new exit code for conflict to avoid crashing if test accounts already exist
Goffi <goffi@goffi.org>
parents:
3429
diff
changeset
|
166 except sh.ErrorReturnCode_19: |
f9011d62a87a
tests (e2e/conftest): check new exit code for conflict to avoid crashing if test accounts already exist
Goffi <goffi@goffi.org>
parents:
3429
diff
changeset
|
167 # this is the conlict exit code, this can happen when tests are run |
f9011d62a87a
tests (e2e/conftest): check new exit code for conflict to avoid crashing if test accounts already exist
Goffi <goffi@goffi.org>
parents:
3429
diff
changeset
|
168 # inside a container when --keep-profiles is used with run_e2e.py. |
f9011d62a87a
tests (e2e/conftest): check new exit code for conflict to avoid crashing if test accounts already exist
Goffi <goffi@goffi.org>
parents:
3429
diff
changeset
|
169 pass |
3498
d78b5eae912a
tests: update following names change
Goffi <goffi@goffi.org>
parents:
3480
diff
changeset
|
170 li.profile.modify(profile="account1", default=True, connect=True) |
d78b5eae912a
tests: update following names change
Goffi <goffi@goffi.org>
parents:
3480
diff
changeset
|
171 li.profile.connect(profile="account1_s2", connect=True) |
3415 | 172 yield tuple(profiles) |
3429
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
173 # This environment may be used during tests development |
3498
d78b5eae912a
tests: update following names change
Goffi <goffi@goffi.org>
parents:
3480
diff
changeset
|
174 if os.getenv("LIBERVIA_TEST_E2E_KEEP_PROFILES") == None: |
3429
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
175 for profile in profiles: |
3498
d78b5eae912a
tests: update following names change
Goffi <goffi@goffi.org>
parents:
3480
diff
changeset
|
176 li.account.delete(profile=profile, connect=True, force=True) |
d78b5eae912a
tests: update following names change
Goffi <goffi@goffi.org>
parents:
3480
diff
changeset
|
177 li.profile.delete(profile, force=True) |
3415 | 178 |
179 | |
180 @pytest.fixture(scope="class") | |
181 def pubsub_nodes(test_profiles): | |
182 """Create 2 testing nodes | |
183 | |
3429
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
184 Both nodes will be created with "account1" profile, named "test" and have an "open" |
3415 | 185 access model. |
3498
d78b5eae912a
tests: update following names change
Goffi <goffi@goffi.org>
parents:
3480
diff
changeset
|
186 One node will be on account1's PEP, the other one on pubsub.server1.test. |
3415 | 187 """ |
3498
d78b5eae912a
tests: update following names change
Goffi <goffi@goffi.org>
parents:
3480
diff
changeset
|
188 li.pubsub.node.create( |
3415 | 189 "-f", "access_model", "open", |
190 node="test", | |
191 profile="account1", connect=True | |
192 ) | |
3498
d78b5eae912a
tests: update following names change
Goffi <goffi@goffi.org>
parents:
3480
diff
changeset
|
193 li.pubsub.node.create( |
3415 | 194 "-f", "access_model", "open", |
195 service="pubsub.server1.test", node="test", | |
196 profile="account1" | |
197 ) | |
198 yield | |
3498
d78b5eae912a
tests: update following names change
Goffi <goffi@goffi.org>
parents:
3480
diff
changeset
|
199 li.pubsub.node.delete( |
3415 | 200 node="test", |
201 profile="account1", connect=True, | |
202 force=True | |
203 ) | |
3498
d78b5eae912a
tests: update following names change
Goffi <goffi@goffi.org>
parents:
3480
diff
changeset
|
204 li.pubsub.node.delete( |
3415 | 205 service="pubsub.server1.test", node="test", |
206 profile="account1", | |
207 force=True | |
208 ) | |
209 | |
210 | |
211 @pytest.fixture(scope="session") | |
212 def fake_file(): | |
213 """Manage dummy files creation and destination path""" | |
214 return FakeFile() | |
3429
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
215 |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
216 |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
217 @pytest.fixture(scope="session") |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
218 def test_files(): |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
219 """Return a Path to test files directory""" |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
220 return Path(__file__).parent.parent / "_files" |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
221 |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
222 |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
223 @pytest.fixture(scope="session") |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
224 def fake_smtp(): |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
225 """Create a fake STMP server to check sent emails""" |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
226 controller = Controller(SMTPMessageHandler()) |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
227 controller.hostname = "0.0.0.0" |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
228 controller.start() |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
229 yield |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
230 controller.stop() |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
231 |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
232 |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
233 @pytest.fixture |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
234 def sent_emails(fake_smtp): |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
235 """Catch email sent during the tests""" |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
236 SMTPMessageHandler.messages.clear() |
d4558f3cbf13
tests, docker(e2e): added e2e tests for Libervia:
Goffi <goffi@goffi.org>
parents:
3415
diff
changeset
|
237 return SMTPMessageHandler.messages |
3440
53da72a17139
tests (e2e): new fixture to share data between tests:
Goffi <goffi@goffi.org>
parents:
3437
diff
changeset
|
238 |
53da72a17139
tests (e2e): new fixture to share data between tests:
Goffi <goffi@goffi.org>
parents:
3437
diff
changeset
|
239 |
53da72a17139
tests (e2e): new fixture to share data between tests:
Goffi <goffi@goffi.org>
parents:
3437
diff
changeset
|
240 @pytest.fixture(scope="class") |
53da72a17139
tests (e2e): new fixture to share data between tests:
Goffi <goffi@goffi.org>
parents:
3437
diff
changeset
|
241 def shared_data(): |
53da72a17139
tests (e2e): new fixture to share data between tests:
Goffi <goffi@goffi.org>
parents:
3437
diff
changeset
|
242 """A dictionary used for share data between dependent tests""" |
53da72a17139
tests (e2e): new fixture to share data between tests:
Goffi <goffi@goffi.org>
parents:
3437
diff
changeset
|
243 return {} |