KBRTestApp.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2006 Institut fuer Telematik, Universitaet Karlsruhe (TH)
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 //
00018 
00024 #include <IPAddressResolver.h>
00025 #include <CommonMessages_m.h>
00026 #include <GlobalStatistics.h>
00027 #include <UnderlayConfigurator.h>
00028 #include <GlobalNodeList.h>
00029 
00030 #include "KBRTestApp.h"
00031 #include "KBRTestMessage_m.h"
00032 
00033 Define_Module(KBRTestApp);
00034 
00035 KBRTestApp::KBRTestApp()
00036 {
00037     onewayTimer = NULL;
00038 }
00039 
00040 KBRTestApp::~KBRTestApp()
00041 {
00042     cancelAndDelete(onewayTimer);
00043     cancelAndDelete(rpcTimer);
00044     cancelAndDelete(lookupTimer);
00045 }
00046 
00047 void KBRTestApp::initializeApp(int stage)
00048 {
00049     if (stage != MIN_STAGE_APP) {
00050         return;
00051     }
00052 
00053     kbrOneWayTest = par("kbrOneWayTest");
00054     kbrRpcTest = par("kbrRpcTest");
00055     kbrLookupTest = par("kbrLookupTest");
00056 
00057     if (!kbrOneWayTest && !kbrRpcTest && !kbrLookupTest) {
00058         throw cRuntimeError("KBRTestApp::initializeApp(): nothing to do!");
00059     }
00060 
00061     failureLatency = par("failureLatency");
00062 
00063     testMsgSize = par("testMsgSize");
00064     lookupNodeIds = par("lookupNodeIds");
00065     mean = par("testMsgInterval");
00066     deviation = mean / 10;
00067     activeNetwInitPhase = par("activeNetwInitPhase");
00068     msgHandleBufSize = par("msgHandleBufSize");
00069 
00070     numSent = 0;
00071     bytesSent = 0;
00072     numDelivered = 0;
00073     bytesDelivered = 0;
00074     numDropped = 0;
00075     bytesDropped = 0;
00076     WATCH(numSent);
00077     WATCH(bytesSent);
00078     WATCH(numDelivered);
00079     WATCH(bytesDelivered);
00080     WATCH(numDropped);
00081     WATCH(bytesDropped);
00082 
00083     numRpcSent = 0;
00084     bytesRpcSent = 0;
00085     numRpcDelivered = 0;
00086     bytesRpcDelivered = 0;
00087     numRpcDropped = 0;
00088     bytesRpcDropped = 0;
00089     rpcSuccLatencyCount = 0;
00090     rpcSuccLatencySum = 0;
00091     rpcTotalLatencyCount = 0;
00092     rpcTotalLatencySum = 0;
00093     WATCH(numRpcSent);
00094     WATCH(bytesRpcSent);
00095     WATCH(numRpcDelivered);
00096     WATCH(bytesRpcDelivered);
00097     WATCH(numRpcDropped);
00098     WATCH(bytesRpcDropped);
00099 
00100     numLookupSent = 0;
00101     numLookupSuccess = 0;
00102     numLookupFailed = 0;
00103     WATCH(numLookupSent);
00104     WATCH(numLookupSuccess);
00105     WATCH(numLookupFailed);
00106 
00107     sequenceNumber = 0;
00108 
00109     nodeIsLeavingSoon = false;
00110 
00111     // initialize circular buffer
00112     if (msgHandleBufSize > 0) {
00113         mhBuf.resize(msgHandleBufSize);
00114         mhBufBegin = mhBuf.begin();
00115         mhBufEnd = mhBuf.end();
00116         mhBufNext = mhBufBegin;
00117     }
00118 
00119 #if 0
00120     bindToPort(1025);
00121     thisNode.setPort(1025);
00122 #endif
00123 
00124     // start periodic timer
00125     onewayTimer = new cMessage("onewayTimer");
00126     rpcTimer = new cMessage("rpcTimer");
00127     lookupTimer = new cMessage("lookupTimer");
00128 
00129     if (kbrOneWayTest) {
00130         scheduleAt(simTime() + truncnormal(mean, deviation), onewayTimer);
00131     }
00132     if (kbrRpcTest) {
00133         scheduleAt(simTime() + truncnormal(mean, deviation), rpcTimer);
00134     }
00135     if (kbrLookupTest) {
00136         scheduleAt(simTime() + truncnormal(mean, deviation), lookupTimer);
00137     }
00138 }
00139 
00140 void KBRTestApp::handleTimerEvent(cMessage* msg)
00141 {
00142     // schedule next timer event
00143     scheduleAt(simTime() + truncnormal(mean, deviation), msg);
00144 
00145     // do nothing if the network is still in the initialization phase
00146     if ((!activeNetwInitPhase && underlayConfigurator->isInInitPhase())
00147             || underlayConfigurator->isSimulationEndingSoon()
00148             || nodeIsLeavingSoon) {
00149         return;
00150     }
00151 
00152     OverlayKey destKey;
00153 
00154     if (msg == onewayTimer) {
00155         // TEST 1: route a test message to a key (one-way)
00156         destKey = createDestKey();
00157         // do nothing if there are currently no nodes in the network
00158         if (!destKey.isUnspecified()) {
00159             // create a 100 byte test message
00160             KBRTestMessage* testMsg = new KBRTestMessage("KBRTestMessage");
00161             testMsg->setId(getId());
00162             testMsg->setSeqNum(sequenceNumber++);
00163             testMsg->setByteLength(testMsgSize);
00164             testMsg->setMeasurementPhase(globalStatistics->isMeasuring());
00165 
00166             RECORD_STATS(globalStatistics->sentKBRTestAppMessages++;
00167                          numSent++; bytesSent += testMsg->getByteLength());
00168 
00169             callRoute(destKey, testMsg);
00170         }
00171     } else if (msg == rpcTimer) {
00172         // TEST 2: send a remote procedure call to a specific key and wait for a response
00173         destKey = createDestKey();
00174         // do nothing if there are currently no nodes in the network
00175         if (!destKey.isUnspecified()) {
00176             KbrTestCall* call = new KbrTestCall;
00177             call->setByteLength(testMsgSize);
00178             KbrRpcContext* context = new KbrRpcContext;
00179             context->setDestKey(destKey);
00180             context->setMeasurementPhase(globalStatistics->isMeasuring());
00181 
00182             RECORD_STATS(numRpcSent++;
00183                          bytesRpcSent += call->getByteLength());
00184 
00185             sendRouteRpcCall(TIER1_COMP, destKey, call, context);
00186         }
00187     } else /*if (msg == lookupTimer &&)*/ {
00188         // TEST 3: perform a lookup of a specific key
00189         destKey = createDestKey();
00190         // do nothing if there are currently no nodes in the network
00191         if (!destKey.isUnspecified()) {
00192             LookupCall* call = new LookupCall();
00193             call->setKey(destKey);
00194             call->setNumSiblings(overlay->getMaxNumSiblings());
00195             KbrRpcContext* context = new KbrRpcContext;
00196             context->setDestKey(destKey);
00197             context->setMeasurementPhase(globalStatistics->isMeasuring());
00198             sendInternalRpcCall(OVERLAY_COMP, call, context);
00199 
00200             RECORD_STATS(numLookupSent++);
00201         }
00202     }
00203 
00204 #if 0
00205     thisNode.setPort(1025);
00206     NodeHandle handle = globalNodeList->getBootstrapNode();
00207     handle.setPort(1025);
00208     pingNode(handle, -1, -1, NULL, "TestPING", NULL, -1, UDP_TRANSPORT);
00209 #endif
00210 
00211 }
00212 void KBRTestApp::pingResponse(PingResponse* response, cPolymorphic* context,
00213                               int rpcId, simtime_t rtt)
00214 {
00215     //std::cout << rtt << std::endl;
00216 }
00217 bool KBRTestApp::handleRpcCall(BaseCallMessage* msg)
00218 {
00219     RPC_SWITCH_START( msg );
00220         RPC_DELEGATE( KbrTest, kbrTestCall );
00221     RPC_SWITCH_END( );
00222 
00223     return RPC_HANDLED;
00224 }
00225 void KBRTestApp::kbrTestCall(KbrTestCall* call)
00226 {
00227     KbrTestResponse* response = new KbrTestResponse;
00228     response->setByteLength(call->getByteLength());
00229     sendRpcResponse(call, response);
00230 }
00231 
00232 void KBRTestApp::handleRpcResponse(BaseResponseMessage* msg,
00233                                    cPolymorphic* context, int rpcId,
00234                                    simtime_t rtt)
00235 {
00236     RPC_SWITCH_START(msg)
00237     RPC_ON_RESPONSE(Lookup) {
00238         EV << "[KBRTestApp::handleRpcResponse() @ " << overlay->getThisNode().getAddress()
00239            << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00240            << "    Lookup RPC Response received: id=" << rpcId << "\n"
00241            << "    msg=" << *_LookupResponse << " rtt=" << rtt
00242            << endl;
00243         handleLookupResponse(_LookupResponse, context, rtt);
00244         break;
00245     }
00246     RPC_ON_RESPONSE(KbrTest) {
00247         KbrRpcContext* kbrRpcContext = check_and_cast<KbrRpcContext*>(context);
00248         if (kbrRpcContext->getMeasurementPhase() == true) {
00249             if (!lookupNodeIds ||
00250                     kbrRpcContext->getDestKey() == msg->getSrcNode().getKey()) {
00251 
00252                 RECORD_STATS(numRpcDelivered++;
00253                              bytesRpcDelivered += msg->getByteLength());
00254                 RECORD_STATS(globalStatistics->recordOutVector(
00255                         "KBRTestApp: RPC Success Latency", SIMTIME_DBL(rtt)));
00256                 RECORD_STATS(globalStatistics->recordOutVector(
00257                         "KBRTestApp: RPC Total Latency", SIMTIME_DBL(rtt)));
00258                 RECORD_STATS(rpcSuccLatencyCount++;
00259                              rpcSuccLatencySum += SIMTIME_DBL(rtt));
00260                 RECORD_STATS(rpcTotalLatencyCount++;
00261                              rpcTotalLatencySum += SIMTIME_DBL(rtt));
00262                 OverlayCtrlInfo* overlayCtrlInfo =
00263                         dynamic_cast<OverlayCtrlInfo*>(msg->getControlInfo());
00264 
00265                 uint16_t hopSum = msg->getCallHopCount();
00266                 hopSum += (overlayCtrlInfo ? overlayCtrlInfo->getHopCount() : 1);
00267                 RECORD_STATS(globalStatistics->recordOutVector(
00268                         "KBRTestApp: RPC Hop Count", hopSum));
00269             } else {
00270                 RECORD_STATS(numRpcDropped++;
00271                              bytesRpcDropped += msg->getByteLength());
00272                 // for failed RPCs add failureLatency to latency statistics vector
00273                 RECORD_STATS(globalStatistics->recordOutVector(
00274                         "KBRTestApp: RPC Total Latency",
00275                         SIMTIME_DBL(failureLatency)));
00276                 RECORD_STATS(rpcTotalLatencyCount++;
00277                              rpcTotalLatencySum += SIMTIME_DBL(failureLatency));
00278             }
00279         }
00280         delete kbrRpcContext;
00281         break;
00282     }
00283     RPC_SWITCH_END( )
00284 }
00285 
00286 void KBRTestApp::handleRpcTimeout(BaseCallMessage* msg,
00287                                   const TransportAddress& dest,
00288                                   cPolymorphic* context, int rpcId,
00289                                   const OverlayKey& destKey)
00290 {
00291     RPC_SWITCH_START(msg)
00292     RPC_ON_CALL(KbrTest) {
00293         KbrRpcContext* kbrRpcContext = check_and_cast<KbrRpcContext*>(context);
00294         if (kbrRpcContext->getMeasurementPhase() == true) {
00295              RECORD_STATS(numRpcDropped++;
00296                           bytesRpcDropped += msg->getByteLength());
00297              // for failed RPCs add failureLatency to latency statistics vector
00298              RECORD_STATS(globalStatistics->recordOutVector(
00299                          "KBRTestApp: RPC Total Latency",
00300                          SIMTIME_DBL(failureLatency)));
00301              RECORD_STATS(rpcTotalLatencyCount++;
00302                           rpcTotalLatencySum += SIMTIME_DBL(failureLatency));
00303 
00304         }
00305         break;
00306     }
00307     RPC_ON_CALL(Lookup) {
00308         KbrRpcContext* kbrRpcContext = check_and_cast<KbrRpcContext*>(context);
00309         if (kbrRpcContext->getMeasurementPhase() == true) {
00310             RECORD_STATS(numLookupFailed++);
00311             // for failed lookups add failureLatency to latency statistics vector
00312             RECORD_STATS(globalStatistics->recordOutVector(
00313                          "KBRTestApp: Lookup Total Latency",
00314                          SIMTIME_DBL(failureLatency)));
00315         }
00316         break;
00317     }
00318     RPC_SWITCH_END()
00319 
00320     delete context;
00321 }
00322 
00323 void KBRTestApp::handleLookupResponse(LookupResponse* msg,
00324                                       cObject* context, simtime_t latency)
00325 {
00326     EV << "[KBRTestApp::handleLookupResponse() @ " << overlay->getThisNode().getAddress()
00327        << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00328        << "    Lookup response for key " << msg->getKey()<< " : ";
00329 
00330     KbrRpcContext* kbrRpcContext = check_and_cast<KbrRpcContext*>(context);
00331 
00332     if (kbrRpcContext->getMeasurementPhase() == true) {
00333         if (msg->getIsValid() && (!lookupNodeIds ||
00334                               (msg->getSiblingsArraySize() > 0 &&
00335                                msg->getSiblings(0).getKey() == msg->getKey()))) {
00336             RECORD_STATS(numLookupSuccess++);
00337             RECORD_STATS(globalStatistics->recordOutVector(
00338                    "KBRTestApp: Lookup Success Latency", SIMTIME_DBL(latency)));
00339             RECORD_STATS(globalStatistics->recordOutVector(
00340                    "KBRTestApp: Lookup Total Latency", SIMTIME_DBL(latency)));
00341             RECORD_STATS(globalStatistics->recordOutVector(
00342                     "KBRTestApp: Lookup Hop Count", msg->getHopCount()));
00343         } else {
00344             RECORD_STATS(numLookupFailed++);
00345             // for failed lookups add failureLatency to latency statistics vector
00346             RECORD_STATS(globalStatistics->recordOutVector(
00347                          "KBRTestApp: Lookup Total Latency",
00348                          SIMTIME_DBL(failureLatency)));
00349             RECORD_STATS(globalStatistics->recordOutVector(
00350                     "KBRTestApp: Failed Lookup Hop Count", msg->getHopCount()));
00351         }
00352     }
00353 
00354     delete kbrRpcContext;
00355 }
00356 
00357 void KBRTestApp::handleNodeLeaveNotification()
00358 {
00359     nodeIsLeavingSoon = true;
00360 }
00361 
00362 void KBRTestApp::deliver(OverlayKey& key, cMessage* msg)
00363 {
00364     KBRTestMessage* testMsg = check_and_cast<KBRTestMessage*>(msg);
00365     OverlayCtrlInfo* overlayCtrlInfo =
00366         check_and_cast<OverlayCtrlInfo*>(msg->removeControlInfo());
00367 
00368     if (overlay->getThisNode().getKey().isUnspecified())
00369         error("key");
00370 
00371     // check for duplicate
00372     if ((msgHandleBufSize > 0 )
00373             && checkSeen(overlayCtrlInfo->getSrcNode().getKey(), testMsg->getSeqNum())) {
00374         EV << "[KBRTestApp::deliver() @ " << overlay->getThisNode().getAddress()
00375            << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00376            << "    Duplicate dropped."
00377            << endl;
00378         delete overlayCtrlInfo;
00379         delete testMsg;
00380         return;
00381     }
00382 
00383     // Return statistical data to the sender.
00384     if (cModule* mod = simulation.getModule(testMsg->getId())) {
00385         if (KBRTestApp* sender = dynamic_cast<KBRTestApp*>(mod)) {
00386             if ((!lookupNodeIds) || (overlay->getThisNode().getKey() == key)) {
00387                 if (testMsg->getMeasurementPhase() == true) {
00388                         sender->evaluateData((simTime() - testMsg->getCreationTime()),
00389                                              overlayCtrlInfo->getHopCount(),
00390                                              testMsg->getByteLength());
00391                 }
00392             } else if(lookupNodeIds) {
00393                 if (testMsg->getMeasurementPhase() == true) {
00394                     RECORD_STATS(numDropped++;
00395                                  bytesDropped += testMsg->getByteLength());
00396                 }
00397                 EV << "[KBRTestApp::deliver() @ " << overlay->getThisNode().getAddress()
00398                    << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00399                    << "    Error: Lookup of NodeIDs and KBRTestMessage"
00400                    << " received with different destKey!"
00401                    << endl;
00402             }
00403         }
00404     }
00405 
00406     EV << "[KBRTestApp::deliver() @ " << overlay->getThisNode().getAddress()
00407        << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00408        << "    Received \"" << testMsg->getName() << "(seqNr: "
00409        << testMsg->getSeqNum() << ")\n"
00410        << "    with destination key: " << key.toString(16)
00411        << endl;
00412 
00413     delete overlayCtrlInfo;
00414     delete testMsg;
00415 }
00416 
00417 void KBRTestApp::forward(OverlayKey* key, cPacket** msg,
00418                          NodeHandle* nextHopNode)
00419 {
00420     KBRTestMessage* tempMsg = dynamic_cast<KBRTestMessage*>(*msg);
00421 
00422     if (tempMsg == NULL) return;
00423 
00424     tempMsg->setVisitedNodesArraySize(tempMsg->getVisitedNodesArraySize() + 1);
00425     tempMsg->setVisitedNodes(tempMsg->getVisitedNodesArraySize() - 1,
00426                              overlay->getThisNode().getAddress());
00427 }
00428 
00429 OverlayKey KBRTestApp::createDestKey()
00430 {
00431     if (lookupNodeIds) {
00432         return globalNodeList->getRandomNode(0, true, true).getKey();
00433     }
00434     // generate random destination key
00435     return OverlayKey::random();
00436 }
00437 
00438 bool KBRTestApp::checkSeen(const OverlayKey& key, int seqNum)
00439 {
00440     MsgHandle hdl(key, seqNum);
00441 
00442     for (MsgHandleBuf::iterator it = mhBufBegin; it != mhBufEnd; ++it) {
00443         if (it->key.isUnspecified()) {
00444             continue;
00445         }
00446 
00447         if (*it == hdl) {
00448             return true;
00449         }
00450     }
00451 
00452     *(mhBufNext++) = hdl;
00453     if (mhBufNext == mhBufEnd) {
00454         mhBufNext = mhBufBegin;
00455     }
00456     return false;
00457 }
00458 
00459 void KBRTestApp::evaluateData(simtime_t latency, int hopCount, long int bytes)
00460 {
00461     // count the number and size of successfully delivered messages
00462     RECORD_STATS(numDelivered++; bytesDelivered += bytes;
00463                  globalStatistics->deliveredKBRTestAppMessages++);
00464 
00465     if (numSent < numDelivered) {
00466         error("KBRTestApp::evaluateData(): numSent < numDelivered!");
00467     }
00468 
00469     RECORD_STATS(globalStatistics->recordOutVector("KBRTestApp: One-way Hop "
00470                                                    "Count", hopCount));
00471     RECORD_STATS(globalStatistics->recordOutVector("KBRTestApp: One-way Latency",
00472                                                    SIMTIME_DBL(latency)));
00473 }
00474 
00475 void KBRTestApp::finishApp()
00476 {
00477     simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00478 
00479     if (time >= GlobalStatistics::MIN_MEASURED) {
00480         if (kbrOneWayTest) {
00481             globalStatistics->addStdDev("KBRTestApp: One-way Delivered Messages/s",
00482                                         numDelivered / time);
00483             globalStatistics->addStdDev("KBRTestApp: One-way Delivered Bytes/s",
00484                                         bytesDelivered / time);
00485             globalStatistics->addStdDev("KBRTestApp: One-way Dropped Messages/s",
00486                                         numDropped / time);
00487             globalStatistics->addStdDev("KBRTestApp: One-way Dropped Bytes/s",
00488                                         bytesDropped / time);
00489             if (numSent > 0) {
00490                 globalStatistics->addStdDev("KBRTestApp: One-way Delivery Ratio",
00491                                             (float)numDelivered /
00492                                             (float)numSent);
00493             }
00494         }
00495 
00496         if (kbrRpcTest) {
00497             globalStatistics->addStdDev("KBRTestApp: RPC Delivered Messages/s",
00498                                         numRpcDelivered / time);
00499             globalStatistics->addStdDev("KBRTestApp: RPC Delivered Bytes/s",
00500                                         bytesRpcDelivered / time);
00501             globalStatistics->addStdDev("KBRTestApp: RPC Dropped Messages/s",
00502                                         numRpcDropped / time);
00503             globalStatistics->addStdDev("KBRTestApp: RPC Dropped Bytes/s",
00504                                         bytesRpcDropped / time);
00505 #if 0
00506             if (rpcSuccLatencyCount > 0) {
00507                 globalStatistics->addStdDev("KBRTestApp: RPC Success Session Latency",
00508                                         SIMTIME_DBL(rpcSuccLatencySum) / rpcSuccLatencyCount);
00509             }
00510 
00511             if (rpcTotalLatencyCount > 0) {
00512                 globalStatistics->addStdDev("KBRTestApp: RPC Total Session Latency",
00513                                         SIMTIME_DBL(rpcTotalLatencySum) / rpcTotalLatencyCount);
00514             }
00515 #endif
00516 
00517             if (numRpcSent > 0) {
00518                 globalStatistics->addStdDev("KBRTestApp: RPC Delivery Ratio",
00519                                             (float)numRpcDelivered /
00520                                             (float)numRpcSent);
00521             }
00522         }
00523 
00524         if (kbrLookupTest) {
00525             globalStatistics->addStdDev("KBRTestApp: Successful Lookups/s",
00526                                         numLookupSuccess / time);
00527             globalStatistics->addStdDev("KBRTestApp: Failed Lookups/s",
00528                                         numLookupFailed / time);
00529             if (numLookupSent > 0) {
00530                 globalStatistics->addStdDev("KBRTestApp: Lookup Success Ratio",
00531                                             (float)numLookupSuccess /
00532                                             (float)numLookupSent);
00533             }
00534         }
00535     }
00536 }

Generated on Tue Sep 8 17:26:53 2009 for OverSim by  doxygen 1.5.8