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

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

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

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

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

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

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

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

मुझे अलग-अलग कैंपेन के लिए, विज्ञापन दिखाने के तरीके को लागू करने के बारे में क्या जानना चाहिए?

  • आपका रनर सिर्फ़ कुछ शर्तों के हिसाब से शर्ड हो सकता है. ऐसे में, जब आपने शर्ड नहीं किया है, तो 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;
    }
    ...
}

इस उदाहरण में, अपने-आप एक नया इंस्टेंस बन जाता है और उसमें स्hard पैरामीटर सेट हो जाते हैं. हालांकि, अलग-अलग टेस्ट के लिए, डेटा को बांटने का लॉजिक पूरी तरह से अलग हो सकता है. जब तक यह लॉजिक तय हो और इससे सभी सबसेट मिलते हों, तब तक यह ठीक है.

इंडिपेंडेंस

शर्ड अलग-अलग होने चाहिए! आपके रनर में split को लागू करने से, दो शर्ड बनते हैं. इन शर्ड को एक-दूसरे पर निर्भर नहीं होना चाहिए या एक-दूसरे के साथ संसाधन शेयर नहीं करने चाहिए.

स्hards splitting को तय करना ज़रूरी है! यह भी ज़रूरी है कि एक ही शर्तों के हिसाब से, आपका 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, अलग-अलग हिस्सों में बांटकर किए गए अनुरोधों के लिए, टेस्ट के नतीजों को एग्रीगेट नहीं करता. इसलिए, आपको यह पक्का करना होगा कि आपकी रिपोर्टिंग सेवा इस सुविधा के साथ काम करती है.