본문으로 건너뛰기
cccskills
무료GitHub에 공개한국어 소개

run-e2e

`skywalking-infra-e2e`로 지정한 SkyWalking E2E 테스트를 로컬에서 실행하는 절차를 안내합니다. 실패 로그를 확인하고 검증을 따로 재시도하며, 실제 조회 결과를 바탕으로 기대 YAML을 작성하는 방법을 다룹니다.

원문원문 설명 보기

Run SkyWalking E2E tests locally

apache/skywalking스타 24,978(GitHub 24,978 + cccskills 0)
연동 도구Kubernetes

실행 점수 미검증

설치 방법 보기

이럴 때 유용합니다

  • E2E 테스트 케이스를 로컬에서 실행할 때
  • 로그를 바탕으로 테스트 실패를 조사할 때
  • 실제 출력으로 기대 YAML을 작성할 때
  • OAP 변경이 테스트 환경에 반영됐는지 확인할 때

한국어 소개

할 수 있는 일

이 스킬은 skywalking-infra-e2e를 사용해 test/e2e-v2/cases/에 있는 SkyWalking E2E 테스트 케이스를 로컬에서 실행하는 절차를 안내합니다. 필요한 도구를 확인하고, 소스 변경 뒤 OAP나 테스트 서비스의 재빌드가 필요한지 살펴본 다음 선택한 케이스를 실행합니다. 테스트가 실패하면 컨테이너 로그를 확인하고 검증 단계만 따로 재시도하거나, 실행 중인 OAP에 쿼리를 개별 실행해 원인을 좁히는 방법을 설명합니다. 새 검증 케이스를 만들 때는 실제 조회 결과에서 기대 YAML을 작성하고 동적 값을 다루는 흐름도 안내합니다.

이럴 때 유용합니다

E2E 테스트를 로컬에서 재현하거나 실패 원인이 애플리케이션, 쿼리, 기대 결과 중 어디에 있는지 확인할 때 유용합니다. 테스트 케이스를 새로 작성하거나 UI 템플릿을 수정했는데 기존 데이터에 반영되지 않는 이유를 조사할 때도 참고할 수 있습니다.

사용 예시

  • “storage/banyandb E2E 테스트를 로컬에서 실행해 주세요.”
  • “로그와 검증 쿼리를 보고 이 테스트 실패 원인을 조사해 주세요.”
  • “실행 중인 OAP의 조회 결과로 기대 YAML을 작성하고 싶습니다.”

주의 사항

Go와 skywalking-infra-e2e가 필요합니다. 테스트 케이스에 따라 swctl, yq, kubectl, helm 등이 추가로 필요할 수 있습니다. 소스 변경에 따른 재빌드가 필요하면 실행 전에 사용자 확인을 받도록 자료에 명시되어 있습니다. 디버깅이 끝난 뒤 정리 단계를 실행합니다.

이 소개문은 공개된 SKILL.md를 바탕으로 AI(OpenAI Codex)가 작성했습니다. 정확한 사양은 아래 원문을 확인하세요.

문서 점검

AI가 SKILL.md의 내용에서 주의가 필요한 작업과 도입 전제를 확인했습니다. 점수는 실제로 실행한 결과(실행 검증)만으로 매깁니다.

안전성전송·삭제·명령 실행 등을 명시하고 있는가
B일부 부족재빌드 전 확인을 요구하지만 정리와 컨테이너 삭제 작업도 설명합니다.
도입의 용이성필요한 도구나 API 키가 적고 적혀 있는가
B일부 부족Go와 E2E 명령줄 도구가 필요하며 추가 도구는 테스트 케이스에 따라 달라집니다.

점수에는 넣지 않았습니다. 2026년 10월 29일 기준으로 AI(OpenAI Codex)가 판정했습니다. 참고용이므로 설치 전에 원문도 확인해 주세요.

평가가 다르다고 생각되면 재검토를 요청하기

어느 항목이 왜 다르다고 생각하는지 적어 주세요. 로그인은 필요 없습니다. SKILL.md와 대조해 평가를 다시 만들고 이곳에 반영합니다.

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

포함된 파일(1)

  • SKILL.md12.1 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

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 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

ci-e2e-debug

무료요약 있음

GitHub Actions에서 실패한 E2E 테스트를 조사하는 스킬입니다. 실행 로그 산출물을 가져와 OAP와 다른 구성 요소의 오류를 확인하고, 별도 테스트 프로세스의 실패까지 포함해 원인 후보를 정리합니다.

  • GitHub Actions E2E 실패 조사
  • 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

무료요약 있음

PR 브랜치의 변경 사항을 빌드, 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 등록, UI 템플릿, 문서, 로컬 검증 등 함께 필요한 작업을 파악하도록 돕습니다.

  • 새 모니터링 Layer 변경 계획
  • 메트릭·로그 확장 지점 선택
  • Layer 추가에 따른 UI·문서 항목 정리
apache/skywalking2.5만2026년 10월 29일 업데이트

apache의 스킬 모두 보기

이 스킬의 문제 신고