Parçalı IRemoteTest test çalıştırıcısı yazma

Test çalıştırıcısı yazarken ölçeklenebilirliği göz önünde bulundurmak önemlidir. Soru "test çalıştırıcımın 200 bin test durumu çalıştırması gerektiyse" ne kadar sürer?

Bölme, Trade Federation'da sunulan çözümlerden biridir. Bu, çalıştırıcının ihtiyaç duyduğu tüm testlerin paralelleştirilebilecek birkaç parçaya bölünmesini gerektirir.

Bu sayfada, çalıştırıcınızın Tradefed için nasıl parçalara ayrılabileceği açıklanmaktadır.

Uygulanacak arayüz

TF tarafından parçalanabilir olarak kabul edilmek için uygulanması gereken en önemli arayüz IShardableTest'tir. Bu arayüz, split(int numShard) ve split() olmak üzere iki yöntem içerir.

Parçalama işleminiz istenen parça sayısına bağlı olacaksa split(int numShard) öğesini uygulamalıdır. Aksi takdirde split() uygulayın.

Bir TF test komutu, --shard-count ve --shard-index bölme parametreleriyle yürütüldüğünde TF, IShardableTest'ı uygulayan IRemoteTest öğelerini aramak için tüm IRemoteTest öğelerini iteratif olarak tarar. Bulunursa belirli bir bölüm için test durumlarının bir alt kümesini çalıştırmak üzere yeni bir IRemoteTest nesnesi almak için split çağrılır.

Bölme uygulaması hakkında bilmem gerekenler neler?

  • Koşucunuz yalnızca bazı koşullarda kırılabilir; bu durumda şunu döndürün: null siz kırık kırmadınız.
  • Mantıklı olduğu kadar bölmeye çalışın: koşucuyu üçe bölün. yürütmenin en iyi yöntemi budur. Bu tamamen koşucunuza göre değişir. Örneğin, örnek: Ana Makine Testi her test sınıfı ayrı bir parçaya yerleştirilir.
  • Mantıklıysa parçalamayı biraz kontrol etmek için bazı seçenekler ekleyin. Örnek: AndroidJUnitTest maksimum parça sayısını belirtmek için bir ajur-max-shard öğesine sahip bölünmesini istemeyiz.

Ayrıntılı örnek uygulama

Referans olarak kullanabileceğiniz IShardableTest uygulamasını gösteren örnek bir kod snippet'i aşağıda verilmiştir. Tam kodu şu adreste bulabilirsiniz: (https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/main/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;
    }
    ...
}

Bu örnekte, kendi yeni bir örneği oluşturulur ve bu örnek için bölüm parametreleri ayarlanır. Ancak bölme mantığı, testten teste tamamen farklı olabilir. Belirleyici olduğu ve toplu olarak kapsamlı alt kümeler sağladığı sürece bu sorun teşkil etmez.

Bağımsızlık

Parçaların bağımsız olması gerekir. Koşucunuzdaki split karakterinin birbirine bağımlılığı olmamalıdır. kaynaklar.

Parçaların bölünmesi deterministik olmalıdır. Geçerli olduğu sürece aynı koşullar altında, split yönteminiz her zaman aynı anahtar kelime listesini döndürmelidir aynı sıraya sokar.

NOT: Her kırık farklı TF örneklerinde çalışabileceğinden split mantığının birbirini dışlayan ve birbirini dışlayan alt kümeler getirdiğinden emin olun. ayrıntılı bir şekilde ele alacağız.

Testi yerel olarak parçalama

Bir testi yerel TF'de parçalamak için, arka planda --shard-count seçeneğini eklemeniz yeterlidir. komut satırını kullanın.

tf >run host --class com.android.tradefed.UnitTests --shard-count 3

Ardından TF, her kırık için otomatik olarak komutlar üretir ve bunları çalıştırı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çalara ayrılmış çağrılar için herhangi bir test sonucu toplama işlemi yapmadığından, raporlama hizmetinizin bunu desteklediğinden emin olmanız gerekir.