Określanie strategii zakończenia przy użyciu kodu niestandardowego

Przy użyciu niestandardowej klasy Java™ można określić, kiedy element odbierania gniazda zatrzymuje odbieranie. Zapewnia to większą elastyczność, ale wymaga napisania własnej klasy Java przy użyciu interfejsu API rozszerzenia produktu Rational Performance Tester.

Zanim rozpoczniesz

Strategia zakończenia określa, w jaki sposób element odbierania zatrzymuje odbiór i umożliwia wznowienie testu. Do wyboru jest kilka predefiniowanych strategii zakończenia, na przykład po odebraniu pewniej liczby bajtów lub wykryciu konkretnego łańcucha. Jednak w niektórych przypadkach należy zdefiniować warunek złożony. Można to zrobić przez delegowanie decyzji do kodu niestandardowego.

Procedura

Aby utworzyć nową klasę kodu niestandardowego:

  1. W edytorze testów wybierz element odbierania gniazda.
  2. W sekcji Strategia zakończenia wybierz opcję Delegowane do kodu niestandardowego i kliknij przycisk Generuj kod. Zostanie utworzony szablon klasy Java zgodny z interfejsem API rozszerzenia produktu Rational Performance Tester. Klasa Java jest tworzona w folderze src bieżącego projektu.
  3. Napisz kod niestandardowy, rozszerzając klasę generowania. Więcej informacji o rozszerzaniu produktu Rational Performance Tester przy użyciu kodu Java zawiera temat Rozszerzanie wykonania testu za pomocą kodu niestandardowego.
  4. Zapisz kod niestandardowy i test. Aby później edytować klasę Java, można kliknąć opcję Wyświetl kod.

Przykład

Poniżej przedstawiono przykładową klasę niestandardową, która demonstruje konfigurowanie niestandardowej strategii zakończenia dla internetowego protokołu czasu:
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;

/**
 * Niestandardowa strategia odbierania CustomReceive_TimeReceiver.
 * W przypadku dokumentacji Javadoc interfejsu ITestExecutionServices wybierz w menu pomocy opcję Spis treści pomocy, a następnie wybierz pozycję
 * Rozszerzanie funkcjonalności produktu Rational Performance Tester -> Rozszerzanie wykonania testu za pomocą kodu niestandardowego
 */
public class CustomReceive_TimeReceiver implements ISckCustomReceivePolicy {

	// statyczne {
	//	 Bloki statyczne są wywoływane jednokrotnie przy każdym uruchomieniu i umożliwiają na przykład powiązanie
	//	 z zewnętrzną biblioteką dynamiczną
	// }

	ISckReceiveAction receiveAction;
	ITestExecutionServices testExecutionServices;

	public CustomReceive_TimeReceiver() {
		// Konstruktor jest wywoływany podczas tworzenia testu, a nie w czasie wykonywania
		// dostosowanego działania odbierania
	}

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

	public boolean onRead(int readByte) {
		// Protokół TIME (RFC 868): połączony serwer zwraca 4 bajty i zamyka połączenie
		// Te 4 bajty oznaczają liczbę sekund od 1 stycznia 1900
		// Test polega na połączeniu do jednego serwera czasu na porcie 37
		// (lista serwerów publicznych: nazwę hosta serwera można znaleźć na stronie http://tf.nist.gov/service/time-servers.html).
		// Następnie jest odbierane delegowanie do tej klasy kodu niestandardowego,
		// a później następuje zamknięcie.
		try {
			if (readByte == EndOfStream) {
				/* W przypadku powodzenia: */
				receiveAction.receiveSuccess();
				String message = extractAndCheckTime(receiveAction.getConnectionHolder().getFinallyReceivedBytes());
				/* Komunikat jest dopisywany do dziennika testu po działaniu odbioru: */
				testExecutionServices.getTestLogManager().reportMessage(message);
				return true;
			}
		} catch (Throwable t) {
				/* W przypadku wyjątku: */
			receiveAction.handleException(t);
			return true;
		}
		if (receiveAction.getConnectionHolder().getCurrentlyReceivedBytesCount() > 4) {
			/* Nieoczekiwany warunek: */
			receiveAction.handleException(new Exception("Time protocol server returned more than 4 bytes"));
			return true;
		}
		/* Do zakończenia odbierania są potrzebne kolejne bajty */
		return false;
	}

	private String extractAndCheckTime(byte[] bytes) {
		// Kolejność w sieci, na przykład układ big endian
		long remoteTime = ((((long)bytes[0]) & 0x00000000000000ff) << 24) +
						  ((((long)bytes[1]) & 0x00000000000000ff) << 16) +
						  ((((long)bytes[2]) & 0x00000000000000ff) << 8) +
						   (((long)bytes[3]) & 0x00000000000000ff);
		// Od 1900 do 1970: różnica odwołania, patrz RFC 868 i dokumentacja Javadoc klasy 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 += "-> No difference";
		} else {
			message += "-> Difference (seconds): " + diff;
		}
		return message;
	}

}

Opinia