คำสั่งเชลล์อุปกรณ์

ในระหว่างการทดสอบ VTS คำสั่งเชลล์จะใช้เพื่อดำเนินการไบนารีทดสอบฝั่งเป้าหมาย เพื่อรับ/ตั้งค่าคุณสมบัติ ตัวแปรสภาพแวดล้อม และข้อมูลระบบ และเพื่อเริ่ม/หยุดเฟรมเวิร์ก Android คุณสามารถดำเนินการคำสั่งเชลล์อุปกรณ์ VTS โดยใช้คำสั่ง adb shell หรือไดรเวอร์เชลล์ VTS ที่ทำงานบนอุปกรณ์ (แนะนำ)

การใช้เชลล์ ADB

การทดสอบที่ต้องปิดพอร์ต USB หรือรีบูตอุปกรณ์ในระหว่างการทดสอบต้องใช้เชลล์ ADB เนื่องจากไดรเวอร์เชลล์ VTS ไม่พร้อมใช้งานหากไม่มีการเชื่อมต่อ USB แบบถาวร คุณสามารถเรียกใช้ ADB shell จากวัตถุ AndroidDevice ในสคริปต์ทดสอบ Python ตัวอย่าง:

  • รับวัตถุอุปกรณ์ 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 แต่ละเครื่อง และสร้างการเชื่อมต่อ TCP กับเอเจนต์ VTS บนอุปกรณ์เหล่านั้น

ในการดำเนินการคำสั่งเชลล์ สคริปต์ Python ฝั่งโฮสต์จะเรียกใช้ฟังก์ชันไปยังอ็อบเจ็กต์ ShellMirror ภายในอ็อบเจ็กต์ AndroidDevice วัตถุ ShellMirror บรรจุข้อความคำสั่งเชลล์ลงในข้อความ protobuf และส่ง (ผ่านช่องทาง TCP) ไปยังตัวแทน VTS บนอุปกรณ์ Android เอเจนต์ที่ทำงานบนอุปกรณ์จะส่งต่อคำสั่งเชลล์ไปยังไดรเวอร์เชลล์ VTS ผ่านซ็อกเก็ต Unix

เมื่อไดรเวอร์เชลล์ VTS ได้รับคำสั่งเชลล์ โปรแกรมจะดำเนินการคำสั่งผ่าน nohup บนเชลล์อุปกรณ์เพื่อป้องกันการหยุดทำงาน จากนั้นดึงรหัส Stdout, stderr และส่งคืนจาก nohup และส่งกลับไปยังตัวแทน VTS สุดท้าย เอเจนต์จะตอบกลับโฮสต์โดยห่อผลลัพธ์ของคำสั่งลงในข้อความ protobuf

ข้อดี

ข้อดีของการใช้ไดรเวอร์เชลล์ VTS แทน adb shell ได้แก่:

  • ความน่าเชื่อถือ ไดรเวอร์เชลล์ VTS ใช้ nohup เพื่อรันคำสั่งตามการตั้งค่าเริ่มต้น เนื่องจากการทดสอบ VTS ส่วนใหญ่เป็นการทดสอบ HAL และเคอร์เนลระดับล่าง nohup จึงมั่นใจได้ว่าคำสั่งเชลล์จะไม่ค้างระหว่างการดำเนินการ
  • ประสิทธิภาพ . แม้ว่าคำสั่ง adb shell จะแคชผลลัพธ์บางอย่าง (เช่น การแสดงรายการไฟล์ในไดเร็กทอรี) แต่ก็มีโอเวอร์เฮดในการเชื่อมต่อเมื่อทำงานต่างๆ เช่น รันไบนารีทดสอบ ไดรเวอร์เชลล์ VTS จะรักษาการเชื่อมต่อที่ใช้งานได้ตลอดการทดสอบ ดังนั้นค่าใช้จ่ายเพียงอย่างเดียวคือการสื่อสารผ่าน USB ในการทดสอบของเรา การใช้ไดรเวอร์เชลล์ VTS เพื่อรันคำสั่งที่มีการเรียก 100 ครั้งไปยังไบนารี gtest ที่ว่างเปล่านั้นเร็วกว่าการใช้ adb shell ประมาณ 20 เปอร์เซ็นต์; ความแตกต่างที่แท้จริงนั้นยิ่งใหญ่กว่าเนื่องจากการสื่อสารของเชลล์ VTS มีการบันทึกที่กว้างขวาง
  • การรักษาสถานะ . ไดรเวอร์เชลล์ VTS จะรักษาเซสชันเทอร์มินัลสำหรับชื่อเทอร์มินัลแต่ละชื่อ (ชื่อเทอร์มินัลเริ่มต้นคือ default ) ตัวแปรสภาพแวดล้อมที่ตั้งค่าในเซสชันเทอร์มินัลหนึ่งจะใช้ได้เฉพาะกับคำสั่งที่ตามมาในเซสชันเดียวกันเท่านั้น
  • ขยาย ได้ การสื่อสารคำสั่งเชลล์ระหว่างเฟรมเวิร์ก VTS และไดรเวอร์อุปกรณ์ถูกรวมไว้ใน protobuf เพื่อเปิดใช้งานการบีบอัด ระยะไกล การเข้ารหัส ฯลฯ ที่อาจเกิดขึ้นในอนาคต ความเป็นไปได้อื่น ๆ สำหรับการปรับปรุงประสิทธิภาพก็มีให้เช่นกัน รวมถึงการแยกวิเคราะห์ผลลัพธ์ด้านอุปกรณ์เมื่อโอเวอร์เฮดการสื่อสารมีขนาดใหญ่กว่าการแยกวิเคราะห์สตริงผลลัพธ์

ข้อเสีย

ข้อเสียของการใช้ไดรเวอร์เชลล์ VTS แทน adb shell ได้แก่:

  • ไบนารีเพิ่มเติม ต้องพุชไฟล์ตัวแทน VTS ไปที่อุปกรณ์และล้างข้อมูลหลังจากดำเนินการทดสอบ
  • ต้องมีการเชื่อมต่อที่ใช้งานอยู่ หากการเชื่อมต่อ TCP ระหว่างโฮสต์และเอเจนต์ขาดหายไประหว่างการทดสอบ (เนื่องจากการตัดการเชื่อมต่อ USB การปิดพอร์ต อุปกรณ์ขัดข้อง ฯลฯ) ไม่ว่าจะโดยตั้งใจหรือไม่ตั้งใจ คำสั่งเชลล์จะไม่สามารถส่งไปยังเอเจนต์ VTS ได้ แม้จะมีการสลับอัตโนมัติเป็น adb shell ผลลัพธ์และสถานะของคำสั่งก่อนการตัดการเชื่อมต่อจะไม่เป็นที่รู้จัก

ตัวอย่าง

ตัวอย่างการใช้คำสั่งเชลล์ในสคริปต์ทดสอบ Python ฝั่งโฮสต์ VTS:

  • รับวัตถุอุปกรณ์ 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')