- SQLite는 철저한 자동화 테스트 체계를 통해 높은 신뢰성과 견고성을 유지하며, 코드보다 590배 많은 테스트 코드가 존재함
- 네 가지 독립 테스트 하니스(TCL, TH3, SQL Logic Test, dbsqlfuzz) 가 핵심 라이브러리를 검증하며, 수억 건의 테스트를 수행
-
이상 상황 테스트(OOM, I/O 오류, 크래시 시뮬레이션) 와 퍼즈 테스트(fuzz testing) 를 통해 비정상 입력과 시스템 장애에도 안정적으로 동작함을 확인
-
100% 분기 및 MC/DC 커버리지, 리소스 누수 검출, Valgrind·정적 분석·체크리스트 등 다층적 검증 절차를 유지
- 이러한 체계적 테스트 덕분에 SQLite는 상용 DB 수준의 신뢰성과 품질을 확보한 오픈소스 데이터베이스로 평가됨
1. 개요
- SQLite의 신뢰성과 견고성은 세밀한 테스트 과정에서 비롯됨
- 버전 3.42.0 기준, SQLite는 약 155.8 KSLOC의 C 코드와 92053.1 KSLOC의 테스트 코드로 구성
- 테스트 체계는 4개의 독립 하니스, 100% 분기 커버리지, 수백만 건의 테스트 케이스를 포함
- OOM, I/O 오류, 크래시, 퍼즈, 경계값, 회귀, 비정상 DB 파일, 최적화 비활성화 테스트 등 다수 항목 포함
2. 테스트 하니스
-
TCL Tests
- SQLite 개발 중 주로 사용되는 공개 테스트 세트
- 27.2 KSLOC의 C 코드와 1390개 스크립트 파일(23.2MB)로 구성
- 약 5만여 개 테스트 케이스, 매개변수화로 전체 실행 시 수백만 건 수행
-
TH3
- 상용 C 기반 테스트 세트로 100% 분기 및 MC/DC 커버리지 달성
- 임베디드 환경에서도 동작하며, 1055.4 KSLOC·약 5만여 케이스 포함
- 전체 커버리지 테스트 시 약 2.4백만 건, 릴리스 전 2.48억 건 soak 테스트 수행
-
SQL Logic Test (SLT)
- SQLite와 PostgreSQL, MySQL, SQL Server, Oracle 10g 결과를 비교
-
7.2백만 쿼리, 1.12GB 데이터로 구성
-
dbsqlfuzz
- SQL과 데이터베이스 파일을 동시에 변형하는 libFuzzer 기반 퍼저
- 하루 약 10억 번의 변이 테스트 수행, 악의적 입력에 대한 견고성 검증
-
추가 도구
- speedtest1.c, mptester.c, threadtest3.c, fuzzershell.c, jfuzz 등
- 모든 테스트는 다중 플랫폼·컴파일 설정에서 통과해야 릴리스 가능
3. 이상 상황 테스트
-
OOM 테스트
- malloc() 실패를 시뮬레이션하여 메모리 부족 시 정상 복구 여부 검증
- 실패 시점 카운터를 증가시키며 반복 수행
-
I/O 오류 테스트
- 가상 파일 시스템(VFS)을 이용해 디스크 오류를 시뮬레이션
- 오류 후 PRAGMA integrity_check로 데이터 손상 여부 확인
-
크래시 테스트
- 전원 차단·OS 크래시 상황을 시뮬레이션
- TCL 하니스는 자식 프로세스 기반, TH3는 메모리 기반 VFS 사용
- 트랜잭션의 완전 롤백 또는 완전 완료 여부 검증
-
복합 실패 테스트
- 크래시 후 OOM 또는 I/O 오류가 연속 발생하는 상황까지 검증
4. 퍼즈 테스트
-
SQL Fuzz
- 문법적으로 유효하지만 비정상적인 SQL을 생성해 SQLite 반응 검증
-
American Fuzzy Lop (AFL)
- 2014년 도입된 프로파일 기반 퍼저로, 새로운 제어 경로를 탐색
- SQLite의 assert 실패·크래시·잘못된 결과를 다수 발견
-
Google OSS Fuzz
- 2016년부터 Google 인프라에서 자동 퍼징 수행
- 신규 커밋에서 간헐적 문제를 탐지
-
dbsqlfuzz / jfuzz
- 2018년 이후 내부 퍼저로 도입, SQL과 DB 파일 동시 변이
- 하루 5억 건 이상 테스트, 외부 퍼저의 버그 리포트 거의 소멸
- 2024년부터 jfuzz가 JSONB 입력 검증 추가
-
타사 퍼저 및 fuzzcheck
- 외부 연구자(예: Manuel Rigger)가 잘못된 결과 계산 사례 다수 발견
- fuzzcheck 유틸리티가 과거 퍼즈 케이스 중 ‘흥미로운’ 수천 건을 재검증
-
MC/DC와 퍼즈 테스트의 긴장 관계
- MC/DC는 방어 코드 최소화, 퍼즈는 방어 코드 필요
- SQLite는 두 접근을 병행해 정상·악의적 입력 모두에 견고한 코드 유지
5. 회귀 테스트
- 보고된 버그는 수정 후 반드시 새 테스트 케이스로 추가
6. 자동 리소스 누수 검출
- TCL·TH3 하니스가 메모리·파일·스레드·뮤텍스 누수 자동 감시
- OOM·I/O 오류 후에도 메모리 누수가 없어야 함
7. 테스트 커버리지
8. 동적 분석
9. 최적화 비활성화 테스트
-
sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS)으로 최적화 끄기
- 최적화 유무에 관계없이 동일 결과를 산출해야 함
- 일부 성능 측정용 테스트는 예외
10. 체크리스트
- 릴리스 전 약 200개 항목의 수동 체크리스트 검증
- 일부는 수초, 일부는 수시간 소요
- 문제 발견 시 즉시 항목 추가, 지속적 개선
11. 정적 분석
- GCC·Clang·MSVC에서 경고 없이 컴파일
- Clang Static Analyzer에서도 유효 경고 없음
- 정적 분석은 실제 버그 탐지 효과가 제한적
12. 요약
- SQLite는 오픈소스임에도 상용 수준의 품질과 낮은 결함률을 유지
- 철저한 테스트와 코드 설계가 핵심 요인
- 모든 릴리스는 위 절차를 거쳐 미션 크리티컬 환경에서도 신뢰 가능한 DB 엔진으로 제공됨