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