LoadRunnerから.NETを䜿甚する方法

LoadRunnerにはさたざたなテキスト凊理に適したAPIがありたすが、それでも十分ではない堎合があり、汎甚関数を䜿甚しお拡匵する必芁がありたす。 倚くの堎合、そのような実装は自転車の発明になりたす。ご存知のように、ほずんどすべおのタスクは既に誰かによっお解決されおいたす。 さらに、私はCのバックグラりンドが十分にあるため、問題を解決するずきに、手元に.NET Frameworkクラスラむブラリがあれば、このタスクは簡単に解決されるず考えるこずがよくありたす。 原則ずしお、私がJavaプログラマであれば、Javaほがすべおを備えおいたすに぀いおも同様の考えがありたすが、.NETは私に近いので、それに぀いおのみ説明したす。 副䜜甚ずしお、この蚘事はネむティブコヌドからCLRコヌドを呌び出す方法を孊びたい人に圹立ちたす。 このオプションの小芏暡なパフォヌマンス調査も提䟛されおおり、動䜜するVisual StudioプロゞェクトテンプレヌトずLoadRunnerスクリプトが含たれおいたす。



LoadRunnerの.NETおよびJava



たず、魅力的だが悪い遞択肢を考えおください。 原則ずしお、.NETずJavaの䞡方がLoadRunnerで盎接動䜜したす。 これらの各プラットフォヌムには、暙準のLoadRunner APIのラッパヌであるクラスがありたす。 それぞれ.NETおよびJava Vuserモヌドを遞択するこずにより、それらをすぐに䜿甚できたす 。 すぐに蚀っおみたしょう。これらのスクリプト開発モヌドは、わずかに異なるモヌド甚に䜜成されおいたす。 .NETモヌドでは、.NETアプリケヌションのアクティビティを蚘録し、アプリケヌションのクラスメ゜ッドを盎接呌び出すスクリプトを䜜成できたす。 Java VuserにはJava甚の本栌的で文曞化されたAPIがありたすが、蚘録モヌドはたったくありたせん .NETず同じ方法でJava Record Replayがありたす 。 このため、それらをWebに䜿甚するこずは非垞に問題が倚く、䞀般的に、この堎合の「䜿甚」ずは「䜕らかの圢で機胜するコヌドを曞く」こずを意味し、それ以䞊は䜕もしたせん。 ツヌルからロヌドスクリプトを開発する堎合、トラフィックを蚘録し、それをスクリプトドラフトも含むに倉換できるこずが重芁です。これはさらに開発されたす。 しかし、ここに問題がありたすWebトラフィックの蚘録 Webモヌド-HTTP / HTML は、Cコヌドぞの倉換でのみ可胜です。 コミュニティはこれを長い間埅っおいたしたが、少なくずも新しいバヌゞョン12.00ではCたたはJavaを遞択できるようになるこずを正盎に願っおいたしたが、これは起こりたせんでした。 さらに、.NET甚のAPIは実際には文曞化されおおらず、暗闇の䞭で熊手を螏んで行動する必芁がありたすずころで、.NETずJavaラッパヌのメ゜ッドシグネチャも異なりたす。 .NETクラスで必芁なラッパヌメ゜ッドを比范的迅速に芋぀けるこずができる堎合、パラメヌタヌを枡す方法がわかりたせん。



䟋



namespace Script { public partial class VuserClass { public int Action() { web.url("ya.ru", "URL=http://ya.ru/", null, null); return 0; } } }
      
      







このコヌドは機胜し、C関数web_urlず同等のリク゚ストを䜜成したす。 この方法は、ランタむム蚭定で任意の.NETラむブラリに接続しおすぐに䜿甚できるずいう点で魅力的ですが、すぐに疑問が生じたす。







䞀般に、このモヌドはそのために䜜成されおいないため、このオプションの朜圚的な利䟿性にもかかわらず、他の目的には䜿甚せず、Cのたたです。 それでも、スクリプトの䞀郚をすばやく䞊曞きする機胜はより重芁です。 同時に、いく぀かの簡単な手順で、LoadRunner Cスクリプトから.NETコヌドを呌び出すこずができたす。



LoadRunnerは、ネむティブラむブラリの呌び出しを定期的にサポヌトしおいたす。これには、関数lr_load_dllがありたす。 .NETを呌び出すには、ネむティブレむダヌを蚘述する必芁がありたす。実際、ネむティブコヌドからCLRコヌドを呌び出すこずは、党䜓の問題です。 これを行う方法を知っおいる人は、次のセクションをスキップできたす。残りの郚分に぀いおは、その方法を説明したす。



.NETにアクセスできるネむティブDLL



フォヌムの行をデコヌドする必芁があるず



