菜单

开发与测试

相关源文件

本文档介绍了 Protocol Buffers (protobuf) 项目的开发工作流程、测试基础设施和贡献指南。它解释了如何有效地为代码库做贡献、使用测试框架以及确保跨平台兼容性。

开发环境设置

构建系统

Protocol Buffers 支持多种构建系统,其中 Bazel 是开发和测试的主要系统。

来源:.bazelrc1-42 ci/common.bazelrc1-84 examples/BUILD.bazel1-209 examples/WORKSPACE1-86 examples/MODULE.bazel1-31

Bazel 配置

Bazel 是主要的开发构建系统。该存储库包含针对不同构建类型的多个 Bazel 配置选项。

构建类型配置目的
调试--config=dbg带调试信息构建
优化--config=opt带优化构建
ASAN--config=asan用于内存错误的 AddressSanitizer
MSAN--config=msan用于未初始化读取的 MemorySanitizer
TSAN--config=tsan用于数据竞争的 ThreadSanitizer
UBSAN--config=ubsanUndefinedBehaviorSanitizer

来源:.bazelrc1-42 ci/common.bazelrc1-84

测试基础设施

Protocol Buffers 使用全面的测试基础设施来确保跨多种语言、平台和配置的可靠性。

来源:.github/workflows/test_cpp.yml1-591 .github/workflows/test_upb.yml1-318 .github/workflows/test_php.yml1-252 .github/workflows/test_ruby.yml1-213 .github/workflows/test_java.yml1-143 .github/workflows/test_objectivec.yml1-167 .github/workflows/test_python.yml1-126 .github/workflows/test_csharp.yml1-122

持续集成

该项目使用 GitHub Actions 进行持续集成。CI 系统针对以下方面运行测试:

  1. 不同的语言实现
  2. 多种构建配置
  3. 多种操作系统
  4. 不同架构

每个拉取请求在合并前都必须通过所有相关测试。

来源:.github/workflows/test_cpp.yml1-591 .github/workflows/test_java.yml1-143

测试类型

Protocol Buffers 采用多种测试类型

测试类型目的示例
单元测试测试单个组件//src/google/protobuf:map_test
符合性测试确保语言实现符合规范//conformance:conformance_test
集成测试测试组件之间的交互//examples:test
内存测试检查内存泄漏PHP 内存泄漏测试
Sanitizer 测试查找各种运行时问题ASAN, MSAN, TSAN, UBSAN

来源:.github/workflows/test_cpp.yml30-37 .github/workflows/test_php.yml40-44 python/google/protobuf/internal/testing_refleaks.py1-129

跨平台支持

Protocol Buffers 设计用于跨不同平台和架构工作。代码库包含平台检测逻辑和条件编译。

来源:src/google/protobuf/stubs/platform_macros.h1-115 .github/workflows/test_cpp.yml412-450

平台检测

文件 src/google/protobuf/stubs/platform_macros.h 包含用于在编译时检测平台和架构的宏。

架构检测示例

  • 用于 x86_64 的 GOOGLE_PROTOBUF_ARCH_X64
  • 用于 i386 的 GOOGLE_PROTOBUF_ARCH_IA32
  • 用于 ARM 的 GOOGLE_PROTOBUF_ARCH_ARM
  • 用于 ARMv8/AArch64 的 GOOGLE_PROTOBUF_ARCH_AARCH64

操作系统检测示例

  • 用于 macOS/iOS 的 GOOGLE_PROTOBUF_OS_APPLE
  • 用于 Android 的 GOOGLE_PROTOBUF_OS_ANDROID

来源: src/google/protobuf/stubs/platform_macros.h15-79 .github/workflows/test_cpp.yml81-98

跨平台测试

CI 系统在多个平台上测试 Protocol Buffers

  1. Linux:在各种发行版和配置上进行测试
  2. macOS:在 Apple Intel 和 Apple Silicon 上进行测试
  3. Windows:使用 MSVC 和 clang-cl 进行测试

此外,测试还在不同架构上运行

  • x86_64 (64 位)
  • i386 (32 位)
  • aarch64(ARM 64 位)

来源: .github/workflows/test_cpp.yml26-105 .github/workflows/test_cpp.yml148-167 .github/workflows/test_cpp.yml412-450

特定语言的测试

每种语言的实现都有特定的测试要求和配置。

C++

