콘텐츠로 이동
무료 평가 시작

시뮬레이터 자동화와 오류 재현

  • 시뮬레이터를 상대 장비 또는 상대 호스트로 써서 자신의 프로그램을 시험합니다.
  • headless 시나리오로 시험을 자동화하고 종료 코드로 결과를 판정합니다.
  • 연결 거부, 세션 ID 불일치, T3 타임아웃, 처리하지 않는 요청, 쓰기 배압을 일부러 만들고 각각 어떻게 보이는지 확인합니다.
  • 재현 결과를 추적 파일과 로그로 남깁니다.
  • 첫 통신을 마친 환경. 튜토리얼 C++ 예제 build/pdcomm-tutorial을 씁니다.
  • 환경 변수 PDCOMM_ROOT, PDCOMM_SIMULATOR

명령은 Linux와 macOS 셸 기준입니다. Windows에서는 "$PDCOMM_SIMULATOR/pdcomm-simulator-headless"를 & "$Simulator\pdcomm-simulator-headless.exe"로 바꿉니다.

1. 내 호스트를 시뮬레이터 장비로 시험합니다

섹션 제목: “1. 내 호스트를 시뮬레이터 장비로 시험합니다”

external-peer 시나리오는 장비를 띄우고, 외부 호스트가 S1F13과 S1F1을 보낸 뒤 끊기를 기다립니다.

터미널 창
"$PDCOMM_SIMULATOR/pdcomm-simulator-headless" --scenario external-peer --session-id 7 --timeout-ms 20000

두 번째 줄의 local_address(예: 127.0.0.1:50092)로 호스트를 연결하고 establish, identity, quit을 입력합니다.

터미널 창
"$PDCOMM_ROOT/build/pdcomm-tutorial" host active 127.0.0.1:50092

시뮬레이터가 s1f13, s1f1, disconnect를 관찰하고 "outcome":"passed", 종료 코드 0으로 끝납니다. 자신의 호스트 프로그램을 자동 시험에 넣을 때는 이 출력의 두 번째 줄에서 주소를 읽어 호스트에 넘기고, 시뮬레이터의 종료 코드로 판정합니다.

2. 내 장비를 시뮬레이터 호스트로 시험합니다

섹션 제목: “2. 내 장비를 시뮬레이터 호스트로 시험합니다”

먼저 튜토리얼 장비를 시작합니다.

터미널 창
"$PDCOMM_ROOT/build/pdcomm-tutorial" equipment passive 127.0.0.1:5006

다른 터미널에서 시뮬레이터를 호스트 역할로 실행합니다.

터미널 창
"$PDCOMM_SIMULATOR/pdcomm-simulator-headless" --role host --address 127.0.0.1:5006 --session-id 7

시뮬레이터가 연결하고 통신을 수립한 뒤 "outcome":"passed"로 끝납니다. 장비 터미널에는 받은 S1F13의 결과 RESULT kind=1 request=0 outcome=2가 나옵니다.

3. 시나리오로 기능을 한 번에 확인합니다

섹션 제목: “3. 시나리오로 기능을 한 번에 확인합니다”

headless 시뮬레이터에는 기능별 왕복 시나리오가 들어 있습니다. 튜토리얼의 각 장에 대응하는 시나리오를 실행해 SDK와 시뮬레이터가 그 기능을 지원하는지 먼저 확인합니다.

터미널 창
mkdir -p results
for scenario in status-round-trip data-report-round-trip directory-round-trip remote-report-config-round-trip typed-command-round-trip; do
"$PDCOMM_SIMULATOR/pdcomm-simulator-headless" --scenario "$scenario" > "results/$scenario.jsonl"
echo "$scenario exit=$?"
done
status-round-trip exit=0
data-report-round-trip exit=0
directory-round-trip exit=0
remote-report-config-round-trip exit=0
typed-command-round-trip exit=0

시나리오 목록과 출력 형식은 headless 시뮬레이터에 있습니다. GUI에서 만든 프로필과 시나리오도 프로젝트 파일로 저장해 같은 방식으로 실행할 수 있습니다.

4. 스크립트나 AI 도구로 시뮬레이터를 조작합니다

섹션 제목: “4. 스크립트나 AI 도구로 시뮬레이터를 조작합니다”

GUI를 --mcp-stdio로 실행하면 MCP 클라이언트가 GUI의 세션을 만들고 시작할 수 있습니다. GUI가 스스로 입출력을 진행하므로 외부 프로그램을 그 세션에 바로 연결할 수 있습니다.

다음 순서로 시뮬레이터 장비를 만들고 튜토리얼 호스트를 연결해 값을 바꾸는 시험을 자동화할 수 있습니다.

  1. simulator.session.create: role equipment, mode passive, address 127.0.0.1:5000, protocol_session_id 7
  2. simulator.lifecycle.start: 응답의 generation과 revision을 다음 호출에 씁니다.
  3. 튜토리얼 호스트에서 establish, values 1001 1002 → SECS-II 01 02 41 04 49 44 4c 45 b1 04 00 00 00 00
  4. simulator.status_data.update: kind status, id 1002, value "5"
  5. 튜토리얼 호스트에서 values 1001 1002 → 마지막 값이 b1 04 00 00 00 05로 바뀝니다.

