24 puan yazan GN⁺ 2025-12-19 | 4 yorum | WhatsApp'ta paylaş
  • SQLite, son derece kapsamlı bir otomatik test sistemi sayesinde yüksek güvenilirlik ve dayanıklılık sağlıyor; koddan 590 kat fazla test kodu bulunuyor
  • Dört adet bağımsız test harness’i (TCL, TH3, SQL Logic Test, dbsqlfuzz) çekirdek kütüphaneyi doğruluyor ve yüz milyonlarca test çalıştırıyor
  • Anormal durum testleri (OOM, I/O hataları, çökme simülasyonu) ve fuzz testing ile, olağandışı girdiler ve sistem arızaları altında da kararlı çalıştığı doğrulanıyor
  • %100 branch ve MC/DC coverage, kaynak sızıntısı tespiti, Valgrind·statik analiz·checklist gibi çok katmanlı doğrulama süreçleri sürdürülüyor
  • Bu sistematik test yaklaşımı sayesinde SQLite, ticari veritabanı düzeyinde güvenilirlik ve kaliteye sahip bir açık kaynak veritabanı olarak değerlendiriliyor

1. Genel bakış

  • SQLite’ın güvenilirliği ve dayanıklılığı, ayrıntılı test süreçlerinden kaynaklanıyor
    • Sürüm 3.42.0 itibarıyla SQLite, yaklaşık 155.8 KSLOC C kodu ve 92053.1 KSLOC test kodundan oluşuyor
  • Test sistemi; 4 bağımsız harness, %100 branch coverage ve milyonlarca test vakasını içeriyor
    • OOM, I/O hatası, çökme, fuzz, sınır değer, regresyon, bozuk DB dosyaları, optimizasyon devre dışı testleri gibi çok sayıda başlık dahil

2. Test harness’leri

  • TCL Tests
    • SQLite geliştirme sürecinde ağırlıklı olarak kullanılan, herkese açık test seti
    • 27.2 KSLOC C kodu ve 1390 script dosyasından (23.2MB) oluşuyor
    • Yaklaşık 50 bin test vakası içeriyor; parametreleştirme ile tam çalıştırmada yüz milyonlarca test yapılıyor
  • TH3
    • Ticari C tabanlı test seti; %100 branch ve MC/DC coverage sağlıyor
    • Gömülü ortamlarda da çalışıyor; 1055.4 KSLOC ve yaklaşık 50 bin vaka içeriyor
    • Tam coverage testinde yaklaşık 2.4 milyon, sürüm öncesinde ise 248 milyon soak test yürütülüyor
  • SQL Logic Test (SLT)
    • SQLite sonuçlarını PostgreSQL, MySQL, SQL Server ve Oracle 10g ile karşılaştırıyor
    • 7.2 milyon sorgu ve 1.12GB veriden oluşuyor
  • dbsqlfuzz
    • SQL ile veritabanı dosyalarını aynı anda mutasyona uğratan libFuzzer tabanlı bir fuzzer
    • Günde yaklaşık 1 milyar mutasyon testi çalıştırıyor; kötü niyetli girdilere karşı dayanıklılığı doğruluyor
  • Ek araçlar
    • speedtest1.c, mptester.c, threadtest3.c, fuzzershell.c, jfuzz vb.
    • Tüm testlerin çoklu platform ve derleme yapılandırmalarında geçmesi gerekiyor; ancak o zaman sürüm yayımlanabiliyor

3. Anormal durum testleri

  • OOM testleri
    • malloc() başarısızlığı simüle edilerek, bellek yetersizliği durumunda düzgün toparlanıp toparlanmadığı doğrulanıyor
    • Hata anı sayacı artırılarak test tekrar tekrar çalıştırılıyor
  • I/O hata testleri
    • Sanal dosya sistemi (VFS) kullanılarak disk hataları simüle ediliyor
    • Hata sonrası PRAGMA integrity_check ile veri bozulması olup olmadığı kontrol ediliyor
  • Çökme testleri
    • Güç kesintisi ve OS çökmesi senaryoları simüle ediliyor
    • TCL harness’i child process tabanlı, TH3 ise bellek tabanlı VFS kullanıyor
    • Transaction’ın ya tamamen rollback olması ya da tamamen tamamlanması gerektiği doğrulanıyor
  • Birleşik hata testleri
    • Çökme sonrasında OOM veya I/O hatalarının art arda yaşandığı senaryolar da test ediliyor

