# Testing signals — Genymobile/scrcpy

> Canonical page: https://codevetter.com/unpack/scrcpy/testing-signals

# Testing signals — Genymobile/scrcpy

Scanned commit 19c1261d2e2cbf2b5e6a71a8b64cc1dd3ede06ac (2026-09-05). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Client tests are 12 assert-based C programs in app/tests, each compiled as a Meson test() executable — but only when buildtype=debug so asserts execute. They cover adb parsing, binary helpers, CLI parsing, control-message serialization, device-message deserialization, orientation parsing, string/strbuf/vecdeque/vector containers and Windows command building. Server tests are JUnit4 in server/src/test covering ControlMessageReader, DeviceMessageWriter, CodecOptions, BinarySearch, Binary, CommandParser and StringUtils. CI runs release/test_server.sh (gradle test) and release/test_client.sh (meson test) plus a build-without-gradle check; there is no end-to-end socket-protocol or UI test coverage.
- app/tests contains 12 test files (test_adb_parser, test_audiobuf, test_binary, test_cli, test_command_windows, test_control_msg_serialize, test_device_msg_deserialize, test_orientation, test_str, test_strbuf, test_vecdeque, test_vector) registered as meson test() targets. — [app/meson.build#L222-298](https://github.com/Genymobile/scrcpy/blob/19c1261d2e2cbf2b5e6a71a8b64cc1dd3ede06ac/app/meson.build#L222-L298)
- Tests are only built when get_option('buildtype') == 'debug', because the tests are plain assert()-based programs compiled with -DSC_TEST. — [app/meson.build#L224-297](https://github.com/Genymobile/scrcpy/blob/19c1261d2e2cbf2b5e6a71a8b64cc1dd3ede06ac/app/meson.build#L224-L297) [app/tests/test_control_msg_serialize.c#L9-32](https://github.com/Genymobile/scrcpy/blob/19c1261d2e2cbf2b5e6a71a8b64cc1dd3ede06ac/app/tests/test_control_msg_serialize.c#L9-L32)
- Serialization is tested at the byte level: test_control_msg_serialize asserts exact serialized layouts (e.g. INJECT_KEYCODE == 14 bytes with specific keycode/metastate encoding). — [app/tests/test_control_msg_serialize.c#L9-52](https://github.com/Genymobile/scrcpy/blob/19c1261d2e2cbf2b5e6a71a8b64cc1dd3ede06ac/app/tests/test_control_msg_serialize.c#L9-L52)
- Server unit tests (JUnit 4.13.2) live in server/src/test/java under control/, model/, util/: ControlMessageReaderTest, DeviceMessageWriterTest, CodecOptionsTest, BinarySearchTest, BinaryTest, CommandParserTest, StringUtilsTest. — [server/build.gradle](https://github.com/Genymobile/scrcpy/blob/19c1261d2e2cbf2b5e6a71a8b64cc1dd3ede06ac/server/build.gradle) [server/src/test/java/com/genymobile/scrcpy/control/ControlMessageReaderTest.java](https://github.com/Genymobile/scrcpy/blob/19c1261d2e2cbf2b5e6a71a8b64cc1dd3ede06ac/server/src/test/java/com/genymobile/scrcpy/control/ControlMessageReaderTest.java)
- CI job test-scrcpy-server runs release/test_server.sh on ubuntu-latest with JDK 17 (zulu) using native gradle. — [.github/workflows/release.yml#L14-29](https://github.com/Genymobile/scrcpy/blob/19c1261d2e2cbf2b5e6a71a8b64cc1dd3ede06ac/.github/workflows/release.yml#L14-L29)
- CI job test-client installs meson/ffmpeg/SDL deps (SDL3 built by app/deps/sdl.sh since it is not packaged in Ubuntu) and runs release/test_client.sh. — [.github/workflows/release.yml#L69-98](https://github.com/Genymobile/scrcpy/blob/19c1261d2e2cbf2b5e6a71a8b64cc1dd3ede06ac/.github/workflows/release.yml#L69-L98) [release/test_client.sh](https://github.com/Genymobile/scrcpy/blob/19c1261d2e2cbf2b5e6a71a8b64cc1dd3ede06ac/release/test_client.sh)
- A dedicated CI job builds the server without Gradle via server/build_without_gradle.sh, keeping the manual javac/d8 path tested. — [.github/workflows/release.yml#L54-67](https://github.com/Genymobile/scrcpy/blob/19c1261d2e2cbf2b5e6a71a8b64cc1dd3ede06ac/.github/workflows/release.yml#L54-L67) [server/build_without_gradle.sh](https://github.com/Genymobile/scrcpy/blob/19c1261d2e2cbf2b5e6a71a8b64cc1dd3ede06ac/server/build_without_gradle.sh)
- Both sides test the same protocol independently (client serializer tests vs server reader tests) but no test exercises a real socket round-trip between client and server; protocol drift would only be caught manually. (inferred) — [app/tests/test_control_msg_serialize.c](https://github.com/Genymobile/scrcpy/blob/19c1261d2e2cbf2b5e6a71a8b64cc1dd3ede06ac/app/tests/test_control_msg_serialize.c) [server/src/test/java/com/genymobile/scrcpy/control/ControlMessageReaderTest.java](https://github.com/Genymobile/scrcpy/blob/19c1261d2e2cbf2b5e6a71a8b64cc1dd3ede06ac/server/src/test/java/com/genymobile/scrcpy/control/ControlMessageReaderTest.java)
- No tests exist for demuxer, decoder, recorder, screen, server.c, adb process management or any SDL/audio playback path — the largest files (cli.c, screen.c, recorder.c, server.c) are exercised only manually or via release scripts. (inferred) — [app/meson.build#L225-297](https://github.com/Genymobile/scrcpy/blob/19c1261d2e2cbf2b5e6a71a8b64cc1dd3ede06ac/app/meson.build#L225-L297)
- test_cli compiles the real cli.c+options.c, so option-table regressions (missing longopt, bad argdesc) are caught in CI. — [app/meson.build#L242-251](https://github.com/Genymobile/scrcpy/blob/19c1261d2e2cbf2b5e6a71a8b64cc1dd3ede06ac/app/meson.build#L242-L251) [app/tests/test_cli.c](https://github.com/Genymobile/scrcpy/blob/19c1261d2e2cbf2b5e6a71a8b64cc1dd3ede06ac/app/tests/test_cli.c)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
