LONGBOW_TEST_CASE(Global, athenaFIB_RemoveLink) { TestData *data = longBowTestCase_GetClipBoardData(testCase); athenaFIB_AddRoute(data->testFIB, data->testName1, data->testVector1); athenaFIB_AddRoute(data->testFIB, data->testName2, data->testVector2); PARCBitVector *result = athenaFIB_Lookup(data->testFIB, data->testName1, NULL); assertTrue(parcBitVector_Equals(result, data->testVector1), "Expected lookup to equal test vector"); parcBitVector_Release(&result); result = athenaFIB_Lookup(data->testFIB, data->testName2, NULL); assertTrue(parcBitVector_Equals(result, data->testVector2), "Expected lookup to equal test vector"); parcBitVector_Release(&result); athenaFIB_RemoveLink(data->testFIB, data->testVector1); result = athenaFIB_Lookup(data->testFIB, data->testName1, NULL); assertNull(result, "Expecting a NULL result from Lookup after Delete Route"); result = athenaFIB_Lookup(data->testFIB, data->testName2, NULL); assertTrue(parcBitVector_Equals(result, data->testVector2), "Expected lookup to equal test vector"); parcBitVector_Release(&result); athenaFIB_AddRoute(data->testFIB, data->testName1, data->testVector12); athenaFIB_RemoveLink(data->testFIB, data->testVector2); result = athenaFIB_Lookup(data->testFIB, data->testName2, NULL); assertNull(result, "Expecting a NULL result from Lookup after Delete Route"); result = athenaFIB_Lookup(data->testFIB, data->testName1, NULL); assertTrue(parcBitVector_Equals(result, data->testVector1), "Expected lookup to equal test vector"); parcBitVector_Release(&result); }
LONGBOW_TEST_CASE(Global, athenaFIB_Lookup_EmptyPath) { TestData *data = longBowTestCase_GetClipBoardData(testCase); athenaFIB_AddRoute(data->testFIB, data->testName3, data->testVector1); PARCBitVector *result = athenaFIB_Lookup(data->testFIB, data->testName3, NULL); assertNotNull(result, "Expect non-null match to global path (\"/\")"); assertTrue(parcBitVector_Equals(result, data->testVector1), "Expected lookup to equal test vector"); parcBitVector_Release(&result); result = athenaFIB_Lookup(data->testFIB, data->testName1, NULL); assertNotNull(result, "Expect non-null match to global path (\"/\")"); assertTrue(parcBitVector_Equals(result, data->testVector1), "Expected lookup to equal test vector"); parcBitVector_Release(&result); result = athenaFIB_Lookup(data->testFIB, data->testName2, NULL); assertNotNull(result, "Expect non-null match to global path (\"/\")"); assertTrue(parcBitVector_Equals(result, data->testVector1), "Expected lookup to equal test vector"); parcBitVector_Release(&result); athenaFIB_AddRoute(data->testFIB, data->testName3, data->testVector2); result = athenaFIB_Lookup(data->testFIB, data->testName3, NULL); assertNotNull(result, "Expect non-null match to global path (\"/\")"); assertTrue(parcBitVector_Equals(result, data->testVector12), "Expected lookup to equal test vector"); parcBitVector_Release(&result); result = athenaFIB_Lookup(data->testFIB, data->testName1, NULL); assertNotNull(result, "Expect non-null match to global path (\"/\")"); assertTrue(parcBitVector_Equals(result, data->testVector12), "Expected lookup to equal test vector"); parcBitVector_Release(&result); result = athenaFIB_Lookup(data->testFIB, data->testName2, NULL); assertNotNull(result, "Expect non-null match to global path (\"/\")"); assertTrue(parcBitVector_Equals(result, data->testVector12), "Expected lookup to equal test vector"); parcBitVector_Release(&result); }
LONGBOW_TEST_CASE(Global, athenaFIB_CreateEntryList) { TestData *data = longBowTestCase_GetClipBoardData(testCase); athenaFIB_AddRoute(data->testFIB, data->testName1, data->testVector12); PARCBitVector *result = athenaFIB_Lookup(data->testFIB, data->testName1, NULL); assertTrue(parcBitVector_Equals(result, data->testVector12), "Expected lookup to equal test vector"); parcBitVector_Release(&result); PARCList *entryList = athenaFIB_CreateEntryList(data->testFIB); assertTrue(parcList_Size(entryList) == 2, "Expected the EntryList to have 2 elements"); AthenaFIBListEntry *entry = parcList_GetAtIndex(entryList, 0); assertNotNull(entry, "Expect entry at 0 to be non-NULL"); assertTrue(ccnxName_Equals(data->testName1, entry->name), "Expect the name at 0 to be testName1"); assertTrue(entry->linkId == 0, "Expect the routeId at 0 to be 0"); entry = parcList_GetAtIndex(entryList, 1); assertNotNull(entry, "Expect entry at 1 to be non-NULL"); assertTrue(ccnxName_Equals(data->testName1, entry->name), "Expect the name at 1 to be testName1"); assertTrue(entry->linkId == 42, "Expect the routeId at 0 to be 42"); parcList_Release(&entryList); }
LONGBOW_TEST_CASE(Global, athenaFIB_Lookup) { TestData *data = longBowTestCase_GetClipBoardData(testCase); athenaFIB_AddRoute(data->testFIB, data->testName1, data->testVector1); PARCBitVector *result = athenaFIB_Lookup(data->testFIB, data->testName1, NULL); assertTrue(parcBitVector_Equals(result, data->testVector1), "Expected lookup to equal test vector"); parcBitVector_Release(&result); // // Name3 (the default route) contains both vector1 and vector2. // Name1 (a/b/c) contains only vector 1. // Name4 (a/b/c/d) is what we're looking for. // Although Name1 is a match for Name4, it only contains the ingress vector1. // We must the search until we match the default route. Ingress vector1 // must be removed from the returned vector list from the default route. // // Make sure we see only vector2 in the result. // athenaFIB_AddRoute(data->testFIB, data->testName3, data->testVector12); result = athenaFIB_Lookup(data->testFIB, data->testName4, data->testVector1); assertTrue(parcBitVector_Equals(result, data->testVector2), "Expected lookup to equal test vector"); parcBitVector_Release(&result); }
static CCNxMetaMessage * _FIB_Command(Athena *athena, CCNxInterest *interest, PARCBitVector *ingress) { CCNxMetaMessage *responseMessage; responseMessage = athenaFIB_ProcessMessage(athena->athenaFIB, interest); if (responseMessage) { return responseMessage; } CCNxName *ccnxName = ccnxInterest_GetName(interest); if (ccnxName_GetSegmentCount(ccnxName) > AthenaCommandSegment) { CCNxNameSegment *nameSegment = ccnxName_GetSegment(ccnxName, AthenaCommandSegment); char *command = ccnxNameSegment_ToString(nameSegment); if ((strcasecmp(command, AthenaCommand_Add) == 0) || (strcasecmp(command, AthenaCommand_Remove) == 0)) { char *arguments = _get_arguments(interest); if (arguments == NULL) { responseMessage = _create_response(athena, ccnxName, "No link or prefix arguments given to %s route command", command); parcMemory_Deallocate(&command); return responseMessage; } char linkName[MAXPATHLEN]; char prefix[MAXPATHLEN]; PARCBitVector *linkVector; // {Add,Remove} Route arguments "<prefix> [<linkName>]", if linkName not specified, use the incoming link id ([de-]registration) int numberOfArguments = sscanf(arguments, "%s %s", prefix, linkName); if (numberOfArguments == 2) { int linkId = athenaTransportLinkAdapter_LinkNameToId(athena->athenaTransportLinkAdapter, linkName); if (linkId == -1) { responseMessage = _create_response(athena, ccnxName, "Unknown linkName %s", linkName); parcMemory_Deallocate(&command); parcMemory_Deallocate(&arguments); return responseMessage; } linkVector = parcBitVector_Create(); parcBitVector_Set(linkVector, linkId); } else if (numberOfArguments == 1) { // use ingress link linkVector = parcBitVector_Acquire(ingress); } else { responseMessage = _create_response(athena, ccnxName, "No prefix specified or too many arguments"); parcMemory_Deallocate(&command); parcMemory_Deallocate(&arguments); return responseMessage; } CCNxName *prefixName = ccnxName_CreateFromCString(prefix); if (prefixName == NULL) { responseMessage = _create_response(athena, ccnxName, "Unable to parse prefix %s", prefix); parcMemory_Deallocate(&command); parcMemory_Deallocate(&arguments); parcBitVector_Release(&linkVector); return responseMessage; } int result = false; if (strcasecmp(command, AthenaCommand_Add) == 0) { result = athenaFIB_AddRoute(athena->athenaFIB, prefixName, linkVector); } else if (strcasecmp(command, AthenaCommand_Remove) == 0) { result = athenaFIB_DeleteRoute(athena->athenaFIB, prefixName, linkVector); } if (result == true) { char *routePrefix = ccnxName_ToString(prefixName); const char *linkIdName = athenaTransportLinkAdapter_LinkIdToName(athena->athenaTransportLinkAdapter, parcBitVector_NextBitSet(linkVector, 0)); responseMessage = _create_response(athena, ccnxName, "%s route %s -> %s", command, routePrefix, linkIdName); athenaInterestControl_LogConfigurationChange(athena, ccnxName, "%s %s", routePrefix, linkIdName); parcMemory_Deallocate(&routePrefix); } else { responseMessage = _create_response(athena, ccnxName, "%s failed", command); } parcBitVector_Release(&linkVector); ccnxName_Release(&prefixName); parcMemory_Deallocate(&arguments); } else if (strcasecmp(command, AthenaCommand_List) == 0) { // Need to create the response here because as the FIB doesn't know the linkName parcLog_Debug(athena->log, "FIB List command invoked"); PARCList *fibEntries = athenaFIB_CreateEntryList(athena->athenaFIB); responseMessage = _create_FIBList_response(athena, ccnxName, fibEntries); parcList_Release(&fibEntries); } else { responseMessage = _create_response(athena, ccnxName, "Unknown command: %s", command); } parcMemory_Deallocate(&command); } return responseMessage; }
LONGBOW_TEST_CASE(Global, athenaFIB_AddRoute) { TestData *data = longBowTestCase_GetClipBoardData(testCase); athenaFIB_AddRoute(data->testFIB, data->testName1, data->testVector1); }
LONGBOW_TEST_CASE(Global, athena_ProcessInterest) { PARCURI *connectionURI; Athena *athena = athena_Create(100); CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar/baz"); CCNxInterest *interest = ccnxInterest_CreateSimple(name); uint64_t chunkNum = 0; CCNxNameSegment *chunkSegment = ccnxNameSegmentNumber_Create(CCNxNameLabelType_CHUNK, chunkNum); ccnxName_Append(name, chunkSegment); ccnxNameSegment_Release(&chunkSegment); PARCBuffer *payload = parcBuffer_WrapCString("this is a payload"); CCNxContentObject *contentObject = ccnxContentObject_CreateWithNameAndPayload(name, payload); parcBuffer_Release(&payload); struct timeval tv; gettimeofday(&tv, NULL); uint64_t nowInMillis = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); ccnxContentObject_SetExpiryTime(contentObject, nowInMillis + 100000); // expire in 100 seconds connectionURI = parcURI_Parse("tcp://localhost:50100/listener/name=TCPListener"); const char *result = athenaTransportLinkAdapter_Open(athena->athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed(%s)", strerror(errno)); parcURI_Release(&connectionURI); connectionURI = parcURI_Parse("tcp://localhost:50100/name=TCP_0/local=false"); result = athenaTransportLinkAdapter_Open(athena->athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); connectionURI = parcURI_Parse("tcp://localhost:50100/name=TCP_1/local=false"); result = athenaTransportLinkAdapter_Open(athena->athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); int linkId = athenaTransportLinkAdapter_LinkNameToId(athena->athenaTransportLinkAdapter, "TCP_0"); PARCBitVector *interestIngressVector = parcBitVector_Create(); parcBitVector_Set(interestIngressVector, linkId); linkId = athenaTransportLinkAdapter_LinkNameToId(athena->athenaTransportLinkAdapter, "TCP_1"); PARCBitVector *contentObjectIngressVector = parcBitVector_Create(); parcBitVector_Set(contentObjectIngressVector, linkId); athena_EncodeMessage(interest); athena_EncodeMessage(contentObject); // Before FIB entry interest should not be forwarded athena_ProcessMessage(athena, interest, interestIngressVector); // Add route for interest, it should now be forwarded athenaFIB_AddRoute(athena->athenaFIB, name, contentObjectIngressVector); CCNxName *defaultName = ccnxName_CreateFromCString("lci:/"); athenaFIB_AddRoute(athena->athenaFIB, defaultName, contentObjectIngressVector); ccnxName_Release(&defaultName); // Process exact interest match athena_ProcessMessage(athena, interest, interestIngressVector); // Process a super-interest match CCNxName *superName = ccnxName_CreateFromCString("lci:/foo/bar/baz/unmatched"); CCNxInterest *superInterest = ccnxInterest_CreateSimple(superName); athena_EncodeMessage(superInterest); athena_ProcessMessage(athena, superInterest, interestIngressVector); ccnxName_Release(&superName); ccnxInterest_Release(&superInterest); // Process no-match/default route interest CCNxName *noMatchName = ccnxName_CreateFromCString("lci:/buggs/bunny"); CCNxInterest *noMatchInterest = ccnxInterest_CreateSimple(noMatchName); athena_EncodeMessage(noMatchInterest); athena_ProcessMessage(athena, noMatchInterest, interestIngressVector); ccnxName_Release(&noMatchName); ccnxInterest_Release(&noMatchInterest); // Create a matching content object that the store should retain and reply to the following interest with athena_ProcessMessage(athena, contentObject, contentObjectIngressVector); athena_ProcessMessage(athena, interest, interestIngressVector); parcBitVector_Release(&interestIngressVector); parcBitVector_Release(&contentObjectIngressVector); ccnxName_Release(&name); ccnxInterest_Release(&interest); ccnxInterest_Release(&contentObject); athena_Release(&athena); }