آزمایش تخصیص

این یک معرفی مختصر از نگاشت آزمایش و توضیحاتی درباره نحوه شروع پیکربندی آزمایش‌ها در «پروژه منبع باز Android»‏ (AOSP) است.

درباره تخصیص آزمایش

آزمایش نگاشت رویکردی مبتنی بر Gerrit است که به توسعه‌دهندگان امکان می‌دهد قوانین آزمایش پیش‌ارسال و پس‌ارسال را مستقیماً در درخت منبع Android ایجاد کنند و تصمیم‌گیری درباره شاخه‌ها و دستگاه‌های مورد آزمایش را به زیرساخت آزمایش واگذار کنند. تعاریف نگاشت آزمایشی فایل‌های JSON با نام TEST_MAPPING هستند که می‌توانید آن‌ها را در هر دایرکتوری منبعی قرار دهید.

Atest می‌تواند از فایل‌های TEST_MAPPING برای اجرای آزمایش‌های پیش‌ارسال در دایرکتوری‌های مرتبط استفاده کند. با نگاشت آزمایش، می‌توانید مجموعه یکسانی از آزمایش‌ها را با حداقل تغییر در درخت منبع Android به بررسی‌های پیش‌از ارسال اضافه کنید.

این نمونه‌ها را ببینید:

نگاشت آزمایشی برای اجرای آزمایش‌ها و گزارش نتایج به مجموعه داده‌های تست Trade Federation (TF) متکی است.

تعریف گروه‌های آزمایش

آزمایش کردن گروه‌های نگاشت با گروه آزمایشی. نام گروه آزمایش می‌تواند هر رشته‌ای باشد. برای مثال، پیش‌ارسال می‌تواند نام گروهی از آزمایش‌ها باشد که هنگام اعتبارسنجی تغییرات اجرا می‌شود. و postsubmit می‌تواند آزمایش‌هایی باشد که برای اعتبارسنجی ساخت‌ها پس‌از ادغام تغییرات استفاده می‌شود.

قوانین دستورگان ساخت بسته

برای اینکه مجموعه داده‌های تست Trade Federation بتواند ماژول‌های تست را برای ساخت مشخصی اجرا کند، این ماژول‌ها باید test_suites برای Soong یا LOCAL_COMPATIBILITY_SUITE برای Make در یکی از این دو مجموعه تنظیم شده باشد:

  • general-tests برای آزمایش‌هایی است که به قابلیت‌های مختص دستگاه (مثل سخت‌افزار مختص فروشنده که اکثر دستگاه‌ها ندارند) وابسته نیستند. اکثر آزمایش‌ها باید در مجموعه general-tests باشند، حتی اگر مختص یک ABI یا بیت‌گرایی یا ویژگی‌های سخت‌افزاری مانند HWASan باشند (یک هدف test_suites جداگانه برای هر ABI وجود دارد)، و حتی اگر مجبور باشند روی یک دستگاه اجرا شوند.
  • device-tests برای آزمایش‌هایی است که به قابلیت‌های ویژه دستگاه بستگی دارند. معمولاً این آزمایش‌ها در بخش vendor/ قرار دارند. ویژه دستگاه فقط به قابلیت‌هایی اشاره دارد که مختص یک دستگاه است، بنابراین این مورد هم برای آزمایش‌های JUnit و هم برای آزمایش‌های GTest (که معمولاً باید به‌عنوان general-tests علامت‌گذاری شوند، حتی اگر مختص ABI باشند) اعمال می‌شود.

نمونه‌ها:

Android.bp: test_suites: ["general-tests"],
Android.mk: LOCAL_COMPATIBILITY_SUITE := general-tests

پیکربندی آزمایش‌ها برای اجرا در مجموعه آزمایش

برای اینکه آزمایشی در مجموعه آزمایشی اجرا شود، آزمایش باید:

  • نباید هیچ ارائه‌دهنده ساخت داشته باشد.
  • باید پس‌از اتمام، پاک‌سازی کند، برای مثال، با حذف کردن هرگونه فایل موقتی که درطول آزمایش تولید شده است.
  • باید تنظیمات سیستم را به مقدار پیش‌فرض یا اصلی تغییر دهید.
  • نباید فرض شود که دستگاه در وضعیت خاصی است، برای مثال، آماده ریشه‌یابی است. اکثر آزمایش‌ها برای اجرا به امتیاز ریشه نیاز ندارند. اگر آزمایشی باید به دسترسی ریشه نیاز داشته باشد، باید این مورد را با RootTargetPreparer در AndroidTest.xml خود مشخص کند، مانند مثال زیر:

    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
    