4. Fuzz testleri

  • SQL Fuzz
    • Sözdizimi açısından geçerli ama olağandışı SQL üreterek SQLite’ın tepkisi doğrulanıyor
  • American Fuzzy Lop (AFL)
    • 2014’te devreye alınan, profile tabanlı bir fuzzer; yeni kontrol yollarını keşfediyor
    • SQLite’ta çok sayıda assert hatası, çökme ve yanlış sonuç buldu
  • Google OSS Fuzz
    • 2016’dan beri Google altyapısında otomatik fuzzing yürütüyor
    • Yeni commit’lerde aralıklı ortaya çıkan sorunları tespit ediyor
  • dbsqlfuzz / jfuzz
    • 2018’den sonra kurum içi fuzzer olarak devreye alındı; SQL ve DB dosyalarını birlikte mutasyona uğratıyor
    • Günde 500 milyondan fazla test yapılıyor; dış fuzzer’lardan gelen bug raporları neredeyse yok oldu
    • 2024’ten itibaren jfuzz, JSONB girdileri için ek doğrulama yapıyor
  • Üçüncü taraf fuzzer’lar ve fuzzcheck
    • Harici araştırmacılar (ör. Manuel Rigger), çok sayıda yanlış sonuç hesaplama örneği buldu
    • fuzzcheck yardımcı aracı, geçmiş fuzz vakaları arasındaki “ilginç” binlerce örneği yeniden doğruluyor
  • MC/DC ile fuzz testleri arasındaki gerilim
    • MC/DC, savunma kodunu en aza indirmeyi; fuzz ise savunma koduna ihtiyaç duyulmasını teşvik ediyor
    • SQLite, bu iki yaklaşımı birlikte kullanarak hem normal hem kötü niyetli girdilere karşı dayanıklı kod sürdürüyor

5. Regresyon testleri

  • Bildirilen her hata, düzeltildikten sonra mutlaka yeni bir test vakası olarak ekleniyor
    • Amaç, geçmişteki hataların tekrar ortaya çıkmasını önlemek

6. Otomatik kaynak sızıntısı tespiti

  • TCL ve TH3 harness’leri; bellek, dosya, thread ve mutex sızıntılarını otomatik olarak izliyor
    • OOM ve I/O hatalarından sonra bile bellek sızıntısı olmamalı

7. Test coverage

  • SQLite çekirdeği, TH3'e göre %100 branch coverage sağlıyor
    • FTS3, RTree gibi eklentiler hariç
  • Statement vs Branch Coverage
    • Branch coverage, statement coverage’dan daha katıdır; tüm koşul dallarını iki yönde de doğrular
  • Savunma kodu coverage
    • ALWAYS(), NEVER() makrolarıyla savunma koşulları açıkça belirtiliyor
    • Üç farklı tanım biçimiyle testler tekrarlanarak tutarlılık doğrulanıyor
  • Sınır değer ve boolean vector testleri
    • testcase() makrosu ile koşulların hem doğru hem yanlış sonuçları doğrulanıyor
    • 1184 adet testcase() kullanılıyor
  • MC/DC sağlanması
    • testcase() makrosu sayesinde tüm koşulların bağımsız etkisi doğrulanıyor
  • gcov tabanlı ölçüm
    • Coverage, -fprofile-arcs -ftest-coverage seçenekleriyle ölçülüyor
    • Sonuç karşılaştırmaları üzerinden compiler bug’ları veya tanımsız davranış tespit ediliyor
  • Mutation Testing
    • Branch komutları değiştirilerek testlerin bunu yakalayıp yakalamadığı kontrol ediliyor
    • Optimizasyon branch’leri (/*OPTIMIZATION-IF-TRUE*/) istisna olarak ele alınıyor
  • Tam coverage deneyimi
    • Tüm branch’lerin test edilmesi sayesinde, kod değişikliklerinde yan etki en aza indiriliyor
    • Bakım maliyeti yüksek olsa da, geniş çapta dağıtılan bir altyapı kütüphanesi için bu yaklaşım haklı görülüyor

8. Dinamik analiz

  • Assert()
    • 6754 adet assert ifadesiyle ön/son koşullar ve döngü değişmezleri doğrulanıyor
    • Yalnızca SQLITE_DEBUG build’lerinde etkin
  • Valgrind
    • Bellek hataları, stack overflow ve ilklendirilmemiş bellek erişimi tespit ediliyor
    • Sürüm öncesinde veryquick ve TH3 testleri Valgrind ile çalıştırılıyor
  • Memsys2
    • SQLITE_MEMDEBUG build’inde, bellek hatalarını izlemek için wrapper ekleniyor
    • Valgrind’e göre daha hızlı yinelenen doğrulama yapılabiliyor
  • Mutex Asserts
    • sqlite3_mutex_held() vb. ile çoklu thread senkronizasyonu doğrulanıyor
  • Journal Tests
    • Rollback journal’ın DB’den önce yazılıp yazılmadığı kontrol edilerek transaction atomikliği güvence altına alınıyor
  • Undefined Behavior Checks
    • -ftrapv, -fsanitize=undefined, /RTC1 vb. ile tanımsız davranış tespit ediliyor
    • 32/64 bit, endian farkları ve çeşitli CPU mimarilerinde tekrar tekrar yürütülüyor

