문서가 실패할 때: AI를 이용한 브루트포스 스펙 탐색

발행: (2025년 12월 23일 오후 11:00 GMT+9)
6 분 소요
원문: Dev.to

Source: Dev.to

문제: 문서화되지 않은 동작

ksqlDB에서 Apache Flink SQL로 LINQ‑기반 쿼리 라이브러리를 포팅해야 했습니다.

문제는 코드가 아니라, 두 플랫폼 모두 어떤 것이 동작하고 어떤 것이 동작하지 않으며, 실패했을 때 어떤 대안이 있는지 완전히 문서화하지 않았다는 점이었습니다.

  • ksqlDB에는 LEN(s)가 있습니다. Flink에는 없으며 CHAR_LENGTH(s)를 사용합니다.
  • ksqlDB에는 DATEADD가 있습니다. Flink는 TIMESTAMPADD 또는 인터벌 연산을 사용합니다.
  • ksqlDB의 JSON_EXTRACT_STRING은 Flink의 JSON_VALUE가 됩니다.
  • 일부 함수는 양쪽에 존재하지만 동작 방식이 다릅니다.

문서는 정상적인 경우만 다룹니다. 실제 운영에서는 전체 매핑이 필요합니다.

인간적인 접근 방식: 지속 불가능

수동 테스트는 다음과 같이 진행됩니다:

  1. 함수 선택
  2. 테스트 쿼리 작성
  3. Flink에서 실행
  4. 성공/실패 기록
  5. 실패 시 대안 검색
  6. 모든 함수 × 데이터 타입 × 절(Clause) 조합에 대해 반복

50개 이상의 함수, 10개 이상의 데이터 타입, 그리고 5개의 절(SELECT, WHERE, GROUP BY, HAVING, JOIN) 조합을 고려하면 수천 개의 조합이 됩니다.

  • 소요 시간: 몇 주.
  • 필요한 인내: 초인적.

AI 접근법: 무차별 탐색

AI에게 간단한 지시를 내렸다:

  • Flink SQL에서 사용할 수 있는 쿼리를 조사한다.
  • 데이터 타입과 함수의 조합을 테스트한다.
  • SELECT, WHERE, GROUP BY, HAVING, 그리고 JOIN을 포함한다.

상세한 테스트 계획도, 경우의 수 열거도 없었다. AI는 조합을 생성하고 Dockerized Flink 환경에서 실행해 결과를 기록했으며, 실패가 발생하면 대안을 탐색했다.

결과: 방언 매핑

체계적인 탐색 후, 포괄적인 매핑이 도출되었습니다:

함수ksqlDBFlink상태
String lengthLEN(s)CHAR_LENGTH(s)ksqlDB 형식 NG
String splitSPLIT(s, d)SPLIT_INDEX(s, d, i)ksqlDB 형식 NG
Date addDATEADD(unit, n, ts)TIMESTAMPADD(UNIT, n, ts)ksqlDB 형식 NG
JSON extractJSON_EXTRACT_STRINGJSON_VALUEksqlDB 형식 NG
Regex matchREGEXP_LIKESIMILAR TOksqlDB 형식 NG
PaddingLPAD/RPADLPAD/RPADOK
Null handlingCOALESCE/NULLIFCOALESCE/NULLIFOK
Safe castN/ATRY_CASTFlink 전용

문서에 언급되지 않은 엣지 케이스

  • JSON_QUERY는 특정 환경에서 배열 요소 접근 시 NULL을 반환합니다.
  • LIKE 절에서 ESCAPE '\\'가 실패합니다; 대신 ESCAPE '^'를 사용하세요.
  • 배열 인덱싱은 1‑기반이며, arr[0]은 오류를 발생시킵니다.
  • SESSION 윈도우는 스트리밍 모드에서는 동작하지만 배치에서는 실패합니다.
  • 예약어를 별칭으로 사용하면(예: AS Values) 구문 오류가 발생합니다.

Speed: The Decisive Advantage

ApproachTimeCoverage
ManualWeeksPartial, fatigue‑limited
AI‑drivenHoursExhaustive

AI는 피곤하지 않는다. AI는 금요일 오후라서 가장자리 경우를 건너뛰지 않는다. AI는 첫 번째와 같은 성실함으로 JSON 함수 테스트의 47번째 변형을 실행한다. 속도 이점은 점진적인 것이 아니라 범주적이다.

What This Changes

전통적인 E2E 테스트는 사양을 알고 구현을 검증한다고 가정합니다. 이는 모델을 뒤집습니다: E2E를 사양 발견으로. 외부 시스템의 문서가 불완전할 때, AI‑powered brute‑force testing이 실제 상황을 파악하는 가장 빠른 경로가 됩니다.

인간 역할

AI가 조합 폭발을 처리했다. 나의 역할은:

  • 축 정의: data types, functions, clause contexts
  • 환경 제공: Dockerized Flink for execution
  • 결과 판단: OK/NG/alternative mappings
  • 디자인 결정: which patterns to support, which to fail‑fast

이러한 발견은 내 라이브러리의 방언 추상화 레이어에 직접 반영되었습니다—ksqlDB와 Flink가 정확히 어디서 차이 나는지 알면 런타임 서프라이즈가 아닌 컴파일 타임에 깔끔한 분리를 할 수 있습니다.

결론

문서화가 실패하면, 무차별적인 시도가 승리합니다. AI는 E2E 테스트를 검증 활동에서 탐색 활동으로 전환합니다. 인간이 모든 경우를 테스트하는 것이 불가능하게 만드는 조합 폭발은 AI에게는 자연스러운 작동 모드가 됩니다.

이 테스트 접근 방식은 여러 SQL 방언을 지원하는 쿼리 추상화 레이어인 Kafka.Context.Streaming을 만들면서 개발되었습니다.

Back to Blog

관련 글

더 보기 »