C++ 测试包括:

  1. 单元测试核心功能
  2. 使用不同的编译器标志进行测试(例如,--config=opt--config=asan
  3. 使用不同编译器版本进行测试(GCC、Clang)
  4. 具有各种配置的 CMake 构建测试

来源: .github/workflows/test_cpp.yml26-105 .github/workflows/test_cpp.yml148-167

Python

Python 测试包括:

  1. 纯 Python 实现的测试
  2. C++ 扩展实现的测试
  3. 跨多个 Python 版本(3.9-3.13)的测试
  4. 使用引用计数进行内存泄漏测试

Python 提供了一个特殊的 TestCase 来检测引用泄漏

来源: .github/workflows/test_python.yml26-125 python/google/protobuf/internal/testing_refleaks.py1-129

Java

Java 测试包括:

  1. 在多个 Java 版本(8、11、17)上进行测试
  2. 使用不同的 Bazel 配置进行测试
  3. Maven 构件的测试

来源: .github/workflows/test_java.yml26-122

PHP

PHP 测试包括:

  1. 在多个 PHP 版本(8.1、8.3)上进行测试
  2. 内存泄漏测试
  3. 使用 Valgrind 进行内存错误检测测试
  4. 纯 PHP 和 C 扩展实现的测试

来源: .github/workflows/test_php.yml26-186 .github/workflows/test_php_ext.yml1-78

Ruby

Ruby 测试包括:

  1. 在多个 Ruby 版本(3.1-3.4)上进行测试
  2. JRuby 测试
  3. 原生和 FFI 实现的测试
  4. Gem 安装测试

来源: .github/workflows/test_ruby.yml26-213

Objective-C

Objective-C 测试包括:

  1. 在不同平台(macOS、iOS)上进行测试
  2. Xcode 测试
  3. CocoaPods 验证
  4. Apple Silicon 测试

来源: .github/workflows/test_objectivec.yml26-167

C#

C# 测试包括:

  1. 在不同平台(Linux、Windows)上进行测试
  2. 一致性测试
  3. 架构测试(aarch64)

来源: .github/workflows/test_csharp.yml14-122

Rust

Rust 测试包括:

  1. 不同配置的测试(Bzlmod、Workspace、Optimized、ASAN)
  2. Cargo 测试

来源: .github/workflows/test_rust.yml1-57

为 Protocol Buffers 做出贡献

该项目维护着一个 CONTRIBUTORS.txt 文件,以表彰对代码库做出贡献的人员。贡献以各种形式出现,包括:

  1. 原始设计和实现
  2. 特定语言的实现
  3. Bug 修复和性能改进
  4. 文档
  5. 平台支持

来源: CONTRIBUTORS.txt1-108

开发工作流

典型的开发工作流程包括

  1. Fork 仓库
  2. 创建功能分支
  3. 进行更改
  4. 运行相应的测试
  5. 提交拉取请求 (pull request)
  6. 处理评审意见

测试指南

贡献 Protocol Buffers 时,请确保

  1. 所有现有测试均通过
  2. 新功能包含相应的测试
  3. 在适用情况下,测试覆盖多个平台
  4. 对于性能关键的代码,请包含基准测试

持续测试

Protocol Buffers 区分预提交测试和持续测试

  1. 预提交测试:每项拉取请求都会运行一部分测试
  2. 持续测试:定期或按需运行更广泛的测试

这种方法平衡了全面性和开发速度。

来源: .github/workflows/test_cpp.yml3-19 .github/workflows/test_java.yml3-20

调试和故障排除

内存泄漏检测

对于 Python、PHP 和 C++ 等语言,该项目包含专门用于检测内存泄漏的测试。

  1. Python:使用引用计数来检测泄漏
  2. PHP:使用专用的内存泄漏测试
  3. C++:使用 Sanitizer(ASAN、LSAN)来检测泄漏

来源: python/google/protobuf/internal/testing_refleaks.py1-129 .github/workflows/test_php.yml40-44

Sanitizer 工具

Sanitizer 工具可帮助检测各种运行时问题

  1. AddressSanitizer (ASAN):检测内存错误
  2. MemorySanitizer (MSAN):检测未初始化读取
  3. ThreadSanitizer (TSAN):检测数据竞争
  4. UndefinedBehaviorSanitizer (UBSAN):检测未定义行为

来源: .bazelrc13-35 ci/common.bazelrc8-35

结论

Protocol Buffers 项目拥有全面的开发和测试基础设施,旨在确保跨多种语言、平台和架构的可靠性。通过遵循本文档中概述的指南,贡献者可以有效地开发和测试代码库的更改。

有关 Protocol Buffers CI/CD 系统的更多信息,请参阅 持续集成