Erlang 21 - 12. Event Handling

12 इवेंट हैंडलिंग




erlang

12 इवेंट हैंडलिंग

12.1 सामान्य

एक Common Test सिस्टम का ऑपरेटर टेस्ट रन के दौरान लगातार इवेंट नोटिफिकेशन प्राप्त कर सकता है। उदाहरण के लिए, Common Test रिपोर्ट करता है जब कोई टेस्ट केस शुरू होता है और रुक जाता है, तो सफल, फेल और स्किप किए गए मामलों की वर्तमान संख्या और इसी तरह की गणना। इस जानकारी का उपयोग विभिन्न उद्देश्यों के लिए किया जा सकता है जैसे एचटीएमएल की तुलना में प्रगति और परिणाम को लॉग इन करना, रिपोर्ट जनरेशन के लिए डेटाबेस में आंकड़ों को सहेजना और सिस्टम पर्यवेक्षण का परीक्षण करना।

Common Test में ओटीपी इवेंट मैनेजर अवधारणा और gen_event व्यवहार के आधार पर ईवेंट हैंडलिंग के लिए एक रूपरेखा है। जब Common Test सर्वर शुरू होता है, तो यह एक इवेंट मैनेजर को जन्म देता है। परीक्षण निष्पादन के दौरान प्रबंधक को सर्वर से एक सूचना मिलती है जब कुछ संभावित ब्याज होता है। इवेंट मैनेजर में प्लग किया गया कोई भी ईवेंट हैंडलर रूचि की घटनाओं पर मेल कर सकता है, कार्रवाई कर सकता है या सूचना को पास कर सकता है। ईवेंट हैंडलर gen_event Common Test उपयोगकर्ता द्वारा लागू किए गए gen_event मॉड्यूल हैं जो कि gen_event व्यवहार (विवरण के लिए, सिस्टम डॉक्यूमेंटेशन में ओटीपी डिज़ाइन सिद्धांत में मॉड्यूल gen_event और अनुभाग gen_event Behaviour देखें)।

एक Common Test सर्वर हमेशा एक इवेंट मैनेजर शुरू करता है। सर्वर एक डिफ़ॉल्ट ईवेंट हैंडलर में भी प्लग इन करता है, जिसका उद्देश्य केवल विश्व स्तर पर पंजीकृत Common Test मास्टर इवेंट मैनेजर (यदि Common Test मास्टर सर्वर सिस्टम में चल रहा है) को सूचनाओं को रिले करना है। Common Test मास्टर स्टार्टअप में एक इवेंट मैनेजर भी पैदा करता है। इस प्रबंधक में प्लग किए गए इवेंट हैंडलर सभी टेस्ट नोड्स से घटनाओं को प्राप्त करते हैं, साथ ही Common Test मास्टर सर्वर से जानकारी भी प्राप्त करते हैं।

उपयोगकर्ता-विशिष्ट ईवेंट हैंडलर को Common Test ईवेंट मैनेजर में प्लग किया जा सकता है, या तो Common Test को टेस्ट रन (बाद में वर्णित) से पहले स्थापित करने के लिए कहकर या परीक्षण के दौरान हैंडलर को गतिशील रूप से gen_event:add_handler/3 का उपयोग करके gen_event:add_handler/3 या gen_event:add_sup_handler/3 बाद के परिदृश्य में, Common Test इवेंट मैनेजर के संदर्भ की आवश्यकता होती है। इसे प्राप्त करने के लिए, ct:get_event_mgr_ref/0 या ( Common Test मास्टर नोड पर) ct_master:get_event_mgr_ref/0

12.2 उपयोग करें

ईवेंट हैंडलर को एक event_handler स्टार्ट फ्लैग ( ct_run ) या विकल्प ct:run_test/1 द्वारा स्थापित किया जा सकता है, जहां तर्क एक या एक से अधिक ईवेंट हैंडलर मॉड्यूल के नामों को निर्दिष्ट करता है।

उदाहरण:

$ ct_run -suite test/my_SUITE -event_handler handlers/my_evh1 handlers/my_evh2 -pa $PWD/handlers

ईवेंट हैंडलर ct_run -event_handler_init फ़ंक्शन के लिए दलीलें पास करने के लिए, ct_run -event_handler_init बजाय ct_run -event_handler_init विकल्प का उपयोग करें।

ध्यान दें

