Saat menulis test runner, penting untuk memikirkan skalabilitas. Tanyakan pada diri Anda sendiri, "jika test runner saya harus menjalankan 200K test case" berapa lama waktu yang dibutuhkan?
Sharding adalah salah satu jawaban yang tersedia di Federasi Perdagangan. Ini membutuhkan pemisahan semua tes yang dibutuhkan pelari menjadi beberapa bagian yang dapat diparalelkan.
Halaman ini menjelaskan cara membuat runner Anda dapat di-shardable untuk Tradefed.
Antarmuka untuk diimplementasikan
Satu-satunya antarmuka yang paling penting untuk diterapkan agar dianggap dapat dipecah oleh TF adalah IShardableTest , yang berisi dua metode: split(int numShard)
dan split()
.
Jika sharding Anda akan bergantung pada jumlah shard yang diminta, Anda harus mengimplementasikan split(int numShard)
. Jika tidak, implementasikan split()
.
Ketika perintah pengujian TF dijalankan dengan parameter sharding --shard-count
dan --shard-index
, TF mengulangi semua IRemoteTest
untuk mencari yang mengimplementasikan IShardableTest
. Jika ditemukan, itu akan memanggil split
untuk mendapatkan objek IRemoteTest
baru untuk menjalankan subset kasus uji untuk pecahan tertentu.
Apa yang harus saya ketahui tentang implementasi split?
- Pelari Anda hanya boleh melakukan shard pada beberapa kondisi; dalam hal ini kembalikan
null
ketika Anda tidak melakukan shard. - Cobalah untuk membagi sebanyak yang masuk akal: bagi pelari Anda menjadi unit eksekusi yang masuk akal untuk itu. Itu sangat tergantung pada pelari Anda. Misalnya: HostTest di-shard di tingkat Class, setiap kelas tes diletakkan di shard terpisah.
- Jika masuk akal, tambahkan beberapa opsi untuk sedikit mengontrol sharding. Misalnya: AndroidJUnitTest memiliki
ajur-max-shard
untuk menentukan jumlah maksimum shard yang dapat dibagi, berapa pun jumlah yang diminta.
Contoh implementasi terperinci
Berikut adalah contoh cuplikan kode yang mengimplementasikan IShardableTest
yang dapat Anda rujuk. Kode lengkap tersedia di (https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/master/test_framework/com/android/tradefed/testtype/InstalledInstrumentationsTest.java)
/**
* Runs all instrumentation found on current device.
*/
@OptionClass(alias = "installed-instrumentation")
public class InstalledInstrumentationsTest
implements IDeviceTest, IResumableTest, IShardableTest {
...
/** {@inheritDoc} */
@Override
public Collection<IRemoteTest> split(int shardCountHint) {
if (shardCountHint > 1) {
Collection<IRemoteTest> shards = new ArrayList<>(shardCountHint);
for (int index = 0; index < shardCountHint; index++) {
shards.add(getTestShard(shardCountHint, index));
}
return shards;
}
// Nothing to shard
return null;
}
private IRemoteTest getTestShard(int shardCount, int shardIndex) {
InstalledInstrumentationsTest shard = new InstalledInstrumentationsTest();
try {
OptionCopier.copyOptions(this, shard);
} catch (ConfigurationException e) {
CLog.e("failed to copy instrumentation options: %s", e.getMessage());
}
shard.mShardIndex = shardIndex;
shard.mTotalShards = shardCount;
return shard;
}
...
}
Contoh ini hanya membuat instance baru dari dirinya sendiri dan menetapkan parameter shard ke dalamnya. Namun, logika pemisahan bisa sangat berbeda dari tes ke tes; dan selama itu deterministik dan menghasilkan himpunan bagian yang lengkap secara kolektif, tidak apa-apa.
Kemerdekaan
Pecahan harus mandiri! Dua pecahan yang dibuat oleh implementasi split
Anda di runner Anda tidak boleh memiliki ketergantungan satu sama lain atau berbagi sumber daya.
Pemisahan pecahan harus deterministik! Ini juga wajib, mengingat kondisi yang sama, metode split
Anda harus selalu mengembalikan daftar pecahan yang sama persis dalam urutan yang sama.
CATATAN: Karena setiap shard dapat berjalan pada instans TF yang berbeda, sangat penting untuk memastikan logika split
menghasilkan subset yang saling eksklusif dan lengkap secara kolektif dengan cara yang deterministik.
Cara shard tes secara lokal
Untuk shard tes pada TF lokal, Anda cukup menambahkan opsi --shard-count
ke baris perintah.
tf >run host --class com.android.tradefed.UnitTests --shard-count 3
Kemudian TF akan secara otomatis menelurkan perintah untuk setiap pecahan dan menjalankannya.
tf >l i
Command Id Exec Time Device State
3 0m:03 [null-device-2] running stub on build 0 (shard 1 of 3)
3 0m:03 [null-device-1] running stub on build 0 (shard 0 of 3)
3 0m:03 [null-device-3] running stub on build 0 (shard 2 of 3)
Agregasi hasil tes
Karena TF tidak melakukan agregasi hasil pengujian apa pun untuk pemanggilan sharded, Anda perlu memastikan layanan pelaporan Anda mendukungnya.