it-swarm-id.com

Bagaimana cara unit menguji kode multi-utas?

Apakah ada cara untuk menguji unit kode multi-utas Anda untuk kondisi balapan dan kebuntuan?

Untuk melihat apakah mereka melakukan cara mereka seharusnya ...

34
Tamara Wijsman

CATUR , sebuah proyek dari Microsoft Research. Mengutip situs mereka:

CHESS adalah alat untuk menemukan dan mereproduksi Heisenbug dalam program bersamaan. CHESS berulang kali menjalankan tes bersamaan memastikan bahwa setiap proses menjalankan interleaving yang berbeda. Jika interleaving menghasilkan kesalahan, CHESS dapat mereproduksi interleaving untuk meningkatkan debugging. CHESS tersedia untuk program yang dikelola dan asli.

Pembaruan (23/09/2015): Untuk C, C++, dan Go, Anda dapat menggunakan ThreadSanitizer .

19
Josh Kelley

Valgrind has Helgrind yang sangat membantu. Tidak hanya itu membantu menunjukkan ras yang dapat menyebabkan kelaparan atau kebuntuan, sedikit perlambatan memiliki program yang diprofilkan kadang-kadang memperlihatkan ras yang mungkin tidak terlihat sebaliknya.

Jadi, bahkan jika Anda menggunakan komando dengan semacam metode bebas kunci, itu tetap membantu :)

Namun, POSIX sentris. Ini dikirimkan dengan tajuk yang mudah membuat pustaka uji unit sederhana seperti TAP sadar bahwa itu sedang berjalan, yang juga sangat membantu. Misalnya, Anda dapat memiliki utas yang biasanya tidak akan diblokir saat mencoba mendapatkan kunci, lalu blokir (mungkin secara acak), hanya untuk mensimulasikan kelaparan.

10
Tim Post

Saya tidak ingat persis detailnya, tetapi ini adalah gagasan umum. Dan saya hanya pernah melakukannya sekali, tetapi yang saya lakukan adalah memisahkan kode peserta dari kode yang melakukan tugas, menggunakan antarmuka untuk dapat mengejek kelas tugas.

Kemudian saya merancang mock-up saya untuk dapat mengunci panggilan sehingga saya tahu utas berada di bagian kritis, dan kemudian memanggilnya lagi dan memverifikasi bahwa itu menunggu, sebelum melepaskan utas pertama dan selesai dengan bersih.

Sesuatu seperti itu.

Saya tidak yakin itu akan berhasil untuk skenario yang lebih kompleks, tetapi ini membantu menjaga perilaku selama refactoring.

5

Di JAOO/GOTO tahun ini saya melihat presentasi ini:

http://gotocon.com/aarhus-2010/presentation/Testing%20Asynchronous%20Behaviour%20in%20an%20Instant%20Pesanaging%20Server

Kuncinya adalah Anda memodelkan apa yang seharusnya dilakukan oleh aplikasi hairball Anda, dalam hal langkah-langkah doa serta operasi aktual pada aplikasi Anda. Perangkat lunak John Hughes kemudian secara sistematis mencoba banyak permutasi dari langkah-langkah doa berulang kali dalam paralel dan memeriksa setelah itu bahwa keadaan aplikasi sesuai dengan keadaan model. Jika kesalahan ditemukan, perangkat lunak tahu bagaimana mengurangi langkah-langkah ke kasus minimal yang menghasilkan kesalahan.

Dia menunjukkan secara langsung bagaimana menangkap beberapa bug di perpustakaan inti Erlang yang telah mengintai selama 15 tahun dan kadang-kadang dilaporkan tetapi tidak ada yang bisa mencari tahu dari mana mereka berasal dan karenanya cara memperbaikinya. Dengan kasus minimal yang dilaporkan oleh perangkat lunak, pengelola perpustakaan dapat memperbaiki setiap bug dalam satu hari .

Itu SO mengesankan.

John Hughes menjual perangkat lunak ini melalui perusahaannya.

