כשכותבים מפעיל בדיקות, חשוב להביא בחשבון את יכולת ההתאמה לעומס. כדאי לשאול את עצמכם: "אם הכלי להרצת הבדיקות שלי יצטרך להריץ 200,000 תרחישי בדיקה, כמה זמן זה ייקח?"
פיצול הוא אחת מהתשובות הזמינות באיחוד שירותי הסחר. הוא מחייב לפצל את כל הבדיקות שדרושות לריצה לכמה מקטעי נתונים מקביל.
דף זה מתאר כיצד להפוך את ריצה לפיצול ל-TrendFed.
ממשק להטמעה
הממשק החשוב ביותר שצריך להטמיע כדי שייחשב לפיצול
TF הוא
IShardableTest,
שמכיל שתי שיטות: split(int numShard)
ו-split()
.
אם חלוקת המשנה תלויה במספר פלחים המבוקשים, צריך להטמיע את split(int numShard)
. אחרת, מטמיעים את split()
.
כשמפעילים פקודת בדיקה של TF עם פרמטרים של חלוקה לפלחים --shard-count
ו---shard-index
, TF מבצע חזרה על כל IRemoteTest
כדי לחפש אלה שמטמיעים את IShardableTest
. אם המכשיר יימצא, תתבצע שיחה למספר split
אל
מקבלים אובייקט IRemoteTest
חדש כדי להריץ קבוצת משנה של מקרי בדיקה
שמפוצל.
מה חשוב לדעת על ההטמעה המפוצלת?
- הריצה יכולה לפצל תנאים מסוימים בלבד. במקרה הזה, צריך להחזיר
null
כשלא פיצול. - נסה לפצל את מה שנראה לך הגיוני: פוצלו את משחק הריצה ליחידה של שמתאימה לו. זה תלוי בגורם שמריץ את הבדיקה. עבור דוגמה: בדיקת מארח הם מחולקים ברמת הכיתה, כל כיתה למבחן מחולקת לפיצול נפרד.
- אם זה הגיוני, מוסיפים כמה אפשרויות כדי לשלוט קצת בחלוקה לפלחים.
מוצרים לדוגמה:
AndroidJUnitTest
מכיל
ajur-max-shard
כדי לציין את מספר הפיצולים המקסימלי שהוא יכול לפצל אותן, בלי קשר למספר המבוקש.
הטמעה מפורטת לדוגמה
הנה קטע קוד לדוגמה עם הטמעה של IShardableTest
. הקוד המלא זמין בכתובת
(https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/main/test_framework/com/android/tradefed/testtype/InstalledInstrumentationsTest.java)
/**
* Runs all instrumentation found on current device.
*/
@OptionClass(alias = "installed-instrumentation")
public class InstalledInstrumentationsTest
implements IDeviceTest, IResumableTest, IShardableTest {
...
/** {@inheritDoc} */
@Override
public Collection<IRemoteTest> split(int shardCountHint) {
if (shardCountHint > 1) {
Collection<IRemoteTest> shards = new ArrayList<>(shardCountHint);
for (int index = 0; index < shardCountHint; index++) {
shards.add(getTestShard(shardCountHint, index));
}
return shards;
}
// Nothing to shard
return null;
}
private IRemoteTest getTestShard(int shardCount, int shardIndex) {
InstalledInstrumentationsTest shard = new InstalledInstrumentationsTest();
try {
OptionCopier.copyOptions(this, shard);
} catch (ConfigurationException e) {
CLog.e("failed to copy instrumentation options: %s", e.getMessage());
}
shard.mShardIndex = shardIndex;
shard.mTotalShards = shardCount;
return shard;
}
...
}
הדוגמה הזו פשוט יוצרת מופע חדש של עצמה ומגדירה פיצול . אבל לוגיקת הפיצול יכולה להיות שונה לחלוטין בדיקה. וכל עוד הוא דטרמיניסטי ויוצר באופן גורף קבוצת משנה מקיפה, זה בסדר.
עצמאות
אסור שהפלחים יהיו תלויים זה בזה! לשני שברי המידע שנוצרו על ידי ההטמעה של split
ב-runner לא צריכות להיות יחסי תלות זה בזה, והם לא צריכים לשתף משאבים.
פיצול פיצולים צריך להיות דטרמיניסטי! זוהי גם חובה, בהינתן
אותם תנאים, השיטה split
צריכה תמיד להחזיר בדיוק את אותה רשימה של
של פיצולים באותו סדר.
הערה: מאחר שכל שריד יכול לפעול במכונות TF שונות, חשוב לוודא שהלוגיקה של split
מניבה קבוצות משנה שהן בלתי ניתנות להפרדה ומקיפות באופן דטרמיניסטי.
פיצול בדיקה באופן מקומי
כדי לפצל בדיקה ב-TF מקומי, פשוט מוסיפים את האפשרות --shard-count
לשורת הפקודה.
tf >run host --class com.android.tradefed.UnitTests --shard-count 3
לאחר מכן, TF ייצור פקודות באופן אוטומטי לכל שריד ויפעיל אותן.
tf >l i
Command Id Exec Time Device State
3 0m:03 [null-device-2] running stub on build 0 (shard 1 of 3)
3 0m:03 [null-device-1] running stub on build 0 (shard 0 of 3)
3 0m:03 [null-device-3] running stub on build 0 (shard 2 of 3)
צבירת תוצאות בדיקה
מכיוון ש-TF לא מבצע צבירת תוצאות בדיקה עבור הפעלות מפוצלות, צריך לוודא ששירות הדיווח שלכם תומך בכך.