सभी घटना हैंडलर मॉड्यूल में gen_event व्यवहार होना चाहिए। इन मॉड्यूलों को पहले से तैयार किया जाना चाहिए और उनके स्थानों को स्पष्ट रूप से Erlang कोड सर्वर खोज पथ में जोड़ा जाना चाहिए (पिछले उदाहरण के अनुसार)।

एक इवेंट_हैंडलर टपल बहस में है। ऑप्स की निम्नलिखित परिभाषा है (देखें ct:run_test/1 ):

{event_handler,EventHandlers}

EventHandlers = EH | [EH]
EH = atom() | {atom(),InitArgs} | {[atom()],InitArgs}
InitArgs = [term()]

निम्न उदाहरण में, my_SUITE परीक्षण के लिए दो ईवेंट हैंडलर इंस्टॉल किए गए हैं:

1> ct:run_test([{suite,"test/my_SUITE"},{event_handler,[my_evh1,{my_evh2,[node()]}]}]).

इवेंट हैंडलर my_evh1 को init फ़ंक्शन के तर्क के रूप में [] से शुरू किया जाता है। इवेंट हैंडलर my_evh2 को init तर्क सूची में वर्तमान नोड के नाम के साथ शुरू किया गया है।

इवेंट हैंडलर को निम्नलिखित test specification शर्तों में से एक का उपयोग करके प्लग किया जा सकता है:

  • {event_handler, EventHandlers}
  • {event_handler, EventHandlers, InitArgs}
  • {event_handler, NodeRefs, EventHandlers}
  • {event_handler, NodeRefs, EventHandlers, InitArgs}

EventHandlers मॉड्यूल नामों की एक सूची है। एक परीक्षण सत्र शुरू होने से पहले, ईवेंट हैंडलर में प्रत्येक प्लग इन का फ़ंक्शन कहा जाता है ( InitArgs सूची को तर्क के रूप में या [] यदि कोई प्रारंभ तर्क निर्दिष्ट नहीं हैं)।

Common Test मास्टर इवेंट मैनेजर के लिए एक हैंडलर में प्लग करने के लिए, NodeRefs में नोड के रूप में master निर्दिष्ट करें।

घटनाओं पर मिलान करने में सक्षम होने के लिए, ईवेंट हैंडलर मॉड्यूल में हेडर फ़ाइल ct_event.hrl शामिल होना चाहिए। एक घटना निम्नलिखित परिभाषा के साथ एक रिकॉर्ड है:

#event{name, node, data}

name

घटना का लेबल (प्रकार)।

node

उस नोड का नाम जो इस घटना से उत्पन्न हुआ (केवल Common Test मास्टर इवेंट हैंडलर के लिए प्रासंगिक)।

data

घटना के लिए विशिष्ट।

सामान्य घटनाएँ

सामान्य घटनाएं इस प्रकार हैं:

#event{name = start_logging, data = LogDir}

LogDir = string() , टेस्ट रन के लिए टॉप-लेवल लॉग डायरेक्टरी।

यह घटना बताती है कि Common Test की लॉगिंग प्रक्रिया सफलतापूर्वक शुरू हो गई है और I / O संदेश प्राप्त करने के लिए तैयार है।

#event{name = stop_logging, data = []}

यह घटना इंगित करती है कि Common Test के अंत में Common Test की लॉगिंग प्रक्रिया बंद कर दी गई थी।

#event{name = test_start, data = {StartTime,LogDir}}

StartTime = {date(),time()} , परीक्षण प्रारंभ दिनांक और समय।

LogDir = string() , टेस्ट रन के लिए टॉप-लेवल लॉग डायरेक्टरी।

यह घटना इंगित करती है कि Common Test ने प्रारंभिक तैयारी पूरी कर ली है और परीक्षण मामलों को निष्पादित करना शुरू कर देता है।

#event{name = test_done, data = EndTime}

EndTime = {date(),time()} , दिनांक और समय परीक्षण समाप्त हुआ।

यह घटना इंगित करती है कि अंतिम परीक्षण मामले को निष्पादित कर दिया गया है और Common Test बंद हो रहा है।

#event{name = start_info, data = {Tests,Suites,Cases}}

Tests = integer() , परीक्षणों की संख्या।

Suites = integer() , सुइट की कुल संख्या।

Cases = integer() | unknown Cases = integer() | unknown , परीक्षण मामलों की कुल संख्या।

