LONGBOW_TEST_CASE(Global, athena_ProcessControl) { PARCURI *connectionURI; Athena *athena = athena_Create(100); CCNxControl *control = ccnxControl_CreateFlushRequest(); 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"); 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 *ingressVector = parcBitVector_Create(); parcBitVector_Set(ingressVector, linkId); athena_ProcessMessage(athena, control, ingressVector); parcBitVector_Release(&ingressVector); ccnxInterest_Release(&control); athena_Release(&athena); }
LONGBOW_TEST_CASE(Global, parcBitVector_Set) { PARCBitVector *parcBitVector = parcBitVector_Create(); assertTrue(parcBitVector, "parcBitVector_Create returned a NULL pointer"); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 0, "parcBitVector_Create created a non-empty vector"); parcBitVector_Set(parcBitVector, 0); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 1, "Expect number of bits set to be 1"); assertTrue(parcBitVector->firstBitSet == 0, "Expect first bit set to be 0"); assertTrue(parcBitVector->bitLength == 8, "Expect the bitLength to be 8"); assertTrue(parcBitVector->bitArray[0] == (uint8_t) 1, "Expect the bitArray as a unsigned char to be = 1"); parcBitVector_Set(parcBitVector, 7); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 2, "Expect number of bits set to be 2"); assertTrue(parcBitVector->firstBitSet == 0, "Expect first bit set to be 0"); assertTrue(parcBitVector->bitLength == 8, "Expect the bitLength to be 8"); assertTrue(parcBitVector->bitArray[0] == (uint8_t) 0x81, "Expect the bitArray as a unsigned char to be = 0x81"); parcBitVector_Set(parcBitVector, 8); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 3, "Expect number of bits set to be 3"); assertTrue(parcBitVector->firstBitSet == 0, "Expect first bit set to be 0"); assertTrue(parcBitVector->bitLength == 16, "Expect the bitLength to be 16"); assertTrue(parcBitVector->bitArray[0] == (uint8_t) 0x81, "Expect the bitArray as a unsigned char to be = 0x81"); assertTrue(parcBitVector->bitArray[1] == (uint8_t) 0x1, "Expect the bitArray as a unsigned char to be = 0x1"); parcBitVector_Release(&parcBitVector); }
LONGBOW_TEST_CASE(Global, parcBitVector_NextBitSet) { PARCBitVector *parcBitVector = parcBitVector_Create(); assertTrue(parcBitVector, "parcBitVector_Create returned a NULL pointer"); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 0, "parcBitVector_Create created a non-empty vector"); int nextBit = parcBitVector_NextBitSet(parcBitVector, 0); assertTrue(nextBit == -1, "parcBitVector_NextBitSet should have failed (%d)", nextBit); parcBitVector_Set(parcBitVector, 10); nextBit = parcBitVector_NextBitSet(parcBitVector, 0); assertTrue(nextBit == 10, "parcBitVector_NextBitSet failed (%d)", nextBit); nextBit = parcBitVector_NextBitSet(parcBitVector, 20); assertTrue(nextBit == -1, "parcBitVector_NextBitSet read past end of vector (%d)", nextBit); nextBit = parcBitVector_NextBitSet(parcBitVector, 10); assertTrue(nextBit == 10, "parcBitVector_NextBitSet failed (%d)", nextBit); nextBit = parcBitVector_NextBitSet(parcBitVector, 11); assertTrue(nextBit == -1, "parcBitVector_NextBitSet should have failed (%d)", nextBit); parcBitVector_Set(parcBitVector, 20); nextBit = parcBitVector_NextBitSet(parcBitVector, 11); assertTrue(nextBit == 20, "parcBitVector_NextBitSet failed (%d)", nextBit); parcBitVector_Release(&parcBitVector); }
LONGBOW_TEST_CASE(Global, athena_ProcessControl_CPI_REGISTER_PREFIX) { PARCURI *connectionURI; Athena *athena = athena_Create(100); CCNxName *name = ccnxName_CreateFromCString("ccnx:/foo/bar"); CCNxControl *control = ccnxControl_CreateAddRouteToSelfRequest(name); // CPI_REGISTER_PREFIX CCNxMetaMessage *registerPrefixCommand = ccnxMetaMessage_CreateFromControl(control); ccnxControl_Release(&control); control = ccnxControl_CreateRemoveRouteToSelfRequest(name); // CPI_UNREGISTER_PREFIX CCNxMetaMessage *unregisterPrefixCommand = ccnxMetaMessage_CreateFromControl(control); ccnxControl_Release(&control); ccnxName_Release(&name); 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"); 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 *ingressVector = parcBitVector_Create(); parcBitVector_Set(ingressVector, linkId); // Call _Receive() once to prime the link. Messages are dropped until _Receive() is called once. PARCBitVector *linksRead = NULL; CCNxMetaMessage *msg = athenaTransportLinkAdapter_Receive(athena->athenaTransportLinkAdapter, &linksRead, -1); assertNull(msg, "Expected to NOT receive a message after the first call to _Receive()"); CCNxMetaMessage *cpiMessages[2]; cpiMessages[0] = registerPrefixCommand; // CPI_REGISTER_PREFIX cpiMessages[1] = unregisterPrefixCommand; // CPI_UNREGISTER_PREFIX for (int i = 0; i < 2; i++) { CCNxMetaMessage *cpiMessageToSend = cpiMessages[i]; athena_ProcessMessage(athena, cpiMessageToSend, ingressVector); ccnxMetaMessage_Release(&cpiMessageToSend); CCNxMetaMessage *ack = athenaTransportLinkAdapter_Receive(athena->athenaTransportLinkAdapter, &linksRead, -1); assertNotNull(ack, "Expected a CPI_ACK message back"); assertTrue(ccnxMetaMessage_IsControl(ack), "Expected a control message back"); parcBitVector_Release(&linksRead); PARCJSON *json = ccnxControl_GetJson(ack); const PARCJSONValue *cpiAckResult = parcJSON_GetByPath(json, "CPI_ACK/REQUEST/RESULT"); bool commandResult = parcJSONValue_GetBoolean(cpiAckResult); assertTrue(commandResult, "Expected the ACK to contain RESULT=true"); ccnxMetaMessage_Release(&ack); } parcBitVector_Release(&ingressVector); athena_Release(&athena); }
LONGBOW_TEST_CASE(Global, parcBitVector_Contains) { PARCBitVector *supersetVector = parcBitVector_Create(); parcBitVector_Set(supersetVector, 10); parcBitVector_Set(supersetVector, 11); PARCBitVector *testVector = parcBitVector_Create(); parcBitVector_Set(testVector, 10); assertTrue(parcBitVector_Contains(supersetVector, testVector), "Expect superset to contain testVector"); parcBitVector_Set(testVector, 12); assertFalse(parcBitVector_Contains(supersetVector, testVector), "Expect superset to not contain testVector"); parcBitVector_Release(&supersetVector); parcBitVector_Release(&testVector); }
LONGBOW_TEST_CASE(Global, athena_ForwarderEngine) { // Create a new athena instance Athena *newAthena = athena_Create(AthenaDefaultContentStoreSize); assertNotNull(newAthena, "Could not create a new Athena instance"); // Add a link PARCURI *connectionURI = parcURI_Parse("tcp://localhost:50100/listener"); const char *result = athenaTransportLinkAdapter_Open(newAthena->athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed\n"); parcURI_Release(&connectionURI); pthread_t thread; // Passing in a reference that will be released by the new thread as the thread may not // have time to acquire a reference itself before we release our reference. int ret = pthread_create(&thread, NULL, athena_ForwarderEngine, (void *) athena_Acquire(newAthena)); assertTrue(ret == 0, "pthread_create failed"); athena_Release(&newAthena); // Create a new local instance we can send a quit message from Athena *athena = athena_Create(AthenaDefaultContentStoreSize); assertNotNull(athena, "Could not create a new Athena instance"); connectionURI = parcURI_Parse("tcp://localhost:50100/name=TCP_1"); result = athenaTransportLinkAdapter_Open(athena->athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); PARCBitVector *linkVector = parcBitVector_Create(); int linkId = athenaTransportLinkAdapter_LinkNameToId(athena->athenaTransportLinkAdapter, "TCP_1"); parcBitVector_Set(linkVector, linkId); CCNxName *name = ccnxName_CreateFromCString(CCNxNameAthenaCommand_Quit); CCNxMetaMessage *interest = ccnxInterest_CreateSimple(name); ccnxName_Release(&name); athena_EncodeMessage(interest); PARCBitVector *resultVector = athenaTransportLinkAdapter_Send(athena->athenaTransportLinkAdapter, interest, linkVector); assertNull(resultVector, "athenaTransportLinkAdapter_Send failed"); ccnxMetaMessage_Release(&interest); parcBitVector_Release(&linkVector); CCNxMetaMessage *response = athenaTransportLinkAdapter_Receive(athena->athenaTransportLinkAdapter, &resultVector, -1); assertNotNull(resultVector, "athenaTransportLinkAdapter_Receive failed"); assertTrue(parcBitVector_NumberOfBitsSet(resultVector) > 0, "athenaTransportLinkAdapter_Receive failed"); parcBitVector_Release(&resultVector); ccnxMetaMessage_Release(&response); athenaTransportLinkAdapter_CloseByName(athena->athenaTransportLinkAdapter, "TCP_1"); pthread_join(thread, NULL); // Wait for the child athena to actually finish athena_Release(&athena); }
LONGBOW_TEST_CASE(Global, parcBitVector_Create_Release) { PARCBitVector *parcBitVector = parcBitVector_Create(); assertTrue(parcBitVector, "parcBitVector_Create returned a NULL pointer"); PARCBitVector *reference = parcBitVector; parcBitVector_Acquire(reference); parcBitVector_Release(&parcBitVector); parcBitVector_Release(&reference); }
LONGBOW_TEST_CASE(Global, athenaTransportLinkModuleUDP_SendReceive) { PARCURI *connectionURI; const char *result; AthenaTransportLinkAdapter *athenaTransportLinkAdapter = athenaTransportLinkAdapter_Create(_removeLink, NULL); assertNotNull(athenaTransportLinkAdapter, "athenaTransportLinkAdapter_Create returned NULL"); connectionURI = parcURI_Parse("udp://127.0.0.1:40000/Listener/name=UDPListener"); result = athenaTransportLinkAdapter_Open(athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); connectionURI = parcURI_Parse("udp://127.0.0.1:40000/name=UDP_1"); result = athenaTransportLinkAdapter_Open(athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); athenaTransportLinkAdapter_Poll(athenaTransportLinkAdapter, 0); CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar"); CCNxMetaMessage *ccnxMetaMessage = ccnxInterest_CreateSimple(name); ccnxName_Release(&name); PARCBitVector *sendVector = parcBitVector_Create(); int linkId = athenaTransportLinkAdapter_LinkNameToId(athenaTransportLinkAdapter, "UDP_1"); parcBitVector_Set(sendVector, linkId); athena_EncodeMessage(ccnxMetaMessage); PARCBitVector *resultVector; resultVector = athenaTransportLinkAdapter_Send(athenaTransportLinkAdapter, ccnxMetaMessage, sendVector); assertNotNull(resultVector, "athenaTransportLinkAdapter_Send failed"); parcBitVector_Release(&resultVector); ccnxMetaMessage_Release(&ccnxMetaMessage); parcBitVector_Release(&sendVector); usleep(1000); ccnxMetaMessage = athenaTransportLinkAdapter_Receive(athenaTransportLinkAdapter, &resultVector, 0); assertNotNull(resultVector, "athenaTransportLinkAdapter_Receive failed"); assertTrue(parcBitVector_NumberOfBitsSet(resultVector) == 1, "athenaTransportLinkAdapter_Receive return message with more than one ingress link"); assertNotNull(ccnxMetaMessage, "athenaTransportLinkAdapter_Receive failed to provide message"); parcBitVector_Release(&resultVector); ccnxMetaMessage_Release(&ccnxMetaMessage); // Close one end of the connection and send a message from the other. int closeResult = athenaTransportLinkAdapter_CloseByName(athenaTransportLinkAdapter, "UDPListener"); assertTrue(closeResult == 0, "athenaTransportLinkAdapter_CloseByName failed (%s)", strerror(errno)); ccnxMetaMessage = athenaTransportLinkAdapter_Receive(athenaTransportLinkAdapter, &resultVector, 1); assertNull(resultVector, "athenaTransportLinkAdapter_Receive should have failed"); closeResult = athenaTransportLinkAdapter_CloseByName(athenaTransportLinkAdapter, "UDP_1"); assertTrue(closeResult == 0, "athenaTransportLinkAdapter_CloseByName failed (%s)", strerror(errno)); athenaTransportLinkAdapter_Destroy(&athenaTransportLinkAdapter); }
LONGBOW_TEST_CASE(Global, athenaTransportLinkModuleUDP_MTU) { PARCURI *connectionURI; const char *result; AthenaTransportLinkAdapter *athenaTransportLinkAdapter = athenaTransportLinkAdapter_Create(_removeLink, NULL); assertNotNull(athenaTransportLinkAdapter, "athenaTransportLinkAdapter_Create returned NULL"); connectionURI = parcURI_Parse("udp://127.0.0.1:40000/Listener/name=UDPListener/mtu="); result = athenaTransportLinkAdapter_Open(athenaTransportLinkAdapter, connectionURI); assertTrue(result == NULL, "athenaTransportLinkAdapter_Open failed to detect improper MTU (%s)", strerror(errno)); parcURI_Release(&connectionURI); connectionURI = parcURI_Parse("udp://127.0.0.1:40000/Listener/name=UDPListener/mtu=20"); result = athenaTransportLinkAdapter_Open(athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); connectionURI = parcURI_Parse("udp://127.0.0.1:40000/name=UDP_1/mtu=20"); result = athenaTransportLinkAdapter_Open(athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); athenaTransportLinkAdapter_Poll(athenaTransportLinkAdapter, 0); CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar"); CCNxMetaMessage *ccnxMetaMessage = ccnxInterest_CreateSimple(name); ccnxName_Release(&name); PARCBitVector *sendVector = parcBitVector_Create(); int linkId = athenaTransportLinkAdapter_LinkNameToId(athenaTransportLinkAdapter, "UDP_1"); parcBitVector_Set(sendVector, linkId); athena_EncodeMessage(ccnxMetaMessage); PARCBitVector *resultVector; resultVector = athenaTransportLinkAdapter_Send(athenaTransportLinkAdapter, ccnxMetaMessage, sendVector); assertTrue(parcBitVector_NumberOfBitsSet(resultVector) == 0, "athenaTransportLinkAdapter_Send should have failed"); assertTrue(errno == EMSGSIZE, "athenaTransportLinkAdapter_Send should have failed with EMSGSIZE (%d): %s", errno, strerror(errno)); parcBitVector_Release(&resultVector); ccnxMetaMessage_Release(&ccnxMetaMessage); parcBitVector_Release(&sendVector); usleep(1000); ccnxMetaMessage = athenaTransportLinkAdapter_Receive(athenaTransportLinkAdapter, &resultVector, 0); assertNull(ccnxMetaMessage, "athenaTransportLinkAdapter_Receive should have failed"); int closeResult = athenaTransportLinkAdapter_CloseByName(athenaTransportLinkAdapter, "UDPListener"); assertTrue(closeResult == 0, "athenaTransportLinkAdapter_CloseByName failed (%s)", strerror(errno)); closeResult = athenaTransportLinkAdapter_CloseByName(athenaTransportLinkAdapter, "UDP_1"); assertTrue(closeResult == 0, "athenaTransportLinkAdapter_CloseByName failed (%s)", strerror(errno)); athenaTransportLinkAdapter_Destroy(&athenaTransportLinkAdapter); }
LONGBOW_TEST_CASE(Global, parcBitVector_SetVector) { PARCBitVector *parcBitVector = parcBitVector_Create(); assertTrue(parcBitVector, "parcBitVector_Create returned a NULL pointer"); PARCBitVector *setVector = parcBitVector_Create(); parcBitVector_Set(parcBitVector, 1); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 1, "parcBitVector_Set failed"); parcBitVector_Set(setVector, 20); parcBitVector_SetVector(parcBitVector, setVector); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 2, "parcBitVector_SetVector failed"); assertTrue(parcBitVector_NextBitSet(parcBitVector, 0) == 1, "parcBitVector_Set failed to set bit 1"); assertTrue(parcBitVector_NextBitSet(parcBitVector, 2) == 20, "parcBitVector_SetVector failed to set bit 20"); parcBitVector_Set(setVector, 10); parcBitVector_SetVector(parcBitVector, setVector); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 3, "parcBitVector_SetVector failed"); parcBitVector_Release(&parcBitVector); parcBitVector_Release(&setVector); }
LONGBOW_TEST_CASE(Global, athena_ProcessContentObject) { PARCURI *connectionURI; Athena *athena = athena_Create(100); CCNxName *name = ccnxName_CreateFromCString("lci:/cakes/and/pies"); 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); ccnxName_Release(&name); parcBuffer_Release(&payload); 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"); 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 *ingressVector = parcBitVector_Create(); parcBitVector_Set(ingressVector, linkId); athena_EncodeMessage(contentObject); athena_ProcessMessage(athena, contentObject, ingressVector); parcBitVector_Release(&ingressVector); // Make sure we recover processing a "nameless" content object payload = parcBuffer_WrapCString("Hello World"); CCNxContentObject *reply = ccnxContentObject_CreateWithPayload(payload); parcBuffer_Release(&payload); CCNxMetaMessage *response = ccnxMetaMessage_CreateFromContentObject(reply); ccnxContentObject_Release(&reply); athena_EncodeMessage(response); athena_ProcessMessage(athena, response, ingressVector); assertNull(ingressVector, "Processing nameless content object didn't fail."); ccnxInterest_Release(&contentObject); ccnxInterest_Release(&response); athena_Release(&athena); }
PARCBitVector * athenaTransportLinkAdapter_Send(AthenaTransportLinkAdapter *athenaTransportLinkAdapter, CCNxMetaMessage *ccnxMetaMessage, PARCBitVector *linkOutputVector) { PARCBitVector *resultVector = parcBitVector_Create(); int nextLinkToWrite = 0; if (athenaTransportLinkAdapter->instanceList == NULL) { return resultVector; } while ((nextLinkToWrite = parcBitVector_NextBitSet(linkOutputVector, nextLinkToWrite)) >= 0) { athenaTransportLinkAdapter->stats.messageSend_Attempted++; if (nextLinkToWrite >= parcArrayList_Size(athenaTransportLinkAdapter->instanceList)) { athenaTransportLinkAdapter->stats.messageSend_LinkDoesNotExist++; nextLinkToWrite++; continue; } AthenaTransportLink *athenaTransportLink = parcArrayList_Get(athenaTransportLinkAdapter->instanceList, nextLinkToWrite); if (athenaTransportLink == NULL) { athenaTransportLinkAdapter->stats.messageSend_LinkDoesNotExist++; nextLinkToWrite++; continue; } if (!(athenaTransportLink_GetEvent(athenaTransportLink) & AthenaTransportLinkEvent_Send)) { athenaTransportLinkAdapter->stats.messageSend_LinkNotAcceptingSendRequests++; nextLinkToWrite++; continue; } // If we're sending an interest to a non-local link, // check that it has a sufficient hoplimit. if (ccnxMetaMessage_IsInterest(ccnxMetaMessage)) { if (athenaTransportLink_IsNotLocal(athenaTransportLink)) { if (ccnxInterest_GetHopLimit(ccnxMetaMessage) == 0) { athenaTransportLinkAdapter->stats.messageSend_HopLimitExceeded++; nextLinkToWrite++; continue; } } } int result = athenaTransportLink_Send(athenaTransportLink, ccnxMetaMessage); if (result == 0) { athenaTransportLinkAdapter->stats.messageSent++; parcBitVector_Set(resultVector, nextLinkToWrite); } else { athenaTransportLinkAdapter->stats.messageSend_LinkSendFailed++; } nextLinkToWrite++; } return resultVector; }
/** * @abstract called from below the link adapter to coordinate termination of a link instance * @discussion * * This is called exclusively from the Transport Link Module to instigate the removal of * an active link. The link has been flagged closing by the originator. This method * must ensure that all references to the link have been removed and then call the * instance close method to finish the operation. * * @param [in] athenaTransportLinkAdapter link adapter instance * @param [in] athenaTransportLink link instance to remove * * Example: * @code * { * * } * @endcode */ static void _athenaTransportLinkAdapter_RemoveLink(AthenaTransportLinkAdapter *athenaTransportLinkAdapter, AthenaTransportLink *athenaTransportLink) { int linkId = -1; // if this is a listener it can simply be removed if (athenaTransportLink_IsNotRoutable(athenaTransportLink)) { if (athenaTransportLinkAdapter->listenerList) { for (int index = 0; index < parcArrayList_Size(athenaTransportLinkAdapter->listenerList); index++) { AthenaTransportLink *transportLink = parcArrayList_Get(athenaTransportLinkAdapter->listenerList, index); if (athenaTransportLink == transportLink) { parcArrayList_RemoveAtIndex(athenaTransportLinkAdapter->listenerList, index); _remove_from_pollfdList(athenaTransportLinkAdapter, athenaTransportLink); parcLog_Debug(athenaTransportLinkAdapter_GetLogger(athenaTransportLinkAdapter), "listener removed: %s", athenaTransportLink_GetName(athenaTransportLink)); athenaTransportLink_Release(&athenaTransportLink); return; } } } } // Remove from our internal instance list. // The index entry remains to be reused by links that are added in the future. if (athenaTransportLinkAdapter->instanceList) { for (int index = 0; index < parcArrayList_Size(athenaTransportLinkAdapter->instanceList); index++) { AthenaTransportLink *transportLink = parcArrayList_Get(athenaTransportLinkAdapter->instanceList, index); if (athenaTransportLink == transportLink) { parcArrayList_Set(athenaTransportLinkAdapter->instanceList, index, NULL); _remove_from_pollfdList(athenaTransportLinkAdapter, athenaTransportLink); linkId = index; break; } } } assertFalse(linkId == -1, "Attempt to remove link not found in link adapter lists"); // Callback to notify that the link has been removed and references need to be dropped. PARCBitVector *linkVector = parcBitVector_Create(); parcBitVector_Set(linkVector, linkId); athenaTransportLinkAdapter->removeLink(athenaTransportLinkAdapter->removeLinkContext, linkVector); parcBitVector_Release(&linkVector); // we assume all references to the linkId associated with this instance have been // cleared from the PIT and FIB when removeLink returns. parcLog_Debug(athenaTransportLinkAdapter_GetLogger(athenaTransportLinkAdapter), "link removed: %s", athenaTransportLink_GetName(athenaTransportLink)); athenaTransportLink_Release(&athenaTransportLink); }
LONGBOW_TEST_CASE(Global, parcBitVector_ClearVector) { PARCBitVector *parcBitVector = parcBitVector_Create(); assertTrue(parcBitVector, "parcBitVector_Create returned a NULL pointer"); PARCBitVector *setVector = parcBitVector_Create(); parcBitVector_Set(parcBitVector, 1); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 1, "parcBitVector_Set failed to set bit"); parcBitVector_Set(setVector, 1); parcBitVector_Set(setVector, 20); parcBitVector_ClearVector(parcBitVector, setVector); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 0, "parcBitVector_ClearVector failed to clear vector"); parcBitVector_Set(parcBitVector, 12); parcBitVector_Set(parcBitVector, 17); parcBitVector_ClearVector(parcBitVector, parcBitVector); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 0, "parcBitVector_ClearVector failed to clear vector"); parcBitVector_Release(&parcBitVector); parcBitVector_Release(&setVector); }
LONGBOW_TEST_CASE(Global, parcBitVector_Copy) { PARCBitVector *parcBitVector = parcBitVector_Create(); assertTrue(parcBitVector, "parcBitVector_Create returned a NULL pointer"); parcBitVector_Set(parcBitVector, 10); PARCBitVector *copy = parcBitVector_Copy(parcBitVector); assertTrue(parcBitVector_NumberOfBitsSet(copy) == 1, "parcBitVector_Copy failed to copy set bit"); assertTrue(parcBitVector_NextBitSet(copy, 0) == 10, "parcBitVector_Copy failed to copy correct bit"); parcBitVector_Release(©); parcBitVector_Release(&parcBitVector); }
PARCBitVector * athenaTransportLinkAdapter_Close(AthenaTransportLinkAdapter *athenaTransportLinkAdapter, PARCBitVector *linkVector) { PARCBitVector *resultVector = parcBitVector_Create(); int nextLinkToClose = 0; while ((nextLinkToClose = parcBitVector_NextBitSet(linkVector, nextLinkToClose)) >= 0) { AthenaTransportLink *athenaTransportLink = parcArrayList_Get(athenaTransportLinkAdapter->instanceList, nextLinkToClose); if (athenaTransportLink) { athenaTransportLink_Close(athenaTransportLink); parcBitVector_Set(resultVector, nextLinkToClose); nextLinkToClose++; } } return resultVector; }
LONGBOW_TEST_CASE(Global, parcBitVector_ToString) { PARCBitVector *parcBitVector = parcBitVector_Create(); assertTrue(parcBitVector, "parcBitVector_Create returned a NULL pointer"); char *string = parcBitVector_ToString(parcBitVector); assertTrue(strcmp(string, "[ ]") == 0, "parcBitVector_ToString returned unexpected representation (%s != [ ])", string); parcMemory_Deallocate(&string); parcBitVector_Set(parcBitVector, 10); parcBitVector_Set(parcBitVector, 1); string = parcBitVector_ToString(parcBitVector); assertTrue(strcmp(string, "[ 1 10 ]") == 0, "parcBitVector_ToString returned unexpected representation (%s != [ 1 10 ])", string); parcMemory_Deallocate(&string); parcBitVector_Release(&parcBitVector); }
LONGBOW_TEST_CASE(Global, parcBitVector_SetClear) { PARCBitVector *parcBitVector = parcBitVector_Create(); assertTrue(parcBitVector, "parcBitVector_Create returned a NULL pointer"); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 0, "parcBitVector_Create created a non-empty vector"); parcBitVector_Set(parcBitVector, 10); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 1, "parcBitVector_Set failed"); parcBitVector_Clear(parcBitVector, 10); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 0, "parcBitVector_Clear failed"); parcBitVector_Clear(parcBitVector, 20); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 0, "parcBitVector_Clear failed"); parcBitVector_Release(&parcBitVector); }
LONGBOW_TEST_CASE(Global, athenaTransportLinkModuleUDP_P2P) { PARCURI *connectionURI; const char *result; AthenaTransportLinkAdapter *athenaTransportLinkAdapter = athenaTransportLinkAdapter_Create(_removeLink, NULL); assertNotNull(athenaTransportLinkAdapter, "athenaTransportLinkAdapter_Create returned NULL"); connectionURI = parcURI_Parse("udp://localhost:40001/src=localhost:40002/name=UDP_0"); result = athenaTransportLinkAdapter_Open(athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); connectionURI = parcURI_Parse("udp://localhost:40002/src=localhost:40001/name=UDP_1"); result = athenaTransportLinkAdapter_Open(athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); CCNxName *name = ccnxName_CreateFromURI("lci:/foo/bar"); CCNxMetaMessage *ccnxMetaMessage = ccnxInterest_CreateSimple(name); ccnxName_Release(&name); PARCBitVector *sendVector = parcBitVector_Create(); int linkId = athenaTransportLinkAdapter_LinkNameToId(athenaTransportLinkAdapter, "UDP_1"); parcBitVector_Set(sendVector, linkId); athena_EncodeMessage(ccnxMetaMessage); PARCBitVector *resultVector; resultVector = athenaTransportLinkAdapter_Send(athenaTransportLinkAdapter, ccnxMetaMessage, sendVector); assertNotNull(resultVector, "athenaTransportLinkAdapter_Send failed"); parcBitVector_Release(&resultVector); ccnxMetaMessage_Release(&ccnxMetaMessage); parcBitVector_Release(&sendVector); usleep(1000); ccnxMetaMessage = athenaTransportLinkAdapter_Receive(athenaTransportLinkAdapter, &resultVector, 0); assertNotNull(resultVector, "athenaTransportLinkAdapter_Receive failed"); assertTrue(parcBitVector_NumberOfBitsSet(resultVector) == 1, "athenaTransportLinkAdapter_Receive return message with more than one ingress link"); assertNotNull(ccnxMetaMessage, "athenaTransportLinkAdapter_Receive failed to provide message"); parcBitVector_Release(&resultVector); ccnxMetaMessage_Release(&ccnxMetaMessage); athenaTransportLinkAdapter_Destroy(&athenaTransportLinkAdapter); }
LONGBOW_TEST_CASE(Global, parcBitVector_Get) { PARCBitVector *parcBitVector = parcBitVector_Create(); assertTrue(parcBitVector, "parcBitVector_Create returned a NULL pointer"); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 0, "parcBitVector_Create created a non-empty vector"); parcBitVector_Set(parcBitVector, 10); int bitValue = parcBitVector_Get(parcBitVector, 10); assertTrue(bitValue == 1, "parcBitVector_Get returned wrong value (%d)", bitValue); bitValue = parcBitVector_Get(parcBitVector, 11); assertTrue(bitValue == 0, "parcBitVector_Get returned wrong value (%d)", bitValue); bitValue = parcBitVector_Get(parcBitVector, 100); assertTrue(bitValue == -1, "parcBitVector_NextBitSet should have failed (%d)", bitValue); parcBitVector_Release(&parcBitVector); }
CCNxMetaMessage * athenaTransportLinkAdapter_Receive(AthenaTransportLinkAdapter *athenaTransportLinkAdapter, PARCBitVector **resultVector, int timeout) { int linkId; *resultVector = parcBitVector_Create(); // Traverse instance list starting from where we last left off. linkId = athenaTransportLinkAdapter->nextLinkToRead; CCNxMetaMessage *ccnxMetaMessage = _retrieve_next_message(athenaTransportLinkAdapter, athenaTransportLinkAdapter->instanceList, &linkId); if (ccnxMetaMessage) { parcBitVector_Set(*resultVector, linkId); athenaTransportLinkAdapter->nextLinkToRead = linkId + 1; athenaTransportLinkAdapter->stats.messageReceived++; return ccnxMetaMessage; } // Once the instance list is clear, traverse the entire listener list ccnxMetaMessage = _retrieve_next_message(athenaTransportLinkAdapter, athenaTransportLinkAdapter->listenerList, NULL); assertNull(ccnxMetaMessage, "listener returned an unexpected message"); // Last instance event has been serviced, poll all modules. athenaTransportLinkAdapter_Poll(athenaTransportLinkAdapter, timeout); // Traverse the entire listener list (could potentially populate other instances) ccnxMetaMessage = _retrieve_next_message(athenaTransportLinkAdapter, athenaTransportLinkAdapter->listenerList, NULL); assertNull(ccnxMetaMessage, "listener returned an unexpected message"); // Search instance list from the beginning. athenaTransportLinkAdapter->nextLinkToRead = 0; linkId = athenaTransportLinkAdapter->nextLinkToRead; ccnxMetaMessage = _retrieve_next_message(athenaTransportLinkAdapter, athenaTransportLinkAdapter->instanceList, &linkId); if (ccnxMetaMessage) { parcBitVector_Set(*resultVector, linkId); athenaTransportLinkAdapter->nextLinkToRead = linkId + 1; athenaTransportLinkAdapter->stats.messageReceived++; return ccnxMetaMessage; } parcBitVector_Release(resultVector); errno = EAGAIN; return NULL; }
LONGBOW_TEST_CASE(Global, parcBitVector_Reset) { PARCBitVector *parcBitVector = parcBitVector_Create(); assertTrue(parcBitVector, "parcBitVector_Create returned a NULL pointer"); // Reset and empty vector test parcBitVector_Reset(parcBitVector); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 0, "parcBitVector_Reset failed"); parcBitVector_Set(parcBitVector, 1); parcBitVector_Set(parcBitVector, 42); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 2, "parcBitVector_Set failed"); assertTrue(parcBitVector->bitLength == 48, "Expected a bitLength of 48"); parcBitVector_Reset(parcBitVector); assertTrue(parcBitVector_NumberOfBitsSet(parcBitVector) == 0, "parcBitVector_Reset failed"); assertTrue(parcBitVector->bitLength == 48, "Expected a bitLength of 48"); parcBitVector_Release(&parcBitVector); }
LONGBOW_TEST_CASE(Global, athena_ProcessInterestReturn) { PARCURI *connectionURI; Athena *athena = athena_Create(100); CCNxName *name = ccnxName_CreateFromCString("lci:/boose/roo/pie"); CCNxInterest *interest = ccnxInterest_CreateWithImpl(&CCNxInterestFacadeV1_Implementation, name, CCNxInterestDefault_LifetimeMilliseconds, NULL, NULL, CCNxInterestDefault_HopLimit); ccnxName_Release(&name); CCNxInterestReturn *interestReturn = ccnxInterestReturn_Create(interest, CCNxInterestReturn_ReturnCode_Congestion); ccnxInterest_Release(&interest); 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"); 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 *ingressVector = parcBitVector_Create(); parcBitVector_Set(ingressVector, linkId); athena_EncodeMessage(interestReturn); athena_ProcessMessage(athena, interestReturn, ingressVector); parcBitVector_Release(&ingressVector); ccnxInterest_Release(&interestReturn); athena_Release(&athena); }
LONGBOW_TEST_CASE(Global, athenaTransportLinkAdapter_NameToIdToName) { PARCURI *connectionURI; const char *result; AthenaTransportLinkAdapter *athenaTransportLinkAdapter = athenaTransportLinkAdapter_Create(_removeLink, NULL); assertNotNull(athenaTransportLinkAdapter, "athenaTransportLinkAdapter_Create returned NULL"); _LoadModule(athenaTransportLinkAdapter, "TCP"); connectionURI = parcURI_Parse("tcp://127.0.0.1:50200/Listener/name=TCP_0"); result = athenaTransportLinkAdapter_Open(athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); connectionURI = parcURI_Parse("tcp://127.0.0.1:50200/name=TCP_1"); result = athenaTransportLinkAdapter_Open(athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); PARCBitVector *linkVector = parcBitVector_Create(); int linkId = athenaTransportLinkAdapter_LinkNameToId(athenaTransportLinkAdapter, "TCP_1"); const char *linkName = athenaTransportLinkAdapter_LinkIdToName(athenaTransportLinkAdapter, linkId); assertTrue(strcmp(linkName, "TCP_1") == 0, "athenaTransportLinkAdapter_LinkIdToName failed (%s != TCP_1", linkName); linkName = athenaTransportLinkAdapter_LinkIdToName(athenaTransportLinkAdapter, 9999); assertTrue(linkName == NULL, "athenaTransportLinkAdapter_LinkIdToName returned name for unknown linkID (9999/%s)", linkName); parcBitVector_Set(linkVector, linkId); PARCBitVector *resultVector = athenaTransportLinkAdapter_Close(athenaTransportLinkAdapter, linkVector); assertNotNull(resultVector, "athenaTransportLinkAdapter_Close failed"); parcBitVector_Release(&linkVector); parcBitVector_Release(&resultVector); linkId = athenaTransportLinkAdapter_LinkNameToId(athenaTransportLinkAdapter, "TCP_0"); assertTrue(linkId == -1, "athenaTransportLinkAdapter_LinkNameToId returned id for non routable link (TCP_0 == %d)", linkId); int closeResult = athenaTransportLinkAdapter_CloseByName(athenaTransportLinkAdapter, "TCP_0"); assertTrue(closeResult == 0, "athenaTransportLinkAdapter_CloseByName failed (%s)", strerror(errno)); athenaTransportLinkAdapter_Destroy(&athenaTransportLinkAdapter); }
LONGBOW_TEST_CASE(Global, parcBitVector_Equals) { PARCBitVector *parcBitVector = parcBitVector_Create(); assertTrue(parcBitVector, "parcBitVector_Create returned a NULL pointer"); parcBitVector_Set(parcBitVector, 10); PARCBitVector *copy = parcBitVector_Copy(parcBitVector); assertTrue(parcBitVector_Equals(parcBitVector, copy), "Duplicate vector found unequal"); parcBitVector_Set(copy, 9); assertFalse(parcBitVector_Equals(parcBitVector, copy), "Unequal vector found equal"); parcBitVector_Clear(copy, 9); parcBitVector_Set(copy, 29); assertFalse(parcBitVector_Equals(parcBitVector, copy), "Unequal long vector found equal"); parcBitVector_Clear(copy, 29); assertTrue(parcBitVector_Equals(parcBitVector, copy), "Equal long vector found unequal"); assertTrue(parcBitVector_Equals(copy, parcBitVector), "Equal long vector found unequal"); parcBitVector_Release(©); parcBitVector_Release(&parcBitVector); }
LONGBOW_TEST_CASE(Global, athenaTransportLinkAdapter_SendReceive) { PARCURI *connectionURI; const char *result; CCNxMetaMessage *receiveMessage; PARCBitVector *resultVector; AthenaTransportLinkAdapter *athenaTransportLinkAdapter = athenaTransportLinkAdapter_Create(_removeLink, NULL); assertNotNull(athenaTransportLinkAdapter, "athenaTransportLinkAdapter_Create returned NULL"); _LoadModule(athenaTransportLinkAdapter, "TCP"); connectionURI = parcURI_Parse("tcp://127.0.0.1:50200/Listener/name=TCPListener"); result = athenaTransportLinkAdapter_Open(athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); receiveMessage = athenaTransportLinkAdapter_Receive(athenaTransportLinkAdapter, &resultVector, 0); assertNull(resultVector, "Received message when none sent"); connectionURI = parcURI_Parse("tcp://127.0.0.1:50200/name=TCP_1"); result = athenaTransportLinkAdapter_Open(athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); receiveMessage = athenaTransportLinkAdapter_Receive(athenaTransportLinkAdapter, &resultVector, 0); assertNull(resultVector, "Received message when none sent"); connectionURI = parcURI_Parse("tcp://127.0.0.1:50200/name=TCP_2"); result = athenaTransportLinkAdapter_Open(athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); receiveMessage = athenaTransportLinkAdapter_Receive(athenaTransportLinkAdapter, &resultVector, 0); assertNull(resultVector, "Received message when none sent"); connectionURI = parcURI_Parse("tcp://127.0.0.1:50200/name=TCP_3"); result = athenaTransportLinkAdapter_Open(athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); receiveMessage = athenaTransportLinkAdapter_Receive(athenaTransportLinkAdapter, &resultVector, 0); assertNull(resultVector, "Received message when none sent"); connectionURI = parcURI_Parse("tcp://127.0.0.1:50200/name=TCP_4"); result = athenaTransportLinkAdapter_Open(athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); receiveMessage = athenaTransportLinkAdapter_Receive(athenaTransportLinkAdapter, &resultVector, 0); assertNull(resultVector, "Received message when none sent"); connectionURI = parcURI_Parse("tcp://127.0.0.1:50200/name=TCP_5"); result = athenaTransportLinkAdapter_Open(athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); receiveMessage = athenaTransportLinkAdapter_Receive(athenaTransportLinkAdapter, &resultVector, 0); assertNull(resultVector, "Received message when none sent"); int closeResult = athenaTransportLinkAdapter_CloseByName(athenaTransportLinkAdapter, "TCP_3"); assertTrue(closeResult == 0, "athenaTransportLinkAdapter_CloseByName failed (%s)", strerror(errno)); connectionURI = parcURI_Parse("tcp://127.0.0.1:50200/name=TCP_3"); result = athenaTransportLinkAdapter_Open(athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); receiveMessage = athenaTransportLinkAdapter_Receive(athenaTransportLinkAdapter, &resultVector, 0); assertNull(resultVector, "Received message when none sent"); CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar"); CCNxMetaMessage *sendMessage = ccnxInterest_CreateSimple(name); ccnxName_Release(&name); PARCBitVector *linkVector = parcBitVector_Create(); int linkId = athenaTransportLinkAdapter_LinkNameToId(athenaTransportLinkAdapter, "TCP_1"); parcBitVector_Set(linkVector, linkId); linkId = athenaTransportLinkAdapter_LinkNameToId(athenaTransportLinkAdapter, "TCP_2"); parcBitVector_Set(linkVector, linkId); linkId = athenaTransportLinkAdapter_LinkNameToId(athenaTransportLinkAdapter, "TCP_3"); parcBitVector_Set(linkVector, linkId); athena_EncodeMessage(sendMessage); resultVector = athenaTransportLinkAdapter_Send(athenaTransportLinkAdapter, sendMessage, linkVector); assertNull(resultVector, "athenaTransportLinkAdapter_Send failed"); usleep(1000); char *resultString; receiveMessage = athenaTransportLinkAdapter_Receive(athenaTransportLinkAdapter, &resultVector, -1); assertNotNull(resultVector, "athenaTransportLinkAdapter_Receive failed"); printf("Receive1 = %s\n", resultString = parcBitVector_ToString(resultVector)); assertTrue(parcBitVector_NumberOfBitsSet(resultVector) > 0, "athenaTransportLinkAdapter_Receive failed"); assertTrue(parcBitVector_NumberOfBitsSet(resultVector) == 1, "athenaTransportLinkAdapter_Receive returned message with more than one ingress link (%s)", resultString); parcMemory_Deallocate(&resultString); parcBitVector_Release(&resultVector); ccnxMetaMessage_Release(&receiveMessage); receiveMessage = athenaTransportLinkAdapter_Receive(athenaTransportLinkAdapter, &resultVector, -1); assertNotNull(resultVector, "athenaTransportLinkAdapter_Receive failed"); printf("Receive2 = %s\n", resultString = parcBitVector_ToString(resultVector)); assertTrue(parcBitVector_NumberOfBitsSet(resultVector) > 0, "athenaTransportLinkAdapter_Receive failed"); assertTrue(parcBitVector_NumberOfBitsSet(resultVector) == 1, "athenaTransportLinkAdapter_Receive returned message with more than one ingress link (%s)", resultString); parcMemory_Deallocate(&resultString); parcBitVector_Release(&resultVector); ccnxMetaMessage_Release(&receiveMessage); receiveMessage = athenaTransportLinkAdapter_Receive(athenaTransportLinkAdapter, &resultVector, -1); assertNotNull(resultVector, "athenaTransportLinkAdapter_Receive failed"); printf("Receive3 = %s\n", resultString = parcBitVector_ToString(resultVector)); assertTrue(parcBitVector_NumberOfBitsSet(resultVector) > 0, "athenaTransportLinkAdapter_Receive failed"); assertTrue(parcBitVector_NumberOfBitsSet(resultVector) == 1, "athenaTransportLinkAdapter_Receive returned message with more than one ingress link (%s)", resultString); parcMemory_Deallocate(&resultString); parcBitVector_Release(&resultVector); ccnxMetaMessage_Release(&receiveMessage); closeResult = athenaTransportLinkAdapter_CloseByName(athenaTransportLinkAdapter, "TCP_1"); assertTrue(closeResult == 0, "athenaTransportLinkAdapter_CloseByName failed (%s)", strerror(errno)); closeResult = athenaTransportLinkAdapter_CloseByName(athenaTransportLinkAdapter, "TCP_2"); assertTrue(closeResult == 0, "athenaTransportLinkAdapter_CloseByName failed (%s)", strerror(errno)); resultVector = athenaTransportLinkAdapter_Send(athenaTransportLinkAdapter, sendMessage, linkVector); assertTrue(parcBitVector_NumberOfBitsSet(resultVector) == 2, "athenaTransportLinkAdapter_Send should have partially failed"); parcBitVector_Release(&linkVector); parcBitVector_Release(&resultVector); linkVector = parcBitVector_Create(); parcBitVector_Set(linkVector, 100); resultVector = athenaTransportLinkAdapter_Send(athenaTransportLinkAdapter, sendMessage, linkVector); assertTrue(parcBitVector_NumberOfBitsSet(resultVector) == 1, "athenaTransportLinkAdapter_Send should have failed to send to unknown link"); parcBitVector_Release(&resultVector); parcBitVector_Release(&linkVector); ccnxMetaMessage_Release(&sendMessage); athenaTransportLinkAdapter_Destroy(&athenaTransportLinkAdapter); }
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, 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); }
LONGBOW_TEST_CASE(Global, athenaTransportLinkModuleTEMPLATE_SendReceive) { PARCURI *connectionURI; char linkSpecificationURI[MAXPATHLEN]; const char *result; AthenaTransportLinkAdapter *athenaTransportLinkAdapter = athenaTransportLinkAdapter_Create(_removeLink, NULL); assertNotNull(athenaTransportLinkAdapter, "athenaTransportLinkAdapter_Create returned NULL"); // Open a link we can send messages on sprintf(linkSpecificationURI, "template:///name=TEMPLATE_1"); connectionURI = parcURI_Parse(linkSpecificationURI); result = athenaTransportLinkAdapter_Open(athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); // Enable debug logging after all instances are open athenaTransportLinkAdapter_SetLogLevel(athenaTransportLinkAdapter, PARCLogLevel_Debug); // Construct an interest CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar"); CCNxMetaMessage *ccnxMetaMessage = ccnxInterest_CreateSimple(name); ccnxName_Release(&name); PARCBitVector *sendVector = parcBitVector_Create(); // Send the interest out on the link, this message will also be received by ourself // since we're sending it to our own MAC destination. int linkId = athenaTransportLinkAdapter_LinkNameToId(athenaTransportLinkAdapter, "TEMPLATE_1"); parcBitVector_Set(sendVector, linkId); athena_EncodeMessage(ccnxMetaMessage); PARCBitVector *resultVector; resultVector = athenaTransportLinkAdapter_Send(athenaTransportLinkAdapter, ccnxMetaMessage, sendVector); assertNull(resultVector, "athenaTransportLinkAdapter_Send failed"); // Send the message a second time resultVector = athenaTransportLinkAdapter_Send(athenaTransportLinkAdapter, ccnxMetaMessage, sendVector); assertNull(resultVector, "athenaTransportLinkAdapter_Send failed"); parcBitVector_Release(&sendVector); ccnxMetaMessage_Release(&ccnxMetaMessage); ccnxMetaMessage = athenaTransportLinkAdapter_Receive(athenaTransportLinkAdapter, &resultVector, 0); assertNotNull(resultVector, "athenaTransportLinkAdapter_Receive failed"); assertTrue(parcBitVector_NumberOfBitsSet(resultVector) == 1, "athenaTransportLinkAdapter_Receive return message with more than one ingress link"); assertNotNull(ccnxMetaMessage, "athenaTransportLinkAdapter_Receive failed to provide message"); parcBitVector_Release(&resultVector); ccnxMetaMessage_Release(&ccnxMetaMessage); // Receive the duplicate ccnxMetaMessage = athenaTransportLinkAdapter_Receive(athenaTransportLinkAdapter, &resultVector, 0); assertTrue(ccnxMetaMessage != NULL, "athenaTransportLinkAdapter_Receive failed to receive duplicate message"); parcBitVector_Release(&resultVector); ccnxMetaMessage_Release(&ccnxMetaMessage); // Nothing else should remain ccnxMetaMessage = athenaTransportLinkAdapter_Receive(athenaTransportLinkAdapter, &resultVector, 0); assertTrue(ccnxMetaMessage == NULL, "athenaTransportLinkAdapter_Receive received extraneous message"); int closeResult = athenaTransportLinkAdapter_CloseByName(athenaTransportLinkAdapter, "TEMPLATE_1"); assertTrue(closeResult == 0, "athenaTransportLinkAdapter_CloseByName failed (%s)", strerror(errno)); athenaTransportLinkAdapter_Destroy(&athenaTransportLinkAdapter); }