rtpbench 0.4.0__tar.gz → 0.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. {rtpbench-0.4.0 → rtpbench-0.4.1}/PKG-INFO +1 -1
  2. {rtpbench-0.4.0 → rtpbench-0.4.1}/pyproject.toml +1 -1
  3. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/bench.py +4 -3
  4. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/cases.py +2 -0
  5. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/realtime.py +19 -2
  6. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/aivc/compose.yaml +3 -3
  7. {rtpbench-0.4.0 → rtpbench-0.4.1}/tests/test_images.py +7 -0
  8. {rtpbench-0.4.0 → rtpbench-0.4.1}/tests/test_realtime.py +16 -0
  9. {rtpbench-0.4.0 → rtpbench-0.4.1}/.dockerignore +0 -0
  10. {rtpbench-0.4.0 → rtpbench-0.4.1}/.gitignore +0 -0
  11. {rtpbench-0.4.0 → rtpbench-0.4.1}/Dockerfile +0 -0
  12. {rtpbench-0.4.0 → rtpbench-0.4.1}/LICENSE +0 -0
  13. {rtpbench-0.4.0 → rtpbench-0.4.1}/README.md +0 -0
  14. {rtpbench-0.4.0 → rtpbench-0.4.1}/carrier/compose.yaml +0 -0
  15. {rtpbench-0.4.0 → rtpbench-0.4.1}/carrier/opensips.cfg +0 -0
  16. {rtpbench-0.4.0 → rtpbench-0.4.1}/carrier/tls.cfg +0 -0
  17. {rtpbench-0.4.0 → rtpbench-0.4.1}/carrier/tls.yaml +0 -0
  18. {rtpbench-0.4.0 → rtpbench-0.4.1}/compose.yaml +0 -0
  19. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/README.md +0 -0
  20. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/cough-c1-0.wav +0 -0
  21. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/cough-c1-1.wav +0 -0
  22. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/cough-c2-0.wav +0 -0
  23. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/cough-c2-1.wav +0 -0
  24. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/cough-man-0.wav +0 -0
  25. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/cough-man-1.wav +0 -0
  26. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/cough-short-0.wav +0 -0
  27. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/cough-short-1.wav +0 -0
  28. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/cough-woman_three_times-0.wav +0 -0
  29. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/human-en-dr-0.wav +0 -0
  30. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/human-en-dr-1.wav +0 -0
  31. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/human-en-sc-0.wav +0 -0
  32. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/human-en-sc-1.wav +0 -0
  33. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/human-en-sc-2.wav +0 -0
  34. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/human-es-f012-0.wav +0 -0
  35. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/human-es-f012-1.wav +0 -0
  36. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/human-es-f012-2.wav +0 -0
  37. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/human-es-f016-0.wav +0 -0
  38. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/human-es-f016-1.wav +0 -0
  39. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/human-es-f016-2.wav +0 -0
  40. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/interrupt-00.wav +0 -0
  41. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/interrupt-01.wav +0 -0
  42. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/interrupt-02.wav +0 -0
  43. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/interrupt-03.wav +0 -0
  44. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/prompt-00.wav +0 -0
  45. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/prompt-01.wav +0 -0
  46. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/prompt-02.wav +0 -0
  47. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/prompt-03.wav +0 -0
  48. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/prompt-04.wav +0 -0
  49. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/prompt-05.wav +0 -0
  50. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/prompt-06.wav +0 -0
  51. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/prompt-07.wav +0 -0
  52. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/prompt-08.wav +0 -0
  53. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/prompt-09.wav +0 -0
  54. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/prompt.wav +0 -0
  55. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/transfer.wav +0 -0
  56. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/turn-00.wav +0 -0
  57. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/turn-01.wav +0 -0
  58. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/turn-02.wav +0 -0
  59. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/turn-03.wav +0 -0
  60. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/turn-04.wav +0 -0
  61. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/turn-05.wav +0 -0
  62. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/turn-06.wav +0 -0
  63. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/turn-07.wav +0 -0
  64. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/turn-08.wav +0 -0
  65. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/turn-09.wav +0 -0
  66. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/turn-10.wav +0 -0
  67. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/lines/en/turn-11.wav +0 -0
  68. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-ald-bc.wav +0 -0
  69. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-ald-long.wav +0 -0
  70. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-ald-s03.wav +0 -0
  71. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-ald-s07.wav +0 -0
  72. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-ald-s11.wav +0 -0
  73. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-cori-bc.wav +0 -0
  74. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-cori-long.wav +0 -0
  75. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-cori-s01.wav +0 -0
  76. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-cori-s05.wav +0 -0
  77. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-cori-s09.wav +0 -0
  78. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-davefx-bc.wav +0 -0
  79. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-davefx-long.wav +0 -0
  80. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-davefx-s00.wav +0 -0
  81. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-davefx-s04.wav +0 -0
  82. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-davefx-s08.wav +0 -0
  83. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-libritts0-bc.wav +0 -0
  84. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-libritts0-long.wav +0 -0
  85. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-libritts0-s02.wav +0 -0
  86. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-libritts0-s06.wav +0 -0
  87. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-libritts0-s10.wav +0 -0
  88. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-libritts3-bc.wav +0 -0
  89. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-libritts3-long.wav +0 -0
  90. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-libritts3-s03.wav +0 -0
  91. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-libritts3-s07.wav +0 -0
  92. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-libritts3-s11.wav +0 -0
  93. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-ljspeech-bc.wav +0 -0
  94. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-ljspeech-long.wav +0 -0
  95. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-ljspeech-s00.wav +0 -0
  96. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-ljspeech-s04.wav +0 -0
  97. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-ljspeech-s08.wav +0 -0
  98. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-sharvardf-bc.wav +0 -0
  99. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-sharvardf-long.wav +0 -0
  100. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-sharvardf-s02.wav +0 -0
  101. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-sharvardf-s06.wav +0 -0
  102. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-sharvardf-s10.wav +0 -0
  103. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-sharvardm-bc.wav +0 -0
  104. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-sharvardm-long.wav +0 -0
  105. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-sharvardm-s01.wav +0 -0
  106. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-sharvardm-s05.wav +0 -0
  107. {rtpbench-0.4.0 → rtpbench-0.4.1}/corpus/tts-sharvardm-s09.wav +0 -0
  108. {rtpbench-0.4.0 → rtpbench-0.4.1}/mock/compose.yaml +0 -0
  109. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/__init__.py +0 -0
  110. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/__main__.py +0 -0
  111. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/agent.py +0 -0
  112. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/analyze.py +0 -0
  113. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/bargein.py +0 -0
  114. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/caller.py +0 -0
  115. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/capture.py +0 -0
  116. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/check.py +0 -0
  117. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/cli.py +0 -0
  118. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/clock.py +0 -0
  119. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/detect.py +0 -0
  120. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/g711.py +0 -0
  121. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/pcap.py +0 -0
  122. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/progress.py +0 -0
  123. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/report.py +0 -0
  124. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/rtp.py +0 -0
  125. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/sip.py +0 -0
  126. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/speech.py +0 -0
  127. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/speechcal.py +0 -0
  128. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/srtp.py +0 -0
  129. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/tls.py +0 -0
  130. {rtpbench-0.4.0 → rtpbench-0.4.1}/src/rtpbench/voice.py +0 -0
  131. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/aivc/aivc.ini +0 -0
  132. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/aivc/constraints.txt +0 -0
  133. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/aivc/opensips.cfg +0 -0
  134. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/aivc/source.yaml +0 -0
  135. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/ava/ai-agent.yaml +0 -0
  136. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/ava/ari.conf +0 -0
  137. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/ava/compose.yaml +0 -0
  138. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/ava/constraints.txt +0 -0
  139. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/ava/extensions.conf +0 -0
  140. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/ava/http.conf +0 -0
  141. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/ava/pjsip.conf +0 -0
  142. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/ava/source.yaml +0 -0
  143. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/ava/websocket_client.conf +0 -0
  144. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/livekit/agent.py +0 -0
  145. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/livekit/compose.yaml +0 -0
  146. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/livekit/constraints.txt +0 -0
  147. {rtpbench-0.4.0 → rtpbench-0.4.1}/targets/livekit/source.yaml +0 -0
  148. {rtpbench-0.4.0 → rtpbench-0.4.1}/tests/test_bargein.py +0 -0
  149. {rtpbench-0.4.0 → rtpbench-0.4.1}/tests/test_cases.py +0 -0
  150. {rtpbench-0.4.0 → rtpbench-0.4.1}/tests/test_check.py +0 -0
  151. {rtpbench-0.4.0 → rtpbench-0.4.1}/tests/test_cli.py +0 -0
  152. {rtpbench-0.4.0 → rtpbench-0.4.1}/tests/test_clock.py +0 -0
  153. {rtpbench-0.4.0 → rtpbench-0.4.1}/tests/test_progress.py +0 -0
  154. {rtpbench-0.4.0 → rtpbench-0.4.1}/tests/test_report.py +0 -0
  155. {rtpbench-0.4.0 → rtpbench-0.4.1}/tests/test_speech.py +0 -0
  156. {rtpbench-0.4.0 → rtpbench-0.4.1}/tests/test_speechcal.py +0 -0
  157. {rtpbench-0.4.0 → rtpbench-0.4.1}/tests/test_srtp.py +0 -0
  158. {rtpbench-0.4.0 → rtpbench-0.4.1}/tests/test_timing.py +0 -0
  159. {rtpbench-0.4.0 → rtpbench-0.4.1}/tests/test_tls.py +0 -0
  160. {rtpbench-0.4.0 → rtpbench-0.4.1}/tests/test_wheel.py +0 -0
  161. {rtpbench-0.4.0 → rtpbench-0.4.1}/tests/test_wire.py +0 -0
  162. {rtpbench-0.4.0 → rtpbench-0.4.1}/uri/advertise.yaml +0 -0
  163. {rtpbench-0.4.0 → rtpbench-0.4.1}/uri/network.yaml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: rtpbench
