Banyak proyek menghadapi masalah tes serpihan, dan topik ini telah diangkat lebih dari satu kali di Habré. Tes yang belum memutuskan kondisinya secara konstan tidak hanya memakan waktu mesin, tetapi juga waktu pengembang dan penguji. Dan jika di perusahaan komersial Anda dapat mengalokasikan sumber daya tertentu untuk menyelesaikan masalah ini dan menunjuk orang yang bertanggung jawab, maka di komunitas opensource itu tidak begitu sederhana. Terutama ketika menyangkut proyek besar - misalnya, seperti Apache Ignite, di mana ada hampir 60 ribu tes berbeda.

Dalam posting ini, kami, pada kenyataannya, akan memberi tahu Anda cara mengatasi masalah ini di Apache Ignite. Kami adalah Dmitry Pavlov, insinyur perangkat lunak / manajer komunitas terkemuka di GridGain, dan Nikolai Kulagin, insinyur TI di Sberbank Technologies.
Segala sesuatu yang tertulis di bawah ini tidak mewakili posisi perusahaan mana pun, termasuk Sberbank. Kisah ini secara eksklusif dari anggota komunitas Apache Ignite.Apache Menyalakan dan menguji
Kisah Apache Ignite dimulai pada 2014, ketika GridGain menyumbangkan versi pertama produk internal ke Apache Software Foundation. Lebih dari 4 tahun telah berlalu sejak itu, dan selama ini jumlah tes mendekati tanda 60 ribu.
Kami menggunakan JetBrains TeamCity sebagai server integrasi berkelanjutan - terima kasih kepada orang-orang dari JetBrains untuk mendukung pergerakan sumber terbuka. Semua tes kami didistribusikan di antara suite-suite, yang jumlahnya untuk cabang master hampir mencapai 140. Di suite-suite tersebut, tes-tes tersebut dikelompokkan berdasarkan beberapa kriteria. Ini dapat menguji hanya fungsionalitas Machine Learning [RunMl], hanya cache [RunCache], atau seluruh [RunAll]. Di masa depan, jangka waktu pengujian akan berarti persis [RunAll] - pemeriksaan lengkap. Butuh sekitar 55 jam waktu mesin.
Junit digunakan sebagai perpustakaan utama, tetapi ada beberapa tes unit. Sebagian besar, semua tes kami adalah tes integrasi, karena berisi peluncuran satu atau lebih node (dan ini membutuhkan beberapa detik). Tentu saja, tes integrasi nyaman karena satu tes tersebut mencakup banyak aspek dan interaksi, yang cukup sulit untuk dicapai dengan uji unit tunggal. Tetapi ada juga kelemahannya: dalam kasus kami, ini adalah waktu yang cukup lama, serta kesulitan menemukan masalah.
Masalah dengan serpihan
Sebagian dari tes ini bersisik. Sekarang, menurut klasifikasi TeamCity, sekitar 1.700 tes ditandai sebagai serpihan - yaitu, dengan perubahan status tanpa mengubah kode atau konfigurasi. Tes semacam itu tidak dapat diabaikan, karena ada risiko mendapatkan bug dalam produksi. Oleh karena itu, mereka harus diperiksa ulang dan dimulai kembali, kadang-kadang beberapa kali, untuk menganalisis hasil jatuh - dan ini membutuhkan waktu dan upaya yang berharga. Dan jika anggota masyarakat yang ada mengatasi tugas ini, maka bagi kontributor baru ini dapat menjadi penghalang nyata. Anda harus mengakui bahwa ketika Anda membuat perubahan pada Java Doc, Anda tidak berharap akan mengalami crash, tetapi tidak satu, tetapi beberapa lusin.

