Utilizzo del codice personalizzato per specificare una politica di fine

È possibile scrivere una classe Java™ personalizzata per specificare quando un elemento di ricezione socket interrompe la ricezione. In questo modo si fornisce una maggiore flessibilità, ma si richiede di scrivere la classe Java utilizzando l'API di estensione di Rational Performance Tester.

Prima di iniziare

La politica di fine specifica come l'elemento di ricezione arresta la ricezione e consente il ripristino del test. Ci sono diverse politiche di fine predefinite da cui è possibile scegliere, ad esempio dopo che è stato ricevuto un determinato numero di byte o quando viene rilevata una stringa specifica. Tuttavia, in alcuni casi, è necessario definire una condizione complessa. Questo può essere fatto delegando la decisione al codice personalizzato.

Procedura

Per creare una nuova classe del codice personalizzato:

  1. Nell'editor di test, selezionare un elemento di ricezione del socket.
  2. Nella sezione Politica di fine, selezionare Delegato al codice personalizzato e fare clic su Genera codice. In questo modo si crea un modello di classe Java che segue l'API di estensione Rational Performance Tester. La classe Java viene creata nella cartella src del progetto corrente.
  3. Scrivere il codice personalizzato estendendo la classe di generazione. Per ulteriori informazioni sull'estensione di Rational Performance Tester con il codice Java, consultare Estensione esecuzione test con il codice personalizzato.
  4. Salvare il codice personalizzato ed il test. È possibile fare clic su Visualizza codice per modificare la classe Java successivamente.

Esempio

Il seguente esempio è una classe personalizzata di esempio che dimostra come configurare una politica di fine personalizzata per il protocollo orario di 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;

/**
 *  Politica di ricezione personalizzata CustomReceive_TimeReceiver.
 *  Per javadoc di ITestExecutionServices, selezionare 'Help Contents' nel menu Guida e selezionare
 *  'Extending Rational Performance Tester functionality' -> 'Extending test execution with custom code'
 */
public class CustomReceive_TimeReceiver implements ISckCustomReceivePolicy {

	// statico {
	//	 i blocchi statici sono chiamati una volta su ogni esecuzione e consentono ad esempio di collegare
	//	 ad una libreria esterna dinamica
	// }

	ISckReceiveAction receiveAction;
	ITestExecutionServices testExecutionServices;

	public CustomReceive_TimeReceiver() {
		// Il costruttore viene chiamato durante la creazione del test, non al momento dell'esecuzione della
		// azione di ricezione personalizzata
	}

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

	public boolean onRead(int readByte) {
		// Protocollo TIME (RFC 868): un server connesso restituisce 4 byte e chiude la connessione
		// Questi 4 byte sono il numero di secondi da 1900/1/1
		// Il test è semplicemente fatto di una connessione ad un server TIME sulla porta 37
		// (i server pubblici sono di seguito elencati: Ottenuto nome host del server orario da http://tf.nist.gov/service/time-servers.html),
		// Quindi un delegato di ricezione a questa classe del codice personalizzato,
		// Quindi uno chiuso
		try {
			if (readByte == EndOfStream) {
				/* In caso di riuscita: */
				receiveAction.receiveSuccess();
				String message = extractAndCheckTime(receiveAction.getConnectionHolder().getFinallyReceivedBytes());
				/* Viene allegato un messaggio nel log di test dopo questa azione di ricezione: */
				testExecutionServices.getTestLogManager().reportMessage(message);
				return true;
			}
		} catch (Throwable t) {
			/* In caso di eccezione: */
			receiveAction.handleException(t);
			return true;
		}
		if (receiveAction.getConnectionHolder().getCurrentlyReceivedBytesCount() > 4) {
			/* Condizione non prevista: */
			receiveAction.handleException(new Exception("Time protocol server returned more than 4 bytes"));
			return true;
		}
		/* Sono necessari altri byte per completare questa ricezione */
		return false;
	}

	private String extractAndCheckTime(byte[] bytes) {
		// Questo è un ordine di rete, ad esempio big endian
		long remoteTime = ((((long)bytes[0]) & 0x00000000000000ff) << 24) +
						  ((((long)bytes[1]) & 0x00000000000000ff) << 16) +
						  ((((long)bytes[2]) & 0x00000000000000ff) << 8) +
						   (((long)bytes[3]) & 0x00000000000000ff);
		// da 1900 a 1970: una differenza di riferimento, vedere RFC 868 e 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