9. Optimizasyon devre dışı testleri

  • sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS) ile optimizasyonlar kapatılıyor
    • Optimizasyon açık ya da kapalıyken aynı sonuçların üretilmesi gerekiyor
    • Bazı performans ölçüm testleri istisna

10. Checklist

  • Sürüm öncesinde yaklaşık 200 maddelik manuel checklist doğrulanıyor
    • Bazıları birkaç saniye, bazıları ise birkaç saat sürüyor
    • Sorun bulunduğunda ilgili madde hemen ekleniyor; süreç sürekli iyileştiriliyor

11. Statik analiz

  • GCC, Clang ve MSVC üzerinde uyarı olmadan derleniyor
    • Clang Static Analyzer’da da geçerli uyarı yok
    • Statik analizin gerçek hata bulma etkisi sınırlı kabul ediliyor

12. Özet

  • SQLite, açık kaynak olmasına rağmen ticari düzeyde kalite ve düşük hata oranını koruyor
    • Bunun temel nedeni, son derece titiz testler ve kod tasarımı
    • Her sürüm, yukarıdaki süreçlerden geçirilerek mission-critical ortamlarda bile güvenilebilecek bir DB engine olarak sunuluyor

4 yorum

 
regentag 2025-12-19

Birlikte okumaya değer yazı: SQLite'in bilinmeyen hikayesi

Bu, SQLite geliştiricisi Richard Hipp ile yapılan röportajı özetleyen bir yazıdır.

SQLite geliştiricilerinin, Rockwell Collins'te çalıştıkları dönemde Do-178 ile tanıştıkları ve bu prosedürü izlemeye başladıkları söyleniyor. Bunlardan biri de %100 MC/DC'ye ulaşmak.

Do-178 gerçekten çok kullanışlı bir kılavuzdur; bu yüzden geliştiriciyseniz herkesin okumasını tavsiye ederim.

 
regentag 2025-12-19

