Ich möchte automatisch testen, ob eine Software wie erwartet reagiert, wenn eine wichtige SQLite-DB-Datei nicht gelesen werden kann (was zu einem E / A-Fehler führt). Genau das ist vor einigen Tagen bei einem Kunden passiert. Wir haben es manuell behoben, aber jetzt möchte ich automatischen Code erstellen, um es zu beheben, und brauche Zugriff auf eine beschädigte Datei, um dies zu testen.
Da alles in Unix eine Datei ist, vermutete ich, dass es eine spezielle Datei geben könnte, die immer I / O-Fehler verursacht, wenn man versucht, sie zu lesen (zB in / dev).
Einige ähnliche Dateien (imo) wären:
/dev/full
die immer "No space left on device" sagt, wenn Sie versuchen, es zu schreiben/dev/null
und/dev/zero
Ich nahm also an, dass es nur eine solche Datei geben muss (aber noch keine gefunden hat).
Kennt jemand eine solche Datei oder eine andere Methode, mit der ich das gewünschte Ergebnis erzielen kann (ein absichtlich fehlerhaftes Partitionsimage, ein Wrapper um open () mit LD_PRELOAD, ...)?
Was ist der beste Weg, um hierher zu kommen?
Antworten:
Mit können Sie
dmsetup
ein Device-Mapper-Gerät erstellen, indem Sie entweder die Zieleerror
oderflakey
verwenden, um Fehler zu simulieren.Wobei 123 die Länge des Geräts ist und / dev / loop0 das ursprüngliche Gerät ist, auf dem Sie Fehler simulieren möchten. Für einen Fehler benötigen Sie die nachfolgenden Argumente nicht, da immer ein Fehler zurückgegeben wird.
quelle
dmsetup table test
. Sie können sogarfoo bar
dahinter schreibenerror
; es ist einfach egal (und sollte daher gelöscht werden).Bei Stack Overflow und Server Fault gibt es bereits eine Reihe von Antworten darauf, aber es fehlten einige Techniken. Um Ihnen das Leben zu erleichtern, finden Sie hier eine Liste der I / O-Fehlerinjektionsmechanismen für VM / Linux-Blockgeräte / Linux-Dateisysteme / Linux-Userspace-Bibliotheken:
--layout
Informationen zur Konfiguration finden Sie in der Option auf der Manpage zu mdadm (Kernel- und mdadm-Userspace-Bits).LD_PRELOAD
).FAIL_MAKE_REQUEST=y
).BLK_DEV_NULL_BLK_FAULT_INJECTION=y
).delay
oder bereitgestellt wird,error
und hängen Sie ein Blockgerät übernbd-client
(Kernel + NBD-Benutzerbereichsbits, Kernel> = 4.18 mit NBD-Unterstützung, nbdclient> = 3.18 und nbdkit> an = 1.8.1 empfohlen - siehe NBDKit-Demo-Video um die 20-Minuten-Marke).Vorteil: SQLite verfügt über einen VFS-Treiber zum Simulieren von Fehlern , um eine gute Testabdeckung zu erzielen.
Verbunden:
quelle
Sie möchten einen Fehlerinjektionsmechanismus für E / A.
Unter Linux erfordert die folgende Methode keine vorherige Einrichtung und generiert einen ungewöhnlichen Fehler (nicht EIO „Eingabe- / Ausgabefehler“, sondern ESRCH „Kein solcher Prozess“):
Dabei ist 1234 die PID eines Prozesses, der als derselbe Benutzer wie der zu testende Prozess ausgeführt wird, nicht jedoch dieser Prozess. Credits rubasov für das Denken an
/proc/$pid/mem
.Wenn Sie die PID des Prozesses selbst verwenden, erhalten Sie EIO, aber nur, wenn Sie aus einem Bereich lesen, der nicht im Speicher des Prozesses zugeordnet ist. Die erste Seite wird nie zugeordnet, daher ist es in Ordnung, wenn Sie die Datei nacheinander lesen, jedoch nicht für einen Datenbankprozess geeignet, der direkt in die Mitte der Datei sucht.
Mit etwas mehr Setup als root können Sie den Device Mapper nutzen , um Dateien mit gültigen Sektoren und fehlerhaften Sektoren zu erstellen.
Ein anderer Ansatz wäre die Implementierung eines kleinen FUSE- Dateisystems. EIO ist der Standardfehlercode, wenn Ihr Userspace-Dateisystemtreiber etwas falsch macht. Sowohl die Perl- als auch die Python- Bindung enthalten Beispiele für den Einstieg. Sie können schnell ein Dateisystem schreiben, das zumeist vorhandene Dateien spiegelt, aber an sorgfältig ausgewählten Stellen eine EIO einfügt. Es gibt ein solches Dateisystem: petardfs ( Artikel ). Ich weiß nicht, wie es sofort funktioniert.
Noch eine andere Methode ist ein
LD_PRELOAD
Wrapper. Eine existierende ist Libfiu (Fehlerinjektion im Userspace). Hierzu wird eine Bibliothek vorab geladen, die die POSIX-API-Aufrufe überlastet. Sie können einfache Anweisungen oder beliebigen C-Code schreiben, um das normale Verhalten zu überschreiben.quelle
Die Lösung ist viel einfacher, wenn es in Ordnung ist, eine Gerätedatei als "Datei mit E / A-Fehlern" zu verwenden. Mein Vorschlag gilt für die Fälle, in denen eine reguläre Datei solche Fehler aufweisen soll.
Ich muss zugeben, dass ich ein bisschen verwirrt bin, weil ich es nicht geschafft habe, einzelne Sektoren aus dieser Datei fehlerfrei (mit
dd .. seek=...
) zu lesen . Vielleicht ist das ein Vorausleseproblem.quelle
Sie können CharybdeFS verwenden, das genau für diesen Zweck entwickelt wurde.
Es ist ein Passthrough-Fuse-Dateisystem wie PetardFS, aber viel konfigurierbarer.
Das CharybdeFS-Kochbuch finden Sie hier: http://www.scylladb.com/2016/05/02/fault-injection-filesystem-cookbook/
Es ist weit genug fortgeschritten, um eine Datenbank zu testen.
quelle