Siapa yang harus disalahkan?
Setengah dari masalah dengan tes bersisik muncul karena konfigurasi peralatan, karena ukuran instalasi. Dan babak kedua terhubung langsung dengan orang-orang yang ketinggalan dan tidak memperbaiki bug mereka.
Secara konvensional, semua anggota masyarakat dapat dibagi menjadi dua kelompok:
- Penggemar yang memasuki komunitas atas kehendak bebas mereka sendiri dan berkontribusi pada waktu luang mereka.
- Kontributor penuh yang bekerja untuk perusahaan yang entah bagaimana menggunakan atau dikaitkan dengan produk sumber terbuka ini.
Kontributor dari grup pertama dapat membuat satu pengeditan dan meninggalkan komunitas. Dan untuk mencapainya jika terdeteksi bug hampir tidak mungkin. Lebih mudah untuk berinteraksi dengan orang-orang dari kelompok kedua, mereka lebih cenderung merespon tes yang mereka hancurkan. Tetapi kebetulan sebuah perusahaan yang sebelumnya tertarik pada suatu produk tidak lagi membutuhkannya. Dia meninggalkan komunitas, dan karyawannya yang berkontribusi ikut bersamanya. Atau mungkin saja kontributor meninggalkan perusahaan, dan bersama komunitas. Tentu saja, setelah perubahan tersebut, beberapa masih terus berpartisipasi dalam komunitas. Tapi tidak semua.
Siapa yang akan memperbaikinya?
Jika kita berbicara tentang orang yang meninggalkan komunitas, maka bug mereka, tentu saja, pergi ke kontributor saat ini. Perlu dicatat bahwa untuk revisi yang mengarah ke bug, peninjau juga bertanggung jawab, tetapi ia mungkin juga seorang penggila - yaitu, ia tidak akan selalu tersedia.
Kebetulan menjangkau seseorang, katakan padanya: ini masalahnya. Tapi dia berkata: tidak, ini bukan perbaikan saya memperkenalkan bug. Karena menjalankan penuh cabang master secara otomatis dilakukan dengan antrian yang relatif bebas, ini paling sering terjadi pada malam hari. Sebelum ini, beberapa komitmen dapat dicurahkan ke cabang sepanjang hari.
Di TeamCity, modifikasi kode apa pun dianggap sebagai changelog. Jika setelah tiga pengubah kami mengalami penurunan baru, maka tiga orang akan mengatakan bahwa ini bukan karena komitmen mereka. Jika ada lima changer, maka kami akan mendengarnya dari lima orang.
Masalah lain: untuk memberi tahu kontributor bahwa tes harus dijalankan sebelum setiap tinjauan. Beberapa tidak tahu di mana, apa dan bagaimana menjalankannya. Atau tes dijalankan, tetapi kontributor tidak menulis tentang itu di tiket. Ada masalah pada tahap ini juga.
Silakan. Misalkan tes dijalankan, dan di tiket ada tautan ke hasilnya. Tapi, ternyata, ini tidak memberikan jaminan analisis uji run-through. Kontributor dapat melihat larinya, melihat beberapa tetes di sana, tetapi menulis "TeamCity Looks Good". Peninjau - terutama jika ia akrab dengan kontributor atau telah berhasil memeriksanya sebelumnya - mungkin tidak benar-benar melihat hasilnya. Dan kami mendapatkan "TeamCity Looks Good":

Di mana "Bagus" ada di sini tidak jelas. Namun ternyata, penulis setidaknya tahu bahwa tes perlu dijalankan.
Bagaimana kami melawan ini
Metode 1. Tes terpisah
Kami membagi tes menjadi dua kelompok. Dalam yang pertama, "bersih" - tes stabil. Di kedua - tidak stabil. Pendekatannya cukup jelas, tetapi tidak berhasil meskipun dengan dua upaya. Mengapa Karena sebuah suite dengan tes yang tidak stabil berubah menjadi ghetto di mana sesuatu mulai tentu saja time out, crash, dll. Akibatnya, semua orang mulai mengabaikan tes yang selalu bermasalah ini. Secara umum, tidak ada gunanya membagi tes berdasarkan kelas.
Metode 2. Pemisahan dan pemberitahuan
Opsi kedua mirip dengan yang pertama - untuk mengalokasikan tes yang lebih stabil, dan menjalankan tes PR yang tersisa di malam hari. Jika ada yang rusak dalam grup stabil, maka pesan dikirim ke kontributor dengan alat TeamCity standar yang mengatakan bahwa sesuatu perlu diperbaiki.

