comparison tests/e2e/run_e2e.py @ 3498:d78b5eae912a

tests: update following names change
author Goffi <goffi@goffi.org>
date Fri, 16 Apr 2021 18:32:34 +0200
parents 7550ae9cfbac
children 8ee0140cc8b6
comparison
equal deleted inserted replaced
3497:73e04040d577 3498:d78b5eae912a
23 import tempfile 23 import tempfile
24 from textwrap import dedent 24 from textwrap import dedent
25 from datetime import datetime 25 from datetime import datetime
26 import sh 26 import sh
27 import io 27 import io
28 import re
29 import sat_templates 28 import sat_templates
30 import libervia 29 import libervia
31 from sat.core import exceptions 30 from sat.core import exceptions
31 from sat.tools.common import regex
32 import yaml 32 import yaml
33 try: 33 try:
34 from yaml import CLoader as Loader, CDumper as Dumper 34 from yaml import CLoader as Loader, CDumper as Dumper
35 except ImportError: 35 except ImportError:
36 from yaml import Loader, Dumper 36 from yaml import Loader, Dumper
46 dev_mode_inst = dedent("""\ 46 dev_mode_inst = dedent("""\
47 Here is a short script to start working with a logged account: 47 Here is a short script to start working with a logged account:
48 48
49 from helium import * 49 from helium import *
50 start_firefox() 50 start_firefox()
51 go_to("https://libervia.test:8443/login") 51 go_to("https://libervia-web.test:8443/login")
52 write("account1", "login") 52 write("account1", "login")
53 write("test", "password") 53 write("test", "password")
54 click("log in") 54 click("log in")
55 """) 55 """)
56 report_buffer = io.StringIO() 56 report_buffer = io.StringIO()
57 live_out_buf = []
58 live_err_buf = []
57 59
58 60
59 def live_out(data): 61 def live_out(data):
60 sys.stdout.write(data) 62 if live_out_buf:
63 # we may get bytes when buffer is reached and we are in the middle of an unicode
64 # sequence. In this case we buffer it, and print it when it's complete
65 if isinstance(data, str):
66 data = b''.join(live_out_buf).decode() + data
67 live_out_buf.clear()
68 else:
69 live_out_buf.append(data)
70 return
71 try:
72 sys.stdout.write(data)
73 except TypeError:
74 live_out_buf.append(data)
75 return
61 sys.stdout.flush() 76 sys.stdout.flush()
62 report_buffer.write(data) 77 report_buffer.write(data)
63 78
64 79
65 def live_err(data): 80 def live_err(data):
66 sys.stderr.write(data) 81 if live_err_buf:
82 if isinstance(data, str):
83 data = b''.join(live_err_buf).decode() + data
84 live_err_buf.clear()
85 else:
86 live_err_buf.append(data)
87 return
88 try:
89 sys.stderr.write(data)
90 except TypeError:
91 live_err_buf.append(data)
92 return
67 sys.stderr.flush() 93 sys.stderr.flush()
68 report_buffer.write(data) 94 report_buffer.write(data)
69 95
70 96
71 def get_opt(opt_name): 97 def get_opt(opt_name):
80 return False 106 return False
81 107
82 108
83 def set_env(override, name, value="1"): 109 def set_env(override, name, value="1"):
84 """Set environement variable""" 110 """Set environement variable"""
85 environment = override["services"]["sat"].setdefault("environment", {}) 111 environment = override["services"]["backend"].setdefault("environment", {})
86 environment[name] = value 112 environment[name] = value
87 113
114 def write_report_log(path, log_raw, with_ansi=False):
115 log_raw = str(log_raw)
116 if with_ansi:
117 # we save 2 versions: one with ANSI escape codes
118 report_ansi = path.with_suffix(".ansi")
119 with report_ansi.open('w') as f:
120 f.write(log_raw)
121 # and one cleaner, without them
122 report_log = path.with_suffix(".log")
123 with report_log.open('w') as f:
124 f.write(regex.RE_ANSI_REMOVE.sub('', log_raw))
125 else:
126 report_log = path.with_suffix(".log")
127 with report_log.open('w') as f:
128 f.write(log_raw)
88 129
89 def use_e2e_env(): 130 def use_e2e_env():
90 visual = get_opt(OPT_VISUAL) 131 visual = get_opt(OPT_VISUAL)
91 keep_containers = get_opt(OPT_KEEP_CONTAINERS) 132 keep_containers = get_opt(OPT_KEEP_CONTAINERS)
92 keep_profiles = get_opt(OPT_KEEP_PROFILES) 133 keep_profiles = get_opt(OPT_KEEP_PROFILES)
103 144
104 for p in Path.cwd().parents: 145 for p in Path.cwd().parents:
105 package_path = p / "sat" 146 package_path = p / "sat"
106 docker_path = p / "docker" 147 docker_path = p / "docker"
107 if package_path.is_dir() and docker_path.is_dir(): 148 if package_path.is_dir() and docker_path.is_dir():
108 sat_root_path = p 149 backend_root_path = p
109 break 150 break
110 else: 151 else:
111 raise exceptions.NotFound( 152 raise exceptions.NotFound(
112 "Can't find root of SàT code, are you sure that you are running the test " 153 "Can't find root of SàT code, are you sure that you are running the test "
113 "from the backend repository?" 154 "from the backend repository?"
114 ) 155 )
115 156
116 libervia_path = Path(libervia.__file__).parent.resolve() 157 libervia_web_path = Path(libervia.__file__).parent.resolve()
117 libervia_root_path = libervia_path.parent 158 libervia_web_root_path = libervia_web_path.parent
118 if (libervia_root_path / ".hg").is_dir(): 159 if (libervia_web_root_path / ".hg").is_dir():
119 libervia_source = libervia_root_path 160 libervia_web_source = libervia_web_root_path
120 libervia_target = "/src/libervia" 161 libervia_web_target = "/src/libervia"
121 else: 162 else:
122 libervia_source = libervia_path 163 libervia_web_source = libervia_web_path
123 libervia_target = "/src/libervia/libervia" 164 libervia_web_target = "/src/libervia/libervia"
124 165
125 sat_templates_path = Path(sat_templates.__file__).parent.resolve() 166 sat_templates_path = Path(sat_templates.__file__).parent.resolve()
126 sat_templates_root_path = sat_templates_path.parent 167 sat_templates_root_path = sat_templates_path.parent
127 if (sat_templates_root_path / ".hg").is_dir(): 168 if (sat_templates_root_path / ".hg").is_dir():
128 sat_templates_source = sat_templates_root_path 169 sat_templates_source = sat_templates_root_path
129 sat_templates_target = "/src/sat_templates" 170 sat_templates_target = "/src/sat_templates"
130 else: 171 else:
131 sat_templates_source = sat_templates_path 172 sat_templates_source = sat_templates_path
132 sat_templates_target = "/src/sat_templates/sat_templates" 173 sat_templates_target = "/src/sat_templates/sat_templates"
133 174
134 compose_e2e_path = docker_path / "docker-compose_e2e.yml" 175 compose_e2e_path = docker_path / "docker-compose-e2e.yml"
135 if not compose_e2e_path.is_file(): 176 if not compose_e2e_path.is_file():
136 raise exceptions.NotFound('"docker-compose_e2e.yml" file can\'t be found') 177 raise exceptions.NotFound('"docker-compose-e2e.yml" file can\'t be found')
137 178
138 with tempfile.TemporaryDirectory(prefix="sat_test_e2e_") as temp_dir: 179 with tempfile.TemporaryDirectory(prefix="sat_test_e2e_") as temp_dir:
139 override_path = Path(temp_dir) / "test_override.yml" 180 override_path = Path(temp_dir) / "test_override.yml"
140 override = yaml.load( 181 override = yaml.load(
141 dedent(f"""\ 182 dedent(f"""\
142 version: "3.6" 183 version: "3.6"
143 services: 184 services:
144 sat: 185 backend:
145 volumes: 186 volumes:
146 - type: bind 187 - type: bind
147 source: {sat_root_path} 188 source: {backend_root_path}
148 target: /src/sat 189 target: /src/sat
149 read_only: true 190 read_only: true
150 libervia: 191 web:
151 volumes: 192 volumes:
152 - type: bind 193 - type: bind
153 source: {sat_root_path} 194 source: {backend_root_path}
154 target: /src/sat 195 target: /src/sat
155 read_only: true 196 read_only: true
156 - type: bind 197 - type: bind
157 source: {libervia_source} 198 source: {libervia_web_source}
158 target: {libervia_target} 199 target: {libervia_web_target}
159 read_only: true 200 read_only: true
160 - type: bind 201 - type: bind
161 source: {sat_templates_source} 202 source: {sat_templates_source}
162 target: {sat_templates_target} 203 target: {sat_templates_target}
163 read_only: true 204 read_only: true
165 ), 206 ),
166 Loader=Loader 207 Loader=Loader
167 ) 208 )
168 209
169 if keep_profiles: 210 if keep_profiles:
170 set_env(override, "SAT_TEST_E2E_KEEP_PROFILES") 211 set_env(override, "LIBERVIA_TEST_E2E_KEEP_PROFILES")
171 212
172 if visual: 213 if visual:
173 set_env(override, "SAT_TEST_E2E_LIBERVIA_NO_HEADLESS") 214 set_env(override, "LIBERVIA_TEST_E2E_WEB_NO_HEADLESS")
174 215
175 if keep_browser: 216 if keep_browser:
176 set_env(override, "SAT_TEST_E2E_LIBERVIA_KEEP_BROWSER") 217 set_env(override, "LIBERVIA_TEST_E2E_WEB_KEEP_BROWSER")
177 218
178 with override_path.open("w") as f: 219 with override_path.open("w") as f:
179 yaml.dump(override, f, Dumper=Dumper) 220 yaml.dump(override, f, Dumper=Dumper)
180 221
181 docker_compose = sh.docker_compose.bake( 222 docker_compose = sh.docker_compose.bake(
182 "-f", compose_e2e_path, "-f", override_path) 223 "-f", compose_e2e_path, "-f", override_path)
183 docker_compose.up("-d") 224 docker_compose.up("-d")
184 225
185 p = docker_compose.exec( 226 p = docker_compose.exec(
186 "-T", "--workdir", "/src/sat/tests", "sat", 227 "-T", "--workdir", "/src/sat/tests", "backend",
187 "pytest", "-o", "cache_dir=/tmp", *sys.argv[1:], color="yes", 228 "pytest", "-o", "cache_dir=/tmp", *sys.argv[1:], color="yes",
188 _in=sys.stdin, _out=live_out, _out_bufsize=0, _err=live_err, _err_bufsize=0, 229 _in=sys.stdin, _out=live_out, _out_bufsize=0, _err=live_err, _err_bufsize=0,
189 _bg=True 230 _bg=True
190 ) 231 )
191 if visual: 232 if visual:
192 vnc_port = docker_compose.port("sat", "5900").split(':', 1)[1].strip() 233 vnc_port = docker_compose.port("backend", "5900").split(':', 1)[1].strip()
193 p_vnc = sh.vncviewer( 234 p_vnc = sh.vncviewer(
194 f"localhost:{vnc_port}", 235 f"localhost:{vnc_port}",
195 _bg=True, 236 _bg=True,
196 # vncviewer exits with 1 when we send an SIGTERM to it, and it's printed 237 # vncviewer exits with 1 when we send an SIGTERM to it, and it's printed
197 # before we can catch it (it's happening in a thread). Thus we set exit 238 # before we can catch it (it's happening in a thread). Thus we set exit
202 p_vnc = None 243 p_vnc = None
203 244
204 try: 245 try:
205 p.wait() 246 p.wait()
206 except sh.ErrorReturnCode as e: 247 except sh.ErrorReturnCode as e:
207 sat_cont_id = docker_compose.ps("-q", "sat").strip() 248 libervia_cont_id = docker_compose.ps("-q", "backend").strip()
208 report_dest = Path(f"reports_{datetime.now().isoformat()}/") 249 report_dest = Path(f"report_{datetime.now().isoformat()}/")
209 # we need to make `report_dest` explicitely local with "./", otherwise 250 # we need to make `report_dest` explicitely local with "./", otherwise
210 # docker parse takes it as a container path due to the presence of ":" 251 # docker parse takes it as a container path due to the presence of ":"
211 # with `isoformat()`. 252 # with `isoformat()`.
212 sh.docker.cp(f"{sat_cont_id}:/reports", f"./{report_dest}") 253 sh.docker.cp(f"{libervia_cont_id}:/reports", f"./{report_dest}")
213 # we save 2 versions: one with ANSI escape codes 254 write_report_log(
214 report_ansi = report_dest / "report.ansi" 255 report_dest/"report",
215 with report_ansi.open('w') as f: 256 report_buffer.getvalue(),
216 f.write(report_buffer.getvalue()) 257 with_ansi=True
217 # and one without (cf. https://stackoverflow.com/a/14693789) 258 )
218 ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])') 259 write_report_log(
219 report_log = report_dest / "report.log" 260 report_dest/"backend",
220 with report_log.open('w') as f: 261 docker_compose.logs("--no-log-prefix", "backend")
221 f.write(ansi_escape.sub('', report_buffer.getvalue())) 262 )
222 263 write_report_log(
264 report_dest/"web",
265 docker_compose.logs("--no-log-prefix", "web")
266 )
223 print(f"report saved to {report_dest}") 267 print(f"report saved to {report_dest}")
224 sys.exit(e.exit_code) 268 sys.exit(e.exit_code)
225 finally: 269 finally:
226 if p_vnc is not None and p_vnc.is_alive() and not keep_vnc: 270 if p_vnc is not None and p_vnc.is_alive() and not keep_vnc:
227 p_vnc.terminate() 271 p_vnc.terminate()