Skip to Content.
Sympa Menu

ndt-dev - [ndt-dev] [ndt] r1064 committed - Add HTTP support for S2C test to server and flash client.

Subject: NDT-DEV email list created

List archive

[ndt-dev] [ndt] r1064 committed - Add HTTP support for S2C test to server and flash client.


Chronological Thread 
  • From:
  • To:
  • Subject: [ndt-dev] [ndt] r1064 committed - Add HTTP support for S2C test to server and flash client.
  • Date: Thu, 29 May 2014 01:07:38 +0000

Revision: 1064
Author:

Date: Thu May 29 01:07:21 2014 UTC
Log: Add HTTP support for S2C test to server and flash client.
http://code.google.com/p/ndt/source/detail?r=1064

Modified:
/branches/Issue144/flash-client/ndt-flash-config.xml
/branches/Issue144/flash-client/src/TestC2S.as
/branches/Issue144/flash-client/src/TestMETA.as
/branches/Issue144/flash-client/src/TestS2C.as
/branches/Issue144/src/test_s2c_srv.c

=======================================
--- /branches/Issue144/flash-client/ndt-flash-config.xml Sun Feb 2 19:14:17 2014 UTC
+++ /branches/Issue144/flash-client/ndt-flash-config.xml Thu May 29 01:07:21 2014 UTC
@@ -31,7 +31,7 @@
</define>
<define append="true">
<name>CONFIG::clientVersion</name>
- <value>"v1.0.0.0"</value>
+ <value>"v1.0.0.0-url"</value>
</define>
<verbose-stacktraces>true</verbose-stacktraces>
<!-- The locales to compile into the application-->
=======================================
--- /branches/Issue144/flash-client/src/TestC2S.as Wed May 28 11:17:18 2014 UTC
+++ /branches/Issue144/flash-client/src/TestC2S.as Thu May 29 01:07:21 2014 UTC
@@ -35,13 +35,14 @@
// Valid values for _testStage.
private static const PREPARE_TEST1:int = 0;
private static const PREPARE_TEST2:int = 1;
- private static const START_TEST:int = 2;
- private static const SEND_DATA:int = 3;
- private static const COMPUTE_THROUGHPUT:int = 4;
- private static const COMPARE_SERVER1:int = 5;
- private static const COMPARE_SERVER2:int = 6;
- private static const FINALIZE_TEST:int = 7;
- private static const END_TEST:int = 8;
+ private static const START_TEST1:int = 2;
+ private static const START_TEST2:int = 3;
+ private static const SEND_DATA:int = 4;
+ private static const COMPUTE_THROUGHPUT:int = 5;
+ private static const COMPARE_SERVER1:int = 6;
+ private static const COMPARE_SERVER2:int = 7;
+ private static const FINALIZE_TEST:int = 8;
+ private static const END_TEST:int = 9;

private var _callerObj:NDTPController;
private var _c2sTestSuccess:Boolean;
@@ -111,7 +112,9 @@
break;
case PREPARE_TEST2: prepareTest2();
break;
- case START_TEST: startTest();
+ case START_TEST1: startTest1();
+ break;
+ case START_TEST2: startTest2();
break;
case COMPARE_SERVER1: compareWithServer1();
break;
@@ -191,7 +194,7 @@
_speedUpdateTimer = new Timer(SPEED_UPDATE_TIMER);
_speedUpdateTimer.addEventListener(TimerEvent.TIMER, onSpeedUpdate);
_msg = new Message();
- _testStage = START_TEST;
+ _testStage = START_TEST1;
TestResults.appendDebugMsg("C2S test: START_TEST stage.");

if (_ctlSocket.bytesAvailable > 0)
@@ -199,7 +202,7 @@
// they trigger a single ProgressEvent.SOCKET_DATA event. In such case,
// it's necessary to explicitly call the following function to move to
// the next step.
- startTest();
+ startTest1();
}

private function addC2SSocketEventListeners():void {
@@ -272,12 +275,21 @@
/ _c2sTestDuration);
}

