跳到正文
cccskills
免费在 GitHub 公开中文介绍

run-e2e

使用 `skywalking-infra-e2e` 在本地运行指定的 SkyWalking 端到端测试,并介绍如何查看失败日志、单独重试验证,以及根据实时查询结果编写预期 YAML。

原文查看原文说明

Run SkyWalking E2E tests locally

apache/skywalking星标 24,978(GitHub 24,978 + cccskills 0)
集成工具Kubernetes

实测评分 未实测

查看安装方法

适用场景

  • 在本地运行端到端测试
  • 通过日志调查测试失败
  • 根据实时输出编写预期 YAML
  • 确认 OAP 变更已进入测试环境

中文介绍

功能

本技能介绍如何使用 skywalking-infra-e2e,在本地运行 test/e2e-v2/cases/ 中指定的 SkyWalking 端到端测试。它会说明所需工具,检查源码变更后是否需要重新构建 OAP 或测试服务,并运行选定的测试用例。测试失败时,可查看容器日志、单独重试验证步骤,或针对仍在运行的 OAP 单独执行查询,以缩小问题范围。编写新的验证用例时,技能还会介绍如何根据实际查询结果制作预期 YAML,以及如何处理动态值。

适用场景

需要在本地复现端到端测试,或判断失败来自应用、查询还是预期结果时,可以使用本技能。创建测试用例,以及修改 UI 模板后发现既有数据没有反映变更时,也可以参考其中的检查方法。

使用示例

  • “在本地运行 storage/banyandb 端到端测试。”
  • “请结合日志和验证查询调查这个测试失败。”
  • “根据运行中的 OAP 查询结果编写预期 YAML。”

注意事项

需要 Go 和 skywalking-infra-e2e。根据测试用例,还可能需要 swctl、yq、kubectl 或 helm。如果发现源码变更需要重建,资料要求先征得用户确认再执行。调试结束后再进行清理。

本介绍由 AI(OpenAI Codex)根据公开的 SKILL.md 撰写。准确的规格请查看下方原文。

文档检查

AI 根据 SKILL.md 的内容检查了需要注意的操作和使用前提。评分只依据实际运行的结果(实测对比)。

安全性发送数据、删除文件、执行命令等是否有说明
B部分不足资料规定重建前须确认,同时也介绍了清理和删除容器的操作。
安装难易度所需工具和 API 密钥是否少且有说明
B部分不足需要 Go 和 E2E 命令行工具,其他工具取决于测试用例。

不计入评分。 由 AI(OpenAI Codex)于 2026年10月29日 评估。仅供参考,安装前请同时查看原文。

如果您认为评估有误,请申请复核

请写明哪一项有误以及原因。无需登录。我们会对照 SKILL.md 重新评估,并在此处更新结果。

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

包含的文件(1)

  • SKILL.md12.1 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Run SkyWalking E2E Test

Run an E2E test case using skywalking-infra-e2e. The user provides a test case path (e.g., simple/jdk, storage/banyandb, alarm).

Prerequisites

All tools require Go installed. Check .github/workflows/ for the exact e2e commit used in CI.

e2e CLI

Built from apache/skywalking-infra-e2e, pinned by commit in CI:

# Install the pinned commit
go install github.com/apache/skywalking-infra-e2e/cmd/e2e@<commit-id>

# Or clone and build locally (useful when debugging the e2e tool itself)
git clone https://github.com/apache/skywalking-infra-e2e.git
cd skywalking-infra-e2e
git checkout <commit-id>
make build
# binary is in bin/e2e — add to PATH or copy to $GOPATH/bin

swctl, yq, and other tools

E2E test cases run pre-install steps (see setup.steps in each e2e.yaml) that install tools into /tmp/skywalking-infra-e2e/bin. When running locally, you need these tools on your PATH.

swctl — SkyWalking CLI, used in verify cases to query OAP's GraphQL API. Pinned at SW_CTL_COMMIT in test/e2e-v2/script/env:

# Option 1: Use the install script (same as CI)
bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh swctl
export PATH=/tmp/skywalking-infra-e2e/bin:$PATH

# Option 2: Build from source
go install github.com/apache/skywalking-cli/cmd/swctl@<SW_CTL_COMMIT>

