テスト対象システムのすべてのコンポーネントが、定義されたワイヤプロトコルや、トラフィックを別のホストや別のエンドポイントに向けるためにテスト対象アプリケーション (AUT) を簡単に再構成することで仮想化できる API を介して通信するわけではありません。場合によっては、アプリケーション コードを直接変更しないと制御できない API を介して統合が行われます。
Java AUT を使用しているチームの場合、Parasoft の Java 仮想化エージェントを使用して、Java メソッド呼び出しをアプリケーション JVM 内で直接記録し、これらの呼び出しの動作を仮想化することができます。Parasoft Java 仮想化エージェントは、RMI、リモート EJB 呼び出し、または依存システムに機能や接続を提供するその他の内部開発コードを仮想化するのに特に便利です。
テスト対象アプリケーションは、JVM 起動パラメーターとして設定された Parasoft エージェントを使用して起動されます。そのエージェントの設定は、指定されたターゲット クラスとメソッドのそれぞれについて、非アクティブモード、記録モード、仮想化モードのいずれであるかを示します。
エージェントが記録モードになったら、記録したい動作でテスト対象アプリケーションを実行できます。エージェントは、メソッド呼び出しのデータをローカルファイルに保存します。記録された動作を表す仮想アセットを作成するには、そのファイルを Virtualize の仮想アセット作成ウィザードに渡します。
目的の動作が記録されたら、エージェントを仮想化モードに切り替え、Virtualize 仮想アセットの HTTP エンドポイントを使用して設定できます。これで、同じメソッド呼び出しが実際のメソッドではなく Virtualize PVA にリダイレクトされます。以前に記録されたオブジェクト インスタンスが返されます。
以下は、Oracle WebLogic medrec サンプル アプリケーションで記録されたサンプル PVA です。
Java メソッドの呼び出しを記録し、その戻り値を仮想化するために使用できる 2 つの異なる仮想化パターンがあります。
適用する最適なパターンは、アプリケーションのニーズによって異なります。2 つの仮想化パターンを混在させたり、指定されたクラス/メソッドごとにさまざまなモードを混在させたりすることができます。
このパターンでは、クラス V の呼び出し元は仮想化された戻り値を受け取ります。基本的に、これは、仮想化されたメソッドがどのように (どこから) 呼び出されるかに関係なく、クラス V の動作をグローバルに変更します。
このタイプの仮想化を設定するには、完全修飾クラス名と、仮想化するメソッド名 (または記録モードの場合は記録する) メソッドの名前を指定します。仮想化モードでは、これらの指定されたメソッドの戻り値が変更されます。
このパターンでは、特定のメソッドが特定の場所からどのように呼び出されるかを仮想化します。ここでは、次の情報を渡します。
このパターンは、リモート EJB メソッド呼び出しの仮想化に特に有用です。呼び出し元クラスは通常、コントローラー オブジェクトです。コントローラー オブジェクト内では、宣言されたリモート インターフェイス タイプを使用してリモート EJB 呼び出しが行われます。以下に、このパターンを使用してリモート EJB 呼び出しを仮想化する方法を図で示します。
アプリケーションの java スタートアップ実行ファイルに次の JVM 引数を追加します (各 –D
引数の前にスペースを入れて 1 行で指定します)。
-javaagent:"C:/PathTo/ParasoftJavaVirtAgent.jar" -Dparasoft.virtualize.config="C:/Path/AgentConfig.xml" -Dparasoft.virtualize.log.config="C:/Path/logging.properties" |
アプリケーションが ClassNotFoundExceptions
をログに記録する場合は、次のフラグを追加してみてください。
-Xbootclasspath/a:"C:/Path/ParasoftJavaVirtAgent.jar;C:/Path/xstream-1.4.2.jar" |
Oracle WebLogic
上記の引数を追加するには、setDomainEnv.sh サーバー起動スクリプトを編集します。Xbootclasspath
を設定する必要はありません。
Apache Karaf/ServiceMix
Xbootclasspath
の設定が必要です。また、親クラスローダーにデリゲートされる Java パッケージも調整する必要があります。これにより、OSGi バンドルが Parasoft Agent ランタイム ライブラリに対して実行時に可視性を持つようになります。Apache Service Mix では、/etc/
ディレクトリの custom.properties ファイル内の org.osgi.framework.bootdelegation
プロパティの末尾に次の内容 (すべて 1 行) を追加することで、これを実現できます。
,com.parasoft.virtualize.java.agent.runtime,com.parasoft.virtualize.java.agent.runtime.*
,com.thoughtworks.xstream.*
IBM WebSphere Application Server
サーバー起動ファイルを編集する必要はありません。IBM Integrated Solutions Console for WAS を使用してエージェントを構成できます。[Application servers] > [server name] > [Process definition] > [Java Virtual Machine] に移動します。[Generic JVM Arguments] フィールドに、エージェント設定引数を入力します。例 (すべて 1 行で、各 -D
引数はスペースで区切ります):
-javaagent:C:/Parasoft/ParasoftJavaVirtAgent.jar -Dparasoft.virtualize.config=C:/Parasoft/PlantsByWebSphere.xml -Dparasoft.virtualize.log.config=C:/Parasoft/logging.properties |
-javaagent
パスが誤って入力されているか、ファイルが削除されているためサーバーの起動に失敗した場合は、[was.install.root]/profiles/[profile name]/config/cells/[cellname]/nodes/[node name]/servers/server1/
ディレクトリの server.xml ファイルを編集し、不正な引数を削除することで修正できます (ParasoftJavaVirtAgent.jar または指定したその他の引数パラメーターの出現箇所を検索します)。
WebSphere Application Server は、エージェントのログ記録構成を上書きし、常に出力を独自のログ記録フレームワークにリダイレクトします。IBM Console の [Logging and Tracing] > [server1] > [Change log detail levels] で、必要なログ記録レベルを設定できます。com.parasoft.virtualize.*
コンポーネントを探し、必要に応じてログ記録レベルを調整します。Parasoft Java Virtualization エージェントのログは、[was.install.root]/profiles/[profilename]/logs/[server name]/native_stdout.log
にあります。
IBM WebSphere Community Edition
Xbootclasspath
の設定が必要です。
JavaVirtualization.pva (zip アーカイブに含まれる) を Virtualize サーバーにデプロイし、エージェントの Virtualize サーバー URL がそのアセットを指すように設定します。このアセットは、次の操作を実行できるようになります。
以下の設定をエージェント上で構成する必要があります。
-Dparasoft.virtualize.remote.mode=true
true の場合、実行時にモードの切り替えが有効になります。この切り替えは、JavaVirtualization.pva で使用されている環境を更新することによって行われます。PVA をチェックして、適切な環境をアクティブに設定することでモードを制御できることを確認します。
logging.properties
Java ユーティリティ ログをサーバーに送信できるようにするには、これを com.parasoft.virtualize.java.agent.log.ServerHandler
に設定します。
AgentConfig.xml
エージェントが記録されたトラフィックを Virtualize サーバーに送信するには、AgentConfig.xml の recorderType
を HTTP_TRAFFIC_SERVER
に設定します (AgentConfig.xml の詳細については、次のセクションを参照してください)。
エージェントには、logging.properties ファイルが含まれています。このファイルを編集することで、エージェントによって作成されるローカル ログ ファイルの詳細度と場所を設定できます。エージェントは Java の標準組み込みロギングフレームワークを使用するため、そのフレームワークに適用されるプロパティと設定がエージェントにも適用されます (http://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html を参照)。一般に、次の 2 つのプロパティを考慮する必要があります。
com.parasoft.virtualize.java.agent.level=ALL|FINEST|FINER|FINE|INFO|WARNING|SEVERE
java.util.logging.FileHandler.pattern=C:\path/parasoft_java_agent_log.%g.txt
一部のアプリケーション サーバー プラットフォームでは、エージェントの logging.properties ファイルで設定されたログ出力先とレベルが上書きされることに注意してください。このような場合は、アプリケーション サーバー独自のフレームワークを使用してログ出力レベルを調整できます。特定のサーバー構成に関する注意事項については、「エージェントを使用するために Java アプリケーションを構成する」セクション (上記) を参照してください。
デフォルトでは、アプリケーション JVM がエージェントを使用して正常に起動すると、次のログ ステートメントが表示されます。
[Parasoft Java Virtualization Agent: INFO {timestamp}] class file transformer initialized using configuration file {file path}
アプリケーションがロードされてインストルメントされると、次のログ ステートメントの 1 つ以上がデフォルトのログ出力レベル (info) で表示されます。
[Parasoft Java Virtualization Agent: INFO {timestamp}] transforming {class name provided in the agent configuration XML}
AgentConfig.xml は、エージェント固有の XML 記述子です。エージェントに、どのクラスとメソッドを適用するか、どのモード (仮想化、記録など) を適用するかを伝えます。以下に設定ファイルの例を示します。
<ParasoftJavaVirtAgent> <virtualizeServer> <url>http://localhost:9080/ParaBankJavaLoanRequest</url> </virtualizeServer> <recorderType>HTTP_TRAFFIC_FILE</recorderType> <localRecordingFilePath>/Users/jsmith/JavaVirt/JavaRecording.txt</localRecordingFilePath> <callVirtualizationClasses> <callVirtualizationClass> <callingMethods> <method> <className>com.parasoft.parabank.domain.logic.impl.BankManagerImpl</className> <methodName>requestLoan</methodName> <argumentTypes> <string></string> </argumentTypes> <mode>INACTIVE</mode> </method> </callingMethods> <virtualizedMethods> <method> <className>com.parasoft.parabank.domain.logic.LoanProvider</className> <methodName>requestLoan</methodName> <argumentTypes> <string></string> </argumentTypes> <mode>INACTIVE</mode> </method> </virtualizedMethods> </callVirtualizationClass> </callVirtualizationClasses> <methodVirtualizationClasses> <method> <className>com.parasoft.parabank.domain.logic.impl.ConfigurableLoanProvider</className> <methodName>requestLoan</methodName> <argumentTypes> <string></string> </argumentTypes> <mode>RECORD</mode> </method></methodVirtualizationClasses> </ParasoftJavaVirtAgent> |
エージェント構成セクション
<virtualizeServer> <url>http://virtServerHost:9080/ParaBankJavaLoanRequest</url> </virtualizeServer> |
このセクションは、VIRTUALIZE モードのメソッドに適用されます。Virtualize サーバーへの HTTP パスと、記録から事前に生成された PVA を示します。
<localRecordingFilePath>/Users/jsmith/JavaVirt/JavaRecording.txt</localRecordingFilePath> |
このセクションは、Java メソッド呼び出しを保存する場所への絶対パスです (RECORD モードの場合)。デフォルトでは、新しいトラフィックが既存のトラフィック ファイルに追加されることに注意してください。したがって、同じ呼び出しを複数回記録すると、ファイル内のデータが重複する可能性があります。
<callVirtualizationClasses> </callVirtualizationClasses> |
このセクションには、1 つ以上の <callVirtualizationClass>
要素を含めることができます。呼び出し仮想化パターンのクラスとメソッドを指定します。なお、以下を使用してメソッドの完全修飾シグネチャを指定することは
<argumentTypes><string>argTypesNYI</string></argumentTypes> |
現時点ではサポートされていません。
<callingMethods>
要素は、どのメソッドから呼び出しの仮想化を適用するかを指定します。<virtualizedMethods>
要素で指定されたメソッドは、実際に仮想化されるメソッドです。
<mode> </mode> |
このセクションは、指定されたメソッドに対して、3 つの値 (INACTIVE、RECORD、VIRTUALIZE) のいずれかを取ることができます。INACTIVE は、エージェントに、元のメソッドの起動を記録したり、仮想化したり、動作を変更したりせずに、元のメソッドを呼び出させるよう指示します。
<methodVirtualizationClasses> |
このセクションでは、クラス メソッド仮想化パターンを適用するクラスとそのメソッドのリストを指定します。
この例からわかるように、2 つの仮想化パターンを混在させ、指定されたクラス/メソッドごとにさまざまなモードを混在させることができます。
アプリケーションが目的のシナリオで実行され、一部のクラス/メソッドが RECORD モードで設定されたら、記録されたファイルをテスト対象アプリケーションから取得し、トラフィックから Virtualize の PVA 作成ウィザードに渡すことができます。
トラフィックから PVA を作成するときは、HTTP オプションを選択します (エージェントが生成した Java 記録ファイルは、オブジェクトが XML 表現に変換された HTTP トラフィック ファイルとしてフォーマットされます)。
記録された各メソッドには XML ファイル内に一意の XML ルート要素があるため、一意のメソッドごとにレスポンダーが作成されます。各レスポンダーは、記録されたさまざまな入力引数/戻り値を反映するために、"複数レスポンス" モードで作成されます。
PVA がデプロイされたら、AgentConfig.xml を VIRTUALIZE モードに切り替え、url 要素を PVA デプロイメントの HTTP エンドポイントに指定します。エージェントにより、アプリケーションの JVM は、実際のメソッドを呼び出す代わりに、指定されたメソッド呼び出しをリモートで Virtualize に (HTTP 経由で) リダイレクトします。Virtualize で設定されている戻りオブジェクトが、これらのメソッドの戻り値として使用されます。
Java 仮想化エージェントは、アプリケーション内の別のサブコンポーネントで何らかの機能を実行したり、リモートで何らかの依存関係を呼び出したりするステートレス メソッド呼び出しを記録および仮想化するのに特に有用です。
このリリースのエージェントを使用する際に留意すべき制約の一部を次に示します。
まず、ConfigurableLoanProvider
クラスの動作を仮想化して、クラス メソッドの仮想化パターンを試してみましょう。このクラスは、ParaBank でどのローン プロバイダーが設定されているかに関係なく、ローンを申請するために呼び出されます。
localRecordingFilePath
を、ご使用の環境で記録ファイルを保存する場所に変更します)。ParaBank Run Configuration を開き、VM 引数を追加します (すべて 1 行で、各 –D
引数をスペースで区切ります)。
-javaagent:"C:\PATH\ParasoftJavaVirtAgent.jar" -Dparasoft.virtualize.config="C:\PATH\AgentConfig.xml" -Dparasoft.virtualize.log.config="C:\PATH\logging.properties" |
RecordingFilePath
で指定した場所にファイルが作成されたことを確認します。ParaBank をシャットダウンします。
AgentConfig.xml にあるものと一致するデプロイメント エンドポイントを指定します。ここでは次を使用します:
/ParaBankJavaLoanRequest
<virtualizeServer> <url>http://localhost:9080/ParaBankJavaLoanRequest</url> </virtualizeServer> |
<loanProviderName>Parasoft Virtualize</loanProviderName>
AgentConfig.xml のモードを VIRTUALIZE に切り替えます。
<methodVirtualizationClasses> <method> <className>com.parasoft.parabank.domain.logic.impl.ConfigurableLoanProvider</className> <methodName>requestLoan</methodName> <argumentTypes> <string></string> </argumentTypes> <mode>VIRTUALIZE</mode> </method> </methodVirtualizationClasses> |
次に、呼び出しの仮想化パターンを試してみましょう。この演習の目標は、BankManagerImpl.java
のメソッド requestLoan()
の次の呼び出し行を仮想化することです。
LoanResponse loanResponse = loanProvider.requestLoan(loanRequest); |
そのためには、エージェントに次のことを指示する必要があります。
BankManagerImpl
は呼び出しクラスです。requestLoan()
メソッドが呼び出しメソッドです。LoanProvider
なので、これが仮想化クラスであり、ここで仮想化したいメソッド呼び出しは requestLoan()
です。(この例で呼び出しメソッド名と仮想化メソッド名が同じなのは単なる偶然です。)呼び出し仮想化パターンを試すには、次の操作を行います。
クラス メソッドの仮想化を INACTIVE に設定します。
<methodVirtualizationClasses> <method> <className>com.parasoft.parabank.domain.logic.impl.ConfigurableLoanProvider</className> <methodName>requestLoan</methodName> <argumentTypes> <string></string> </argumentTypes> <mode>INACTIVE</mode> </method> </methodVirtualizationClasses> |
呼び出し Virtualization クラス モードを RECORD に設定します。
<callVirtualizationClass> <callingMethods> <method> <className>com.parasoft.parabank.domain.logic.impl.BankManagerImpl</className> <methodName>requestLoan</methodName> <argumentTypes> <string></string> </argumentTypes> <mode>RECORD</mode> </method> </callingMethods> <virtualizedMethods> <method> <className>com.parasoft.parabank.domain.logic.LoanProvider</className> <methodName>requestLoan</methodName> <argumentTypes> <string></string> </argumentTypes> <mode>RECORD</mode> </method> </virtualizedMethods> </callVirtualizationClass> |