Paylaştığınız bağlantı sanırım bir DO-178 eğitim materyali.
Asıl belgeye şu bağlantıdan bakabilirsiniz.
https://studylib.net/doc/27132454/rtca-do-178b

 
GN⁺ 2025-12-19
Hacker News yorumları
  • Yaklaşık 10 yıl önce SQLite’ın bakımcısı OSCON’da test uygulamaları hakkında bir sunum yapmıştı
    Özellikle etkileyici olan şey kontrol listesi (checklist) gücüydü. Pilotların her uçuş öncesi kullandığı aracın aynısı
    Ayrıca Sınır Tanımayan Doktorlar (Doctors Without Borders) örneğini de vermişti; sağlık çalışanları birbirlerinin adını bilmiyor ve farklı diller konuşuyordu, bu yüzden ameliyat sonuçları düşüktü
    Çözüm basitti — ameliyat öncesi bir kontrol listesi hazırlayıp herkesin adını ve rolünü söylemesini sağlamak. Bu küçük ritüelin, teknik değil iletişimi iyileştirerek hayatta kalma oranını artırdığı söylenmişti
    İlgili kaynak: SQLite checklist örneği

    • Buna karşılık, bu tür hikâyelerin gereksiz bürokrasi ürettiğini düşünüyorum. Havacılık, MSF ve SQLite’taki kontrol listeleri harika, ama çoğu kuruluş işe yaramaz kontrol listeleriyle zaman kaybediyor
      İyi kontrol listesi ile kötü kontrol listesi arasındaki fark hakkında daha fazla tartışma gerek. Matematikteki güzel formüller gibi, basit görünüyor ama keşfetmesi zor
    • Uzun zamandır havacılık operasyonları ve mühendislikten öğrenilecek çok şey olduğunu düşünüyorum. Bu ilkeleri askeri tarz liderlikle birleştiren bir BT organizasyonu hayal ediyorum
      Özellikle ABD Ordusu’nun FM22-100 belgesini birkaç kez okudum; şaşırtıcı derecede modern ve ilham verici
      FM22-100 belgesine bakın
    • İyi kontrol listesi yapmayı öğrenmek istiyorsanız The Checklist Manifesto’yu şiddetle tavsiye ederim
      Kitap bağlantısı
    • Geliştiricilerin çoğunun programlama dışı basit işleri neden kaçındığını anlamıyorum
      Testler ve CI dışında, Markdown biçiminde bir dağıtım kontrol listesi de takip ediyorum. Sonuçları kaydetmiyorum bile ama adımları tek tek uyguluyorum
      İnsanların neden böyle basit bir şeyi yapmadığını anlamıyorum
    • Ritüellerin performansı artırması ilginç. Bugünlerde toplantılarda da katılımcı tanıtım turu yapıldığında katılımın belirgin şekilde arttığını görüyorum
      MSF örneğini ele alan resmî bir sayfa varsa gerçekten görmek isterim. Google’da aradım ama bulamadım
  • SQLite’ın testleriyle ilgili eski tartışmaları burada toplamışlar
    2009~2024 HN başlık listesi
    Yeniden paylaşımın her yıl tekrarlandığı anlaşılıyor

  • SQLite gibi bir yazılımı bu kadar kusursuzca cilalama sürecini hem kıskanıyor hem hayranlıkla izliyorum
    Gerçek bir zanaatkârlık hissi veriyor

    • Aslında bunu herkes yapabilir. Yavaş ama doğru üretmek yüzünden kimse işten çıkarılmaz
      Zamanla kalite standardınız yükselir ve aynı emekle daha büyük ödüller alırsınız
      El attığı yeri biraz daha temiz bırakan birinden kimse nefret etmez
  • SQLite gerçekten harika bir yazılım. Resmî web sitesinin de pazarlama yerine bilgi odaklı olması hoşuma gidiyor
    Yine de son dönemde HN’de resmî siteden sayfaların tek tek paylaşılması ilginç

    • Muhtemelen dün simonw’nin LLM portlama yazısı gündem olunca ilgili bağlantılar da yeniden dikkat çekti
    • HN’de bu tür şeyler periyodik olarak tekrar ediyor. Eskiden Haskell böyleydi, bugünlerde ise Zig bu döngüden geçiyor
      Böyle bağlantıları bir yerde toplamak eğlenceli olabilir
  • SQLite’ın açık yazılım olmasına rağmen kapalı testler kullanması ilginç
    Bir açık kaynak projenin kapalı testlere sahip olabileceğini ancak şimdi fark ettim
    Bu model, open-core benzeri yeni bir iş modeli bile olabilir

    • Gerçekte test paketi çoğu zaman koddan daha değerlidir. Örneğin Excel gibi bir yazılımın sayısız uç durumunu belgelemek, uygulamayı yazmaktan daha zor olabilir
    • Ben de şirket projelerinde benzer bir şey yapıyorum. GPL çift lisanslamayla birlikte testler ve veri üreticileri yalnızca ticari lisans kullanıcılarına açık oluyor
      Örnek: railgunlabs/unicorn lisansı
  • SQLite’ın %100 branch coverage değerine ulaşması, projenin kendisi kadar etkileyici
    Bunu sürekli koruyabilmeleri özellikle olağanüstü

  • Testlerin kapalı olması ilginç. LLM tabanlı kodlamanın geliştiği bugünlerde, testlerin implementasyondan daha önemli hâle geldiği bir döneme giriyoruz
    Kısa süre önce simonw’nin justHTML motorunu Python’dan JS’e neredeyse otomatik çevirdiği örneği görünce SQLite’ın test stratejisi aklıma geldi

    • Açık kaynak ürünlerin iş modeli açısından bakınca, kapsamlı test paketleri verimli değişiklik ve değer üretiminin temel varlığı hâline geliyor
    • SQLite’ın How SQLite Is Tested belgesi kelimenin tam anlamıyla testlerin incili gibi hissettiriyor
  • Yakın zamanda SQLite ile DuckDB arasındaki uyumluluğu düşünerek bir LLM ile tartıştım; eşzamanlılık işleme açısından SQLite’ın daha iyi olduğu sonucuna vardım

  • SQLite’ın test dokümanında performance regression hakkında az şey söylenmesine şaşırdım
    Doğruluk önemli, ama belirli sorgu yollarındaki performans düşüşleri de ölümcül olabilir

    • HFT alanında çalıştım ama performans garantisi vermeyi öne çıkaran neredeyse hiç açık kaynak proje görmedim
      Acaba bunu temel misyonu olarak benimseyen bir proje var mı diye merak ediyorum
  • SQLite’ın kararlılığına bakınca anomali testlerinin nasıl yapıldığı hakkında daha fazla şey öğrenmek istedim
    Ama yazıda buna neredeyse hiç değinilmemişti. Buna rağmen SQLite, her cihazda kullanılan en sağlam yazılımlardan biri olmaya devam ediyor

    • Test paketine erişim yıllık yaklaşık 150 bin dolar düzeyinde olduğundan, içeriği açıklamalarının pek olası olmadığını düşünüyorum