- private function startTest():void {
+ private function startTest1():void {
if (!_msg.readHeader(_ctlSocket))
return;
+ _testStage = START_TEST2;
+ if (_ctlSocket.bytesAvailable > 0)
+ // In case header and body have arrive together at the client, they
+ // trigger a single ProgressEvent.SOCKET_DATA event. In such case,
+ // it's necessary to explicitly call the following function to move to
+ // the next step.
+ startTest2();
+ }
+
+ private function startTest2():void {
if (!_msg.readBody(_ctlSocket, _msg.length))
return;
-
if (_msg.type != MessageType.TEST_START) {
TestResults.appendErrMsg(ResourceManager.getInstance().getString(
NDTConstants.BUNDLE_NAME, "outboundWrongMessage", null,
=======================================
--- /branches/Issue144/flash-client/src/TestMETA.as Wed May 28 11:17:18 2014 UTC
+++ /branches/Issue144/flash-client/src/TestMETA.as Thu May 29 01:07:21 2014 UTC
@@ -27,10 +27,12 @@
// Valid values for _testStage.
private static const PREPARE_TEST1:int = 0;
private static const PREPARE_TEST2:int = 1;
- private static const START_TEST:int = 2;
- private static const SEND_DATA:int = 3;
- private static const FINALIZE_TEST:int = 4;
- private static const END_TEST:int = 5;
+ private static const START_TEST1:int = 2;
+ private static const START_TEST2:int = 3;
+ private static const SEND_DATA:int = 4;
+ private static const FINALIZE_TEST1:int = 5;
+ private static const FINALIZE_TEST2:int = 6;
+ private static const END_TEST:int = 7;

private var _callerObj:NDTPController;
private var _ctlSocket:Socket;
@@ -86,9 +88,13 @@
break;
case PREPARE_TEST2: prepareTest2();
break;
- case START_TEST: startTest();
+ case START_TEST1: startTest1();
break;
- case FINALIZE_TEST: finalizeTest();
+ case START_TEST2: startTest2();
+ break;
+ case FINALIZE_TEST1:finalizeTest1();
+ break;
+ case FINALIZE_TEST2:finalizeTest2();
break;
case END_TEST: endTest();
break;
@@ -129,7 +135,7 @@
}

_msg = new Message();
- _testStage = START_TEST;
+ _testStage = START_TEST1;
TestResults.appendDebugMsg("META test: START_TEST stage.");

if (_ctlSocket.bytesAvailable > 0)
@@ -137,12 +143,22 @@
// they trigger a single ProgressEvent.SOCKET_DATA event. In such case,
// it's necessary to explicitly call the following function to move to
// the next step.
- startTest();
+ startTest1();
}

- private function startTest():void {
+ private function startTest1():void {
if (!_msg.readHeader(_ctlSocket))
return;
+ _testStage = START_TEST2;
+ if (_ctlSocket.bytesAvailable > 0)
+ // In case header and body have arrive together at the client, they
+ // trigger a single ProgressEvent.SOCKET_DATA event. In such case,
+ // it's necessary to explicitly call the following function to move to
+ // the next step.
+ startTest2();
+ }
+
+ private function startTest2():void {
if (!_msg.readBody(_ctlSocket, _msg.length))
return;

@@ -224,17 +240,29 @@
return;
}

- _testStage = FINALIZE_TEST;
+ _msg = new Message();
+ _testStage = FINALIZE_TEST1;
TestResults.appendDebugMsg("META test: FINALIZE_TEST stage.");
// The following check is probably not necessary. Added anyway, in case
// the TEST_FINALIZE message does not trigger onReceivedData.
if (_ctlSocket.bytesAvailable > 0)
- finalizeTest();
+ finalizeTest1();
}

- private function finalizeTest():void {
+ private function finalizeTest1():void {
if (!_msg.readHeader(_ctlSocket))
return;
+ _testStage = FINALIZE_TEST2;
+ if (_ctlSocket.bytesAvailable > 0)
+ // In case header and body have arrive together at the client, they
+ // trigger a single ProgressEvent.SOCKET_DATA event. In such case,
+ // it's necessary to explicitly call the following function to move to
+ // the next step.
+ finalizeTest2();
+ }
+
+
+ private function finalizeTest2():void {
if (!_msg.readBody(_ctlSocket, _msg.length))
return;

=======================================
--- /branches/Issue144/flash-client/src/TestS2C.as Wed May 28 11:17:18 2014 UTC
+++ /branches/Issue144/flash-client/src/TestS2C.as Thu May 29 01:07:21 2014 UTC
@@ -23,6 +23,8 @@
import flash.utils.ByteArray;
import flash.utils.getTimer;
import flash.utils.Timer;
+ import flash.net.URLLoader;
+ import flash.net.URLRequest;
import mx.resources.ResourceManager;

/**
@@ -36,14 +38,15 @@
// Valid values for _testStage.
private static const PREPARE_TEST1:int = 0;
private static const PREPARE_TEST2:int = 1;
- private static const START_TEST:int = 2;
- private static const RECEIVE_DATA:int = 3;
- private static const COMPARE_SERVER1:int = 4;
- private static const COMPARE_SERVER2:int = 5;
- private static const COMPUTE_THROUGHPUT:int = 6;
- private static const GET_WEB1001:int = 7;
- private static const GET_WEB1002:int = 8;
- private static const END_TEST:int = 9;
+ private static const START_TEST1:int = 2;
+ private static const START_TEST2:int = 3;
+ private static const RECEIVE_DATA:int = 4;
+ private static const COMPARE_SERVER1:int = 5;
+ private static const COMPARE_SERVER2:int = 6;
+ private static const COMPUTE_THROUGHPUT:int = 7;
+ private static const GET_WEB1001:int = 8;
+ private static const GET_WEB1002:int = 9;
+ private static const END_TEST:int = 10;
private static const THROUGHPUT_VALUE:String = "ThroughputValue";
private static const UNSENT_DATA_AMOUNT:String = "UnsentDataAmount";
private static const TOTAL_SENT_BYTE:String = "TotalSentByte";
@@ -54,7 +57,7 @@
private var _readTimer:Timer;
private var _speedUpdateTimer:Timer;
private var _s2cByteCount:int;
- private var _s2cSocket:Socket;
+ private var _s2cUrl:URLLoader;
private var _s2cTimer:Timer;
// Time to send data to client on the S2C socket.
private var _s2cTestDuration:Number;
@@ -115,7 +118,9 @@
break;
case PREPARE_TEST2: prepareTest2();
break;
- case START_TEST: startTest();
+ case START_TEST1: startTest1();
+ break;
+ case START_TEST2: startTest2();
break;
case COMPARE_SERVER1: compareWithServer1();
break;
@@ -169,17 +174,22 @@
String(_msg.body),
NDTUtils.JSON_DEFAULT_KEY))
: new String(_msg.body));
- _s2cSocket = new Socket();
- addS2CSocketEventListeners();
+ var s2cUrlRequest:URLRequest = new URLRequest("http://"; +
+ _serverHostname +
+ ":" +
+ s2cPort +
+ "/");
+ _s2cUrl = new URLLoader();
+ addS2CUrlEventListeners();
try {
- _s2cSocket.connect(_serverHostname, s2cPort);
+ _s2cUrl.load(s2cUrlRequest);
} catch(e:IOError) {
- TestResults.appendErrMsg("S2C socket connect IO error: " + e);
+ TestResults.appendErrMsg("S2C url connect IO error: " + e);
_s2cTestSuccess = false;
endTest();
return;
} catch(e:SecurityError) {
- TestResults.appendErrMsg("S2C socket connect security error: " + e);
+ TestResults.appendErrMsg("S2C url connect security error: " + e);
_s2cTestSuccess = false;
endTest();
return;
@@ -191,7 +201,7 @@
_s2cTimer = new Timer(NDTConstants.S2C_DURATION);
_s2cTimer.addEventListener(TimerEvent.TIMER, onS2CTimeout);
_msg = new Message();
- _testStage = START_TEST;
+ _testStage = START_TEST1;
TestResults.appendDebugMsg("S2C test: START_TEST stage.");

if (_ctlSocket.bytesAvailable > 0)
@@ -199,57 +209,55 @@
// they trigger a single ProgressEvent.SOCKET_DATA event. In such case,
// it's necessary to explicitly call the following function to move to
// the next step.
- startTest();
+ startTest1();
}

- private function addS2CSocketEventListeners():void {
- _s2cSocket.addEventListener(Event.CONNECT, onS2CConnect);
- _s2cSocket.addEventListener(Event.CLOSE, onS2CClose);
- _s2cSocket.addEventListener(IOErrorEvent.IO_ERROR, onS2CError);
- _s2cSocket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,
+ private function addS2CUrlEventListeners():void {
+ _s2cUrl.addEventListener(Event.CONNECT, onS2CConnect);
+ _s2cUrl.addEventListener(Event.CLOSE, onS2CClose);
+ _s2cUrl.addEventListener(IOErrorEvent.IO_ERROR, onS2CError);
+ _s2cUrl.addEventListener(SecurityErrorEvent.SECURITY_ERROR,
onS2CSecError);
- _s2cSocket.addEventListener(ProgressEvent.SOCKET_DATA, onS2CReceivedData);
+ _s2cUrl.addEventListener(Event.COMPLETE, onS2CComplete);
}

- private function removeS2CSocketEventListeners():void {
- _s2cSocket.removeEventListener(Event.CONNECT, onS2CConnect);
- _s2cSocket.removeEventListener(Event.CLOSE, onS2CClose);
- _s2cSocket.removeEventListener(IOErrorEvent.IO_ERROR, onS2CError);
- _s2cSocket.removeEventListener(SecurityErrorEvent.SECURITY_ERROR,
- onS2CSecError);
- _s2cSocket.removeEventListener(ProgressEvent.SOCKET_DATA,
- onS2CReceivedData);
+ private function removeS2CUrlEventListeners():void {
+ _s2cUrl.removeEventListener(Event.CONNECT, onS2CConnect);
+ _s2cUrl.removeEventListener(Event.CLOSE, onS2CClose);
+ _s2cUrl.removeEventListener(IOErrorEvent.IO_ERROR, onS2CError);
+ _s2cUrl.removeEventListener(SecurityErrorEvent.SECURITY_ERROR,
+ onS2CSecError);
+ _s2cUrl.removeEventListener(Event.COMPLETE, onS2CComplete);
}

private function onS2CConnect(e:Event):void {
- TestResults.appendDebugMsg("S2C socket connected.");
+ TestResults.appendDebugMsg("S2C URL connected.");
}

private function onS2CClose(e:Event):void {
- TestResults.appendDebugMsg("S2C socket closed by the server.");
- closeS2CSocket();
+ TestResults.appendDebugMsg("S2C URL closed by the server.");
+ endDataDownload();
+ }
+
+ private function onS2CComplete(e:Event):void {
+ TestResults.appendDebugMsg("S2C URL download completed.");
+ endDataDownload();
}
+

private function onS2CError(e:IOErrorEvent):void {
- TestResults.appendErrMsg("IOError on S2C socket: : " + e);
+ TestResults.appendErrMsg("IOError on S2C URL: : " + e);
_s2cTestSuccess = false;
- closeS2CSocket();
+ endDataDownload();
endTest();
}

private function onS2CSecError(e:SecurityErrorEvent):void {
TestResults.appendErrMsg("Security error on S2C socket: " + e);
_s2cTestSuccess = false;
- closeS2CSocket();
+ endDataDownload();
endTest();
}
-
- private function onS2CReceivedData(e:ProgressEvent):void {
- _readTimer.stop();
- _readTimer.reset();
- _readTimer.start();
- receiveData();
- }

private function onSpeedUpdate(e:TimerEvent):void {
_s2cTestDuration = getTimer() - _s2cTestStartTime;
@@ -258,9 +266,19 @@
/ _s2cTestDuration;
}

- private function startTest():void {
+ private function startTest1():void {
if (!_msg.readHeader(_ctlSocket))
return;
+ _testStage = START_TEST2;
+ if (_ctlSocket.bytesAvailable > 0)
+ // In case header and body have arrive together at the client, they
+ // trigger a single ProgressEvent.SOCKET_DATA event. In such case,
+ // it's necessary to explicitly call the following function to move to
+ // the next step.
+ startTest2();
+ }
+
+ private function startTest2():void {
if (!_msg.readBody(_ctlSocket, _msg.length))
return;

@@ -289,29 +307,14 @@

_testStage = RECEIVE_DATA;
TestResults.appendDebugMsg("S2C test: RECEIVE_DATA stage.");
- if (_s2cSocket.bytesAvailable > 0)
- receiveData();
}

private function onS2CTimeout(e:TimerEvent):void {
TestResults.appendDebugMsg("Timeout for receiving data on S2C socket.");
- closeS2CSocket();
- }
-
- /**
- * Function that is called repeatedly by the S2C socket response listener
- * for the duration of the test. It processes and keeps track of the total
- * bytes received from the server. The test only goes past this stage if:
- * 1. All data was successfully received and the server closed the socket.
- * 2. A read timeout occured on S2C socket.
- * 3. More than NDTConstants.S2C_DURATION seconds have passed since the
- * beginning of the test.
- */
- private function receiveData():void {
- _s2cByteCount += NDTUtils.readAllBytesAndDiscard(_s2cSocket);
+ endDataDownload();
}

- private function closeS2CSocket():void {
+ private function endDataDownload():void {
// Record end time right after it stops receiving data, to be as accurate
// as possible.
_s2cTimer.stop();
@@ -324,12 +327,11 @@
_readTimer.removeEventListener(TimerEvent.TIMER, onS2CTimeout);
_s2cTimer.removeEventListener(TimerEvent.TIMER, onS2CTimeout);

- if (_s2cSocket.connected)
- _s2cByteCount += _s2cSocket.bytesAvailable;
+ _s2cByteCount = _s2cUrl.bytesTotal;

removeCtlSocketOnReceivedDataListener();
try {
- _s2cSocket.close();
+ _s2cUrl.close();
TestResults.appendDebugMsg("S2C socket closed by the client.");

} catch (e:IOError) {
=======================================
--- /branches/Issue144/src/test_s2c_srv.c Wed May 28 11:17:18 2014 UTC
+++ /branches/Issue144/src/test_s2c_srv.c Thu May 29 01:07:21 2014 UTC
@@ -26,6 +26,79 @@
extern pthread_mutex_t mainmutex;
extern pthread_cond_t maincond;

+extern int errno;
+
+int matchGetRequest(int s, char *m) {
+#define MATCH_SENTINEL "\x01"
+ char *match_sentinel = MATCH_SENTINEL;
+ char *match = NULL;
+ char eohmatch[] = "\r\n\r\n" MATCH_SENTINEL;
+ char *eohmatch_status = NULL;
+ char *match_status = NULL;
+ char r;
+ int didMatch = 0;
+ int iterator = 0;
+
+ match = (char*)malloc(strlen(m) + 2);
+ memset(match, 0, strlen(m) + 2);
+ strcpy(match, m);
+ strcat(match, match_sentinel);
+
+ match_status = match;
+ eohmatch_status = eohmatch;
+
+ while (read(s, &r, 1) > 0) {
+
+ /*
+ * Pre-emptively cycle to the beginning if there is a
+ * mismatch.
+ */
+ if (*match_status != r)
+ match_status = match;
+ if (*eohmatch_status != r)
+ eohmatch_status = eohmatch;
+
+ /*
+ * Check for a continuing match!
+ */
+ if (*match_status == r)
+ match_status++;
+ if (*eohmatch_status == r)
+ eohmatch_status++;
+
+ /*
+ * Check for match completion.
+ */
+ if (*match_status == *match_sentinel) {
+ didMatch = 1;
+ break;
+ }
+ if (*eohmatch_status == *match_sentinel) {
+ break;
+ }
+
+ iterator++;
+ }
+ free(match);
+
+ /*
+ * read the rest of the header, if necessary.
+ */
+ int flags = fcntl(s, F_GETFL, 0);
+ fcntl(s, F_SETFL, flags | O_NONBLOCK);
+ do {
+ int jr = read(s, &r, 1);
+ if (jr < 0 && errno == EAGAIN) {
+ break;
+ }
+ }
+ while (1);
+ fcntl(s, F_SETFL, flags);
+
+ return didMatch;
+}
+
+
const char RESULTS_KEYS[] = "ThroughputValue UnsentDataAmount TotalSentByte";

/**
@@ -118,6 +191,25 @@
int sndqueue;
struct sigaction new, old;
char* jsonMsgValue;
+ int isUrlClient = 0;
+ int haveSentUrlHttpHeader = 0;
+ char urlHttpHeader[] = "HTTP/1.0 200 OK\r\n"
+ "Date: Fri, 40 Mar 2014 16:32:34 GMT\r\n"
+ "Connection: close\r\nExpires: -1\r\n\r\n";
+ char urlPolicy[] = "HTTP/1.0 200 OK\r\n"
+ "Content-Type: text/xml\r\n"
+ "Date: Fri, 40 Mar 2014 16:32:34 GMT\r\n"
+ "Connection: close\r\n"
+ "Expires: -1\r\n\r\n"
+ "<?xml version=\"1.0\"?>"
+ "<!DOCTYPE cross-domain-policy SYSTEM "
+ "\"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\";>"
+ "<cross-domain-policy>"
+ "<site-control permitted-cross-domain-policies=\"master-only\"/>"
+ "<allow-access-from domain=\"*\" to-ports=\"*\" secure=\"false\"/>"
+ "<allow-http-request-headers-from domain=\"*\" headers=\"*\"/>"
+ "</cross-domain-policy>";
+

pthread_t workerThreadId;
int nextseqtosend = 0, lastunackedseq = 0;
@@ -139,6 +231,10 @@
wait_sig = 0;

log_println(0, "test client version: %s", testOptions->client_version);
+
+ if (!strncmp(testOptions->client_version, "v1.0.0.0-url", 12)) {
+ isUrlClient = 1;
+ }

// Determine port to be used. Compute based on options set earlier
// by reading from config file, or use default port2 (3003)
@@ -261,6 +357,12 @@
if (xmitsfd > 0) {
log_println(6, "accept() for %d completed",
testOptions->child0);
+ char cdGetRequest[] = "GET /crossdomain.xml";
+ if (isUrlClient && matchGetRequest(xmitsfd, cdGetRequest)) {
+ writen(xmitsfd, urlPolicy, strlen(urlPolicy));
+ close(xmitsfd);
+ continue;
+ }
procstatusenum = PROCESS_STARTED;
proctypeenum = CONNECT_TYPE;
protolog_procstatus(testOptions->child0, testids, proctypeenum,
@@ -452,7 +554,18 @@
}

// attempt to write random data into the client socket
- n = write(xmitsfd, buff, RECLTH);
+ /*
+ * On the first pass through, send a
+ * HTTP header.
+ */
+ if (isUrlClient && !haveSentUrlHttpHeader) {
+ n = write(xmitsfd, urlHttpHeader, strlen(urlHttpHeader));
+ haveSentUrlHttpHeader = 1;
+ } else {
+ // attempt to write random data into the client socket
+ n = write(xmitsfd, buff, RECLTH);
+ }
+
// socket interrupted, continue attempting to write
if ((n == -1) && (errno == EINTR))
continue;
@@ -594,10 +707,10 @@

#if USE_WEB100
// send web100 data to client
- ret = tcp_stat_get_data(tsnap, xmitsfd, ctlsockfd, agent, count_vars);
+ ret = tcp_stat_get_data(tsnap, xmitsfd, ctlsockfd, agent, count_vars, testOptions->json_support);
web100_snapshot_free(tsnap);
// send tuning-related web100 data collected to client
- ret = tcp_stat_get_data(rsnap, xmitsfd, ctlsockfd, agent, count_vars);
+ ret = tcp_stat_get_data(rsnap, xmitsfd, ctlsockfd, agent, count_vars, testOptions->json_support);
web100_snapshot_free(rsnap);
#elif USE_WEB10G
ret = tcp_stat_get_data(snap, xmitsfd, ctlsockfd, agent, count_vars, testOptions->json_support);


  • [ndt-dev] [ndt] r1064 committed - Add HTTP support for S2C test to server and flash client., ndt, 05/29/2014

Archive powered by MHonArc 2.6.16.

Top of Page