72 lines
2.8 KiB
Python
72 lines
2.8 KiB
Python
"""Контракт файлового канала: владение, атомарный ответ и неизвестный итог."""
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import sys
|
|
import tempfile
|
|
import threading
|
|
import time
|
|
import unittest
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
sys.path.insert(0, str(ROOT / 'toolchain'))
|
|
from sdbg.build import write_json
|
|
from sdbg.transport import BridgeError, FileBridge
|
|
|
|
|
|
class TransportTests(unittest.TestCase):
|
|
def test_owner_lock(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
first = FileBridge(directory, 'one')
|
|
try:
|
|
with self.assertRaisesRegex(BridgeError, 'управляющая'):
|
|
FileBridge(directory, 'one')
|
|
finally:
|
|
first.close()
|
|
with self.assertRaisesRegex(BridgeError, 'закрыт'):
|
|
first.request('continue')
|
|
second = FileBridge(directory, 'one')
|
|
second.close()
|
|
|
|
def test_response_generation_and_session(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
bridge = FileBridge(directory, 'session', timeout=1)
|
|
def backend():
|
|
deadline = time.monotonic() + 1
|
|
while time.monotonic() < deadline:
|
|
requests = list(Path(directory).glob('req_*.json'))
|
|
if requests:
|
|
request = requests[0]
|
|
data = json.loads(request.read_text())
|
|
response = request.with_name(request.name.replace('req_', 'resp_'))
|
|
write_json(response, {'session': data['session'], 'generation': 7,
|
|
'ok': True, 'result': {'state': 'stopped'}})
|
|
request.unlink()
|
|
return
|
|
time.sleep(.001)
|
|
thread = threading.Thread(target=backend)
|
|
thread.start()
|
|
try:
|
|
self.assertEqual(bridge.request('snapshot')['state'], 'stopped')
|
|
self.assertEqual(bridge.generation, 7)
|
|
finally:
|
|
thread.join()
|
|
bridge.close()
|
|
|
|
def test_timeout_never_retries_mutation(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
bridge = FileBridge(directory, 'session', timeout=.025)
|
|
try:
|
|
with self.assertRaisesRegex(BridgeError, 'Timeout'):
|
|
bridge.request('continue')
|
|
self.assertTrue(bridge.invalid)
|
|
with self.assertRaisesRegex(BridgeError, 'инвалидирован'):
|
|
bridge.request('continue')
|
|
self.assertFalse(list(Path(directory).glob('req_*.json')))
|
|
finally:
|
|
bridge.close()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|