2
user1249
  1. Tes dengan hasil yang tidak dapat direproduksi tidak berguna. Itu mengesampingkan tes sepenuhnya acak, tetapi meninggalkan dalam tes yang dihasilkan dari urutan pseudo-acak.
  2. Setiap aktor dalam lingkungan bersamaan memiliki komponen algoritmik atau non konkurensi yang dapat diuji dengan cara konvensional. Setelah mengujinya, kegagalan yang tersisa harus terletak pada logika konkurensi.
  3. Kejadian-kejadian dalam sistem konkuren selalu pada kenyataannya merupakan urutan kejadian linear. Jika cukup presisi digunakan untuk mengukur waktu, maka tidak ada peristiwa yang terjadi "pada saat yang sama". Itu berarti bahwa para aktor dalam sistem konkuren dapat diuji dengan menghasilkan peristiwa secara berurutan. Menangkap urutan peristiwa di sekitar waktu kegagalan sistem bersamaan memberikan kasus uji yang diperlukan.
  4. Kode yang memberi para pelaku keaktifan (utas) lebih sering diberikan oleh sistem operasi atau oleh pustaka sistem. Aman untuk mengasumsikan bahwa kata kode tidak perlu diuji. Kode yang bertanggung jawab atas komunikasi dan sinkronisasi biasanya ditulis oleh pemrogram aplikasi. Kode itu dapat diuji tanpa menggunakan kode sistem, yaitu, tanpa meluncurkan utas apa pun.
  5. Kondisi batas dalam kode algoritmik (antrian kosong) sering memerlukan penanganan dalam kode sinkronisasi, dan itu adalah target yang baik untuk pengujian.
  6. Mendefinisikan proxy di sekitar kode sistem (t.wait ()) memungkinkan penggunaan stubs/ejekan fungsi selama pengujian.
2
Apalala

Anda dapat mencoba Relacy Race Detector saya . Ini dirancang untuk secara cermat dan tepat memverifikasi algoritma sinkronisasi seperti antrian produsen-konsumen dan wadah bersamaan, tetapi tidak terlalu cocok untuk verifikasi seluruh program. Namun, mungkin itu ide yang baik untuk menyebarkan sinkronisasi dan menghentikan semua program, tetapi sebaliknya memusatkan sinkronisasi dalam komponen khusus (yang dapat diverifikasi dengan Relacy).

1
Dmitry Vyukov

Itu tidak mudah, tetapi pada dasarnya satu-satunya cara adalah memanggil kode multi-utas bersamaan dari beberapa utas dan mengubah waktu dan memesan secara acak dengan bermain dengan acak Thread.sleep() dan Thread.yield() panggilan (dengan asumsi Java).

Ada juga alat-alat siap yang tersedia (seperti TestNG) yang melakukan sesuatu seperti dijelaskan di atas, tetapi mereka belum terlalu matang, sejauh yang saya tahu.

0
Joonas Pulakka

Bukan tes unit yang ketat, tetapi pemeriksaan runtime yang telah membantu saya dengan beberapa tes yang gagal sebentar-sebentar. Cepat & kotor, tetapi berhasil.

Ketika mutex diberikan, saya menyimpan jejak dari thread mana yang memilikinya. Semua permintaan mutex memiliki batas waktu tiga puluh detik, setelah itu mereka menjerit kebuntuan.

Saya kemudian dapat menggunakan daftar mutex yang diberikan untuk melihat utas mana yang memegang mutex pemblokiran, dan mengapa begitu lama. Dalam kasus saya sejauh ini karena itu menemui jalan buntu pada sesuatu yang lain, jadi saya kemudian dapat memperbaiki situasi itu.

Ini bekerja untuk saya karena mutex saya memiliki kelas pembungkus lintas platform sehingga mudah untuk menyuntikkan penyimpanan catatan dan batas waktu. Saya juga cukup tahu tentang aplikasi untuk tahu itu tidak boleh diblokir di mutex selama 30 detik.

Mungkin ini bukan tujuan yang sepenuhnya umum, tetapi menghemat banyak proses debug selama sekitar beberapa jam. Biaya overhead dapat diabaikan, dan itu bisa berupa debug-build saja.

Saya akan melihat untuk memperluasnya untuk mencatat urutan permintaan mutex bersarang, dan melihat apakah ada yang berpotensi menyebabkan kebuntuan (mis. Satu utas mengunci A lalu B dan kunci lainnya B lalu A) daripada hanya kebuntuan yang sebenarnya mendorong, tetapi sejauh ini sudah banyak manfaatnya untuk upaya sepele.

0
Andy Krouwel