yq — YAML processor, used in verify cases:

# Option 1: Use the install script
bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh yq
export PATH=/tmp/skywalking-infra-e2e/bin:$PATH

# Option 2: brew install yq (macOS)

Other tools (only needed for specific test cases):

ToolInstall scriptUsed by
kubectlinstall.sh kubectlKubernetes-based tests
helminstall.sh helmHelm chart tests
istioctlinstall.sh istioctlIstio/service mesh tests
etcdctlinstall.sh etcdctletcd cluster tests

All install scripts are at test/e2e-v2/script/prepare/setup-e2e-shell/.

Steps

1. Determine the test case

Resolve the user's argument to a full path under test/e2e-v2/cases/. If ambiguous, list matching directories and ask.

ls test/e2e-v2/cases/<argument>/e2e.yaml

2. Check if rebuild is needed

Compare source file timestamps against the last build:

# OAP server changes since last build
find oap-server apm-protocol -type f \( \
  -name "*.java" -o -name "*.yaml" -o -name "*.yml" -o \
  -name "*.json" -o -name "*.xml" -o -name "*.properties" -o \
  -name "*.proto" \
\) -newer dist/apache-skywalking-apm-bin.tar.gz 2>/dev/null | head -5

# Test service changes since last build
find test/e2e-v2/java-test-service -type f \( \
  -name "*.java" -o -name "*.xml" -o -name "*.yaml" -o -name "*.yml" \
\) -newer test/e2e-v2/java-test-service/e2e-service-provider/target/*.jar 2>/dev/null | head -5

If files are found, warn the user and suggest rebuilding before running.

3. Rebuild if needed (only with user confirmation)

# Rebuild OAP
./mvnw clean flatten:flatten package -Pall -Dmaven.test.skip && make docker

# Rebuild test services
./mvnw -f test/e2e-v2/java-test-service/pom.xml clean flatten:flatten package

4. Run the E2E test

Set required environment variables and run:

export SW_AGENT_JDK_VERSION=8
e2e run -c test/e2e-v2/cases/<case-path>/e2e.yaml

5. If the test fails

Do NOT run cleanup immediately. Instead:

  1. Check container logs:

    docker compose -f test/e2e-v2/cases/<case-path>/docker-compose.yml logs oap
    docker compose -f test/e2e-v2/cases/<case-path>/docker-compose.yml logs provider
    
  2. Run verify separately (can retry after investigation):

    e2e verify -c test/e2e-v2/cases/<case-path>/e2e.yaml
    
  3. Only cleanup when done debugging:

    e2e cleanup -c test/e2e-v2/cases/<case-path>/e2e.yaml
    

6. Manually fire each verify query (fast triage)

The e2e verify retry loop runs in sequence and stops at the first failing case, so a single bad query hides every case after it. When a verify fails, run each verify case directly against the still-running OAP before editing anything — you'll see the real error (bad flag, missing data, wrong expected), not the progress spinner. This is also the right way to author new verify cases: craft the query against live OAP, confirm the actual YAML, then write the expected file.

# Find the host-side port that infra-e2e bound to OAP's container port 12800.
# (Each run picks a new random port; the trigger log prints it too.)
docker ps --filter "name=skywalking_e2e-oap" --format "{{.Ports}}" \
  | grep -oE "[0-9]+->12800" | head -1
# => e.g. 56381->12800

URL=http://localhost:56381/graphql
SWCTL=/tmp/skywalking-infra-e2e/bin/swctl

# Copy the query from e2e.yaml verbatim, then substitute ${oap_host} → localhost
# and ${oap_12800} → the port you just found:
$SWCTL --display yaml --base-url=$URL service ly IOS
$SWCTL --display yaml --base-url=$URL logs list --service-name=MyiOSApp
$SWCTL --display yaml --base-url=$URL metrics exec --expression=service_cpm --service-name=MyiOSApp

When a swctl subcommand rejects a flag (Incorrect Usage: flag provided but not defined: -layer), the e2e config is using syntax the pinned swctl commit doesn't support. Find the right syntax with swctl <cmd> --help and update the e2e config. Common cases encountered:

Broken flag/formWorking form
service ls --layer IOSservice ly IOS
metrics exec ... --is-normal=truedrop --is-normal (default behavior)

For queries that don't use swctl (raw curl against /loki/..., Zipkin, PromQL), hit the matching exposed port:

curl "http://localhost:$(docker ps --filter name=skywalking_e2e-oap --format '{{.Ports}}' | grep -oE '[0-9]+->3100' | head -1 | cut -d'-' -f1)/loki/api/v1/labels"

7. UI template changes require a fresh DB

UITemplateInitializer.initTemplate() (in oap-server/server-core) calls uiTemplateManagementService.addIfNotExist(setting) — keyed by the id field in each ui-initialized-templates/**/*.json. Same ID → skipped. So edits to an existing template JSON (adding widgets, relabeling, changing expressions) will not be applied on an already-initialized OAP, even after a container restart, because the old copy still lives in storage.

