3proxy/tests/cases/counters.py
Vladimir Dubrovin 235f899668
Some checks failed
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Has been cancelled
C/C++ CI cmake / ubuntu-latest (wolfSSL) (push) Has been cancelled
help: the features of the build listed, and the tests skip what they need
3proxy --help (and the usage message of a bad invocation) now lists
what the build was made with: TLS and its backend, RADIUS, PCRE, IPv6,
UNIX sockets, the built-in HTTP server, transparency, ODBC and the
optional proxy services. The test runner reads the list before the
first case and the cases state the features they need with
t.skip_unless(), so a build without a feature skips its cases instead
of failing them; a binary too old to report anything skips the cases
with needs and runs the rest.
2026-10-30 14:17:54 +03:00

61 lines
1.9 KiB
Python

"""Traffic counters: a numbered counter keeps what it counted across a
reload, the value belonging to the process rather than to the configuration
read."""
import re
import time
def run(t):
if not t.skip_unless("httpsrv"):
return
origin = t.free_port()
proxy = t.free_port()
adm = t.free_port()
server = t.start("counters", f"""
log
auth iponly
allow *
http data * /data
httpsrv -p{origin}
flush
auth iponly
allow *
countin 3/counted D 100 * * *
proxy -p{proxy}
admin -p{adm}
""", ports=[origin, proxy, adm])
def counted():
"""The counter's value in MB, as the counters page shows it."""
page = t.http(f"http://127.0.0.1:{adm}/C").text
m = re.search(r"counted.*?</td><td>([0-9]+\.[0-9])</td>", page, re.S)
return float(m.group(1)) if m else None
def wait_counted(least, timeout=5.0):
deadline = time.time() + timeout
value = counted()
while (value is None or value < least) and time.time() < deadline:
time.sleep(0.1)
value = counted()
return value
reply = t.http(f"http://127.0.0.1:{origin}/data?size=300000",
proxy=f"127.0.0.1:{proxy}")
t.eq(300000, reply.length, "a body passes through the counted proxy")
before = wait_counted(0.2)
t.ok("the counter counts it") if before is not None and before >= 0.2 else \
t.fail("the counter counts it", ">= 0.2", before)
# reload, and wait for the services of the new configuration to run
out = server.output()
accepting = out.count("Accepting connections")
t.http(f"http://127.0.0.1:{adm}/R")
deadline = time.time() + 10
while time.time() < deadline and server.output().count("Accepting connections") < accepting + 3:
time.sleep(0.05)
after = wait_counted(0.2)
t.eq(before, after, "a reload keeps what the numbered counter counted")