合规测试基础设施 + RFC 4475 首批 fixtures(叠加 PR #2) - #3
Draft
lixuanqun wants to merge 3 commits into
Draft
Conversation
- .gitattributes:将 *.raw 标记为 binary,禁止 git/编辑器对 SIP wire-format 做 CRLF↔LF 转换;其他源代码文件统一 LF。 - tools/write_fixture.py:从 .fixture 源文件(LF)生成 byte-exact .raw(CRLF) 和 .expect.properties 双文件。详细约定见脚本内文档。 - tools/rfc4475/rfc4475.txt:保留 RFC 4475 原始 ASCII 副本,作为后续 fixture byte-exact 提取的事实来源。 - tools/rfc4475/extract_message.py:按 'Message Details : <id>' 标记从 RFC 正文提取单条消息(剥去 RFC 6 空格缩进、跨页符、分页页脚),便于将更多 fixture 增量纳入仓库。 Co-authored-by: li xuanqun <793005378@qq.com>
新增 com.sip.compliance.fixture 包:
- MessageKind:sealed enum(REQUEST/RESPONSE)
- FixtureExpectation:sealed 接口(Accept/Reject 两种 verdict)
- TortureFixture:record,承载 id、source、bytes、expectation
- FixtureRepository:从 classpath 'torture/' 根递归扫描所有 .raw +
配对的 .expect.properties,返回稳定排序的 fixture 列表
- FixtureRepositoryTest:harness 自身的 self-test,使用 JUnit 5
DynamicTest 对每个 fixture 做:
· CRLF 字节级一致性(不允许 lone CR / lone LF)
· accept 一致性(CRLFCRLF 终止符、body.length 与实际字节数匹配、
request/response 必填字段齐全)
· reject 一致性(error.category 非空且符合 kebab-case)
manifest 走 java.util.Properties,零依赖。
本提交不引入任何 fixture 数据,下一个提交单独添加。
旧的 Rfc4475TortureSmokeTest 占位测试被新的 self-test 取代。
Co-authored-by: li xuanqun <793005378@qq.com>
self-test/(4 个我们自己撰写的基线 fixture):
- simple-options.fixture clean OPTIONS request(accept)
- simple-200-ok.fixture clean 200 OK response(accept)
- invite-with-sdp.fixture INVITE + 162 字节 SDP body(accept,
验证 Content-Length-driven framing)
- missing-sip-version.fixture Request-Line 缺 SIP-Version token
(reject, malformed-start-line)
rfc4475/(3 个从 RFC 4475 byte-exact 提取的 torture vector):
- 3.1.1.6-lwsdisp.fixture display-name 与 < 之间无 LWS(accept)
- 3.1.1.9-semiuri.fixture URI userpart 含分号参数 + Accept 头
LWS folding(accept)
- 3.1.2.1-badinv01.fixture Via 与 Contact 头多余分隔符(reject,
malformed-header)
每个 fixture 通过 tools/write_fixture.py 从 .fixture 源生成
.raw(CRLF byte-exact)和 .expect.properties(JDK Properties,零依赖)。
torture/README.md 详细说明 fixture 文件格式约定和 no-body / with-body
两种结构下空行的语义。
FixtureRepositoryTest 跑通全部 15 个动态测试:
- 1 个全局排序/去重检查
- 7 个 CRLF 字节级一致性(每个 fixture 一个)
- 5 个 accept 一致性(CRLFCRLF + body.length + 必填字段)
- 2 个 reject 一致性(category 非空 + kebab-case)
Co-authored-by: li xuanqun <793005378@qq.com>
This was referenced May 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概述
为 Phase 2(parser)做铺垫:先建 数据 + harness。本 PR 完全不动协议核心代码,只搭合规测试的基础设施和首批 fixture 数据,让后续的 parser 实现可以一边写一边让 fixture 一个一个转绿。
决策与设计
1. Fixture 文件格式:两段式
.fixture源 + 生成器直接手写
.raw风险大(编辑器会悄悄把 CRLF 改成 LF)。改为:.gitattributes把*.raw标为 binary,禁止 git/编辑器任何变换。2. Manifest 用
java.util.Properties而非 JSON零依赖、零引入。schema 见
torture/README.md。3. 目录分桶
4. 加载器:sealed + record
com.sip.compliance.fixture包:MessageKindFixtureExpectationAccept/Reject(record)TortureFixtureFixtureRepository本 PR 落地的内容
工具链 (
tools/)write_fixture.py— 主生成器,含详细切分约定(含 no-body / with-body 两种空行语义)rfc4475/rfc4475.txt— RFC 4475 原文 ASCII 副本(事实来源)rfc4475/extract_message.py— 按Message Details : <id>摘取单条消息(去缩进、去分页符)加载器 (
sip-compliance-tests/.../fixture/)FixtureRepositoryTest用 JUnit 5 DynamicTest 跑 self-test:首批 fixtures
self-test/(4 个)
simple-optionssimple-200-okinvite-with-sdpmissing-sip-versionrfc4475/(3 个,byte-exact 来自 RFC)
3.1.1.6-lwsdisp<之间无 LWS3.1.1.9-semiuri3.1.2.1-badinv01验证
Total: 26 tests passed, 0 failed.
字节级抽样验证(
od -c):所有 fixture 的.raw都以正确的方式终止(no-body 以 CRLFCRLF;with-body 以 body 的最后 1 字节,body 长度严格等于 Content-Length)。下一步(Phase 2b)
新开一个 PR,依赖本 PR 的 fixture 基础设施,开始实现真正的
SipParser:合并顺序建议: