본문 바로가기
C.W.K.
Stream
Lesson 04 of 04 · published

검사는 다 통과했고 렌더는 망가져 있었어

~14 min · verification, limits, human-review, coverage

Level 0불 꺼진 작업장
0 XP0/35 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

방금 배운 규율의 한계

세 강의가 측정을 주장했어. 산출물을 재라, 절차를 믿지 마라. 시계를 의식적으로 골라라. 낡음이 벌어질 수 없게 캐시를 내용으로 키잡아라. 진짜 규율이고 진짜 결함을 잡아.

그다음 시험 운행이 그림이 소리보다 12 초쯤 앞서 가는 렌더를 실어 보냈고, 검증 단계가 그걸 통과시켰어.

무슨 일이 있었나

원인은 앞 강의의 그 실패 양상이었어. 내용 키잡이 수정, 그러니까 낡은 산출물을 구조적으로 불가능하게 만들기로 했던 그거. 그 키에 구멍이 있었거든. 출력을 바꿀 수 있는 입력이 다이제스트에 안 들어가 있었고, 그래서 고친 장면이 이미 있는 주소로 풀렸고, 캐시가 이전 판본을 내줬어. 그게 타임라인을 어긋나게 했고, 그림이 소리보다 12 초 앞서 나갔지.

이제 중요한 부분. 검증이 완성된 파일에 돌았고 통과했어. 전체 길이 맞았어. 음량 맞았고. 스트림 구성도 맞았어. 누군가 검사로 부호화할 생각을 한 성질은 전부 실제로 맞았어. 그리고 그 산출물은 못 쓰는 물건이었고.

구멍은 정확해. 그림 타임라인이랑 오디오 타임라인을 서로 견주는 검사가 없었어. 둘 다 자기 안에서는 일관됐거든. 망가진 건 그 둘의 관계였고, 두 물건 사이의 관계야말로 성질별 검사가 안 보는 바로 그거야.

일반적인 형태

검증은 누군가 예상한 결함이 산출물에 없다고 말해줘. 이게 맞다고는 말 못 해. 검사를 아무리 더 붙여도 범주가 안 바뀌고. 새 검사 하나는 예상 결함 목록에 하나를 더할 뿐이야. 그리고 아픈 실패는 항상 아무도 목록에 안 적은 그거고.

밑에 더 날카로운 교훈이 하나 더 있어. 이 결함은 수정이 만들어냈어. 내용 키잡이 작업은 좋은 이유로 한 옳은 개선이었고, 자기가 막으려고 설계된 바로 그 실패를, 기존 검사한테 안 보이는 형태로 들여왔어. 위험 한 종류를 줄이는 변경이 다른 종류를 만들어내는 건 흔한 일이야. 그리고 새로 생긴 쪽은 감시가 안 돼. 감시를 설계할 당시에 존재하지 않았다는 이유로 정확히.

검사는 성질을 확인하고, 물건을 확인하는 건 사람뿐이야. 측정하지 말자는 얘기가 아냐. 이 파이프라인 결함 대부분을 측정이 잡았고, 그래서 사람 통과에 볼 게 남아 있는 거니까. 초록색 실행 하나를 충분한 걸로 취급하지 말자는 얘기야. 마지막 관문은 누군가 그 산출물을 보는 거고, 규율은 전부 통과일 때도, 특히 전부 통과일 때 그 관문을 지키는 거야.

Code

검증기, 그리고 그게 한 번도 안 던진 질문·python
def stage_validate(ep: Path) -> None:
    out = ep / "out" / "episode.mp4"

    dur = probe_duration(out)
    assert abs(dur - expected_total(ep)) < 0.10       # PASSED

    lufs = measure_loudness(out)
    assert -16.5 <= lufs <= -13.0                     # PASSED

    streams = probe_streams(out)
    assert stream_layout(streams) == ["video", "audio"]  # PASSED

    # ...and the render was 12 seconds out of sync.
    #
    # Every assertion above examines ONE property in isolation.
    # The defect lived in the RELATIONSHIP between two of them:
    #   where the picture timeline says scene N starts, versus
    #   where the audio timeline says segment N starts.
    #
    # The check that would have caught it, added afterward:
    for n, (pic_t, aud_t) in enumerate(zip(picture_cues(ep), audio_cues(ep))):
        if abs(pic_t - aud_t) > 0.20:
            raise Desync(f"cue {n}: picture {pic_t:.2f}s vs audio {aud_t:.2f}s")

    # Note that this check exists BECAUSE the failure happened.
    # It could not have been written in advance by someone who had
    # not yet seen a desynchronized render - which is the whole point.

External links

Exercise

네가 내보내는 것의 검증을 열어서, 검사 하나하나를 성질별이랑 성질 사이로 나눠봐. 대부분의 묶음이 전부 앞쪽일 거야. 그다음 네 산출물에서 서로 일치해야 하는 성질 둘을 골라서, 그걸 견주는 검사를 써봐. 개수랑 그게 세는 항목들, 시각이랑 그게 서술하는 사건, 합계랑 그 구성 요소들.
Hint
제일 풍부한 원천은 두 시스템이 같은 사실을 각자 뽑아내는 자리야. 둘 다 자기 안에선 맞으면서 서로 안 맞을 수 있고, 어느 한쪽만 보는 검사는 절대 못 알아채. 12 초 어긋남의 형태가 정확히 그거였고.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.