기기 셸 명령어

VTS 테스트 중에 셸 명령어는 타겟 측 테스트 바이너리를 실행하고 속성, 환경 변수 및 시스템 정보를 가져오거나 설정하고 Android 프레임워크를 시작하거나 중지하는 데 사용됩니다. VTS 기기 셸 명령어는 adb shell 명령어 또는 기기에서 실행되는 VTS 셸 드라이버(권장)를 사용하여 실행할 수 있습니다.

ADB 셸 사용

테스트 중에 USB 포트를 종료하거나 기기를 재부팅해야 하는 테스트의 경우 영구 USB 연결 없이는 VTS 셸 드라이버를 사용할 수 없으므로 ADB 셸을 사용해야 합니다. ADB 셸은 Python 테스트 스크립트의 AndroidDevice 객체에서 호출할 수 있습니다. 예를 들면 다음과 같습니다.

  • Android 기기 객체 가져오기:
    self.device = self.android_devices[0]
    
  • 단일 셸 명령어 실행:
    result = self.device.adb.shell(‘ls')
    

VTS 셸 드라이버 사용

VTS 셸 드라이버는 기기에서 실행되고 셸 명령어를 실행하는 에이전트 바이너리입니다. 기본적으로 VTS는 셸 드라이버가 기기에서 실행 중인 경우 이 드라이버를 사용합니다. 이 방법이 adb shell 명령어를 사용하는 것보다 지연 시간이 짧기 때문입니다.

그림 1. VTS 셸 드라이버

VTS 프레임워크는 각 Android 기기가 기본 실행자에서 AndroidDevice 객체로 표시되는 다중 기기 테스트를 지원합니다. 기본적으로 VTS 프레임워크는 VTS 에이전트와 VTS 셸 드라이버 바이너리를 각 Android 기기에 푸시하고, 그러한 기기에 있는 VTS 에이전트로 TCP 연결을 설정합니다.

셸 명령어를 실행하기 위해 호스트 측 Python 스크립트는 AndroidDevice 객체 내의 ShellMirror 객체를 함수 호출합니다. ShellMirror 객체는 셸 명령어 텍스트를 protobuf 메시지로 압축하여 TCP 채널을 통해 Android 기기의 VTS 에이전트에 보냅니다. 그러면 기기에서 실행 중인 에이전트가 Unix 소켓을 통해 셸 명령어를 VTS 셸 드라이버에 전달합니다.

VTS 셸 드라이버가 셸 명령어를 수신하면 중단 현상을 방지하기 위해 기기 셸에서 nohup을 통해 명령어를 실행합니다. 그러면 stdout, stderr 및 return code를 nohup에서 가져오고 이를 VTS 에이전트로 다시 보냅니다. 마지막으로 에이전트는 명령어 결과를 protobuf 메시지로 래핑하여 호스트에 응답합니다.

장점

adb shell 대신 VTS 셸 드라이버를 사용할 때의 장점은 다음과 같습니다.

  • 안정성. VTS 셸 드라이버는 nohup을 사용하여 기본 설정에서 명령어를 실행합니다. VTS 테스트는 대부분 하위 수준의 HAL 및 커널 테스트이기 때문에 nohup에서 실행 중에 셸 명령어가 중단되지 않도록 보장합니다.
  • 성능. adb shell 명령어가 일부 결과(예: 디렉터리에 파일 나열)를 캐시하지만, 테스트 바이너리 실행과 같은 작업을 할 때 연결 오버헤드가 발생합니다. VTS 셸 드라이버는 테스트 전반에 걸쳐 활성 상태의 연결을 유지하기 때문에 USB 통신이 유일한 오버헤드입니다. 테스트에서 VTS 셸 드라이버를 사용하여 빈 gtest 바이너리를 100번 호출하는 방식으로 명령어를 실행하면 adb shell을 사용하는 것보다 약 20% 더 빠른 것으로 나타났습니다. VTS 셸 통신에서는 로깅이 광범위하기 때문에 실제 차이는 더 큽니다.
  • 상태 유지. VTS 셸 드라이버는 터미널 이름마다 터미널 세션을 유지합니다(기본 터미널 이름은 default임). 한 터미널 세션에 설정된 환경 변수는 동일한 세션의 후속 명령어에만 사용할 수 있습니다.
  • 확장 가능성. VTS 프레임워크와 기기 드라이버 간의 셸 명령어 통신은 향후 잠재적인 압축과 원격 사용, 암호화 등이 가능하도록 protobuf로 래핑됩니다. 성능 개선을 위해 다른 방법도 사용할 수 있습니다. 예를 들면 통신 오버헤드가 결과 문자열 파싱보다 클 경우 기기 측 결과를 파싱할 수 있습니다.

단점

adb shell 대신 VTS 셸 드라이버를 사용하는 때의 단점은 다음과 같습니다.

  • 추가 바이너리. VTS 에이전트 파일을 기기에 푸시해야 하고 테스트 실행 후 정리해야 합니다.
  • 활성 상태의 연결 필요. 테스트 중에 USB 연결 해제, 포트 종료, 기기 장애 등으로 인해 호스트와 에이전트 간의 TCP 연결이 의도적으로 또는 의도치 않게 끊어지면 셸 명령어를 VTS 에이전트로 전송할 수 없습니다. adb shell로 자동 전환되어도 연결이 끊어지기 전의 명령어 상태와 결과는 알 수 없습니다.

VTS 호스트 측 Python 테스트 스크립트에서 셸 명령어를 사용하는 예:

  • Android 기기 객체 가져오기:
    self.device = self.android_devices[0]
    
  • 선택한 기기의 셸 객체 가져오기:
    self.shell = self.device.shell
    
  • 단일 셸 명령어 실행:
    results = self.shell.Execute(‘ls')
    
  • 셸 명령어 목록 실행:
    results = self.shell.Execute([‘cd /data/local/tmp', ‘ls'])
    

명령어 결과 객체

셸 명령어 실행의 반환 객체는 키 stdouts, stderrs, return_codes가 포함된 사전입니다. 셸 명령어가 단일 문자열로 제공되든 명령어 문자열 목록으로 제공되든 관계없이 결과 사전의 각 값은 항상 목록입니다.

명령어 목록의 반환 코드를 확인하려면 테스트 스크립트는 색인을 확인해야 합니다. 예:

asserts.assertFalse(any(results[‘return_codes']), ‘some command failed.')

또는 스크립트는 각 명령어 색인을 개별적으로 확인할 수 있습니다. 예:

asserts.assertEqual(results[‘return_codes'][0], 0, ‘first command failed')
asserts.assertEqual(results[‘return_codes'][1], 0, ‘second command failed')