엔드투엔드 테스트 파이프라인
GitLab v19.4요약
모든 E2E 테스트는 별도의 하위 파이프라인에서 실행됩니다. e2e-test-pipeline-generate job은 E2E 테스트를 실행하는 하위 파이프라인을 트리거하는 데 사용되는 CI/CD YAML 파일 정의를 생성합니다.
공통 아키텍처#
모든 E2E 테스트는 별도의 하위 파이프라인에서 실행됩니다. E2E 테스트 파이프라인의 다양한 동적 기능을 지원하기 위해 모든 하위 파이프라인 YAML 파일은 e2e-test-pipeline-generate CI/CD job이 생성하며 각각의 트리거 job이 실행합니다.
e2e-test-pipeline-generate#
e2e-test-pipeline-generate job은 E2E 테스트를 실행하는 하위 파이프라인을 트리거하는 데 사용되는 CI/CD YAML 파일 정의를 생성합니다.
generate_e2e_pipelines Rake 태스크는 다음을 수행합니다.
- 특정 머지 리퀘스트 파이프라인에서 어떤 e2e 스펙을 실행할지 결정합니다.
- E2E 테스트 파이프라인 유형별로 CI/CD YAML 파일 정의를 생성합니다.
이 Rake 태스크의 동작은 다음과 같습니다.
- 특정 머지 리퀘스트의 변경 사항을 분석하고 다음 기준에 따라 선택적 테스트 실행으로
어떤 스펙을 실행해야 하는지 결정합니다. 이를 바탕으로 모든 시나리오에 대해
dry-run을 실행해 시나리오에 실행 가능한 테스트가 있는지 판단합니다. - 각 시나리오의 총 실행 시간을 계산합니다.
- 실행 시간 값을 기준으로 동적 job 스케일링이 시나리오 유형별로 필요한 병렬 CI/CD job 수를 계산하고 적절한 값이 반영된 파이프라인 YAML 파일을 생성합니다.
e2e:perf-on-cng#
e2e:perf-on-cng 하위 파이프라인은 Cloud Native GitLab 설치본을 대상으로 테스트를 실행합니다.
배포는 orchestrator
CLI 도구가 관리하며, 이 도구로 CI/CD 배포를 로컬에서 그대로 재현할 수도 있습니다.
e2e:perf-on-cng 하위 파이프라인은 머지 리퀘스트에서 실행되며 블로킹 job이 아닙니다. 테스트가 실패하더라도 머지 리퀘스트 병합을 막지 않습니다.
설정#
이 E2E 테스트 하위 파이프라인은 e2e-test-pipeline-generate CI/CD job에 아티팩트로 저장된 동적 생성 CI/CD YAML 파일을 사용해
e2e:perf-on-cng job이 트리거합니다. CI/CD YAML 파일은 템플릿을 사용해 생성됩니다.
하위 파이프라인 job#
하위 파이프라인은 E2E 테스트 실행을 지원하는 여러 Stage로 구성됩니다.
.pre#
build-cng-envjob은 CNG 다운스트림 파이프라인의 모든 환경 변수를 설정합니다build-cngjob은 필요한 모든 이미지를 빌드하는CNG다운스트림 파이프라인을 트리거합니다
prepare#
dotenv-varsjob은 모든 k6 성능 테스트가 들어 있는qa/performance_test폴더로 아티팩트를 생성합니다. 이 아티팩트는 다운스트림 파이프라인 job이 테스트를 실행하기 위해 내려받습니다. 또한 job 정의에서 볼 수 있듯이CI_JOB_NAME,CI_JOB_ID,GITLAB_HELM_CHART_REF같은 일부 환경 변수를 저장하며, 이 값은run-performance-testsjob이 사용합니다
test#
run-performance-test job#
이 job은 Component Performance testing 프로젝트의 다운스트림 멀티 프로젝트 파이프라인을 트리거합니다. 이 파이프라인은 다음 작업을 수행합니다.
- 동일한 리전과 존에 GCP 인스턴스 두 개를 만듭니다.
새 테스트 추가#
run-performance-test job의 일부로 실행되는 새 k6 테스트를 추가할 수 있습니다.
새 테스트를 추가하는 방법은 다음과 같습니다.
qa/performance_test/k6_test아래에 새.js파일을 만듭니다.- 테스트를 작성하기 전에 다음 보일러플레이트를 복사해 붙여 넣습니다.
- 주석 부분을 해당 값과 코드로 업데이트합니다.
export const TTFB_THRESHOLD= /* TTFB THRESHOLD VALUE EXPECTED */;
export const RPS_THRESHOLD= /* RPS THRESHOLD VALUE EXPECTED */;
export const TEST_NAME=/* 'NAME OF THE TEST IN QUOTES' */;
export const LOAD_TEST_VUS = 2; /* THE NUMBER OF THREADS OF ACTUAL TEST */
export const LOAD_TEST_DURATION = '50s'; /* THE DURATION FOR THE ACTUAL TEST RUN */
export const WARMUP_TEST_VUS = 1; /* THE NUMBER OF THREADS FOR WARMING UP THE SYSTEM */
export const WARMUP_TEST_DURATION = '10s'; /* THE DURATION FOR THE WARMUP RUN */
export const LOAD_TEST_START_TIME = '10s'; /* THE TIME TO WAIT AFTER WHICH THE LOAD TEST STARTS
USUALLY THIS WOULD BE EQUAL TO WARMUP_TEST_DURATION */
export const options = {
scenarios: {
warmup: {
executor: 'constant-vus',
vus: WARMUP_TEST_VUS,
duration: WARMUP_TEST_DURATION,
gracefulStop: '0s',
tags: { scenario: 'warmup' },
},
load_test: {
executor: 'constant-vus',
vus: LOAD_TEST_VUS,
duration: LOAD_TEST_DURATION,
startTime: LOAD_TEST_START_TIME,
tags: { scenario: 'load_test' },
},
},
thresholds: {
'http_req_waiting{scenario:load_test}': [
{ threshold: `p(90)<${TTFB_THRESHOLD}`, abortOnFail: false }
],
'http_reqs{scenario:load_test}': [
{ threshold: `rate>=${RPS_THRESHOLD}`, abortOnFail: false }
]
},
};
export default function () {
// WRITE THE TEST HERE
}
TTFB_THRESHOLD와 RPS_THRESHOLD에는 현재 어떤 값을 넣어도 됩니다. 지금은 리포팅에 사용되지 않으며 https://gitlab.com/gitlab-org/quality/component-performance-testing/-/issues/75의 일부로 제거될 예정입니다
테스트를 작성할 때는 qa/performance_test/k6_test에 있는 다른 테스트를 참고할 수 있습니다.
테스트에 환경 내 데이터가 필요하면 mr_seed.rb 파일을 업데이트해 필요한 리소스를 추가할 수 있습니다.
mr_seed.rb에서 생성되는 기존 리소스는 제거하지 않습니다.
Component Performance testing은 현재 여러 시드 파일을 지원하지 않으며, 이는 https://gitlab.com/gitlab-org/quality/component-performance-testing/-/issues/76의 일부로 해결될 예정입니다
e2e:perf-on-cng 테스트 job 건너뛰기#
MR 파이프라인에서 e2e:perf-on-cng 테스트 job을 건너뛰려면 머지 리퀘스트를 만들 때 pipeline:skip-performance 레이블을 추가합니다.
문제 해결#
run-performance-test job 아래의 멀티 프로젝트 job이 데이터 시딩 중 gem 호환성 오류로 실패하는 경우가 있습니다.
오류 예시는 다음과 같습니다.
/usr/lib/ruby/gems/3.3.0/gems/bundler-2.6.9/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb:225:in `resolve_conflict': Could not find compatible versions (Bundler::PubGrub::SolveFailure)
Because every version of gitlab-backup-cli depends on grpc ~> 1.74.0
and Gemfile depends on gitlab-backup-cli >= 0,
grpc ~> 1.74.0 is required.
머지 리퀘스트에 포함되지 않은 Gemfile 업데이트가 있었기 때문에 발생합니다. 머지 리퀘스트 브랜치를 master 브랜치로 리베이스하면 해결됩니다.
e2e:test-on-cng#
e2e:test-on-cng 하위 파이프라인은 Cloud Native GitLab 설치본을 대상으로 테스트를 실행합니다.
배포는 orchestrator
CLI 도구가 관리하며, 이 도구로 CI/CD 배포를 로컬에서 그대로 재현할 수도 있습니다.
e2e:test-on-cng 하위 파이프라인은 머지 리퀘스트에서 실행되며 병합 전 검증 수명 주기의 일부입니다. 테스트가 실패하면 도입한 코드 변경을
병합할 수 없습니다.
설정#
이 E2E 테스트 하위 파이프라인은 e2e-test-pipeline-generate CI/CD job에 아티팩트로 저장된 동적 생성 CI/CD YAML 파일을 사용해
e2e:test-on-cng job이 트리거합니다. CI/CD YAML 파일은 템플릿을 사용해 생성됩니다.
하위 파이프라인 job#
하위 파이프라인은 E2E 테스트 실행을 지원하는 여러 Stage로 구성됩니다.
.pre#
build-cng-envjob은 CNG 다운스트림 파이프라인의 모든 환경 변수를 설정합니다build-cngjob은 필요한 모든 이미지를 빌드하는CNG다운스트림 파이프라인을 트리거합니다
test#
test Stage의 job은 다음 작업을 수행합니다.
test Stage의 job 목록입니다.
cng-instance는 오케스트레이션 테스트를 제외한 전체 e2e 스위트를 CNG 대상으로 실행합니다cng-registry는 레지스트리 시나리오Test::Integration::Registry를 CNG 대상으로 실행합니다cng-relative-url은 스모크 스위트Test::Instance::Smoke를 실행하되 CNG에 상대 URL을 설정해 실행합니다cng-oauth는 OmniAuth가 활성화된 상태에서 GitHub와 GitLab 간 인증 e2e 스펙을 실행합니다.cng-secrets-manager는 OpenBao가 활성화된 상태로 배포된 CNG 대상으로 Secrets Manager 시나리오Test::Integration::SecretsManager를 실행합니다cng-vue3-rollout은vue3_migrate_jobs기능 플래그가 활성화된 상태로 배포된 CNG 대상으로 Vue 3 롤아웃 시나리오Test::Instance::Vue3Rollout을 실행합니다
report#
이 Stage는 allure 테스트 리포트 생성을 담당합니다.
디버깅#
디버깅에 도움이 되는 사항은 다음과 같습니다.
- 각 테스트 job은
orchestrator에 전달해 동일한 배포를 로컬 디버깅용으로 그대로 재현할 수 있는 인자 목록을 출력합니다. - 클러스터 이벤트 로그와 모든 Pod 로그는 E2E 테스트 job 아티팩트에 저장됩니다.
- 배포에 실패하면
orchestrator가 오류가 포함된 모든 클러스터 이벤트를 자동으로 출력합니다.
e2e:test-on-omnibus-ee#
e2e:test-on-omnibus-ee 하위 파이프라인은 Omnibus 설치본을 대상으로 테스트를 실행합니다. 이 파이프라인 유형은 기본적으로
머지 리퀘스트 파이프라인에서 실행되지 않으며 e2e:test-on-omnibus-ee job을 실행해 수동으로 트리거할 수 있습니다.
이 파이프라인 유형은 실패가 허용되며, 머지 리퀘스트 파이프라인 안에서 수동으로 트리거한 경우에도 테스트 실패가 병합을 막지 않습니다.
Linux 패키지 배포는 gitlab-qa가 관리합니다.
설정#
이 E2E 테스트 하위 파이프라인은 e2e-test-pipeline-generate CI/CD job에 아티팩트로 저장된 동적 생성 CI/CD YAML 파일을 사용해
e2e:test-on-omnibus-ee job이 트리거합니다. CI/CD YAML 파일은
템플릿을 사용해 생성됩니다.
하위 파이프라인 job#
E2E 테스트 실행 파이프라인은 E2E 테스트 실행을 지원하는 여러 Stage로 구성됩니다.
.pre#
이 Stage는 다음 작업을 담당합니다.
omnibus-gitlabDocker 이미지를 빌드하는 다운스트림 파이프라인을 트리거합니다.
test#
test Stage의 job은 다음 작업을 수행합니다.
- 빌드된 Linux 패키지를 사용해 GitLab을 설치합니다.
- Linux 패키지 설치본을 대상으로 E2E 테스트를 실행합니다.
report#
이 Stage는 allure 테스트 리포트 생성을 담당합니다.
e2e:test-on-gdk#
e2e:test-on-gdk 파이프라인은 폐지되어 더 이상 실행되지 않습니다.
이 파이프라인은
GitLab Development Kit(GDK) 인스턴스를 대상으로 엔드투엔드 테스트를 실행했습니다.
e2e:test-on-cng가 머지 리퀘스트를 담당하고, e2e:test-on-omnibus-ee가 Linux
패키지 설치를 담당합니다.
두 파이프라인 모두 운영 환경에 가까운 환경에서 실행되므로 더 권장됩니다.
자세한 내용은
GDK 대상 E2E 테스트 실행 중단을 참고합니다.
설정#
이 E2E 테스트 하위 파이프라인은 e2e-test-pipeline-generate CI/CD job에 아티팩트로 저장된 동적 생성
CI/CD YAML 파일을 사용해 e2e:test-on-gdk job이 트리거했습니다.
CI/CD YAML 파일은 템플릿을 사용해 생성했습니다.
하위 파이프라인 job#
하위 파이프라인은 E2E 테스트 실행을 지원하는 여러 Stage로 구성되었습니다.
test#
test Stage의 job은 다음 작업을 수행했습니다.
build-gdk-imagejob이 빌드한 Docker 이미지를 사용해 GDK 인스턴스를 시작했습니다.- 실행 중인 GDK 인스턴스를 대상으로 E2E 테스트를 실행했습니다.
report#
이 Stage는 allure 테스트 리포트 생성을 담당했습니다.
테스트 라이선스#
이 파이프라인이 사용하는 라이선스에 대한 자세한 내용은 테스트 라이선스를 참고합니다.
E2E 테스트 파이프라인에 새 job 추가#
E2E 테스트 파이프라인은 실행 시간을 기준으로 job을 동적으로 스케일링합니다. 파이프라인 정의 YAML 파일의 job 정의와
특정 테스트 시나리오를 연결하기 위해 scenario 클래스를 사용합니다. 이 클래스는 qa/qa/scenario 폴더에 있습니다.
e2e 테스트 파이프라인 정의 YAML 파일의 일반적인 job 정의는 다음과 같습니다.
my-new-test-job:
# ...
variables:
QA_SCENARIO: Test::Integration::MyNewTestScenario
이 예시에서 각 항목의 의미는 다음과 같습니다.
QA_SCENARIO: Test::Integration::MyNewTestScenario:qa/bin/qa테스트 실행 스크립트에 전달되는 시나리오 클래스 이름입니다. 전체 클래스 이름은QA::Scenario::Test:Integration::MyNewTestScenario이지만, 정의를 짧게 유지하기 위해QA::Scenario는 생략합니다.
위 예시를 기준으로 새 job을 만들려면 다음 단계를 수행합니다.
-
e2e테스트 프레임워크의integration디렉터리에 새 시나리오my_new_job.rb를 만듭니다. 시나리오 클래스는 해당 시나리오를 특정 파이프라인 유형의 특정 job과 연결하는 파이프라인 매핑을 정의해야 합니다. job을 test-on-cng 파이프라인에 추가했다면, 이 시나리오는 실행해야 할 RSpec 태그와 파이프라인 매핑을 다음과 같이 정의합니다.module QA module Scenario module Test module Integration class MyNewJob < Test::Instance::All tags :some_special_tag pipeline_mappings test_on_cng: %w[my-new-test-job] end end end end end -
main.gitlab-ci.yml파이프라인 정의에 새 job 정의를 추가합니다.my-new-test-job: extends: - .cng-test variables: QA_SCENARIO: Test::Integration::MyNewTestScenario
이렇게 정의하면 my-new-test-job은 미리 정의된 실행 시간 임계값을 기준으로 병렬 job 스케일링을 자동으로 적용받습니다.