Viết trình chạy thử IRemoteTest đã phân mảnh

Khi viết chương trình chạy thử, điều quan trọng là phải nghĩ đến khả năng mở rộng. Hãy tự hỏi bản thân, "nếu người chạy thử nghiệm của tôi phải chạy 200 nghìn trường hợp thử nghiệm" thì sẽ mất bao lâu?

Sharding là một trong những câu trả lời có sẵn trong Liên đoàn Thương mại. Nó yêu cầu chia tất cả các bài kiểm tra mà người chạy cần thành nhiều phần có thể song song.

Trang này mô tả cách làm cho người chạy của bạn có thể phân mảnh được cho Tradefed.

Giao diện thực hiện

Giao diện quan trọng nhất cần triển khai để được TF coi là có thể phân đoạn được là IShardableTest , chứa hai phương thức: split(int numShard)split() .

Nếu phân đoạn của bạn phụ thuộc vào số lượng phân đoạn được yêu cầu, bạn nên triển khai split(int numShard) . Nếu không, hãy triển khai split() .

Khi lệnh kiểm tra TF được thực thi với các tham số sharding --shard-count--shard-index , TF sẽ lặp qua tất cả IRemoteTest để tìm kiếm những tham số triển khai IShardableTest . Nếu được tìm thấy, nó sẽ gọi lệnh split để lấy đối tượng IRemoteTest mới để chạy một tập hợp con các trường hợp thử nghiệm cho một phân đoạn cụ thể.

Tôi nên biết gì về việc triển khai phân tách?

  • Người chạy của bạn chỉ có thể tuân theo một số điều kiện; trong trường hợp đó trả về null khi bạn không phân đoạn.
  • Cố gắng phân chia càng nhiều càng tốt: chia người chạy của bạn thành đơn vị thực hiện phù hợp với nó. Nó thực sự phụ thuộc vào người chạy của bạn. Ví dụ: HostTest được phân đoạn ở cấp Lớp, mỗi lớp kiểm tra được đặt trong một phân đoạn riêng.
  • Nếu thấy hợp lý, hãy thêm một số tùy chọn để kiểm soát phân đoạn một chút. Ví dụ: AndroidJUnitTestajur-max-shard để chỉ định số lượng phân đoạn tối đa mà nó có thể chia thành, bất kể số lượng được yêu cầu.

Triển khai ví dụ chi tiết

Dưới đây là đoạn mã ví dụ triển khai IShardableTest bạn có thể tham khảo. Mã đầy đủ có sẵn tại (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;
    }
    ...
}

Ví dụ này chỉ đơn giản tạo một phiên bản mới của chính nó và đặt các tham số phân đoạn cho nó. Tuy nhiên, logic phân tách có thể hoàn toàn khác nhau giữa các thử nghiệm; và miễn là nó mang tính xác định và mang lại các tập hợp con đầy đủ thì không sao cả.

Sự độc lập

Các mảnh cần phải độc lập! Hai phân đoạn được tạo bằng cách triển khai tính năng split trong trình chạy của bạn không được phụ thuộc vào nhau hoặc chia sẻ tài nguyên.

Việc chia tách các mảnh cần phải mang tính quyết định! Điều này cũng là bắt buộc, với cùng điều kiện, phương thức split của bạn phải luôn trả về cùng một danh sách các phân đoạn theo cùng một thứ tự.

LƯU Ý: Vì mỗi phân đoạn có thể chạy trên các phiên bản TF khác nhau nên điều quan trọng là phải đảm bảo logic split mang lại các tập hợp con loại trừ lẫn nhau và toàn diện theo cách xác định.

Chia nhỏ bài kiểm tra tại địa phương

Để phân đoạn bài kiểm tra trên TF cục bộ, bạn chỉ cần thêm tùy chọn --shard-count vào dòng lệnh.

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

Sau đó TF sẽ tự động sinh ra các lệnh cho từng phân đoạn và chạy chúng.

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)

Tổng hợp kết quả kiểm tra

Vì TF không thực hiện bất kỳ hoạt động tổng hợp kết quả kiểm tra nào cho các yêu cầu phân đoạn nên bạn cần đảm bảo rằng dịch vụ báo cáo của mình hỗ trợ việc đó.