To pick up dashboard JSON changes:

# Remove both containers — BanyanDB stores state inside the container FS in the
# e2e compose (no named volume), so removing the container wipes state cleanly.
docker rm -f skywalking_e2e-oap-1 skywalking_e2e-banyandb-1

# For compose setups that use a named volume, also:
# docker volume rm <volume-name>

# Then re-run — OAP sees empty storage, loads the new template JSON.
e2e run -c test/e2e-v2/cases/<case>/e2e.yaml

Symptom to watch for: you edit the JSON, rebuild, redeploy — dashboard in the UI still shows the pre-edit layout. That's not a caching bug; that's addIfNotExist doing exactly what its name says.

8. Author the expected YAML from live output

For a new verify case, the workflow is:

  1. Fire the query manually (see step 6) and capture the YAML.
  2. Pick which fields are meaningful domain values (must match exactly) vs dynamic runtime values (notEmpty / gt / ge). See test/e2e-v2/CLAUDE.md for the decision guide.
  3. Write the expected file. If the response is a list, wrap the items in {{- contains . }} ... {{- end }} so ordering and extra actual items don't fail the match.
  4. Re-run e2e verify alone (the containers are still up from the previous run); iterate on the expected file without rebuilding.

9. Expected-file authoring traps

These burn CI cycles and pass locally. Each was learned the hard way.

