تست چند دستگاهی

VTS از تست‌هایی که نیاز به تعامل بین چندین دستگاه اندروید دارند، پشتیبانی می‌کند.

معماری

VTS از چارچوب TradeFed برای دریافت و ارسال سریال‌های دستگاه به ماژول‌های آزمایشی استفاده می‌کند.

شکل ۱. سریال‌های دستگاه عبور VTS.

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

تخصیص دستگاه

زیرساخت تست (معمولاً زمان‌بند تست) دستگاه‌های موجود را که الزامات مشخص شده در پیکربندی طرح تست را برآورده می‌کنند، به چارچوب VTS اختصاص می‌دهد. دستگاه‌های اختصاص داده شده برای طرح تست رزرو شده‌اند، حتی اگر ماژول تست از آنها استفاده نکند. سپس فایل‌های باینری عامل VTS به تمام دستگاه‌های اختصاص داده شده ارسال شده و روی آنها اجرا می‌شوند (مگر اینکه به طور خاص دستور داده شده باشد که اجرا نشوند). این تضمین می‌کند که اتصالات TCP برای دستورات shell و HAL RPCها برای همه دستگاه‌ها در یک اسکریپت تست در دسترس هستند.

آماده‌کنندگان آزمون

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

  • آماده‌سازهای هدف تک دستگاهی (مثال در VtsDeviceInfoCollector ):
    • فقط در پیکربندی طرح آزمایشی با لیست دستگاه‌های مورد نیاز قابل تعیین است (نسخه‌های آینده امکان پیکربندی در سطح ماژول را نیز فراهم خواهند کرد).
    • فقط یک سریال دستگاه دریافت کنید.
    • وظایف آماده‌سازی و پاکسازی را روی یک دستگاه خاص اجرا کنید.
  • آماده‌سازهای هدف چند دستگاهی (مثال در VtsPythonVirtualenvPreparer ):
    • می‌تواند در پیکربندی طرح آزمون یا پیکربندی ماژول آزمون مشخص شود
    • دریافت سریال تمام دستگاه‌ها
    • وظایف آماده‌سازی و پاکسازی را برای هر دستگاه یا همه دستگاه‌ها اجرا کنید.

ماژول‌های تست

ماژول‌های تست پس از اینکه آماده‌سازهای تست، تنظیم میزبان/دستگاه‌ها را تمام کردند، لیستی از دستگاه‌ها را دریافت می‌کنند. برای هر ماژول تست چند دستگاهی، یک ماژول تست پایتون سمت میزبان اجرا می‌شود. دستگاه‌های اندروید اختصاص داده شده از ماژول‌های تست پایتون به عنوان لیستی از اشیاء AndroidDevice قابل دسترسی هستند:

devices = self.android_devices
device1 = devices[0]
device1_serial = device1.serial

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

ارتباط دستگاه در طول آزمایش

تست‌های چند-اندرویدی مؤثر شامل ارتباط بین دستگاه‌های اختصاص داده شده است. هنگام توسعه چنین تست‌هایی، باید نحوه برقراری ارتباط بین دستگاه‌های اختصاص داده شده را تعیین کنید. بخش‌های زیر سه مثال ارتباطی ارائه می‌دهند (با این حال، توسعه‌دهندگان تست می‌توانند مدل‌های دیگری را طراحی کنند).

نوع ۱: تست‌های HAL سمت میزبان

تست‌های HAL سمت میزبان می‌توانند از درایورهای VTS HAL که به طور پیش‌فرض به دستگاه‌ها اعمال می‌شوند، استفاده کنند:

شکل ۲. تست HAL سمت میزبان.

در این سناریو:

  • منطق تست روی میزبان اجرا می‌شود.
  • اسکریپت تست سمت میزبان، فراخوانی‌های RPC را به درایورهای هر دستگاه ارسال می‌کند.
  • سمت میزبان، تعاملات دستگاه را هماهنگ می‌کند.

نوع ۲: تست‌های مبتنی بر عامل سمت میزبان

به جای استفاده از عوامل VTS روی دستگاه، یک تست سمت میزبان می‌تواند عامل خود (برنامه یا باینری) را نیز به هر دستگاه ارسال کند:

