একটি শার্ডেড IRemoteTest টেস্ট রানার লিখুন

টেস্ট রানার লেখার সময় স্কেলেবিলিটি বা সম্প্রসারণযোগ্যতা নিয়ে ভাবা জরুরি। নিজেকে জিজ্ঞাসা করুন, "যদি আমার টেস্ট রানারকে ২ লক্ষ টেস্ট কেস চালাতে হতো," তাহলে এতে কত সময় লাগত?

ট্রেড ফেডারেশনে উপলব্ধ সমাধানগুলোর মধ্যে শার্ডিং অন্যতম। এর জন্য রানারের প্রয়োজনীয় সমস্ত টেস্টকে এমন কয়েকটি খণ্ডে বিভক্ত করতে হয়, যেগুলোকে সমান্তরালভাবে চালানো যায়।

এই পৃষ্ঠায় বর্ণনা করা হয়েছে কীভাবে আপনার রানারকে ট্রেডফেডের জন্য শার্ডযোগ্য করে তুলবেন।

বাস্তবায়নের জন্য ইন্টারফেস

TF দ্বারা শার্ডেবল হিসেবে বিবেচিত হওয়ার জন্য ইমপ্লিমেন্ট করার সবচেয়ে গুরুত্বপূর্ণ ইন্টারফেসটি হলো IShardableTest , যেটিতে দুটি মেথড রয়েছে: split(int numShard) এবং split()

যদি আপনার শার্ডিং অনুরোধ করা শার্ডের সংখ্যার উপর নির্ভর করে, তাহলে আপনার split(int numShard) ইমপ্লিমেন্ট করা উচিত। অন্যথায়, split() ইমপ্লিমেন্ট করুন।

যখন --shard-count এবং --shard-index শার্ডিং প্যারামিটারসহ একটি TF টেস্ট কমান্ড চালানো হয়, তখন TF সমস্ত IRemoteTest মধ্যে দিয়ে গিয়ে IShardableTest ইমপ্লিমেন্টকারী টেস্ট কেসগুলো খোঁজে। যদি খুঁজে পাওয়া যায়, তবে এটি একটি নির্দিষ্ট শার্ডের জন্য টেস্ট কেসগুলোর একটি উপসেট চালানোর উদ্দেশ্যে একটি নতুন IRemoteTest অবজেক্ট পেতে split কল করে।

স্প্লিট ইমপ্লিমেন্টেশন সম্পর্কে আমার কী জানা উচিত?

  • আপনার রানার শুধুমাত্র কিছু নির্দিষ্ট শর্ত সাপেক্ষে শার্ড করতে পারে; সেক্ষেত্রে শার্ড না করলে null রিটার্ন করুন।
  • যতটা সম্ভব যৌক্তিকভাবে ভাগ করার চেষ্টা করুন: আপনার রানারকে এমনভাবে এক্সিকিউশনের ইউনিটে ভাগ করুন যা এর জন্য অর্থবহ। এটি আসলেই আপনার রানারের উপর নির্ভর করে। উদাহরণস্বরূপ: HostTest ক্লাস লেভেলে শার্ড করা থাকলে, প্রতিটি টেস্ট ক্লাস একটি আলাদা শার্ডে রাখা হয়।
  • যদি যুক্তিযুক্ত হয়, শার্ডিং কিছুটা নিয়ন্ত্রণ করার জন্য কিছু অপশন যোগ করুন। উদাহরণস্বরূপ: AndroidJUnitTest-এ একটি ajur-max-shard আছে, যা অনুরোধ করা সংখ্যার নির্বিশেষে, এটিকে সর্বাধিক কতগুলো শার্ডে বিভক্ত করা যাবে তা নির্দিষ্ট করে দেয়।

বিস্তারিত উদাহরণ বাস্তবায়ন

এখানে IShardableTest প্রয়োগ করা একটি উদাহরণ কোড স্নিপেট দেওয়া হলো, যা আপনি রেফারেন্স হিসেবে ব্যবহার করতে পারেন। সম্পূর্ণ কোডটি এই লিঙ্কে পাওয়া যাবে (https://android.googlesource.com/platform/tools/tradefederation/+/refs/heads/android17-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 মেথডকে সর্বদা একই ক্রমে শার্ডগুলোর হুবহু একই তালিকা ফেরত দিতে হবে।

দ্রষ্টব্য: যেহেতু প্রতিটি শার্ড ভিন্ন ভিন্ন 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 শার্ডেড ইনভোকেশনের জন্য কোনো টেস্ট রেজাল্ট অ্যাগ্রিগেশন করে না, তাই আপনাকে নিশ্চিত করতে হবে যে আপনার রিপোর্টিং সার্ভিসটি এটি সাপোর্ট করে।