VTS est compatible avec les tests qui nécessitent une interaction entre plusieurs appareils Android.
Architecture
VTS utilise le framework TradeFed pour obtenir et transmettre les numéros de série des appareils aux modules de test.
Les exigences concernant les appareils, telles que le nombre et les types d'appareils, sont spécifiées dans la configuration du plan de test. Par exemple, vous pouvez spécifier un plan de test qui nécessite deux appareils Android avec des cibles de compilation Sailfish.
Attribution d'appareils
L'infrastructure de test (généralement le planificateur de tests) alloue au framework VTS les appareils disponibles qui répondent aux exigences spécifiées dans la configuration du plan de test. Les appareils attribués sont réservés au plan de test, même si le module de test ne les utilise pas. Les binaires de l'agent VTS sont ensuite transférés et exécutés sur tous les appareils alloués (sauf indication contraire). Cela garantit que les connexions TCP pour les commandes shell et les RPC HAL sont disponibles pour tous les appareils d'un script de test.
Préparateurs de tests
Le framework exécute les préparateurs de test pour tous les appareils dont il a reçu les numéros de série. Les préparateurs cibles peuvent être à un ou plusieurs appareils :
- Préparateurs de cibles à un seul appareil (exemple dans VtsDeviceInfoCollector) :
- Ne peut être spécifié que dans la configuration du plan de test avec la liste des appareils requise (les futures versions autoriseront la configuration au niveau du module).
- Vous ne recevez qu'un seul numéro de série d'appareil.
- Exécutez des tâches de préparation et de nettoyage sur un appareil spécifique.
- Préparateurs de cibles multi-appareils (exemple dans VtsPythonVirtualenvPreparer) :
- Peut être spécifié dans la configuration du plan de test ou du module de test
- Recevoir tous les numéros de série des appareils
- Exécutez les tâches de préparation et de nettoyage pour chaque appareil ou pour tous les appareils.
Modules de test
Les modules de test obtiennent une liste d'appareils une fois que les préparateurs de tests ont terminé de configurer l'hôte/les appareils. Un module de test Python côté hôte s'exécute pour chaque module de test multi-appareils. Les appareils Android attribués sont accessibles à partir des modules de test Python sous forme de liste d'objets AndroidDevice :
devices = self.android_devices device1 = devices[0] device1_serial = device1.serial
Tous les appareils attribués sont réservés au plan de test, même si un module de test du plan n'utilise qu'un seul appareil.
Communication de l'appareil pendant les tests
Pour être efficaces, les tests multi-Android impliquent une communication entre les appareils attribués. Lorsque vous développez de tels tests, vous devez déterminer comment établir la communication entre les appareils attribués. Les sections suivantes fournissent trois exemples de communication (toutefois, les développeurs de tests sont libres de concevoir d'autres modèles).
Type 1 : Tests HAL côté hôte
Les tests HAL côté hôte peuvent utiliser les pilotes VTS HAL qui sont transférés sur les appareils par défaut :
Dans ce cas :
- La logique de test s'exécute sur l'hôte.
- Le script de test côté hôte émet des appels RPC vers les pilotes de chaque appareil.
- Le côté hôte coordonne les interactions avec l'appareil.
Type 2 : Tests basés sur l'agent côté hôte
Au lieu d'utiliser des agents VTS sur l'appareil, un test côté hôte peut également envoyer son propre agent (application ou binaire) à chaque appareil :
Dans ce cas :
- La logique de test s'exécute sur l'hôte.
- L'application (ou le binaire) de l'agent s'installe sur chaque appareil.
- Le script de test côté hôte envoie des commandes aux applications sur chaque appareil.
- Le côté hôte coordonne les interactions avec l'appareil.
Par exemple, les tests Next Billion Users dans le dépôt VTS actuel sont des tests côté hôte, basés sur des applications et multi-appareils.
Type 3 : Tests HIDL côté cible
Les tests HIDL multi-appareils côté cible placent toute la logique de test sur les binaires de test côté appareil, ce qui nécessite que les tests synchronisent les appareils lors de l'exécution des tests :
Dans ce cas :
- La logique de test s'exécute sur les appareils.
- Le framework côté hôte fournit l'identification initiale de l'appareil.
- Le binaire de test côté cible nécessite une synchronisation :
- Même binaire de test pour tous les appareils.
- Différents binaires de test pour chaque rôle.
Exemple : Plan de test multi-appareils
Cet exemple spécifie la configuration de deux appareils :
- L'appareil 1 inclut un fournisseur de compilation et un préparateur cible
VtsDeviceInfoCollector
. - L'appareil 2 inclut un préparateur
FilePusher
supplémentaire qui transfère un groupe de fichiers associés pilotés par l'hôte vers l'appareil.
<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>
Exemple : Script de test Python côté hôte
Pour obtenir des informations et des exemples sur les préparateurs de tests, consultez Préparateurs de tests. Pour obtenir un exemple complet côté hôte et multi-appareils, consultez l'atelier de programmation 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')