Erlang 21 - 9. External Configuration Data

9 बाहरी कॉन्फ़िगरेशन डेटा




erlang

9 बाहरी कॉन्फ़िगरेशन डेटा

9.1 सामान्य

परीक्षण सूट में परीक्षण और / या सिस्टम अंडर टेस्ट (एसयूटी) से संबंधित हार्ड-कोडिंग डेटा मूल्यों से बचने के लिए, डेटा को कॉन्फ़िगरेशन फ़ाइलों या स्ट्रिंग्स के माध्यम से निर्दिष्ट किया जा सकता है जो कि Common Test की शुरुआत से पहले Common Test पढ़ता है। बाहरी कॉन्फ़िगरेशन डेटा डेटा का उपयोग करके परीक्षण सुइट्स को संशोधित किए बिना परीक्षण गुणों को बदलना संभव बनाता है। कॉन्फ़िगरेशन डेटा के उदाहरण इस प्रकार हैं:

  • परीक्षण संयंत्र या अन्य उपकरणों को संबोधित करता है
  • उपयोगकर्ता लॉगिन जानकारी
  • परीक्षण के लिए आवश्यक फाइलों के नाम
  • परीक्षण के दौरान निष्पादित किए जाने वाले कार्यक्रमों के नाम
  • परीक्षण द्वारा आवश्यक कोई अन्य चर

9.2 सिंटेक्स

कॉन्फ़िगरेशन फ़ाइल में किसी भी प्रकार के तत्व शामिल हो सकते हैं:

{CfgVarName,Value}.

कहा पे

CfgVarName = atom()
Value = term() | [{CfgVarName,Value}]

9.3 कॉन्फ़िगरेशन डेटा की आवश्यकता और पढ़ना

एक परीक्षण सूट में, एक की आवश्यकता होनी चाहिए कि एक कॉन्फ़िगरेशन चर (पिछली परिभाषा में CfgVarName ) एक परीक्षण मामले या कॉन्फ़िगरेशन फ़ंक्शन में संबंधित मूल्य को पढ़ने का प्रयास करने से पहले मौजूद है।

require एक मुखर कथन है, जो Test Suite Information Function या Test Case Information Function हिस्सा हो सकता है। यदि आवश्यक चर अनुपलब्ध है, तो परीक्षण को छोड़ दिया जाता है (जब तक कि कोई डिफ़ॉल्ट मान निर्दिष्ट नहीं किया गया है, विवरण के लिए अनुभाग Test Case Information Function देखें)। इसके अलावा, फ़ंक्शन ct:require/1/2 को परीक्षण मामले से यह जांचने के लिए बुलाया जा सकता है कि क्या कोई विशिष्ट चर उपलब्ध है। इस फ़ंक्शन से वापसी मान को स्पष्ट रूप से जांचना चाहिए और परिणाम के आधार पर उचित कार्रवाई की जानी चाहिए (उदाहरण के लिए, परीक्षण मामले को छोड़ने के लिए यदि प्रश्न में चर मौजूद नहीं है)।

परीक्षण सूट सूचना मामले या परीक्षण मामले की जानकारी-सूची में एक require कथन की require {require,CfgVarName} या {require,AliasName,CfgVarName} । तर्क AliasName और CfgVarName ct:require/1/2 के तर्क के समान हैं ct:require/1/2 AliasName कॉन्फ़िगरेशन चर के लिए एक उपनाम बन जाता है, और इसका उपयोग कॉन्फ़िगरेशन डेटा मान के संदर्भ के रूप में किया जा सकता है। कॉन्फ़िगरेशन चर किसी भी संख्या में अन्य नामों से संबद्ध हो सकता है, लेकिन प्रत्येक नाम एक ही परीक्षण सूट के भीतर अद्वितीय होना चाहिए। उपनाम नामों के लिए दो मुख्य उपयोग इस प्रकार हैं:

  • कनेक्शन की पहचान करने के लिए (बाद में वर्णित)।
  • एक परीक्षण सूट (या परीक्षण मामले) में कॉन्फ़िगरेशन डेटा को अनुकूलित करने और पठनीयता में सुधार करने में मदद करने के लिए।

कॉन्फ़िगरेशन चर का मान पढ़ने के लिए, फ़ंक्शन get_config/1,2,3 उपयोग करें।

उदाहरण:

suite() -> 
    [{require, domain, 'CONN_SPEC_DNS_SUFFIX'}].

...

testcase(Config) ->
    Domain = ct:get_config(domain),
    ...

9.4 कई फाइलों में विन्यास चर का उपयोग करना

