Указание стратегии завершения с помощью пользовательского кода

Для управления прекращением работы элемента приема сокета можно создать пользовательский класс Java™. Такой подход обеспечивает наиболее высокий уровень гибкости, однако требует создания собственного класса Java с помощью API расширения Rational Performance Tester.

Прежде чем начать

Стратегия завершения задает способ прекращения работы элемента приема и позволяет возобновить выполнение теста. Доступно несколько стандартных стратегий завершения, например после приема заданного числа байт или при обнаружении конкретной строки. Однако в ряде случаев может потребоваться создать сложное условие. Это можно сделать путем делегирования решения пользовательскому коду.

Процедура

Для создания нового класса пользовательского кода выполните следующие действия:

  1. В редакторе тестов выберите элемент приема сокета.
  2. В разделе Стратегия окончания выберите С помощью пользовательской процедуры, затем выберите Создать код. При этом создается шаблон класса Java, соответствующий требованиям API расширения Rational Performance Tester. Класс Java создается в папке src текущего проекта.
  3. Создайте пользовательский код путем расширения класса. Дополнительная информация о расширении возможностей Rational Performance Tester с помощью кода Java приведена в разделе Расширение тестов с помощью пользовательского кода.
  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.
 *  Для просмотра javadoc ITestExecutionServices выберите 'Оглавление справки' в меню Справка, затем выберите
 * 'Расширение функциональности 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 байта задают число секунд, прошедших с 1 января 1900 года
		// Тест подключается к серверу TIME через порт 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 и 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 += "-> No difference";
		} else {
			message += "-> Difference (seconds): " + diff;
		}
		return message;
	}

}

Комментарии