คำสั่ง Shell อุปกรณ์

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

ใช้เชลล์ ADB

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

  • รับออบเจ็กต์อุปกรณ์ Android
    self.device = self.android_devices[0]
    
  • ออกคำสั่ง Shell รายการเดียว ดังนี้
    result = self.device.adb.shell(‘ls')
    

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

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

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

เฟรมเวิร์ก VTS รองรับการทดสอบหลายอุปกรณ์ โดยอุปกรณ์ Android แต่ละเครื่องจะแสดงเป็นออบเจ็กต์ AndroidDevice ใน Base Runner โดยค่าเริ่มต้น เฟรมเวิร์ก VTS จะพุชไบนารีของตัวแทน VTS และไดรเวอร์เชลล์ VTS ไปยังอุปกรณ์ Android แต่ละเครื่อง และสร้างการเชื่อมต่อ TCP กับตัวแทน VTS ในอุปกรณ์เหล่านั้น

หากต้องการเรียกใช้คำสั่ง Shell สคริปต์ Python ฝั่งโฮสต์จะเรียกใช้ฟังก์ชันกับออบเจ็กต์ ShellMirror ภายในออบเจ็กต์ AndroidDevice ออบเจ็กต์ ShellMirror จะแพ็กข้อความคำสั่งเชลล์เป็นข้อความ protobuf แล้วส่ง (ผ่านช่องทาง TCP) ไปยังตัวแทน VTS ในอุปกรณ์ Android จากนั้น Agent ที่ทำงานในอุปกรณ์จะส่งต่อคำสั่งเชลล์ไปยังไดรเวอร์เชลล์ 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) ตัวแปรสภาพแวดล้อมที่ตั้งค่าไว้ในเซสชันเทอร์มินัล 1 เซสชันจะใช้ได้กับคำสั่งที่ตามมาในเซสชันเดียวกันเท่านั้น
  • ขยายได้ การสื่อสารคําสั่ง Shell ระหว่างเฟรมเวิร์ก 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
    
  • ออกคำสั่ง Shell รายการเดียว ดังนี้
    results = self.shell.Execute(‘ls')
    
  • ออกรายการคำสั่ง Shell ดังนี้
    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')