यदि एक कॉन्फ़िगरेशन चर को कई फ़ाइलों में परिभाषित किया गया है और आप सभी संभव मानों तक पहुंचना चाहते हैं, तो फ़ंक्शन ct:get_config/3 का उपयोग करें और all को विकल्प सूची में निर्दिष्ट करें। मानों को फिर एक सूची में लौटाया जाता है और तत्वों का क्रम उस क्रम से मेल खाता है जो कॉन्फ़िगरेशन फ़ाइलों को स्टार्टअप पर निर्दिष्ट किया गया था।

9.5 एन्क्रिप्टेड कॉन्फ़िगरेशन फ़ाइलें

संवेदनशील डेटा वाली कॉन्फ़िगरेशन फ़ाइलों को एन्क्रिप्ट किया जा सकता है अगर उन्हें खुले और साझा निर्देशिकाओं में संग्रहीत किया जाना चाहिए।

अनुप्रयोग Crypto में फ़ंक्शन DES3 का उपयोग करके एक निर्दिष्ट फ़ाइल को Common Test एन्क्रिप्ट करने के लिए, ct:encrypt_config_file/2,3 एन्क्रिप्ट की गई फ़ाइल को अन्य एन्क्रिप्ट की गई फ़ाइलों या सामान्य पाठ फ़ाइलों के साथ संयोजन में एक नियमित कॉन्फ़िगरेशन फ़ाइल के रूप में उपयोग किया जा सकता है। हालाँकि, कॉन्फ़िगरेशन फ़ाइल को डिक्रिप्ट करने के लिए कुंजी परीक्षण प्रदान करते समय प्रदान की जानी चाहिए। यह ध्वज / विकल्प decrypt_key या decrypt_file , या पूर्वनिर्धारित स्थान की एक कुंजी फ़ाइल के साथ किया जा सकता है।

Common Test भी डिक्रिप्शन फ़ंक्शंस प्रदान करता है, ct:decrypt_config_file/2,3 , मूल पाठ फ़ाइलों को पुनः बनाने के लिए।

9.6 कॉन्फ़िगरेशन डेटा का उपयोग करके कनेक्शन खोलना

उदाहरण के लिए, ct_ssh , ct_ftp , और ct_telnet इस प्रकार, समर्थन कार्यों का उपयोग करके कनेक्शन खोलने के लिए दो अलग-अलग तरीके हैं:

  • संदर्भ के रूप में एक कॉन्फ़िगरेशन लक्ष्य नाम (एक उपनाम) का उपयोग करना।
  • संदर्भ के रूप में कॉन्फ़िगरेशन चर का उपयोग करना।

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

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

9.7 उपयोगकर्ता-विशिष्ट कॉन्फ़िगरेशन डेटा प्रारूप

उपयोगकर्ता एक पाठ फ़ाइल में कुंजी-मूल्य ट्यूपल्स की तुलना में एक अलग प्रारूप पर कॉन्फ़िगरेशन डेटा निर्दिष्ट कर सकता है, जैसा कि अब तक वर्णित है। उदाहरण के लिए, डेटा, HTTP पर वेब से प्राप्त की गई किसी भी फाइल से पढ़ा जा सकता है, या उपयोगकर्ता-विशिष्ट प्रक्रिया से अनुरोध किया जा सकता है। इसका समर्थन करने के लिए, Common Test कॉन्फ़िगरेशन डेटा को संभालने के लिए एक कॉलबैक मॉड्यूल प्लगइन तंत्र प्रदान करता है।

कॉन्फ़िगरेशन डेटा को संभालने के लिए डिफ़ॉल्ट कॉलबैक मॉड्यूल

Common Test में मानक कॉन्फ़िगरेशन फ़ाइलों (पहले वर्णित) और XML फ़ाइलों में निर्दिष्ट कॉन्फ़िगरेशन डेटा को संभालने के लिए डिफ़ॉल्ट कॉलबैक मॉड्यूल शामिल हैं:

  • ct_config_plain - कुंजी-मूल्य टुपल्स (मानक प्रारूप) के साथ कॉन्फ़िगरेशन फ़ाइलों को पढ़ने के लिए। यदि कोई उपयोगकर्ता कॉलबैक निर्दिष्ट नहीं है, तो यह हैंडलर कॉन्फ़िगरेशन फ़ाइलों को पार्स करने के लिए उपयोग किया जाता है।
  • ct_config_xml - XML ​​फ़ाइलों से कॉन्फ़िगरेशन डेटा पढ़ने के लिए।

XML कॉन्फ़िगरेशन फ़ाइलों का उपयोग करना

XML कॉन्फ़िगरेशन फ़ाइल का एक उदाहरण इस प्रकार है:

<config>
   <ftp_host>
       <ftp>"targethost"</ftp>
       <username>"tester"</username>
       <password>"letmein"</password>
   </ftp_host>
   <lm_directory>"/test/loadmodules"</lm_directory>
</config>

एक बार पढ़ने के बाद, यह फ़ाइल निम्न पाठ फ़ाइल के समान कॉन्फ़िगरेशन चर उत्पन्न करती है:

{ftp_host, [{ftp,"targethost"},
            {username,"tester"},
            {password,"letmein"}]}.

{lm_directory, "/test/loadmodules"}.

उपयोगकर्ता-विशिष्ट हैंडलर लागू करें

उपयोगकर्ता-विशिष्ट हैंडलर को विशेष कॉन्फ़िगरेशन फ़ाइल स्वरूपों को संभालने के लिए लिखा जा सकता है। पैरामीटर फ़ाइल नाम या कॉन्फ़िगरेशन स्ट्रिंग्स (खाली सूची मान्य है) या तो हो सकता है।

हैंडलर को लागू करने वाला कॉलबैक मॉड्यूल कॉन्फ़िगरेशन स्ट्रिंग्स की शुद्धता की जांच करने के लिए जिम्मेदार है।

कॉन्फ़िगरेशन स्ट्रिंग्स को मान्य करने के लिए, कॉलबैक मॉड्यूल में फ़ंक्शन Callback:check_parameter/1 निर्यात किया गया।

Common Test से इनपुट तर्क पारित किया जाता है, जैसा कि परीक्षण विनिर्देश में परिभाषित किया गया है, या ct_run या ct:run_test विकल्प के रूप में निर्दिष्ट किया गया है।

वापसी मान निम्न में से कोई भी मान होना चाहिए, यह दर्शाता है कि निर्दिष्ट कॉन्फ़िगरेशन पैरामीटर मान्य है:

  • {ok, {file, FileName}} - पैरामीटर एक फ़ाइल नाम है और फ़ाइल मौजूद है।
  • {ok, {config, ConfigString}} - पैरामीटर एक कॉन्फ़िगरेशन स्ट्रिंग है और यह सही है।
  • {error, {nofile, FileName}} - वर्तमान निर्देशिका में निर्दिष्ट नाम के साथ कोई फ़ाइल नहीं है।
  • {error, {wrong_config, ConfigString}} - कॉन्फ़िगरेशन स्ट्रिंग गलत है।

फ़ंक्शन Callback:read_config/1 को कॉलबैक मॉड्यूल से कॉन्फ़िगरेशन डेटा पढ़ने के लिए निर्यात किया जाता है, शुरू में परीक्षण शुरू होने से पहले या परीक्षण निष्पादन के दौरान डेटा को फिर से लोड किए जाने के परिणामस्वरूप। इनपुट तर्क फ़ंक्शन check_parameter/1 लिए समान है।

वापसी मान निम्नलिखित में से एक है:

  • {ok, Config} - यदि कॉन्फ़िगरेशन चर सफलतापूर्वक पढ़े जाते हैं।
  • {error, {Error, ErrorDetails}} - यदि कॉलबैक मॉड्यूल निर्दिष्ट कॉन्फ़िगरेशन मापदंडों के साथ आगे बढ़ने में विफल रहता है।

Config उचित Erlang कुंजी-मूल्य सूची है, जिसमें मानों के रूप में संभावित कुंजी-मूल्य सब्लिस्ट्स हैं, जैसे पहले कॉन्फ़िगरेशन फ़ाइल उदाहरण:

[{ftp_host, [{ftp, "targethost"}, {username, "tester"}, {password, "letmein"}]},
 {lm_directory, "/test/loadmodules"}]

9.8 कॉन्फ़िगरेशन डेटा हैंडलिंग के उदाहरण

दूरस्थ होस्ट पर फ़ाइलों को एक्सेस करने के लिए FTP क्लाइंट का उपयोग करने के लिए एक कॉन्फ़िगरेशन फ़ाइल निम्नानुसार दिख सकती है:

 {ftp_host, [{ftp,"targethost"},
{username,"tester"},
{password,"letmein"}]}.

 {lm_directory, "/test/loadmodules"}.

पहले दिखाए गए XML संस्करण का भी उपयोग किया जा सकता है, लेकिन यह स्पष्ट रूप से निर्दिष्ट किया जाना है कि ct_config_xml कॉलबैक मॉड्यूल का उपयोग Common Test द्वारा किया जाना है।

निम्नलिखित इस बात का उदाहरण है कि कैसे कॉन्फ़िगरेशन डेटा उपलब्ध है और एफ़टीपी सत्र के लिए उपयोग किया जा सकता है।

init_per_testcase(ftptest, Config) ->
    {ok,_} = ct_ftp:open(ftp),
    Config.