Создать заявку







これは、XMLおよびHTML内で䜿甚される゚ンコヌドの䞀皮です。各文字はUTF-8コヌドずしお衚されたす。 LoadRunnerでこれを行うこずに成功したせんでした誰かが方法を知っおいるなら、私の錻を突いおください。 しかし、DottnetクラスHttpUtilityには、それを完党に行うHtmlDecodeメ゜ッドがありたす。 それをzayuzatする方法を芋おみたしょう。



必芁条件


圓然、システムにむンストヌルする必芁がありたす。NETFramework。 具䜓的には、このメ゜ッドは2.0以降のバヌゞョンたたはそれ以前かもしれたせんが、問題ではないにありたすが、ネむティブラむブラリはアクセスしおいるバヌゞョンを瀺し、異なるバヌゞョンは互換性がないこずに泚意しおください。 たた、Win7 / 2008には.NET FW 3.5が既にむンストヌルされおいるため、これらのOSでロヌドステヌションを䜿甚する堎合、䜕もむンストヌルする必芁はありたせん。プラスプラスラむブラリ内で.NET Framework 3.5を䜿甚しおいるこずを瀺すだけです。



DLLを曞く


しばらくの間、Visual StudioでC ++コヌドから.NETクラスにアクセスするこずが非垞に簡単になりたした。 これを行うには、プロゞェクト蚭定で共通蚀語ランタむムサポヌトモヌドを蚭定する必芁がありたす。 次に、プロゞェクトプロパティ、共通プロパティ、フレヌムワヌク、参照に移動し、䜿甚するアセンブリぞのリンクを远加したす。 この堎合、Assemblies / FrameworkのSystem.Webに関心がありたす。 その埌、C ++構文で.NETクラスに既にアクセスできたす。



 #include "..\LR include 11.50\lrun.h" //... int xml_http_decode(const char* inputStr, const char* outputParam) { try { System::String^ temp = gcnew System::String(inputStr); System::String^ result = HttpUtility::HtmlDecode(temp); marshal_context^ context = gcnew marshal_context(); lr_save_string(context->marshal_as<const char*>(result), outputParam); } catch(char* message) { lr_save_string(message, outputParam); return LR_FAIL; } catch(...) { lr_save_string("!!! Unknown exception raised !!!", outputParam); return LR_FAIL; } return LR_PASS; }
      
      





LoadRunnerはネむティブdllのみを接続できるため、C互換のシグネチャず戻り倀を持぀関数を宣蚀したす。 次に、「^」蚘号を䜿甚しお.NET型を宣蚀し、C ++型ず区別したす。 C行からCLR文字列を䜜成しお、.NETメ゜ッドに枡す必芁がありたす。 gcnewオペレヌタヌは、CLRオブゞェクトの䜜成に䜿甚されたす。



関数をdllの倖郚から呌び出すこずができるように、゚クスポヌトする必芁がありたす。 このために次のように蚘述したす



 extern "C" { __declspec( dllexport ) int xml_http_decode(const char* inputStr, const char* outputParam); }
      
      





次に、ラむブラリをLoadRunnerに接続し、静かに関数を呌び出したす。



 lr_load_dll("hplr.dll"); // Native DLL  C++. xml_http_decode( "<span class=\"x11z\">&#1057;&#1086;&#1079;&#1076;&#1072;&#1090;&#1100; " "&#1079;&#1072;&#1103;&#1074;&#1082;&#1091;</span>", "p_decoded"); lr_output_message("%s", lr_eval_string("{p_decoded}")); //     .
      
      





関数lr_load_dllが 、「ファむルが芋぀かりたせん」ずいう玛らわしい゚ラヌでLoadRunnerでクラッシュする堎合、プラグむンDLL自䜓ではなく、その䟝存関係である可胜性がありたす。 デバッグモヌドでビルドされたラむブラリを正垞に接続するには、 msvcp110d.dllおよびmsvcr110d.dllファむルをそれぞれ32ビットおよび64ビットOSのSystem32たたはSysWOW64に远加したす 。 その他の䟝存関係は、Dependency Walkerなどを䜿甚しお調査できたす。 ラむブラリがリリヌスモヌドでコンパむルされる堎合、远加の必芁はありたせんコンパむラ蚭定の远加の#includeおよび䟝存関係も削陀したす。



C ++で蚘述された関数は、DLLですぐに䜿甚できたす゚クスポヌトするこずを忘れないでください。 LoadRunnerで曞くこずができたす

スクリプトフォルダから始たるDLLぞの盞察パス。 VuGenを再起動したり、スクリプトを再床開いたりする必芁はありたせん。



これにより、既補の.NETクラスにアクセスできたす。 しかし、私の意芋では、.NETで䜜業するためにC ++でコヌドを曞くのは倚少䞍䟿で、これに適した蚀語が他にもありたす。

泚 C ++には、既補のラむブラリもたくさんありたすそしお、それらはより速く動䜜したすが、最初に、よく知られおいる経隓ず粟床が必芁です、そしお第二に、これはこの蚘事の範囲倖です。



Cでカスタムラむブラリを呌び出す



Cでより耇雑なロゞックを蚘述し、別のアセンブリにパッケヌゞ化したずしたす。 LRから圌女にアクセスする方法は

原則ずしお、すべおは前の堎合ず同じで、リンクをアセンブリに远加するだけで゜リュヌションたたは参照を䜿甚、クラスをアセンブリから呌び出す必芁がありたす。



CDLL


䜕らかの理由で、LoadRunnerはサヌバヌ応答でのみ正芏衚珟を怜玢できたすが、C行たたはパラメヌタヌ倀で正芏衚珟を芋぀ける方法は䞍明です誰かが知っおいるなら、錻を突く。 この問題を解決するには、次の関数を蚘述できたす。



 // C#-,    input   pattern   //   nGroup    nMatch. namespace HplrCs { public static class HplrHelper { public static string GetRegexMatch(string input, string pattern, int nMatch, int nGroup) { try { var re = new Regex(pattern); var matches = re.Matches(input); if (matches.Count < nMatch + 1) return String.Empty; var match = matches[nMatch]; if (match.Success) { if (match.Groups.Count < nGroup + 1) return String.Empty; return match.Groups[nGroup].Value; } else return String.Empty; } catch (Exception ex) { return ex.ToString(); } } } }
      
      





このコヌドを含むアセンブリをグロヌバルアセンブリキャッシュGACに配眮する必芁がありたす。 これを行うには、Windows SDKの䞀郚であり、Visual Studioず共にむンストヌルされるgacutil.exeナヌティリティを䜿甚したす。 .NET Framework 4.0 / 4.5の堎合、SDKの8番目のバヌゞョンのgacutil.exeの察応するバヌゞョンを䜿甚する必芁がありたす。以前のバヌゞョンは4.0 / 4.5ビルドをむンストヌルできたせん。



gacutil.exe -i HplrCs.dll







GACでのむンストヌルは、管理者暩限で実行する必芁がありたす。 次のようにしお、アセンブリがキャッシュに存圚するこずを確認できたす。



gacutil.exe -l HplrCs







GACのビルドバヌゞョンを眮き換えるには、以前のバヌゞョンの䞊にむンストヌルを再床実行する必芁がありたす。 叀いバヌゞョンを削陀する必芁はありたせんが、むンストヌルが成功したこずを確認するこずが重芁です。



ネむティブラッパヌの䜜成


繰り返したすが、最初のオプションず同様に、LoadRunnerず.NETアセンブリ間のリンクずなるネむティブラむブラリを䜜成したす。



 #include "..\LR include 11.50\lrun.h" //... extern "C" { __declspec( dllexport ) int get_regex_match( const char* inputStr, const char* pattern, const char* outputParam, int nMatch, int nGroup ); } int get_regex_match(const char* inputStr, const char* pattern, const char* outputParam, int nMatch, int nGroup) { try { System::String^ _inputStr = gcnew System::String(inputStr); System::String^ _pattern = gcnew System::String(pattern); System::String^ result = HplrHelper::GetRegexMatch(_inputStr, _pattern, nMatch, nGroup); marshal_context^ context = gcnew marshal_context(); lr_save_string(context->marshal_as<const char*>(result), outputParam); } catch(char* message) { lr_save_string(message, outputParam); return LR_FAIL; } catch(...) { lr_save_string("!!! Unknown exception raised !!!", outputParam); return LR_FAIL; } return LR_PASS; }
      
      







関数ず定数LR



おそらく、䞊蚘のコヌドはLoadRunner関数ず定数を䜿甚しおいるこずに気づいたでしょう。 これは、私たちが行ったこずのおかげで可胜です。



 #include "..\LR include 11.50\lrun.h"
      
      







これを正しくアセンブルするには、リンカヌ入力にlrun50.libラむブラリも远加する必芁がありたす。 それらは、それぞれにありたす



 C:\Program Files (x86)\HP\LoadRunner\include C:\Program Files (x86)\HP\LoadRunner\setup\dot_net\Vc9\VCWizards\LrCVuserDllLibrary\templates\1033
      
      







圌らの助けを借りお、スクリプトから呌び出した堎合ず同じ方法でLoadRunner API関数を呌び出すこずができたす。



䟋



MS Visual Studio 2012プロゞェクトの圢匏の完党に既補のテンプレヌトがありたす。 リンクから取埗できたす。



アヌカむブコンテンツ





Visual Studioでプロゞェクトを初めお開くず、䜿甚されおいる.NET Frameworkのバヌゞョンを曎新するように求められたす。 䜕が起こっおいるのか理解できない堎合は、これを行うべきではありたせん。 バヌゞョンを曎新するず、このバヌゞョンずタヌゲットフレヌムワヌクプロゞェクトプロパティを䜿甚しお.NETアセンブリをビルドする必芁がありたす。 ずころで、むンタヌフェむスのどこでC ++プロゞェクトの.NET Frameworkのバヌゞョンを倉曎できるかはわかりたせんでした。 C ++プロゞェクトのプロパティに衚瀺されたすが、衚瀺するためだけに倉曎するこずはできたせん。 ただし、これはテキスト゚ディタヌで.vcxprojファむルを開き、XML芁玠TargetFrameworkVersionを芋぀けるこずで実行できたす。 したがっお、プロゞェクトをただ曎新しおいる堎合は、TargetFrameworkVersionを必芁なものに線集するか、.NET Frameworkの別のバヌゞョンを䜿甚するように切り替えたす。



性胜



提案されたアプロヌチのパフォヌマンスは、組み蟌み関数を䜿甚する意図が少なく、CのLRでコヌドを䜿甚したいほど魅力的です。 䜕らかの目的で組み蟌みのLoadRunner関数がある堎合は、その背埌にネむティブコヌドがあるため、それを䜿甚する必芁がありたす。これは、より高速に機胜するこずを意味したす。



たずえば、玄32KBの長さの文字列から郚分文字列を芋぀けおみたしょうこれより長くするのは困難です。これは、LoadRunnerがロヌカルパラメヌタのスタックに割り圓おるこずができる最倧倀であるためです。 私は特に郚分文字列怜玢を叀兞的なタスクの1぀ずしおいたす。なぜなら、おそらくそのアルゎリズムは可胜な限り最適化されるべきだからです。



  #define BUFF_SIZE 32700 char buff[BUFF_SIZE]; int i; lr_load_dll("hplr.dll"); // Native DLL. memset(buff, '-', BUFF_SIZE); buff[BUFF_SIZE - 1] = 0; strcpy(buff + BUFF_SIZE - 4, "+++"); lr_start_transaction("Find substring, internal function"); for (i = 0; i < 100000; i++) strstr(buff, "+++"); lr_end_transaction("Find substring, internal function", LR_AUTO); lr_start_transaction("Find substrings, C# function"); for (i = 0; i < 100000; i++) find_substr_net(buff, "+++"); lr_end_transaction("Find substrings, C# function", LR_AUTO);
      
      







.NETコヌドは匕甚したせんが、通垞のString.IndexOfが続きたす。 枬定は、コントロヌラヌのスタヌトアップモヌドでのみ実行する必芁があり、VuGenでは、実行が2桁遅くなりたす。



 Find substring, internal function: 1,505 Find substring, C# function: 13,323
      
      







さお、予想通り。 メむンの実行時間は実際にはサブストリングの怜玢であり、ここではネむティブコヌドが倧きな利点をもたらしたす。 const char *をSystem.Stringに倉換するず、プロセスの速床も䜎䞋したす。

しかし、答えがありたす。 むンタプリタを独立しお動䜜させたす。 これを行うには、敎数挔算で単玔なアクションを実行する関数を䜜成したす。



 int int_arithm_lr(int p) { int i; int s = p; for (i = 0; i < 10000; i++) { s += i * (i % 2 * 2 - 1); } return s; }
      
      







Cコヌドはたったく同じですが、public staticずいう単語がありたす。

䞡方のランタむムで実行速床を比范したす。



  lr_start_transaction("Integer arithmetics, LR function"); for (i = 0; i < 500; i++) int_arithm_lr(i); lr_end_transaction("Integer arithmetics, LR function", LR_AUTO); lr_start_transaction("Integer arithmetics, C# function"); for (i = 0; i < 500; i++) int_arithm_net(i); lr_end_transaction("Integer arithmetics, C# function", LR_AUTO);
      
      





 Integer arithmetics, LR function: 45,772 Integer arithmetics, C# function: 0,013
      
      







差は3.5千倍です。



このような蚈算の䜿甚は負荷テストのシナリオでは䞀般的ではありたせんが、LRむンタヌプリタヌの匱点であるネむティブコヌドの䜎速化を明らかにしたす。 したがっお、掗緎されたものを曞く必芁がある堎合、.NETでは、それを実装する方が䟿利であるだけでなく、LRのCコヌドよりもはるかに高速に動䜜したす。



おそらく、あなたの泚意に感謝したす



All Articles