본문으로 건너뛰기

CI에서의 Signal Lab ​

설치를 가동시키는 실험은 그 회귀 테스트이기도 합니다. 파이프라인에서 signallab run은 창 없이 실행하고, 모든 단계를 출력하며, 모든 CI 시스템이 표시하는 JUnit 보고서를 쓰고, 작업이 이해하는 코드로 종료합니다:

종료 코드파이프라인이 해야 할 일
0계속 진행합니다: 모든 실험이 통과했습니다
1실패시킵니다: 실험이 실행되어 실패했습니다
2실패시킵니다: 실험이나 명령이 잘못되었습니다(검증 오류, 알 수 없는 매개변수, 없는 시크릿)
3실패 또는 재시도: 아무것도 실행할 수 없었습니다(서버에 닿을 수 없거나 토큰을 거부함, 포트를 열 수 없음)

들어가는 방법은 네 가지입니다:

방법실행되는 곳
GitHub ActionLinux 러너, 서버 이미지에서.
이미지컨테이너를 실행하는 모든 CI: GitLab, Jenkins, Docker가 있는 셸.
바이너리모든 러너, Windows 포함.
랩 서버실행이 장비 옆의 Signal Lab 서버에서 이루어지고, 파이프라인은 보내기만 합니다.

GitHub Actions ​

이 저장소는 GitHub Action이기도 합니다. ghcr.io/proanima/signallab 이미지에서 signallab을 실행하고, 실험이 실패하면 작업을 실패시키며, JUnit 보고서를 남깁니다:

