void testUpdateSameBinding() { UtlSList bindings; RegistrationBinding* binding; RegistrationDbTestContext testDbContext(TEST_DATA_DIR "/regdbdata", TEST_WORK_DIR "/regdbdata" ); testDbContext.inputFile("updateBindings.xml"); RegistrationDB* regDb = RegistrationDB::getInstance(); // Get an existing binding Int64 seqOneUpdates = regDb->getNewUpdatesForRegistrar("seqOne", 2, bindings); CPPUNIT_ASSERT_EQUAL(1LL, seqOneUpdates); binding = (RegistrationBinding*)bindings.first(); // Call updateBinding with the same binding regDb->updateBinding(*binding); // Get it back and make sure we still only have one bindings.destroyAll(); seqOneUpdates = regDb->getNewUpdatesForRegistrar("seqOne", 2, bindings); CPPUNIT_ASSERT_EQUAL(1LL, seqOneUpdates); }
/*!a Test case to test the destroyAll() * method. */ void testClearAndDestroy() { const char* prefix = "test the destroyAll() method " ; const char* suffix1 = ":- Verify that all entries are removed" ; const char* suffix2 = ":- The objects are deleted" ; UtlContainableTestStub* uStub ; UtlContainableTestStub* uStubPtr ; uStub = new UtlContainableTestStub(0) ; uStubPtr = new UtlContainableTestStub(1) ; emptyList.append(uStub) ; emptyList.append(uStubPtr) ; emptyList.destroyAll() ; int cCountAfter = UtlContainableTestStub::getCount() ; string msg ; TestUtilities::createMessage(2, &msg, prefix, suffix1) ; CPPUNIT_ASSERT_EQUAL_MESSAGE(msg.data(), 0, (int)emptyList.entries()) ; // Since the TestStub has been implemented such that destructor // decrements the static counter, to verify that the objects have // been deleted, verify that the static counter has been decremented. TestUtilities::createMessage(2, &msg, prefix, suffix2) ; CPPUNIT_ASSERT_EQUAL_MESSAGE(msg.data(), 0, cCountAfter) ; } //testClearAndDestroy
void RegistrationDB::getUnexpiredContactsFieldsContaining ( UtlString& substringToMatch, const int& timeNow, UtlSList& matchingContactFields ) const { // Clear the results matchingContactFields.destroyAll(); if( m_pFastDB != NULL ) { SMART_DB_ACCESS; dbCursor< RegistrationRow > cursor; UtlString queryString = "contact like '%" + substringToMatch + "%' and expires>"; queryString.appendNumber( timeNow ); dbQuery query; query = queryString; if ( cursor.select(query) > 0 ) { // Copy all the unexpired contacts into the result list do { UtlString* contactValue = new UtlString(cursor->contact); matchingContactFields.append( contactValue ); } while ( cursor.next() ); } } else { OsSysLog::add(FAC_DB, PRI_CRIT, "RegistrationDB::getUnexpiredContactsFieldsContaining failed - no DB"); } }
void testUpdateExistingUriNewContact() { UtlSList bindings; RegistrationBinding* binding; RegistrationDbTestContext testDbContext(TEST_DATA_DIR "/regdbdata", TEST_WORK_DIR "/regdbdata" ); testDbContext.inputFile("updateBindings.xml"); RegistrationDB* regDb = RegistrationDB::getInstance(); // Get an existing binding Int64 seqOneUpdates = regDb->getNewUpdatesForRegistrar("seqOne", 2, bindings); CPPUNIT_ASSERT_EQUAL(1LL, seqOneUpdates); binding = (RegistrationBinding*)bindings.first(); // Change the contact address const UtlString* oldContact = binding->getContact(); UtlString newContact(*oldContact); newContact.replace('2', '3'); binding->setContact(newContact); regDb->updateBinding(*binding); // We should have 2 bindings now bindings.destroyAll(); seqOneUpdates = regDb->getNewUpdatesForRegistrar("seqOne", 2, bindings); CPPUNIT_ASSERT_EQUAL(2LL, seqOneUpdates); }
void testUpdateExistingBinding() { UtlSList bindings; RegistrationBinding* binding; RegistrationDbTestContext testDbContext(TEST_DATA_DIR "/regdbdata", TEST_WORK_DIR "/regdbdata" ); testDbContext.inputFile("updateBindings.xml"); RegistrationDB* regDb = RegistrationDB::getInstance(); // Get an existing binding Int64 seqOneUpdates = regDb->getNewUpdatesForRegistrar("seqOne", 2, bindings); CPPUNIT_ASSERT_EQUAL(1LL, seqOneUpdates); binding = (RegistrationBinding*)bindings.first(); // Increment the CSeq number int newCseq = binding->getCseq() + 1; binding->setCseq(newCseq); regDb->updateBinding(*binding); binding->setCseq(0); // Get the same binding bindings.destroyAll(); seqOneUpdates = regDb->getNewUpdatesForRegistrar("seqOne", 2, bindings); CPPUNIT_ASSERT_EQUAL(1LL, seqOneUpdates); // Test if the new CSeq number got updated binding = (RegistrationBinding*)bindings.first(); CPPUNIT_ASSERT_EQUAL(newCseq, binding->getCseq()); }
int NatMaintainer::run( void* runArg ) { OsStatus rc; while( !isShuttingDown() ) { //TODO: Optimization. Do not maintain db entries for which we are not the primary since // no pinhole is open for us at the remote NAT if we are the secondary. Note: once this // optimization gets implemented, we will need to start refreshing callers of every active // CallTracker if not registered with the system handling the call to ensure that its // pinhole remains open throughout the call. rc = mTimerMutex.acquire( NAT_REFRESH_INTERVAL_IN_MILLISECS ); if( rc == OS_WAIT_TIMEOUT ) { if( mpSipRouter ) { mRefreshRoundNumber++; int timeNow = OsDateTime::getSecsSinceEpoch(); // Increment CSeq so that the OPTIONS sent in this // wave have incrementing Cseq as per spec mpKeepAliveMessage->setCSeqField( mNextSeqValue, "OPTIONS" ); mNextSeqValue++; // timer has expired - refresh timeout UtlSList resultList; UtlString stringToMatch( SIPX_PRIVATE_CONTACT_URI_PARAM ); // start by sending keep-alives to non-expired contacts for far-end NATed phones // found in the subscription database mpSubscriptionDB->getUnexpiredContactsFieldsContaining( stringToMatch, timeNow, resultList ); sendKeepAliveToContactList( resultList ); resultList.destroyAll(); // next, send keep-alives to non-expired contacts for far-end NATed phones // found in the registration database mpRegistrationDB->getUnexpiredContactsFieldsContaining( stringToMatch, timeNow, resultList ); sendKeepAliveToContactList( resultList ); resultList.destroyAll(); // finally, send keep-alives to the endpoints that were inserted into our // external keep alive list by other components of the NAT traversal feature. sendKeepAliveToExternalKeepAliveList(); } } } return 0; }
void testGetNextUpdateForRegistrar() { UtlSList bindings; RegistrationDbTestContext testDbContext(TEST_DATA_DIR "/regdbdata", TEST_WORK_DIR "/regdbdata" ); testDbContext.inputFile("getMaxUpdate.xml"); RegistrationDB* regDb = RegistrationDB::getInstance(); Int64 seqOneUpdates = regDb->getNextUpdateForRegistrar("seqOne", 2, bindings); CPPUNIT_ASSERT_EQUAL(1LL, seqOneUpdates); UtlSListIterator iterator(bindings); // Loop through all returned bindings and mark the ones we've seen. // Also check correctness of bindings RegistrationBinding *binding; while ((binding = (RegistrationBinding*)iterator())) { CPPUNIT_ASSERT_EQUAL(binding->getCallId()->compareTo("ID3"), 0); CPPUNIT_ASSERT_EQUAL(binding->getContact()->compareTo("sip:[email protected]"), 0); CPPUNIT_ASSERT_EQUAL(binding->getUri()->toString().compareTo("sip:[email protected]"), 0); CPPUNIT_ASSERT_EQUAL(300, binding->getCseq()); } bindings.destroyAll(); // Pass in high update number value, expect nothing to be returned seqOneUpdates = regDb->getNewUpdatesForRegistrar("seqOne", 8, bindings); CPPUNIT_ASSERT_EQUAL(0LL, seqOneUpdates); bindings.destroyAll(); // Test the other registrar, expect one binding Int64 seqTwoUpdates = regDb->getNewUpdatesForRegistrar("seqTwo", 2, bindings); CPPUNIT_ASSERT_EQUAL(1LL, seqTwoUpdates); binding = (RegistrationBinding*)bindings.first(); CPPUNIT_ASSERT_EQUAL(binding->getContact()->compareTo("sip:[email protected]"), 0); CPPUNIT_ASSERT_EQUAL(binding->getUri()->toString().compareTo("sip:[email protected]"), 0); CPPUNIT_ASSERT_EQUAL(800, binding->getCseq()); }
//deep copy of aliases void SipLine::copyAliases(UtlSList& dest, const UtlSList& source) const { // Clear dest list if (!dest.isEmpty()) { dest.destroyAll() ; } // Copy maintaining order int length = source.entries() ; for (int i=0; i<length; i++) { UtlString* pEntry = (UtlString*) source.at(i) ; dest.append(new UtlString(*pEntry)) ; } }
void runCommand() { FileTestContext testContext(TEST_DATA_DIR "commandDef", TEST_WORK_DIR "commandDef"); // copy test files into testContext structure testContext.inputFile("goodcommand.xml"); testContext.inputFile("goodcommand.sh"); UtlString exePath; testContext.workingFilePath("goodcommand.sh", exePath); chmod(exePath.data(), S_IREAD | S_IWRITE | S_IEXEC); testContext.setSipxDir(SipXecsService::VarDirType, "var"); testContext.setSipxDir(SipXecsService::LogDirType); UtlString path; SipxCommand* command1; testContext.inputFilePath("goodcommand.xml", path); CPPUNIT_ASSERT((command1 = SipxCommand::createFromDefinition(path))); ASSERT_STR_EQUAL("Good", command1->data()); UtlSList msgs; command1->getCommandMessages(msgs); CPPUNIT_ASSERT(0 == msgs.entries()); command1->execute(); OsTask::delay(500); // give task some time to get up and running CPPUNIT_ASSERT(true == command1->isRunning()); OsTask::delay(1000); // give task some time to finish CPPUNIT_ASSERT(false == command1->isRunning()); command1->getCommandMessages(msgs); CPPUNIT_ASSERT(3 == msgs.entries()); ASSERT_STR_EQUAL("stdout.msg-1: goodprocess.sh" , ((UtlString*)msgs.at(0))->data()); ASSERT_STR_EQUAL("return.code: 11" , ((UtlString*)msgs.at(2))->data()); msgs.destroyAll(); delete command1; OsTask::delay(1000); // give task some time to shutdown }
UtlBoolean DialByNameDB::getDigitStrings ( const UtlString& displayName, UtlSList& rDTMFStrings ) const { UtlString lowerString = displayName; lowerString.toLower(); lowerString = lowerString.strip(UtlString::both, '"'); UtlTokenizer next( lowerString ); UtlString token; UtlSList names; // Parse the Display name into a list of names // The algorithm for breaking up the string is as follows // if the string has > 2 tokens (forget about , separators) // create multiple entries in the IMDB for the all combinations // so for example // John Peter Smith Jr would result in DTMF entries for // PeterSmithJrJohn, SmithJrJohnPeter and JrJohnPeterSmith // @JC Added - separator for MIT's Avery-Smith example while (next.next(token, "\t\n,- ")) { names.insert ( new UtlString ( token ) ); } size_t numNames = names.entries(); if ( numNames > 0 ) { UtlString reorderedString; unsigned int splitPosition = 1; do { unsigned int i; UtlString firstNames; for ( i=0; i<splitPosition; i++ ) { firstNames += *(UtlString*)names.at(i); } UtlString lastNames; for ( i = splitPosition; i<numNames; i++) { lastNames += *(UtlString*)names.at(i); } // add the new string reorderedString = lastNames + firstNames; unsigned int len = reorderedString.length(); // calculate thd DTMF digits for the display name // firstly strip all , 's and spaces UtlString digitString; for ( i = 0; i<len; i++ ) { int offset = (int) ( reorderedString(i) - 'a' ); // filter out white space and comma separators if ( (offset >= 0) && (offset < 26) ) digitString += digitmap[ offset ]; } rDTMFStrings.insert ( new UtlString (digitString) ); splitPosition++; } while ( splitPosition<numNames ); } // call the desctuctors on all the temp strings names.destroyAll(); return TRUE; }
// Read and parse the appearance group file and install the appearance groups // into the AppearanceGroupSet. OsStatus AppearanceGroupFileReader::initialize() { Os::Logger::instance().log(FAC_SAA, PRI_DEBUG, "AppearanceGroupFileReader::initialize entered"); int changeDelay = mAppearanceGroupSet->getAppearanceAgent()->getChangeDelay(); // The status to return. OsStatus ret = OS_SUCCESS; // No work to be done if file name is not set. if (!mFileName.isNull()) { // Initialize Tiny XML document object. TiXmlDocument document; TiXmlNode* lists_node; if ( // Load the XML into it. document.LoadFile(mFileName.data()) && // Find the top element, which should be <appearanceGroups>. (lists_node = document.FirstChild("appearanceGroups")) != NULL && lists_node->Type() == TiXmlNode::ELEMENT) { UtlSList newGroupList; // Find all the <resource> children and add them to the AppearanceGroup. for (TiXmlNode* resource_node = 0; (resource_node = lists_node->IterateChildren( "resource", resource_node));) { if (resource_node->Type() == TiXmlNode::ELEMENT) { TiXmlElement* resource_element = resource_node->ToElement(); // Process each <resource> element. bool resource_valid = true; // Process the 'uri' attribute. const char* uri_attribute = resource_element->Attribute("uri"); if (!uri_attribute || *uri_attribute == '\0') { // URI missing or null. Os::Logger::instance().log(FAC_SAA, PRI_ERR, "AppearanceGroupFileReader::initialize " "uri attribute of <resource> was missing or null"); resource_valid = false; ret = OS_FAILED; } if (resource_valid) { newGroupList.append(new UtlString(uri_attribute)); } } } Os::Logger::instance().log(FAC_SAA, PRI_DEBUG, "AppearanceGroupFileReader::initialize Done loading file '%s'", mFileName.data()); // For all groups in the current GroupSet, remove them if not in the new list. // Since these loops contain a delay and can run for a long time, // we have to check gShutdownFlag to abort processing when // a shutdown has been requested. UtlSList oldGroupList; mAppearanceGroupSet->getAllAppearanceGroups(oldGroupList); UtlSListIterator oldGroupItor(oldGroupList); UtlString* group; while (!gShutdownFlag && (group = dynamic_cast <UtlString*> (oldGroupItor()))) { UtlSListIterator newGroupItor(newGroupList); UtlString* newGroup; bool found = false; while (!found && (newGroup = dynamic_cast <UtlString*> (newGroupItor()))) { if (newGroup->compareTo(*group) == 0) { found = true; } } if (!found) { mAppearanceGroupSet->removeAppearanceGroup(group->data()); OsTask::delay(changeDelay); } } // For all groups in the new list, add to GroupSet if they are not there. UtlSListIterator groupItor(newGroupList); while (!gShutdownFlag && (group = dynamic_cast <UtlString*> (groupItor()))) { if (!mAppearanceGroupSet->findAppearanceGroup(group->data())) { mAppearanceGroupSet->addAppearanceGroup(group->data()); OsTask::delay(changeDelay); } } newGroupList.destroyAll(); } else { // Report error parsing file. Os::Logger::instance().log(FAC_SAA, PRI_CRIT, "AppearanceGroupFileReader::initialize " "Appearance group file '%s' could not be parsed.", mFileName.data()); ret = OS_FAILED; } } else { // Report that there is no file. Os::Logger::instance().log(FAC_SAA, PRI_WARNING, "AppearanceGroupFileReader::initialize No Appearance group file set."); } return ret; }
// Read an XML file of Registration DB entries and fill a UtlSList // with RegistrationBinding objects. // The XML must contain all data fields, except for <identity>. void readUpdateList(const char* filename, UtlSList& updates, int timeOffset) { char msg[1024]; // Clear the list. updates.destroyAll(); // Initialize Tiny XML document object. TiXmlDocument document; TiXmlNode* items_element; sprintf(msg, "Data file '%s'", filename); // Load the XML into it. CPPUNIT_ASSERT_MESSAGE(msg, document.LoadFile(filename)); // Find the top element, which should be an <items>. items_element = document.FirstChild("items"); CPPUNIT_ASSERT_MESSAGE(msg, items_element != NULL); CPPUNIT_ASSERT_MESSAGE(msg, items_element->Type() == TiXmlNode::ELEMENT); // Find all the <item> elements. TiXmlNode* item_element; int item_no; for (item_element = 0, item_no = 0; (item_element = items_element->IterateChildren("item", item_element)); item_no++ ) { // Process each <item> element. // The UtlHashMap to convert into a RegistrationBinding. UtlHashMap hash_map; // Process the string elements. const char* string_elements[] = { "callid", "uri", "contact", "qvalue", "instance_id", "gruu", "path", "primary", }; for (unsigned int i = 0; i < sizeof (string_elements) / sizeof (string_elements[0]); i++) { sprintf(msg, "Data file '%s', <item> number %d, element <%s>", filename, item_no, string_elements[i]); // Get the element. TiXmlNode* element = item_element->FirstChild(string_elements[i]); CPPUNIT_ASSERT_MESSAGE(msg, element != NULL); UtlString* value = new UtlString; textContentShallow(*value, element->ToElement()); // Insert it into the hash map. hash_map.insertKeyAndValue(new UtlString(string_elements[i]), value); // From the <uri> value, derive the <identity> value. if (strcmp(string_elements[i], "uri") == 0) { // Parse the <uri> value as a name-addr. Url url(value->data(), FALSE); // Remove any parameters. url.removeParameters(); // Extract the URI proper. UtlString* identity = new UtlString; url.getUri(*identity); // Insert it into the hash map. hash_map.insertKeyAndValue(new UtlString("identity"), value); } } // Process the <cseq> element, which is a UtlInt. { sprintf(msg, "Data file '%s', <item> number %d, element <cseq>", filename, item_no); // Get the element. TiXmlNode* element = item_element->FirstChild("cseq"); CPPUNIT_ASSERT_MESSAGE(msg, element != NULL); UtlString s; textContentShallow(s, element->ToElement()); CPPUNIT_ASSERT_MESSAGE(msg, !s.isNull()); // Convert the value to a UtlInt. char* endptr; int i = strtol(s.data(), &endptr, 10); CPPUNIT_ASSERT_MESSAGE(msg, *endptr == '\0'); UtlInt* value = new UtlInt(i); // Insert it into the hash map. hash_map.insertKeyAndValue(new UtlString("cseq"), value); } // Process the <expires> element, which is a UtlInt, and has the // offset added to it. { sprintf(msg, "Data file '%s', <item> number %d, element <expires>", filename, item_no); // Get the element. TiXmlNode* element = item_element->FirstChild("expires"); CPPUNIT_ASSERT_MESSAGE(msg, element != NULL); UtlString s; textContentShallow(s, element->ToElement()); CPPUNIT_ASSERT_MESSAGE(msg, !s.isNull()); // Convert the value to a UtlInt. char* endptr; int i = strtol(s.data(), &endptr, 10); CPPUNIT_ASSERT_MESSAGE(msg, *endptr == '\0'); UtlInt* value = new UtlInt(i + timeOffset); // Insert it into the hash map. hash_map.insertKeyAndValue(new UtlString("expires"), value); } // Process the <update_number> element, which is a UtlLongLongInt. { sprintf(msg, "Data file '%s', <item> number %d, element <update_number>", filename, item_no); // Get the element. TiXmlNode* element = item_element->FirstChild("update_number"); CPPUNIT_ASSERT_MESSAGE(msg, element != NULL); UtlString s; textContentShallow(s, element->ToElement()); CPPUNIT_ASSERT_MESSAGE(msg, !s.isNull()); // Convert the value to a UtlInt. char* endptr; Int64 i = strtoll(s.data(), &endptr, 10); CPPUNIT_ASSERT_MESSAGE(msg, *endptr == '\0'); UtlLongLongInt* value = new UtlLongLongInt(i); // Insert it into the hash map. hash_map.insertKeyAndValue(new UtlString("update_number"), value); } // Construct the RegistrationBinding object. RegistrationBinding* binding = new RegistrationBinding(hash_map); // Add it to the updates list. updates.append(binding); } }
void PluginHooks::readConfig(OsConfigDb& configDb) { OsSysLog::add(FAC_KERNEL, PRI_DEBUG, "PluginHooks::readConfig" ); // Move any existing hooks from the current configured list to // a temporary holding list. UtlSList existingHooks; UtlContainable* existingHook; UtlSortedListIterator nextHook(mConfiguredHooks); while (existingHook = nextHook()) { existingHooks.append(mConfiguredHooks.removeReference(existingHook)); } // the mConfiguredHooks list is now empty // Walk the current configuration, // any existing hook is moved back to the mConfiguredHooks list, // newly configured hooks are added, // each configured hook is called to read its own configuration. UtlString hookPrefix(mPrefix); hookPrefix.append(HOOK_LIB_PREFIX); OsConfigDb allHooks; OsSysLog::add(FAC_KERNEL, PRI_DEBUG, "PluginHooks::readConfig looking up hooks '%s'", hookPrefix.data() ); if (OS_SUCCESS == configDb.getSubHash(hookPrefix, allHooks)) // any hooks configured for prefix? { UtlString lastHook; UtlString hookName; UtlString hookLibrary; // walk each hook and attempt to load and configure it for ( lastHook = ""; OS_SUCCESS == allHooks.getNext(lastHook, hookName, hookLibrary); lastHook = hookName ) { ConfiguredHook* thisHook; if (NULL == (thisHook = dynamic_cast<ConfiguredHook*>(existingHooks.remove(&hookName)))) { // not an existing hook, so create a new one OsSysLog::add(FAC_KERNEL, PRI_DEBUG, "PluginHooks: loading '%s'", hookName.data() ); thisHook = new ConfiguredHook(hookName, mFactory, hookLibrary); } // put the hook onto the list of active hooks mConfiguredHooks.insert(thisHook); // (re)configure the hook thisHook->readConfig(mPrefix, configDb); } } else { OsSysLog::add(FAC_KERNEL, PRI_INFO, "PluginHooks: no '%s' hooks configured", mPrefix.data() ); } // discard any hooks that are no longer in the configuration existingHooks.destroyAll(); }
/// Send any updates that we can. int RegistrarSync::handleMessage(OsMsg& eventMessage) { UtlBoolean handled = FALSE; OsSysLog::add(FAC_SIP, PRI_DEBUG, "RegistrarSync::handleMessage started"); if (SyncMsg::RegistrationChange == eventMessage.getMsgType()) { /* * Loop over all peers, pushing a single update to each peer. Keep going until * we get through the loop without pushing to any peer or we are asked to shut down. * * On some invocations, this loop will do the 'normal' thing and push the one change * to each peer, but this is not the only possibility. The change may already have * been sent by a pullUpdates from the peer, or by some earlier call to this routine, * or it may fail and need to be sent by a subsequent push attempt. * * Failure to push to a peer marks that peer as UnReachable, which prevents this * loop from further attempts to that peer, and also triggers the RegistrarTest * task to begin polling for when it comes back. */ bool pushedUpdate = true; while (pushedUpdate && !isShuttingDown()) { pushedUpdate = false; // For each Reachable peer, if the local DbUpdateNumber is greater than the // PeerSentDbUpdateNumber, then push a single update. auto_ptr<UtlSListIterator> peers(mRegistrar.getPeers()); RegistrarPeer* peer; while ( (peer = static_cast<RegistrarPeer*>((*peers)())) && !isShuttingDown() ) { if (peer->isReachable()) { UtlSList bindings; bool isUpdateToSend = getRegistrarServer().getNextUpdateToSend(peer, bindings); if (isUpdateToSend) { OsSysLog::add(FAC_SIP, PRI_DEBUG, "RegistrarSync::handleMessage " "attempting to push an update to peer '%s'", peer->name() ); // :LATER: move updating of PeerSentDbUpdateNumber out of // SyncRpcPushUpdates::invoke and into RegistrarSync? SyncRpcPushUpdates::invoke(peer, mRegistrar.primaryName(), &bindings); if (peer->isReachable() /* will not be true if the pushUpdate failed */ ) { pushedUpdate = true; } bindings.destroyAll(); } } } } handled = TRUE; } else { // let the base class handle any other event - should be just the shutdown request. } OsSysLog::add(FAC_SIP, PRI_DEBUG, "RegistrarSync::handleMessage finished"); return handled; }
void testUpdateNewBinding() { Url uri; UtlString contact; UtlSList bindings; RegistrationBinding* binding; RegistrationBinding newBinding; RegistrationDbTestContext testDbContext(TEST_DATA_DIR "/regdbdata", TEST_WORK_DIR "/regdbdata" ); testDbContext.inputFile("updateBindings.xml"); RegistrationDB* regDb = RegistrationDB::getInstance(); // Make sure an existing binding doesn't exist Int64 seqOneUpdates = regDb->getNewUpdatesForRegistrar("seqOne", 3, bindings); CPPUNIT_ASSERT_EQUAL(0LL, seqOneUpdates); // Create new binding with update number 3 uri.setUserId("300"); uri.setHostAddress("testdomain.example.com"); newBinding.setUri(uri); newBinding.setContact("sip:[email protected]"); newBinding.setCallId("ID3"); newBinding.setPrimary("seqOne"); newBinding.setUpdateNumber(3); // Add new binding regDb->updateBinding(newBinding); bindings.destroyAll(); // We should now have two bindings - the original with update number 2 and the new one seqOneUpdates = regDb->getNewUpdatesForRegistrar("seqOne", 2, bindings); CPPUNIT_ASSERT_EQUAL(2LL, seqOneUpdates); // Test if the registration data corresponds to what we expect UtlBoolean bSeenId2 = FALSE; UtlBoolean bSeenId3 = FALSE; UtlBoolean bSeenAnythingElse = FALSE; UtlSListIterator iterator(bindings); while ((binding = (RegistrationBinding*)iterator())) { const UtlString *s = binding->getCallId(); if (s->compareTo("ID2") == 0) { bSeenId2 = TRUE; CPPUNIT_ASSERT_EQUAL(binding->getContact()->compareTo("sip:[email protected]"), 0); CPPUNIT_ASSERT_EQUAL(binding->getUri()->toString().compareTo("sip:[email protected]"), 0); } else if (s->compareTo("ID3") == 0) { bSeenId3 = TRUE; CPPUNIT_ASSERT_EQUAL(binding->getContact()->compareTo("sip:[email protected]"), 0); CPPUNIT_ASSERT_EQUAL(binding->getUri()->toString().compareTo("sip:[email protected]"), 0); CPPUNIT_ASSERT_EQUAL(binding->getUpdateNumber(), 3LL); } else { bSeenAnythingElse = TRUE; } } CPPUNIT_ASSERT(!bSeenAnythingElse); CPPUNIT_ASSERT(bSeenId2); CPPUNIT_ASSERT(bSeenId3); }
void fileExecute(const char* inputFile, bool bSingleStep) { FILE *fp; char szBuffer[128]; char* token; int line = 0; if ((fp=fopen(inputFile, "r")) != NULL) { do { rewind(fp); while (fgets(szBuffer, 128, fp) != NULL) { ++line; if (szBuffer[0] != 0) { printf("Executing %s", szBuffer); } token = strtok(szBuffer, " "); if (token == NULL) { break; } if (strcasecmp(token, "version") == 0) { token = strtok(NULL, " "); if (token == NULL) { fileError(1, line); } else { Url url(token); token = strtok(NULL, " "); if (token == NULL) { fileError(2, line); } else { DataSet = token; requestVersion(url); } } } else if (strcasecmp(token, "get") == 0) { token = strtok(NULL, " "); if (token == NULL) { fileError(1, line); } else { Url url(token); token = strtok(NULL, " "); if (token == NULL) { fileError(2, line); } else { DataSet = token; UtlSList names; while (token != NULL) { token = strtok(NULL, " "); if (token != NULL) { names.append(new UtlString(token)); } } requestGet(url, names); names.destroyAll(); } } } else if (strcasecmp(token, "set") == 0) { token = strtok(NULL, " "); if (token == NULL) { fileError(1, line); } else { Url url(token); token = strtok(NULL, " "); if (token == NULL) { fileError(2, line); } else { DataSet = token; UtlHashMap parameters; char *key; char *value; while (token != NULL) { key = strtok(NULL, " "); if (key == NULL) { break; } value = strtok(NULL, " "); if (value == NULL) { fileError(3, line); break; } parameters.insertKeyAndValue(new UtlString(key), new UtlString(value)); } int entries = parameters.entries(); if (entries != 0 || (entries%2) == 0) { requestSet(url, parameters); parameters.destroyAll(); } } } } else if (strcasecmp(token, "delete") == 0) { token = strtok(NULL, " "); if (token == NULL) { fileError(1, line); } else { Url url(token); token = strtok(NULL, " "); if (token == NULL) { fileError(2, line); } else { DataSet = token; UtlSList names; while (token != NULL) { token = strtok(NULL, " "); if (token != NULL) { names.append(new UtlString(token)); } } requestDelete(url, names); names.destroyAll(); } } } else { fprintf(stderr, "Unknown RPC request %s - ignoring line\n", token); } if (bSingleStep) { getchar(); } } } while ( bRepeatFile ); fclose(fp); } else { fprintf(stderr, "Can't open %s\n", inputFile); exit(1); } }