Repository navigation
Memory regression tests #275
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
2dab90b
5adaeef
a89e5eb
a92fea4
8ba2935
682f6d6
d638cca
da57840
9af5d01
c625207
4cf631b
b3381ed
565be38
205ed52
2845a98
295f1cf
16d3f88
1234d35
4e1ac0b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,175 @@ | ||
| #!/usr/bin/env bash | ||
| # | ||
| # Copyright 2026 LiveKit | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| usage() { | ||
| cat <<'EOF' | ||
| Usage: memory-tester.sh [OPTIONS] | ||
|
|
||
| Run the Linux memory tester and append a table to the | ||
| GitHub step summary when GITHUB_STEP_SUMMARY is set. | ||
|
|
||
| Options: | ||
| --build-dir PATH Build directory (default: build-release) | ||
| --scenario NAME audio-track, video-track, data-track, | ||
| room-reuse, room-client-leave, | ||
| room-server-delete, capture-clock, | ||
| capture-pattern, capture-gstreamer, | ||
| or all (default: audio-track) | ||
| --iterations N Lifecycle cycles (default: 100) | ||
| --warmup N Baseline cycle (default: 20) | ||
| --max-rss-growth-mib MIB Allowed RSS growth; may be fractional (default: 8) | ||
| --max-thread-growth N Allowed thread growth (default: 0) | ||
| -h, --help Show this help | ||
|
|
||
| Environment: | ||
| MEMORY_TESTER_BUILD_DIR, MEMORY_TESTER_SCENARIO, | ||
| MEMORY_TESTER_ITERATIONS, | ||
| MEMORY_TESTER_WARMUP, MEMORY_TESTER_MAX_RSS_GROWTH_MIB, | ||
| MEMORY_TESTER_MAX_THREAD_GROWTH, MALLOC_ARENA_MAX. | ||
| All scenarios require LIVEKIT_URL and LIVEKIT_TOKEN_A. | ||
| EOF | ||
| } | ||
|
|
||
| repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" | ||
| build_dir="${MEMORY_TESTER_BUILD_DIR:-build-release}" | ||
| scenario="${MEMORY_TESTER_SCENARIO:-audio-track}" | ||
| iterations="${MEMORY_TESTER_ITERATIONS:-100}" | ||
| warmup="${MEMORY_TESTER_WARMUP:-20}" | ||
| max_rss_growth_mib="${MEMORY_TESTER_MAX_RSS_GROWTH_MIB:-8}" | ||
| max_thread_growth="${MEMORY_TESTER_MAX_THREAD_GROWTH:-0}" | ||
|
|
||
| while (($#)); do | ||
| case "$1" in | ||
| --build-dir) build_dir="$2"; shift 2 ;; | ||
| --scenario) scenario="$2"; shift 2 ;; | ||
| --iterations) iterations="$2"; shift 2 ;; | ||
| --warmup) warmup="$2"; shift 2 ;; | ||
| --max-rss-growth-mib) max_rss_growth_mib="$2"; shift 2 ;; | ||
| --max-thread-growth) max_thread_growth="$2"; shift 2 ;; | ||
| -h|--help) usage; exit 0 ;; | ||
| *) echo "ERROR: unknown option: $1" >&2; usage >&2; exit 2 ;; | ||
| esac | ||
| done | ||
|
|
||
| if [[ "${build_dir}" != /* ]]; then | ||
| build_dir="${repo_root}/${build_dir}" | ||
| fi | ||
| tester="${build_dir}/bin/livekit_memory_tester" | ||
| if [[ ! -x "${tester}" ]]; then | ||
| echo "ERROR: ${tester} not found. Run ./build.sh release-tests first." >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| case "${scenario}" in | ||
| audio-track|video-track|data-track|room-reuse|room-client-leave|room-server-delete|capture-clock|capture-pattern|capture-gstreamer) | ||
| scenarios=("${scenario}") | ||
| ;; | ||
| all) | ||
| scenarios=( | ||
| audio-track | ||
| video-track | ||
| data-track | ||
| room-reuse | ||
| room-client-leave | ||
| room-server-delete | ||
| capture-clock | ||
| capture-pattern | ||
|
Comment on lines
+90
to
+91
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 All-scenario runs fail on standard builds After a default Learn moreThe build defaults to capture disabled, but still produces the Linux memory tester. The script now appends both capture scenarios to Example: Run Recommended fix: Make Was this helpful? React with 👍 or 👎 to provide feedback. |
||
| capture-gstreamer | ||
| ) | ||
| ;; | ||
| *) | ||
| echo "ERROR: invalid scenario: ${scenario}" >&2 | ||
| usage >&2 | ||
| exit 2 | ||
| ;; | ||
| esac | ||
|
|
||
| for current_scenario in "${scenarios[@]}"; do | ||
| if [[ -z "${LIVEKIT_URL:-}" || -z "${LIVEKIT_TOKEN_A:-}" ]]; then | ||
| echo "ERROR: ${current_scenario} requires LIVEKIT_URL and LIVEKIT_TOKEN_A." >&2 | ||
| echo "Run: source scripts/set-test-tokens.sh" >&2 | ||
| exit 1 | ||
| fi | ||
| done | ||
|
|
||
| if [[ -n "${GITHUB_STEP_SUMMARY:-}" ]]; then | ||
| { | ||
| echo "## Memory tester results" | ||
| echo | ||
| echo "Iterations: ${iterations}" | ||
| echo "Warmup: ${warmup}" | ||
| echo "Threshold: RSS growth ≤ ${max_rss_growth_mib} MiB; thread growth ≤ ${max_thread_growth}." | ||
| echo | ||
| echo "| Scenario | RSS 0→${warmup} | RSS ${warmup}→${iterations} | Threads 0→${warmup} | Threads ${warmup}→${iterations} | Status |" | ||
| echo "|---|---:|---:|---:|---:|---|" | ||
| } >> "${GITHUB_STEP_SUMMARY}" | ||
| fi | ||
|
|
||
| report_regex='memory tester: scenario=([a-z-]+), RSS 0 ([0-9]+\.[0-9]+) -> warmup ([0-9]+\.[0-9]+) MiB \((-?[0-9]+\.[0-9]+) MiB\) -> final ([0-9]+\.[0-9]+) MiB \((-?[0-9]+\.[0-9]+) MiB\), threads 0 ([0-9]+) -> warmup ([0-9]+) \((-?[0-9]+)\) -> final ([0-9]+) \((-?[0-9]+)\), verdict=(PASS|FAIL)' | ||
|
|
||
| format_growth() { | ||
| if [[ "$1" == "0" || "$1" == "0.00" || "$1" == -* ]]; then | ||
| printf '%s' "$1" | ||
| else | ||
| printf '+%s' "$1" | ||
| fi | ||
| } | ||
|
|
||
| overall_status=0 | ||
| for current_scenario in "${scenarios[@]}"; do | ||
| set +e | ||
| output="$( | ||
| MALLOC_ARENA_MAX="${MALLOC_ARENA_MAX:-1}" "${tester}" \ | ||
| --scenario "${current_scenario}" \ | ||
| --iterations "${iterations}" \ | ||
| --warmup "${warmup}" \ | ||
| --max-rss-growth-mib "${max_rss_growth_mib}" \ | ||
| --max-thread-growth "${max_thread_growth}" 2>&1 | ||
| )" | ||
| status=$? | ||
| set -e | ||
| printf '%s\n' "${output}" | ||
|
|
||
| if [[ "${output}" =~ ${report_regex} ]]; then | ||
| if [[ -n "${GITHUB_STEP_SUMMARY:-}" ]]; then | ||
| if [[ "${BASH_REMATCH[12]}" == "PASS" ]]; then | ||
| verdict=":white_check_mark: PASS" | ||
| else | ||
| verdict=":x: FAIL" | ||
| fi | ||
| rss_warmup_growth="$(format_growth "${BASH_REMATCH[4]}")" | ||
| rss_final_growth="$(format_growth "${BASH_REMATCH[6]}")" | ||
| thread_warmup_growth="$(format_growth "${BASH_REMATCH[9]}")" | ||
| thread_final_growth="$(format_growth "${BASH_REMATCH[11]}")" | ||
| echo "| ${BASH_REMATCH[1]} | ${rss_warmup_growth} MiB | ${rss_final_growth} MiB | ${thread_warmup_growth} | ${thread_final_growth} | ${verdict} |" \ | ||
| >> "${GITHUB_STEP_SUMMARY}" | ||
| fi | ||
| else | ||
| echo "ERROR: ${current_scenario} did not produce a memory report." >&2 | ||
| if [[ -n "${GITHUB_STEP_SUMMARY:-}" ]]; then | ||
| echo "| ${current_scenario} | — | — | — | — | :x: ERROR |" >> "${GITHUB_STEP_SUMMARY}" | ||
| fi | ||
| status=1 | ||
| fi | ||
|
|
||
| if [[ "${status}" -ne 0 ]]; then | ||
| overall_status=1 | ||
| fi | ||
| done | ||
|
|
||
| exit "${overall_status}" | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we are only running these on ubuntu x64 release builds?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair callout, but some specific points:
MALLOC_ARENAstuff), given the original customer reportSo I felt having a single run on the most representative platform for robotics/physical AI (resource constrainted linux) would be most applicable