Bölünmüş IRemoteTest test çalıştırıcı yazma

Test çalıştırıcı yazarken ölçeklenebilirliği göz önünde bulundurmak önemlidir. Kendinize "Test çalıştırıcım 200 bin test durumu çalıştırmak zorunda kalsaydı bu ne kadar sürerdi?" diye sorun.

Parçalama, Ticaret Federasyonu'nda mevcut olan yanıtlardan biridir. Çalıştırıcının ihtiyaç duyduğu tüm testlerin paralelleştirilebilecek birkaç parçaya bölünmesi gerekir.

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 edilmek için uygulanması gereken en önemli arayüz IShardableTest'tir. Bu arayüzde iki yöntem bulunur: split(int numShard) ve split().

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

Parçalama parametreleri --shard-count ve --shard-index ile bir TF testi komutu yürütüldüğünde TF, IShardableTest uygulayanları bulmak için tüm IRemoteTest öğelerini yineler. Bulunursa belirli bir parça için test durumlarının bir alt kümesini çalıştırmak üzere yeni bir IRemoteTest nesnesi almak için split işlevini çağırır.

Bölünmüş uygulama hakkında bilmem gerekenler nelerdir?

  • Koşucunuz yalnızca belirli koşullarda parçalama yapabilir. Bu durumda, parçalama yapmadığınızda null değerini döndürün.
  • Mümkün olduğunca fazla bölmeye çalışın: Çalıştırıcınızı, kendisi için mantıklı olan yürütme birimlerine bölün. Bu, koşucunuza bağlıdır. Örneğin: HostTest sınıf düzeyinde parçalanır ve her test sınıfı ayrı bir parçaya yerleştirilir.
  • Gerekirse parçalama işlemini biraz kontrol etmek için bazı seçenekler ekleyin. Örneğin: AndroidJUnitTest istenilen sayıdan bağımsız olarak, bölünebileceği maksimum parça sayısını belirtmek için ajur-max-shard içerir.

Ayrıntılı örnek uygulama

Aşağıda, IShardableTest'yı uygulayan örnek bir kod snippet'i verilmiştir. Tam kod şu adreste mevcuttur: (https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/android17-release/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 örnek, yalnızca kendisinin yeni bir örneğini oluşturur ve parçalama parametrelerini ayarlar. Ancak bölme mantığı testten teste tamamen farklı olabilir. Belirleyici olduğu ve toplu olarak kapsamlı alt kümeler oluşturduğu sürece sorun yoktur.

Independence

Parçalar birbirinden bağımsız olmalıdır. Çalıştırıcınızda split uygulamanızla oluşturulan iki parça, birbirine bağımlı olmamalı veya kaynakları paylaşmamalıdır.

Parçaların bölünmesi deterministik olmalıdır. Aynı koşullar göz önüne alındığında bu da zorunludur. split yönteminiz her zaman aynı parçalar listesini aynı sırada döndürmelidir.

NOT: Her parça farklı TF örneklerinde çalışabileceğinden, split mantığının, karşılıklı olarak hariç tutulan ve toplu olarak kesin bir şekilde kapsamlı olan alt kümeler oluşturduğundan emin olmak çok önemlidir.

Bir testi yerel olarak parçalama

Yerel bir TF'de testi parçalamak için komut satırına --shard-count seçeneğini eklemeniz yeterlidir.

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

Ardından TF, her parça için otomatik olarak komutlar oluşturur 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çalanmış çağırmalar için herhangi bir test sonucu toplama işlemi yapmadığından raporlama hizmetinizin bunu desteklediğinden emin olmanız gerekir.