Bundle mission speech with an admin mute option and fix live audio downloads
This commit is contained in:
@@ -87,6 +87,63 @@ class Session:
|
||||
|
||||
|
||||
class WelcomeTests(unittest.TestCase):
|
||||
def test_large_cached_audio_downloads_in_bounded_parts(self):
|
||||
# A 25-second Google-format clip exceeds Enfusion's single-response
|
||||
# ceiling. Existing disk caches must work without another synthesis.
|
||||
output = io.BytesIO()
|
||||
with wave.open(output, 'wb') as wav:
|
||||
wav.setnchannels(1)
|
||||
wav.setsampwidth(2)
|
||||
wav.setframerate(24000)
|
||||
wav.writeframes(random.Random(53).randbytes(25 * 24000 * 2))
|
||||
audio = output.getvalue()
|
||||
encoded = base64.b64encode(audio)
|
||||
self.assertGreater(len(encoded), 1024 * 1024)
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
def forbidden(text):
|
||||
self.fail('GET must never generate speech')
|
||||
cache = tool.BriefingCache(directory, 'x'*40, forbidden, 'transport-test')
|
||||
key = 'a'*64
|
||||
tool.save_clip(Path(directory)/(key + '.wav'), audio)
|
||||
server = tool.ThreadingHTTPServer(('127.0.0.1', 0), tool.handler_for(audio, cache))
|
||||
worker = threading.Thread(target=server.serve_forever, daemon=True)
|
||||
worker.start()
|
||||
connection = http.client.HTTPConnection(*server.server_address, timeout=3)
|
||||
try:
|
||||
for path in ('/welcome.b64', '/clips/' + key + '.b64'):
|
||||
chunks = []
|
||||
for part, offset in enumerate(range(0, len(encoded), tool.VOICE_CHUNK)):
|
||||
connection.request('GET', path + '?part=' + str(part))
|
||||
response = connection.getresponse()
|
||||
payload = response.read()
|
||||
self.assertEqual(response.status, 200)
|
||||
self.assertEqual(int(response.getheader('Content-Length')), len(payload))
|
||||
self.assertLessEqual(len(payload), 262272)
|
||||
data = json.loads(payload)
|
||||
self.assertEqual(data['offset'], offset)
|
||||
self.assertEqual(data['total'], len(encoded))
|
||||
chunks.append(data['data'].encode())
|
||||
self.assertEqual(base64.b64decode(b''.join(chunks)), audio)
|
||||
# Legacy clients still receive the original, unmodified clip.
|
||||
connection.request('GET', path)
|
||||
response = connection.getresponse()
|
||||
self.assertEqual(response.read(), encoded)
|
||||
for path, status in [('/welcome.b64?part=99', 416),
|
||||
('/welcome.b64?part=-1', 400),
|
||||
('/welcome.b64?part=0&part=1', 400),
|
||||
('/welcome.wav?part=0', 400),
|
||||
('/welcome.b64?part=10000000', 400)]:
|
||||
connection.request('GET', path)
|
||||
response = connection.getresponse()
|
||||
response.read()
|
||||
self.assertEqual(response.status, status)
|
||||
self.assertEqual(cache.read(key), audio)
|
||||
finally:
|
||||
connection.close()
|
||||
server.shutdown()
|
||||
server.server_close()
|
||||
worker.join(timeout=3)
|
||||
|
||||
def test_bounded_http_request_framing(self):
|
||||
read = tool.read_request_body
|
||||
self.assertEqual(read({'Content-Length': '2'}, io.BytesIO(b'{}')), b'{}')
|
||||
|
||||
Reference in New Issue
Block a user