Unquoted content: {{ notEmpty .content }} with : inside the value. Sim-generated or real log content routinely includes colons (POST https://api.example.com/cart failed: 500, HTTP/1.1 500: Internal Server Error). Without quoting, the template renders to invalid YAML (snakeyaml parses failed: as a nested key) and the whole log entry marshals to nil. Symptom: diff shows - nil at every position in the expected logs list vs real maps in actual. Fix: wrap in single quotes — content: '{{ notEmpty .content }}'. Single-quoted YAML preserves : in the scalar; only fails on embedded '. Double quotes also work unless the content has ".

Nested contains with multiple per-element pattern assertions against a varied stream. The template renders the block body once per actual element; when the outer block body has multiple inner contains patterns asserting specific tag key/value pairs, and only some actuals satisfy all the inner patterns, go-cmp with contains can end up comparing [rendered_for_A0, nil, nil, ...] vs [A0, A1, A2, ...] and fail despite contains being permissive on extras. Specifically: outer contains .logs with a single log pattern + inner contains .tags asserting two distinct key/value pairs. On a simulator emitting heterogeneous errors (js + promise + ajax + pageNotFound), only a subset satisfy the inner assertion. Passes locally with 1–2 logs, fails in CI with 6+.

  • Keep the outer contains body lenient: field-shape checks (notEmpty, gt), one discriminator tag that every element in the stream carries.
  • Cover per-category assertions via separate labeled-metric verify cases, not inside the nested template.
  • Rule of thumb: "at least one log exists with the right layer routing" inside the logs expected; per-category coverage via meter_*_count{label=X} verify cases.

Hand-crafted OTLP curl payloads drift from real SDK output. When the upstream SDK ships a published simulator image (mini-program-monitor's sim-wechat / sim-alipay, browser-client-js sim, etc.), prefer driving the e2e with that image in MODE=timed with a bounded DURATION_MS over hand-rolling the OTLP JSON. Hand-crafted payloads miss real-world shape issues: delta-vs-cumulative temporality, label-cardinality surprises, stacktrace formatting variance, attribute key names that changed between SDK versions. Pin to a released tag (v0.4.0), not :latest or HEAD SHA — reproducibility.

timeUnixNano: "0" in an OTLP metric datapoint. The receiver propagates this into MAL's bucket computation and the metric lands in the 1970 time bucket — swctl metrics exec over the "last N minutes" window won't find it. Either use $(date +%s)000000000 at setup time or omit the field if the receiver accepts "now" as default.

Setup-step curl loop with || sleep pattern. The shell line for ... do curl && break || sleep 5; done exits 0 when every attempt connection-refused because the final sleep 5 returns 0. OAP takes ~50 s to start in CI, so all attempts fail before OAP is ready, and the setup step silently succeeds with zero traffic ingested. Fix: curl -sS -f --retry 30 --retry-delay 5 --retry-connrefused --retry-all-errors --max-time 10 ... + set -e at step top.

swctl flag rejected. If a verify case uses a flag the pinned swctl commit doesn't support (service ls --layer vs service ly), the whole case fails 20× before CI gives up. Fire each verify query by hand once before pushing (step 6 above).

Published image cache miss in CI. docker compose pull sometimes hits rate limits or unreachable registries; the test spins until timeout with "dependency failed to start". Look at the CI log for Error response from daemon: pull access denied or manifest unknown. If you see that, pin a different image tag that's definitely published (check docker manifest inspect <tag> locally), not a floating one.

Common test cases

ShorthandPath
simple/jdktest/e2e-v2/cases/simple/jdk/
storage/banyandbtest/e2e-v2/cases/storage/banyandb/
storage/elasticsearchtest/e2e-v2/cases/storage/elasticsearch/
alarmtest/e2e-v2/cases/alarm/
logtest/e2e-v2/cases/log/
profiling/tracetest/e2e-v2/cases/profiling/trace/

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

ci-e2e-debug

免费有简介

用于排查 GitHub Actions 中失败的端到端测试。它会获取并解压运行日志,检查 OAP 及其他组件的错误,并整理可能的原因,包括独立测试进程中的故障。

  • 排查 GitHub Actions 中失败的端到端测试
  • 检查 OAP、BanyanDB 或 UI 日志
  • 追踪独立测试进程的故障
apache/skywalking2.5万2026年10月29日 更新

compile

免费有简介

通过 Maven 包装器构建 SkyWalking OAP,并检查 Javadoc 和 Checkstyle。可选择全量、后端、单个模块构建或单项检查,用于提交 PR 前验证改动。

  • 提交 PR 前运行全量构建
  • 检查 Javadoc 错误和警告
  • 只构建修改过的模块
apache/skywalking2.5万2026年10月29日 更新

generate-classes

免费有简介

编译 SkyWalking 的 MAL、OAL、LAL 或 Hierarchy DSL 脚本,并输出生成的 `.class` 文件供检查。可选择一种 DSL,也可生成全部四种,再用 `javap` 查看字节码。

  • 检查 MAL 表达式生成的类
  • 查看 OAL 指标和分发器类
  • 检查 LAL 或 Hierarchy 输出
apache/skywalking2.5万2026年10月29日 更新

gh-pull-request

免费有简介

在推送前检查构建、Checkstyle、许可证标头和 Java 类名写法,修复问题后提交并推送分支;若当前分支尚无 PR,则按项目模板创建。

  • 提交 PR 前检查改动
  • 提交并推送分支改动
  • 从当前分支创建 PR
apache/skywalking2.5万2026年10月29日 更新

license

免费有简介

用 `license-eye` 检查源文件的 Apache 2.0 标头和依赖许可证清单;可修复标头、重新生成清单,并在提交 PR 前核对差异。

  • 提交 PR 前检查 Apache 标头
  • 修复缺失的许可证标头
  • 核对依赖许可证清单差异
apache/skywalking2.5万2026年10月29日 更新

new-monitoring-feature

免费有简介

为 SkyWalking OAP 增加监控对象或 Layer 时,梳理不同信号对应的扩展点,并列出 Layer 注册、界面模板、文档和本地验证等相关工作。

  • 规划新增监控 Layer 的改动
  • 选择指标或日志的扩展点
  • 整理 Layer 相关界面和文档更新
apache/skywalking2.5万2026年10月29日 更新

查看 apache 的全部技能

报告此技能的问题