diff options
author | Luca Muscariello <lumuscar+fdio@cisco.com> | 2017-02-23 20:44:26 +0100 |
---|---|---|
committer | Luca Muscariello <lumuscar+fdio@cisco.com> | 2017-02-23 19:51:14 +0000 |
commit | d18ae43123fcd7604d1c36a1ec8450dbe6071824 (patch) | |
tree | 2d49fc3aabd0f2607251c854565648d47b56b2e9 /libccnx-common/ccnx/common/internal/test | |
parent | 9b30fc10fb1cbebe651e5a107e8ca5b24de54675 (diff) |
Initial commit: ccnxlibs.
Change-Id: I1b376527a7dd01a6b9e083a6cb646955902f45c0
Signed-off-by: Luca Muscariello <lumuscar+fdio@cisco.com>
Diffstat (limited to 'libccnx-common/ccnx/common/internal/test')
17 files changed, 4010 insertions, 0 deletions
diff --git a/libccnx-common/ccnx/common/internal/test/.gitignore b/libccnx-common/ccnx/common/internal/test/.gitignore new file mode 100644 index 00000000..d8148318 --- /dev/null +++ b/libccnx-common/ccnx/common/internal/test/.gitignore @@ -0,0 +1,18 @@ +test_ccnx_ChunkingFacadeV0 +test_ccnx_ChunkingFacadeV1 +test_ccnx_ContentObjectFacadeV0 +test_ccnx_ContentObjectFacadeV1 +test_ccnx_ContentObjectInterface +test_ccnx_ControlFacade +test_ccnx_InterestFacadeV0 +test_ccnx_InterestFacadeV1 +test_ccnx_InterestInterface +test_ccnx_InterestReturnInterface +test_ccnx_Tlv +test_ccnx_TlvDictionary +test_ccnx_TlvEncodingBuffer +test_ccnx_TlvError +test_ccnx_ValidationFacadeV0 +test_ccnx_ValidationFacadeV1 +test_ccnx_WireFormatFacadeV0 +test_ccnx_WireFormatFacadeV1 diff --git a/libccnx-common/ccnx/common/internal/test/CMakeLists.txt b/libccnx-common/ccnx/common/internal/test/CMakeLists.txt new file mode 100644 index 00000000..900ba031 --- /dev/null +++ b/libccnx-common/ccnx/common/internal/test/CMakeLists.txt @@ -0,0 +1,24 @@ +# Enable gcov output for the tests +add_definitions(--coverage) +set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} " --coverage") + +set(TestsExpectedToPass + test_ccnx_ChunkingFacadeV1 + test_ccnx_ContentObjectFacadeV1 + test_ccnx_ContentObjectInterface + test_ccnx_InterestFacadeV1 + test_ccnx_InterestInterface + test_ccnx_InterestReturnFacadeV1 + test_ccnx_InterestReturnInterface + test_ccnx_ManifestFacadeV1 + test_ccnx_ManifestInterface + test_ccnx_TlvDictionary + test_ccnx_ValidationFacadeV1 + test_ccnx_WireFormatFacadeV1 +) + + +foreach(test ${TestsExpectedToPass}) + AddTest(${test}) +endforeach() + diff --git a/libccnx-common/ccnx/common/internal/test/test_ccnx_ChunkingFacade b/libccnx-common/ccnx/common/internal/test/test_ccnx_ChunkingFacade Binary files differnew file mode 100755 index 00000000..0894fcbd --- /dev/null +++ b/libccnx-common/ccnx/common/internal/test/test_ccnx_ChunkingFacade diff --git a/libccnx-common/ccnx/common/internal/test/test_ccnx_ChunkingFacadeV1.c b/libccnx-common/ccnx/common/internal/test/test_ccnx_ChunkingFacadeV1.c new file mode 100755 index 00000000..6f14cf47 --- /dev/null +++ b/libccnx-common/ccnx/common/internal/test/test_ccnx_ChunkingFacadeV1.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + */ + +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. +#include "../ccnx_ChunkingFacadeV1.c" +#include <parc/algol/parc_SafeMemory.h> + +#include <LongBow/unit-test.h> +#include <inttypes.h> + +#include <ccnx/common/ccnx_ContentObject.h> +#include <ccnx/common/ccnx_Interest.h> +#include <ccnx/common/ccnx_PayloadType.h> + +#include <ccnx/common/internal/ccnx_ContentObjectInterface.h> + +typedef struct test_data { + CCNxName *name; + CCNxTlvDictionary *contentObjectV1; + CCNxTlvDictionary *contentObjectVFF; + + CCNxTlvDictionary *interest; +} TestData; + +static TestData * +_commonSetup(void) +{ + TestData *data = parcMemory_AllocateAndClear(sizeof(TestData)); + assertNotNull(data, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(TestData)); + + data->name = ccnxName_CreateFromCString("lci:/foo/bar/v1"); + + data->contentObjectV1 = + ccnxContentObject_CreateWithImplAndPayload(&CCNxContentObjectFacadeV1_Implementation, + data->name, + CCNxPayloadType_DATA, NULL); + + data->contentObjectVFF = ccnxTlvDictionary_Create(CCNxCodecSchemaV1TlvDictionary_MessageFastArray_END, CCNxCodecSchemaV1TlvDictionary_Lists_END); + + ccnxTlvDictionary_SetMessageType_ContentObject(data->contentObjectVFF, 0xFF); + + data->interest = + ccnxInterest_CreateWithImpl(&CCNxInterestFacadeV1_Implementation, + data->name, 5000, NULL, NULL, 100); + + return data; +} + +static void +_commonTeardown(TestData *data) +{ + ccnxName_Release(&data->name); + ccnxTlvDictionary_Release(&data->contentObjectV1); + ccnxTlvDictionary_Release(&data->contentObjectVFF); + ccnxTlvDictionary_Release(&data->interest); + parcMemory_Deallocate((void **) &data); +} + +LONGBOW_TEST_RUNNER(ccnx_ChunkingFacade) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(ccnx_ChunkingFacade) +{ + parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory); + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_ChunkingFacade) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, ccnxChunkingFacade_GetEndChunkNumber_NotContentObject); + + LONGBOW_RUN_TEST_CASE(Global, ccnxChunkingFacade_GetEndChunkNumber_V1_With); + LONGBOW_RUN_TEST_CASE(Global, ccnxChunkingFacade_GetEndChunkNumber_V1_Without); + LONGBOW_RUN_TEST_CASE(Global, ccnxChunkingFacade_GetEndChunkNumber_InvalidVersion); + + LONGBOW_RUN_TEST_CASE(Global, ccnxChunkingFacade_HasEndChunkNumber_NotContentObject); + LONGBOW_RUN_TEST_CASE(Global, ccnxChunkingFacade_HasEndChunkNumber_V1_With); + LONGBOW_RUN_TEST_CASE(Global, ccnxChunkingFacade_HasEndChunkNumber_V1_Without); + LONGBOW_RUN_TEST_CASE(Global, ccnxChunkingFacade_HasEndChunkNumber_InvalidVersion); + + LONGBOW_RUN_TEST_CASE(Global, ccnxChunkingFacade_SetEndChunkNumber_NotContentObject); + LONGBOW_RUN_TEST_CASE(Global, ccnxChunkingFacade_SetEndChunkNumber_InvalidVersion); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + longBowTestCase_SetClipBoardData(testCase, _commonSetup()); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + _commonTeardown(data); + + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +// ====================================================================================== + +LONGBOW_TEST_CASE_EXPECTS(Global, ccnxChunkingFacade_GetEndChunkNumber_NotContentObject, .event = &LongBowTrapIllegalValue) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + ccnxChunkingFacadeV1_GetEndChunkNumber(data->interest); +} + +LONGBOW_TEST_CASE(Global, ccnxChunkingFacade_GetEndChunkNumber_V1_With) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + uint64_t endChunkNumber = 5; + + ccnxChunkingFacadeV1_SetEndChunkNumber(data->contentObjectV1, endChunkNumber); + uint64_t test = ccnxChunkingFacadeV1_GetEndChunkNumber(data->contentObjectV1); + assertTrue(test == endChunkNumber, "wrong value, got %" PRIu64 " expected %" PRIu64 "", test, endChunkNumber) + { + ccnxTlvDictionary_Display(data->contentObjectV1, 3); + } +} + +LONGBOW_TEST_CASE_EXPECTS(Global, ccnxChunkingFacade_GetEndChunkNumber_V1_Without, .event = &LongBowTrapIllegalValue) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + ccnxChunkingFacadeV1_GetEndChunkNumber(data->contentObjectV1); +} + +LONGBOW_TEST_CASE_EXPECTS(Global, ccnxChunkingFacade_GetEndChunkNumber_InvalidVersion, .event = &LongBowTrapIllegalValue) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + ccnxChunkingFacadeV1_GetEndChunkNumber(data->contentObjectVFF); +} + +// ====================================================================================== + + +LONGBOW_TEST_CASE(Global, ccnxChunkingFacade_HasEndChunkNumber_NotContentObject) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + bool success = ccnxChunkingFacadeV1_HasEndChunkNumber(data->interest); + assertFalse(success, "An Interest should always return FALSE for EndChunkNumber"); +} + +LONGBOW_TEST_CASE(Global, ccnxChunkingFacade_HasEndChunkNumber_V1_With) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + + ccnxChunkingFacadeV1_SetEndChunkNumber(data->contentObjectV1, 5); + bool success = ccnxChunkingFacadeV1_HasEndChunkNumber(data->contentObjectV1); + assertTrue(success, "Content Object with EndChunkNumber returned false") + { + ccnxTlvDictionary_Display(data->contentObjectV1, 3); + } +} + +LONGBOW_TEST_CASE(Global, ccnxChunkingFacade_HasEndChunkNumber_V1_Without) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + + bool success = ccnxChunkingFacadeV1_HasEndChunkNumber(data->contentObjectV1); + assertFalse(success, "Content Object without EndChunkNumber returned true") + { + ccnxTlvDictionary_Display(data->contentObjectV1, 3); + } +} + +LONGBOW_TEST_CASE_EXPECTS(Global, ccnxChunkingFacade_HasEndChunkNumber_InvalidVersion, .event = &LongBowTrapIllegalValue) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + ccnxChunkingFacadeV1_HasEndChunkNumber(data->contentObjectVFF); +} + +// ====================================================================================== + +LONGBOW_TEST_CASE_EXPECTS(Global, ccnxChunkingFacade_SetEndChunkNumber_NotContentObject, .event = &LongBowTrapIllegalValue) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + uint64_t endChunkNumber = 7; + ccnxChunkingFacadeV1_SetEndChunkNumber(data->interest, endChunkNumber); +} + + +LONGBOW_TEST_CASE(Global, ccnxChunkingFacade_SetEndChunkNumber_V1) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + uint64_t endChunkNumber = 7; + bool success = ccnxChunkingFacadeV1_SetEndChunkNumber(data->contentObjectV1, endChunkNumber); + + assertTrue(success, "Setting EndChunkNumber failed") + { + ccnxTlvDictionary_Display(data->contentObjectV1, 3); + } +} + +LONGBOW_TEST_CASE_EXPECTS(Global, ccnxChunkingFacade_SetEndChunkNumber_InvalidVersion, .event = &LongBowTrapIllegalValue) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + ccnxChunkingFacadeV1_SetEndChunkNumber(data->contentObjectVFF, 7); +} + +// ====================================================================================== + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_ChunkingFacade); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libccnx-common/ccnx/common/internal/test/test_ccnx_ContentObjectFacade b/libccnx-common/ccnx/common/internal/test/test_ccnx_ContentObjectFacade Binary files differnew file mode 100755 index 00000000..073ccae4 --- /dev/null +++ b/libccnx-common/ccnx/common/internal/test/test_ccnx_ContentObjectFacade diff --git a/libccnx-common/ccnx/common/internal/test/test_ccnx_ContentObjectFacadeV1.c b/libccnx-common/ccnx/common/internal/test/test_ccnx_ContentObjectFacadeV1.c new file mode 100644 index 00000000..b3c6b343 --- /dev/null +++ b/libccnx-common/ccnx/common/internal/test/test_ccnx_ContentObjectFacadeV1.c @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + */ + +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. +#include "../ccnx_ContentObjectFacadeV1.c" +#include <parc/algol/parc_SafeMemory.h> +#include <LongBow/unit-test.h> + +#include <ccnx/common/codec/schema_v1/ccnxCodecSchemaV1_TlvDictionary.h> +#include <inttypes.h> + +typedef struct test_data { + CCNxName *name; + CCNxPayloadType payloadType; + PARCBuffer *payload; + + // a V1 dictionary but with no values set + CCNxTlvDictionary *contentObjectV1Empty; + + // a V1 nameless Content Object + CCNxTlvDictionary *contentObjectV1Nameless; + + // a valid V1 Content Object + CCNxTlvDictionary *contentObjectV1; + CCNxTlvDictionary *contentObjectVFF; +} TestData; + +static TestData * +_commonSetup(void) +{ + TestData *data = parcMemory_AllocateAndClear(sizeof(TestData)); + assertNotNull(data, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(TestData)); + + data->name = ccnxName_CreateFromCString("lci:/foo/bar"); + data->payloadType = CCNxPayloadType_DATA; + + data->payload = parcBuffer_Flip(parcBuffer_PutArray(parcBuffer_Allocate(20), 7, (uint8_t *) "payload")); + + data->contentObjectV1Empty = ccnxCodecSchemaV1TlvDictionary_CreateContentObject(); + data->contentObjectV1 = _ccnxContentObjectFacadeV1_CreateWithNameAndPayload(data->name, data->payloadType, + data->payload); + data->contentObjectV1Nameless = _ccnxContentObjectFacadeV1_CreateWithPayload(data->payloadType, data->payload); + + data->contentObjectVFF = ccnxTlvDictionary_Create(CCNxCodecSchemaV1TlvDictionary_MessageFastArray_END, CCNxCodecSchemaV1TlvDictionary_Lists_END); + ccnxTlvDictionary_SetMessageType_ContentObject(data->contentObjectVFF, 0xFF); + + return data; +} + +static void +_commonTeardown(TestData *data) +{ + ccnxName_Release(&data->name); + parcBuffer_Release(&data->payload); + + ccnxTlvDictionary_Release(&data->contentObjectV1Empty); + ccnxTlvDictionary_Release(&data->contentObjectV1); + ccnxTlvDictionary_Release(&data->contentObjectV1Nameless); + ccnxTlvDictionary_Release(&data->contentObjectVFF); + parcMemory_Deallocate((void **) &data); +} + + +LONGBOW_TEST_RUNNER(ccnx_ContentObjectFacade) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(ImplInterface); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(ccnx_ContentObjectFacade) +{ + parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory); + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_ContentObjectFacade) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// ====================================================================================== + +LONGBOW_TEST_FIXTURE(ImplInterface) +{ + LONGBOW_RUN_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_Init); + + LONGBOW_RUN_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_GetName); + LONGBOW_RUN_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_GetPayload); + LONGBOW_RUN_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_SetPayload); + LONGBOW_RUN_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_SetPayload_Link); + LONGBOW_RUN_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_GetPayloadType); + LONGBOW_RUN_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_GetPayloadType_Unset); + LONGBOW_RUN_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_GetExpiryTime); + LONGBOW_RUN_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_SetExpiryTime); + + LONGBOW_RUN_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_SetSignature); + LONGBOW_RUN_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_GetKeyId); + + LONGBOW_RUN_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_ToString); + LONGBOW_RUN_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_Display); + LONGBOW_RUN_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_Equals); +} + +LONGBOW_TEST_FIXTURE_SETUP(ImplInterface) +{ + longBowTestCase_SetClipBoardData(testCase, _commonSetup()); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(ImplInterface) +{ + _commonTeardown(longBowTestCase_GetClipBoardData(testCase)); + + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +// ====================================================================================== + +LONGBOW_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_Init) +{ + CCNxContentObjectInterface *impl = &CCNxContentObjectFacadeV1_Implementation; + assertNotNull(impl->createWithNameAndPayload, "Expected CreateWithNameAndPayload to be set"); + assertNotNull(impl->createWithPayload, "Expected CreateWithPayload to be set"); + + assertNotNull(impl->getName, "Expected GetName to be set"); + assertNotNull(impl->setSignature, "Expected SetSignature to be set"); + assertNotNull(impl->getKeyId, "Expected GetKeyID to be set"); + assertNotNull(impl->getPayload, "Expected GetPayload to be set"); + assertNotNull(impl->getPayloadType, "Expected GetPayloadType to be set"); + + assertNotNull(impl->hasFinalChunkNumber, "Expected HasFinalChunkNumber to be set"); + assertNotNull(impl->getFinalChunkNumber, "Expected GetFinalChunkNumber to be set"); + assertNotNull(impl->setFinalChunkNumber, "Expected SetFinalChunkNumber to be set"); + + assertNotNull(impl->hasExpiryTime, "Expected HasExpiryTime to be set"); + assertNotNull(impl->getExpiryTime, "Expected GetExpiryTime to be set"); + assertNotNull(impl->setExpiryTime, "Expected SetExpiryTime to be set"); + + assertNotNull(impl->toString, "Expected ToString to be set"); + assertNotNull(impl->display, "Expected Display to be set"); +} + +LONGBOW_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_GetName) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + CCNxName *test = _ccnxContentObjectFacadeV1_GetName(data->contentObjectV1); + assertTrue(ccnxName_Equals(test, data->name), "Names do not match") + { + ccnxName_Display(test, 0); + ccnxName_Display(data->name, 0); + } + test = _ccnxContentObjectFacadeV1_GetName(data->contentObjectV1Nameless); + assertNull(test, "A nameless Content Object has no name."); +} + +LONGBOW_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_SetPayload) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *newPayload = parcBuffer_WrapCString("this is a new payload"); + + // Shouldn't be able to set it on an already initialized ContentObject. + // (Though this may change...) + assertFalse(_ccnxContentObjectFacadeV1_SetPayload(data->contentObjectV1, CCNxPayloadType_DATA, newPayload), + "Expected to not be able to re-assign a payload on an already initialized ContentObject"); + + CCNxTlvDictionary *contentObject = + _ccnxContentObjectFacadeV1_CreateWithNameAndPayload(data->name, + CCNxPayloadType_DATA, + NULL); + + + bool status = _ccnxContentObjectFacadeV1_SetPayload(contentObject, CCNxPayloadType_KEY, newPayload); + assertTrue(status, "Expected to be able to set the buffer"); + + PARCBuffer *testPayload = _ccnxContentObjectFacadeV1_GetPayload(contentObject); + assertTrue(parcBuffer_Equals(newPayload, testPayload), "payloads do not match") + { + parcBuffer_Display(newPayload, 0); + parcBuffer_Display(data->payload, 0); + } + + CCNxPayloadType testType = _ccnxContentObjectFacadeV1_GetPayloadType(contentObject); + assertTrue(testType == CCNxPayloadType_KEY, "Expected type KEY"); + + parcBuffer_Release(&newPayload); + ccnxTlvDictionary_Release(&contentObject); +} + +LONGBOW_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_SetPayload_Link) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *payload = parcBuffer_WrapCString("this is a payload"); + + CCNxTlvDictionary *contentObject = + _ccnxContentObjectFacadeV1_CreateWithNameAndPayload(data->name, + CCNxPayloadType_LINK, + payload); + + PARCBuffer *testPayload = _ccnxContentObjectFacadeV1_GetPayload(contentObject); + assertTrue(parcBuffer_Equals(payload, testPayload), "payloads do not match") + { + parcBuffer_Display(payload, 0); + parcBuffer_Display(testPayload, 0); + } + + CCNxPayloadType testType = _ccnxContentObjectFacadeV1_GetPayloadType(contentObject); + assertTrue(testType == CCNxPayloadType_LINK, "Expected type LINK"); + + parcBuffer_Release(&payload); + ccnxTlvDictionary_Release(&contentObject); +} + +LONGBOW_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_GetPayload) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *test = _ccnxContentObjectFacadeV1_GetPayload(data->contentObjectV1); + assertTrue(parcBuffer_Equals(test, data->payload), "payloads do not match") + { + parcBuffer_Display(test, 0); + parcBuffer_Display(data->payload, 0); + } +} + +LONGBOW_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_GetPayloadType) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + CCNxPayloadType test = _ccnxContentObjectFacadeV1_GetPayloadType(data->contentObjectV1); + assertTrue(test == data->payloadType, "payloads do not match, got %d expected %d", test, data->payloadType) + { + ccnxTlvDictionary_Display(data->contentObjectV1, 0); + } +} + +LONGBOW_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_GetPayloadType_Unset) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + CCNxPayloadType test = _ccnxContentObjectFacadeV1_GetPayloadType(data->contentObjectV1Empty); + assertTrue(test == CCNxPayloadType_DATA, "payloads do not match, got %d expected %d", test, CCNxPayloadType_DATA) + { + ccnxTlvDictionary_Display(data->contentObjectV1, 0); + } +} + +LONGBOW_TEST_CASE_EXPECTS(ImplInterface, ccnxContentObjectFacadeV1_ToString, .event = &LongBowTrapNotImplemented) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + _ccnxContentObjectFacadeV1_ToString(data->contentObjectV1); +} + +LONGBOW_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_Display) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + _ccnxContentObjectFacadeV1_Display(data->contentObjectV1, 0); +} + +LONGBOW_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_Equals) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + assertTrue(_ccnxContentObjectFacadeV1_Equals(data->contentObjectV1, data->contentObjectV1), + "Expected equals to be true"); + assertFalse(_ccnxContentObjectFacadeV1_Equals(data->contentObjectV1, data->contentObjectV1Empty), + "Expected equals to be false"); +} + +LONGBOW_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_GetExpiryTime) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + + uint64_t truth = 12345; + ccnxTlvDictionary_PutInteger(data->contentObjectV1, CCNxCodecSchemaV1TlvDictionary_MessageFastArray_EXPIRY_TIME, truth); + + assertTrue(_ccnxContentObjectFacadeV1_HasExpiryTime(data->contentObjectV1), "Expected HasExpiryTime() to return true"); + uint64_t expiryTime = _ccnxContentObjectFacadeV1_GetExpiryTime(data->contentObjectV1); + assertTrue(truth == expiryTime, "times do not match, expected %" PRIu64 ", got %" PRIu64, truth, expiryTime); +} + +LONGBOW_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_SetExpiryTime) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + + uint64_t truth = 12345; + _ccnxContentObjectFacadeV1_SetExpiryTime(data->contentObjectV1, truth); + uint64_t expiryTime = _ccnxContentObjectFacadeV1_GetExpiryTime(data->contentObjectV1); + assertTrue(truth == expiryTime, "times do not match, expected %" PRIu64 ", got %" PRIu64, truth, expiryTime); +} + +LONGBOW_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_SetSignature) +{ + CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar/baz"); + PARCBuffer *payload = parcBuffer_Allocate(100); + + CCNxTlvDictionary *contentObject = _ccnxContentObjectFacadeV1_CreateWithNameAndPayload(name, CCNxPayloadType_DATA, + payload); + + PARCBuffer *keyId = parcBuffer_WrapCString("keyhash"); + char *rawsig = "siggybits"; + PARCBuffer *sigbits = parcBuffer_CreateFromArray((void *) rawsig, strlen(rawsig)); + + PARCSignature *signature = parcSignature_Create(PARCSigningAlgorithm_RSA, PARCCryptoHashType_SHA256, parcBuffer_Flip(sigbits)); + parcBuffer_Release(&sigbits); + + assertTrue(_ccnxContentObjectFacadeV1_SetSignature(contentObject, keyId, signature, NULL), + "Expected to be able to set the signature"); + + ccnxName_Release(&name); + parcBuffer_Release(&payload); + parcSignature_Release(&signature); + parcBuffer_Release(&keyId); + ccnxTlvDictionary_Release(&contentObject); +} + +LONGBOW_TEST_CASE(ImplInterface, ccnxContentObjectFacadeV1_GetKeyId) +{ + CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar/baz"); + PARCBuffer *payload = parcBuffer_Allocate(100); + + CCNxTlvDictionary *contentObject = _ccnxContentObjectFacadeV1_CreateWithNameAndPayload(name, CCNxPayloadType_DATA, + payload); + + assertNull(_ccnxContentObjectFacadeV1_GetKeyId(contentObject), "Expect key ID to be NULL"); + + PARCBuffer *testKeyId = parcBuffer_WrapCString("keyhash"); + char *rawsig = "siggybits"; + PARCBuffer *sigbits = parcBuffer_CreateFromArray((void *) rawsig, strlen(rawsig)); + + PARCSignature *signature = parcSignature_Create(PARCSigningAlgorithm_RSA, PARCCryptoHashType_SHA256, parcBuffer_Flip(sigbits)); + parcBuffer_Release(&sigbits); + + assertTrue(_ccnxContentObjectFacadeV1_SetSignature(contentObject, testKeyId, signature, NULL), + "Expected to be able to set the signature"); + + PARCBuffer *keyId = _ccnxContentObjectFacadeV1_GetKeyId(contentObject); + + assertTrue(parcBuffer_Equals(keyId, testKeyId), "Expect key ID's to be the same"); + + ccnxName_Release(&name); + parcBuffer_Release(&payload); + parcSignature_Release(&signature); + parcBuffer_Release(&keyId); + ccnxTlvDictionary_Release(&contentObject); +} + +// ====================================================================================== + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_ContentObjectFacade); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libccnx-common/ccnx/common/internal/test/test_ccnx_ContentObjectInterface.c b/libccnx-common/ccnx/common/internal/test/test_ccnx_ContentObjectInterface.c new file mode 100755 index 00000000..65e78bed --- /dev/null +++ b/libccnx-common/ccnx/common/internal/test/test_ccnx_ContentObjectInterface.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + */ + +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. +#include "../ccnx_ContentObjectInterface.c" + +#include <stdio.h> + +#include <ccnx/common/ccnx_ContentObject.h> + +#include <parc/algol/parc_SafeMemory.h> +#include <LongBow/unit-test.h> + +LONGBOW_TEST_RUNNER(ccnx_ContentObjectInterface) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(ccnx_ContentObjectInterface) +{ + parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory); + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_ContentObjectInterface) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// ====================================================================================== + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, ccnxContentObjectInterface_GetInterface); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +// ====================================================================================== + + +LONGBOW_TEST_CASE(Global, ccnxContentObjectInterface_GetInterface) +{ + CCNxName *name = ccnxName_CreateFromCString("lci:/boose/roo/pie"); + + CCNxContentObject *contentObjectV1 = + ccnxContentObject_CreateWithImplAndPayload(&CCNxContentObjectFacadeV1_Implementation, + name, + CCNxPayloadType_DATA, + NULL); + + assertTrue(ccnxContentObjectInterface_GetInterface(contentObjectV1) == &CCNxContentObjectFacadeV1_Implementation, + "Expected V1 Implementation"); + + // Now unset the pointer and see if it gets derived properly. + ccnxTlvDictionary_SetMessageInterface(contentObjectV1, NULL); + assertTrue(ccnxContentObjectInterface_GetInterface(contentObjectV1) == &CCNxContentObjectFacadeV1_Implementation, + "Expected V1 Implementation"); + + + ccnxName_Release(&name); + ccnxContentObject_Release(&contentObjectV1); +} + + +// ====================================================================================== + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_ContentObjectInterface); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libccnx-common/ccnx/common/internal/test/test_ccnx_InterestFacadeV1.c b/libccnx-common/ccnx/common/internal/test/test_ccnx_InterestFacadeV1.c new file mode 100755 index 00000000..477b963d --- /dev/null +++ b/libccnx-common/ccnx/common/internal/test/test_ccnx_InterestFacadeV1.c @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + */ + +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. +#include "../ccnx_InterestFacadeV1.c" +#include <parc/algol/parc_SafeMemory.h> +#include <LongBow/unit-test.h> + +#include <ccnx/common/ccnx_Interest.h> + +typedef struct test_data { + CCNxTlvDictionary *interest; + + CCNxName *name; + PARCBuffer *keyid; + PARCBuffer *contentObjectHash; + PARCBuffer *payload; + + // allocated data + uint8_t keyidArray[32]; + uint8_t contentObjectHashArray[32]; + uint8_t payloadArray[128]; + + uint32_t lifetime; + uint32_t hoplimit; +} TestData; + +static TestData * +_commonSetup(void) +{ + TestData *data = parcMemory_AllocateAndClear(sizeof(TestData)); + assertNotNull(data, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(TestData)); + data->name = ccnxName_CreateFromCString("lci:/once/upon/a/time"); + + for (int i = 0; i < 32; i++) { + data->keyidArray[i] = i * 7; + data->contentObjectHashArray[i] = i * 11; + } + + for (int i = 0; i < 128; i++) { + data->payloadArray[i] = i * 13; + } + + data->keyid = parcBuffer_Wrap(data->keyidArray, 32, 0, 32); + data->contentObjectHash = parcBuffer_Wrap(data->contentObjectHashArray, 32, 0, 32); + data->payload = parcBuffer_Wrap(data->payloadArray, 128, 0, 128); + + data->lifetime = 900; + data->hoplimit = 77; + + data->interest = _ccnxInterestFacadeV1_Create(data->name, + data->lifetime, + data->keyid, + data->contentObjectHash, + data->hoplimit); + + _ccnxInterestFacadeV1_SetPayload(data->interest, data->payload); + + return data; +} + +static void +_commonTeardown(TestData *data) +{ + ccnxName_Release(&data->name); + parcBuffer_Release(&data->keyid); + parcBuffer_Release(&data->contentObjectHash); + parcBuffer_Release(&data->payload); + ccnxTlvDictionary_Release(&data->interest); + + parcMemory_Deallocate((void **) &data); +} + +LONGBOW_TEST_RUNNER(ccnx_InterestFacadeV1) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Performance); + + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(ccnx_InterestFacadeV1) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_InterestFacadeV1) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// ======================================================================================== + +LONGBOW_TEST_FIXTURE(Performance) +{ + LONGBOW_RUN_TEST_CASE(Performance, newfangled); +// LONGBOW_RUN_TEST_CASE(Performance, oldtimey); +} + +LONGBOW_TEST_FIXTURE_SETUP(Performance) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Performance) +{ + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Performance, newfangled) +{ + uint8_t keyidArray[32]; + for (int i = 0; i < 32; i++) { + keyidArray[i] = i; + } + + PARCBuffer *keyid = parcBuffer_Wrap(keyidArray, 32, 0, 32); + CCNxName *name = ccnxName_CreateFromCString("lci:/dark/and/stormy/bits"); + + struct timeval t0, t1; + unsigned trials = 10000; + gettimeofday(&t0, NULL); + for (int i = 0; i < trials; i++) { + CCNxTlvDictionary *interest = _ccnxInterestFacadeV1_Create(name, + CCNxInterestDefault_LifetimeMilliseconds, + keyid, + NULL, + 0x45); + + ccnxTlvDictionary_Release(&interest); + } + gettimeofday(&t1, NULL); + timersub(&t1, &t0, &t1); + double seconds = t1.tv_sec + t1.tv_usec * 1E-6; + printf("\nNewFangled iterations %u seconds %.3f msg/sec %.3f\n", trials, seconds, trials / seconds); + + ccnxName_Release(&name); + parcBuffer_Release(&keyid); +} + + +// ======================================================================================== + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, ccnxInterestFacadeV1_CreateSimple); + LONGBOW_RUN_TEST_CASE(Global, ccnxInterestFacadeV1_GetContentObjectHash); + LONGBOW_RUN_TEST_CASE(Global, ccnxInterestFacadeV1_GetHopLimit); + LONGBOW_RUN_TEST_CASE(Global, ccnxInterestFacadeV1_GetInterestLifetime); + LONGBOW_RUN_TEST_CASE(Global, ccnxInterestFacadeV1_GetName); + LONGBOW_RUN_TEST_CASE(Global, ccnxInterestFacadeV1_GetPayload); + LONGBOW_RUN_TEST_CASE(Global, ccnxInterestFacadeV1_GetPublisherPublicKeyDigest); + LONGBOW_RUN_TEST_CASE(Global, ccnxInterestFacadeV1_AssertValid); + LONGBOW_RUN_TEST_CASE(Global, ccnxInterestFacadeV1_Display); + + LONGBOW_RUN_TEST_CASE(Global, ccnxInterestFacadeV1_Equals); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + longBowTestCase_SetClipBoardData(testCase, _commonSetup()); + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + _commonTeardown(longBowTestCase_GetClipBoardData(testCase)); + + if (parcSafeMemory_ReportAllocation(STDOUT_FILENO) != 0) { + printf("('%s' leaks memory by %d (allocs - frees)) ", longBowTestCase_GetName(testCase), parcMemory_Outstanding()); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, ccnxInterestFacadeV1_CreateSimple) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + CCNxTlvDictionary *interest = _ccnxInterestFacadeV1_CreateSimple(data->name); + + CCNxName *test = _ccnxInterestFacadeV1_GetName(interest); + assertTrue(ccnxName_Equals(test, data->name), "Names do not match"); + ccnxTlvDictionary_Release(&interest); +} + +LONGBOW_TEST_CASE(Global, ccnxInterestFacadeV1_GetContentObjectHash) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *test = _ccnxInterestFacadeV1_GetContentObjectHashRestriction(data->interest); + assertTrue(parcBuffer_Equals(test, data->contentObjectHash), "ContentObjectHashes do not match") + { + printf("\ngot : \n"); parcBuffer_Display(test, 3); + printf("\nexpected: \n"); parcBuffer_Display(data->contentObjectHash, 3); + } +} + +LONGBOW_TEST_CASE(Global, ccnxInterestFacadeV1_GetHopLimit) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + unsigned test = (unsigned) _ccnxInterestFacadeV1_GetHopLimit(data->interest); + assertTrue(test == data->hoplimit, "Wrong hoplimit: got %u expected %u", test, data->hoplimit); +} + +LONGBOW_TEST_CASE(Global, ccnxInterestFacadeV1_GetInterestLifetime) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + unsigned test = (unsigned) _ccnxInterestFacadeV1_GetLifetime(data->interest); + assertTrue(test == data->lifetime, "Wrong lifetime: got %u expected %u", test, data->lifetime); +} + +LONGBOW_TEST_CASE(Global, ccnxInterestFacadeV1_AssertValid) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + _ccnxInterestFacadeV1_Display(data->interest, 4); +} + +LONGBOW_TEST_CASE(Global, ccnxInterestFacadeV1_Display) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + _ccnxInterestFacadeV1_AssertValid(data->interest); +} + +LONGBOW_TEST_CASE(Global, ccnxInterestFacadeV1_GetName) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + CCNxName *test = _ccnxInterestFacadeV1_GetName(data->interest); + assertTrue(ccnxName_Equals(test, data->name), "Names do not match") + { + printf("\ngot : \n"); ccnxName_Display(test, 3); + printf("\nexpected: \n"); ccnxName_Display(data->name, 3); + } +} + +LONGBOW_TEST_CASE(Global, ccnxInterestFacadeV1_GetPublisherPublicKeyDigest) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *test = _ccnxInterestFacadeV1_GetKeyIdRestriction(data->interest); + assertTrue(parcBuffer_Equals(test, data->keyid), "KeyIDs do not match") + { + printf("\ngot : \n"); parcBuffer_Display(test, 3); + printf("\nexpected: \n"); parcBuffer_Display(data->keyid, 3); + } +} + +LONGBOW_TEST_CASE(Global, ccnxInterestFacadeV1_GetPayload) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *test = _ccnxInterestFacadeV1_GetPayload(data->interest); + assertTrue(parcBuffer_Equals(test, data->payload), "Payloads do not match") + { + printf("\ngot : \n"); parcBuffer_Display(test, 3); + printf("\nexpected: \n"); parcBuffer_Display(data->payload, 3); + } +} + +LONGBOW_TEST_CASE(Global, ccnxInterestFacadeV1_Equals) +{ + CCNxName *name1 = ccnxName_CreateFromCString("lci:/name/1"); + CCNxName *name2 = ccnxName_CreateFromCString("lci:/name/2"); + + CCNxTlvDictionary *x = _ccnxInterestFacadeV1_CreateSimple(name1); // same + CCNxTlvDictionary *y = _ccnxInterestFacadeV1_CreateSimple(name1); // same + CCNxTlvDictionary *z = _ccnxInterestFacadeV1_CreateSimple(name1); // same + + CCNxTlvDictionary *diff = _ccnxInterestFacadeV1_CreateSimple(name2); // different + + assertEqualsContract(_ccnxInterestFacadeV1_Equals, x, y, z, diff); + + ccnxTlvDictionary_Release(&x); + ccnxTlvDictionary_Release(&y); + ccnxTlvDictionary_Release(&z); + ccnxTlvDictionary_Release(&diff); + + ccnxName_Release(&name1); + ccnxName_Release(&name2); +} + + +// ======================================================================================== + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_InterestFacadeV1); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libccnx-common/ccnx/common/internal/test/test_ccnx_InterestInterface.c b/libccnx-common/ccnx/common/internal/test/test_ccnx_InterestInterface.c new file mode 100755 index 00000000..67bde1f5 --- /dev/null +++ b/libccnx-common/ccnx/common/internal/test/test_ccnx_InterestInterface.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + */ + +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. + +#include <config.h> +#include <LongBow/unit-test.h> + +#include "../ccnx_InterestInterface.c" + +#include <stdio.h> + +#include <ccnx/common/ccnx_Interest.h> +#include <ccnx/common/internal/ccnx_InterestDefault.h> + +#include <parc/algol/parc_SafeMemory.h> + + +LONGBOW_TEST_RUNNER(ccnx_InterestInterface) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(ccnx_InterestInterface) +{ + parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory); + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_InterestInterface) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// ====================================================================================== + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, ccnxInterestInterface_GetInterface); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +// ====================================================================================== + + +LONGBOW_TEST_CASE(Global, ccnxInterestInterface_GetInterface) +{ + CCNxName *name = ccnxName_CreateFromCString("lci:/boose/roo/pie"); + + CCNxInterest *interestV1 = + ccnxInterest_CreateWithImpl(&CCNxInterestFacadeV1_Implementation, + name, + CCNxInterestDefault_LifetimeMilliseconds, + NULL, + NULL, + CCNxInterestDefault_HopLimit); + + CCNxInterestInterface *interface = ccnxInterestInterface_GetInterface(interestV1); + assertTrue(interface == &CCNxInterestFacadeV1_Implementation, "Expected V1 Implementation"); + + ccnxName_Release(&name); + ccnxInterest_Release(&interestV1); +} + + +// ====================================================================================== + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_InterestInterface); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libccnx-common/ccnx/common/internal/test/test_ccnx_InterestReturnFacadeV1.c b/libccnx-common/ccnx/common/internal/test/test_ccnx_InterestReturnFacadeV1.c new file mode 100755 index 00000000..1372a750 --- /dev/null +++ b/libccnx-common/ccnx/common/internal/test/test_ccnx_InterestReturnFacadeV1.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + */ + +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. +#include "../ccnx_InterestReturnFacadeV1.c" +#include "../ccnx_InterestFacadeV1.h" +#include <parc/algol/parc_SafeMemory.h> +#include <LongBow/unit-test.h> + +#include <ccnx/common/ccnx_Interest.h> +#include <ccnx/common/ccnx_InterestReturn.h> +#include <ccnx/common/ccnx_PayloadType.h> + +typedef struct test_data { + CCNxTlvDictionary *interest; + + CCNxName *name; + PARCBuffer *keyid; + PARCBuffer *contentObjectHash; + PARCBuffer *payload; + + // allocated data + uint8_t keyidArray[32]; + uint8_t contentObjectHashArray[32]; + uint8_t payloadArray[128]; + + uint32_t lifetime; + uint32_t hoplimit; + CCNxPayloadType payloadType; +} TestData; + + +LONGBOW_TEST_RUNNER(ccnx_InterestReturnFacadeV1) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(ccnx_InterestReturnFacadeV1) +{ + parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory); + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_InterestReturnFacadeV1) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// ======================================================================================== + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, ccnxInterestReturnFacadeV1_Create); + LONGBOW_RUN_TEST_CASE(Global, ccnxInterestReturnFacadeV1_GetReturnCode); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + TestData *data = parcMemory_AllocateAndClear(sizeof(TestData)); + assertNotNull(data, "parcMemory_AllocateAndClear(%lu) returned NULL", sizeof(TestData)); + data->name = ccnxName_CreateFromCString("lci:/once/upon/a/time"); + + for (int i = 0; i < 32; i++) { + data->keyidArray[i] = i * 7; + data->contentObjectHashArray[i] = i * 11; + } + + for (int i = 0; i < 128; i++) { + data->payloadArray[i] = i * 13; + } + + data->keyid = parcBuffer_Wrap(data->keyidArray, 32, 0, 32); + data->contentObjectHash = parcBuffer_Wrap(data->contentObjectHashArray, 32, 0, 32); + data->payloadType = CCNxPayloadType_DATA; + data->payload = parcBuffer_Wrap(data->payloadArray, 128, 0, 128); + + data->lifetime = 900; + data->hoplimit = 77; + + data->interest = ccnxInterest_Create(data->name, + data->lifetime, + data->keyid, + data->contentObjectHash); + + ccnxInterest_SetPayload(data->interest, data->payload); + + longBowTestCase_SetClipBoardData(testCase, data); + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + ccnxName_Release(&data->name); + parcBuffer_Release(&data->keyid); + parcBuffer_Release(&data->contentObjectHash); + parcBuffer_Release(&data->payload); + ccnxTlvDictionary_Release(&data->interest); + + parcMemory_Deallocate((void **) &data); + + if (parcSafeMemory_ReportAllocation(STDOUT_FILENO) != 0) { + printf("('%s' leaks memory by %d (allocs - frees)) ", longBowTestCase_GetName(testCase), parcMemory_Outstanding()); + return LONGBOW_STATUS_TEARDOWN_FAILED; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, ccnxInterestReturnFacadeV1_Create) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + + CCNxTlvDictionary *interestReturn = + _ccnxInterestReturnFacadeV1_Create(data->interest, CCNxInterestReturn_ReturnCode_NoRoute); + assertNotNull(interestReturn, "Expect non-NULL interestReturn"); + _ccnxInterestReturnFacadeV1_AssertValid(interestReturn); + + CCNxInterestReturn_ReturnCode code = _ccnxInterestReturnFacadeV1_GetReturnCode(interestReturn); + assertTrue((CCNxInterestReturn_ReturnCode_NoRoute == code), "InterestReturn wrong Return Code"); + ccnxTlvDictionary_Release(&interestReturn); +} + +LONGBOW_TEST_CASE(Global, ccnxInterestReturnFacadeV1_GetReturnCode) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + + CCNxTlvDictionary *interestReturn = + _ccnxInterestReturnFacadeV1_Create(data->interest, CCNxInterestReturn_ReturnCode_NoRoute); + _ccnxInterestReturnFacadeV1_AssertValid(interestReturn); + + CCNxInterestReturn_ReturnCode code = + _ccnxInterestReturnFacadeV1_GetReturnCode(interestReturn); + + assertTrue((CCNxInterestReturn_ReturnCode_NoRoute == code), "InterestReturn wrong Return Code"); + ccnxTlvDictionary_Release(&interestReturn); +} + + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_InterestReturnFacadeV1); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libccnx-common/ccnx/common/internal/test/test_ccnx_InterestReturnInterface.c b/libccnx-common/ccnx/common/internal/test/test_ccnx_InterestReturnInterface.c new file mode 100755 index 00000000..a22ab4e9 --- /dev/null +++ b/libccnx-common/ccnx/common/internal/test/test_ccnx_InterestReturnInterface.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + */ + +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. +#include "../ccnx_InterestReturnInterface.c" + +#include <ccnx/common/ccnx_InterestReturn.h> +#include <ccnx/common/internal/ccnx_InterestDefault.h> + +#include <parc/algol/parc_SafeMemory.h> +#include <LongBow/unit-test.h> + +#include <stdio.h> + +LONGBOW_TEST_RUNNER(ccnx_InterestReturnInterface) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(ccnx_InterestReturnInterface) +{ + parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory); + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_InterestReturnInterface) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// ====================================================================================== + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, ccnxInterestReturnInterface_GetImplementation); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +// ====================================================================================== + + +LONGBOW_TEST_CASE(Global, ccnxInterestReturnInterface_GetImplementation) +{ + CCNxName *name = ccnxName_CreateFromCString("lci:/boose/roo/pie"); + + CCNxInterest *interestV1 = + ccnxInterest_CreateWithImpl(&CCNxInterestFacadeV1_Implementation, + name, + CCNxInterestDefault_LifetimeMilliseconds, + NULL, + NULL, + CCNxInterestDefault_HopLimit); + ccnxName_Release(&name); + + CCNxInterestReturn *interestReturn = ccnxInterestReturn_Create(interestV1, CCNxInterestReturn_ReturnCode_Congestion); + + assertTrue(ccnxInterestReturnInterface_GetInterface(interestReturn) == &CCNxInterestReturnFacadeV1_Implementation, + "Expected V1 Implementation"); + + // Now unset the pointer and see if it gets derived properly. + ccnxTlvDictionary_SetMessageInterface(interestReturn, NULL); + + assertTrue(ccnxInterestReturnInterface_GetInterface(interestReturn) == &CCNxInterestReturnFacadeV1_Implementation, + "Expected V1 Implementation"); + + ccnxInterestReturn_Release(&interestReturn); + ccnxInterest_Release(&interestV1); +} + + +// ====================================================================================== + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_InterestReturnInterface); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libccnx-common/ccnx/common/internal/test/test_ccnx_ManifestFacadeV1.c.c b/libccnx-common/ccnx/common/internal/test/test_ccnx_ManifestFacadeV1.c.c new file mode 100644 index 00000000..253b8e5a --- /dev/null +++ b/libccnx-common/ccnx/common/internal/test/test_ccnx_ManifestFacadeV1.c.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + */ + +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. +#include "../ccnx_ManifestFacadeV1.c" +#include <parc/algol/parc_SafeMemory.h> +#include <parc/algol/parc_Memory.h> +#include <LongBow/unit-test.h> + +#include <ccnx/common/ccnx_Manifest.h> + +typedef struct test_data { + CCNxTlvDictionary *manifest; + + CCNxName *name; +} TestData; + +static TestData * +_commonSetup(void) +{ + TestData *data = parcMemory_AllocateAndClear(sizeof(TestData)); + assertNotNull(data, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(TestData)); + + data->name = ccnxName_CreateFromCString("lci:/once/upon/a/time"); + data->manifest = _ccnxManifestFacadeV1_Create(data->name); + + return data; +} + +static void +_commonTeardown(TestData *data) +{ + ccnxName_Release(&data->name); + ccnxTlvDictionary_Release(&data->manifest); + + parcMemory_Deallocate((void **) &data); +} + +LONGBOW_TEST_RUNNER(ccnx_ManifestFacadeV1) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(ccnx_ManifestFacadeV1) +{ + parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory); + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_ManifestFacadeV1) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// ======================================================================================== + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, ccnxManifestFacadeV1_Create); + LONGBOW_RUN_TEST_CASE(Global, ccnxManifestFacadeV1_GetName); + LONGBOW_RUN_TEST_CASE(Global, ccnxManifestFacadeV1_AddHashGroup); + LONGBOW_RUN_TEST_CASE(Global, ccnxManifestFacadeV1_GetHashGroup); + LONGBOW_RUN_TEST_CASE(Global, ccnxManifestFacadeV1_Equals); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + longBowTestCase_SetClipBoardData(testCase, _commonSetup()); + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + _commonTeardown(longBowTestCase_GetClipBoardData(testCase)); + + if (parcSafeMemory_ReportAllocation(STDOUT_FILENO) != 0) { + printf("('%s' leaks memory by %d (allocs - frees)) ", longBowTestCase_GetName(testCase), parcMemory_Outstanding()); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, ccnxManifestFacadeV1_Create) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + CCNxTlvDictionary *manifest = _ccnxManifestFacadeV1_Create(data->name); + + const CCNxName *test = _ccnxManifestFacadeV1_GetName(manifest); + assertTrue(ccnxName_Equals(test, data->name), "Names do not match"); + ccnxTlvDictionary_Release(&manifest); +} + +LONGBOW_TEST_CASE(Global, ccnxManifestFacadeV1_AddHashGroup) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + CCNxTlvDictionary *manifest = _ccnxManifestFacadeV1_Create(data->name); + + int actual = 0; + int numberOfGroups = _ccnxManifestFacadeV1_GetNumberOfHashGroups(manifest); + assertTrue(numberOfGroups == actual, "Expected %d, got %d", actual, numberOfGroups); + + CCNxManifestHashGroup *hashGroup = ccnxManifestHashGroup_Create(); + _ccnxManifestFacadeV1_AddHashGroup(manifest, hashGroup); + actual++; + numberOfGroups = _ccnxManifestFacadeV1_GetNumberOfHashGroups(manifest); + + assertTrue(numberOfGroups == actual, "Expected %d, got %d", actual, numberOfGroups); + + ccnxManifestHashGroup_Release(&hashGroup); + ccnxTlvDictionary_Release(&manifest); +} + +LONGBOW_TEST_CASE(Global, ccnxManifestFacadeV1_GetHashGroup) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + CCNxTlvDictionary *manifest = _ccnxManifestFacadeV1_Create(data->name); + + CCNxManifestHashGroup *hashGroup = ccnxManifestHashGroup_Create(); + _ccnxManifestFacadeV1_AddHashGroup(manifest, hashGroup); + + CCNxManifestHashGroup *firstGroup = _ccnxManifestFacadeV1_GetHashGroup(manifest, 0); + assertTrue(ccnxManifestHashGroup_Equals(hashGroup, firstGroup), "Expected the HashGroups to be equal"); + + ccnxManifestHashGroup_Release(&hashGroup); + ccnxManifestHashGroup_Release(&firstGroup); + ccnxTlvDictionary_Release(&manifest); +} + +LONGBOW_TEST_CASE(Global, ccnxManifestFacadeV1_GetNumberOfHashGroups) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + CCNxTlvDictionary *manifest = _ccnxManifestFacadeV1_Create(data->name); + + size_t numberOfGroups = _ccnxManifestFacadeV1_GetNumberOfHashGroups(manifest); + assertTrue(numberOfGroups == 1, "Expected 1 group, got %zu", numberOfGroups); + ccnxTlvDictionary_Release(&manifest); +} + +LONGBOW_TEST_CASE(Global, ccnxManifestFacadeV1_GetName) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + const CCNxName *test = _ccnxManifestFacadeV1_GetName(data->manifest); + assertTrue(ccnxName_Equals(test, data->name), "Names do not match") + { + printf("\ngot : \n"); ccnxName_Display(test, 3); + printf("\nexpected: \n"); ccnxName_Display(data->name, 3); + } +} + +LONGBOW_TEST_CASE(Global, ccnxManifestFacadeV1_Equals) +{ + CCNxName *name1 = ccnxName_CreateFromCString("lci:/name/1"); + CCNxName *name2 = ccnxName_CreateFromCString("lci:/name/2"); + + CCNxTlvDictionary *x = _ccnxManifestFacadeV1_Create(name1); + CCNxTlvDictionary *y = _ccnxManifestFacadeV1_Create(name1); + CCNxTlvDictionary *z = _ccnxManifestFacadeV1_Create(name1); + + CCNxTlvDictionary *diff = _ccnxManifestFacadeV1_Create(name2); + + assertEqualsContract(_ccnxManifestFacadeV1_Equals, x, y, z, diff, NULL); + + ccnxTlvDictionary_Release(&x); + ccnxTlvDictionary_Release(&y); + ccnxTlvDictionary_Release(&z); + ccnxTlvDictionary_Release(&diff); + + ccnxName_Release(&name1); + ccnxName_Release(&name2); +} + +// ======================================================================================== + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_ManifestFacadeV1); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libccnx-common/ccnx/common/internal/test/test_ccnx_ManifestInterface.c.c b/libccnx-common/ccnx/common/internal/test/test_ccnx_ManifestInterface.c.c new file mode 100755 index 00000000..42ce095f --- /dev/null +++ b/libccnx-common/ccnx/common/internal/test/test_ccnx_ManifestInterface.c.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + */ + +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. +#include "../ccnx_ManifestInterface.c" + +#include <ccnx/common/ccnx_Manifest.h> + +#include <parc/algol/parc_SafeMemory.h> +#include <LongBow/unit-test.h> + +#include <stdio.h> + +LONGBOW_TEST_RUNNER(ccnx_ManifestInterface) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(ccnx_ManifestInterface) +{ + parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory); + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_ManifestInterface) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// ====================================================================================== + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, ccnxManifestInterface_GetImplementation); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +// ====================================================================================== + + +LONGBOW_TEST_CASE(Global, ccnxManifestInterface_GetImplementation) +{ + CCNxName *name = ccnxName_CreateFromCString("lci:/boose/roo/pie"); + + CCNxManifest *manifestV1 = ccnxManifest_Create(name); + ccnxName_Release(&name); + + assertTrue(ccnxManifestInterface_GetInterface(manifestV1) == &CCNxManifestFacadeV1_Interface, "Expected V1 Implementation"); + + // Now unset the pointer and see if it gets derived properly. + ccnxTlvDictionary_SetMessageInterface(manifestV1, NULL); + + assertTrue(ccnxManifestInterface_GetInterface(manifestV1) == &CCNxManifestFacadeV1_Interface, "Expected V1 Implementation"); + + ccnxManifest_Release(&manifestV1); +} + + +// ====================================================================================== + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_ManifestInterface); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libccnx-common/ccnx/common/internal/test/test_ccnx_TlvDictionary.c b/libccnx-common/ccnx/common/internal/test/test_ccnx_TlvDictionary.c new file mode 100755 index 00000000..51936d96 --- /dev/null +++ b/libccnx-common/ccnx/common/internal/test/test_ccnx_TlvDictionary.c @@ -0,0 +1,1142 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + */ + +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. +#include "../ccnx_TlvDictionary.c" +#include <parc/algol/parc_SafeMemory.h> + +#include <ccnx/common/internal/ccnx_ContentObjectInterface.h> +#include <ccnx/common/internal/ccnx_InterestInterface.h> + +#include <LongBow/unit-test.h> + +typedef struct test_data { + CCNxTlvDictionary *dictionary; + size_t fastArraySize; + size_t listSize; +} TestData; + +typedef enum { + SchemaFree = 0, + SchemaBuffer = 1, + SchemaInteger = 2, + SchemaIoVec = 3, + SchemaJson = 4, + SchemaName = 5, + SchemaEnd = 6, +} TestSchema; + +static CCNxCodecNetworkBufferIoVec * +createIoVec(void) +{ + CCNxCodecNetworkBuffer *netbuff = ccnxCodecNetworkBuffer_Create(&ParcMemoryMemoryBlock, NULL); + CCNxCodecNetworkBufferIoVec *vec = ccnxCodecNetworkBuffer_CreateIoVec(netbuff); + ccnxCodecNetworkBuffer_Release(&netbuff); + return vec; +} + +static TestData * +_commonSetup(void) +{ + TestData *data = parcMemory_AllocateAndClear(sizeof(TestData)); + assertNotNull(data, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(TestData)); + data->fastArraySize = SchemaEnd + 2; + data->listSize = SchemaEnd + 10; + data->dictionary = ccnxTlvDictionary_Create(data->fastArraySize, data->listSize); + + // populate the know test vectors + PARCBuffer *buffer = parcBuffer_Allocate(5); + ccnxTlvDictionary_PutBuffer(data->dictionary, SchemaBuffer, buffer); + parcBuffer_Release(&buffer); + + ccnxTlvDictionary_PutInteger(data->dictionary, SchemaInteger, 42); + + CCNxCodecNetworkBufferIoVec *vec = createIoVec(); + ccnxTlvDictionary_PutIoVec(data->dictionary, SchemaIoVec, vec); + ccnxCodecNetworkBufferIoVec_Release(&vec); + + PARCJSON *json = parcJSON_ParseString("{\"KEY\": \"VALUE\"}"); + ccnxTlvDictionary_PutJson(data->dictionary, SchemaJson, json); + parcJSON_Release(&json); + + CCNxName *name = ccnxName_CreateFromCString("lci:/great/gatsby"); + ccnxTlvDictionary_PutName(data->dictionary, SchemaName, name); + ccnxName_Release(&name); + + return data; +} + +static void +_commonTeardown(TestData *data) +{ + ccnxTlvDictionary_Release(&data->dictionary); + parcMemory_Deallocate((void **) &data); +} + +// ============================================================= + +LONGBOW_TEST_RUNNER(rta_TlvDictionary) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(KnownKeys); + LONGBOW_RUN_TEST_FIXTURE(UnknownKeys); + LONGBOW_RUN_TEST_FIXTURE(Local); + + // type specific tests + LONGBOW_RUN_TEST_FIXTURE(Buffer); + LONGBOW_RUN_TEST_FIXTURE(Integer); + LONGBOW_RUN_TEST_FIXTURE(IoVec); + LONGBOW_RUN_TEST_FIXTURE(Json); + LONGBOW_RUN_TEST_FIXTURE(Name); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(rta_TlvDictionary) +{ + parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory); + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(rta_TlvDictionary) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// ============================================================= + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, ccnxTlvDictionary_Performance); + LONGBOW_RUN_TEST_CASE(Global, ccnxTlvDictionary_Acquire); + LONGBOW_RUN_TEST_CASE(Global, ccnxTlvDictionary_Create); + LONGBOW_RUN_TEST_CASE(Global, ccnxTlvDictionary_Release); + LONGBOW_RUN_TEST_CASE(Global, ccnxTlvDictionary_SetMessageType_ContentObject); + LONGBOW_RUN_TEST_CASE(Global, ccnxTlvDictionary_SetMessageType_Interest); + LONGBOW_RUN_TEST_CASE(Global, ccnxTlvDictionary_SetMessageType_Control); + LONGBOW_RUN_TEST_CASE(Global, ccnxTlvDictionary_SetMessageType_InterestReturn); + LONGBOW_RUN_TEST_CASE(Global, ccnxTlvDictionary_SetGetMessageTypeImplementation); + + + LONGBOW_RUN_TEST_CASE(Global, ccnxTlvDictionary_Equals); + LONGBOW_RUN_TEST_CASE(Global, ccnxTlvDictionary_ShallowCopy); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + longBowTestCase_SetClipBoardData(testCase, _commonSetup()); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + _commonTeardown(longBowTestCase_GetClipBoardData(testCase)); + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, ccnxTlvDictionary_Performance) +{ + int reps = 100000; + struct timeval t0, t1; + gettimeofday(&t0, NULL); + for (int i = 0; i < reps; i++) { + CCNxTlvDictionary *dictionary = ccnxTlvDictionary_Create(10, 20); + ccnxTlvDictionary_Release(&dictionary); + } + gettimeofday(&t1, NULL); + timersub(&t1, &t0, &t1); + double seconds = t1.tv_sec + t1.tv_usec * 1E-6; + + printf("time %.6f seconds, tps = %.2f\n", seconds, (double) reps / seconds); +} + +LONGBOW_TEST_CASE(Global, ccnxTlvDictionary_Acquire) +{ + CCNxTlvDictionary *first = ccnxTlvDictionary_Create(10, 20); + CCNxTlvDictionary *second = ccnxTlvDictionary_Acquire(first); + + assertTrue(parcObject_GetReferenceCount(first) == 2, "Wrong ref count, got %" PRIu64 " expected %u", parcObject_GetReferenceCount(first), 2); + + ccnxTlvDictionary_Release(&second); + ccnxTlvDictionary_Release(&first); +} + +LONGBOW_TEST_CASE(Global, ccnxTlvDictionary_Create) +{ + CCNxTlvDictionary *dictionary = ccnxTlvDictionary_Create(20, 30); + assertNotNull(dictionary, "Got null dictionary from Create"); + assertNotNull(dictionary->directArray, "DirectArray is null"); + assertNotNull(dictionary->fixedListHeads, "fixedListHeads is null"); + + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Global, ccnxTlvDictionary_Release) +{ + CCNxTlvDictionary *dictionary = ccnxTlvDictionary_Create(1, 1); + ccnxTlvDictionary_Release(&dictionary); + assertNull(dictionary, "Release did not null argument"); +} + +LONGBOW_TEST_CASE(Global, ccnxTlvDictionary_SetMessageType_ContentObject) +{ + CCNxTlvDictionary *dictionary = ccnxTlvDictionary_Create(1, 1); + ccnxTlvDictionary_SetMessageType_ContentObject(dictionary, CCNxTlvDictionary_SchemaVersion_V1); + assertTrue(ccnxTlvDictionary_IsContentObject(dictionary), "Wrong message type"); + assertFalse(ccnxTlvDictionary_IsControl(dictionary), "Wrong message type"); + assertFalse(ccnxTlvDictionary_IsInterest(dictionary), "Wrong message type"); + assertFalse(ccnxTlvDictionary_IsInterestReturn(dictionary), "Wrong message type"); + assertTrue(ccnxTlvDictionary_GetSchemaVersion(dictionary) == CCNxTlvDictionary_SchemaVersion_V1, "Wrong schema type"); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Global, ccnxTlvDictionary_SetMessageType_Interest) +{ + CCNxTlvDictionary *dictionary = ccnxTlvDictionary_Create(1, 1); + ccnxTlvDictionary_SetMessageType_Interest(dictionary, CCNxTlvDictionary_SchemaVersion_V1); + assertFalse(ccnxTlvDictionary_IsContentObject(dictionary), "Wrong message type"); + assertFalse(ccnxTlvDictionary_IsControl(dictionary), "Wrong message type"); + assertTrue(ccnxTlvDictionary_IsInterest(dictionary), "Wrong message type"); + assertFalse(ccnxTlvDictionary_IsInterestReturn(dictionary), "Wrong message type"); + assertTrue(ccnxTlvDictionary_GetSchemaVersion(dictionary) == CCNxTlvDictionary_SchemaVersion_V1, "Wrong schema type"); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Global, ccnxTlvDictionary_SetMessageType_Control) +{ + CCNxTlvDictionary *dictionary = ccnxTlvDictionary_Create(1, 1); + ccnxTlvDictionary_SetMessageType_Control(dictionary, CCNxTlvDictionary_SchemaVersion_V1); + assertFalse(ccnxTlvDictionary_IsContentObject(dictionary), "Wrong message type"); + assertTrue(ccnxTlvDictionary_IsControl(dictionary), "Wrong message type"); + assertFalse(ccnxTlvDictionary_IsInterest(dictionary), "Wrong message type"); + assertFalse(ccnxTlvDictionary_IsInterestReturn(dictionary), "Wrong message type"); + assertTrue(ccnxTlvDictionary_GetSchemaVersion(dictionary) == CCNxTlvDictionary_SchemaVersion_V1, "Wrong schema type"); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Global, ccnxTlvDictionary_SetMessageType_InterestReturn) +{ + CCNxTlvDictionary *dictionary = ccnxTlvDictionary_Create(1, 1); + ccnxTlvDictionary_SetMessageType_InterestReturn(dictionary, CCNxTlvDictionary_SchemaVersion_V1); + assertFalse(ccnxTlvDictionary_IsContentObject(dictionary), "Wrong message type"); + assertFalse(ccnxTlvDictionary_IsControl(dictionary), "Wrong message type"); + assertFalse(ccnxTlvDictionary_IsInterest(dictionary), "Wrong message type"); + assertTrue(ccnxTlvDictionary_IsInterestReturn(dictionary), "Wrong message type"); + assertTrue(ccnxTlvDictionary_GetSchemaVersion(dictionary) == CCNxTlvDictionary_SchemaVersion_V1, "Wrong schema type"); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Global, ccnxTlvDictionary_SetGetMessageTypeImplementation) +{ + CCNxTlvDictionary *dictionary = ccnxTlvDictionary_Create(1, 1); + void *impl = ccnxTlvDictionary_GetMessageInterface(dictionary); + + assertNull(impl, "Expected a NULL implementation by default"); + + ccnxTlvDictionary_SetMessageInterface(dictionary, &CCNxContentObjectFacadeV1_Implementation); + assertTrue(ccnxTlvDictionary_GetMessageInterface(dictionary) == &CCNxContentObjectFacadeV1_Implementation, + "Expected CCNxContentObjectFacadeV1_Implementation"); + + ccnxTlvDictionary_SetMessageInterface(dictionary, &CCNxContentObjectFacadeV1_Implementation); + assertTrue(ccnxTlvDictionary_GetMessageInterface(dictionary) == &CCNxContentObjectFacadeV1_Implementation, + "Expected CCNxContentObjectFacadeV1_Implementation"); + + ccnxTlvDictionary_SetMessageInterface(dictionary, &CCNxInterestFacadeV1_Implementation); + assertTrue(ccnxTlvDictionary_GetMessageInterface(dictionary) == &CCNxInterestFacadeV1_Implementation, + "Expected CCNxInterestFacadeV1_Implementation"); + + ccnxTlvDictionary_SetMessageInterface(dictionary, &CCNxInterestFacadeV1_Implementation); + assertTrue(ccnxTlvDictionary_GetMessageInterface(dictionary) == &CCNxInterestFacadeV1_Implementation, + "Expected CCNxInterestFacadeV1_Implementation"); + + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Global, ccnxTlvDictionary_Equals) +{ + CCNxTlvDictionary *a = ccnxTlvDictionary_Create(1, 1); + CCNxTlvDictionary *b = ccnxTlvDictionary_Create(1, 1); + CCNxTlvDictionary *c = ccnxTlvDictionary_Create(1, 1); + + ccnxTlvDictionary_SetMessageType_Interest(a, CCNxTlvDictionary_SchemaVersion_V1); + ccnxTlvDictionary_SetMessageType_Interest(b, CCNxTlvDictionary_SchemaVersion_V1); + ccnxTlvDictionary_SetMessageType_Interest(c, CCNxTlvDictionary_SchemaVersion_V1); + + CCNxTlvDictionary *diffArraySize = ccnxTlvDictionary_Create(2, 1); + CCNxTlvDictionary *diffListSize = ccnxTlvDictionary_Create(1, 2); + CCNxTlvDictionary *diffType = ccnxTlvDictionary_Create(1, 1); + ccnxTlvDictionary_SetMessageType_Control(diffType, CCNxTlvDictionary_SchemaVersion_V1); + + CCNxTlvDictionary *diffType2 = ccnxTlvDictionary_Create(1, 1); + ccnxTlvDictionary_SetMessageType_ContentObject(diffType2, CCNxTlvDictionary_SchemaVersion_V1); + + assertEqualsContract(ccnxTlvDictionary_Equals, a, b, c, diffArraySize, diffListSize, diffType, diffType2, NULL); + + ccnxTlvDictionary_Release(&diffType2); + ccnxTlvDictionary_Release(&diffType); + ccnxTlvDictionary_Release(&diffListSize); + ccnxTlvDictionary_Release(&diffArraySize); + ccnxTlvDictionary_Release(&c); + ccnxTlvDictionary_Release(&b); + ccnxTlvDictionary_Release(&a); +} + +LONGBOW_TEST_CASE(Global, ccnxTlvDictionary_ShallowCopy) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + + CCNxTlvDictionary *a = data->dictionary; + + PARCBuffer *buffer = parcBuffer_WrapCString("Some Stuff"); + ccnxTlvDictionary_PutListBuffer(a, SchemaEnd, 23, buffer); + parcBuffer_Release(&buffer); + + CCNxTlvDictionary *b = ccnxTlvDictionary_ShallowCopy(a); + + assertTrue(ccnxTlvDictionary_Equals(a, b), "Expected Dictionaries to be Equal after ShallowCopy"); + + ccnxTlvDictionary_Release(&b); +} + +// ================================================================ + +LONGBOW_TEST_FIXTURE(KnownKeys) +{ + LONGBOW_RUN_TEST_CASE(KnownKeys, ccnxTlvDictionary_Get_Exists); + LONGBOW_RUN_TEST_CASE(KnownKeys, ccnxTlvDictionary_Get_NotExists); + LONGBOW_RUN_TEST_CASE(KnownKeys, ccnxTlvDictionary_Put_Unique); + LONGBOW_RUN_TEST_CASE(KnownKeys, ccnxTlvDictionary_Put_Duplicate); + + LONGBOW_RUN_TEST_CASE(KnownKeys, ccnxTlvDictionary_PutList_Unique); + LONGBOW_RUN_TEST_CASE(KnownKeys, ccnxTlvDictionary_PutList_Duplicate); +} + +LONGBOW_TEST_FIXTURE_SETUP(KnownKeys) +{ + longBowTestCase_SetClipBoardData(testCase, _commonSetup()); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(KnownKeys) +{ + _commonTeardown(longBowTestCase_GetClipBoardData(testCase)); + + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(KnownKeys, ccnxTlvDictionary_Get_Exists) +{ + uint32_t key = SchemaEnd; + + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *buffer = parcBuffer_Allocate(1); + + ccnxTlvDictionary_PutBuffer(data->dictionary, key, buffer); + PARCBuffer *test = ccnxTlvDictionary_GetBuffer(data->dictionary, key); + assertTrue(test == buffer, "Get value wrong, got %p expected %p", (void *) test, (void *) buffer); + + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(KnownKeys, ccnxTlvDictionary_Get_NotExists) +{ + uint32_t key = SchemaEnd; + TestData *data = longBowTestCase_GetClipBoardData(testCase); + + PARCBuffer *buffer = parcBuffer_Allocate(1); + ccnxTlvDictionary_PutBuffer(data->dictionary, key, buffer); + PARCBuffer *test = ccnxTlvDictionary_GetBuffer(data->dictionary, key + 1); + assertNull(test, "Get for missing key should return null"); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(KnownKeys, ccnxTlvDictionary_Put_Unique) +{ + uint32_t key = SchemaEnd; + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *buffer = parcBuffer_Allocate(1); + bool success = ccnxTlvDictionary_PutBuffer(data->dictionary, key, buffer); + assertTrue(success, "Put returned false adding a unique key"); + parcBuffer_Release(&buffer); + + // one extra test particular to it being in the fast array + assertTrue(data->dictionary->directArray[key].entryType == ENTRY_BUFFER, "Not buffer type, got %d", data->dictionary->directArray[key].entryType); + assertNotNull(data->dictionary->directArray[key]._entry.buffer, "They fast array entry for key is null"); +} + +LONGBOW_TEST_CASE(KnownKeys, ccnxTlvDictionary_Put_Duplicate) +{ + uint32_t key = SchemaEnd; + + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *buffer = parcBuffer_Allocate(1); + ccnxTlvDictionary_PutBuffer(data->dictionary, key, buffer); + bool success = ccnxTlvDictionary_PutBuffer(data->dictionary, key, buffer); + assertFalse(success, "Put returned true adding a duplicate key"); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(KnownKeys, ccnxTlvDictionary_PutList_Unique) +{ + uint32_t listKey = SchemaEnd; + uint32_t bufferKey = 1000; + + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *buffer = parcBuffer_Allocate(1); + bool success = ccnxTlvDictionary_PutListBuffer(data->dictionary, listKey, bufferKey, buffer); + assertTrue(success, "Put returned false adding a unique key"); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(KnownKeys, ccnxTlvDictionary_PutList_Duplicate) +{ + uint32_t listKey = SchemaEnd; + uint32_t bufferKey = 1000; + + // its ok to have duplicates of the custom keys + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *buffer = parcBuffer_Allocate(1); + ccnxTlvDictionary_PutListBuffer(data->dictionary, listKey, bufferKey, buffer); + bool success = ccnxTlvDictionary_PutListBuffer(data->dictionary, listKey, bufferKey, buffer); + assertTrue(success, "Put returned false adding a duplicate key to list"); + parcBuffer_Release(&buffer); +} + +// ================================================================ + +LONGBOW_TEST_FIXTURE(UnknownKeys) +{ + LONGBOW_RUN_TEST_CASE(UnknownKeys, ccnxTlvDictionary_PutList_Unique); + LONGBOW_RUN_TEST_CASE(UnknownKeys, ccnxTlvDictionary_PutList_Duplicate); + + LONGBOW_RUN_TEST_CASE(UnknownKeys, ccnxTlvDictionary_ListGetByPosition); + LONGBOW_RUN_TEST_CASE(UnknownKeys, ccnxTlvDictionary_ListGetByType); + LONGBOW_RUN_TEST_CASE(UnknownKeys, ccnxTlvDictionary_ListSize); + LONGBOW_RUN_TEST_CASE(UnknownKeys, ccnxTlvDictionary_ListEquals); +} + +LONGBOW_TEST_FIXTURE_SETUP(UnknownKeys) +{ + longBowTestCase_SetClipBoardData(testCase, _commonSetup()); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(UnknownKeys) +{ + _commonTeardown(longBowTestCase_GetClipBoardData(testCase)); + + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(UnknownKeys, ccnxTlvDictionary_PutList_Unique) +{ + uint32_t listKey = FIXED_LIST_LENGTH + 1; + uint32_t bufferKey = 1000; + + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *buffer = parcBuffer_Allocate(1); + bool success = ccnxTlvDictionary_PutListBuffer(data->dictionary, listKey, bufferKey, buffer); + assertTrue(success, "Put returned false adding a unique key"); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(UnknownKeys, ccnxTlvDictionary_PutList_Duplicate) +{ + uint32_t listKey = FIXED_LIST_LENGTH + 1; + uint32_t bufferKey = 1000; + + // its ok to have duplicates of the custom keys + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *buffer = parcBuffer_Allocate(1); + ccnxTlvDictionary_PutListBuffer(data->dictionary, listKey, bufferKey, buffer); + bool success = ccnxTlvDictionary_PutListBuffer(data->dictionary, listKey, bufferKey, buffer); + assertTrue(success, "Put returned false adding a duplicate key to list"); + parcBuffer_Release(&buffer); +} + +/* + * Add 3 items to list then make sure we can retrieve the 2nd + */ +LONGBOW_TEST_CASE(UnknownKeys, ccnxTlvDictionary_ListGetByPosition) +{ + uint32_t listKey = SchemaEnd; + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *a = parcBuffer_Allocate(1); + PARCBuffer *b = parcBuffer_Allocate(1); + PARCBuffer *c = parcBuffer_Allocate(1); + + ccnxTlvDictionary_PutListBuffer(data->dictionary, listKey, 1000, a); + ccnxTlvDictionary_PutListBuffer(data->dictionary, listKey, 1001, b); + ccnxTlvDictionary_PutListBuffer(data->dictionary, listKey, 1002, c); + + PARCBuffer *test = NULL; + uint32_t testkey = 0; + ccnxTlvDictionary_ListGetByPosition(data->dictionary, listKey, 1, &test, &testkey); + + assertTrue(testkey == 1001, "Wrong key, expected %u got %u", 1001, testkey); + assertTrue(test == b, "Wrong buffer, expected %p got %p", (void *) b, (void *) test); + + parcBuffer_Release(&a); + parcBuffer_Release(&b); + parcBuffer_Release(&c); +} + +/* + * Add 3 items to list then make sure we can retrieve the 2nd + */ +LONGBOW_TEST_CASE(UnknownKeys, ccnxTlvDictionary_ListGetByType) +{ + uint32_t listKey = SchemaEnd; + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *a = parcBuffer_Allocate(1); + PARCBuffer *b = parcBuffer_Allocate(1); + PARCBuffer *c = parcBuffer_Allocate(1); + + ccnxTlvDictionary_PutListBuffer(data->dictionary, listKey, 1000, a); + ccnxTlvDictionary_PutListBuffer(data->dictionary, listKey, 1001, b); + ccnxTlvDictionary_PutListBuffer(data->dictionary, listKey, 1002, c); + + PARCBuffer *test = ccnxTlvDictionary_ListGetByType(data->dictionary, listKey, 1001); + assertTrue(test == b, "Wrong buffer, expected %p got %p", (void *) b, (void *) test); + + parcBuffer_Release(&a); + parcBuffer_Release(&b); + parcBuffer_Release(&c); +} + +LONGBOW_TEST_CASE(UnknownKeys, ccnxTlvDictionary_ListSize) +{ + uint32_t listKey = SchemaEnd; + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *a = parcBuffer_Allocate(1); + PARCBuffer *b = parcBuffer_Allocate(1); + PARCBuffer *c = parcBuffer_Allocate(1); + + ccnxTlvDictionary_PutListBuffer(data->dictionary, listKey, 1000, a); + ccnxTlvDictionary_PutListBuffer(data->dictionary, listKey, 1001, b); + ccnxTlvDictionary_PutListBuffer(data->dictionary, listKey, 1002, c); + + size_t length = ccnxTlvDictionary_ListSize(data->dictionary, listKey); + assertTrue(length == 3, "Wrong length, expected %u got %zu", 3, length); + + parcBuffer_Release(&a); + parcBuffer_Release(&b); + parcBuffer_Release(&c); +} + +LONGBOW_TEST_CASE(UnknownKeys, ccnxTlvDictionary_ListEquals) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *a = parcBuffer_Allocate(1); + PARCBuffer *b = parcBuffer_Allocate(1); + PARCBuffer *c = parcBuffer_Allocate(1); + + ccnxTlvDictionary_PutListBuffer(data->dictionary, 6, 1000, a); + ccnxTlvDictionary_PutListBuffer(data->dictionary, 6, 1001, b); + ccnxTlvDictionary_PutListBuffer(data->dictionary, 6, 1002, c); + + ccnxTlvDictionary_PutListBuffer(data->dictionary, 7, 1000, a); + ccnxTlvDictionary_PutListBuffer(data->dictionary, 7, 1001, b); + ccnxTlvDictionary_PutListBuffer(data->dictionary, 7, 1002, c); + + bool equals = _ccnxTlvDictionary_ListEquals(_getListHead(data->dictionary, 6), _getListHead(data->dictionary, 7)); + assertTrue(equals, "Lists should be equal"); + + parcBuffer_Release(&a); + parcBuffer_Release(&b); + parcBuffer_Release(&c); +} + + + +// ============================================================= + +LONGBOW_TEST_FIXTURE(Buffer) +{ + LONGBOW_RUN_TEST_CASE(Buffer, ccnxTlvDictionary_GetBuffer_Exists); + LONGBOW_RUN_TEST_CASE(Buffer, ccnxTlvDictionary_GetBuffer_Missing); + LONGBOW_RUN_TEST_CASE(Buffer, ccnxTlvDictionary_PutBuffer_OK); + LONGBOW_RUN_TEST_CASE(Buffer, ccnxTlvDictionary_PutBuffer_Duplicate); + LONGBOW_RUN_TEST_CASE(Buffer, ccnxTlvDictionary_IsValueBuffer_True); + LONGBOW_RUN_TEST_CASE(Buffer, ccnxTlvDictionary_IsValueBuffer_False); +} + +LONGBOW_TEST_FIXTURE_SETUP(Buffer) +{ + longBowTestCase_SetClipBoardData(testCase, _commonSetup()); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Buffer) +{ + _commonTeardown(longBowTestCase_GetClipBoardData(testCase)); + + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Buffer, ccnxTlvDictionary_GetBuffer_Exists) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *test = ccnxTlvDictionary_GetBuffer(data->dictionary, SchemaBuffer); + assertNotNull(test, "Got null buffer from key that hsould be buffer"); +} + +LONGBOW_TEST_CASE(Buffer, ccnxTlvDictionary_GetBuffer_Missing) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + ccnxTlvDictionary_GetBuffer(data->dictionary, SchemaFree); +} + +LONGBOW_TEST_CASE(Buffer, ccnxTlvDictionary_PutBuffer_OK) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *buffer = parcBuffer_Allocate(1); + bool success = ccnxTlvDictionary_PutBuffer(data->dictionary, SchemaFree, buffer); + assertTrue(success, "Did not put buffer in to available slot"); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(Buffer, ccnxTlvDictionary_PutBuffer_Duplicate) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *buffer = parcBuffer_Allocate(1); + bool success = ccnxTlvDictionary_PutBuffer(data->dictionary, SchemaBuffer, buffer); + assertFalse(success, "Should have failed putting duplicate"); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(Buffer, ccnxTlvDictionary_IsValueBuffer_True) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + bool success = ccnxTlvDictionary_IsValueBuffer(data->dictionary, SchemaBuffer); + assertTrue(success, "Should have succeeded on a buffer key"); +} + +LONGBOW_TEST_CASE(Buffer, ccnxTlvDictionary_IsValueBuffer_False) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + bool success = ccnxTlvDictionary_IsValueBuffer(data->dictionary, SchemaInteger); + assertFalse(success, "Should have failed on a non-buffer"); +} + +// ============================================================= + +LONGBOW_TEST_FIXTURE(Integer) +{ + LONGBOW_RUN_TEST_CASE(Integer, ccnxTlvDictionary_GetInteger_Exists); + LONGBOW_RUN_TEST_CASE(Integer, ccnxTlvDictionary_GetInteger_Missing); + LONGBOW_RUN_TEST_CASE(Integer, ccnxTlvDictionary_PutInteger_OK); + LONGBOW_RUN_TEST_CASE(Integer, ccnxTlvDictionary_PutInteger_Duplicate); + LONGBOW_RUN_TEST_CASE(Integer, ccnxTlvDictionary_PutInteger_OverBuffer); + LONGBOW_RUN_TEST_CASE(Integer, ccnxTlvDictionary_IsValueInteger_True); + LONGBOW_RUN_TEST_CASE(Integer, ccnxTlvDictionary_IsValueInteger_False); +} + +LONGBOW_TEST_FIXTURE_SETUP(Integer) +{ + longBowTestCase_SetClipBoardData(testCase, _commonSetup()); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Integer) +{ + _commonTeardown(longBowTestCase_GetClipBoardData(testCase)); + + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Integer, ccnxTlvDictionary_GetInteger_Exists) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + uint64_t test = ccnxTlvDictionary_GetInteger(data->dictionary, SchemaInteger); + assertTrue(test == 42, "Got wrong integer, got %" PRIu64 " expected 42", test); +} + +LONGBOW_TEST_CASE_EXPECTS(Integer, ccnxTlvDictionary_GetInteger_Missing, .event = &LongBowTrapIllegalValue) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + ccnxTlvDictionary_GetInteger(data->dictionary, SchemaBuffer); +} + +LONGBOW_TEST_CASE(Integer, ccnxTlvDictionary_PutInteger_OK) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + bool success = ccnxTlvDictionary_PutInteger(data->dictionary, SchemaFree, 69); + assertTrue(success, "Did not put integer in to available slot"); +} + +LONGBOW_TEST_CASE(Integer, ccnxTlvDictionary_PutInteger_Duplicate) +{ + // we allow replacing integer + TestData *data = longBowTestCase_GetClipBoardData(testCase); + bool success = ccnxTlvDictionary_PutInteger(data->dictionary, SchemaInteger, 69); + assertTrue(success, "Should have succeeded putting duplicate"); +} + +LONGBOW_TEST_CASE(Integer, ccnxTlvDictionary_PutInteger_OverBuffer) +{ + // This will fail, cannot change a buffer to an integer + TestData *data = longBowTestCase_GetClipBoardData(testCase); + bool success = ccnxTlvDictionary_PutInteger(data->dictionary, SchemaBuffer, 69); + assertFalse(success, "Should not be able to change a buffer to an integer"); +} + +LONGBOW_TEST_CASE(Integer, ccnxTlvDictionary_IsValueInteger_True) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + bool success = ccnxTlvDictionary_IsValueInteger(data->dictionary, SchemaInteger); + assertTrue(success, "Should have succeeded on a integer key"); +} + +LONGBOW_TEST_CASE(Integer, ccnxTlvDictionary_IsValueInteger_False) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + bool success = ccnxTlvDictionary_IsValueInteger(data->dictionary, SchemaBuffer); + assertFalse(success, "Should have failed on a non-integer"); +} + +// ============================================================= + +LONGBOW_TEST_FIXTURE(IoVec) +{ + LONGBOW_RUN_TEST_CASE(IoVec, ccnxTlvDictionary_GetIoVec_Exists); + LONGBOW_RUN_TEST_CASE(IoVec, ccnxTlvDictionary_GetIoVec_Missing); + LONGBOW_RUN_TEST_CASE(IoVec, ccnxTlvDictionary_PutIoVec_OK); + LONGBOW_RUN_TEST_CASE(IoVec, ccnxTlvDictionary_PutIoVec_Duplicate); + LONGBOW_RUN_TEST_CASE(IoVec, ccnxTlvDictionary_IsValueIoVec_True); + LONGBOW_RUN_TEST_CASE(IoVec, ccnxTlvDictionary_IsValueIoVec_False); +} + +LONGBOW_TEST_FIXTURE_SETUP(IoVec) +{ + longBowTestCase_SetClipBoardData(testCase, _commonSetup()); + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(IoVec) +{ + _commonTeardown(longBowTestCase_GetClipBoardData(testCase)); + + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(IoVec, ccnxTlvDictionary_GetIoVec_Exists) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + CCNxCodecNetworkBufferIoVec *test = ccnxTlvDictionary_GetIoVec(data->dictionary, SchemaIoVec); + assertNotNull(test, "Got null buffer from key that hsould be buffer"); +} + +LONGBOW_TEST_CASE(IoVec, ccnxTlvDictionary_GetIoVec_Missing) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + ccnxTlvDictionary_GetIoVec(data->dictionary, SchemaFree); +} + +LONGBOW_TEST_CASE(IoVec, ccnxTlvDictionary_PutIoVec_OK) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + CCNxCodecNetworkBufferIoVec *vec = createIoVec(); + bool success = ccnxTlvDictionary_PutIoVec(data->dictionary, SchemaFree, vec); + assertTrue(success, "Did not put vec in to available slot"); + ccnxCodecNetworkBufferIoVec_Release(&vec); +} + +LONGBOW_TEST_CASE(IoVec, ccnxTlvDictionary_PutIoVec_Duplicate) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + CCNxCodecNetworkBufferIoVec *vec = createIoVec(); + bool success = ccnxTlvDictionary_PutIoVec(data->dictionary, SchemaIoVec, vec); + assertFalse(success, "Should have failed putting duplicate"); + ccnxCodecNetworkBufferIoVec_Release(&vec); +} + +LONGBOW_TEST_CASE(IoVec, ccnxTlvDictionary_IsValueIoVec_True) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + bool success = ccnxTlvDictionary_IsValueIoVec(data->dictionary, SchemaIoVec); + assertTrue(success, "Should have succeeded on a vec key"); +} + +LONGBOW_TEST_CASE(IoVec, ccnxTlvDictionary_IsValueIoVec_False) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + bool success = ccnxTlvDictionary_IsValueIoVec(data->dictionary, SchemaInteger); + assertFalse(success, "Should have failed on a non-vec"); +} + +// ============================================================= + +LONGBOW_TEST_FIXTURE(Json) +{ + LONGBOW_RUN_TEST_CASE(Json, ccnxTlvDictionary_GetJson_Exists); + LONGBOW_RUN_TEST_CASE(Json, ccnxTlvDictionary_GetJson_Missing); + LONGBOW_RUN_TEST_CASE(Json, ccnxTlvDictionary_PutJson_OK); + LONGBOW_RUN_TEST_CASE(Json, ccnxTlvDictionary_PutJson_Duplicate); + LONGBOW_RUN_TEST_CASE(Json, ccnxTlvDictionary_IsValueJson_True); + LONGBOW_RUN_TEST_CASE(Json, ccnxTlvDictionary_IsValueJson_False); +} + +LONGBOW_TEST_FIXTURE_SETUP(Json) +{ + longBowTestCase_SetClipBoardData(testCase, _commonSetup()); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Json) +{ + _commonTeardown(longBowTestCase_GetClipBoardData(testCase)); + + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Json, ccnxTlvDictionary_GetJson_Exists) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCJSON *test = ccnxTlvDictionary_GetJson(data->dictionary, SchemaJson); + assertNotNull(test, "Got null json from key that should be json"); +} + +LONGBOW_TEST_CASE(Json, ccnxTlvDictionary_GetJson_Missing) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCJSON *test = ccnxTlvDictionary_GetJson(data->dictionary, SchemaFree); + assertNull(test, "Should have gotten null for non-json key"); +} + +LONGBOW_TEST_CASE(Json, ccnxTlvDictionary_PutJson_OK) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCJSON *json = parcJSON_Create(); + bool success = ccnxTlvDictionary_PutJson(data->dictionary, SchemaFree, json); + assertTrue(success, "Did not put buffer in to available slot"); + parcJSON_Release(&json); +} + +LONGBOW_TEST_CASE(Json, ccnxTlvDictionary_PutJson_Duplicate) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + PARCJSON *json = parcJSON_Create(); + bool success = ccnxTlvDictionary_PutJson(data->dictionary, SchemaJson, json); + assertFalse(success, "Should have failed putting duplicate"); + parcJSON_Release(&json); +} + +LONGBOW_TEST_CASE(Json, ccnxTlvDictionary_IsValueJson_True) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + bool success = ccnxTlvDictionary_IsValueJson(data->dictionary, SchemaJson); + assertTrue(success, "Should have succeeded on a json key"); +} + +LONGBOW_TEST_CASE(Json, ccnxTlvDictionary_IsValueJson_False) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + bool success = ccnxTlvDictionary_IsValueJson(data->dictionary, SchemaInteger); + assertFalse(success, "Should have failed on a non-json"); +} + +// ============================================================= + +LONGBOW_TEST_FIXTURE(Name) +{ + LONGBOW_RUN_TEST_CASE(Name, ccnxTlvDictionary_GetName_Exists); + LONGBOW_RUN_TEST_CASE(Name, ccnxTlvDictionary_GetName_Missing); + LONGBOW_RUN_TEST_CASE(Name, ccnxTlvDictionary_PutName_OK); + LONGBOW_RUN_TEST_CASE(Name, ccnxTlvDictionary_PutName_Duplicate); + LONGBOW_RUN_TEST_CASE(Name, ccnxTlvDictionary_IsValueName_True); + LONGBOW_RUN_TEST_CASE(Name, ccnxTlvDictionary_IsValueName_False); +} + +LONGBOW_TEST_FIXTURE_SETUP(Name) +{ + longBowTestCase_SetClipBoardData(testCase, _commonSetup()); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Name) +{ + _commonTeardown(longBowTestCase_GetClipBoardData(testCase)); + + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Name, ccnxTlvDictionary_GetName_Exists) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + CCNxName *test = ccnxTlvDictionary_GetName(data->dictionary, SchemaName); + assertNotNull(test, "Got null json from key that should be name"); +} + +LONGBOW_TEST_CASE(Name, ccnxTlvDictionary_GetName_Missing) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + CCNxName *test = ccnxTlvDictionary_GetName(data->dictionary, SchemaFree); + assertNull(test, "Should have gotten null for non-name key"); +} + +LONGBOW_TEST_CASE(Name, ccnxTlvDictionary_PutName_OK) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + CCNxName *name = ccnxName_Create(); + bool success = ccnxTlvDictionary_PutName(data->dictionary, SchemaFree, name); + assertTrue(success, "Did not put name in to available slot"); + ccnxName_Release(&name); +} + +LONGBOW_TEST_CASE(Name, ccnxTlvDictionary_PutName_Duplicate) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + CCNxName *name = ccnxName_Create(); + bool success = ccnxTlvDictionary_PutName(data->dictionary, SchemaName, name); + assertFalse(success, "Should have failed putting duplicate"); + ccnxName_Release(&name); +} + +LONGBOW_TEST_CASE(Name, ccnxTlvDictionary_IsValueName_True) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + bool success = ccnxTlvDictionary_IsValueName(data->dictionary, SchemaName); + assertTrue(success, "Should have succeeded on a json key"); +} + +LONGBOW_TEST_CASE(Name, ccnxTlvDictionary_IsValueName_False) +{ + TestData *data = longBowTestCase_GetClipBoardData(testCase); + bool success = ccnxTlvDictionary_IsValueName(data->dictionary, SchemaInteger); + assertFalse(success, "Should have failed on a non-json"); +} + +// ============================================================= + +LONGBOW_TEST_FIXTURE(Local) +{ + LONGBOW_RUN_TEST_CASE(Local, _rtaTlvEntry_Equals_Unset); + LONGBOW_RUN_TEST_CASE(Local, _rtaTlvEntry_Equals_Buffer); + LONGBOW_RUN_TEST_CASE(Local, _rtaTlvEntry_Equals_Integer); + LONGBOW_RUN_TEST_CASE(Local, _rtaTlvEntry_Equals_IoVec); + LONGBOW_RUN_TEST_CASE(Local, _rtaTlvEntry_Equals_Json); + LONGBOW_RUN_TEST_CASE(Local, _rtaTlvEntry_Equals_Name); +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +static void +assertRtaTlvEntryEquals(int length, _CCNxTlvDictionaryEntry array[length]) +{ + assertTrue(length == 5, "Must provide 5 array elements"); + assertEqualsContract((bool (*)(void *, void *))_ccnxTlvDictionaryEntry_Equals, &array[0], &array[1], &array[2], &array[3], &array[4], NULL); +} + +LONGBOW_TEST_CASE(Local, _rtaTlvEntry_Equals_Unset) +{ + _CCNxTlvDictionaryEntry array[5]; + memset(&array, 0, sizeof(array)); + + array[3].entryType = ENTRY_JSON; + array[4].entryType = ENTRY_BUFFER; + assertRtaTlvEntryEquals(5, array); +} + +LONGBOW_TEST_CASE(Local, _rtaTlvEntry_Equals_Buffer) +{ + char apple[] = "apple"; + char bananna[] = "bannana"; + + _CCNxTlvDictionaryEntry array[5]; + memset(&array, 0, sizeof(array)); + + for (int i = 0; i < 3; i++) { + array[i].entryType = ENTRY_BUFFER; + array[i]._entry.buffer = parcBuffer_Flip(parcBuffer_PutArray(parcBuffer_Allocate(20), sizeof(apple), (uint8_t *) apple)); + } + + array[3].entryType = ENTRY_JSON; + array[4].entryType = ENTRY_BUFFER; + array[4]._entry.buffer = parcBuffer_Flip(parcBuffer_PutArray(parcBuffer_Allocate(20), sizeof(bananna), (uint8_t *) bananna)); + assertRtaTlvEntryEquals(5, array); + + for (int i = 0; i < 5; i++) { + if (array[i]._entry.buffer) { + parcBuffer_Release(&array[i]._entry.buffer); + } + } +} + +LONGBOW_TEST_CASE(Local, _rtaTlvEntry_Equals_Integer) +{ + _CCNxTlvDictionaryEntry array[5]; + memset(&array, 0, sizeof(array)); + + for (int i = 0; i < 3; i++) { + array[i].entryType = ENTRY_INTEGER; + array[i]._entry.integer = 13; + } + + array[3].entryType = ENTRY_JSON; + array[4].entryType = ENTRY_INTEGER; + array[4]._entry.integer = 99; + + assertRtaTlvEntryEquals(5, array); +} + +LONGBOW_TEST_CASE(Local, _rtaTlvEntry_Equals_IoVec) +{ + CCNxCodecNetworkBuffer *netbuff = ccnxCodecNetworkBuffer_Create(&ParcMemoryMemoryBlock, NULL); + ccnxCodecNetworkBuffer_PutUint8(netbuff, 0); + CCNxCodecNetworkBufferIoVec *unequal = ccnxCodecNetworkBuffer_CreateIoVec(netbuff); + ccnxCodecNetworkBuffer_Release(&netbuff); + + _CCNxTlvDictionaryEntry array[5]; + memset(&array, 0, sizeof(array)); + + for (int i = 0; i < 3; i++) { + array[i].entryType = ENTRY_IOVEC; + array[i]._entry.vec = createIoVec(); + } + + array[3].entryType = ENTRY_JSON; + array[4].entryType = ENTRY_IOVEC; + array[4]._entry.vec = unequal; + assertRtaTlvEntryEquals(5, array); + + for (int i = 0; i < 5; i++) { + if (array[i]._entry.vec) { + ccnxCodecNetworkBufferIoVec_Release(&array[i]._entry.vec); + } + } +} + +LONGBOW_TEST_CASE(Local, _rtaTlvEntry_Equals_Json) +{ + char apple[] = "{\"apple\": 0}"; + char bananna[] = "{\"bannana\": 1}"; + + _CCNxTlvDictionaryEntry array[5]; + memset(&array, 0, sizeof(array)); + + for (int i = 0; i < 3; i++) { + array[i].entryType = ENTRY_JSON; + array[i]._entry.json = parcJSON_ParseString(apple); + } + + array[3].entryType = ENTRY_JSON; + array[4].entryType = ENTRY_JSON; + array[4]._entry.json = parcJSON_ParseString(bananna); + assertRtaTlvEntryEquals(5, array); + + for (int i = 0; i < 5; i++) { + if (array[i]._entry.json) { + parcJSON_Release(&array[i]._entry.json); + } + } +} + +LONGBOW_TEST_CASE(Local, _rtaTlvEntry_Equals_Name) +{ + char apple[] = "lci:/apple"; + char bananna[] = "lci:/bannana"; + + _CCNxTlvDictionaryEntry array[5]; + memset(&array, 0, sizeof(array)); + + for (int i = 0; i < 3; i++) { + array[i].entryType = ENTRY_NAME; + array[i]._entry.name = ccnxName_CreateFromCString(apple); + } + + array[3].entryType = ENTRY_JSON; + array[4].entryType = ENTRY_NAME; + array[4]._entry.name = ccnxName_CreateFromCString(bananna); + assertRtaTlvEntryEquals(5, array); + + for (int i = 0; i < 5; i++) { + if (array[i]._entry.name) { + ccnxName_Release(&array[i]._entry.name); + } + } +} + +// ============================================================= + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(rta_TlvDictionary); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libccnx-common/ccnx/common/internal/test/test_ccnx_ValidationFacade b/libccnx-common/ccnx/common/internal/test/test_ccnx_ValidationFacade Binary files differnew file mode 100755 index 00000000..39a27830 --- /dev/null +++ b/libccnx-common/ccnx/common/internal/test/test_ccnx_ValidationFacade diff --git a/libccnx-common/ccnx/common/internal/test/test_ccnx_ValidationFacadeV1.c b/libccnx-common/ccnx/common/internal/test/test_ccnx_ValidationFacadeV1.c new file mode 100755 index 00000000..fe3ead29 --- /dev/null +++ b/libccnx-common/ccnx/common/internal/test/test_ccnx_ValidationFacadeV1.c @@ -0,0 +1,444 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Setter tests use ground truth by examining the dictionary. + * Getter tests use the setters to set values. + * + */ + +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. +#include "../ccnx_ValidationFacadeV1.c" + +#include <stdio.h> +#include <inttypes.h> + +#include <parc/algol/parc_SafeMemory.h> + +#include <LongBow/unit-test.h> + +//#include "../validation/test/testrig_validation.c" + +LONGBOW_TEST_RUNNER(ccnx_ValidationFacadeV1) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Setters); + LONGBOW_RUN_TEST_FIXTURE(Getters); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(ccnx_ValidationFacadeV1) +{ + parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory); + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_ValidationFacadeV1) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Setters) +{ + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_SetKeyId); + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_SetKeyName); + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_SetPublicKey); + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_SetCertificate); + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_SetPayload); + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_SetCryptoSuite); + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_SetSigningTime); +} + +LONGBOW_TEST_FIXTURE_SETUP(Setters) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Setters) +{ + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_SetKeyId) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + PARCBuffer *keyid = parcBuffer_Wrap((uint8_t []) { 1, 2, 3, 4, 5 }, 5, 0, 5); + bool success = ccnxValidationFacadeV1_SetKeyId(dictionary, keyid); + assertTrue(success, "Failed to set keyid"); + + PARCBuffer *test = ccnxTlvDictionary_GetBuffer(dictionary, CCNxCodecSchemaV1TlvDictionary_ValidationFastArray_KEYID); + assertTrue(parcBuffer_Equals(test, keyid), "Buffer mismatch") + { + printf("Expected\n"); + parcBuffer_Display(keyid, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + } + + parcBuffer_Release(&keyid); + ccnxTlvDictionary_Release(&dictionary); +} + + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_SetKeyName) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + PARCBuffer *keyid = parcBuffer_Wrap((uint8_t []) { 1, 2, 3, 4, 5 }, 5, 0, 5); + PARCBuffer *hash = parcBuffer_Wrap((uint8_t []) { 11, 12, 13, 14 }, 4, 0, 4); + CCNxName *name = ccnxName_CreateFromCString("lci:/foo"); + CCNxLink *link = ccnxLink_Create(name, keyid, hash); + + bool success = ccnxValidationFacadeV1_SetKeyName(dictionary, link); + assertTrue(success, "Failed to set keyname"); + + CCNxName *testName = ccnxTlvDictionary_GetName(dictionary, CCNxCodecSchemaV1TlvDictionary_ValidationFastArray_KEYNAME_NAME); + assertTrue(ccnxName_Equals(testName, name), "Wrong name") + { + printf("Expected\n"); + ccnxName_Display(name, 3); + printf("Got\n"); + ccnxName_Display(testName, 3); + } + + PARCBuffer *testKeyid = ccnxTlvDictionary_GetBuffer(dictionary, CCNxCodecSchemaV1TlvDictionary_ValidationFastArray_KEYNAME_KEYID); + assertTrue(parcBuffer_Equals(testKeyid, keyid), "Wrong keyid") + { + printf("Expected\n"); + parcBuffer_Display(keyid, 3); + printf("Got\n"); + parcBuffer_Display(testKeyid, 3); + } + + PARCBuffer *testHash = ccnxTlvDictionary_GetBuffer(dictionary, CCNxCodecSchemaV1TlvDictionary_ValidationFastArray_KEYNAME_OBJHASH); + assertTrue(parcBuffer_Equals(testHash, hash), "Wrong hash") + { + printf("Expected\n"); + parcBuffer_Display(hash, 3); + printf("Got\n"); + parcBuffer_Display(testHash, 3); + } + + parcBuffer_Release(&hash); + parcBuffer_Release(&keyid); + ccnxName_Release(&name); + ccnxLink_Release(&link); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_SetPublicKey) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + PARCBuffer *key = parcBuffer_Wrap((uint8_t []) { 1, 2, 3, 4, 5 }, 5, 0, 5); + bool success = ccnxValidationFacadeV1_SetPublicKey(dictionary, key); + assertTrue(success, "Failed to set keyid"); + + PARCBuffer *test = ccnxTlvDictionary_GetBuffer(dictionary, CCNxCodecSchemaV1TlvDictionary_ValidationFastArray_KEY); + assertTrue(parcBuffer_Equals(test, key), "Buffer mismatch") + { + printf("Expected\n"); + parcBuffer_Display(key, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + } + + parcBuffer_Release(&key); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_SetCertificate) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + PARCBuffer *cert = parcBuffer_Wrap((uint8_t []) { 1, 2, 3, 4, 5 }, 5, 0, 5); + bool success = ccnxValidationFacadeV1_SetCertificate(dictionary, cert); + assertTrue(success, "Failed to set keyid"); + + PARCBuffer *test = ccnxTlvDictionary_GetBuffer(dictionary, CCNxCodecSchemaV1TlvDictionary_ValidationFastArray_CERT); + assertTrue(parcBuffer_Equals(test, cert), "Buffer mismatch") + { + printf("Expected\n"); + parcBuffer_Display(cert, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + } + + parcBuffer_Release(&cert); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_SetPayload) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + PARCBuffer *payload = parcBuffer_Wrap((uint8_t []) { 1, 2, 3, 4, 5 }, 5, 0, 5); + bool success = ccnxValidationFacadeV1_SetPayload(dictionary, payload); + assertTrue(success, "Failed to set keyid"); + + PARCBuffer *test = ccnxTlvDictionary_GetBuffer(dictionary, CCNxCodecSchemaV1TlvDictionary_ValidationFastArray_PAYLOAD); + assertTrue(parcBuffer_Equals(test, payload), "Buffer mismatch") + { + printf("Expected\n"); + parcBuffer_Display(payload, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + } + + parcBuffer_Release(&payload); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_SetCryptoSuite) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + PARCCryptoSuite suite = PARCCryptoSuite_RSA_SHA256; + bool success = ccnxValidationFacadeV1_SetCryptoSuite(dictionary, suite); + assertTrue(success, "Failed to set keyid"); + + bool hasCryptoSuite = ccnxTlvDictionary_IsValueInteger(dictionary, CCNxCodecSchemaV1TlvDictionary_ValidationFastArray_CRYPTO_SUITE); + assertTrue(hasCryptoSuite, "Dictionary does not have a crypto suite value in it"); + + PARCCryptoSuite test = (PARCCryptoSuite) ccnxTlvDictionary_GetInteger(dictionary, CCNxCodecSchemaV1TlvDictionary_ValidationFastArray_CRYPTO_SUITE); + assertTrue(test == suite, "Wrong suite, expected %d got %d", suite, test); + + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_SetSigningTime) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + uint64_t signingTime = 0x0102030405060708ULL; + + bool success = ccnxValidationFacadeV1_SetSigningTime(dictionary, signingTime); + assertTrue(success, "Failed to set signing time"); + + bool hasSigningTime = ccnxTlvDictionary_IsValueInteger(dictionary, CCNxCodecSchemaV1TlvDictionary_ValidationFastArray_SIGNTIME); + assertTrue(hasSigningTime, "Dictionary does not have a signing time value in it"); + + uint64_t test = ccnxTlvDictionary_GetInteger(dictionary, CCNxCodecSchemaV1TlvDictionary_ValidationFastArray_SIGNTIME); + assertTrue(test == signingTime, "Wrong signing time, expected %" PRIx64 " got %" PRIx64, signingTime, test); + + ccnxTlvDictionary_Release(&dictionary); +} + +// ============================================================= + +LONGBOW_TEST_FIXTURE(Getters) +{ + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_GetKeyId); + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_GetKeyName); + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_GetPublicKey); + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_GetCertificate); + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_GetPayload); + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_HasCryptoSuite_True); + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_HasCryptoSuite_False); + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_GetCryptoSuite); + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_HasSigningTime_True); + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_HasSigningTime_False); + LONGBOW_RUN_TEST_CASE(Setters, ccnxValidationFacadeV1_GetSigningTime); +} + +LONGBOW_TEST_FIXTURE_SETUP(Getters) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Getters) +{ + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_GetKeyId) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + PARCBuffer *keyid = parcBuffer_Wrap((uint8_t []) { 1, 2, 3, 4, 5 }, 5, 0, 5); + ccnxValidationFacadeV1_SetKeyId(dictionary, keyid); + + PARCBuffer *test = ccnxValidationFacadeV1_GetKeyId(dictionary); + assertTrue(parcBuffer_Equals(test, keyid), "Buffer mismatch") + { + printf("Expected\n"); + parcBuffer_Display(keyid, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + } + + parcBuffer_Release(&keyid); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_GetKeyName) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + PARCBuffer *keyid = parcBuffer_Wrap((uint8_t []) { 1, 2, 3, 4, 5 }, 5, 0, 5); + PARCBuffer *hash = parcBuffer_Wrap((uint8_t []) { 11, 12, 13, 14 }, 4, 0, 4); + CCNxName *name = ccnxName_CreateFromCString("lci:/foo"); + CCNxLink *link = ccnxLink_Create(name, keyid, hash); + + ccnxValidationFacadeV1_SetKeyName(dictionary, link); + + CCNxLink *testLink = ccnxValidationFacadeV1_GetKeyName(dictionary); + assertTrue(ccnxLink_Equals(testLink, link), "Wrong link"); + // no ccnxLink_Dispay, so cannot easily display items + + ccnxLink_Release(&testLink); + parcBuffer_Release(&hash); + parcBuffer_Release(&keyid); + ccnxName_Release(&name); + ccnxLink_Release(&link); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_GetPublicKey) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + PARCBuffer *key = parcBuffer_Wrap((uint8_t []) { 1, 2, 3, 4, 5 }, 5, 0, 5); + ccnxValidationFacadeV1_SetPublicKey(dictionary, key); + + PARCBuffer *test = ccnxValidationFacadeV1_GetPublicKey(dictionary); + assertTrue(parcBuffer_Equals(test, key), "Buffer mismatch") + { + printf("Expected\n"); + parcBuffer_Display(key, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + } + + parcBuffer_Release(&key); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_GetCertificate) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + PARCBuffer *cert = parcBuffer_Wrap((uint8_t []) { 1, 2, 3, 4, 5 }, 5, 0, 5); + ccnxValidationFacadeV1_SetCertificate(dictionary, cert); + + PARCBuffer *test = ccnxValidationFacadeV1_GetCertificate(dictionary); + assertTrue(parcBuffer_Equals(test, cert), "Buffer mismatch") + { + printf("Expected\n"); + parcBuffer_Display(cert, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + } + + parcBuffer_Release(&cert); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_GetPayload) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + PARCBuffer *payload = parcBuffer_Wrap((uint8_t []) { 1, 2, 3, 4, 5 }, 5, 0, 5); + ccnxValidationFacadeV1_SetPayload(dictionary, payload); + + PARCBuffer *test = ccnxValidationFacadeV1_GetPayload(dictionary); + assertTrue(parcBuffer_Equals(test, payload), "Buffer mismatch") + { + printf("Expected\n"); + parcBuffer_Display(payload, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + } + + parcBuffer_Release(&payload); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_HasCryptoSuite_True) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + PARCCryptoSuite suite = PARCCryptoSuite_RSA_SHA256; + ccnxValidationFacadeV1_SetCryptoSuite(dictionary, suite); + + bool hasCryptoSuite = ccnxValidationFacadeV1_HasCryptoSuite(dictionary); + assertTrue(hasCryptoSuite, "Dictionary does not have a crypto suite value in it"); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_HasCryptoSuite_False) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + + bool hasCryptoSuite = ccnxValidationFacadeV1_HasCryptoSuite(dictionary); + assertFalse(hasCryptoSuite, "Dictionary says it has a crypto suite when none was set"); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_GetCryptoSuite) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + PARCCryptoSuite suite = PARCCryptoSuite_RSA_SHA256; + ccnxValidationFacadeV1_SetCryptoSuite(dictionary, suite); + + PARCCryptoSuite test = ccnxValidationFacadeV1_GetCryptoSuite(dictionary); + assertTrue(test == suite, "Wrong crypto suite, expected %d got %d", suite, test); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_HasSigningTime_True) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + uint64_t signingTime = 0x0102030405060708ULL; + ccnxValidationFacadeV1_SetSigningTime(dictionary, signingTime); + + bool hasSigningTime = ccnxValidationFacadeV1_HasSigningTime(dictionary); + assertTrue(hasSigningTime, "Dictionary does not have a signing time value in it"); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_HasSigningTime_False) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + + bool hasSigningTime = ccnxValidationFacadeV1_HasSigningTime(dictionary); + assertFalse(hasSigningTime, "Dictionary says it has a signing time when none was set"); + ccnxTlvDictionary_Release(&dictionary); +} + +LONGBOW_TEST_CASE(Setters, ccnxValidationFacadeV1_GetSigningTime) +{ + CCNxTlvDictionary *dictionary = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + uint64_t signingTime = 0x0102030405060708ULL; + ccnxValidationFacadeV1_SetSigningTime(dictionary, signingTime); + + uint64_t test = ccnxValidationFacadeV1_GetSigningTime(dictionary); + assertTrue(test == signingTime, "Wrong signing time, expected %" PRIx64 " got %" PRIx64, signingTime, test); + ccnxTlvDictionary_Release(&dictionary); +} + + +// ============================================================= + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_ValidationFacadeV1); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libccnx-common/ccnx/common/internal/test/test_ccnx_WireFormatFacadeV1.c b/libccnx-common/ccnx/common/internal/test/test_ccnx_WireFormatFacadeV1.c new file mode 100755 index 00000000..194ef02c --- /dev/null +++ b/libccnx-common/ccnx/common/internal/test/test_ccnx_WireFormatFacadeV1.c @@ -0,0 +1,594 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + */ + +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. +#include "../ccnx_WireFormatFacadeV1.c" + +#include <parc/algol/parc_SafeMemory.h> + +#include <LongBow/unit-test.h> + +#include <ccnx/common/ccnx_ContentObject.h> +#include <ccnx/common/ccnx_WireFormatMessage.h> +#include <ccnx/common/codec/ccnxCodec_TlvPacket.h> + +#include <ccnx/common/codec/schema_v1/testdata/v1_interest_nameA.h> +#include <ccnx/common/codec/schema_v1/testdata/v1_content_nameA_crc32c.h> +#include <ccnx/common/codec/schema_v1/testdata/v1_cpi_add_route.h> + +LONGBOW_TEST_RUNNER(ccnx_WireFormatFacade) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(SchemaV1); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(ccnx_WireFormatFacade) +{ + parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory); + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_WireFormatFacade) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +/* + * Small size allocator for creating a network buffer + */ +static size_t +allocator(void *userarg, size_t bytes, void **output) +{ + const size_t allocationSize = *(size_t *) userarg; + void *allocated = parcMemory_Allocate(allocationSize); + *output = allocated; + return allocationSize; +} + +/* + * deallocator for network buffer + */ +static void +deallocator(void *userarg, void **memoryPtr) +{ + parcMemory_Deallocate(memoryPtr); +} + +static const CCNxCodecNetworkBufferMemoryBlockFunctions memory = { .allocator = allocator, .deallocator = deallocator }; + +/* + * Create a network buffer that looks like this. The actual number of iovecs might + * be a little different, but the digest area will span several iovec. + * + * +-----------+-----------+-----------+-----------+-----------+ + * iov[0] iov[1] iov[2] iov[3] + * +-----------+-----------+-----------+-----------+-----------+ + * ^ ^ + * | | + * start end + */ +static CCNxCodecNetworkBufferIoVec * +createNetworkBufferIoVec(size_t allocationSize, size_t padlen, uint8_t pad[padlen], size_t datalen, uint8_t data[datalen]) +{ + CCNxCodecNetworkBuffer *netbuff = ccnxCodecNetworkBuffer_Create(&memory, &allocationSize); + // build the network buffer + ccnxCodecNetworkBuffer_PutArray(netbuff, padlen, pad); + ccnxCodecNetworkBuffer_PutArray(netbuff, datalen, data); + ccnxCodecNetworkBuffer_PutArray(netbuff, padlen, pad); + + CCNxCodecNetworkBufferIoVec *vec = ccnxCodecNetworkBuffer_CreateIoVec(netbuff); + ccnxCodecNetworkBuffer_Release(&netbuff); + return vec; +} + +// ======================================================================= + +LONGBOW_TEST_FIXTURE(SchemaV1) +{ + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_FromContentObjectPacketType); + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_FromControlPacketType); + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_FromInterestPacketType); + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_FromInterestReturnPacketType); + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_Get); + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_Put); + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_WriteToFile); + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_FromInterestPacketTypeIoVec); + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_GetIoVec); + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_SetHopLimit); + + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_SetProtectedRegionStart); + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_SetProtectedRegionLength); + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_HashProtectedRegion_Buffer); + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_HashProtectedRegion_IoVec); + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_ComputeContentObjectHash); + + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_Create_Interest); + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_Create_ContentObject); + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_Create_Control); + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_Create_InterestReturn); + LONGBOW_RUN_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_Create_UnknownPacketType); +} + +LONGBOW_TEST_FIXTURE_SETUP(SchemaV1) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(SchemaV1) +{ + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_FromContentObjectPacketType) +{ + PARCBuffer *buffer = parcBuffer_Allocate(1); + CCNxTlvDictionary *wireformat = _ccnxWireFormatFacadeV1_FromContentObjectPacketType(buffer); + assertNotNull(wireformat, "Got null wireformat"); + assertTrue(ccnxTlvDictionary_IsContentObject(wireformat), "Wrong message type"); + assertTrue(ccnxTlvDictionary_GetSchemaVersion(wireformat) == CCNxTlvDictionary_SchemaVersion_V1, + "Wrong schema, got %d expected %d", + ccnxTlvDictionary_GetSchemaVersion(wireformat), CCNxTlvDictionary_SchemaVersion_V1); + + ccnxTlvDictionary_Release(&wireformat); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_FromControlPacketType) +{ + PARCBuffer *buffer = parcBuffer_Allocate(1); + CCNxTlvDictionary *wireformat = _ccnxWireFormatFacadeV1_FromControlPacketType(buffer); + assertNotNull(wireformat, "Got null wireformat"); + assertTrue(ccnxTlvDictionary_IsControl(wireformat), "Wrong message type"); + assertTrue(ccnxTlvDictionary_GetSchemaVersion(wireformat) == CCNxTlvDictionary_SchemaVersion_V1, + "Wrong schema, got %d expected %d", + ccnxTlvDictionary_GetSchemaVersion(wireformat), CCNxTlvDictionary_SchemaVersion_V1); + + ccnxTlvDictionary_Release(&wireformat); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_FromInterestPacketType) +{ + PARCBuffer *buffer = parcBuffer_Allocate(1); + CCNxTlvDictionary *wireformat = _ccnxWireFormatFacadeV1_FromInterestPacketType(buffer); + assertNotNull(wireformat, "Got null wireformat"); + assertTrue(ccnxTlvDictionary_IsInterest(wireformat), "Wrong message type"); + assertTrue(ccnxTlvDictionary_GetSchemaVersion(wireformat) == CCNxTlvDictionary_SchemaVersion_V1, + "Wrong schema, got %d expected %d", + ccnxTlvDictionary_GetSchemaVersion(wireformat), CCNxTlvDictionary_SchemaVersion_V1); + + ccnxTlvDictionary_Release(&wireformat); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_FromInterestReturnPacketType) +{ + PARCBuffer *buffer = parcBuffer_Allocate(1); + CCNxTlvDictionary *wireformat = _ccnxWireFormatFacadeV1_FromInterestReturnPacketType(buffer); + assertNotNull(wireformat, "Got null wireformat"); + assertTrue(ccnxTlvDictionary_IsInterestReturn(wireformat), "Wrong message type"); + assertTrue(ccnxTlvDictionary_GetSchemaVersion(wireformat) == CCNxTlvDictionary_SchemaVersion_V1, + "Wrong schema, got %d expected %d", + ccnxTlvDictionary_GetSchemaVersion(wireformat), CCNxTlvDictionary_SchemaVersion_V1); + + ccnxTlvDictionary_Release(&wireformat); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_Get) +{ + PARCBuffer *buffer = parcBuffer_Allocate(1); + CCNxTlvDictionary *wireformat = _ccnxWireFormatFacadeV1_FromInterestPacketType(buffer); + + PARCBuffer *test = _ccnxWireFormatFacadeV1_GetWireFormatBuffer(wireformat); + assertTrue(test == buffer, "Wrong iovec: got %p expected %p", (void *) test, (void *) buffer); + + ccnxTlvDictionary_Release(&wireformat); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_Put) +{ + PARCBuffer *buffer = parcBuffer_Allocate(1); + CCNxTlvDictionary *packet = ccnxTlvDictionary_Create(20, 20); + ccnxTlvDictionary_SetMessageType_Interest(packet, CCNxTlvDictionary_SchemaVersion_V1); + bool success = _ccnxWireFormatFacadeV1_PutWireFormatBuffer(packet, buffer); + + assertTrue(success, "Failed to put buffer in to dictionary"); + + ccnxTlvDictionary_Release(&packet); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_WriteToFile) +{ + const char string[] = "Hello dev null\n"; + PARCBuffer *buffer = parcBuffer_Wrap((void *) string, sizeof(string), 0, sizeof(string)); + CCNxTlvDictionary *wireformat = _ccnxWireFormatFacadeV1_FromInterestPacketType(buffer); + + _ccnxWireFormatFacadeV1_WriteToFile(wireformat, "/dev/null"); + + ccnxTlvDictionary_Release(&wireformat); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_FromInterestPacketTypeIoVec) +{ + uint8_t data[64]; + + uint8_t pad[32]; + CCNxCodecNetworkBufferIoVec *vec = createNetworkBufferIoVec(512, 32, pad, 64, data); + + CCNxTlvDictionary *wireformat = _ccnxWireFormatFacadeV1_FromInterestPacketTypeIoVec(vec); + assertNotNull(wireformat, "Got null wireformat"); + assertTrue(ccnxTlvDictionary_IsInterest(wireformat), "Wrong message type"); + assertTrue(ccnxTlvDictionary_GetSchemaVersion(wireformat) == CCNxTlvDictionary_SchemaVersion_V1, + "Wrong schema, got %d expected %d", + ccnxTlvDictionary_GetSchemaVersion(wireformat), CCNxTlvDictionary_SchemaVersion_V1); + + ccnxTlvDictionary_Release(&wireformat); + ccnxCodecNetworkBufferIoVec_Release(&vec); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_GetIoVec) +{ + uint8_t *data = parcMemory_Allocate(64); + memset(data, 0, 64); + + PARCBuffer *buffer = parcBuffer_Allocate(1); + CCNxCodecNetworkBuffer *netbuff = ccnxCodecNetworkBuffer_CreateFromArray(&ParcMemoryMemoryBlock, NULL, 64, data); + CCNxCodecNetworkBufferIoVec *iovec = ccnxCodecNetworkBuffer_CreateIoVec(netbuff); + + CCNxTlvDictionary *packet = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + _ccnxWireFormatFacadeV1_PutIoVec(packet, iovec); + + CCNxCodecNetworkBufferIoVec *test = _ccnxWireFormatFacadeV1_GetIoVec(packet); + assertTrue(test == iovec, "Failed to get iovec from dictionary, expected %p got %p", (void *) iovec, (void *) test); + + ccnxTlvDictionary_Release(&packet); + parcBuffer_Release(&buffer); + ccnxCodecNetworkBufferIoVec_Release(&iovec); + ccnxCodecNetworkBuffer_Release(&netbuff); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_SetHopLimit) +{ + uint8_t *data = parcMemory_Allocate(64); + memset(data, 0, 64); + + PARCBuffer *buffer = parcBuffer_Allocate(1); + CCNxCodecNetworkBuffer *netbuff = ccnxCodecNetworkBuffer_CreateFromArray(&ParcMemoryMemoryBlock, NULL, 64, data); + CCNxCodecNetworkBufferIoVec *iovec = ccnxCodecNetworkBuffer_CreateIoVec(netbuff); + + CCNxTlvDictionary *packet = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + _ccnxWireFormatFacadeV1_PutIoVec(packet, iovec); + + _ccnxWireFormatFacadeV1_SetHopLimit(packet, 10); + + ccnxTlvDictionary_Release(&packet); + parcBuffer_Release(&buffer); + ccnxCodecNetworkBufferIoVec_Release(&iovec); + ccnxCodecNetworkBuffer_Release(&netbuff); + + CCNxCodecSchemaV1InterestHeader header; + + buffer = parcBuffer_Wrap((void *) &header, sizeof(header), 0, sizeof(header)); + + packet = _ccnxWireFormatFacadeV1_FromContentObjectPacketType(buffer); + + _ccnxWireFormatFacadeV1_SetHopLimit(packet, 10); + + ccnxTlvDictionary_Release(&packet); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_SetProtectedRegionStart) +{ + const char string[] = "Hello dev null\n"; + PARCBuffer *buffer = parcBuffer_Wrap((void *) string, sizeof(string), 0, sizeof(string)); + + CCNxTlvDictionary *packet = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + _ccnxWireFormatFacadeV1_PutWireFormatBuffer(packet, buffer); + + size_t start = 5; + bool success = _ccnxWireFormatFacadeV1_SetProtectedRegionStart(packet, start); + assertTrue(success, "Failed to put integer in to dictionary"); + + assertTrue(ccnxTlvDictionary_IsValueInteger(packet, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_ProtectedStart), "ProtectedStart not set"); + + ccnxTlvDictionary_Release(&packet); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_SetProtectedRegionLength) +{ + const char string[] = "Hello dev null\n"; + PARCBuffer *buffer = parcBuffer_Wrap((void *) string, sizeof(string), 0, sizeof(string)); + + CCNxTlvDictionary *packet = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + _ccnxWireFormatFacadeV1_PutWireFormatBuffer(packet, buffer); + + size_t length = 5; + bool success = _ccnxWireFormatFacadeV1_SetProtectedRegionLength(packet, length); + assertTrue(success, "Failed to put integer in to dictionary"); + + assertTrue(ccnxTlvDictionary_IsValueInteger(packet, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_ProtectedLength), "ProtectedLength not set"); + + ccnxTlvDictionary_Release(&packet); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_HashProtectedRegion_Buffer) +{ + // >1234< + const char string[] = "Hello dev null\n"; + + PARCBuffer *buffer = parcBuffer_Wrap((void *) string, sizeof(string), 0, sizeof(string)); + size_t start = 5; + size_t length = 4; + + CCNxTlvDictionary *packet = _ccnxWireFormatFacadeV1_FromContentObjectPacketType(buffer); + _ccnxWireFormatFacadeV1_SetProtectedRegionStart(packet, start); + _ccnxWireFormatFacadeV1_SetProtectedRegionLength(packet, length); + + PARCCryptoHasher *hasher = parcCryptoHasher_Create(PARCCryptoHashType_SHA256); + PARCCryptoHash *hash = _ccnxWireFormatFacadeV1_HashProtectedRegion(packet, hasher); + + // the correctness of the has is tested in _ccnxWireFormatFacadeV1_ComputeHash + assertNotNull(hash, "Got null hash from a good packet"); + + ccnxTlvDictionary_Release(&packet); + parcCryptoHash_Release(&hash); + parcBuffer_Release(&buffer); + parcCryptoHasher_Release(&hasher); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_HashProtectedRegion_IoVec) +{ + uint8_t *data = parcMemory_Allocate(64); + memset(data, 0, 64); + + PARCBuffer *buffer = parcBuffer_Allocate(1); + CCNxCodecNetworkBuffer *netbuff = ccnxCodecNetworkBuffer_CreateFromArray(&ParcMemoryMemoryBlock, NULL, 64, data); + CCNxCodecNetworkBufferIoVec *iovec = ccnxCodecNetworkBuffer_CreateIoVec(netbuff); + + CCNxTlvDictionary *packet = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + _ccnxWireFormatFacadeV1_PutIoVec(packet, iovec); + + _ccnxWireFormatFacadeV1_SetProtectedRegionStart(packet, 0); + _ccnxWireFormatFacadeV1_SetProtectedRegionLength(packet, 64); + + PARCCryptoHasher *hasher = parcCryptoHasher_Create(PARCCryptoHashType_SHA256); + PARCCryptoHash *hash = _ccnxWireFormatFacadeV1_HashProtectedRegion(packet, hasher); + + // the correctness of the has is tested in _ccnxWireFormatFacadeV1_ComputeHash + assertNotNull(hash, "Got null hash from a good packet"); + + ccnxTlvDictionary_Release(&packet); + parcCryptoHash_Release(&hash); + parcBuffer_Release(&buffer); + parcCryptoHasher_Release(&hasher); + ccnxCodecNetworkBufferIoVec_Release(&iovec); + ccnxCodecNetworkBuffer_Release(&netbuff); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_Create_Interest) +{ + PARCBuffer *wireFormat = parcBuffer_Wrap(v1_interest_nameA, sizeof(v1_interest_nameA), 0, sizeof(v1_interest_nameA)); + CCNxTlvDictionary *test = _ccnxWireFormatFacadeV1_CreateFromV1(wireFormat); + assertNotNull(test, "Got null dictionary for good interest"); + assertTrue(ccnxTlvDictionary_IsInterest(test), "Dictionary says it is not an Interest"); + assertTrue(ccnxTlvDictionary_GetSchemaVersion(test) == 1, "Schema says it is not v1"); + parcBuffer_Release(&wireFormat); + ccnxTlvDictionary_Release(&test); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_Create_ContentObject) +{ + PARCBuffer *wireFormat = parcBuffer_Wrap(v1_content_nameA_crc32c, sizeof(v1_content_nameA_crc32c), 0, sizeof(v1_content_nameA_crc32c)); + CCNxTlvDictionary *test = _ccnxWireFormatFacadeV1_CreateFromV1(wireFormat); + assertNotNull(test, "Got null dictionary for good content object"); + assertTrue(ccnxTlvDictionary_IsContentObject(test), "Dictionary says it is not a Content Object"); + assertTrue(ccnxTlvDictionary_GetSchemaVersion(test) == 1, "Schema says it is not v1"); + parcBuffer_Release(&wireFormat); + ccnxTlvDictionary_Release(&test); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_Create_Control) +{ + PARCBuffer *wireFormat = parcBuffer_Wrap(v1_cpi_add_route, sizeof(v1_cpi_add_route), 0, sizeof(v1_cpi_add_route)); + CCNxTlvDictionary *test = _ccnxWireFormatFacadeV1_CreateFromV1(wireFormat); + assertNotNull(test, "Got null dictionary for good control"); + assertTrue(ccnxTlvDictionary_IsControl(test), "Dictionary says it is not a control"); + assertTrue(ccnxTlvDictionary_GetSchemaVersion(test) == 1, "Schema says it is not v1"); + parcBuffer_Release(&wireFormat); + ccnxTlvDictionary_Release(&test); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_Create_InterestReturn) +{ + uint8_t encoded[] = { 1, CCNxCodecSchemaV1Types_PacketType_InterestReturn, 0, 23 }; + PARCBuffer *wireFormat = parcBuffer_Wrap(encoded, sizeof(encoded), 0, sizeof(encoded)); + CCNxTlvDictionary *test = _ccnxWireFormatFacadeV1_CreateFromV1(wireFormat); + assertNotNull(test, "Got null dictionary for good InterestReturn"); + assertTrue(ccnxTlvDictionary_IsInterestReturn(test), "Expected IsInterestReturn() to be true"); + assertTrue(ccnxTlvDictionary_GetSchemaVersion(test) == 1, "Schema says it is not v1"); + parcBuffer_Release(&wireFormat); + ccnxTlvDictionary_Release(&test); +} + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_Create_UnknownPacketType) +{ + uint8_t encoded[] = { 1, 99, 0, 23 }; + PARCBuffer *wireFormat = parcBuffer_Wrap(encoded, sizeof(encoded), 0, sizeof(encoded)); + CCNxTlvDictionary *test = _ccnxWireFormatFacadeV1_CreateFromV1(wireFormat); + assertNull(test, "Should have gotten null dictionary for unknown packet type"); + parcBuffer_Release(&wireFormat); +} + + +static uint8_t _v1_ContentObject_WithKnownHash[] = { + // Name: lci:/boose/roo/pie + // Payload: "this is the payload" + // Signer: CRC32 + // CO Hash: 4FB301EA5FD523B9A71287B721DC20C94B2D4827674A8CA275B7D57C60447876 + + 0x01, 0x01, 0x00, 0x4e, // Fixed Header + 0x00, 0x00, 0x00, 0x08, + + 0x00, 0x02, 0x00, 0x32, // Type 2 == ContentObject, length 50 (0x32) + 0x00, 0x00, 0x00, 0x17, // Name, length 23 (0x17) + + 0x00, 0x01, 0x00, 0x05, // NameSegment, length 5 + 0x62, 0x6f, 0x6f, 0x73, // "boose" + 0x65, + + 0x00, 0x01, 0x00, 0x03, // NameSegment, length 3 + 0x72, 0x6f, 0x6f, // "roo" + + 0x00, 0x01, 0x00, 0x03, // NameSegment, length 3 + 0x70, 0x69, 0x65, // "pie" + + 0x00, 0x01, 0x00, 0x13, // Payload, length 19 (0x13) + 0x74, 0x68, 0x69, 0x73, // "this is the payload" + 0x20, 0x69, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x20, + 0x70, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, + + 0x00, 0x03, 0x00, 0x04, // Validation Alg, length 4 + 0x00, 0x02, 0x00, 0x00, // CRC32, length 0 + + 0x00, 0x04, 0x00, 0x04, // Validation Payload, length 4 + 0x7e, 0x60, 0x54, 0xc4, // The payload (the CRC32) +}; + +LONGBOW_TEST_CASE(SchemaV1, ccnxWireFormatFacadeV1_ComputeContentObjectHash) +{ + PARCBuffer *wireFormatBuffer = parcBuffer_Wrap(_v1_ContentObject_WithKnownHash, sizeof(_v1_ContentObject_WithKnownHash), + 0, sizeof(_v1_ContentObject_WithKnownHash)); + + CCNxWireFormatMessage *message = ccnxWireFormatMessage_Create(wireFormatBuffer); + + CCNxTlvDictionary *contentObject = ccnxWireFormatMessage_GetDictionary(message); + + // We have a partially unpacked dictionary now, but we need to more fully unpack it for our processing. + assertTrue(ccnxCodecTlvPacket_BufferDecode(wireFormatBuffer, contentObject), "Expected to decode the wireformat buffer"); + + + PARCCryptoHash *coHash = _ccnxWireFormatFacadeV1_ComputeContentObjectHash(contentObject); + + assertNotNull(coHash, "Expected a non-NULL content object hash"); + + char *computedHash = parcBuffer_ToHexString(parcCryptoHash_GetDigest(coHash)); + + char *knownHash = "4FB301EA5FD523B9A71287B721DC20C94B2D4827674A8CA275B7D57C60447876"; + + assertTrue(strncasecmp(computedHash, knownHash, strlen(knownHash)) == 0, "Expected a matching ContentObject hash"); + + parcMemory_Deallocate(&computedHash); + parcCryptoHash_Release(&coHash); + parcBuffer_Release(&wireFormatBuffer); + + ccnxContentObject_Release(&contentObject); +} + +// ======================================================================= + +LONGBOW_TEST_FIXTURE(Local) +{ + LONGBOW_RUN_TEST_CASE(Local, _ccnxWireFormatFacadeV1_ComputeHash); +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + + +LONGBOW_TEST_CASE(Local, _ccnxWireFormatFacadeV1_ComputeHash) +{ + // >1234< + const char string[] = "Hello dev null\n"; + const char substring[] = " dev"; + + PARCBuffer *buffer = parcBuffer_Wrap((void *) string, sizeof(string), 0, sizeof(string)); + size_t start = 5; + size_t length = 4; + + + // compute the true hash + PARCCryptoHasher *hasher = parcCryptoHasher_Create(PARCCryptoHashType_SHA256); + parcCryptoHasher_Init(hasher); + parcCryptoHasher_UpdateBytes(hasher, substring, length); + PARCCryptoHash *truthHash = parcCryptoHasher_Finalize(hasher); + + // Compute the test hash + PARCCryptoHash *testHash = _ccnxWireFormatFacadeV1_ComputeBufferHash(buffer, hasher, start, length); + + // Test + bool equals = parcCryptoHash_Equals(truthHash, testHash); + assertTrue(equals, "Hashes do not match") + { + PARCBuffer *truthBuffer = parcCryptoHash_GetDigest(truthHash); + PARCBuffer *testBuffer = parcCryptoHash_GetDigest(testHash); + + printf("Expected:\n"); + parcBuffer_Display(truthBuffer, 3); + + printf("Got:\n"); + parcBuffer_Display(testBuffer, 3); + } + + parcCryptoHash_Release(&truthHash); + parcCryptoHash_Release(&testHash); + parcBuffer_Release(&buffer); + parcCryptoHasher_Release(&hasher); +} + +// ======================================================================= + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_WireFormatFacade); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} |