annotate tests/e2e/conftest.py @ 3415:814e118d9ef3

tests: end-2-end tests first draft: - e2e tests are launched inside the new docker e2e test environment - `run_e2e.py` launch the docker container, mount the current code base in it, launch the e2e tests and print report in real time - `conftest.py` are pytest fixtures managing many things such as account creation, fake files management, JSON or Domish.Element parsing, fake editor, etc. - `test_jp.py` are end-to-end test done with `jp`. `sh` library is used to make tests writting as user-friendly as possible. The `SAT_TEST_ENV_E2E` environment variable is checked, and tests will be skipped if it's not set.
author Goffi <goffi@goffi.org>
date Thu, 12 Nov 2020 14:53:16 +0100
parents
children d4558f3cbf13
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3415
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # SàT: an XMPP client
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # Copyright (C) 2009-2020 Jérôme Poisson (goffi@goffi.org)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
5
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
18
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
19 import sys
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
20 import os
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 import tempfile
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 import string
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 import hashlib
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 import random
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from pathlib import Path
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from textwrap import dedent
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 import json
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 import pytest
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 from sh import jp
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
30
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
31
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 class JpJson:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 """jp like commands parsing result as JSON"""
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
34
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 def __init__(self):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 self.subcommands = []
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
37
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
38 def __call__(self, *args, **kwargs):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 args = self.subcommands + list(args)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 self.subcommands.clear()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 kwargs['output'] = 'json_raw'
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 kwargs['_tty_out'] = False
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 cmd = jp(*args, **kwargs)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 return json.loads(cmd.stdout)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
45
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 def __getattr__(self, name):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 if name.startswith('_'):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 # no jp subcommand starts with a "_",
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 # and pytest uses some attributes with this name scheme
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 return super().__getattr__(name)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 self.subcommands.append(name)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 return self
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
53
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
54
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 class JpElt(JpJson):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 """jp like commands parsing result as domishElement"""
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
57
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 def __init__(self):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 super().__init__()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 from sat.tools.xml_tools import ElementParser
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
61 self.parser = ElementParser()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
62
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 def __call__(self, *args, **kwargs):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
64 args = self.subcommands + list(args)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
65 self.subcommands.clear()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 kwargs['output'] = 'xml_raw'
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
67 kwargs['_tty_out'] = False
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
68 cmd = jp(*args, **kwargs)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
69 return self.parser(cmd.stdout.decode().strip())
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
70
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
71
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
72 class Editor:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
73
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
74 def __init__(self):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
75 # temporary directory will be deleted Automatically when this object will be
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
76 # destroyed
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
77 self.tmp_dir_obj = tempfile.TemporaryDirectory(prefix="sat_e2e_test_editor_")
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 self.tmp_dir_path = Path(self.tmp_dir_obj.name)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
79 if not sys.executable:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
80 raise Exception("Can't find python executable")
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
81 self.editor_set = False
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
82 self.editor_path = self.tmp_dir_path / "editor.py"
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
83 self.ori_content_path = self.tmp_dir_path / "original_content"
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
84 self.new_content_path = self.tmp_dir_path / "new_content"
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
85 self.base_script = dedent(f"""\
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
86 #!{sys.executable}
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
87 import sys
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
88
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
89 def content_filter(content):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
90 return {{content_filter}}
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
91
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
92 with open(sys.argv[1], 'r+') as f:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
93 original_content = f.read()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
94 f.seek(0)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
95 new_content = content_filter(original_content)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
96 f.write(new_content)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
97 f.truncate()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
98
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
99 with open("{self.ori_content_path}", "w") as f:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
100 f.write(original_content)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
101
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
102 with open("{self.new_content_path}", "w") as f:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
103 f.write(new_content)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
104 """
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
105 )
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
106 self._env = os.environ.copy()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
107 self._env["EDITOR"] = str(self.editor_path)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
108
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
109 def set_filter(self, content_filter: str = "content"):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
110 """Python code to modify original content
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
111
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
112 The code will be applied to content received by editor.
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
113 The original content received by editor is in the "content" variable.
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
114 If filter_ is not specified, original content is written unmodified.
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
115 Code must be on a single line.
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
116 """
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
117 if '\n' in content_filter:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
118 raise ValueError("new lines can't be used in filter_")
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
119 with self.editor_path.open('w') as f:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
120 f.write(self.base_script.format(content_filter=content_filter))
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
121 self.editor_path.chmod(0o700)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
122 self.editor_set = True
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
123
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
124 @property
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
125 def env(self):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
126 """Get environment variable with the editor set"""
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
127 if not self.editor_set:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
128 self.set_filter()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
129 return self._env
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
130
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
131 @property
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
132 def original_content(self):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
133 """Last content received by editor, before any modification
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
134
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
135 returns None if editor has not yet been called
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
136 """
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
137 try:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
138 with self.ori_content_path.open() as f:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
139 return f.read()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
140 except FileNotFoundError:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
141 return None
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
142
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
143 @property
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
144 def new_content(self):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
145 """Last content writen by editor
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
146
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
147 This is the final content, after filter has been applied to original content
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
148 returns None if editor has not yet been called
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
149 """
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
150 try:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
151 with self.new_content_path.open() as f:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
152 return f.read()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
153 except FileNotFoundError:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
154 return None
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
155
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
156
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
157 class FakeFile:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
158 ALPHABET = f"{string.ascii_letters}{string.digits}_"
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
159 BUF_SIZE = 65535
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
160
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
161 def __init__(self):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
162 self.tmp_dir_obj = tempfile.TemporaryDirectory(prefix="sat_e2e_test_files_")
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
163 self.tmp_dir_path = Path(self.tmp_dir_obj.name)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
164 self.source_files = self.tmp_dir_path / "source"
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
165 self.source_files.mkdir()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
166 self.dest_files = self.tmp_dir_path / "dest"
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
167 self.dest_files.mkdir()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
168 self.hashes = {}
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
169
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
170 @property
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
171 def dest_path(self):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
172 """Path of a directory where files can be received
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
173
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
174 The directory will be deleted at the end of session.
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
175 Files from other test can be present, be sure to create a unique subdirectory or
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
176 to use a unique destination file name
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
177 """
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
178 return self.dest_files
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
179
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
180 def new_dest_file(self) -> Path:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
181 """Path to a randomly named destination file
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
182
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
183 The file will be in self.dest_path.
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
184 The file should be deleted after use. If not, it will be deleted at the end of
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
185 session with the whole temporary test files directory.
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
186 """
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
187 name = ''.join(random.choices(self.ALPHABET, k=8))
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
188 return self.dest_files / name
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
189
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
190 def size(self, size: int, use_cache: bool = True):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
191 """Create a file of requested size, and returns its path
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
192
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
193 @param use_cache: if True and a file of this size already exists, it is re-used
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
194 """
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
195 dest_path = self.source_files / str(size)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
196 if not use_cache or not dest_path.exists():
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
197 hash_ = hashlib.sha256()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
198 remaining = size
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
199 with dest_path.open('wb') as f:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
200 while remaining:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
201 if remaining > self.BUF_SIZE:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
202 to_get = self.BUF_SIZE
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
203 else:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
204 to_get = remaining
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
205 buf = os.urandom(to_get)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
206 f.write(buf)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
207 hash_.update(buf)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
208 remaining -= to_get
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
209 self.hashes[dest_path] = hash_.hexdigest()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
210 return dest_path
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
211
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
212 def get_source_hash(self, source_file: Path) -> str:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
213 """Retrieve hash calculated for a generated source file"""
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
214 return self.hashes[source_file]
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
215
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
216 def get_dest_hash(self, dest_file: Path) -> str:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
217 """Calculate hash of file at given path"""
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
218 hash_ = hashlib.sha256()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
219 with dest_file.open('rb') as f:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
220 while True:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
221 buf = f.read(self.BUF_SIZE)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
222 if not buf:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
223 break
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
224 hash_.update(buf)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
225 return hash_.hexdigest()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
226
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
227
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
228 @pytest.fixture(scope="session")
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
229 def jp_json():
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
230 """Run jp with "json_raw" output, and returns the parsed value"""
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
231 return JpJson()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
232
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
233
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
234 @pytest.fixture(scope="session")
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
235 def jp_elt():
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
236 """Run jp with "xml_raw" output, and returns the parsed value"""
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
237 return JpElt()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
238
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
239
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
240 @pytest.fixture(scope="session")
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
241 def test_profiles():
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
242 """Test accounts created using in-band registration
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
243
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
244 They will be removed at the end of session.
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
245 The number of account per servers is set in the "accounts_by_servers" dict.
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
246 Jids are in the form "account[x]@server[y].test".
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
247 The profiles used are in the form "account[x]" for server1.test, and
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
248 "account[x]_s[y]" for other servers.
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
249 Password is "test" for all profiles and XMPP accounts.
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
250 "account1" is connected and set as default profile
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
251 Profiles created are returned as a tuple
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
252 """
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
253 profiles = []
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
254 nb_servers = 3
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
255 accounts_by_servers = {
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
256 1: 1,
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
257 2: 1,
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
258 3: 0,
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
259 }
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
260 for server_idx in range(1, nb_servers+1):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
261 account_stop = accounts_by_servers[server_idx] + 1
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
262 for account_idx in range(1, account_stop):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
263 profile_suff = f"_s{server_idx}" if server_idx>1 else ""
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
264 profile = f"account{account_idx}{profile_suff}"
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
265 profiles.append(profile)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
266 jp.account.create(
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
267 f"account{account_idx}@server{server_idx}.test",
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
268 "test",
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
269 profile=profile,
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
270 host=f"server{server_idx}.test"
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
271 )
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
272 jp.profile.modify(profile="account1", default=True, connect=True)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
273 jp.profile.connect(profile="account1_s2", connect=True)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
274 yield tuple(profiles)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
275 for profile in profiles:
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
276 jp.account.delete(profile=profile, connect=True, force=True)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
277 jp.profile.delete(profile, force=True)
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
278
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
279
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
280 @pytest.fixture(scope="class")
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
281 def pubsub_nodes(test_profiles):
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
282 """Create 2 testing nodes
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
283
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
284 Both nodes will be created with "account1" profile, named "test" and have and "open"
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
285 access model.
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
286 One node will account1's PEP, the other one on pubsub.server1.test.
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
287 """
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
288 jp.pubsub.node.create(
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
289 "-f", "access_model", "open",
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
290 node="test",
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
291 profile="account1", connect=True
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
292 )
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
293 jp.pubsub.node.create(
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
294 "-f", "access_model", "open",
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
295 service="pubsub.server1.test", node="test",
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
296 profile="account1"
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
297 )
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
298 yield
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
299 jp.pubsub.node.delete(
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
300 node="test",
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
301 profile="account1", connect=True,
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
302 force=True
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
303 )
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
304 jp.pubsub.node.delete(
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
305 service="pubsub.server1.test", node="test",
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
306 profile="account1",
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
307 force=True
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
308 )
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
309
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
310
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
311 @pytest.fixture()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
312 def editor():
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
313 """Create a fake editor to automatise edition from CLI"""
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
314 return Editor()
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
315
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
316
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
317 @pytest.fixture(scope="session")
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
318 def fake_file():
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
319 """Manage dummy files creation and destination path"""
814e118d9ef3 tests: end-2-end tests first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
320 return FakeFile()