
Test automatizzati per trovare bug logici e di performance nei sistemi di database.

SQLancer è uno strumento per testare automaticamente i Database Management System (DBMS) al fine di trovare bug nella loro implementazione. Ovvero, trova bug nel codice dell'implementazione del DBMS, piuttosto che nelle query scritte dall'utente. SQLancer ha trovato centinaia di bug in DBMS maturi e ampiamente conosciuti.
SQLancer affronta due sfide essenziali quando testa automaticamente i DBMS:
Community. Abbiamo uno Slack workspace per discutere di SQLancer e del testing dei DBMS in generale. In precedenza, SQLancer aveva un account su Twitter/X @sqlancer_dbms, che non è più mantenuto. Abbiamo un blog, che, al momento, contiene solo post di contributori del progetto Google Summer of Code.
Requisiti Minimi:
I seguenti comandi clonano SQLancer, creano un JAR e avviano SQLancer per testare SQLite utilizzando Non-optimizing Reference Engine Construction (NoREC):
git clone https://github.com/sqlancer/sqlancer
cd sqlancer
mvn package -DskipTests
cd target
java -jar sqlancer-*.jar --num-threads 4 sqlite3 --oracle NoREC
Esecuzione e terminazione. Se l'esecuzione stampa informazioni di avanzamento ogni cinque secondi, allora lo strumento funziona come previsto. La scorciatoia CTRL+C può essere utilizzata per terminare SQLancer manualmente. Se SQLancer non trova alcun bug, viene eseguito all'infinito. L'opzione --num-tries può essere utilizzata per controllare dopo quanti bug SQLancer termina. In alternativa, l'opzione --timeout-seconds può essere utilizzata per specificare la durata massima consentita di esecuzione di SQLancer.
Parametri. Se si avvia SQLancer senza parametri, vengono visualizzate le opzioni e i comandi disponibili. Si noti che le opzioni generali supportate da tutte le implementazioni di test DBMS (ad esempio, --num-threads) devono precedere il nome del DBMS da testare (ad esempio, sqlite3). Le opzioni supportate solo per DBMS specifici (ad esempio, --test-rtree per SQLite3), o le opzioni per cui ogni implementazione di test fornisce valori diversi (ad esempio --oracle NoREC) devono andare dopo il nome del DBMS.
DBMS. Per eseguire SQLancer su SQLite, non è stato necessario installare e configurare un DBMS. Il motivo è che i DBMS embedded vengono eseguiti nello stesso processo dell'applicazione e quindi non richiedono un'installazione o una configurazione separate. I DBMS embedded supportati da SQLancer includono DuckDB, H2 e SQLite. I loro binari sono inclusi come dipendenze JAR. Si noti che eventuali crash in questi sistemi causeranno anche un crash nella JVM su cui viene eseguito SQLancer.
Log. SQLancer memorizza i log nella sottodirectory target/logs. Per impostazione predefinita, l'opzione --log-each-select è abilitata, il che comporta la registrazione di ogni istruzione SQL inviata al DBMS. I nomi dei file corrispondenti hanno il suffisso -cur.log. Inoltre, se SQLancer rileva un bug logico, crea un file con estensione .log, in cui vengono registrate le istruzioni per riprodurre il bug, includendo solo l'ultima query eseguita insieme alle altre istruzioni per impostare lo stato del database.
Riduzione dei bug. Dopo aver trovato un input di test che induce un bug, l'input deve tipicamente essere ridotto per essere ulteriormente analizzato, poiché potrebbe contenere molte istruzioni SQL ridondanti per riprodurre il bug. Un'opzione è farlo manualmente, rimuovendo un'istruzione o una funzionalità alla volta, rieseguendo le istruzioni che inducono il bug e applicando il test oracle (ad esempio, per test oracle come TLP o NoREC, ciò richiederebbe di verificare che entrambe le query producano ancora un risultato diverso). Questo processo può essere automatizzato utilizzando un cosiddetto approccio di delta-debugging. SQLancer include un'implementazione sperimentale di un approccio di delta debugging, che può essere abilitata utilizzando --use-reducer. In passato, abbiamo utilizzato con successo C-Reduce, che richiede di specificare il test oracle in uno script che può essere eseguito da C-Reduce.