यह घटना प्रारंभिक परीक्षण चलाने की जानकारी देती है, जिसकी व्याख्या इस प्रकार की जा सकती है: "यह परीक्षण रन सूट के सूट की संख्या में परीक्षण के मामलों की कुल संख्या वाले टेस्ट का परीक्षण करेगा।" हालाँकि, यदि किसी परीक्षण में रिपीट प्रॉपर्टी वाला एक टेस्ट केस ग्रुप मौजूद है, तो कुल टेस्ट केस की गणना (अज्ञात) नहीं की जा सकती है।

#event{name = tc_start, data = {Suite,FuncOrGroup}}

Suite = atom() , परीक्षण सूट का नाम।

FuncOrGroup = Func | {Conf,GroupName,GroupProperties}

Func = atom() , टेस्ट केस या कॉन्फ़िगरेशन फ़ंक्शन का नाम।

Conf = init_per_group | end_per_group Conf = init_per_group | end_per_group , समूह कॉन्फ़िगरेशन फ़ंक्शन।

GroupName = atom() , समूह का नाम।

GroupProperties = list() , समूह के लिए निष्पादन संपत्तियों की सूची।

यह घटना एक परीक्षण मामले की शुरुआत, या एक समूह कॉन्फ़िगरेशन फ़ंक्शन के बारे में बताती है। घटना init_per_suite और end_per_suite लिए भी भेजी end_per_suite , लेकिन init_per_testcase और end_per_testcase लिए नहीं। यदि कोई समूह कॉन्फ़िगरेशन फ़ंक्शन प्रारंभ होता है, तो समूह का नाम और निष्पादन गुण भी निर्दिष्ट होते हैं।

#event{name = tc_logfile, data = {{Suite,Func},LogFileName}}

Suite = atom() , परीक्षण सूट का नाम।

Func = atom() , टेस्ट केस या कॉन्फ़िगरेशन फ़ंक्शन का नाम।

LogFileName = string() , टेस्ट केस लॉग फाइल का पूरा नाम।

यह घटना प्रत्येक परीक्षण मामले (और कॉन्फ़िगरेशन फ़ंक्शन init/end_per_testcase को छोड़कर) के प्रारंभ में भेजी जाती है और वर्तमान परीक्षण केस लॉग फ़ाइल के पूर्ण नाम (पूर्ण निर्देशिका पथ सहित फ़ाइल नाम) के बारे में जानकारी प्रदान करती है।

#event{name = tc_done, data = {Suite,FuncOrGroup,Result}}

Suite = atom() , सुइट का नाम।

FuncOrGroup = Func | {Conf,GroupName,GroupProperties}

Func = atom() , टेस्ट केस या कॉन्फ़िगरेशन फ़ंक्शन का नाम।

Conf = init_per_group | end_per_group Conf = init_per_group | end_per_group , समूह कॉन्फ़िगरेशन फ़ंक्शन।

GroupName = unknown | atom() GroupName = unknown | atom() , समूह का नाम (अज्ञात यदि init- या अंत कार्य समय बाहर)।

GroupProperties = list() , समूह के लिए निष्पादन संपत्तियों की सूची।

Result = ok | {auto_skipped,SkipReason} | {skipped,SkipReason} | {failed,FailReason} Result = ok | {auto_skipped,SkipReason} | {skipped,SkipReason} | {failed,FailReason} , परिणाम।

SkipReason = {require_failed,RequireInfo} | {require_failed_in_suite0,RequireInfo} | {failed,{Suite,init_per_testcase,FailInfo}} | UserTerm SkipReason = {require_failed,RequireInfo} | {require_failed_in_suite0,RequireInfo} | {failed,{Suite,init_per_testcase,FailInfo}} | UserTerm , क्यों मामला छोड़ दिया गया था।

FailReason = {error,FailInfo} | {error,{RunTimeError,StackTrace}} | {timetrap_timeout,integer()} | {failed,{Suite,end_per_testcase,FailInfo}} FailReason = {error,FailInfo} | {error,{RunTimeError,StackTrace}} | {timetrap_timeout,integer()} | {failed,{Suite,end_per_testcase,FailInfo}} , असफलता का कारण।

RequireInfo = {not_available,atom() | tuple()} RequireInfo = {not_available,atom() | tuple()} , क्यों असफल की आवश्यकता है।

FailInfo = {timetrap_timeout,integer()} | {RunTimeError,StackTrace} | UserTerm FailInfo = {timetrap_timeout,integer()} | {RunTimeError,StackTrace} | UserTerm , त्रुटि विवरण।

RunTimeError = term() , एक रनटाइम त्रुटि, उदाहरण के लिए, badmatch या badmatch