... 0 orang bereaksi terhadap pesan-pesan ini. Semua mengabaikan mereka.
Metode 3. Pemantauan Harian
Kami membagi suite menjadi beberapa "pengamat", anggota komunitas yang paling bertanggung jawab, dan menandatangani mereka untuk peringatan tentang jatuh. Akibatnya, dalam praktiknya dikonfirmasi bahwa antusiasme cenderung berakhir. Kontributor meninggalkan usaha ini dan berhenti memeriksa secara teratur. Lalu saya melewatkannya, melihat ke sana - dan lagi-lagi sesuatu merangkak ke dalam tuan.
Metode 4. Otomatisasi
Setelah metode lain yang gagal, orang-orang dari GridGain ingat utilitas yang dikembangkan sebelumnya yang menambahkan fungsionalitas yang hilang pada saat itu di TeamCity. Yaitu, kemampuan untuk melihat statistik umum tentang jumlah jatuh: berapa banyak dan apa yang jatuh, memburuk atau meningkatkan hasilnya pada hari berikutnya. Utilitas ini dikembangkan secara bertahap, laporan ditambahkan, dan diganti namanya. Kemudian mereka menambahkan notifikasi, diganti namanya lagi. Jadi ternyata TeamCity Bot. Sekarang ia memiliki hampir 500 komit dan 7 kontributor dan ia berada dalam repositori Apache tambahan.
Apa yang dilakukan bot? Kemampuannya dapat digabungkan menjadi dua kelompok:
- Pemantauan proyek - pemantauan visual dengan melihat hasil lari, serta pemberitahuan otomatis dalam pesan instan (misalnya, kendur)
- Periksa cabang - analisis pengujian PR, serta mengeluarkan visa dalam tiket.
Alur Kerja TeamCity Bot
Sebelum Apache Ignite Teamcity Bot, proses "berkontribusi" kepada komunitas adalah sebagai berikut:
- Di JIRA, salah satu tiket dipilih dan diperbaiki;
- Permintaan penarikan dibuat;
- Menjalankan tes yang mungkin dipengaruhi oleh perubahan yang dilakukan;
- Jika tes lulus, permintaan tarik dapat dipratinjau dan dimatikan oleh pengendara.

Ini terlihat sederhana, tetapi pada kenyataannya poin ketiga dapat menjadi penghalang bagi beberapa kontributor. Sebagai contoh: seorang pendatang baru di komunitas memutuskan untuk memberikan kontribusi pertamanya dengan memilih tiket paling sederhana. Ini dapat mengedit Java Doc atau memperbarui versi ketergantungan maven. Menganalisis hasil lari dalam perbaikan kecilnya, ia tiba-tiba menemukan bahwa sekitar 30 tes telah jatuh. Dari mana datangnya sejumlah tes gagal dan bagaimana menganalisisnya - dia tidak tahu. Mungkin diharapkan bahwa kontributor tidak akan pernah kembali ke sini lagi.
Anggota masyarakat yang lebih berpengalaman juga menderita keripik - mereka menghabiskan waktu menganalisis tes yang jatuh secara kebetulan, dan dengan demikian menghambat pengembangan produk.
Skema kontribusi dengan TeamCity BotDengan munculnya bot, langkah-langkah dalam counterplay meningkat, tetapi waktu yang dihabiskan untuk menganalisis tes jatuh menurun secara signifikan. Sekarang cukup untuk menjalankan tes dan setelah lulus, lihat halaman bot yang sesuai. Jika ada kemungkinan pemblokir (tes yang dibatalkan yang tidak dianggap serpihan), cukup untuk melakukan pemeriksaan ganda, yang akan menghasilkan visa dalam bentuk komentar di JIRA dengan hasil tes.
Ikhtisar Fitur
Periksa Kontribusi - daftar semua PR yang tidak tertutup dengan ringkasan setiap informasi: tanggal pembaruan terakhir, nomor PR, nama, penulis, dan tiket di JIRA .
Untuk setiap permintaan tarik, tersedia tab dengan informasi yang lebih terperinci: nama PR yang benar, tanpanya bot tidak akan dapat menemukan tiket yang diinginkan di JIRA; apakah tes dijalankan; apakah hasil tes siap; meninggalkan komentar di JIRA.Analisis hasil tes:


Berikut adalah dua laporan tentang pengujian PR yang sama. Yang pertama adalah dari bot. Yang kedua adalah laporan standar tentang Teamcity. Perbedaan dalam jumlah informasi jelas, dan ini tidak memperhitungkan fakta bahwa untuk melihat riwayat uji coba TC, perlu juga untuk membuat beberapa transisi ke halaman yang berdekatan.

Mari kita kembali ke laporan bot. Laporan ini secara visual dibagi menjadi dua tabel: kemungkinan blocker dan semua crash. Blocker termasuk tes yang:
- memiliki tingkat kegagalan dalam master kurang dari 4% (kurang dari 4 mulai dari 100 tidak berhasil);
- tidak serpihan menurut klasifikasi TeamCity;
- jatuh karena batas waktu, kehabisan memori, kode keluar, kegagalan JVM.
Misalnya, pada tangkapan layar di atas, dua suite diindikasikan sebagai kemungkinan pemblokir - yang pertama, tes jatuh, dan yang kedua, timeout terjadi.

