বাইটকোড ইন্সট্রুমেন্টেশন (Bytecode instrumentation) এবং এর ব্যবহার

বাইটকোড ইন্সট্রুমেন্টেশন (Bytecode instrumentation)  এবং এর ব্যবহার:
১১ নভেম্বর, শুক্রবার, ২০১৬

জাভাতে আমরা যে সোর্স কোড লিখি, সেটা কম্পাইল হওয়ার পর কি হয়? মেশিন কোড?  - না আসলে সেটা বাইটকোড নামের একটা মধ্যবর্তী (intermediate) কোডে রূপান্তরিত হয়।  এই বাইটকোড পড়ে আবার জাভা ভার্চুয়াল মেশিন।  ভার্চুয়াল মেশিনের দায়িত্ব হচ্ছে এই বাইটকোড পড়ে বা ইন্টারপ্রেট করে কোড মেশিনে কোডে রূপান্তর করা।

কিন্তু এতে লাভটা কী?

এতে করে সবচেয়ে বড় যে সুবিধাটা হয় তা হচ্ছে জাভাতে লেখা কোড মেশিন ইন্ডিপেন্ডেন্ট হয়।  অর্থাৎ, একই বাইটকোড যেকনো মেশিনে (উইন্ডোস, লিনাক্স, ম্যাক-ওস কিংবা এন্ড্রয়েড ফোনে) চলতে পারে। শুধু মেশিন অনুযায়ী ভার্চুয়াল মেশিন ইন্স্টল্ করে নিলেই হলো। 

আরেকটা উপকার হচ্ছে, এই বাইটকোড ইনস্ট্রুমেন্ট করা যায়।  বাইটকোড ইনস্ট্রুমেন্ট বলতে আসলে বাইটকোড পরিবর্তন করে নতুন ফীচার বা ফাংশনালিটি যোগ করা বোঝায়।  একটা উদহারণ দিয়ে ব্যাপারটা ব্যাখ্যা করার চেষ্টা করি।

ধরা যাক, আপনি একটা বিরাট প্রজেক্ট -এর কোড লিখলেন। কোড টেস্ট করার জন্য অনেকগুলা ইউনিট টেস্ট কেস-ও লিখলেন। এখন কেউ যদি জিজ্ঞেস করে, "আচ্ছা, আপনার লেখা টেস্ট কেস গুলো আপনার কোডের কত পার্সেন্ট কভার করে? অর্থাৎ, আপনার টেস্ট কাভারেজ কত পার্সেন্ট??" আপনি এর উত্তর বের করবেন কিভাবে?

অনেকেই হয়তো উত্তরে বলে বসতে পারে, "আমি টেস্ট কাভারেজ টুল ব্যবহার করবো। সেটা ইনস্টল করে তারপর আমার টেস্ট গুলো রান করলে এই টুল-ই আমাকে বলে দিবে আমার টেস্ট কভারেজ পার্সেন্টেজ কত"।  - ঠিক আছে. কিন্তু কখনো কি ভেবে দেখেছেন এই টুল কিভাবে সেটা বের করে?

উত্তরটা হচ্ছে, খুব সম্ভবতঃ এই টুল বাইটকোড ইন্সট্রুমেন্টেশন ব্যবহার করে।  আপনার লেখা কোডের বাইটকোডে এই টুল কিছু অতিরিক্ত ইন্সট্রাকশন বা কোড যোগ করে দেয়।  তারপর যখন আপনার টেস্ট কেস গুলো রান করে তখন সে যোগ করা ওই অতিরিক্ত ইন্সট্রাকশন গুলোর এক্সেকিউশন খেয়াল করে আর তারপরই বের করে কত পার্সেন্ট কোড কভার হলো।

একটু অন্যভাবে এইভাবে ব্যাপারটা চিন্তা করা যায়: ধরা যাক, আপনার পুরো কোডের প্রতি লাইনের পরেই আপনি একটা করে প্রিন্ট স্টেটমেন্ট যোগ করে দিলেন। মোট কতগুলো স্টেটমেন্ট যোগ করলেন সেটা হিসাব রাখলেন। এরপরে আপনার টেস্ট গুলো চালালে যতগুলো স্টেটমেন্ট প্রিন্ট হলো, তা থেকেই আপনার কাভারেজ বের করে ফেলা যাবে। কিন্তু তাতে করে আপনার সোর্স কোডের চেহারাটা যে যাচ্ছেতাই হয়ে যাবে - সেটাও তো ঠিক, তাই না ? বাইটকোড ইন্সট্রুমেন্টেশন আপনার সোর্স কোডে কোনো হাত দিবে না।  শুধুমাত্র বাইটকোডে পরিবর্তন করেই এই এক্সট্রা লাইন প্রিন্ট সে যোগ করে দিতে পারে!