ایجاد فایل‌های نگاشت آزمایشی

برای دایرکتوری‌ای که به پوشش آزمایش نیاز دارد، TEST_MAPPING فایل JSON شبیه به مثال اضافه کنید. این قوانین تضمین می‌کنند که وقتی هر فایلی در آن فهرست راهنما یا هریک از زیرفهرست‌های راهنمای آن تغییر می‌کند، آزمایش‌ها در بررسی‌های پیش‌از ارسال اجرا می‌شوند.

دنبال کردن نمونه

در اینجا نمونه‌ای از فایل TEST_MAPPING آورده شده است (این فایل در قالب JSON است اما از نظرات پشتیبانی می‌کند):

{
  "presubmit": [
    // JUnit test with options and file patterns.
    {
      "name": "CtsWindowManagerDeviceTestCases",
      "options": [
        {
          "include-annotation": "android.platform.test.annotations.RequiresDevice"
        }
      ],
      "file_patterns": ["(/|^)Window[^/]*\\.java", "(/|^)Activity[^/]*\\.java"]
    },
    // Device-side GTest with options.
    {
      "name" : "hello_world_test",
      "options": [
        {
          "native-test-flag": "\"servicename1 servicename2\""
        },
        {
          "native-test-timeout": "6000"
        }
      ]
    }
    // Host-side GTest.
    {
      "name" : "net_test_avrcp",
      "host" : true
    }
  ],
  "postsubmit": [
    {
      "name": "CtsDeqpTestCases",
      "options": [
        {
          // Use regex in include-filter which is supported in AndroidJUnitTest
          "include-filter": "dEQP-EGL.functional.color_clears.*"
        }
      ]
    }
  ],
  "imports": [
    {
      "path": "frameworks/base/services/core/java/com/android/server/am"
    }
  ]
}

تنظیم مشخصه‌ها

در مثال، presubmit و postsubmit نام هر گروه آزمایشی است. برای اطلاعات بیشتر درباره گروه‌های آزمایشی، به تعریف گروه‌های آزمایشی مراجعه کنید.

می‌توانید نام واحد آزمایش یا نام آزمایش یکپارچه‌سازی «فدراسیون تجارت» (مسیر منبع به فایل XML آزمایش، برای مثال، uiautomator/uiautomator-demo) را در مقدار مشخصه name تنظیم کنید. توجه داشته باشید که فیلد name نمی‌تواند از کلاس name یا روش آزمایش name استفاده کند. برای محدود کردن آزمایش‌هایی که باید اجرا شوند، از گزینه‌هایی مثل include-filter استفاده کنید. include-filter نمونه استفاده را ببینید.

تنظیم host یک آزمایش نشان می‌دهد که آیا آزمایش بدون دستگاه است و روی میزبان اجرا می‌شود یا نه. مقدار پیش‌فرض false است، یعنی آزمایش برای اجرا شدن به دستگاه نیاز دارد. انواع آزمایش‌های پشتیبانی‌شده عبارت‌اند از HostGTest برای دودویی‌های GTest و HostTest برای آزمایش‌های JUnit.

بااستفاده از مشخصه file_patterns می‌توانید فهرستی از رشته‌های عبارت باقاعده را برای مطابقت دادن مسیر نسبی هر فایل کد منبع (نسبت به دایرکتوری حاوی فایل TEST_MAPPING) تنظیم کنید. در مثال، test CtsWindowManagerDeviceTestCases فقط زمانی در پیش‌ارسال اجرا می‌شود که فایل Java با Window یا Activity شروع شود، که در همان پوشه فایل TEST_MAPPING یا هریک از زیرپوشه‌های آن وجود دارد. خطوط مورب معکوس (\\) باید گریز داده شوند زیرا در فایل JSON هستند.

وارد کردن فایل‌های TEST_MAPPING

بااستفاده از مشخصه imports می‌توانید آزمایش‌ها را در فایل‌های TEST_MAPPING دیگر بدون کپی کردن محتوا اضافه کنید. فایل‌های TEST_MAPPING در دایرکتوری‌های والد مسیر واردشده نیز گنجانده شده‌اند. ‫TEST_MAPPING وارد کردن تودرتو را مجاز می‌کند، یعنی فایل‌های واردشده می‌توانند خودشان فایل‌های TEST_MAPPING دیگری را وارد کنند، و نگاشت آزمایشی می‌تواند آزمایش‌های گنجانده‌شده را ادغام کند.

