#!/usr/bin/env python3 """Run one document app through parser-free HTTP, source HTTP, and native CLI.""" import argparse import hashlib import http.client import json from pathlib import Path import select import socket import struct import subprocess import tempfile import time HERE = Path(__file__).resolve().parent PEAK_RSS_LIMIT_KIB = 4096 class Host: def __init__(self, binary, store, fixed, budget=None, timeout_ms=10000): args = [str(binary), '--store', str(store), '--port', '0', '--send-buffer', '4096', '--timeout-ms', str(timeout_ms)] if budget is not None: args += ['--budget', str(budget)] if not fixed: args += ['--program', str(HERE / 'examples/editor.pure')] self.process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) ready, _, _ = select.select([self.process.stdout], [], [], 10) if not ready: self.process.kill() raise AssertionError('HTTP host did not become ready') line = self.process.stdout.readline() if not line: raise AssertionError(self.process.communicate(timeout=5)) self.port = json.loads(line)['port'] def close(self): self.process.terminate() _, error = self.process.communicate(timeout=10) assert self.process.returncode == 0, error[-1000:] stats = json.loads(error) assert stats['active'] == stats['retained_payload_bytes'] == 0 return stats def request(host, method, key, body=b'', expected=None): headers = {'Content-Length': str(len(body))} if expected is not None: headers['If-None-Match' if expected == 0 else 'If-Match'] = ( '*' if expected == 0 else f'"{expected}"') connection = http.client.HTTPConnection('127.0.0.1', host.port, timeout=15) try: connection.request(method, f'/objects/{key}', body, headers) response = connection.getresponse() return response.status, response.getheader('ETag'), response.read() finally: connection.close() def splice(offset, remove, insert): return struct.pack('