StackTrace = list() , रनटाइम त्रुटि से पहले फ़ंक्शन कॉल की सूची।

UserTerm = term() , उपयोगकर्ता द्वारा निर्दिष्ट कोई भी डेटा, या exit/1 जानकारी।

यह घटना एक परीक्षण मामले या कॉन्फ़िगरेशन फ़ंक्शन के अंत के बारे में बताती है (तत्व FuncOrGroup पर विवरण के लिए घटना tc_start देखें)। इस घटना के साथ प्रश्न में फ़ंक्शन का अंतिम परिणाम आता है। यदि फ़ंक्शन सफल, स्किप किया गया (उपयोगकर्ता द्वारा), या यदि यह विफल रहा, तो Result के शीर्ष स्तर पर यह निर्धारित करना संभव है।

गहरी खुदाई करना भी संभव है और, उदाहरण के लिए, छोड़ दिए गए या असफल होने के विभिन्न कारणों पर मिलान करना। ध्यान दें कि {'EXIT',Reason} टुपल्स का अनुवाद {error,Reason} । यह भी देखें कि यदि कोई {failed,{Suite,end_per_testcase,FailInfo} रिजल्ट प्राप्त हुआ है, तो परीक्षण केस सफल रहा, लेकिन end_per_testcase लिए end_per_testcase विफल रहा।

#event{name = tc_auto_skip, data = {Suite,TestName,Reason}}

Suite = atom() , सुइट का नाम।

TestName = init_per_suite | end_per_suite | {init_per_group,GroupName} | {end_per_group,GroupName} | {FuncName,GroupName} | FuncName

FuncName = atom() , टेस्ट केस या कॉन्फ़िगरेशन फ़ंक्शन का नाम।

GroupName = atom() , टेस्ट केस ग्रुप का नाम।

Reason = {failed,FailReason} | {require_failed_in_suite0,RequireInfo} Reason = {failed,FailReason} | {require_failed_in_suite0,RequireInfo} , ऑटो-स्किपिंग Reason = {failed,FailReason} | {require_failed_in_suite0,RequireInfo} कारण।

FailReason = {Suite,ConfigFunc,FailInfo}} | {Suite,FailedCaseInSequence} FailReason = {Suite,ConfigFunc,FailInfo}} | {Suite,FailedCaseInSequence} , विफलता का कारण।

RequireInfo = {not_available,atom() | tuple()} RequireInfo = {not_available,atom() | tuple()} , क्यों असफल की आवश्यकता है।

ConfigFunc = init_per_suite | init_per_group

FailInfo = {timetrap_timeout,integer()} | {RunTimeError,StackTrace} | bad_return | UserTerm FailInfo = {timetrap_timeout,integer()} | {RunTimeError,StackTrace} | bad_return | UserTerm , त्रुटि विवरण।

FailedCaseInSequence = atom() , एक मामले का नाम जो एक अनुक्रम में विफल रहा।

RunTimeError = term() , एक रनटाइम त्रुटि, उदाहरण के लिए badmatch या badmatch

StackTrace = list() , रनटाइम त्रुटि से पहले फ़ंक्शन कॉल की सूची।

UserTerm = term() , उपयोगकर्ता द्वारा निर्दिष्ट कोई भी डेटा, या exit/1 जानकारी।

यह घटना प्रत्येक परीक्षण मामले या कॉन्फ़िगरेशन फ़ंक्शन के लिए भेजी जाती है, जो कि Common Test में विफल init_per_suite या init_per_group कारण स्वचालित रूप से छोड़ दिया गया है, suite/0 में एक असफल require , या एक अनुक्रम में विफल परीक्षण केस। ध्यान दें कि इस घटना को कभी भी init_per_testcase विफल होने के कारण एक परीक्षण मामले के init_per_testcase होने के परिणामस्वरूप प्राप्त नहीं किया जाता है, क्योंकि यह जानकारी इवेंट tc_done के साथ tc_done । यदि एक असफल परीक्षण मामला एक परीक्षण केस समूह का है, तो दूसरा डेटा तत्व एक टपल {FuncName,GroupName} , अन्यथा केवल फ़ंक्शन नाम।

#event{name = tc_user_skip, data = {Suite,TestName,Comment}}

Suite = atom() , सुइट का नाम।

TestName = init_per_suite | end_per_suite | {init_per_group,GroupName} | {end_per_group,GroupName} | {FuncName,GroupName} | FuncName

FuncName = atom() , टेस्ट केस या कॉन्फ़िगरेशन फ़ंक्शन का नाम।

