Using custom code to specify an end policy
You can write a custom Java™ class to specify when a socket receive element stops receiving. This offers the most flexibility, but requires that you write your own Java™ class using the HCL DevOps Test Performance (Test Performance) extension API.
Before you begin
Procedure
To create a new custom code class:
- In the test editor, select a socket receive element.
-
In the End policy section, select Delegated to custom
code and click Generate Code.
This creates a Java™ class template that follows the Test Performance extension API. The Java™ class in created in the src folder of the current project.
- Write the custom code by extending the generating class. See Extending test execution with custom code for more information about extending Test Performance with Java™ code.
- Save the custom code and the test.You can click View Code to edit the Java™ class later.
Example
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 Test Performance 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;
}
}