yaml
jobs:
  signallab:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: ProAnima/SignalLab@v1.0.0
        with:
          version: 1.0.0
          experiments: tests/signallab/*.json
          params: |
            api=http://127.0.0.1:8080
        env:
          SIGNALLAB_SECRET_API_TOKEN: ${{ secrets.API_TOKEN }}

      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: signallab-junit
          path: signallab-junit.xml

통과하지 못한 실행은 실행 페이지에서 실패한 단계 옆에 오류 주석으로도 표시되며, 실험과 실패한 이유가 함께 나옵니다.

입력 ​

입력하는 일기본값
experiments실험 파일 또는 기본 제공 템플릿의 이름, 공백이나 줄로 구분합니다. tests/*.json 같은 패턴은 펼쳐집니다. 공백이 있는 경로는 지원하지 않습니다.필수
params매개변수 값, NAME=VALUE, 한 줄에 하나.
profile실험을 이 프로필로 실행합니다.
matrix조합마다 한 번씩 실행합니다: NAME=V1,V2, 한 줄에 이름 하나.
matrix-fileJSON 파일에서 조합을 읽습니다(실행의 매트릭스 참고).
fail-fast"true": 통과하지 못한 첫 실행에서 멈춥니다."false"
server작업 대신 이 Signal Lab 서버에서 실행합니다, 예: http://192.0.2.10:1430.
token서버의 접근 토큰. 시크릿을 넘기십시오.
junitJUnit 보고서가 가는 곳.signallab-junit.xml
timeout실행에 허용되는 초, 1~300.300
version이미지의 태그.latest
image다른 레지스트리 또는 로컬에서 빌드한 이미지. version이 그 태그입니다.ghcr.io/proanima/signallab
lang메시지와 보고서의 언어: en, ru, es, fr, de, pt, zh, ja, ko, hi 또는 ar.en
fail-on-error"false": 단계를 실패시키지 않고 대신 exit-code를 읽습니다."true"

경로(experiments, matrix-file, junit)는 단계의 작업 디렉터리를 기준으로 합니다.

TIP

version을 테스트한 릴리스로 고정하십시오. latest는 새 안정 릴리스마다 옮겨 갑니다.

출력 ​

출력내용
junitJUnit 보고서의 경로.
exit-codesignallab의 종료 코드: 0, 1, 2 또는 3.

실패 후 계속하기 ​

실패한 단계는 나머지 작업에 아무 출력도 넘기지 않습니다. 직접 결정하려면 fail-on-error: "false"로 설정하고 exit-code로 분기하십시오:

yaml
      - id: lab
        uses: ProAnima/SignalLab@v1.0.0
        with:
          experiments: tests/signallab/smoke.json
          fail-on-error: "false"

      - if: steps.lab.outputs.exit-code == '1'
        run: echo "an experiment failed; the report is ${{ steps.lab.outputs.junit }}"

      - if: steps.lab.outputs.exit-code != '0'
        run: exit 1

액션의 시크릿 ​

실험의 {{secret.NAME}}은 SIGNALLAB_SECRET_NAME을 읽습니다. 그 변수들을 단계에(env:) 저장소의 시크릿에서 설정하십시오. 액션은 그 단계의 모든 SIGNALLAB_SECRET_… 변수를 이름으로 signallab에 넘깁니다. 값은 환경으로 오가며 명령줄에는 절대 오르지 않고, 모든 보고서와 로그 줄은 그 자리에 ••••를 표시합니다. 실험이 필요로 하는데 설정되지 않은 시크릿은 아무것도 보내지기 전에 종료 코드 2로 단계를 실패시킵니다.

token 입력도 같은 방식으로 SIGNALLAB_TOKEN으로 오갑니다.

액션이 실행되는 방식 ​

  • Docker가 있는 Linux 러너가 필요합니다(ubuntu-latest에 있습니다). Windows 또는 macOS 러너에서는 종료 코드 2와 주석과 함께 멈춥니다. 거기서는 바이너리를 쓰십시오.
  • signallab은 이미지 안에서 호스트 네트워킹으로 실행됩니다: 러너가 닿는 것은 무엇이든 닿습니다. 작업이 러너에서 시작한 서비스 — 테스트 대상 시스템, 또는 포트를 공개한 services: 컨테이너 — 는 127.0.0.1에 있습니다.
  • 러너의 사용자로 실행되며 작업 공간이 같은 경로에 마운트되므로, 보고서는 작업의 소유가 됩니다.
  • 위의 입력과 --junit을 그대로 run에 넘깁니다. signallab이 할 수 있는 다른 것 — --report, --seed, --json, emulate — 은 이미지를 직접 쓰십시오.

어떤 CI에서든 이미지 ​

서버 이미지는 signallab을 /usr/local/bin/signallab으로 담고 있습니다. 그것을 쓰려면 엔트리포인트를 재정의하십시오.

GitLab CI:

yaml
signallab:
  image:
    name: ghcr.io/proanima/signallab:1.0.0
    entrypoint: [""]
  script:
    - signallab run tests/signallab/*.json --junit signallab-junit.xml
  artifacts:
    when: always
    reports:
      junit: signallab-junit.xml

시크릿은 SIGNALLAB_SECRET_<NAME>이라는 CI/CD 변수입니다(가림으로 표시하십시오). 작업의 환경이 그것들을 그대로 signallab에 넘깁니다.

셸 또는 어떤 스케줄러에서든 Docker(cron, Jenkins, 배포 스크립트):

bash
docker run --rm --network host \
  --user "$(id -u):$(id -g)" \
  -v "$PWD:/work" -w /work \
  -e SIGNALLAB_SECRET_API_TOKEN \
  --entrypoint signallab \
  ghcr.io/proanima/signallab:1.0.0 \
  run tests/smoke.json --junit junit.xml
echo "signallab exited with $?"
  • --network host는 실행이 호스트가 닿는 것에 닿게 합니다, 브로드캐스트와 멀티캐스트 포함 — Linux 호스트에서. 없으면 컨테이너는 유니캐스트로만 다른 호스트에 닿습니다.
  • 이미지는 비특권 사용자(uid 10001)로 실행됩니다. --user를 쓰면 대신 당신으로 실행되어 보고서를 당신 폴더에 쓸 수 있습니다. 없으면 폴더가 uid 10001에 대해 쓰기 가능해야 합니다.
  • 값을 주지 않은 -e NAME은 그 변수를 당신의 환경에서 넘깁니다.

바이너리 ​

모든 릴리스에는 signallab이 단독으로 들어 있습니다: signallab-<version>-linux-x64.tar.gz와 signallab-<version>-windows-x64.zip이며, 릴리스의 SHA256SUMS.txt에 나열됩니다. Linux용은 Ubuntu 22.04에서 빌드되고 시스템의 OpenSSL 3(libssl3)를 사용합니다: 그 릴리스나 더 새로운 배포판에서 실행됩니다.

yaml
      - name: Signal Lab
        run: |
          curl -fsSL -o signallab.tar.gz https://github.com/ProAnima/SignalLab/releases/download/v1.0.0/signallab-1.0.0-linux-x64.tar.gz
          tar -xzf signallab.tar.gz
          ./signallab run tests/signallab/smoke.json --junit signallab-junit.xml

Windows 러너에서는 zip을 풀고 signallab.exe를 같은 방식으로 실행하십시오. 데스크톱 앱이 설치된 컴퓨터에는 signallab이 이미 PATH에 있습니다.

랩 서버에서의 실행 ​

설치의 네트워크에 있는 장비는 클라우드 러너가 아니라 랩에서 닿을 수 있습니다. 거기서 Signal Lab 서버를 실행하고, 그 토큰을 CI 시크릿으로 보관하고, 실행을 그곳으로 보내십시오:

bash
signallab run tests/stage.json --server http://192.0.2.10:1430 --token-file token.txt --junit junit.xml --report reports/
yaml
      - uses: ProAnima/SignalLab@v1.0.0
        with:
          experiments: tests/signallab/stage.json
          server: http://192.0.2.10:1430
          token: ${{ secrets.SIGNALLAB_TOKEN }}

실험은 파이프라인의 체크아웃에서 옵니다. 서버는 자체 네트워크, 시크릿, 데이터 폴더로 실행하고, 단계를 되돌려 보내며, 보고서를 남깁니다(--report는 사본을 내려받습니다). 토큰은 --token-file 또는 SIGNALLAB_TOKEN에서 옵니다. 종료 코드는 같습니다. 닿을 수 없거나 토큰을 거부하는 서버는 3입니다. 러너는 서버에 닿을 수 있어야 합니다 — 랩의 자체 호스팅 러너, 또는 러너가 열 수 있는 서버 주소.

signallab 없이 서버에서 실행하려면 스크립트가 HTTP API를 직접 호출할 수 있습니다: HTTP로 실험 실행하기를 참고하십시오.

실행의 매트릭스 ​

실험 하나, 모든 대상: 각 조합은 별개의 실행이자 JUnit 보고서의 별개 테스트 스위트이며, 그 값에서 이름을 따옵니다.

bash
signallab run tests/smoke.json \
  -m device=192.0.2.20:9000,192.0.2.21:9000 \
  -m user=admin,guest

액션에서는 한 줄에 이름 하나:

yaml
        with:
          experiments: tests/signallab/smoke.json
          matrix: |
            device=192.0.2.20:9000,192.0.2.21:9000
            user=admin,guest
          fail-fast: "true"

또는 파일에서, --matrix-file(액션에서는 matrix-file)로:

json
[
  { "device": "192.0.2.20:9000", "user": "admin" },
  { "device": "192.0.2.21:9000", "user": "guest" }
]

모든 조합은 첫 조합이 무엇을 보내기 전에 검사되고, 한 명령에서 최대 256번의 실행이 나오며, --fail-fast는 나머지를 시작하지 않고 둡니다 — 그것들은 JUnit 보고서에 건너뜀으로 나타납니다. 규칙은 명령줄 페이지에 있습니다.

실험의 모든 프로필을 시도하려면 프로필마다 한 번씩 — 각각 한 단계, 또는 CI의 작업 매트릭스로 — --profile과 함께 실행하십시오.

JUnit 보고서 ​

--junit PATH(액션은 항상 하나를 씁니다)는 실행마다 테스트 스위트를, 노드마다 테스트 케이스를 담습니다: 일어난 곳에서의 실패를 고른 언어로, 오류 코드와 기술적 세부 사항과 함께; 실행이 닿지 못한 노드를 건너뜀으로; 시드, 결과, 파일, 매트릭스 값을 속성으로. GitHub(보고 액션과 함께), GitLab(artifacts:reports:junit), Jenkins, Azure DevOps가 그것을 테스트 결과로 표시합니다. 그 구조는 명령줄 페이지에 있습니다.

실패한 실행의 시드는 그 스위트의 속성과 로그에 있습니다: --seed <that number>는 같은 임의 값으로 다시 실행합니다.

테스트 대상 시스템이 호출하는 의존 대상 ​

CI에 없는 API, 장치 또는 브로커를 대상으로 자신의 시스템을 테스트하려면 Signal Lab이 그것을 연기하게 하십시오:

  • 실험 안에서, 에뮬레이터 노드가 한 실행 동안 의존 대상 역할을 하고, HTTP 요청 대기가 당신의 시스템이 그것에 보낸 것을 검사합니다. 실행의 출력은 각 에뮬레이터가 무엇을 요청받았는지로 끝납니다. 에뮬레이터를 참고하십시오.

  • 자신의 테스트 주변에서, signallab emulate가 그것들이 실행되는 동안 백그라운드에서 응답하고, 그 집계가 무엇이 호출되었는지 알려 줍니다:

    bash
    signallab emulate tests/payments-mock.json --for 300 --json > mock.ndjson &
    npm test
    wait

스크립트를 위한 출력 ​

--json은 stdout에 한 줄에 JSON 객체 하나만 출력하고 다른 것은 없습니다: started, 모든 step, 전체 결과를 담은 ended, 그리고 total, passed, failed, not_started, exit_code를 담은 summary. 오류는 엔진의 변하지 않는 code를 담으므로, 스크립트가 어떤 언어로든 그것으로 분기할 수 있습니다. 출력을 참고하십시오.

bash
signallab run tests/smoke.json --json | jq -c 'select(.type == "ended") | {file, outcome, seed}'