Utilisation de code personnalisé pour spécifier une règle de fin

Vous pouvez rédiger une classe Java™ personnalisée pour spécifier quand un élément de réception de connexion socket ne doit plus recevoir de données. Cette approche est celle qui offre le plus de souplesse, mais elle nécessite que vous composiez votre propre classe Java à l'aide de l'API d'extension de Rational Performance Tester.

Avant de commencer

La règle de fin spécifie comment l'élément de réception arrête de recevoir des données et permet au test de reprendre son exécution. Pour pouvez choisir entre plusieurs règles de fin prédéfinies, par exemple après qu'un certain nombre d'octets ait été reçu ou lorsqu'une chaîne spécifique est détectée. Cependant, une condition complexe doit être définie dans certains cas. Ceci peut être réalisé en déléguant la décision au code personnalisé.

Procédure

Pour créer une nouvelle classe de code personnalisé, procédez comme suit :

  1. Dans l'éditeur de test, sélectionnez un élément de réception de connexion socket.
  2. Dans la section Règle de fin, sélectionnez Délégué au code personnalisé et cliquez sur Générer le code. Ceci crée un modèle de classe Java qui suit l'API d'extension de Rational Performance Tester. La classe Java est créée dans le dossier src du projet en cours.
  3. Composez le code personnalisé en étendant la classe à partir de laquelle il est généré. Reportez-vous à la rubrique Extension de l'exécution d'un test avec du code personnalisé pour plus d'informations sur l'extension de Rational Performance Tester à l'aide de code Java.
  4. Sauvegardez le code personnalisé et le test. Vous pouvez cliquer sur Afficher le code pour éditer la classe Java ultérieurement.

Exemple

L'exemple suivant contient une classe personnalisée illustrant comment configurer une règle de fin personnalisée pour le protocole Time d'Internet :
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;

/**
 *  Règle de réception personnalisée CustomReceive_TimeReceiver.
 *  Pour la javadoc de ITestExecutionServices, sélectionnez 'table des matières de l'aide dans le menu d'aide et sélectionnez
 *  'Extension de la fonctionnalité Rational Tester ' -> 'Extension de l'exécution d'un test avec du code personnalisé'
 */
public class CustomReceive_TimeReceiver implements ISckCustomReceivePolicy {

	// static {
	//	 Les blocs statiques sont appelés une fois par exécution et permettent par exemple une liaison
	//	 à une bibliothèque dynamique externe
	// }

	ISckReceiveAction receiveAction;
	ITestExecutionServices testExecutionServices;

	public CustomReceive_TimeReceiver() {
		// Le constructeur est appelé lors de la création du test et non pas à l'exécution de
		// l'action de réception personnalisée
	}

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

	public boolean onRead(int readByte) {
		// Protocole TIME (RFC 868) : un serveur connecté renvoie 4 octets et referme la connexion
		// Ces 4 octets sont le nombre de secondes depuis le 1/1/1900
		// Le test est simplement composé d'une connexion à un serveur TIME sur le port 37
		// (les serveurs publics sont listés ici : Le nom d'hôte du serveur Time est obtenu de http://tf.nist.gov/service/time-servers.html),
		// Puis réception déléguée à cette classe de code personnalisé,
		// Puis fermeture
		try {
			if (readByte == EndOfStream) {
				/* En cas de réussite : */
				receiveAction.receiveSuccess();
				String message = extractAndCheckTime(receiveAction.getConnectionHolder().getFinallyReceivedBytes());
				/* Un message est ajouté au Journal de test juste après cette action de réception : */
				testExecutionServices.getTestLogManager().reportMessage(message);
				return true;
			}
		} catch (Throwable t) {
			/* En cas d'exception : */
			receiveAction.handleException(t);
			return true;
		}
		if (receiveAction.getConnectionHolder().getCurrentlyReceivedBytesCount() > 4) {
			/* Condition inattendue : */
			receiveAction.handleException(new Exception("Time protocol server returned more than 4 bytes"));
			return true;
		}
		/* D'autres octets sont requis pour compléter cette réception */
		return false;
	}

	private String extractAndCheckTime(byte[] bytes) {
		// Ordre réseau, par exemple big endian
		long remoteTime = ((((long)bytes[0]) & 0x00000000000000ff) << 24) +
						  ((((long)bytes[1]) & 0x00000000000000ff) << 16) +
						  ((((long)bytes[2]) & 0x00000000000000ff) << 8) +
						   (((long)bytes[3]) & 0x00000000000000ff);
		// 1900 à 1970: différence de référence, voir la RFC 868 et la javadoc java.util.Date
		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 += "-> pas de différence";
		} else {
			message += "-> Différence (secondes): " + diff;
		}
		return message;
	}

}

Retour d'informations