פקודות מעטפת של מכשיר

במהלך בדיקת VTS, פקודות מעטפת משמשות להרצת קובץ בינארי לבדיקה בצד היעד, לאחזור או להגדרה של מאפיינים, משתני סביבה ומידע על המערכת, ולהפעלה או להפסקה של מסגרת Android. אפשר להריץ פקודות מעטפת של מכשיר VTS באמצעות הפקודה adb shell או באמצעות מנהל המעטפת של VTS שפועל במכשיר (מומלץ).

שימוש במעטפת ADB

בבדיקות שדורשות כיבוי של יציאת ה-USB או הפעלה מחדש של המכשיר במהלך הבדיקה, צריך להשתמש ב-ADB shell כי מנהל המעטפת של 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 ב-base runner. כברירת מחדל, מסגרת VTS דוחפת קבצים בינאריים של סוכן VTS ושל מנהל מעטפת VTS לכל מכשיר Android, ומקימה חיבורי TCP לסוכנויות VTS במכשירים האלה.

כדי להריץ פקודה של מעטפת, סקריפט Python בצד המארח מבצע קריאה לפונקציה של האובייקט ShellMirror בתוך האובייקט AndroidDevice. האובייקט ShellMirror מקפל את הטקסטים של פקודות המעטפת להודעת protobuf ושולח אותה (דרך ערוץ ה-TCP) לסוכנות VTS במכשיר Android. לאחר מכן, הסוכן שפועל במכשיר מעביר את פקודת המעטפת למנהל המעטפת של VTS דרך שקע ה-Unix.

כשנהג המעטפת של VTS מקבל פקודה של מעטפת, הוא מבצע את הפקודה באמצעות nohup במעטפת המכשיר כדי למנוע תקיעות. לאחר מכן, סטדווט, סטרד וקוד ההחזרה מאוחזרים מ-nohup ונשלחים חזרה לסוכנות VTS. לבסוף, הסוכן משיב למארח על ידי אריזה של תוצאות הפקודה בהודעת protobuf.

יתרונות

היתרונות של שימוש במנהל המעטפת של VTS במקום ב-adb shell כוללים:

  • אמינות מנהל המעטפת של VTS משתמש ב-nohup כדי להריץ פקודות בהגדרת ברירת המחדל. מאחר שבדיקות VTS הן בעיקר בדיקות HAL וליבת ברמה נמוכה יותר, nohup מוודא שפקדי המעטפת לא נתקעים במהלך הביצוע.
  • ביצועים. הפקודה adb shell מאחסנת במטמון תוצאות מסוימות (כמו רשימה של קבצים בספרייה), אבל יש לה עלות תשתית של חיבור כשמבצעים משימות כמו הפעלת קובץ בינארי לבדיקה. מנהל המעטפת של VTS שומר על חיבור פעיל לאורך כל הבדיקה, כך שהעלות הנוספת היחידה היא תקשורת USB. בבדיקות שלנו, השימוש במנהל המעטפת של VTS כדי להריץ פקודה עם 100 קריאות לקובץ הבינארי gtest הריק מהיר ב-20% בערך מאשר השימוש ב-adb shell. ההבדל בפועל גדול יותר כי בתקשורת של מעטפת VTS יש רישום נרחב ביומן.
  • ניהול מצב. מנהל המעטפת של VTS שומר על סשן מסוים בכל שם מסוים של מסוף (שם ברירת המחדל של מסוף הוא default). משתני הסביבה שמוגדרים בסשן מסוים של מסוף זמינים רק לפקודות הבאות באותו סשן.
  • ניתן להרחבה. התקשורת של פקודות המעטפת בין מסגרת VTS לבין מנהל ההתקן עטופה ב-protobuf כדי לאפשר בעתיד דחיסה, גישה מרחוק, הצפנה וכו'. יש גם אפשרויות אחרות לשיפור הביצועים, כולל ניתוח תוצאות בצד המכשיר כשעלות התקשורת גבוהה יותר מניתוח מחרוזת התוצאות.

חסרונות

החסרונות של שימוש במנהל המעטפת של VTS במקום ב-adb shell כוללים:

  • קובצי בינארי נוספים. צריך לדחוף את קבצי ה-VTS agent למכשיר ולנקות אותם אחרי ביצוע הבדיקה.
  • נדרש חיבור פעיל. אם חיבור ה-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')