// // // Copyright (C) 2006 SIPez LLC. // Licensed to SIPfoundry under a Contributor Agreement. // // Copyright (C) 2006 SIPfoundry Inc. // License by SIPfoundry under the LGPL license. // // Copyright (C) 2006 Pingtel Corp. // Licensed to SIPfoundry under a Contributor Agreement. // // $$ ////////////////////////////////////////////////////////////////////////////// // SYSTEM INCLUDES // APPLICATION INCLUDES #include #include #include #include "utl/UtlSList.h" #include "utl/UtlSListIterator.h" #include "net/Url.h" #include "os/OsDateTime.h" #include "sipdb/RegistrationDB.h" #include "sipdb/RegistrationBinding.h" #include "sipdb/ResultSet.h" #include "testlib/RegistrationDbTestContext.h" //#include "sipdb/SIPDBManager.h" // DEFINES // CONSTANTS // TYPEDEFS // FORWARD DECLARATIONS class RegistryDbTest : public CppUnit::TestCase { CPPUNIT_TEST_SUITE(RegistryDbTest); CPPUNIT_TEST(testIsOutOfSequence); CPPUNIT_TEST(testGetMaxUpdateNumberForRegistrar); CPPUNIT_TEST(testGetNextUpdateNumberForRegistrar); CPPUNIT_TEST(testGetNextUpdateForRegistrar); CPPUNIT_TEST(testGetNewUpdatesForRegistrar); CPPUNIT_TEST(testGetUnexpiredContacts); CPPUNIT_TEST(testUpdateExistingBinding); CPPUNIT_TEST(testUpdateNewBinding); CPPUNIT_TEST(testUpdateSameBinding); CPPUNIT_TEST(testUpdateExistingUriNewContact); CPPUNIT_TEST(testExpireAllBindings); CPPUNIT_TEST(testExpireOldBindings); //CPPUNIT_TEST(testCleanAndPersist); CPPUNIT_TEST_SUITE_END(); public: void tearDown() { RegistrationDB::getInstance()->releaseInstance(); } void testGetMaxUpdateNumberForRegistrar() { RegistrationDbTestContext testDbContext(TEST_DATA_DIR "/regdbdata", TEST_WORK_DIR "/regdbdata" ); testDbContext.inputFile("getMaxUpdate.xml"); RegistrationDB* regDb = RegistrationDB::getInstance(); INT64 seqOneMax = regDb->getMaxUpdateNumberForRegistrar("seqOne"); CPPUNIT_ASSERT_EQUAL(5LL, seqOneMax); // Get maximum number for the other registrar INT64 seqTwoMax = regDb->getMaxUpdateNumberForRegistrar("seqTwo"); CPPUNIT_ASSERT_EQUAL(7LL, seqTwoMax); // Pass in unknown registrar INT64 seqThreeMax = regDb->getMaxUpdateNumberForRegistrar("seqThree"); CPPUNIT_ASSERT_EQUAL(0LL, seqThreeMax); } void testGetNextUpdateNumberForRegistrar() { RegistrationDbTestContext testDbContext(TEST_DATA_DIR "/regdbdata", TEST_WORK_DIR "/regdbdata" ); testDbContext.inputFile("getMaxUpdate.xml"); RegistrationDB* regDb = RegistrationDB::getInstance(); INT64 seqOneNext = regDb->getNextUpdateNumberForRegistrar("seqOne", 0LL); CPPUNIT_ASSERT_EQUAL(1LL, seqOneNext); seqOneNext = regDb->getNextUpdateNumberForRegistrar("seqOne", 1LL); CPPUNIT_ASSERT_EQUAL(2LL, seqOneNext); seqOneNext = regDb->getNextUpdateNumberForRegistrar("seqOne", 2LL); CPPUNIT_ASSERT_EQUAL(3LL, seqOneNext); seqOneNext = regDb->getNextUpdateNumberForRegistrar("seqOne", 3LL); CPPUNIT_ASSERT_EQUAL(5LL, seqOneNext); seqOneNext = regDb->getNextUpdateNumberForRegistrar("seqOne", 4LL); CPPUNIT_ASSERT_EQUAL(5LL, seqOneNext); seqOneNext = regDb->getNextUpdateNumberForRegistrar("seqOne", 5LL); CPPUNIT_ASSERT_EQUAL(0LL, seqOneNext); INT64 seqTwoNext = regDb->getNextUpdateNumberForRegistrar("seqTwo", 4); CPPUNIT_ASSERT_EQUAL(7LL, seqTwoNext); // Pass in unknown registrar INT64 seqThreeNext = regDb->getNextUpdateNumberForRegistrar("seqThree", 1); CPPUNIT_ASSERT_EQUAL(0LL, seqThreeNext); } 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:300@10.1.1.20"), 0); CPPUNIT_ASSERT_EQUAL(binding->getUri()->toString().compareTo("sip:300@testdomain.example.com"), 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:800@10.1.1.20"), 0); CPPUNIT_ASSERT_EQUAL(binding->getUri()->toString().compareTo("sip:800@testdomain.example.com"), 0); CPPUNIT_ASSERT_EQUAL(800, binding->getCseq()); } void testGetNewUpdatesForRegistrar() { UtlSList bindings; RegistrationDbTestContext testDbContext(TEST_DATA_DIR "/regdbdata", TEST_WORK_DIR "/regdbdata" ); testDbContext.inputFile("getMaxUpdate.xml"); RegistrationDB* regDb = RegistrationDB::getInstance(); INT64 seqOneUpdates = regDb->getNewUpdatesForRegistrar("seqOne", 2, bindings); CPPUNIT_ASSERT_EQUAL(2LL, seqOneUpdates); UtlSListIterator iterator(bindings); // Loop through all returned bindings and mark the ones we've seen. // Also check correctness of bindings UtlBoolean bSeenId3 = FALSE; UtlBoolean bSeenId5 = FALSE; UtlBoolean bSeenAnythingElse = FALSE; RegistrationBinding *binding; while ((binding = (RegistrationBinding*)iterator())) { const UtlString *s = binding->getCallId(); if (s->compareTo("ID3") == 0) { bSeenId3 = TRUE; CPPUNIT_ASSERT_EQUAL(binding->getContact()->compareTo("sip:300@10.1.1.20"), 0); CPPUNIT_ASSERT_EQUAL(binding->getUri()->toString().compareTo("sip:300@testdomain.example.com"), 0); CPPUNIT_ASSERT_EQUAL(300, binding->getCseq()); } else if (s->compareTo("ID5") == 0) { bSeenId5 = TRUE; CPPUNIT_ASSERT_EQUAL(binding->getContact()->compareTo("sip:500@10.1.1.20"), 0); CPPUNIT_ASSERT_EQUAL(binding->getUri()->toString().compareTo("sip:500@testdomain.example.com"), 0); CPPUNIT_ASSERT_EQUAL(500, binding->getCseq()); } else { bSeenAnythingElse = TRUE; } } CPPUNIT_ASSERT(!bSeenAnythingElse); CPPUNIT_ASSERT(bSeenId3); CPPUNIT_ASSERT(bSeenId5); 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:800@10.1.1.20"), 0); CPPUNIT_ASSERT_EQUAL(binding->getUri()->toString().compareTo("sip:800@testdomain.example.com"), 0); CPPUNIT_ASSERT_EQUAL(800, binding->getCseq()); } void testGetUnexpiredContacts() { Url uri; ResultSet results; UtlHashMap record1; UtlHashMap record2; int timeNow = OsDateTime::getSecsSinceEpoch(); RegistrationDbTestContext testDbContext(TEST_DATA_DIR "/regdbdata", TEST_WORK_DIR "/regdbdata" ); testDbContext.inputFile("getUnexpiredContacts.xml"); RegistrationDB* regDb = RegistrationDB::getInstance(); uri.setUserId("900"); uri.setHostAddress("testdomain.example.com"); regDb->getUnexpiredContacts(uri, timeNow, results); int numResults = results.getSize(); CPPUNIT_ASSERT_EQUAL(2, numResults); if (numResults == 2) { // Get first record results.getIndex(0, record1); UtlString* value = (UtlString*)record1.findValue(&RegistrationDB::gContactKey); CPPUNIT_ASSERT_EQUAL(value->compareTo("sip:900@10.1.1.20"), 0); value = (UtlString*)record1.findValue(&RegistrationDB::gUriKey); CPPUNIT_ASSERT_EQUAL(value->compareTo("sip:900@testdomain.example.com"), 0); // Get second record results.getIndex(1, record2); value = (UtlString*)record2.findValue(&RegistrationDB::gContactKey); CPPUNIT_ASSERT_EQUAL(value->compareTo("sip:900@10.1.1.21"), 0); value = (UtlString*)record2.findValue(&RegistrationDB::gUriKey); CPPUNIT_ASSERT_EQUAL(value->compareTo("sip:900@testdomain.example.com"), 0); } } void testIsOutOfSequence() { Url uri; UtlString callId; RegistrationDbTestContext testDbContext(TEST_DATA_DIR "/regdbdata", TEST_WORK_DIR "/regdbdata" ); testDbContext.inputFile("getMaxUpdate.xml"); RegistrationDB* regDb = RegistrationDB::getInstance(); uri.setUserId("200"); uri.setHostAddress("testdomain.example.com"); callId = "ID2"; UtlBoolean bOutOfSequence = regDb->isOutOfSequence(uri, callId, 900); CPPUNIT_ASSERT(!bOutOfSequence); bOutOfSequence = regDb->isOutOfSequence(uri, callId, 200); CPPUNIT_ASSERT(bOutOfSequence); bOutOfSequence = regDb->isOutOfSequence(uri, callId, 0); CPPUNIT_ASSERT(bOutOfSequence); } 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()); } 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:300@10.1.1.20"); 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:200@10.1.1.20"), 0); CPPUNIT_ASSERT_EQUAL(binding->getUri()->toString().compareTo("sip:200@testdomain.example.com"), 0); } else if (s->compareTo("ID3") == 0) { bSeenId3 = TRUE; CPPUNIT_ASSERT_EQUAL(binding->getContact()->compareTo("sip:300@10.1.1.20"), 0); CPPUNIT_ASSERT_EQUAL(binding->getUri()->toString().compareTo("sip:300@testdomain.example.com"), 0); CPPUNIT_ASSERT_EQUAL(binding->getUpdateNumber(), 3LL); } else { bSeenAnythingElse = TRUE; } } CPPUNIT_ASSERT(!bSeenAnythingElse); CPPUNIT_ASSERT(bSeenId2); CPPUNIT_ASSERT(bSeenId3); } 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); } 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 testExpireAllBindings() { Url uri; UtlString contact; UtlSList bindings; ResultSet results; int timeNow = OsDateTime::getSecsSinceEpoch(); RegistrationDbTestContext testDbContext(TEST_DATA_DIR "/regdbdata", TEST_WORK_DIR "/regdbdata" ); testDbContext.inputFile("getUnexpiredContacts.xml"); RegistrationDB* regDb = RegistrationDB::getInstance(); uri.setUserId("900"); uri.setHostAddress("testdomain.example.com"); regDb->getUnexpiredContacts(uri, timeNow, results); int numResults = results.getSize(); CPPUNIT_ASSERT_EQUAL(2, numResults); results.destroyAll(); regDb->expireAllBindings(uri, "ID9", 900, timeNow, "seqOne", 7); regDb->getUnexpiredContacts(uri, timeNow, results); numResults = results.getSize(); CPPUNIT_ASSERT_EQUAL(0, numResults); } void testExpireOldBindings() { Url uri; //UtlString contact; //UtlSList bindings; ResultSet results; int timeNow = OsDateTime::getSecsSinceEpoch(); RegistrationDbTestContext testDbContext(TEST_DATA_DIR "/regdbdata", TEST_WORK_DIR "/regdbdata" ); testDbContext.inputFile("getUnexpiredContacts.xml"); RegistrationDB* regDb = RegistrationDB::getInstance(); uri.setUserId("900"); uri.setHostAddress("testdomain.example.com"); regDb->getUnexpiredContacts(uri, timeNow, results); int numResults = results.getSize(); CPPUNIT_ASSERT_EQUAL(2, numResults); results.destroyAll(); regDb->expireOldBindings(uri, "ID9", 900, timeNow, "seqOne", 7); regDb->getUnexpiredContacts(uri, timeNow, results); numResults = results.getSize(); CPPUNIT_ASSERT_EQUAL(1, numResults); } void testCleanAndPersist() { int timeNow = OsDateTime::getSecsSinceEpoch(); RegistrationDbTestContext testDbContext(TEST_DATA_DIR "/regdbdata", TEST_WORK_DIR "/regdbdata" ); testDbContext.inputFile("cleanAndPersist.xml"); RegistrationDB* regDb = RegistrationDB::getInstance(); regDb->cleanAndPersist(timeNow - 50); } }; CPPUNIT_TEST_SUITE_REGISTRATION(RegistryDbTest);