Saya ingin menguji secara otomatis apakah perangkat lunak bereaksi seperti yang diharapkan jika file DB SQLite penting gagal dibaca (menyebabkan kesalahan I / O). Persisnya itu terjadi beberapa hari yang lalu di klien. Kami memperbaikinya secara manual, tetapi sekarang saya ingin membuat kode otomatis untuk memperbaikinya dan memerlukan akses ke file yang rusak untuk mengujinya.
Karena semua yang ada di Unix adalah file, saya curiga bahwa mungkin ada file khusus yang selalu menyebabkan kesalahan I / O ketika seseorang mencoba membacanya (misalnya di / dev).
Beberapa file serupa (imo) adalah:
/dev/full
yang selalu mengatakan "Tidak ada ruang yang tersisa di perangkat" jika Anda mencoba untuk menulisnya/dev/null
dan/dev/zero
jadi saya berasumsi hanya ada file seperti itu (tetapi belum menemukan satu).
Adakah yang tahu file seperti itu atau metode lain bagi saya untuk mendapatkan hasil yang diinginkan (gambar partisi yang sengaja rusak, pembungkus terbuka () menggunakan LD_PRELOAD, ...)?
Apa cara terbaik untuk pergi ke sini?
Jawaban:
Anda dapat menggunakan
dmsetup
untuk membuat perangkat device-mapper menggunakan salah satuerror
atauflakey
target untuk mensimulasikan kegagalan.Di mana 123 adalah panjang perangkat, di sektor dan / dev / loop0 adalah perangkat asli yang Anda inginkan untuk mensimulasikan kesalahan. Untuk kesalahan, Anda tidak perlu argumen berikutnya karena selalu mengembalikan kesalahan.
sumber
dmsetup table test
. Anda bahkan dapat menulis difoo bar
belakangerror
; tidak peduli (dan karenanya harus dihapus).Ada set jawaban yang bagus untuk ini pada Stack Overflow dan Server Fault, tetapi beberapa teknik tidak ada. Untuk membuat hidup lebih mudah di sini adalah daftar VM / Linux block device / Linux filesystem / Linux userspace library I / O mekanisme injeksi kesalahan:
--layout
opsi halaman man mdadm untuk cara mengkonfigurasinya (kernel dan mpacem userspace bits).LD_PRELOAD
).FAIL_MAKE_REQUEST=y
).BLK_DEV_NULL_BLK_FAULT_INJECTION=y
).delay
atauerror
dan kemudian melampirkan perangkat blok ke sana melaluinbd-client
(kernel + NBD userspace bits, kernel> = 4,18 dibangun dengan dukungan NBD, nbdclient> = 3.18 dan nbdkit> = 1.8.1 direkomendasikan - lihat video demo NBDKit sekitar tanda 20 menit).Fakta bonus: SQLite memiliki driver VFS untuk mensimulasikan kesalahan sehingga bisa mendapatkan cakupan tes yang baik.
Terkait:
sumber
Anda menginginkan mekanisme injeksi kesalahan untuk I / O.
Di Linux, inilah metode yang tidak memerlukan pengaturan sebelumnya dan menghasilkan kesalahan yang tidak biasa (bukan EIO "Kesalahan input / output" tetapi ESRCH "Tidak ada proses seperti itu"):
di mana 1234 adalah PID dari suatu proses yang berjalan sebagai pengguna yang sama dengan proses yang Anda uji, tetapi bukan proses itu sendiri. Kredit untuk rubasov untuk berpikir dari
/proc/$pid/mem
.Jika Anda menggunakan PID dari proses itu sendiri, Anda mendapatkan EIO, tetapi hanya jika Anda membaca dari area yang tidak dipetakan dalam memori proses. Halaman pertama tidak pernah dipetakan, jadi tidak apa-apa jika Anda membaca file secara berurutan, tetapi tidak cocok untuk proses database yang mencari langsung ke tengah file.
Dengan beberapa pengaturan lainnya sebagai root, Anda dapat memanfaatkan mapper perangkat untuk membuat file dengan sektor yang valid dan sektor yang buruk.
Pendekatan lain adalah menerapkan sistem file FUSE kecil . EIO adalah kode kesalahan default ketika driver sistem file userspace Anda melakukan sesuatu yang salah, sehingga mudah dicapai. Baik binding dan Perl Python datang dengan contoh untuk memulai, Anda dapat dengan cepat menulis sistem file yang sebagian besar mencerminkan file yang ada tetapi menyuntikkan EIO di tempat yang dipilih dengan cermat. Ada filesystem yang ada: petardfs ( artikel ), saya tidak tahu seberapa baik kerjanya di luar kotak.
Namun metode lain adalah
LD_PRELOAD
pembungkus. Yang sudah ada adalah Libfiu (injeksi kesalahan di userspace). Ini bekerja dengan preloading perpustakaan yang membebani panggilan API POSIX. Anda dapat menulis arahan sederhana atau kode C arbitrer untuk mengesampingkan perilaku normal.sumber
Solusinya jauh lebih mudah jika boleh menggunakan file perangkat sebagai "file dengan kesalahan I / O". Proposal saya untuk kasus-kasus di mana file biasa akan memiliki kesalahan seperti itu.
Saya harus mengakui bahwa saya agak bingung karena saya belum berhasil membaca sektor tunggal dari file itu tanpa kesalahan (dengan
dd .. seek=...
). Mungkin itu masalah baca-depan.sumber
Anda bisa menggunakan CharybdeFS yang dibuat persis untuk tujuan seperti ini.
Ini adalah sistem file sekering passthrough seperti PetardFS tetapi jauh lebih dapat dikonfigurasi.
Lihat buku masak CharybdeFS di sini: http://www.scylladb.com/2016/05/02/fault-injection-filesystem-cookbook/
Cukup canggih untuk menguji basis data.
sumber