Angepassten Code zur Angabe einer Enderichtlinie verwenden

Sie können eine benutzerdefinierte Java™-Klasse erstellen, um so anzugeben, wann ein Socket-Receive-Element das Empfangen stoppen soll. Diese Einstellung ermöglicht die größtmögliche Flexibilität, macht es aber erforderlich, dass Sie eine angepasste Java-Klasse entsprechend der Rational Performance Tester Extension-API codieren.

Vorbereitende Schritte

In der Enderichtlinie wird festgelegt, wie das Receive-Element das Empfangen stoppen und die Wiederaufnahme des Tests ermöglichen soll. Sie können aus einer ganzen Reihe vordefinierter Enderichtlinien auswählen. Eine Richtlinie beispielsweise besagt, dass das Ende nach dem Empfang einer bestimmten Anzahl an Byte oder bei Feststellung einer bestimmten Zeichenfolge erfolgen soll. In einigen Fällen allerdings muss eine komplexe Bedingung definiert werden. Dazu können Sie die erforderliche Entscheidung an entsprechenden angepassten Code delegieren:

Vorgehensweise

So erstellen Sie eine neue Klasse von angepasstem Code:

  1. Wählen Sie im Testeditor ein Socket-Receive-Element aus.
  2. Wählen Sie im Bereich Enderichtlinie den Eintrag An angepassten Code delegiert aus und klicken Sie auf Code generieren. Damit erstellen Sie eine Schablone für eine neue Java-Klasse, die sich an der Rational Performance Tester Extension-API orientiert. Die Java-Klasse wird im Ordner src des aktuellen Projekts erstellt.
  3. Schreiben Sie den angepassten Code, indem Sie die Generierungsklasse erweitern. Weitere Informationen zum Erweitern von Rational Performance Tester mit Java-Code finden Sie unter Testausführung mit angepasstem Code erweitern.
  4. Sichern Sie den angepassten Code und den Test. Sie können auf Code anzeigen klicken, um die Java-Klasse bei Bedarf später zu bearbeiten.

Beispiel

Das folgende Beispiel zeigt das Muster einer benutzerdefinierten Klasse, in dem dargestellt wird, wie eine Enderichtlinie für das Internet-ZeitProtokoll zu konfigurieren ist:
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;

/**
 *  Custom receive policy CustomReceive_TimeReceiver.
 *  For javadoc of ITestExecutionServices, select 'Help Contents' in the Help menu and select
 *  'Extending Rational Performance Tester functionality' -> 'Extending test execution with custom code'
 */
public class CustomReceive_TimeReceiver implements ISckCustomReceivePolicy {

	// static {
	//	 static blocks are called once on each run and allow for example to bind
	//	 to an external dynamic library
	// }

	ISckReceiveAction receiveAction;
	ITestExecutionServices testExecutionServices;

	public CustomReceive_TimeReceiver() {
		// The constructor is called during the test creation, not at the time of the execution of
		// the customized receive action
	}

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

	public boolean onRead(int readByte) {
		// TIME protocol (RFC 868): a connected server returns 4 bytes and closes the connection
		// Those 4 bytes are the number of seconds since 1900/1/1
		// The test is simply made of a connection to one TIME server on port 37
		// (public servers are listed here: Got time server host name from http://tf.nist.gov/service/time-servers.html),
		// Then a receive delegated to this custom code class,
		// Then a close
		try {
			if (readByte == EndOfStream) {
				/* In case of success: */
				receiveAction.receiveSuccess();
				String message = extractAndCheckTime(receiveAction.getConnectionHolder().getFinallyReceivedBytes());
				/* A message is appended in the Test Log just after this receive action: */
				testExecutionServices.getTestLogManager().reportMessage(message);
				return true;
			}
		} catch (Throwable t) {
			/* In case of exception: */
			receiveAction.handleException(t);
			return true;
		}
		if (receiveAction.getConnectionHolder().getCurrentlyReceivedBytesCount() > 4) {
			/* Unexpected condition: */
			receiveAction.handleException(new Exception("Time protocol server returned more than 4 bytes"));
			return true;
		}
		/* We need further bytes to complete this receive */
		return false;
	}

	private String extractAndCheckTime(byte[] bytes) {
		// This is network order, i.e. big endian
		long remoteTime = ((((long)bytes[0]) & 0x00000000000000ff) << 24) +
						  ((((long)bytes[1]) & 0x00000000000000ff) << 16) +
						  ((((long)bytes[2]) & 0x00000000000000ff) << 8) +
						   (((long)bytes[3]) & 0x00000000000000ff);
		// 1900 to 1970: a difference of reference, see RFC 868 and 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;
	}

}

Feedback