TEST_MAPPING از وارد کردن در سطح ریشه و سطح گروه پشتیبانی می‌کند:

  • وارد کردن در سطح ریشه: در سطح بالای فایل TEST_MAPPING (خارج از هر گروه آزمایشی) مشخص شده است. وارد کردن سطح ریشه کل فایل TEST_MAPPING هدف (و دایرکتوری‌های والد آن) را وارد می‌کند، انگار در مسیری که به آن وارد می‌شود نوشته شده است. همه تعریف‌های گروه آزمایشی در فایل واردشده (برای نمونه، presubmit، postsubmit) در گروه‌های آزمایشی متناظر فایل واردکننده ادغام می‌شوند.
  • وارد کردن در سطح گروه: مستقیماً در داخل یک گروه آزمایشی خاص مشخص می‌شود (مانند presubmit یا postsubmit). وارد کردن در سطح گروه به‌طور دقیق به آن گروه آزمایشی محدود می‌شود، به این معنی که فقط آزمایش‌های تعریف‌شده تحت آن گروه خاص در فایل TEST_MAPPING هدف وارد خواهند شد. همه گروه‌های آزمایشی دیگر در فایل هدف نادیده گرفته می‌شوند.

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

نمونه‌ای از وارد کردن سطح ریشه:

{
  "imports": [
    {
      "path": "frameworks/base/services/core"
    }
  ],
  "presubmit": [
    {
      "name": "MyTestModule"
    }
  ]
}

نمونه‌ای از وارد کردن سطح گروه:

{
  "presubmit": [
    {
      "name": "MyTestModule"
    },
    {
      "imports": [
        {
          "path": "frameworks/base/services/core"
        }
      ]
    }
  ],
  "postsubmit": [
    {
      "imports": [
        {
          "path": "frameworks/base/services/accessibility"
        }
      ]
    }
  ]
}

مشخصه options حاوی گزینه‌های خط فرمان Tradefed اضافی است.

برای دریافت فهرست کامل گزینه‌های دردسترس برای آزمایشی معین، این فرمان را اجرا کنید:

tradefed.sh run commandAndExit [test_module] --help

برای جزئیات بیشتر درباره نحوه عملکرد گزینه‌ها، به مدیریت گزینه‌ها در Tradefed مراجعه کنید.

اعتبارسنجی‌های TEST_MAPPING

هنگام ارسال تغییراتی که TEST_MAPPING فایل را اصلاح می‌کنند، بررسی‌های پیش‌ارسال اجرا می‌شود تا از صحت آن‌ها اطمینان حاصل شود:

  • اعتبارسنجی الگوی فایل: تضمین می‌کند که همه عبارات باقاعده در file_patterns حداقل با یک فایل در مخزن مطابقت داشته باشند. الگوهای قدیمی که با هیچ فایلی مطابقت ندارند باعث می‌شوند بررسی ناموفق باشد.
  • اعتبارسنجی زمان ساخت: هشدارهای اعتبارسنجی زمان ساخت را که ساخت جمع‌آوری می‌کند به خطاهای مسدودکننده در پیش‌ارسال برای شاخه‌های اصلی ارتقا می‌دهد. هشدارهای رایج شامل موارد زیر می‌شود:
    • پیمانه‌هایی که وجود ندارند: ارجاع به نام پیمانه آزمایشی که در پایگاه کد وجود ندارد، مثلاً وقتی نام دارای غلط املایی است.
    • واردات نامعتبر: مسیرهای مرجع در imports که وجود ندارند یا حاوی فایل TEST_MAPPING نیستند.
    • مشکلات طرح‌واره: استفاده از کلیدهای پشتیبانی‌نشده یا ساختارهای بدشکل در پیکربندی JSON.

اجرای آزمایش‌ها با Atest

برای اجرای قوانین آزمایش پیش‌ارسال به‌صورت محلی:

  1. به دایرکتوری حاوی فایل TEST_MAPPING بروید.
  2. فرمان را اجرا کنید:

    atest
    

همه آزمایش‌های پیش‌ارسال پیکربندی‌شده در فایل‌های TEST_MAPPING دایرکتوری فعلی و دایرکتوری‌های والد آن اجرا می‌شوند. ‫Atest دو آزمایش را برای پیش‌ارسال (A و B) پیدا و اجرا می‌کند.

این ساده‌ترین راه برای اجرای آزمایش‌های پیش‌از ارسال در TEST_MAPPING فایل در دایرکتوری کاری فعلی (CWD) و دایرکتوری‌های والد است. ‫Atest فایل TEST_MAPPING را در CWD و همه دایرکتوری‌های والد آن پیدا می‌کند و از آن استفاده می‌کند.

