|
8 | 8 | import subprocess |
9 | 9 | import tempfile |
10 | 10 | import time |
| 11 | +import string |
11 | 12 | import urllib.parse |
12 | 13 |
|
13 | 14 | import requests |
14 | 15 | import requests_unixsocket |
15 | 16 |
|
16 | | -from config import POSTGREST_BIN, hpctixfile |
| 17 | +from config import POSTGREST_BIN, NGINX_BIN, hpctixfile |
17 | 18 |
|
18 | 19 |
|
19 | 20 | def sleep_until_postgrest_scache_reload(): |
@@ -170,6 +171,52 @@ def run( |
170 | 171 | process.wait() |
171 | 172 |
|
172 | 173 |
|
| 174 | +@contextlib.contextmanager |
| 175 | +def run_pgproxy(env=None, proxy_timeout="1s"): |
| 176 | + "Run nginx as a unix socket proxy for PostgreSQL and expose PGPROXYHOST." |
| 177 | + env = dict(os.environ if env is None else env) |
| 178 | + |
| 179 | + with tempfile.TemporaryDirectory() as tmpdir: |
| 180 | + # build a <tmpdir>/conf/ so `nginx -p` picks the config automatically |
| 181 | + tmpdir = pathlib.Path(tmpdir) |
| 182 | + conf_dir = tmpdir / "conf" |
| 183 | + conf_dir.mkdir(parents=True) |
| 184 | + |
| 185 | + nginx_env = dict(env) |
| 186 | + nginx_env["PGPROXYHOST"] = str(tmpdir) |
| 187 | + nginx_env["PGPROXY_TIMEOUT"] = proxy_timeout |
| 188 | + |
| 189 | + source_conf = pathlib.Path("test/io/nginx/nginx.conf") |
| 190 | + out_conf = conf_dir / "nginx.conf" |
| 191 | + out_conf.write_text( |
| 192 | + string.Template(source_conf.read_text()).substitute(nginx_env) |
| 193 | + ) |
| 194 | + |
| 195 | + process = subprocess.Popen( |
| 196 | + [NGINX_BIN, "-p", str(tmpdir), "-e", "stderr"], |
| 197 | + stdout=subprocess.PIPE, |
| 198 | + stderr=subprocess.PIPE, |
| 199 | + text=True, |
| 200 | + env=nginx_env, |
| 201 | + ) |
| 202 | + |
| 203 | + if process.poll() is not None: |
| 204 | + (_, stderr_output) = process.communicate(timeout=1) |
| 205 | + raise RuntimeError( |
| 206 | + f"{NGINX_BIN} exited with {process.returncode}: {stderr_output}" |
| 207 | + ) |
| 208 | + |
| 209 | + try: |
| 210 | + yield str(tmpdir) |
| 211 | + finally: |
| 212 | + process.terminate() |
| 213 | + try: |
| 214 | + process.wait(timeout=1) |
| 215 | + except subprocess.TimeoutExpired: |
| 216 | + process.kill() |
| 217 | + process.wait() |
| 218 | + |
| 219 | + |
173 | 220 | def freeport(used_ports=None): |
174 | 221 | "Find an unused free port on localhost." |
175 | 222 | while True: |
|
0 commit comments