Untuk akhirnya memahami apa itu tes serpihan, dan apa itu bug, perhatikan gambar di atas. Bilah horizontal 100 berjalan. Bilah hijau vertikal - berhasil melewati tes, red-drop. Dalam kasus bug, run history tampak alami: bilah hijau polos pada akhirnya berubah warna menjadi merah. Ini berarti bahwa di tempat inilah bug muncul dan tes mulai turun terus-menerus. Jika kita memiliki tes serpihan di hadapan kita, maka riwayat larinya adalah pergantian terus menerus warna hijau dan merah.
Analisis Hasil Uji

Sebagai contoh, kami menganalisis hasil lulus tes dalam tangkapan layar di atas. Menurut versi bot, mungkin ada dua crash karena bug - mereka terdaftar di tabel Kemungkinan Pemblokir. Tapi itu mungkin tes yang rapuh dengan tingkat kegagalan yang rendah. Untuk mengecualikan opsi ini, cukup klik tombol Jalankan kembali kemungkinan blocker, dan dua suite ini akan pergi untuk memeriksa ulang. Untuk membuat tugas lebih mudah, Anda dapat mengklik Jalankan kembali kemungkinan pemblokir & komentar JIRA, dan dapatkan komentar (dan dengan itu pemberitahuan melalui email) dari bot setelah pemeriksaan selesai. Lalu masuk dan lihat apakah ada masalah atau tidak.
Untuk pengulas, ini sangat keren. Anda bisa lupa tentang pengeditan yang tidak lulus pemeriksaan, tetapi cukup klik pada sejumlah pengeditan, klik tombol Re-run hijau besar dan tunggu suratnya.
Laporan sempurna: tidak ada pemblokir yang terdeteksi

Visa hijau (komentar) bot. Tidak ada pemblokir yang ditemukan.

Diperlukan visa merah - memeriksa ulang dan / atau mengedit bugKebetulan beberapa bug masih bocor ke "master". Seperti yang kami katakan, sebelum ini diperjuangkan melalui pemberitahuan pribadi. Atau seseorang memastikan tidak ada yang jatuh. Sekarang kami menggunakan solusi yang lebih sederhana:

Ketika bug baru terdeteksi, sebuah pesan dikirim ke dev-list, yang mengindikasikan kontributor dan penggantinya, yang mungkin menjadi penyebab kesalahan. Jadi seluruh komunitas akan mencari tahu siapa yang menyebabkan semuanya terjadi.
Dengan demikian, kami dapat meningkatkan jumlah perbaikan panas dan sangat mengurangi waktu yang diperlukan untuk memperbaiki masalah.
Memantau status penyihir
Fungsi bot lainnya adalah memantau keadaan wizard dengan statistik pada peluncuran terbaru.

Tren master

Halaman tren Master membandingkan dua pilihan "master" untuk periode waktu tertentu. Untuk setiap item dalam tabel menampilkan nilai maksimum, minimum, dan median.

Selain hasil umum untuk seluruh sampel, tabel berisi grafik untuk setiap indikator dengan tampilan nilai masing-masing bangunan. Dengan mengklik suatu titik, Anda dapat pergi ke hasil lari di TeamCity. Selain itu, dimungkinkan untuk menghapus hasil dari statistik. Ini berguna ketika nilai abnormal terjadi karena gangguan serius, yang mungkin tidak disalahkan oleh kontributor. Hasil tersebut harus dikecualikan sehingga mereka tidak diperhitungkan saat menghitung tes serpihan yang sama. Selain itu, build juga dapat dibedakan untuk melacak hasil untuk setiap indikator.
Apache Ignite Teamcity Bot sekarang memiliki lebih dari 65 anggota terdaftar. Selama seluruh periode penggunaan bot, visa menerima lebih dari 400 permintaan tarik, dan rata-rata lima visa dikeluarkan per hari.
Struktur Bot TeamCity
Bot di-host di server terpisah, menuju ke ignite.apache.org untuk data, secara publik memberi tahu semua orang di daftar-dev - ini adalah platform utama kami untuk pengembang Ignite - dan menulis visa untuk tiket melalui API JIRA.