کد منبع ساختار

این مثال نشان می‌دهد که چگونه می‌توانید فایل‌های TEST_MAPPING را در سراسر درخت منبع پیکربندی کنید:

src
├── project_1
│   └── TEST_MAPPING
├── project_2
│   └── TEST_MAPPING
└── TEST_MAPPING

محتوای src/TEST_MAPPING:

{
  "presubmit": [
    {
      "name": "A"
    }
  ]
}

محتوای src/project_1/TEST_MAPPING:

{
  "presubmit": [
    {
      "name": "B"
    }
  ],
  "postsubmit": [
    {
      "name": "C"
    }
  ],
  "other_group": [
    {
      "name": "X"
    }
  ]}

محتوای src/project_2/TEST_MAPPING:

{
  "presubmit": [
    {
      "name": "D"
    }
  ],
  "import": [
    {
      "path": "src/project_1"
    }
  ]}

مشخص کردن دایرکتوری‌های هدف

می‌توانید دایرکتوری هدفی را مشخص کنید تا آزمایش‌ها در TEST_MAPPING فایل در آن دایرکتوری اجرا شود. فرمان زیر دو آزمایش (A،‏ B) را اجرا می‌کند:

atest --test-mapping src/project_1

اجرای قوانین آزمایش پس‌از ارسال

همچنین می‌توانید از این فرمان برای اجرای قوانین آزمایش پس‌از ارسال تعریف‌شده در TEST_MAPPING در src_path (پیش‌فرض CWD) و دایرکتوری‌های والد آن استفاده کنید:

atest [--test-mapping] [src_path]:postsubmit

فقط آزمایش‌هایی را اجرا کنید که به دستگاه نیاز ندارند

می‌توانید از گزینه --host برای Atest استفاده کنید تا فقط آزمایش‌هایی را اجرا کند که برای میزبان پیکربندی شده‌اند و به دستگاه نیاز ندارند. بدون این گزینه، Atest هر دو نوع آزمایش را اجرا می‌کند، آزمایش‌هایی که به دستگاه نیاز دارند و آزمایش‌هایی که در میزبانی اجرا می‌شوند که به دستگاه نیاز ندارد. آزمایش‌ها در دو مجموعه جداگانه اجرا می‌شوند:

atest [--test-mapping] --host

شناسایی گروه‌های آزمایشی

می‌توانید گروه‌های آزمایش را در فرمان Atest مشخص کنید. فرمان زیر همه postsubmit آزمایش‌های مربوط به فایل‌های فهرست راهنمای src/project_1 را اجرا می‌کند، که فقط یک آزمایش (C) دارد.

یا می‌توانید از :all برای اجرای همه آزمایش‌ها بدون درنظر گرفتن گروه استفاده کنید. دستور زیر چهار آزمایش (A،‏ B،‏ C،‏ X) را اجرا می‌کند:

atest --test-mapping src/project_1:all

گنجاندن زیرپوشه‌ها

به‌طور پیش‌فرض، اجرای آزمایش‌ها در TEST_MAPPING با Atest فقط آزمایش‌های پیش‌ارسال پیکربندی‌شده در فایل TEST_MAPPING در CWD (یا دایرکتوری داده‌شده) و دایرکتوری‌های والد آن را اجرا می‌کند. اگر می‌خواهید آزمایش‌ها را در همه TEST_MAPPING فایل‌های موجود در زیرشاخه‌ها اجرا کنید، از گزینه --include-subdir برای اجبار کردن Atest برای افزودن آن آزمایش‌ها نیز استفاده کنید.

atest --include-subdir

بدون گزینه --include-subdir،‏ Atest فقط آزمایش A را اجرا می‌کند. با گزینه --include-subdir،‏ Atest دو آزمایش (A،‏ B) را اجرا می‌کند.

نظر در سطح خط پشتیبانی می‌شود

می‌توانید نظری با قالب // در سطح خط اضافه کنید تا فایل TEST_MAPPING را با شرح تنظیمات بعدی تکمیل کنید. ATest و Trade Federation TEST_MAPPING را به قالب JSON معتبر بدون نظر پیش‌پردازش می‌کنند. برای تمیز نگه داشتن فایل JSON، فقط نظر قالب // سطح خط پشتیبانی می‌شود.

مثال:

{
  // For presubmit test group.
  "presubmit": [
    {
      // Run test on module A.
      "name": "A"
    }
  ]
}