نوشتن دونده آزمون IRemoteTest تکه‌تکه

هنگام نوشتن یک اجراکننده آزمایش، مهم است که به مقیاس‌پذیری فکر کنید. از خودتان بپرسید «اگر دونده آزمون من مجبور بود ۲۰۰ هزار مورد آزمون را اجرا کند» چقدر طول می‌کشید؟

«تکه‌تکه کردن» یکی از پاسخ‌های موجود در «فدراسیون تجارت» است. این کار مستلزم تقسیم کردن همه آزمایش‌هایی است که اجراکننده نیاز دارد به چند بخش که بتوانند به‌صورت موازی اجرا شوند.

این صفحه نحوه قابل‌تکه کردن دونده برای Tradefed را شرح می‌دهد.

میانایی برای پیاده‌سازی

مهم‌ترین میانای تکی که باید پیاده‌سازی شود تا TF آن را قابل‌تقسیم درنظر بگیرد IShardableTest است که دو روش دارد: split(int numShard) و split().

اگر تقسیم‌بندی شما به تعداد تکه‌های درخواستی بستگی دارد، باید split(int numShard) را پیاده‌سازی کنید. درغیراین‌صورت، split() را پیاده‌سازی کنید.

وقتی فرمان آزمایشی TF با پارامترهای قطعه‌بندی --shard-count و --shard-index اجرا می‌شود، TF همه IRemoteTest را تکرار می‌کند تا مواردی را که IShardableTest را پیاده‌سازی می‌کنند پیدا کند. درصورت پیدا شدن، split را فراخوانی می‌کند تا شیء IRemoteTest جدیدی برای اجرای زیرمجموعه‌ای از چارچوب‌های تست برای تکه خاصی دریافت کند.

درباره پیاده‌سازی تقسیم چه چیزی باید بدانم؟

  • دونده شما ممکن است فقط تحت شرایط خاصی تقسیم شود؛ در این صورت، وقتی تقسیم نشدید، null را برگردانید.
  • تا جایی که منطقی است، سعی کنید آن را تقسیم کنید: دونده‌تان را به واحدهای اجرایی تقسیم کنید که برای آن منطقی باشد. این واقعاً به دونده شما بستگی دارد. برای مثال: HostTest در سطح «کلاس» تکه‌تکه می‌شود، هر کلاس آزمایش در یک تکه جداگانه قرار می‌گیرد.
  • اگر منطقی است، چند گزینه برای کنترل کمی از تکه‌تکه کردن اضافه کنید. برای مثال: AndroidJUnitTest دارای ajur-max-shard برای مشخص کردن حداکثر تعداد قطعاتی است که می‌تواند به آن‌ها تقسیم شود، صرف‌نظر از تعداد درخواست‌شده.

پیاده‌سازی نمونه با جزئیات

در اینجا نمونه‌ای از تکه‌کد پیاده‌سازی IShardableTest آورده شده است که می‌توانید به آن مراجعه کنید. کد کامل در اینجا دردسترس است (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;
    }
    ...
}

این مثال به‌سادگی نمونه جدیدی از خود ایجاد می‌کند و پارامترهای تکه‌تکه کردن را برای آن تنظیم می‌کند. بااین‌حال، منطق تقسیم می‌تواند از آزمایشی به آزمایش دیگر کاملاً متفاوت باشد؛ و تا زمانی که قطعی باشد و زیرمجموعه‌های جامع را به‌صورت جمعی تولید کند، مشکلی ندارد.

استقلال

تکه‌ها باید مستقل باشند! دو تکه ایجادشده توسط پیاده‌سازی شما از split در دونده نباید به یکدیگر وابستگی داشته باشند یا منابع را هم‌رسانی کنند.

تقسیم کردن تکه‌ها باید قطعی باشد! با توجه به شرایط یکسان، این مورد نیز الزامی است، روش split شما باید همیشه فهرست دقیقاً یکسانی از تکه‌تکه کردن‌ها را به همان ترتیب برگرداند.

توجه: ازآنجایی‌که هر تکه می‌تواند روی نمونه‌های TF مختلفی اجرا شود، بسیار مهم است که مطمئن شوید منطق split زیرمجموعه‌هایی را تولید می‌کند که به‌صورت قطعی منحصراً متقابل و به‌صورت جمعی جامع هستند.

آزمایشی را به‌صورت محلی تقسیم کنید

برای تکه‌تکه کردن آزمایش در TF محلی، می‌توانید به‌سادگی گزینه --shard-count را به خط فرمان اضافه کنید.

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

سپس TF به‌طور خودکار فرمان‌هایی را برای هر قطعه ایجاد می‌کند و آن‌ها را اجرا می‌کند.

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)

انبوهش نتیجه آزمایش

ازآنجایی‌که TF هیچ انبوهش نتیجه آزمایشی برای فراخوانی‌های تکه‌تکه انجام نمی‌دهد، باید مطمئن شوید که سرویس گزارش‌دهی شما از آن پشتیبانی می‌کند.