Ia menggunakan server Jetty, servlets Jersey, sejumlah layanan dengan logika bisnis yang kompleks dari bot itu sendiri, termasuk layanan Teamcity, JIRA dan GitHub yang mengakses layanan Ignited Integration. Di atas Integrasi Murni ini untuk permintaan http. Sebagai penyimpanan - produk Apache Ignite sendiri dalam mode tertanam konfigurasi Node Tunggal dengan kegigihan aktif. Selain keuntungan nyata menggunakan Ignite sebagai basis data, ini juga membantu kami menemukan berbagai area penerapan Ignite dan memahami apa yang nyaman dan apa yang tidak.
Versi pertama dari implementasi bot terinspirasi oleh satu artikel tentang cache REST dan merupakan cache REST dan layanan GitHub dan Teamcity. Teamcity xml dan json yang dikembalikan dari server diuraikan oleh Pure Java Objects, yang kemudian di-cache. Pada awalnya itu berhasil, dan cukup cepat. Tetapi dengan peningkatan jumlah data, hasilnya mulai memburuk.
Perlu dicatat bahwa TeamCity menghapus cerita yang lebih tua dari ~ 2 minggu, tetapi bot tidak melakukannya. Pada akhirnya, dengan pendekatan ini, banyak data muncul yang sangat sulit dikelola.
Pengembangan Bot TeamCity
Pendekatan baru mengimplementasikan opsi penyimpanan data yang ringkas dan memilih sejumlah kecil partisi cache. Sejumlah besar partisi pada satu node secara negatif mempengaruhi kecepatan sinkronisasi data ke disk dan meningkatkan waktu mulai cluster.
Semua pembaruan data utama dilakukan secara tidak sinkron, karena jika tidak, kami berisiko mendapatkan UX yang buruk karena lambatnya pengembalian data TeamCity.
Untuk string yang jarang mengubah nilainya (misalnya, nama tes), pemetaan sederhana dilakukan dalam id, yang dihasilkan oleh Urutan Atom. Berikut adalah contoh Entri tersebut:

Nama uji panjang sesuai dengan nomor int, yang disimpan di semua build. Ini menghemat banyak sumber daya. Di atas metode yang mengembalikan baris ini adalah pencegat cache dalam-memori Guava. Berkat penjelasan cache, bahkan di heap kami tidak memilih baris dengan membacanya dari Ignite by id. Dan dengan id kita selalu mendapatkan baris yang sama, yang bagus untuk kinerja.
Untuk garis "yang tidak dapat diprediksi", misalnya, log jejak tumpukan, berbagai jenis kompresi digunakan - kompresi gzip, kompresi tajam atau tidak terkompresi, tergantung mana yang lebih baik. Semua metode ini membantu menyesuaikan data maksimum dalam memori dan dengan cepat memberikan respons kepada klien.
Mengapa TeamCity Bot Lebih Baik
Ini bukan untuk mengatakan bahwa TeamCity tidak memiliki fitur yang tercantum di atas. Mereka, tetapi tersebar di tumpukan tempat yang berbeda. Di bot, semuanya dikumpulkan pada satu halaman dan Anda dapat dengan cepat memahami apa masalahnya.
Tambahan yang bagus adalah surat yang dikirimkan bot pada lembar dev ketika mendeteksi masalah. Segera di komunitas ada kesempatan untuk memulai diskusi: "Ayo, mungkin, sekarang kita akan mundur?". Ini menambah kepercayaan bagi pengulas.
Dengan bot, jauh lebih mudah bagi kontributor baru untuk bergabung dalam proses pengembangan. Membuat perbaikan pertama Anda, Anda tidak selalu tahu apa perubahan yang mungkin terjadi. Dan terjun langsung ke analisis hasil pengujian pada TeamCity, Anda dapat dengan mudah kehilangan antusiasme untuk pengembangan lebih lanjut. Apache Ignite TeamCity Bot akan membantu Anda dengan cepat memahami jika ada masalah dan mempertahankan antusiasme.
Kami berharap bot akan menyederhanakan kehidupan kontributor saat ini dan menarik orang baru ke komunitas. Akhirnya, kami menyarankan, tentu saja, untuk mencegah kemunculan sejumlah besar tes yang tidak pasti, karena sulit untuk mengatasinya. Dan robot kepercayaan - mereka tidak memiliki preferensi dan mereka tidak mengambil kata-kata orang untuk itu.