Bir test çalıştırıcısı yazarken ölçeklenebilirliği düşünmek önemlidir. Kendinize şu soruyu sorun: "Eğer test çalıştırıcım 200.000 test senaryosu çalıştırmak zorunda olsaydı" bu ne kadar sürerdi?
Sharding, Ticaret Federasyonu'ndaki mevcut cevaplardan biridir. Koşucunun ihtiyaç duyduğu tüm testleri paralelleştirilebilecek birkaç parçaya bölmeyi gerektirir.
Bu sayfada koşucunuzu Tradefed için nasıl parçalanabilir hale getireceğiniz açıklanmaktadır.
Uygulanacak arayüz
TF tarafından parçalanabilir olarak kabul edilecek en önemli arayüz IShardableTest'tir ve iki yöntem içerir: split(int numShard)
ve split()
.
Parçalamanız istenen parça sayısına bağlı olacaksa split(int numShard)
uygulamanız gerekir. Aksi halde split()
öğesini uygulayın.
Bir TF test komutu --shard-count
ve --shard-index
parçalama parametreleriyle yürütüldüğünde, TF, IShardableTest
uygulayanları aramak için tüm IRemoteTest
boyunca yinelenir. Bulunursa, belirli bir parça için test senaryolarının bir alt kümesini çalıştırmak üzere yeni bir IRemoteTest
nesnesi almak üzere split
çağrısını yapar.
Bölünmüş uygulama hakkında ne bilmeliyim?
- Koşucu yalnızca bazı koşullar altında parçalanabilir; bu durumda parçalamadığınızda
null
değerini döndürün. - Mantıklı olduğu kadar bölmeye çalışın: Koşucunuzu kendisi için anlamlı olan yürütme birimlerine bölün. Bu gerçekten koşucunuza bağlıdır. Örneğin: HostTest, Sınıf düzeyinde parçalanır, her test sınıfı ayrı bir parçaya yerleştirilir.
- Mantıklı geliyorsa, parçalamayı biraz kontrol etmek için bazı seçenekler ekleyin. Örneğin: AndroidJUnitTest, talep edilen sayıdan bağımsız olarak bölünebileceği maksimum parça sayısını belirtmek için bir
ajur-max-shard
sahiptir.
Ayrıntılı örnek uygulama
Burada başvurabileceğiniz IShardableTest
uygulayan örnek bir kod pasajı verilmiştir. Kodun tamamına (https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/main/test_framework/com/android/tradefed/testtype/InstalledInstrumentationsTest.java) adresinden ulaşılabilir.
/**
* 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;
}
...
}
Bu örnek basitçe kendisinin yeni bir örneğini oluşturur ve buna parça parametrelerini ayarlar. Ancak bölme mantığı testten teste tamamen farklı olabilir; ve deterministik olduğu ve kolektif olarak kapsamlı alt kümeler ürettiği sürece sorun yoktur.
Bağımsızlık
Parçaların bağımsız olması gerekiyor! Koşucunuzdaki split
uygulamanız tarafından oluşturulan iki parçanın birbirine bağımlılığı olmamalı veya kaynakları paylaşmamalıdır.
Parça bölünmesinin deterministik olması gerekiyor! Bu aynı zamanda zorunludur, aynı koşullar göz önüne alındığında, split
yönteminiz her zaman aynı parça listesini aynı sırayla döndürmelidir.
NOT: Her parça farklı TF örneklerinde çalışabildiğinden, split
mantığın deterministik bir şekilde birbirini dışlayan ve toplu olarak kapsamlı alt kümeler üretmesini sağlamak kritik öneme sahiptir.
Testi yerel olarak parçalayın
Yerel bir TF'de testi parçalamak için --shard-count
seçeneğini komut satırına eklemeniz yeterlidir.
tf >run host --class com.android.tradefed.UnitTests --shard-count 3
Daha sonra TF, her parça için otomatik olarak komutlar oluşturacak ve bunları çalıştıracaktır.
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)
Test sonucu toplama
TF, parçalı çağrılar için herhangi bir test sonucu toplama işlemi yapmadığından raporlama hizmetinizin bunu desteklediğinden emin olmanız gerekir.