end_per_testcase(ftptest, _Config) ->
    ct_ftp:close(ftp).

ftptest() ->
    [{require,ftp,ftp_host},
     {require,lm_directory}].

ftptest(Config) ->
    Remote = filename:join(ct:get_config(lm_directory), "loadmodX"),
    Local = filename:join(?config(priv_dir,Config), "loadmodule"),
    ok = ct_ftp:recv(ftp, Remote, Local),
    ...

निम्न उदाहरण है कि पिछले उदाहरण में फ़ंक्शन को फिर से कैसे लिखा जा सकता है यदि एफ़टीपी सर्वर में कई कनेक्शन खोलने के लिए आवश्यक है:

init_per_testcase(ftptest, Config) ->
    {ok,Handle1} = ct_ftp:open(ftp_host),
    {ok,Handle2} = ct_ftp:open(ftp_host),
    [{ftp_handles,[Handle1,Handle2]} | Config].

end_per_testcase(ftptest, Config) ->
    lists:foreach(fun(Handle) -> ct_ftp:close(Handle) end, 
                  ?config(ftp_handles,Config)).

ftptest() ->
    [{require,ftp_host},
     {require,lm_directory}].

ftptest(Config) ->
    Remote = filename:join(ct:get_config(lm_directory), "loadmodX"),
    Local = filename:join(?config(priv_dir,Config), "loadmodule"),
    [Handle | MoreHandles] = ?config(ftp_handles,Config),
    ok = ct_ftp:recv(Handle, Remote, Local),
    ...

9.9 उपयोगकर्ता-विशिष्ट कॉन्फ़िगरेशन हैंडलर का उदाहरण

एक साधारण कॉन्फ़िगरेशन हैंडलिंग ड्राइवर, कॉन्फ़िगरेशन डेटा के लिए एक बाहरी सर्वर से पूछते हुए, निम्नानुसार लागू किया जा सकता है:

-module(config_driver).
-export([read_config/1, check_parameter/1]).

read_config(ServerName)->
    ServerModule = list_to_atom(ServerName),
    ServerModule:start(),
    ServerModule:get_config().

check_parameter(ServerName)->
    ServerModule = list_to_atom(ServerName),
    case code:is_loaded(ServerModule) of
        {file, _}->
            {ok, {config, ServerName}};
        false->
            case code:load_file(ServerModule) of
                {module, ServerModule}->
                    {ok, {config, ServerName}};
                {error, nofile}->
                    {error, {wrong_config, "File not found: " ++ ServerName ++ ".beam"}}
            end
    end.

इस ड्राइवर के लिए कॉन्फ़िगरेशन स्ट्रिंग config_server हो config_server , अगर config_server.erl मॉड्यूल जो निम्न प्रकार संकलित है और परीक्षण निष्पादन के दौरान कोड पथ में मौजूद है:

-module(config_server).
-export([start/0, stop/0, init/1, get_config/0, loop/0]).

-define(REGISTERED_NAME, ct_test_config_server).

start()->
    case whereis(?REGISTERED_NAME) of
        undefined->
            spawn(?MODULE, init, [?REGISTERED_NAME]),
            wait();
        _Pid->
        ok
    end,
    ?REGISTERED_NAME.

init(Name)->
    register(Name, self()),
    loop().

get_config()->
    call(self(), get_config).

stop()->
    call(self(), stop).

call(Client, Request)->
    case whereis(?REGISTERED_NAME) of
        undefined->
            {error, {not_started, Request}};
        Pid->
            Pid ! {Client, Request},
            receive
                Reply->
                    {ok, Reply}
            after 4000->
                {error, {timeout, Request}}
            end
    end.

loop()->
    receive
        {Pid, stop}->
            Pid ! ok;
        {Pid, get_config}->
            {D,T} = erlang:localtime(),
            Pid !
                [{localtime, [{date, D}, {time, T}]},
                 {node, erlang:node()},
                 {now, erlang:now()},
                 {config_server_pid, self()},
                 {config_server_vsn, ?vsn}],
            ?MODULE:loop()
    end.

wait()->
    case whereis(?REGISTERED_NAME) of
        undefined->
            wait();
        _Pid->
            ok
    end.

यहां, हैंडलर गतिशील रूप से कॉन्फ़िगरेशन चर को फिर से लोड करने के लिए भी प्रदान करता है। यदि ct:reload_config(localtime) को टेस्ट केस फ़ंक्शन से कहा जाता है, config_driver:read_config/1 साथ लोड किए गए सभी चर config_driver:read_config/1 को उनके नवीनतम मानों के साथ अपडेट किया जाता है, और चर localtime लिए नया मान वापस आ जाता है।