Download tools/conversation_cache_http_smoke.py from WineryLabs/Winery-Strata: direct link, hf CLI and curl.
- Browser
- Download file 5.85 kB
-
https://huggingface.co/WineryLabs/Winery-Strata/resolve/main/tools/conversation_cache_http_smoke.py
- Command line
-
hf download hf://WineryLabs/Winery-Strata/tools/conversation_cache_http_smoke.py
-
curl -L -o conversation_cache_http_smoke.py https://huggingface.co/WineryLabs/Winery-Strata/resolve/main/tools/conversation_cache_http_smoke.py
5.85 kB
| """Destructive-to-cache HTTP smoke test for an EXCLUSIVE, idle Strata test server. | |
| Sends synthetic conversations, deliberately evicts cached conversations, and | |
| disconnects a streaming response. Never run while other clients are using it. | |
| Dry-run by default; --run explicitly enables network traffic. Does not restart | |
| or reconfigure the server. Use the private-engine parity gate for state hashes. | |
| """ | |
| import argparse | |
| import json | |
| from pathlib import Path | |
| import time | |
| import urllib.request | |
| import uuid | |
| def require(condition, message): | |
| if not condition: | |
| raise RuntimeError(message) | |
| class Client: | |
| def __init__(self, url): | |
| self.url = url.rstrip('/') | |
| def metrics(self): | |
| with urllib.request.urlopen(self.url + '/metrics', timeout=10) as response: | |
| return json.load(response) | |
| def request(self, model, content, stream=False, count=8): | |
| body = {'model': model, 'messages': [{'role': 'user', 'content': content}], | |
| 'max_tokens': count, 'temperature': 0, 'stream': stream, | |
| 'chat_template_kwargs': {'enable_thinking': False}} | |
| request = urllib.request.Request(self.url + '/v1/chat/completions', | |
| data=json.dumps(body).encode(), | |
| headers={'Content-Type': 'application/json'}) | |
| return urllib.request.urlopen(request, timeout=120) | |
| def run(client): | |
| initial = client.metrics() | |
| require(initial['live']['state'] == 'idle' and initial['live']['queued'] == 0, 'server is busy') | |
| info = initial['engine'] | |
| slots = info.get('conversation_cache_slots', 0) | |
| require(info.get('conversation_cache_mib', 0) > 0 and 1 <= slots <= 16, | |
| 'requires an enabled cache with 1–16 slots') | |
| require(not info.get('api_key'), 'use an unauthenticated private test endpoint') | |
| marker = 'cache-smoke-' + uuid.uuid4().hex | |
| records = [] | |
| def before(): | |
| metrics = client.metrics() | |
| require(metrics['live']['state'] == 'idle' and metrics['live']['queued'] == 0, | |
| 'concurrent client detected') | |
| return max((r['time'] for r in metrics['requests']), default=0) | |
| def after(stamp, label): | |
| for _ in range(50): | |
| metrics = client.metrics() | |
| if metrics['live']['state'] == 'idle': | |
| break | |
| time.sleep(.2) | |
| require(metrics['live']['state'] == 'idle', 'request did not drain') | |
| fresh = [r for r in metrics['requests'] if r['time'] > stamp] | |
| require(len(fresh) == 1 and metrics['live']['queued'] == 0, | |
| 'missing request evidence or concurrent traffic') | |
| record = {'name': label, **fresh[0]} | |
| records.append(record) | |
| return record | |
| def prompt(label): | |
| return marker + ' ' + label + '\n' + '\n'.join( | |
| f'Record {i}: blue square, green triangle, red circle.' for i in range(128) | |
| ) + '\nName one color. Answer with one word.' | |
| def ask(label, content): | |
| stamp = before() | |
| with client.request(info['model'], content) as response: | |
| result = json.load(response) | |
| require(bool(result.get('choices')), 'missing completion') | |
| record = after(stamp, label) | |
| require(record['finish'] in ('length', 'stop'), 'request did not finish normally') | |
| return result['choices'][0]['message'], record | |
| a, _ = ask('A', prompt('A')) | |
| ask('B', prompt('B')) | |
| restored, record = ask('A-restored', prompt('A')) | |
| require(record['reused'] > 0 and a == restored, 'A/B/A reuse or output mismatch') | |
| for i in range(slots + 1): | |
| ask(f'evict-{i}', prompt(f'evict-{i}')) | |
| _, record = ask('A-evicted', prompt('A')) | |
| require(record['reused'] == 0, 'old A survived slot eviction') | |
| text = marker + ' cancel: ' + 'blue green red. ' * 256 | |
| text += '\nCount from 1 to 1000, one number per line. Do not summarize.' | |
| stamp = before() | |
| with client.request(info['model'], text, stream=True, count=4096) as response: | |
| for line in response: | |
| if not line.startswith(b'data: ') or line.strip() == b'data: [DONE]': | |
| continue | |
| choices = json.loads(line[6:]).get('choices', []) | |
| if choices and choices[0].get('delta', {}).get('content'): | |
| break | |
| else: | |
| raise RuntimeError('no streamed content to cancel') | |
| record = after(stamp, 'cancelled') | |
| require(record['finish'] in ('disconnect', 'cancel') and 0 < record['output_tokens'] < 4096, | |
| 'stream cancellation not observed') | |
| ask('after-cancel-B', marker + ' Unrelated B: say hello.') | |
| _, record = ask('cancelled-A-restored', text) | |
| require(record['reused'] > 0, 'cancelled conversation was not restored') | |
| return {'engine_info': info, 'records': records} | |
| def main(): | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument('--url', default='http://127.0.0.1:11434') | |
| parser.add_argument('--output', type=Path, required=True, help='new results file; existing paths refused') | |
| parser.add_argument('--run', action='store_true') | |
| args = parser.parse_args() | |
| if not args.run: | |
| print('Dry run: HTTP A/B/A, slot eviction, cancellation and recovery. No network traffic.') | |
| return | |
| # Refuse accidental overwrites before generating traffic. | |
| with args.output.open('x', encoding='utf-8') as output: | |
| try: | |
| result = run(Client(args.url)) | |
| except Exception as error: | |
| json.dump({'passed': False, 'error': str(error)}, output, indent=2) | |
| output.write('\n') | |
| raise | |
| json.dump({'passed': True, **result}, output, indent=2) | |
| output.write('\n') | |
| print(f'PASS: HTTP reuse, slot eviction, cancellation/recovery. Results: {args.output}') | |
| if __name__ == '__main__': | |
| main() | |