gRPC 的 Kokoro 内部 CI 体系:tools/internal_ci 任务配置与测试脚本入口全解析

发布时间:2026/9/10 14:44:33
gRPC 的 Kokoro 内部 CI 体系:tools/internal_ci 任务配置与测试脚本入口全解析 gRPC 的 Kokoro 内部 CI 体系tools/internal_ci 任务配置与测试脚本入口全解析【免费下载链接】grpcC based gRPC (C, Python, Ruby, Objective-C, PHP, C#)项目地址: https://gitcode.com/GitHub_Trending/gr/grpc导读gRPC 是一个横跨 C、Python、Ruby、Objective-C、PHP、C# 等多语言的 RPC 框架其绝大部分开源测试都由名为 Kokoro又称 internal CI的持续集成工具承载。本文以仓库内 tools/internal_ci/README.md 为骨架结合该目录下数百份任务配置文件.cfg与入口脚本.sh/.bat系统拆解 gRPC 内部 CI 的组织方式配置文件采用哪种格式、每个字段含义是什么、测试脚本如何一步步构建并运行测试、跨平台Linux/macOS/Windows与跨场景PR/发布/回归/发布包构建任务如何编排。读完本文你将能读懂 gRPC 任何一条 CI 任务从配置声明到测试执行的完整链路并能对照仓库实际文件验证每一个结论。一、Kokoro 与 internal_ci 目录的定位tools/internal_ci/README.md全文虽然简短却精确界定了整个目录的职责gRPC 使用名为 Kokoro又称 internal CI的持续集成工具运行其绝大部分开源测试。该目录包含 kokoro 测试任务配置的外部部分实际的任务定义存放在内部仓库中以及作为入口执行实际测试的 shell 脚本。这句话揭示了 gRPC CI 的双层结构内部层不可见Kokoro 平台侧真正持有任务定义job definition——例如在哪个机器池pool上调度、使用哪份build_file、镜像与资源如何下发这些存放在 gRPC 团队内部的仓库中不在当前开源仓库内。外部层本仓库可见Kokoro 需要执行的脚本入口和部分任务参数即tools/internal_ci/下的全部内容。Kokoro 在调度任务时会 checkout 本仓库读取.cfg中声明的build_file然后执行对应的 shell 脚本。因此想要理解 gRPC 的 CI 全貌tools/internal_ci是开源侧唯一的事实来源。二、目录结构总览按平台与触发场景组织从目录树可以看出internal_ci 采用平台 场景 任务类型三层组织方式tools/internal_citools/internal_ci/ ├── helper_scripts/ # 被入口脚本 source 的公共辅助逻辑 ├── linux/ # Linux 任务数量最多 │ ├── pull_request/ # 仅 PR 触发bazel RBE、sanitizer、distribtests 等 │ ├── release/ # 仅发布触发收集/发布各语言包 │ ├── sanitizer/ # ASan/MSan/TSan/UBSan 回归任务 │ ├── arm64/ # ARM64 架构任务 │ ├── aws/ # 远程/弹性机器上执行的任务 │ └── *.cfg / *.sh # 常规任务与脚本 ├── macos/ # macOS 任务含 iOS/ObjC/tvOS 相关 │ ├── pull_request/ │ └── release/ └── windows/ # Windows 任务.bat 与 .cfg 成对出现 ├── pull_request/ └── release/2.1 平台目录的职责分工目录核心任务类型据文件名归纳linux/basictests基础测试矩阵、distribtests各语言发布包测试、Bazel RBE 远程构建、sanitizerASan/MSan/TSan/UBSan、xds/PSM 系列、性能测试GKE/singlevm、sanity、portability、interopmacos/basictests、ObjC/iOS/tvOS 测试、Bazel C/C 测试、C#/Python/Ruby distribtests、cfstream 测试、iOS 二进制体积检查windows/basictests、Bazel RBE、distribtestsC#/Python/standalone、clang-cl 构建、portability2.2 场景子目录的语义pull_request/下存放只在 PR 上运行的强化任务例如 linux/pull_request/grpc_bazel_rbe_asan.cfg、linux/pull_request/grpc_sanity.cfg 等release/下存放发布流程专用任务如 linux/release/grpc_collect_all_packages.cfg常规任务无子目录通常既在主干master跑也作为 PR 的基线任务。从文件命名看每类任务几乎都遵循一个.cfg声明任务一个同名.sh/.bat执行逻辑的结对模式例如grpc_distribtests_python.cfg↔grpc_distribtests_python.sh。三、.cfg 配置文件格式protobuf text format 逐字段拆解.cfg是 Kokoro 任务配置的外部可见部分采用protobuf text format书写每个文件头部都有# Config file for the internal CI (in protobuf text format)注释。以最典型的 linux/grpc_basictests_c_cpp_opt.cfg 为例# Location of the continuous shell script in repository. build_file: grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh timeout_mins: 240 action { define_artifacts { regex: **/*sponge_log.* regex: github/grpc/reports/** } } env_vars { key: RUN_TESTS_FLAGS value: -f basictests linux corelang opt --inner_jobs 16 -j 1 --bq_result_table aggregate_results }3.1 核心字段说明字段含义示例值build_file指向仓库内将被 Kokoro 执行的脚本入口相对仓库根的路径前缀grpc/grpc/tools/internal_ci/linux/grpc_run_tests_matrix.shtimeout_mins任务超时分钟数超时即判定失败240C/C opt 基础测试、480Python distribtests、60sanityaction.define_artifacts.regex定义需要收集/上传为任务产物的文件 glob**/*sponge_log.*Sponge 测试报告、github/grpc/reports/**测试报告env_vars注入到脚本环境中的键值对脚本通过环境变量读取任务参数RUN_TESTS_FLAGS、TASK_RUNNER_EXTRA_FILTERS、BAZEL_FLAGS等gfile_resources任务需要挂载的 GCSGoogle Cloud Storage资源路径/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_keybazel_setting让 Kokoro 识别为 Bazel 构建并发布 ResultStore 链接的标记内部字段大多未使用见 linux/grpc_bazel_rbe_opt.cfg 注释upsalite_frontend_address: https://source.cloud.google.com3.2 通过 env_vars 注入的不同参数模式不同任务通过env_vars向脚本注入执行参数这构成了 config 与 script 之间的契约测试矩阵参数RUN_TESTS_FLAGS传给 tools/run_tests/run_tests_matrix.py。例如 basictests 任务传-f basictests linux corelang opt --inner_jobs 16 -j 1 --bq_result_table aggregate_results-f指定测试套件类别、corelang指定语言、opt指定构建模式、--inner_jobs/-j控制并发、--bq_result_table指定把结果写入 BigQuery 的结果表。任务过滤器TASK_RUNNER_EXTRA_FILTERS传给 tools/run_tests/task_runner.py。例如 linux/grpc_distribtests_python.cfg 中-e aarch64表示排除 aarch64 目标distribtests 脚本还会用字符串替换移除presubmit标签因为 PythonPackage 目标不支持 presubmit 标签。Bazel 标志BAZEL_FLAGS注入 bazel 调用如--cache_test_resultsno --configopt见 linux/grpc_bazel_rbe_opt.cfg。结果上传开关UPLOAD_TEST_RESULTStrue控制是否上传测试结果。可见同一个脚本 不同的 env_vars 不同 CI 任务这是整个 internal_ci 复用脚本的核心设计。四、入口脚本的统一执行链路绝大多数入口脚本遵循高度一致的模板化流程。以 linux/grpc_run_tests_matrix.sh 为例set -ex # 1) 避免脚本退出后的慢速 finalization source $(dirname $0)/../../../tools/internal_ci/helper_scripts/move_src_tree_and_respawn_itself_rc # 2) 切换到 grpc 仓库根目录 cd $(dirname $0)/../../.. # 3) 准备 Linux 构建环境 source tools/internal_ci/helper_scripts/prepare_build_linux_rc # 4) 配置 ccache source tools/internal_ci/helper_scripts/prepare_ccache_rc # 5) 若为 PR追加 PR 过滤参数 if [ -n $KOKORO_GITHUB_PULL_REQUEST_NUMBER ] [ -n $RUN_TESTS_FLAGS ]; then export RUN_TESTS_FLAGS--filter_pr_tests --base_branch origin/$KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH $RUN_TESTS_FLAGS fi # 6) 调用真正的测试矩阵驱动 tools/run_tests/run_tests_matrix.py $RUN_TESTS_FLAGS || FAILEDtrue if [ $FAILED ! ]; then exit 1 fi该链路可归纳为五步respawn 工作区 → 切到仓库根 → 准备环境 → 配置缓存 → 执行测试矩阵。下面逐层拆解各步骤的底层实现。4.1 第一步move_src_tree_and_respawn_itself——规避 rsync 慢速收尾的金蝉脱壳helper_scripts/move_src_tree_and_respawn_itself_rc 是 gRPC CI 的一个巧妙技巧。Kokoro agent 的工作区固定为/tmpfs/src而该目录在脚本结束时会整体 rsync 回 agent非常耗时见脚本注释引用的内部 issue b/74837748。因此该脚本若当前目录已是/tmpfs/altsrc说明已完成 respawn直接设置GRPC_TEST_REPORT_BASE_DIR/tmpfs/src/github/grpc保证测试报告仍落在会被 rsync 回传的目录若当前目录是/tmpfs/src执行exec bash -c ...; mv src/github altsrc; cd altsrc; exec 原脚本把整个工作区搬到/tmpfs/altsrc后重新执行自身这样/tmpfs/src只剩少量输入产物finalization 阶段无需回传庞大的源码树其他情况打印提示并跳过防止在非 Kokoro 环境误触发。Windows 侧有对应实现 helper_scripts/move_src_tree_and_respawn_itself.bat工作区为T:\src并在 windows/grpc_run_tests_matrix.bat 中按相同模式调用。4.2 第二步与第三步环境准备脚本 prepare_build_linux_rchelper_scripts/prepare_build_linux_rc 被几乎所有 Linux 脚本 source它完成打印 worker 诊断信息Kokoro 机器池KOKORO_JOB_POOL、自定义 VM 镜像名/GRPC_IMAGE_NAME、内核/系统/Python 版本、CPU、内存、块设备等方便排查环境问题提高文件描述符上限ulimit -n 32768C 测试需要大量 fd调整 Docker 配置把 Docker 数据根目录移到临时盘/tmpfs/docker并使用镜像加速器--registry-mirrorhttps://mirror.gcr.io避免磁盘耗尽与拉取过慢脚本会检测 init 进程是否为 systemd 并选择不同的 docker 服务重启方式初始化子模块git submodule update --init安装基础依赖python3 -m pip install six放开 ptrace将/proc/sys/kernel/yama/ptrace_scope置 0允许测试驱动 GDB 附加子进程校验 scratch 盘挂载检查/tmpfs是否挂载若未挂载则打印告警可能引发 out of disk space。macOS 与 Windows 分别对应 helper_scripts/prepare_build_macos_rc 和 helper_scripts/prepare_build_windows.bat。4.3 第四步ccache 缓存配置Linux 与 Windows 分别通过 helper_scripts/prepare_ccache_rc 与 helper_scripts/prepare_ccache.bat 配置 ccacheWindows 脚本在测试结束后还会输出ccache --show-stats见 windows/grpc_run_tests_matrix.bat便于评估缓存命中率。4.4 PR 场景的测试过滤当脚本检测到KOKORO_GITHUB_PULL_REQUEST_NUMBERPR 环境变量且配置了RUN_TESTS_FLAGS时会追加--filter_pr_tests --base_branch origin/$KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH即只运行与 PR 改动相关的测试大幅缩短 PR 反馈周期。4.5 真正干活的测试驱动入口脚本最终把参数交给 tools/run_tests/run_tests_matrix.py测试矩阵按语言 × 构建模式 × 测试套件展开或 tools/run_tests/task_runner.py任务执行器按 label 过滤任务。Windows 上还额外先启动 tools/run_tests/start_port_server.py 端口服务器脚本注释指出这是 Windows Kokoro worker Python 环境升级前的临时 workaround见 windows/grpc_run_tests_matrix.bat。五、典型任务深度解析5.1 basictests基础测试矩阵C/C/Python/Ruby/C#/PHPbasictests 是最常见的任务族覆盖各语言的单元测试与端到端测试。以 linux/grpc_basictests_python.cfg以及 C/C 的 opt/dbg 变体为代表其RUN_TESTS_FLAGS形如-f basictests linux lang opt --inner_jobs 16 -j 1 --bq_result_table aggregate_results-f basictests选择 basictests 测试套件集合linux lang平台与语言维度corelang表示 C/C 核心语言opt/dbg构建模式优化/调试对应 linux/grpc_basictests_c_cpp_opt.cfg 与 linux/grpc_basictests_c_cpp_dbg.cfg--bq_result_table aggregate_results测试结果聚合写入 BigQuery 表aggregate_results供历史趋势分析。macOS 与 Windows 的 basictests 结构类似如 macos/grpc_basictests_python.cfg、windows/grpc_basictests_python.cfg且 Windows 版还包含 windows/grpc_basictests_c.cfg 等纯 C 任务。ARM64 与 AWS 目录下也有对应移植版本linux/arm64/grpc_basictests_python.cfg、linux/aws/grpc_aws_basictests_python.cfg。5.2 distribtests发布包级测试多阶段流水线distribtests 负责验证各语言发布产物wheel、gem、nuget、pecl 包等能否在目标环境正确构建与安装。以 linux/grpc_distribtests_python.sh 为例它展现了清晰的多阶段流水线# 阶段 1构建所有 Python Linux 产物wheel 与源码包 tools/run_tests/task_runner.py -f artifact linux python ${TASK_RUNNER_EXTRA_FILTERS} -j 12 -x build_artifacts/sponge_log.xml # 阶段 2把产物挪到 input_artifacts/作为下一阶段输入 rm -rf input_artifacts mkdir -p input_artifacts cp -r artifacts/* input_artifacts/ || true # 阶段 3收集并打包PythonPackage 目标不支持 presubmit 标签故先移除该标签 PACKAGE_TASK_RUNNER_EXTRA_FILTERS${TASK_RUNNER_EXTRA_FILTERS//presubmit /} tools/run_tests/task_runner.py -f package linux python ${PACKAGE_TASK_RUNNER_EXTRA_FILTERS} -x build_packages/sponge_log.xml # 阶段 4任一构建/打包失败则提前退出加速失败反馈 if [[ $BUILD_ARTIFACT_FAILED ! || $FAILED ! ]]; then exit 1; fi # 阶段 5运行全部 Python Linux distribtests tools/run_tests/task_runner.py -f distribtest linux python ${TASK_RUNNER_EXTRA_FILTERS} -j 12 -x distribtests/sponge_log.xml # 阶段 6产物体积上限检查 回存产物 tools/internal_ci/helper_scripts/check_python_artifacts_size.sh tools/internal_ci/helper_scripts/store_artifacts_from_moved_src_tree.sh值得注意的细节-x xxx/sponge_log.xml把每一步结果写成 Sponge 兼容的 XML与.cfg中define_artifacts.regex: **/*sponge_log.*呼应——配置文件声明的产物收集规则正是脚本中这些 XML 输出文件阶段 4 的提前退出策略避免了在已知失败时继续跑耗时的 distribtest阶段 6 的check_python_artifacts_size.sh检查是否有产物超过单文件体积上限防止发布包意外膨胀。发布场景下还有 linux/release/grpc_collect_all_packages.cfg 与 linux/grpc_publish_packages.sh 负责汇总与发布各语言包。5.3 Bazel RBE远程构建执行gRPC 在 CI 中大量使用 Bazel Remote Build ExecutionRBE加速测试。入口 linux/grpc_bazel_rbe.sh 的关键路径# 安装上传测试结果所需的 Python 依赖版本锁定到支持 python3.10 pip install --user google-api-python-client2.187.0 oauth2client4.1.3 pyOpenSSL23.2.0 # 通过 bazel_report_helper 生成带结果上传能力的 bazel wrapper python3 tools/run_tests/python_utils/bazel_report_helper.py --report_path bazel_rbe bazel_rbe/bazel_wrapper \ --bazelrctools/remote_build/linux_kokoro.bazelrc \ --output_user_root/tmpfs/bazel \ test \ $BAZEL_FLAGS \ --generate_json_trace_profile \ --profilebazel_rbe/profile.json \ $ -- ${BAZEL_TESTS:-//test/...}远程构建配置集中在 tools/remote_build/linux_kokoro.bazelrc--output_user_root/tmpfs/bazel把 Bazel 输出放到临时盘避免挤占工作区BAZEL_TESTS默认取//test/...整个 test 目录$支持任务侧追加目标生成profile.json用于构建性能分析。BAZEL_FLAGS通过.cfg注入不同变体opt 任务为--cache_test_resultsno --configoptlinux/grpc_bazel_rbe_opt.cfgdbg/tsan/msan/asan/ubsan 各有对应 cfg如 linux/grpc_bazel_rbe_tsan.cfg、linux/pull_request/grpc_bazel_rbe_ubsan.cfg。macOS 与 Windows 也有对应 Bash/Bat 版如 macos/grpc_run_bazel_c_cpp_tests.sh、windows/bazel_rbe.bat。5.4 sanitizer内存/线程/未定义行为检测sanitizer/ 目录集中了 C 与 C 的回归任务变体配置示例检测目标ASanlinux/sanitizer/grpc_c_asan.cfg内存越界/泄漏等MSanlinux/sanitizer/grpc_c_msan.cfg未初始化内存读取TSanlinux/sanitizer/grpc_cpp_tsan.cfg数据竞争UBSanlinux/sanitizer/grpc_c_ubsan.cfg未定义行为PR 场景的 sanitizer 变体放在 linux/sanitizer/pull_request/ 子目录。此外还有独立的 linux/pull_request/grpc_fork_asan.cfg 覆盖 fork 场景的 ASan。5.5 xds / PSM流量治理与托管控制面测试xds 系列任务linux/grpc_xds.cfg、linux/grpc_xds_v3.cfg 等验证 gRPC 对 xDS 协议的控制面数据面行为PSMProxyless Service Mesh系列linux/psm-interop-test-cpp.sh、linux/psm-light.cfg、linux/psm-security.cfg 等验证 gRPC 在 Google 托管网格中的互操作。从脚本名*_k8s_*.sh、grpc_xds_k8s_run_xtest.sh可以推断这类任务需要拉起 Kubernetes 集群与 xDS 控制面属于环境最复杂的端到端 CI。5.6 其他重要任务族sanity代码风格与一致性检查linux/grpc_sanity.cfg 仅timeout_mins: 60是最轻量的常驻任务portability可移植性构建检查含 OpenSSL 变体 linux/grpc_portability_openssl.cfginterop跨语言互操作测试linux/grpc_interop_matrix.sh、linux/grpc_interop_toprod.cfg性能linux/grpc_e2e_performance_gke.sh、linux/grpc_full_performance_master.cfg 等负责基准与负载测试头部依赖构建grpc_build_abseil-cpp_at_head.cfg、grpc_build_boringssl_at_head.cfg、grpc_build_protobuf_at_head.cfg验证 gRPC 对关键第三方依赖最新版本的兼容性clang-tidy / bloat / memory diff静态检查与体积/内存回归对比linux/grpc_bloat_diff.sh、linux/grpc_memory_diff.cfgAndroidlinux/grpc_android.sh 在 Docker 中构建 Android 工程。5.7 条件触发run_if_c_cpp_modified.shlinux/run_if_c_cpp_modified.sh 的存在说明部分任务带变更条件——只有 C/C 相关文件发生改动时才执行避免无关改动触发重型任务。六、helper_scripts被反复 source 的公共底座helper_scripts/是 internal_ci 的函数库从文件名与注释可归纳出以下职责分组脚本职责prepare_build_linux_rcLinux 构建环境准备诊断信息、ulimit、Docker、子模块、ptraceprepare_build_macos_rc / prepare_build_macos_interop_rcmacOS 环境准备prepare_build_windows.batWindows 环境准备prepare_ccache_rc / prepare_ccache.bat / prepare_ccache_symlinks_rcccache 配置move_src_tree_and_respawn_itself_rc / move_src_tree_and_respawn_itself.bat工作区搬移与脚本 respawnprepare_build_interop_rc互操作测试环境准备prepare_build_linux_perf_rc / prepare_build_linux_perf_multilang_rc性能测试环境准备含依赖清单 requirements.linux_perf.txtprepare_qemu_rcQEMU 模拟环境用于 ARM 交叉执行prepare_build_linux_ruby_artifact_rcRuby 产物构建准备store_artifacts_from_moved_src_tree.sh在 respawn 后把产物回存到 Kokoro 可收集的位置check_python_artifacts_size.shPython 产物体积上限校验install_python_interpreters.ps1 / choco_install_with_retry.sh多版本解释器安装、带重试的包安装一个关键认知由于入口脚本在 respawn 后工作区位置已改变产物回存必须通过 store_artifacts_from_moved_src_tree.sh 显式完成见 linux/grpc_distribtests_python.sh这正是 respawn 机制带来的配套设计。七、跨平台差异Windows 与 macOS 的脚本形态Windows使用.bat%RUN_TESTS_FLAGS%环境变量入口 windows/grpc_run_tests_matrix.bat 展示了几个平台特有逻辑用If Not %VAR%%VAR:keyword%模式检测RUN_TESTS_FLAGS是否包含csharp/python从而按需安装对应语言依赖先启动 port server 再跑测试矩阵结尾输出 ccache 统计与磁盘占用。macOS的脚本同样遵循respawn → prepare → run模式macos/grpc_run_tests_matrix.sh并额外覆盖 ObjC/iOS/tvOS 构建与测试如 macos/grpc_basictests_objc_ios.cfg、macos/grpc_ios_binary_size.sh以及 CFStream 相关测试macos/grpc_cfstream.cfg。八、如何在本地阅读与验证这套 CI 体系仓库是只读的你无需也不应修改任何 CI 文件即可深入理解这套体系按任务名找配对文件任取一个.cfg读取其build_file字段即可定位到实际执行脚本再读脚本顶部被 source 的helper_scripts/*_rc形成完整调用链。跟踪 env_vars 的消费点把.cfg中的RUN_TESTS_FLAGS/TASK_RUNNER_EXTRA_FILTERS/BAZEL_FLAGS与脚本中的引用处对应起来就能还原配置如何驱动行为。例如在仓库内搜索RUN_TESTS_FLAGS会发现它在 linux/grpc_run_tests_matrix.sh 与 Windows 批处理中均被直接透传给测试驱动。理解测试驱动入口脚本最终汇入 tools/run_tests/run_tests_matrix.py 与 tools/run_tests/task_runner.py可继续阅读这两个驱动文件了解任务如何按 label 展开与过滤。对照产物声明在.cfg的define_artifacts.regex中看到的sponge_log、reports、artifacts与脚本中-x *.xml输出、artifacts/目录一一对应前后印证即可确认收集机制。结语tools/internal_ci虽然只是 gRPC CI 的开源半壁但它完整承载了任务配置协议protobuf text format 的.cfg、执行入口.sh/.bat与公共底座helper_scripts/并借助env_vars契约实现了一套脚本、多类任务的高复用设计。从 respawn 工作区的小技巧到 distribtests 的多阶段流水线再到 Bazel RBE 的远程执行这套体系保障了 gRPC 在 6 种语言、3 大平台、数十种构建配置下每天海量测试的稳定运行。理解它你也就理解了 gRPC 开源质量保障体系的骨架。【免费下载链接】grpcC based gRPC (C, Python, Ruby, Objective-C, PHP, C#)项目地址: https://gitcode.com/GitHub_Trending/gr/grpc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考