[IMP] alter ngrok startup to allow concurrent runs

Running multiple ngrok concurrently is only allowed from pro and up
(OOTB and without shenanigans) is only allowed from Pro and up. However
multiple tunnels through a single ngrok is allowed

-> when tunneling through ngrok, start the process without any tunnel,
use the API to create then remove the local tunnel, and shut down ngrok
IIF there's no tunnel left.

There's plenty of race conditions but given how slow tests are when they
involve github that's probably not an issue.
This commit is contained in:
Xavier Morel 2019-08-23 16:16:30 +02:00 committed by xmo-odoo
parent 28bcc6b5d7
commit 1981bd68e6

View File

@ -4,9 +4,14 @@ import re
import subprocess
import time
import psutil
import pytest
import requests
NGROK_CLI = [
'ngrok', 'start', '--none', '--region', 'eu',
]
def pytest_addoption(parser):
parser.addoption(
'--tunnel', action="store", type="choice", choices=['ngrok', 'localtunnel'], default='ngrok',
@ -79,8 +84,27 @@ def tunnel(pytestconfig, port):
tunnel = pytestconfig.getoption('--tunnel')
if tunnel == 'ngrok':
p = subprocess.Popen(['ngrok', 'http', '--region', 'eu', str(port)], stdout=subprocess.DEVNULL)
addr = 'localhost:%d' % port
# if ngrok is not running, start it
try:
# FIXME: use config file so we can set web_addr to something else
# than localhost:4040 (otherwise we can't disambiguate
# between the ngrok we started and an ngrok started by
# some other user)
requests.get('http://localhost:4040/api')
except requests.exceptions.ConnectionError:
subprocess.Popen(NGROK_CLI, stdout=subprocess.DEVNULL)
time.sleep(1)
requests.post('http://localhost:4040/api/tunnels', json={
'name': str(port),
'proto': 'http',
'bind_tls': True,
'addr': addr,
'inspect': False,
})
time.sleep(5)
try:
r = requests.get('http://localhost:4040/api/tunnels')
r.raise_for_status()
@ -88,10 +112,22 @@ def tunnel(pytestconfig, port):
t['public_url']
for t in r.json()['tunnels']
if t['proto'] == 'https'
if t['config']['addr'].endswith(addr)
)
finally:
p.terminate()
p.wait(30)
requests.delete('http://localhost:4040/api/tunnels/%s' % port)
time.sleep(5) # apparently tearing down the tunnel can take some time
r = requests.get('http://localhost:4040/api/tunnels')
if r.ok and r.json()['tunnels']:
return
# ngrok is broken or all tunnels have been shut down -> try to
# find and kill it (but only if it looks a lot like we started it)
for p in psutil.process_iter():
if p.name() == 'ngrok' and p.cmdline() == NGROK_CLI:
p.terminate()
break
elif tunnel == 'localtunnel':
p = subprocess.Popen(['lt', '-p', str(port)], stdout=subprocess.PIPE)
try: