IRemoteTest टेस्ट रनर को अलग-अलग हिस्सों में बांटना

टेस्ट रनर लिखते समय, स्केलेबिलिटी के बारे में सोचना ज़रूरी है. खुद से पूछें कि "अगर मेरे टेस्ट रनर को 2 लाख टेस्ट केस चलाने पड़ें", तो इसमें कितना समय लगेगा?

शार्डिंग, Trade Federation में उपलब्ध जवाबों में से एक है. इसके लिए, रनर को जिन सभी टेस्ट की ज़रूरत होती है उन्हें कई ऐसे हिस्सों में बांटना होता है जिन्हें एक साथ चलाया जा सकता है.

इस पेज पर बताया गया है कि Tradefed के लिए, अपने रनर को शेयर करने लायक कैसे बनाया जाए.

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

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

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

जब शार्डिंग पैरामीटर --shard-count और --shard-index के साथ टीएफ़ टेस्ट कमांड को लागू किया जाता है, तो टीएफ़ सभी IRemoteTest को दोहराता है, ताकि IShardableTest को लागू करने वाले पैरामीटर मिल सकें. अगर ऐसा होता है, तो यह split को कॉल करेगा, ताकि किसी खास शार्ड के लिए टेस्ट केस का सबसेट चलाने के लिए, नया IRemoteTest ऑब्जेक्ट मिल सके.

स्प्लिट इंप्लीमेंटेशन के बारे में मुझे क्या जानना चाहिए?

  • रनर को कुछ शर्तों के आधार पर ही शार्ड किया जा सकता है. अगर ऐसा नहीं किया गया है, तो null दिखाएं .
  • जितना हो सके, उतना स्प्लिट करें: अपने रनर को एक्ज़ीक्यूशन की ऐसी यूनिट में स्प्लिट करें जो उसके लिए सही हो. यह आपके रनर पर निर्भर करता है. उदाहरण के लिए: HostTest को क्लास लेवल पर बांटा जाता है. हर टेस्ट क्लास को अलग-अलग शार्ड में रखा जाता है.
  • अगर यह सही लगता है, तो शार्डिंग को थोड़ा कंट्रोल करने के लिए कुछ विकल्प जोड़ें. उदाहरण के लिए: AndroidJUnitTest में ajur-max-shard होता है. इससे, ज़्यादा से ज़्यादा शार्ड की संख्या तय की जा सकती है. भले ही, अनुरोध की गई संख्या कुछ भी हो.

लागू करने के तरीके का उदाहरण

यहां IShardableTest को लागू करने वाले कोड स्निपेट का एक उदाहरण दिया गया है. इसका इस्तेमाल किया जा सकता है. पूरा कोड यहां उपलब्ध है: (https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/android16-release/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 लॉजिक से ऐसे सबसेट मिले जो एक-दूसरे से अलग हों और एक साथ मिलकर, तय किए गए तरीके से पूरे डेटा को शामिल करें.

किसी टेस्ट को स्थानीय तौर पर शेयर करना

लोकल टीएफ़ पर किसी टेस्ट को शार्ड करने के लिए, कमांड लाइन में --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, शार्ड किए गए इनवोकेशन के लिए टेस्ट के नतीजों को एग्रीगेट नहीं करता. इसलिए, आपको यह पक्का करना होगा कि आपकी रिपोर्टिंग सेवा इसका समर्थन करती हो.