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

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

ใช้เชลล์ ADB

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

  • รับวัตถุอุปกรณ์ Android:
    self.device = self.android_devices[0]
    
  • ออกคำสั่งเชลล์เดียว:
    result = self.device.adb.shell(‘ls')
    

ใช้ไดรเวอร์เชลล์ VTS

ไดรเวอร์เชลล์ VTS เป็นไบนารีของตัวแทนที่ทำงานบนอุปกรณ์และดำเนินการคำสั่งเชลล์ ตามค่าเริ่มต้น VTS จะใช้ไดรเวอร์เชลล์หากไดรเวอร์ทำงานบนอุปกรณ์เนื่องจากวิธีนี้มีเวลาแฝงน้อยกว่าการใช้คำสั่ง adb shell

รูปที่ 1. ไดรเวอร์เชลล์ VTS

กรอบงาน VTS รองรับการทดสอบหลายอุปกรณ์ โดยที่อุปกรณ์ Android แต่ละเครื่องจะแสดงเป็นออบเจ็กต์อุปกรณ์ Android ใน Base Runner ตามค่าเริ่มต้น กรอบงาน VTS จะพุช VTS agent และไบนารีไดรเวอร์เชลล์ 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'])
    

วัตถุผลลัพธ์คำสั่ง

อ็อบเจ็กต์ return จากการดำเนินการคำสั่งเชลล์คือพจนานุกรมที่มีคีย์ 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')