شکل ۳. تست مبتنی بر عامل، سمت میزبان.

در این سناریو:

  • منطق تست روی میزبان اجرا می‌شود.
  • برنامه عامل (یا باینری) روی هر دستگاه نصب می‌شود.
  • اسکریپت تست سمت میزبان، دستوراتی را به برنامه‌ها در هر دستگاه صادر می‌کند.
  • سمت میزبان، تعاملات دستگاه را هماهنگ می‌کند.

برای مثال، تست‌های Next Billion User در مخزن فعلی VTS، تست‌های سمت میزبان، مبتنی بر برنامه و چند دستگاهی هستند.

نوع ۳: آزمایش‌های HIDL سمت هدف

تست‌های HIDL سمت هدف و چند دستگاهی، تمام منطق تست را روی فایل‌های باینری تست سمت دستگاه قرار می‌دهند که مستلزم همگام‌سازی دستگاه‌ها در طول اجرای تست است:

شکل ۴. آزمون HIDL مبتنی بر هدف.

در این سناریو:

  • منطق تست روی دستگاه‌ها اجرا می‌شود.
  • چارچوب سمت میزبان، شناسایی اولیه دستگاه را فراهم می‌کند.
  • فایل دودویی تست سمت هدف نیاز به همگام‌سازی دارد:
    • فایل تست دودویی یکسان برای همه دستگاه‌ها.
    • فایل‌های آزمایشی باینری مختلف برای هر نقش.

مثال: طرح تست چند دستگاهی

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

  • دستگاه ۱ شامل یک ارائه‌دهنده‌ی ساخت و آماده‌کننده‌ی هدف VtsDeviceInfoCollector است.
  • دستگاه ۲ شامل یک آماده‌ساز FilePusher اضافی است که گروهی از فایل‌های مرتبط با میزبان را به دستگاه ارسال می‌کند.
<configuration description="VTS Codelab Plan">
  ...
<device name="device1">
<build_provider class="com.android.compatibility.common.tradefed.build.CompatibilityBuildProvider" />
<target_preparer class="com.android.tradefed.targetprep.VtsDeviceInfoCollector" />
</device>
<device name="device2" >
<build_provider class="com.android.compatibility.common.tradefed.build.CompatibilityBuildProvider" />
<target_preparer class="com.android.tradefed.targetprep.VtsDeviceInfoCollector" />
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
<option name="push-group" value="HostDrivenTest.push" />
</target_preparer>
</device>
<option name="compatibility:include-filter" value="VtsCodelabHelloWorldMultiDeviceTest" />
</configuration>

مثال: اسکریپت تست پایتون سمت میزبان

برای جزئیات و مثال‌هایی در مورد آماده‌کننده‌های تست، به آماده‌کننده‌های تست مراجعه کنید. برای یک مثال کامل چند دستگاهی سمت میزبان، به codelab hello_world_multi مراجعه کنید.

def setUpClass(self):
logging.info('number of device: %s', self.android_devices)
asserts.assertEqual(len(self.android_devices), 2, 'number of device is wrong.')
self.dut1 = self.android_devices[0]
self.dut2 = self.android_devices[1]
self.shell1 = self.dut1.shell
self.shell2 = self.dut2.shell

def testSerialNotEqual(self):
'''Checks serial number from two device not being equal.'''
command = 'getprop | grep ro.serial'
res1 = self.shell1.Execute(command)
res2 = self.shell2.Execute(command)

def getSerialFromShellOutput(output):
'''Get serial from getprop query'''
return output[const.STDOUT][0].strip().split(' ')[-1][1:-1]
serial1 = getSerialFromShellOutput(res1)
serial2 = getSerialFromShellOutput(res2)

logging.info('Serial number of device 1 shell output: %s', serial1)
logging.info('Serial number of device 2 shell output: %s', serial2)
asserts.assertNotEqual(serial1, serial2, 'serials from two devices should not be the same')
asserts.assertEqual(serial1, self.dut1.serial, 'serial got from device system property is different from allocated serial')
asserts.assertEqual(serial2, self.dut2.serial, 'serial got from device system property is different from allocated serial')