এই বাইটকোড ইন্সট্রুমেন্টেশন আরো অনেক ব্যবহার আছে।  মূলতঃ প্রোগ্রাম এনালিসিস করার জন্য এটা ব্যবহার হয়। আরেকটা উদাহরণ দেই।  ধরা যাক, আপনার একটা মেথড আছে অনেকটা এই রকম:

public void aMethod(int input) {
   if (input > 5) {
     // ... some lines of code
   } else {
         // some more lines of code
   }
}

এখন আপনি একটা টেস্ট কেস ইনপুট ১০ দিলেন। যেহেতু ১০ > ৫, তাই টেস্টটা if  ব্লকের ভেতর ঢুকে কিছু লাইন এক্সেকিউট করলো।  অর্থাৎ, (input  > ৫ ) এই কন্ডিশন তা true  হয়েছিল।  এখন প্রশ্ন হচ্ছে, কি ইনপুট দিলে কোডের এক্সেকিউশন else ব্লকে যেত? অবশ্যই !(ইনপুট >৫) বা  (ইনপুট <= ৫) টাইপ কিছু, ঠিক?  আর এই কন্ডিশনটা সল্ভ করলেই  আমরা আরেকটা টেস্ট কেস ইনপুট পাবো (৫ থেকে ছোট) যেইটা ব্যবহার করে else ব্লকের কোড এক্সেকিউট করা যাবে।

অর্থাৎ, যেকোনো টেস্ট কেসের কংক্রিট ইনপুট (আমাদের ক্ষেত্রে ১০) -কে কোনো সিম্বল বা ভ্যারিয়েবল দিয়ে রিপ্লেস করে পাথ কন্ডিশন গুলো বের করা যায় (এই প্রসেসকে ডাইনামিক সিম্বলিক এক্সেকিউশন বলে )।  আর এই পাথ কন্ডিশন পরিবর্তন করে বা নিগেট করে যে কন্সট্রেইন্ট পাওয়া যায়  (আমরা যেমন করেছিলাম "!(ইনপুট >৫)") , তা সল্ভ করে পাওয়া ভ্যালু দিয়ে নতুন টেস্ট কেস লেখা যাবে, যেটা ব্যবহার করে নতুন কোড ব্লক এক্সেকিউট করা যাবে।

বাইটকোড ইন্সট্রুমেন্টেশন ব্যবহার করে ডাইনামিক সিম্বলিক এক্সেকিউশন আর কন্সট্রেইন্ট সল্ভ করে আমরা অটোমেটিক্যালি টেস্ট কেস তৈরি করতে পারি।  মাইক্রোসফট-এর Pex নামে একটা টুল আছে যেইটা ঠিক এই কাজটাই করে। ওদের Pex  দিয়ে তৈরি করা PexForFun এই ইন্টারেক্টিভ ওয়েবসাইটটাও বেশ ইন্টারেষ্টিং।

আপনি যদি ভেবে থাকেন, মাইক্রোসফট??! ওরা তো জাভা ব্যবহার করে না, বাইটকোড ইন্সট্রুমেন্টেশনের কথা আসছে কোত্থেকে - ঠিকই ধরেছেন। ওদের প্লাটফর্ম .NET। মজার ব্যাপার হচ্ছে,  ওদেরও  জাভা বাইটকোডের মতো একটা ইন্টারমিডিয়েট ল্যাংগুয়েজ আছে. যার নাম Common Intermediate Language বা সংক্ষেপে CIL (উচ্চারণ সিল বা কিল!)। কাজেই তারাও বাইটকোড বা সিল কোড ইন্সট্রুমেন্টেশন করে এই কাজ গুলো করতে পারে।

আমার পিএইচডি রিসার্চেও এই বাইটকোড ইন্সটুমেনটেশন ব্যবহার করেছিলাম। করেছিলাম বললে ভুল হবে, সুপারভিসর করেছিলেন বলা উচিত। তাঁর তৈরি করা DSc  ফ্রেমওয়ার্ক ব্যবহার করে কিছু কাজ করেছিলাম।

যাই হোক, সব শেষে একটা লিংক দিয়ে লেখা শেষ করি :
বাইটকোড ইন্সট্রুমেন্টেশন আর এর ব্যবহারের উপর খুব ভালো একটা ছোট সেমিনার পেপার আছে, এই লিংকে। অন্য উপকারী লিংকগুলো এই পেপারেই পাবেন। দেখে নিতে পারেন।

ধন্যবাদ,
--ইশতিয়াক



POM or TAP design pattern for test automation using Selenium WebDriver

POM or TAP design pattern for test automation using Selenium WebDriver August 21, Monday, 2017 I've written the same topic in Bangl...