एक शार्ड IRemoteTest टेस्ट रनर लिखें

टेस्ट रनर लिखते समय स्केलेबिलिटी के बारे में सोचना महत्वपूर्ण है। अपने आप से पूछें, "यदि मेरे परीक्षण धावक को 200K परीक्षण मामले चलाने हों" तो इसमें कितना समय लगेगा?

शेयरिंग ट्रेड फेडरेशन में उपलब्ध उत्तरों में से एक है। इसमें धावक के लिए आवश्यक सभी परीक्षणों को कई हिस्सों में विभाजित करने की आवश्यकता होती है जिन्हें समानांतर किया जा सकता है।

यह पृष्ठ वर्णन करता है कि ट्रेडफेड के लिए अपने धावक को कैसे मजबूत बनाया जाए।

लागू करने के लिए इंटरफ़ेस

टीएफ द्वारा शार्डेबल माने जाने के लिए लागू किया जाने वाला सबसे महत्वपूर्ण इंटरफ़ेस IShardableTest है, जिसमें दो विधियाँ शामिल हैं: split(int numShard) और split()

यदि आपकी शार्डिंग अनुरोधित शार्डों की संख्या पर निर्भर होने वाली है, तो आपको split(int numShard) लागू करना चाहिए। अन्यथा, split() लागू करें।

जब एक TF परीक्षण कमांड को शार्डिंग पैरामीटर --shard-count और --shard-index के साथ निष्पादित किया जाता है, तो TF IShardableTest को लागू करने वाले को देखने के लिए सभी IRemoteTest के माध्यम से पुनरावृत्त होता है। यदि पाया जाता है, तो यह एक विशिष्ट शार्ड के लिए परीक्षण मामलों के सबसेट को चलाने के लिए एक नया IRemoteTest ऑब्जेक्ट प्राप्त करने के लिए split कॉल करेगा।

मुझे विभाजित कार्यान्वयन के बारे में क्या पता होना चाहिए?

  • आप धावक केवल कुछ शर्तों पर ही ठीकरा फोड़ सकते हैं; उस स्थिति में जब आपने शार्ड नहीं किया तो 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 के कार्यान्वयन द्वारा बनाए गए दो शार्डों को एक-दूसरे पर निर्भरता या संसाधनों को साझा नहीं करना चाहिए।

टुकड़ों का बंटवारा नियतिवादी होना चाहिए! यह भी अनिवार्य है, समान शर्तों को देखते हुए, आपकी split विधि को हमेशा उसी क्रम में ठीक उसी क्रम में शार्क की समान सूची लौटानी चाहिए।

ध्यान दें: चूंकि प्रत्येक शार्ड अलग-अलग टीएफ उदाहरणों पर चल सकता है, इसलिए यह सुनिश्चित करना महत्वपूर्ण है कि split तर्क उपसमुच्चय उत्पन्न करें जो पारस्परिक रूप से अनन्य और सामूहिक रूप से नियतात्मक तरीके से संपूर्ण हों।

स्थानीय स्तर पर एक परीक्षण साझा करें

स्थानीय TF पर एक परीक्षण को शार्प करने के लिए, आप बस कमांड लाइन में --shard-count विकल्प जोड़ सकते हैं।

tf >run host --class com.android.tradefed.UnitTests --shard-count 3

फिर टीएफ स्वचालित रूप से प्रत्येक शार्ड के लिए कमांड उत्पन्न करेगा और उन्हें चलाएगा।

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)

परीक्षण परिणाम एकत्रीकरण

चूंकि टीएफ शार्ड इनवोकेशन के लिए कोई परीक्षा परिणाम एकत्रीकरण नहीं करता है, इसलिए आपको यह सुनिश्चित करना होगा कि आपकी रिपोर्टिंग सेवा इसका समर्थन करती है।