MCP 서버 설정과 도구 목록은 시뮬레이터 MCP 서버에서 설명합니다.

실패 상황을 미리 만들어 보면 실제 장비에서 같은 증상을 만났을 때 원인을 빨리 찾을 수 있습니다. 각 실험이 끝나면 프로그램을 모두 종료하고 다음 실험을 시작합니다.

장비 없이 호스트만 실행합니다.

터미널 창
"$PDCOMM_ROOT/build/pdcomm-tutorial" host active 127.0.0.1:5010

몇 초 뒤 state를 입력하면 STATE tcp=5 gem=0이 나옵니다. 5는 RetryWait입니다. 호스트는 연결이 거부될 때마다 T5(튜토리얼은 1초)만큼 기다렸다가 다시 연결합니다. quit으로 끝냅니다.

같은 주소로 장비 두 개를 시작합니다. 두 번째 장비는 바로 PDComm native operation failed를 출력하고 종료 코드 1로 끝납니다. C# 예제에서는 상태 이름 IoError가 함께 나옵니다.

HSMS 포트가 이미 사용 중이라는 내용이 활동 로그에 표시된 시뮬레이터 화면HSMS 포트가 이미 사용 중이라는 내용이 활동 로그에 표시된 시뮬레이터 화면

시뮬레이터 GUI를 Equipment, Passive - listen, 127.0.0.1:5000으로 시작하되 Session ID는 기본값 0으로 둡니다. 튜토리얼 호스트(세션 ID 7)로 연결해 establish를 입력합니다. 연결과 Select는 성공하지만(STATE tcp=4) 5초(T3) 뒤에 RESULT kind=3 request=1 outcome=0이 나옵니다. 세션 ID가 맞지 않는 데이터 메시지는 상대가 처리하지 않기 때문입니다.

상대가 응답하지 않을 때: T3 타임아웃

섹션 제목: “상대가 응답하지 않을 때: T3 타임아웃”

장비와 호스트를 연결하고 establish까지 실행합니다. 세 번째 터미널에서 장비 프로세스를 일시 정지합니다.

터미널 창
kill -STOP "$(pgrep -f 'pdcomm-tutorial equipment passive 127.0.0.1:5000')"

호스트에서 values 1 2를 입력하면 5초 뒤 RESULT kind=3 request=3 outcome=0이 나옵니다. 장비를 다시 실행합니다.

터미널 창
kill -CONT "$(pgrep -f 'pdcomm-tutorial equipment passive 127.0.0.1:5000')"

장비는 밀린 S1F3에 뒤늦게 응답합니다. 호스트는 이미 끝난 트랜잭션의 응답이므로 받지 않고, 연결은 Selected로 유지됩니다. 다음 values 1 2는 정상으로 끝납니다. 이 과정을 로그로 확인하는 방법은 실패 진단과 문의에서 다룹니다.

C# 호스트로 튜토리얼 장비에 alarms를 보냅니다. 장비는 알람 카탈로그가 없으므로 요청을 처리하지 않고 ABORT S5F0 for S5F5로 트랜잭션을 중단합니다. 호스트는 T3를 기다리지 않고 바로 RESULT kind=3 request=13을 받습니다. 자세한 설명은 첫 통신의 7단계에 있습니다.

터미널 창
"$PDCOMM_SIMULATOR/pdcomm-simulator-headless" --scenario transport-backpressure-recovery --transport-fault-profile write_backpressure

출력의 second-send-limit-exceeded에서 송신이 한도 초과로 거부되고, transport-fault-released 뒤 retry-send-accepted에서 같은 요청이 다시 받아들여집니다. GUI에서는 세션을 시작하기 전에 Overview의 Transport fault를 Write backpressure로 정하고, 통신이 수립된 뒤 Message Trace & Diagnostics의 Transport fault profile에서 Arm과 Release를 누릅니다.

  • GUI: Message Trace & Diagnostics에서 Export trace를 누르거나 File > **Export Trace…**로 JSON 파일을 저장합니다. 메시지 본문은 들어 있지 않습니다.
  • headless 프로젝트 모드: --trace-output <파일>로 추적을 저장합니다.
  • SDK 프로그램: PDCOMM_LOG 환경 변수로 JSON Lines 진단 로그를 남깁니다.
호스트 메시지 추적의 GEM 기록이 보이는 Message Trace & Diagnostics 화면호스트 메시지 추적의 GEM 기록이 보이는 Message Trace & Diagnostics 화면

실행 중인 튜토리얼 예제는 quit으로, GUI는 Stop 후 창을 닫아 끝냅니다. 일시 정지한 프로세스가 남아 있으면 kill -CONT로 다시 실행한 뒤 종료합니다. results 폴더는 필요 없으면 지웁니다.