GroupName = atom() , टेस्ट केस ग्रुप का नाम।

Comment = string() , क्यों परीक्षण मामले को छोड़ दिया गया था।

यह घटना निर्दिष्ट करती है कि उपयोगकर्ता द्वारा एक परीक्षण मामला छोड़ दिया गया था। यह केवल तभी प्राप्त होता है जब स्किप को एक परीक्षण विनिर्देश में घोषित किया जाता है। अन्यथा, उपयोगकर्ता स्किप की जानकारी परीक्षण मामले के लिए इवेंट tc_done में {skipped,SkipReason} परिणाम के रूप में प्राप्त की जाती है। यदि कोई छोड़ दिया गया परीक्षण मामला किसी परीक्षण केस समूह का है, तो दूसरा डेटा तत्व एक टपल {FuncName,GroupName} , अन्यथा केवल फ़ंक्शन नाम।

#event{name = test_stats, data = {Ok,Failed,Skipped}}

Ok = integer() , सफल परीक्षण मामलों की वर्तमान संख्या।

Failed = integer() , विफल परीक्षण मामलों की वर्तमान संख्या।

Skipped = {UserSkipped,AutoSkipped}

UserSkipped = integer() , उपयोगकर्ता-स्किप किए गए परीक्षण मामलों की वर्तमान संख्या।

AutoSkipped = integer() , ऑटो-स्किप किए गए परीक्षण मामलों की वर्तमान संख्या।

यह अब तक के सफल, छोड़े गए और असफल परीक्षण मामलों की वर्तमान गणना के साथ एक आँकड़े घटना है। यह घटना प्रत्येक परीक्षण मामले के अंत के बाद भेजी जाती है, तुरंत घटना tc_done

आंतरिक घटनाएँ

आंतरिक घटनाएं इस प्रकार हैं:

#event{name = start_make, data = Dir}

Dir = string() , इस निर्देशिका में चल रही है।

इस आंतरिक घटना में कहा गया है कि Common Test निर्देशिका Dir में मॉड्यूल का संकलन शुरू करता है।

#event{name = finished_make, data = Dir}

Dir = string() , इस निर्देशिका में रनिंग मेक समाप्त।

इस आंतरिक घटना में कहा गया है कि Common Test निर्देशिका Dir में मॉड्यूल तैयार कर रहा है।

#event{name = start_write_file, data = FullNameFile}

FullNameFile = string(), full name of the file.

इस आंतरिक घटना का उपयोग Common Test मास्टर प्रक्रिया द्वारा विशेष फ़ाइल संचालन को सिंक्रनाइज़ करने के लिए किया जाता है।

#event{name = finished_write_file, data = FullNameFile}

FullNameFile = string(), full name of the file.

इस आंतरिक घटना का उपयोग Common Test मास्टर प्रक्रिया द्वारा विशेष फ़ाइल संचालन को सिंक्रनाइज़ करने के लिए किया जाता है।

टिप्पणियाँ

घटनाओं को ct_event.erl में भी प्रलेखित किया ct_event.erl । यह मॉड्यूल एक उदाहरण के रूप में काम कर सकता है कि Common Test इवेंट मैनेजर के लिए इवेंट हैंडलर कैसा दिख सकता है।

ध्यान दें

यह सुनिश्चित करने के लिए कि प्रिंटआउट stdout (या ct:log/2,3 या ct:pal,2,3 बने प्रिंटआउट) टेस्ट केस लॉग फाइल में लिखे जाते हैं, और Common Test फ्रेमवर्क लॉग में नहीं, आप इसे सिंक्रनाइज़ कर सकते हैं Common Test सर्वर tc_start और tc_done पर मेल tc_done । इन घटनाओं के बीच की अवधि में, सभी I / O को परीक्षण केस लॉग फ़ाइल के लिए निर्देशित किया जाता है। संभावित समय की समस्याओं से बचने के लिए इन घटनाओं को समकालिक रूप से भेजा जाता है (उदाहरण के लिए, कि एक बाहरी प्रक्रिया से I / O संदेश मिलने से ठीक पहले परीक्षण केस लॉग फ़ाइल बंद हो जाती है)। यह जानकर, आपको सावधान रहने की जरूरत है कि आपका handle_event/2 कॉलबैक फ़ंक्शन परीक्षण निष्पादन को रोक नहीं सकता है, जिसके परिणामस्वरूप संभवतः अप्रत्याशित व्यवहार हो सकता है।