Saya sedang membangun layanan di atas Google App Engine Datastore, yang merupakan penyimpanan data yang pada akhirnya konsisten. Untuk aplikasi saya, ini baik-baik saja.
Namun, saya sedang mengembangkan tes yang melakukan hal-hal seperti objek PUT dan kemudian DAPATKAN objek dan memeriksa properti pada objek yang dikembalikan. Sayangnya, karena datastore pada akhirnya konsisten, tes sederhana ini tidak dapat diulang.
Bagaimana Anda menguji layanan yang pada akhirnya konsisten?
google-app-engine
eventual-consistency
google-cloud-datastore
Doug Richardson
sumber
sumber
How can I reproducibly test an eventually consistent service?
- Kamu tidak bisa. Anda harus menghapus kata "dapat direproduksi" atau kata "akhirnya;" Anda tidak dapat memiliki keduanya.Jawaban:
Pertimbangkan persyaratan non-fungsional saat merancang tes fungsional Anda - jika layanan Anda memiliki persyaratan non-fungsional "Konsisten dalam waktu x (detik / menit / dll)", jalankan saja permintaan PUT, tunggu x, kemudian jalankan permintaan GET.
Pada saat itu, jika data belum 'tiba', Anda dapat menganggap permintaan PUT tidak sesuai dengan kebutuhan Anda.
sumber
Anda benar-benar ingin tes Anda cepat dan konsisten. Jika Anda mulai membuat tes yang kadang-kadang gagal karena konsistensi akhirnya, Anda akan mengabaikan tes ketika gagal, dan lalu apa gunanya?
Buat layanan palsu yang menangani permintaan PUT dan GET, tetapi memiliki operasi tambahan agar konsisten. Tes Anda kemudian:
Ini memungkinkan Anda untuk menguji perilaku perangkat lunak Anda ketika GET berhasil mengambil objek PUT. Hal ini juga memungkinkan Anda untuk menguji perilaku perangkat lunak Anda ketika GET tidak menemukan objek (atau objek yang benar) karena layanan belum konsisten. Tinggalkan saja panggilan untuk
make_consistent()
.Masih layak memiliki tes yang berinteraksi dengan layanan nyata, tetapi harus berjalan di luar alur kerja pengembangan normal Anda, karena mereka tidak akan pernah dapat diandalkan 100% (misalnya jika layanan sedang down). Tes-tes ini harus digunakan untuk:
sumber
OKE begitu. "What Are You Testing" adalah pertanyaan kuncinya.
Dalam hal ini Anda harus mengejek layanan google dan selalu mengembalikan respons.
Dalam hal ini Anda harus mengejek layanan google dan selalu mengembalikan kesalahan sementara sebelum tanggapan yang benar
Anda harus menyuntikkan layanan google asli dan menjalankan tes. Tapi! Kode yang Anda uji harus memiliki penanganan Kesalahan Sementara (coba lagi) di dalamnya. JADI, Anda harus mendapatkan respons yang konsisten. (kecuali google berperilaku sangat buruk)
sumber
Gunakan salah satu dari yang berikut:
Sayangnya, Anda harus memilih nilai ajaib (N atau durasi tidur) untuk kedua teknik ini.
sumber
Seperti yang saya pahami, Google Cloud datastore memungkinkan kueri yang sangat konsisten dan akhirnya konsisten .
Imbalannya adalah bahwa kueri yang sangat konsisten sangat terbatas pada tingkat suku bunga (sesuatu yang dapat Anda jalani selama pengujian).
Salah satu kemungkinan mungkin untuk menempatkan pertanyaan Anda ke datastore dalam pembungkus yang dapat memungkinkan konsistensi yang kuat untuk tujuan pengujian.
Misalnya, Anda dapat meminta metode dipanggil
start_debug_strong_consistency()
danend_debug_strong_consistency()
.Metode mulai akan membuat kunci yang dapat digunakan sebagai kunci leluhur untuk semua permintaan berikutnya, dan metode akhir akan menghapus kunci.
Satu-satunya perubahan pada pertanyaan aktual yang Anda uji adalah menelepon
setAncestor(your_debug_key)
jika kunci itu ada.sumber
Salah satu pendekatan, yang bagus dalam teori tetapi mungkin tidak selalu praktis, adalah membuat semua operasi penulisan dalam sistem diuji idempoten . Itu berarti, dengan asumsi kode tes Anda menguji berbagai hal dalam urutan berurutan tetap, Anda dapat mencoba kembali semua membaca dan semua menulis secara individual sampai Anda mendapatkan hasil yang Anda harapkan, coba lagi hingga batas waktu yang Anda tentukan dalam kode uji terlampaui. Yaitu, lakukan hal A1, coba lagi jika perlu sampai hasilnya B1, kemudian lakukan hal A2, coba lagi jika perlu sampai hasilnya B2, dan seterusnya.
Maka Anda tidak perlu repot untuk memeriksa prasyarat operasi tulis, karena operasi tulis akan sudah memeriksa mereka untuk Anda, dan Anda hanya coba lagi sampai mereka berhasil!
Gunakan batas waktu "default" yang sama sebanyak mungkin, yang dapat ditingkatkan jika keseluruhan sistem menjadi lebih lambat, dan timpa default secara individual ketika mencoba kembali operasi yang sangat lambat.
sumber
Layanan seperti Google App Engine Datastore didasarkan pada replikasi data di beberapa titik keberadaan tersebar global (POP). Tes integrasi apa pun untuk layanan yang pada akhirnya konsisten benar-benar merupakan tes tingkat replikasi layanan tersebut di seluruh rangkaian POPs. Tingkat penyebaran konten ke setiap POP dalam layanan yang diberikan tidak akan sama dengan setiap POP dalam layanan tergantung pada sejumlah faktor, seperti metode replikasi dan berbagai masalah transportasi Internet - ini adalah dua contoh yang menyumbang sebagian besar laporan dalam layanan datastore yang pada akhirnya konsisten (setidaknya itu adalah pengalaman saya ketika saya bekerja untuk CDN utama).
Untuk menguji replikasi objek secara efektif di platform tertentu, Anda harus mengatur tes untuk meminta objek yang baru ditempatkan yang sama dari masing-masing POP layanan. Saya menyarankan pengujian daftar POP satu-ke-lima kali atau sampai semua POP di daftar POP Anda melaporkan memiliki objek. Berikut adalah serangkaian interval untuk melakukan tes yang bebas Anda sesuaikan: 1, 5, 60 menit, 12 jam, 25 jam setelah menempatkannya di datastore. Kuncinya adalah mencatat hasil pada setiap interval untuk ditinjau dan dianalisis kemudian untuk merasakan kemampuan layanan yang diberikan untuk mereplikasi objek secara global. Seringkali layanan datastore hanya menarik salinan lokal ke POP setelah diminta secara lokal [perutean dilakukan melalui protokol BGP, itulah sebabnya pengujian Anda harus meminta objek dari setiap POP tertentu agar valid secara global untuk platform yang diberikan] . Dalam kasus Google's Datastore Anda akan mencari untuk mengatur tes Anda untuk permintaan objek tertentu dari "lebih dari 70 titik kehadiran di 33 negara"; Anda mungkin harus mendapatkan daftar url alamat POP khusus dari Dukungan Google [ref:https://cloud.google.com/about/locations/ ] atau jika Google menggunakan Fastly untuk replikasi, Fastly Support [ https://www.fastly.com/resources ].
Beberapa keuntungan dari metode ini: 1) Anda akan merasakan platform replikasi layanan yang diberikan, mengetahui kekuatan dan kelemahannya secara keseluruhan pada skala global [seperti saat pengujian integrasi]. 2) Untuk objek apa pun yang Anda uji, Anda akan memiliki alat yang tersedia untuk menghangatkan konten [buat permintaan pertama yang membuat salinan di POP lokal yang diberikan] - sehingga memberi Anda cara untuk memastikan konten tersebar secara global sebelum klien Anda meminta dari dimanapun di bumi.
sumber
Saya memiliki pengalaman dengan Google App Engine Datastore. Berjalan secara lokal, secara mengejutkan, seringkali lebih "akhirnya" daripada "konsisten". Contoh paling sederhana: buat entitas baru, lalu ambil kembali. Sering kali selama 5 tahun terakhir, saya telah melihat SDK yang berjalan secara lokal tidak menemukan entitas baru dengan segera, tetapi menemukannya setelah sekitar setengah detik.
Namun, berjalan melawan server Google yang sebenarnya, saya belum melihat perilaku itu. Mereka mencoba membuat klien Datastore Anda selalu berjalan melawan server yang sama di sisi mereka, jadi biasanya setiap perubahan segera tercermin dalam kueri.
Saran saya untuk pengujian integrasi adalah menjalankannya terhadap server nyata, dan kemudian Anda mungkin tidak perlu melakukan polling palsu atau penundaan untuk mendapatkan hasil Anda.
sumber