آزمایش چنددستگاهی

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

معماری

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

شکل ۱. VTS شماره‌های سریال دستگاه را ارسال می‌کند.

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

اختصاص دستگاه

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

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

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

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

پیمانه‌های آزمایشی

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

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

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

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

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

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

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

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

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

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

نوع ۲: آزمایش‌های عامل میزبان

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

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

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

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

برای مثال، آزمایش‌های کاربران بعدی میلیارد در مخزن 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>

مثال: دستورگان آزمایش Python سمت میزبان

برای جزئیات و مثال‌هایی درباره آماده‌کنندگان آزمون، به آماده‌کنندگان آزمون مراجعه کنید. برای مشاهده نمونه کامل چنددستگاهی سمت میزبان، به کدبندی 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')