Menulis runner pengujian IRemoteTest yang di-sharding

Saat menulis runner pengujian, penting untuk mempertimbangkan skalabilitas. Tanya diri Anda sendiri, "jika runner pengujian saya harus menjalankan 200 ribu {i>test case<i}" berapa lama waktu yang dibutuhkan?

Sharding adalah salah satu jawaban yang tersedia di Federasi Perdagangan. Memerlukan membagi semua pengujian yang diperlukan {i>runner<i} menjadi beberapa bagian yang dapat diparalelkan.

Halaman ini menjelaskan cara membuat runner Anda dapat di-sharding untuk Tradefed.

Antarmuka yang akan diimplementasikan

Satu-satunya antarmuka terpenting yang harus diimplementasikan agar dianggap dapat di-sharding oleh TF adalah IShardableTest, yang berisi dua metode: split(int numShard) dan split().

Jika sharding Anda bergantung pada jumlah shard yang diminta, Anda harus menerapkan split(int numShard). Jika tidak, terapkan split().

Saat perintah pengujian TF dijalankan dengan parameter sharding --shard-count dan --shard-index, TF melakukan iterasi melalui semua IRemoteTest untuk mencari satu menerapkan IShardableTest. Jika ditemukan, split akan dipanggil untuk dapatkan objek IRemoteTest baru untuk menjalankan subset kasus pengujian dengan sharding.

Apa yang harus saya ketahui tentang penerapan pemisahan?

  • Runner Anda dapat melakukan sharding pada beberapa kondisi saja; dalam hal ini, tampilkan null saat Anda tidak melakukan sharding.
  • Cobalah untuk membagi sebanyak mungkin: bagi pelari Anda menjadi beberapa unit yang sesuai. Semua tergantung pada pelari Anda. Sebagai contoh: HostTest di-sharding di tingkat Kelas, setiap class pengujian ditempatkan di shard terpisah.
  • Jika memungkinkan, tambahkan beberapa opsi untuk sedikit mengontrol sharding. Contoh: AndroidJUnitTest memiliki ajur-max-shard untuk menentukan jumlah maksimum shard yang dapat dipisah, berapa pun jumlah yang diminta.

Contoh implementasi yang mendetail

Berikut adalah contoh cuplikan kode yang mengimplementasikan IShardableTest yang dapat Anda alamat IP internal. Kode lengkapnya tersedia di (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;
    }
    ...
}

Contoh ini hanya membuat instance baru sendiri dan menetapkan shard parameter pada token tersebut. Namun, logika pemisahan bisa sangat berbeda dari uji untuk diuji; dan selama bersifat determenistik dan menghasilkan kolektif subset yang lengkap, tidak apa-apa.

Kemerdekaan

Shard harus bersifat independen. Dua shard yang dibuat oleh penerapan Anda split di runner tidak boleh saling bergantung atau berbagi Google Cloud Platform.

Pemisahan shard harus bersifat determenistik. Hal ini juga wajib dilakukan, mengingat kondisi yang sama, metode split Anda harus selalu menampilkan daftar sharding dalam urutan yang sama.

CATATAN: Karena setiap shard dapat berjalan pada instance TF yang berbeda, sangat penting untuk memastikan logika split menghasilkan subset yang sama eksklusifnya dan secara kolektif menyeluruh dengan cara yang determenistik.

Melakukan sharding pengujian secara lokal

Untuk melakukan sharding pengujian pada TF lokal, Anda cukup menambahkan opsi --shard-count untuk baris perintah.

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

Kemudian TF akan otomatis memunculkan perintah untuk setiap shard 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 pengujian

Karena TF tidak melakukan agregasi hasil pengujian untuk pemanggilan shard, Anda butuhkan untuk memastikan layanan pelaporan Anda mendukungnya.