3
- Version: 0.4.0
3
+ Version: 0.4.1
4
4
  Summary: Wire-level latency and conformance tests for voice agents over SIP/RTP
5
5
  Author-email: Juanjo Aroztegi <juanjo@aroztegi.com>
6
6
  License-Expression: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "rtpbench"
3
- version = "0.4.0"
3
+ version = "0.4.1"
4
4
  description = "Wire-level latency and conformance tests for voice agents over SIP/RTP"
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -518,9 +518,10 @@ def _host(cmd: str) -> str:
518
518
 
519
519
 
520
520
  def _commit() -> str:
521
- """Counted from a release (results' wave tags would otherwise name the commit); installed,
522
- the release itself: there is no checkout to describe."""
523
- if ROOT == PACKAGE:
521
+ """Counted from a release (results' wave tags would otherwise name the commit); without a
522
+ checkout to describe (installed, or the action's copy of a commit, which has no .git), the
523
+ version it declares: the image tag names the code."""
524
+ if not (ROOT / ".git").exists(): # not `git describe`: it would find any repository above
524
525
  from importlib.metadata import version
525
526
 
526
527
  return f"v{version('rtpbench')}"
@@ -366,6 +366,8 @@ def _hold(dial: Dial, seed: int, offers: list[tuple[str, str | None]]) -> dict[s
366
366
  if s.remote_bye:
367
367
  break
368
368
  m.muted = direction == "inactive"
369
+ if m.muted: # the sender builds each packet a tick ahead: let the last one out first
370
+ s.wait(lambda: s.remote_bye, 2 * rtp.PTIME_NS / 1e9)
369
371
  s.reinvite(direction, conn=conn)
370
372
  s.wait(lambda: s.remote_bye, HOLD_S)
371
373
  s.hangup()
@@ -124,9 +124,24 @@ class Lines:
124
124
  # --- WebSocket (RFC 6455, server side: text frames out, masked frames in) ---
125
125
 
126
126
 
127
- async def _handshake(reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> str:
127
+ async def _handshake(reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> str | None:
128
+ """The request line once the WebSocket is open, or None for a plain HTTP request."""
128
129
  head = (await reader.readuntil(b"\r\n\r\n")).decode(errors="replace").split("\r\n")
129
130
  headers = {k.strip().lower(): v.strip() for k, _, v in (h.partition(":") for h in head[1:])}
131
+ if "sec-websocket-key" not in headers:
132
+ # Some agents check their key against the model list before they connect.
133
+ method, _, rest = head[0].partition(" ")
134
+ path = rest.partition(" ")[0]
135
+ found = method == "GET" and path.split("?")[0].rstrip("/").endswith("/models")
136
+ body = b'{"object": "list", "data": []}' if found else b""
137
+ status = "200 OK" if found else "404 Not Found"
138
+ writer.write(
139
+ f"HTTP/1.1 {status}\r\nContent-Type: application/json\r\n"
140
+ f"Content-Length: {len(body)}\r\nConnection: close\r\n\r\n".encode()
141
+ + body
142
+ )
143
+ await writer.drain()
144
+ return None
130
145
  key = headers["sec-websocket-key"].encode()
131
146
  accept = base64.b64encode(hashlib.sha1(key + _GUID).digest()).decode()
132
147
  writer.write(
@@ -532,7 +547,9 @@ def serve(out: Path, port: int = PORT, ready: Path | None = None) -> None:
532
547
  async def connection(reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> None:
533
548
  try:
534
549
  request = await _handshake(reader, writer)
535
- except asyncio.IncompleteReadError, KeyError, ConnectionError:
550
+ except asyncio.IncompleteReadError, ConnectionError:
551
+ request = None
552
+ if request is None:
536
553
  writer.close()
537
554
  return
538
555
  s = Session(writer, lines, log, steps)
@@ -13,12 +13,12 @@ services:
13
13
  command: sleep infinity
14
14
 
15
15
  opensips:
16
- image: opensips/opensips:3.6@sha256:81a7fa3c7bdbceaadb7cb869ff7ac3f34efb2d95cd7fecb3b689d7b6b1eb0672
16
+ image: opensips/opensips:4.0@sha256:e1d8151b96c00d52c9bd8f102ebc9e7c90fc4e44fe8df117b56009bebbeff7a0
17
17
  network_mode: service:target
18
18
  depends_on: [target]
19
19
  volumes: ["./targets/aivc/opensips.cfg:/etc/opensips/opensips.cfg:ro"]
20
20
  healthcheck:
21
- test: opensips-cli -x mi sr_get_status core | grep -q running
21
+ test: opensips-cli -x mi status_report:get core | grep -q running
22
22
  interval: 1s
23
23
  retries: 20
24
24
 
@@ -54,7 +54,7 @@ services:
54
54
  - -c
55
55
  - >-
56
56
  import json, socket; s = socket.socket(2, 2); s.settimeout(1);
57
- s.sendto(json.dumps({"jsonrpc": "2.0", "id": 1, "method": "subscribers_list",
57
+ s.sendto(json.dumps({"jsonrpc": "2.0", "id": 1, "method": "evi:subscribers",
58
58
  "params": ["E_UA_SESSION"]}).encode(), ("127.0.0.1", 8080));
59
59
  assert json.loads(s.recv(65535))["result"]["Event"]["Subscribers"]
60
60
  interval: 1s
@@ -122,3 +122,10 @@ def test_a_target_built_from_a_checkout_is_tagged_by_its_commit_and_files(
122
122
  assert tag() != clean
123
123
  with pytest.raises(ValueError, match="not a git checkout"):
124
124
  bench.checkout(tmp_path)
125
+
126
+
127
+ def test_a_copy_without_git_records_its_version_as_the_commit(root: Path) -> None:
128
+ from importlib.metadata import version
129
+
130
+ assert not (root / ".git").exists() # as the action unpacks a commit
131
+ assert bench._commit() == f"v{version('rtpbench')}"
@@ -82,6 +82,22 @@ def test_a_port_in_use_is_one_line_naming_the_option(tmp_path: Path) -> None:
82
82
  assert "\n" not in str(e.value)
83
83
 
84
84
 
85
+ def test_a_model_list_request_gets_an_empty_list(engine: tuple[int, Path]) -> None:
86
+ port, _ = engine
87
+
88
+ async def get(path: str) -> bytes:
89
+ reader, writer = await asyncio.open_connection("127.0.0.1", port)
90
+ writer.write(f"GET {path} HTTP/1.1\r\nHost: x\r\nAuthorization: Bearer x\r\n\r\n".encode())
91
+ reply = await reader.read()
92
+ writer.close()
93
+ return reply
94
+
95
+ head, _, body = asyncio.run(get("/v1/models")).partition(b"\r\n\r\n")
96
+ assert head.startswith(b"HTTP/1.1 200")
97
+ assert json.loads(body) == {"object": "list", "data": []}
98
+ assert asyncio.run(get("/v1/realtime")).startswith(b"HTTP/1.1 404")
99
+
100
+
85
101
  def test_lines_are_told_apart_and_answered() -> None:
86
102
  lines = realtime.Lines()
87
103
  for name in ("transfer", "prompt-03", "turn-05", "interrupt-01"):
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes