カスタム・コードを使用した終了ポリシーの指定

カスタム Java™ クラスを作成して、ソケット受信エレメントが受信を停止するタイミングを指定できます。 これにより最高の柔軟性が得られますが、Rational® Performance Tester 拡張 API を使用して独自の Java クラスを作成する必要があります。

始める前に

終了ポリシーは、受信エレメントが受信を停止し、テストの 再開を可能にする方法を指定します。 いくつかのあらかじめ定義済みの終了ポリシーがあり、 ユーザーはそこから選択できます。例えば特定のバイト数の受信後や、特定のストリングの検出などです。 しかし、複合条件を定義しなければならない場合も あります。カスタム・コードに決定を委任することによって、これが可能 になります。

手順

新規のカスタム・コード・クラスを作成するには、以下のようにします。

  1. テスト・エディター内で、ソケット受信エレメントを選択します。
  2. 「終了ポリシー」セクションで、「カスタム・コードへの委任」を選択し、「コードの生成」をクリックします。 これによって、Rational Performance Tester 拡張 API に従った Java クラス・テンプレートが作成されます。 Java クラスは、現在のプロジェクトの src フォルダーに作成されます。
  3. 生成中クラスを拡張して、カスタム・コードを作成します。 Java コードによる Rational Performance Tester の拡張について詳しくは、『カスタム・コードによるテストの実行の拡張』を参照してください。
  4. カスタム・コードおよびテストを保存します。 「コードの表示」をクリックすることで、後から Java クラスを編集することができます。

以下の例は、インターネット時刻プロトコルのカスタム終了ポリシーの構成方法を説明した、カスタム・クラスのサンプルです。
package test;

import java.text.DateFormat;
import java.util.Date;
import java.util.TimeZone;

import com.ibm.rational.test.lt.execution.socket.custom.ISckCustomReceivePolicy;
import com.ibm.rational.test.lt.execution.socket.custom.ISckReceiveAction;
import com.ibm.rational.test.lt.kernel.services.ITestExecutionServices;

/**
 *  カスタム受信ポリシー CustomReceive_TimeReceiver。
 *  ITestExecutionServices の javadoc について、ヘルプ・メニューで「ヘルプ目次」を選択し、
 *  「Rational Performance Tester 機能の拡張」->「カスタム・コードによるテストの実行の拡張」を選択します
 */
public class CustomReceive_TimeReceiver implements ISckCustomReceivePolicy {

	// static {
	//	 静的ブロックが実行ごとに一度呼び出され、例えば、外部の動的ライブラリーに
	//	 バインドできます
	// }

	ISckReceiveAction receiveAction;
	ITestExecutionServices testExecutionServices;

	public CustomReceive_TimeReceiver() {
		// コンストラクターはテスト作成中に呼び出されます。カスタマイズされた
		// 受信アクションの実行時ではありません
	}

	public void setup(ITestExecutionServices tesRef,
			ISckReceiveAction receiveActionRef) {
		testExecutionServices = tesRef;
		receiveAction = receiveActionRef;
	}

	public boolean onRead(int readByte) {
		// TIME プロトコル (RFC 868): 接続されたサーバーは 4 バイト戻して接続をクローズします
		// この 4 バイトは 1900/1/1 以後の秒数です
		// テストは単純に 1 台のタイム・サーバーとポート 37 での接続で構成されます
		// (パブリック・サーバーをリストします。http://tf.nist.gov/service/time-servers.html からタイム・サーバーのホスト名を取得済みです)、
		// 次に受信がこのカスタム・コード・クラスに委任され、
		// クローズします
		try {
			if (readByte == EndOfStream) {
				/* 成功の場合: */
				receiveAction.receiveSuccess();
				String message = extractAndCheckTime(receiveAction.getConnectionHolder().getFinallyReceivedBytes());
				/* この受信アクションの直後にメッセージがテスト・ログに追加されます */
				testExecutionServices.getTestLogManager().reportMessage(message);
				return true;
			}
		} catch (Throwable t) {
			/* 例外の場合: */
			receiveAction.handleException(t);
			return true;
		}
		if (receiveAction.getConnectionHolder().getCurrentlyReceivedBytesCount() > 4) {
			/* 予期しない条件: */
			receiveAction.handleException(new Exception("Time protocol server returned more than 4 bytes"));
			return true;
		}
		/* この受信を完了するにはさらに領域 (バイト数) が必要です */
		return false;
	}

	private String extractAndCheckTime(byte[] bytes) {
		// これはネットワークの順序、つまりビッグ・エンディアンです
		long remoteTime = ((((long)bytes[0]) & 0x00000000000000ff) << 24) +
						  ((((long)bytes[1]) & 0x00000000000000ff) << 16) +
						  ((((long)bytes[2]) & 0x00000000000000ff) << 8) +
						   (((long)bytes[3]) & 0x00000000000000ff);
		// 1900 から 1970: 参照の差異。RFC 868 および java.util.Date javadoc を参照してください
		remoteTime -= 2208988800L;
		Date remoteDate = new Date(remoteTime*1000);
		Date localDate = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance();
		dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
		String message = "Remote time: " + dateFormat.format(remoteDate) + " GMT (TIME server is " +
											receiveAction.getConnectionHolder().getHostName() + ", port 37)¥n" +
						 "Local time:  " + dateFormat.format(localDate) + " GMT¥n";
		long diff = localDate.getTime()/1000 - remoteTime;
		if (diff == 0) {
			message += "-> No difference";
		} else {
			message += "-> Difference (seconds): " + diff;
		}
		return message;
	}

}

フィードバック