diff options
Diffstat (limited to 'metis/ccnx/forwarder/metis/tlv/test')
9 files changed, 2728 insertions, 0 deletions
diff --git a/metis/ccnx/forwarder/metis/tlv/test/.gitignore b/metis/ccnx/forwarder/metis/tlv/test/.gitignore new file mode 100644 index 00000000..5cba902c --- /dev/null +++ b/metis/ccnx/forwarder/metis/tlv/test/.gitignore @@ -0,0 +1,8 @@ +test_metis_Tlv +test_metis_TlvExtent +test_metis_TlvName +test_metis_TlvNameCodec +test_metis_TlvSchemaV0 +test_metis_TlvSchemaV1 +test_metis_TlvSkeleton + diff --git a/metis/ccnx/forwarder/metis/tlv/test/CMakeLists.txt b/metis/ccnx/forwarder/metis/tlv/test/CMakeLists.txt new file mode 100644 index 00000000..73f1d34d --- /dev/null +++ b/metis/ccnx/forwarder/metis/tlv/test/CMakeLists.txt @@ -0,0 +1,19 @@ +# Enable gcov output for the tests +add_definitions(--coverage) +set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} " --coverage") + +set(TestsExpectedToPass + test_metis_Tlv + test_metis_TlvExtent + test_metis_TlvName + test_metis_TlvNameCodec + test_metis_TlvSchemaV0 + test_metis_TlvSchemaV1 + test_metis_TlvSkeleton +) + + +foreach(test ${TestsExpectedToPass}) + AddTest(${test}) +endforeach() + diff --git a/metis/ccnx/forwarder/metis/tlv/test/test_metis_Tlv.c b/metis/ccnx/forwarder/metis/tlv/test/test_metis_Tlv.c new file mode 100644 index 00000000..79a28ed3 --- /dev/null +++ b/metis/ccnx/forwarder/metis/tlv/test/test_metis_Tlv.c @@ -0,0 +1,249 @@ +/* + * 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 "../metis_Tlv.c" +#include <LongBow/unit-test.h> +#include <parc/algol/parc_SafeMemory.h> + +#include <ccnx/forwarder/metis/testdata/metis_TestDataV0.h> +#include <ccnx/forwarder/metis/testdata/metis_TestDataV1.h> + +LONGBOW_TEST_RUNNER(metis_Tlv) +{ + // 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(metis_Tlv) +{ + 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(metis_Tlv) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, metisTlv_NameSegments); + LONGBOW_RUN_TEST_CASE(Global, metisTlv_NameSegments_Realloc); + LONGBOW_RUN_TEST_CASE(Global, metisTlv_ExtentToVarInt); + + LONGBOW_RUN_TEST_CASE(Global, metisTlv_FixedHeaderLength); + LONGBOW_RUN_TEST_CASE(Global, metisTlv_TotalHeaderLength_V0); + LONGBOW_RUN_TEST_CASE(Global, metisTlv_TotalHeaderLength_V1); + LONGBOW_RUN_TEST_CASE(Global, metisTlv_TotalPacketLength_V0); + LONGBOW_RUN_TEST_CASE(Global, metisTlv_TotalPacketLength_V1); + + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, metisTlv_EncodeControlPlaneInformation_V0); + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, metisTlv_EncodeControlPlaneInformation_V1); +} + +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, metisTlv_NameSegments) +{ + uint8_t name[] = { + 0x00, 0x02, 0x00, 0x05, // type = binary, length = 5 + 'h', 'e', 'l', 'l', + 'o', // "hello" + 0xF0, 0x00, 0x00, 0x04, // type = app, length = 4 + 'o', 'u', 'c', 'h' + }; + + MetisTlvExtent *nameExtents; + size_t nameExtentsLength; + + MetisTlvExtent truthExtents[] = { { .offset = 0, .length = 9 }, { .offset = 9, .length = 8 } }; + size_t truthExtentsLength = 2; + + metisTlv_NameSegments(name, sizeof(name), &nameExtents, &nameExtentsLength); + + assertTrue(nameExtentsLength == truthExtentsLength, "nameExtentsLength wrong, expected %zu got %zu", truthExtentsLength, nameExtentsLength); + for (int i = 0; i < nameExtentsLength; i++) { + assertTrue(truthExtents[i].offset == nameExtents[i].offset, + "nameExtents[%d].offset wrong, expected %u got %u", + i, + truthExtents[i].offset, + nameExtents[i].offset); + + assertTrue(truthExtents[i].length == nameExtents[i].length, + "nameExtents[%d].offset wrong, expected %u got %u", + i, + truthExtents[i].length, + nameExtents[i].length); + } + + parcMemory_Deallocate((void **) &nameExtents); +} + +/** + * Create a name with enough name components to cause a re-alloc in the parser + */ +LONGBOW_TEST_CASE(Global, metisTlv_NameSegments_Realloc) +{ + uint8_t oneSegment[] = { + 0x00, 0x02, 0x00, 0x04, // type = binary, length = 4 + 'h', 'e', 'l', 'l' + }; + + // build a name with neededComponents copies of oneSegment such that it will + // exceed the initialLengthForNameExtents allocation in the parser + + size_t neededComponents = _initialLengthForNameExtents + 2; + size_t nameBufferLength = neededComponents * sizeof(oneSegment); + + uint8_t *nameBuffer = parcMemory_Allocate(nameBufferLength); + assertNotNull(nameBuffer, "parcMemory_Allocate(%zu) returned NULL", nameBufferLength); + for (int i = 0; i < neededComponents; i++) { + memcpy(nameBuffer + i * sizeof(oneSegment), oneSegment, sizeof(oneSegment)); + } + + MetisTlvExtent *nameExtents; + size_t nameExtentsLength; + + metisTlv_NameSegments(nameBuffer, nameBufferLength, &nameExtents, &nameExtentsLength); + + assertTrue(nameExtentsLength == neededComponents, + "metisTlv_NameSegments returned wrong number of segments, expected %zu got %zu", + neededComponents, + nameExtentsLength); + + + parcMemory_Deallocate((void **) &nameExtents); + parcMemory_Deallocate((void **) &nameBuffer); +} + +LONGBOW_TEST_CASE(Global, metisTlv_ExtentToVarInt) +{ + uint8_t packet[] = { 0xff, 0xff, 0x00, 0x01, 0x02, 0xff, 0xff }; + MetisTlvExtent extent = { 2, 3 }; + uint64_t truth = 0x0102; + uint64_t test = 0; + + bool success = metisTlv_ExtentToVarInt(packet, &extent, &test); + assertTrue(success, "Failed to parse a good extent"); + assertTrue(truth == test, "Wrong value, expected %#" PRIx64 "got %#" PRIx64, truth, test); +} + +LONGBOW_TEST_CASE(Global, metisTlv_FixedHeaderLength) +{ + size_t test = metisTlv_FixedHeaderLength(); + assertTrue(test == 8, "Wrong fixed header length, got %zu", test); +} + +LONGBOW_TEST_CASE(Global, metisTlv_TotalHeaderLength_V0) +{ + size_t test = metisTlv_TotalHeaderLength(metisTestDataV0_EncodedInterest); + assertTrue(test == 29, "Wrong total header length, expected 29 got %zu", test); +} + +LONGBOW_TEST_CASE(Global, metisTlv_TotalHeaderLength_V1) +{ + size_t test = metisTlv_TotalHeaderLength(metisTestDataV1_Interest_AllFields); + assertTrue(test == 14, "Wrong total header length, expected 14 got %zu", test); +} + +LONGBOW_TEST_CASE(Global, metisTlv_TotalPacketLength_V0) +{ + size_t test = metisTlv_TotalPacketLength(metisTestDataV0_EncodedInterest); + assertTrue(test == sizeof(metisTestDataV0_EncodedInterest), "Wrong total header length, expected %zu got %zu", sizeof(metisTestDataV0_EncodedInterest), test); +} + +LONGBOW_TEST_CASE(Global, metisTlv_TotalPacketLength_V1) +{ + size_t test = metisTlv_TotalPacketLength(metisTestDataV1_Interest_AllFields); + assertTrue(test == sizeof(metisTestDataV1_Interest_AllFields), "Wrong total header length, expected %zu got %zu", sizeof(metisTestDataV1_Interest_AllFields), test); +} + +LONGBOW_TEST_CASE(TlvOpsFunctions, metisTlv_EncodeControlPlaneInformation_V0) +{ + CCNxControl *control = ccnxControl_CreateRouteListRequest(); + + PARCBuffer *buffer = metisTlv_EncodeControlPlaneInformation(control); + ccnxControl_Release(&control); + + assertNotNull(buffer, "Got null encoding buffer"); + uint8_t *overlay = parcBuffer_Overlay(buffer, 0); + + assertTrue(overlay[1] == 0xA4, "PacketType is not Control"); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(TlvOpsFunctions, metisTlv_EncodeControlPlaneInformation_V1) +{ + // there's no easy way to test this right now, cannot contruct a v1 CCNxControl +} + + +// =================================================== + +LONGBOW_TEST_FIXTURE(Local) +{ + // computeHash and parseName Auth are tested called through by other tests + + LONGBOW_RUN_TEST_CASE(Local, _metisTlv_ParseName); +} + +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, _metisTlv_ParseName) +{ +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(metis_Tlv); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvExtent.c b/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvExtent.c new file mode 100644 index 00000000..f61904f9 --- /dev/null +++ b/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvExtent.c @@ -0,0 +1,90 @@ +/* + * 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 "../metis_TlvExtent.c" +#include <LongBow/unit-test.h> +#include <parc/algol/parc_SafeMemory.h> + +LONGBOW_TEST_RUNNER(tlv_Extent) +{ + // 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(tlv_Extent) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(tlv_Extent) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, tlvExtent_Equals_IsEqual); + LONGBOW_RUN_TEST_CASE(Global, tlvExtent_Equals_IsNotEqual); +} + +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, tlvExtent_Equals_IsEqual) +{ + MetisTlvExtent a = { .offset = 5, .length = 7 }; + MetisTlvExtent b = { .offset = 5, .length = 7 }; + MetisTlvExtent c = { .offset = 5, .length = 7 }; + + // transitivity testing too + assertTrue(metisTlvExtent_Equals(&a, &b), "Two equal extents did not compare equal"); + assertTrue(metisTlvExtent_Equals(&b, &c), "Two equal extents did not compare equal"); + assertTrue(metisTlvExtent_Equals(&c, &a), "Two equal extents did not compare equal"); +} + +LONGBOW_TEST_CASE(Global, tlvExtent_Equals_IsNotEqual) +{ + MetisTlvExtent a = { .offset = 5, .length = 7 }; + MetisTlvExtent b = { .offset = 3, .length = 7 }; + + assertFalse(metisTlvExtent_Equals(&a, &b), "Two unequal extents compare equal"); +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(tlv_Extent); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvName.c b/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvName.c new file mode 100644 index 00000000..5fba7669 --- /dev/null +++ b/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvName.c @@ -0,0 +1,470 @@ +/* + * 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 "../metis_TlvName.c" +#include <LongBow/unit-test.h> + +#include <stdint.h> +#include <limits.h> +#include <parc/algol/parc_SafeMemory.h> + +uint8_t encoded_name[] = { + 0x00, 0x02, 0x00, 0x05, // type = binary, length = 5 + 'h', 'e', 'l', 'l', + 'o', // "hello" + 0xF0, 0x00, 0x00, 0x04, // type = app, length = 4 + 'o', 'u', 'c', 'h', // value = "ouch" + 0xF0, 0x01, 0x00, 0x02, // type = app, length = 2 + 0x01, 0xFF // value = 0x01FF +}; + +uint8_t second_name[] = { + 0x00, 0x02, 0x00, 0x05, // type = binary, length = 5 + 'h', 'e', 'l', 'l', + 'o', // "hello" + 0xF0, 0x00, 0x00, 0x04, // type = app, length = 4 + 'o', 'u', 'c', 'h', // value = "ouch" + 0xF0, 0x01, 0x00, 0x02, // type = app, length = 2 + 0xFF, 0xFF // value = 0xFFFF +}; + +uint8_t prefixOf_name[] = { + 0x00, 0x02, 0x00, 0x05, // type = binary, length = 5 + 'h', 'e', 'l', 'l', + 'o', // "hello" + 0xF0, 0x00, 0x00, 0x04, // type = app, length = 4 + 'o', 'u', 'c', 'h', // value = "ouch" +}; + +uint8_t default_route_name[] = { + 0x00, 0x01, 0x00, 0x00, // type = name, length = 0 +}; + +LONGBOW_TEST_RUNNER(metis_TlvName) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(metis_TlvName) +{ + 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(metis_TlvName) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_Acquire); + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_Acquire_CopyAtMost0); + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_Acquire_CopyAtMost1); + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_Acquire_CopyAtMost2); + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_Acquire_CopyAtMostAll); + + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_Create_Destroy); + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_CreateFromCCNxName); + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_CreateFromCCNxName_DefaultRoute); + + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_Equals_IsEqual); + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_Equals_SameCountDifferentBytes); + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_Equals_DifferentCount); + + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_Compare); + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_Compare_DefaultRoute); + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_Compare_DefaultRoute_Binary); + + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_HashCode); + + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_SegmentCount); + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_StartsWith_SelfPrefix); + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_StartsWith_IsPrefix); + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_StartsWith_PrefixTooLong); + LONGBOW_RUN_TEST_CASE(Global, metisTlvName_StartsWith_IsNotPrefix); +} + +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, metisTlvName_Acquire) +{ + MetisTlvName *name = metisTlvName_Create(encoded_name, sizeof(encoded_name)); + + MetisTlvName *copy = metisTlvName_Acquire(name); + assertTrue(_getRefCount(name) == 2, "Name created with wrong refcount, expected %u got %u", 2, _getRefCount(name)); + + metisTlvName_Release(©); + assertTrue(_getRefCount(name) == 1, "Name created with wrong refcount, expected %u got %u", 1, _getRefCount(name)); + + metisTlvName_Release(&name); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_Create_Destroy) +{ + MetisTlvName *name = metisTlvName_Create(encoded_name, sizeof(encoded_name)); + assertTrue(_getRefCount(name) == 1, "Name created with wrong refcount, expected %u got %u", 1, _getRefCount(name)); + metisTlvName_Release(&name); + + assertTrue(parcSafeMemory_ReportAllocation(STDOUT_FILENO) == 0, "Memory imbalance after create/destroy: %u", parcMemory_Outstanding()); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_CreateFromCCNxName) +{ + char uri[] = "lci:/2=hello/0xF000=ouch/0xF001=%01%FF"; + CCNxName *ccnxName = ccnxName_CreateFromCString(uri); + + MetisTlvName *truth = metisTlvName_Create(encoded_name, sizeof(encoded_name)); + MetisTlvName *name = metisTlvName_CreateFromCCNxName(ccnxName); + + assertTrue(metisTlvName_Equals(truth, name), "MetisTlvName from ccnxName did not equal expected"); + metisTlvName_Release(&name); + metisTlvName_Release(&truth); + ccnxName_Release(&ccnxName); + + assertTrue(parcSafeMemory_ReportAllocation(STDOUT_FILENO) == 0, "Memory imbalance after create/destroy: %u", parcMemory_Outstanding()); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_CreateFromCCNxName_DefaultRoute) +{ + char uri[] = "lci:/"; + CCNxName *ccnxName = ccnxName_CreateFromCString(uri); + + MetisTlvName *truth = metisTlvName_Create(default_route_name, sizeof(default_route_name)); + MetisTlvName *name = metisTlvName_CreateFromCCNxName(ccnxName); + + assertTrue(metisTlvName_Equals(truth, name), "MetisTlvName from ccnxName did not equal expected"); + metisTlvName_Release(&name); + metisTlvName_Release(&truth); + ccnxName_Release(&ccnxName); + + assertTrue(parcSafeMemory_ReportAllocation(STDOUT_FILENO) == 0, "Memory imbalance after create/destroy: %u", parcMemory_Outstanding()); +} + + +LONGBOW_TEST_CASE(Global, metisTlvName_Equals_IsEqual) +{ + MetisTlvName *a = metisTlvName_Create(encoded_name, sizeof(encoded_name)); + MetisTlvName *b = metisTlvName_Create(encoded_name, sizeof(encoded_name)); + + assertTrue(metisTlvName_Equals(a, b), "Two equal names did not compare"); + metisTlvName_Release(&a); + metisTlvName_Release(&b); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_Equals_SameCountDifferentBytes) +{ + MetisTlvName *a = metisTlvName_Create(encoded_name, sizeof(encoded_name)); + MetisTlvName *b = metisTlvName_Create(second_name, sizeof(second_name)); + + assertFalse(metisTlvName_Equals(a, b), "Two names with same # component but differnet bytes compared the same."); + metisTlvName_Release(&a); + metisTlvName_Release(&b); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_Equals_DifferentCount) +{ + MetisTlvName *a = metisTlvName_Create(encoded_name, sizeof(encoded_name)); + MetisTlvName *b = metisTlvName_Create(prefixOf_name, sizeof(prefixOf_name)); + + assertFalse(metisTlvName_Equals(a, b), "Two names with different # component compared the same."); + metisTlvName_Release(&a); + metisTlvName_Release(&b); +} + +int +compareWrapper(void *a, void *b) +{ + return metisTlvName_Compare((MetisTlvName *) a, (MetisTlvName *) b); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_Compare) +{ + CCNxName *basename = ccnxName_CreateFromCString("lci:/middle/of/6=the"); + CCNxName *equal_1 = ccnxName_CreateFromCString("lci:/middle/of/6=the"); + CCNxName *defaultRoute = ccnxName_CreateFromCString("lci:/"); + CCNxName *lesser_by_count = ccnxName_CreateFromCString("lci:/middle/of"); + CCNxName *lesser_by_value = ccnxName_CreateFromCString("lci:/middle/of/6=th"); + CCNxName *lesser_by_type_2 = ccnxName_CreateFromCString("lci:/middle/of/2=the"); + CCNxName *greater_by_count = ccnxName_CreateFromCString("lci:/middle/of/the/road"); + CCNxName *greater_by_type = ccnxName_CreateFromCString("lci:/middle/of/7=the"); + CCNxName *greater_by_value = ccnxName_CreateFromCString("lci:/middle/of/the/town"); + CCNxName *greater_2 = ccnxName_CreateFromCString("lci:/nox/arcana/occulta"); + + void *equivalent[] = { equal_1, NULL }; + void *lesser[] = { defaultRoute, lesser_by_count, lesser_by_type_2, lesser_by_value, NULL }; + void *greater[] = { greater_by_count, greater_by_type, greater_by_value, greater_2, NULL }; + + MetisTlvName *tlv_basename = metisTlvName_CreateFromCCNxName(basename); + void **tlv_equivalent = parcMemory_AllocateAndClear(sizeof(equivalent) * sizeof(void *)); + assertNotNull(tlv_equivalent, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(equivalent) * sizeof(void *)); + void **tlv_lesser = parcMemory_AllocateAndClear(sizeof(lesser) * sizeof(void *)); + assertNotNull(tlv_lesser, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(lesser) * sizeof(void *)); + void **tlv_greater = parcMemory_AllocateAndClear(sizeof(greater) * sizeof(void *)); + assertNotNull(tlv_greater, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(greater) * sizeof(void *)); + + for (int i = 0; equivalent[i] != NULL; i++) { + tlv_equivalent[i] = metisTlvName_CreateFromCCNxName(equivalent[i]); + } + + for (int i = 0; lesser[i] != NULL; i++) { + tlv_lesser[i] = metisTlvName_CreateFromCCNxName(lesser[i]); + } + + for (int i = 0; greater[i] != NULL; i++) { + tlv_greater[i] = metisTlvName_CreateFromCCNxName(greater[i]); + } + + // Use this: + assertCompareToContract(compareWrapper, tlv_basename, tlv_equivalent, tlv_lesser, tlv_greater); + // Not this, unless you provide the necessary casts to avoid warnings. + // longbow_AssertCompareToContract(compareWrapper, tlv_basename, tlv_equivalent, tlv_lesser, tlv_greater); + + for (int i = 0; equivalent[i] != NULL; i++) { + ccnxName_Release((CCNxName **) &equivalent[i]); + metisTlvName_Release((MetisTlvName **) &tlv_equivalent[i]); + } + + for (int i = 0; lesser[i] != NULL; i++) { + ccnxName_Release((CCNxName **) &lesser[i]); + metisTlvName_Release((MetisTlvName **) &tlv_lesser[i]); + } + + for (int i = 0; greater[i] != NULL; i++) { + ccnxName_Release((CCNxName **) &greater[i]); + metisTlvName_Release((MetisTlvName **) &tlv_greater[i]); + } + + ccnxName_Release(&basename); + metisTlvName_Release(&tlv_basename); + parcMemory_Deallocate((void **) &tlv_equivalent); + parcMemory_Deallocate((void **) &tlv_greater); + parcMemory_Deallocate((void **) &tlv_lesser); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_Compare_DefaultRoute) +{ + CCNxName *defaultRoute = ccnxName_CreateFromCString("lci:/"); + MetisTlvName *metisDefaultRoute = metisTlvName_CreateFromCCNxName(defaultRoute); + + // THis name cannot be constructed via CCNxName, so do it as a byte array + // Empty name with "0" type + uint8_t shortest[] = { 0x00, 0x00, 0x00, 4, + 0x00, 0x00, 0x00, 0 }; + + MetisTlvName *metisShortest = metisTlvName_Create(shortest, sizeof(shortest)); + + int compare = metisTlvName_Compare(metisDefaultRoute, metisShortest); + assertTrue(compare < 0, "Default route should have compared less than shortest name, compared = %d", compare); + + metisTlvName_Release(&metisShortest); + metisTlvName_Release(&metisDefaultRoute); + ccnxName_Release(&defaultRoute); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_Compare_DefaultRoute_Binary) +{ + // The empty name (default route) + uint8_t defaultRoute[] = { 0x00, 0x00, 0x00, 0}; + MetisTlvName *metisDefaultRoute = metisTlvName_Create(defaultRoute, sizeof(defaultRoute)); + + // THis name cannot be constructed via CCNxName, so do it as a byte array + // Empty name with "0" type + uint8_t shortest[] = { 0x00, 0x00, 0x00, 4, + 0x00, 0x00, 0x00, 0 }; + + MetisTlvName *metisShortest = metisTlvName_Create(shortest, sizeof(shortest)); + + int compare = metisTlvName_Compare(metisDefaultRoute, metisShortest); + assertTrue(compare < 0, "Default route should have compared less than shortest name, compared = %d", compare); + + metisTlvName_Release(&metisShortest); + metisTlvName_Release(&metisDefaultRoute); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_HashCode) +{ + // first, compute the hashes of the name + uint32_t hash_0 = parcHash32_Data(&encoded_name[0], 9); + uint32_t hash_1 = parcHash32_Data_Cumulative(&encoded_name[ 9], 8, hash_0); + uint32_t hash_2 = parcHash32_Data_Cumulative(&encoded_name[17], 6, hash_1); + + MetisTlvName *name = metisTlvName_Create(encoded_name, sizeof(encoded_name)); + + uint32_t test_hash; + test_hash = metisTlvName_HashCode(name); + assertTrue(test_hash == hash_2, "Incorrect hash for segment %d, expected %08X got %08X", 2, hash_2, test_hash); + + metisTlvName_Release(&name); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_Acquire_CopyAtMost0) +{ + unsigned copyLength = 0; + MetisTlvName *name = metisTlvName_Create(encoded_name, sizeof(encoded_name)); + MetisTlvName *copy = metisTlvName_Slice(name, copyLength); + + // hash of a 0-length name is 0 + uint32_t hash_0 = 0; + + assertTrue(_getRefCount(name) == 2, "Wrong refcount in name, expected %u got %u", 2, _getRefCount(name)); + assertTrue(_getRefCount(copy) == 2, "Wrong refcount in copy, expected %u got %u", 2, _getRefCount(copy)); + assertTrue(copy->segmentArrayLength == copyLength, "Wrong array length, expected %u got %zu", copyLength, copy->segmentArrayLength); + uint32_t test_hash = metisTlvName_HashCode(copy); + assertTrue(test_hash == hash_0, "Incorrect hash for segment %d, expected %08X got %08X", 0, hash_0, test_hash); + + metisTlvName_Release(©); + assertTrue(_getRefCount(name) == 1, "Wrong refcount in name, expected %u got %u", 1, _getRefCount(name)); + metisTlvName_Release(&name); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_Acquire_CopyAtMost1) +{ + unsigned copyLength = 1; + MetisTlvName *name = metisTlvName_Create(encoded_name, sizeof(encoded_name)); + MetisTlvName *copy = metisTlvName_Slice(name, copyLength); + uint32_t hash_0 = parcHash32_Data(&encoded_name[0], 9); + + assertTrue(_getRefCount(name) == 2, "Wrong refcount in name, expected %u got %u", 2, _getRefCount(name)); + assertTrue(_getRefCount(copy) == 2, "Wrong refcount in copy, expected %u got %u", 2, _getRefCount(copy)); + assertTrue(copy->segmentArrayLength == copyLength, "Wrong array length, expected %u got %zu", copyLength, copy->segmentArrayLength); + uint32_t test_hash = metisTlvName_HashCode(copy); + assertTrue(test_hash == hash_0, "Incorrect hash for segment %d, expected %08X got %08X", 0, hash_0, test_hash); + + metisTlvName_Release(©); + assertTrue(_getRefCount(name) == 1, "Wrong refcount in name, expected %u got %u", 1, _getRefCount(name)); + metisTlvName_Release(&name); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_Acquire_CopyAtMost2) +{ + unsigned copyLength = 2; + MetisTlvName *name = metisTlvName_Create(encoded_name, sizeof(encoded_name)); + MetisTlvName *copy = metisTlvName_Slice(name, copyLength); + uint32_t hash_0 = parcHash32_Data(&encoded_name[0], 9); + uint32_t hash_1 = parcHash32_Data_Cumulative(&encoded_name[ 9], 8, hash_0); + + assertTrue(_getRefCount(name) == 2, "Wrong refcount in name, expected %u got %u", 2, _getRefCount(name)); + assertTrue(_getRefCount(copy) == 2, "Wrong refcount in copy, expected %u got %u", 2, _getRefCount(copy)); + assertTrue(copy->segmentArrayLength == copyLength, "Wrong array length, expected %u got %zu", copyLength, copy->segmentArrayLength); + uint32_t test_hash = metisTlvName_HashCode(copy); + assertTrue(test_hash == hash_1, "Incorrect hash for segment %d, expected %08X got %08X", 1, hash_1, test_hash); + + metisTlvName_Release(©); + assertTrue(_getRefCount(name) == 1, "Wrong refcount in name, expected %u got %u", 1, _getRefCount(name)); + metisTlvName_Release(&name); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_Acquire_CopyAtMostAll) +{ + unsigned copyLength = 3; + MetisTlvName *name = metisTlvName_Create(encoded_name, sizeof(encoded_name)); + MetisTlvName *copy = metisTlvName_Slice(name, UINT_MAX); + uint32_t hash_0 = parcHash32_Data(&encoded_name[0], 9); + uint32_t hash_1 = parcHash32_Data_Cumulative(&encoded_name[ 9], 8, hash_0); + uint32_t hash_2 = parcHash32_Data_Cumulative(&encoded_name[17], 6, hash_1); + + assertTrue(_getRefCount(name) == 2, "Wrong refcount in name, expected %u got %u", 2, _getRefCount(name)); + assertTrue(_getRefCount(copy) == 2, "Wrong refcount in copy, expected %u got %u", 2, _getRefCount(copy)); + assertTrue(copy->segmentArrayLength == copyLength, "Wrong array length, expected %u got %zu", copyLength, copy->segmentArrayLength); + uint32_t test_hash = metisTlvName_HashCode(copy); + assertTrue(test_hash == hash_2, "Incorrect hash for segment %d, expected %08X got %08X", 2, hash_2, test_hash); + + metisTlvName_Release(©); + assertTrue(_getRefCount(name) == 1, "Wrong refcount in name, expected %u got %u", 1, _getRefCount(name)); + metisTlvName_Release(&name); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_SegmentCount) +{ + MetisTlvName *a = metisTlvName_Create(encoded_name, sizeof(encoded_name)); + + size_t count = metisTlvName_SegmentCount(a); + assertTrue(count == 3, "Incorrect segment count, expected %u got %zu", 3, count); + + metisTlvName_Release(&a); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_StartsWith_SelfPrefix) +{ + MetisTlvName *name = metisTlvName_Create(encoded_name, sizeof(encoded_name)); + + // a name is always a prefix of itself + bool success = metisTlvName_StartsWith(name, name); + assertTrue(success, "Name is not prefix of self in metisTlvName_StartsWith"); + metisTlvName_Release(&name); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_StartsWith_IsPrefix) +{ + MetisTlvName *name = metisTlvName_Create(encoded_name, sizeof(encoded_name)); + MetisTlvName *prefix = metisTlvName_Create(prefixOf_name, sizeof(prefixOf_name)); + + bool success = metisTlvName_StartsWith(name, prefix); + assertTrue(success, "Valid prefix did not test true in metisTlvName_StartsWith"); + metisTlvName_Release(&name); + metisTlvName_Release(&prefix); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_StartsWith_PrefixTooLong) +{ + MetisTlvName *name = metisTlvName_Create(encoded_name, sizeof(encoded_name)); + MetisTlvName *prefix = metisTlvName_Create(prefixOf_name, sizeof(prefixOf_name)); + + // we just reversed the prefix and name from the test metisTlvName_StartsWith_IsPrefix, + // so the prefix is longer than the name + bool success = metisTlvName_StartsWith(prefix, name); + assertFalse(success, "Invalid prefix tested true in metisTlvName_StartsWith"); + metisTlvName_Release(&name); + metisTlvName_Release(&prefix); +} + +LONGBOW_TEST_CASE(Global, metisTlvName_StartsWith_IsNotPrefix) +{ + MetisTlvName *name = metisTlvName_Create(encoded_name, sizeof(encoded_name)); + MetisTlvName *other = metisTlvName_Create(second_name, sizeof(second_name)); + + // we just reversed the prefix and name from the test metisTlvName_StartsWith_IsPrefix + bool success = metisTlvName_StartsWith(other, name); + assertFalse(success, "Invalid prefix tested true in metisTlvName_StartsWith"); + metisTlvName_Release(&name); + metisTlvName_Release(&other); +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(metis_TlvName); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvNameCodec.c b/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvNameCodec.c new file mode 100644 index 00000000..121adf29 --- /dev/null +++ b/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvNameCodec.c @@ -0,0 +1,172 @@ +/* + * 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 "../metis_TlvNameCodec.c" +#include <parc/algol/parc_SafeMemory.h> +#include <LongBow/unit-test.h> + +LONGBOW_TEST_RUNNER(tlv_NameCodec) +{ + // 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(tlv_NameCodec) +{ + 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(tlv_NameCodec) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, tlvName_Decode_0_Length_Name); + LONGBOW_RUN_TEST_CASE(Global, tlvName_Decode_0_Length_Segment); + LONGBOW_RUN_TEST_CASE(Global, tlvName_Decode_Good); + LONGBOW_RUN_TEST_CASE(Global, tlvName_Decode_Overflow); + LONGBOW_RUN_TEST_CASE(Global, tlvName_Decode_UnderRun); +} + +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; +} + +/** + * Buffer is 1 .. 3 bytes + */ +LONGBOW_TEST_CASE_EXPECTS(Global, tlvName_Decode_UnderRun, .event = &LongBowTrapIllegalValue) +{ + // offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + // |-- type --|-- length --|| + uint8_t buffer[] = { 0xFF, 0x00, 0x00, 0x00, 0x04, 0xFF }; + + // This will assert + // CCNxName *name = + metisTlvNameCodec_Decode(buffer, 5, 6); +} + +/** + * Buffer exactly 0 bytes + */ +LONGBOW_TEST_CASE(Global, tlvName_Decode_0_Length_Name) +{ + // offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + // |-- type --|-- length --|| + uint8_t buffer[] = { 0xFF, 0x00, 0x00, 0x00, 0x04, 0xFF }; + + // skip the two 0xFF bytes + // name = "lci:/%02=abcd" + CCNxName *test = metisTlvNameCodec_Decode(buffer, 5, 5); + CCNxName *truth = ccnxName_Create(); + char *nameString = ccnxName_ToString(test); + + assertTrue(ccnxName_Equals(truth, test), "Names not equal, got %s", nameString); + + parcMemory_Deallocate((void **) &nameString); + ccnxName_Release(&truth); + ccnxName_Release(&test); +} + +/** + * Buffer exactly 4 bytes + */ +LONGBOW_TEST_CASE(Global, tlvName_Decode_0_Length_Segment) +{ + // offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + // |-- type --|-- length --|-- type --|-- length --|| + uint8_t buffer[] = { 0xFF, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0xFF }; + + // skip the two 0xFF bytes + // name = "lci:/%02=abcd" + CCNxName *test = metisTlvNameCodec_Decode(buffer, 5, 9); +// CCNxName *truth = ccnxName_CreateFromCString("lci:/%02="); + CCNxName *truth = ccnxName_CreateFromCString("lci:/2="); + char *nameString = ccnxName_ToString(test); + + assertTrue(ccnxName_Equals(truth, test), "Names not equal, got %s", nameString); + + parcMemory_Deallocate((void **) &nameString); + ccnxName_Release(&truth); + ccnxName_Release(&test); +} + +/** + * A good, normal name + */ +LONGBOW_TEST_CASE(Global, tlvName_Decode_Good) +{ + // offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + // |-- type --|-- length --|-- type --|-- length --| ----- value -----| + uint8_t buffer[] = { 0xFF, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x04, 'a', 'b', 'c', 'd', 0xFF }; + + // skip the two 0xFF bytes + // name = "lci:/%02=abcd" + CCNxName *test = metisTlvNameCodec_Decode(buffer, 5, 13); + +// CCNxName *truth = ccnxName_CreateFromCString("lci:/%02=abcd"); + CCNxName *truth = ccnxName_CreateFromCString("lci:/2=abcd"); + char *nameString = ccnxName_ToString(test); + + assertTrue(ccnxName_Equals(truth, test), "Names not equal, got %s", nameString); + + parcMemory_Deallocate((void **) &nameString); + ccnxName_Release(&truth); + ccnxName_Release(&test); +} + +/** + * The name component length shoots beyond the end of the buffer. Byte 8 is "5" instead of "4". + */ +LONGBOW_TEST_CASE_EXPECTS(Global, tlvName_Decode_Overflow, .event = &LongBowTrapIllegalValue) +{ + // offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + // |-- type --|-- length --|-- type --|-- length --| ----- value -----| + uint8_t buffer[] = { 0xFF, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x05, 'a', 'b', 'c', 'd', 0xFF }; + + // This will trap because the length 5 will go beyond 12 + metisTlvNameCodec_Decode(buffer, 5, 13); +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(tlv_NameCodec); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvSchemaV0.c b/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvSchemaV0.c new file mode 100644 index 00000000..bfb5a47c --- /dev/null +++ b/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvSchemaV0.c @@ -0,0 +1,342 @@ +/* + * 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 "../metis_TlvSchemaV0.c" +#include "../metis_TlvSkeleton.c" +#include <LongBow/unit-test.h> +#include <parc/algol/parc_SafeMemory.h> +#include <parc/logging/parc_LogReporterTextStdout.h> + +#include <ccnx/forwarder/metis/testdata/metis_TestDataV0.h> + +static void +verifyInterestPerHop(MetisTlvSkeleton *skeleton) +{ + MetisTlvExtent extent = metisTlvSkeleton_GetHopLimit(skeleton); + assertTrue(extent.offset == 12, "Incorrect hopLimit offset, expected %u got %u", 12, extent.offset); + assertTrue(extent.length == 1, "Incorrect hopLimit length, expected %u got %u", 1, extent.length); +} + +static void +verifyInterestSkeleton(MetisTlvSkeleton *skeleton) +{ + MetisTlvExtent nameExtent = metisTlvSkeleton_GetName(skeleton); + assertTrue(nameExtent.offset == 37, "Incorrect name offset, expected %u got %u", 37, nameExtent.offset); + assertTrue(nameExtent.length == 17, "Incorrect name length, expected %u got %u", 17, nameExtent.length); + + MetisTlvExtent keyidExtent = metisTlvSkeleton_GetKeyId(skeleton); + assertTrue(keyidExtent.offset == 58, "Incorrect keyId offset, expected %u got %u", 58, keyidExtent.offset); + assertTrue(keyidExtent.length == 4, "Incorrect keyId length, expected %u got %u", 4, keyidExtent.length); + + MetisTlvExtent objHashExtent = metisTlvSkeleton_GetObjectHash(skeleton); + assertTrue(objHashExtent.offset == 66, "Incorrect objectHash offset, expected %u got %u", 66, objHashExtent.offset); + assertTrue(objHashExtent.length == 6, "Incorrect objectHash length, expected %u got %u", 6, objHashExtent.length); + + MetisTlvExtent lifetimeExtent = metisTlvSkeleton_GetInterestLifetime(skeleton); + assertTrue(lifetimeExtent.offset == 81, "Incorrect interestLifetime offset, expected %u got %u", 81, lifetimeExtent.offset); + assertTrue(lifetimeExtent.length == 2, "Incorrect interestLifetime length, expected %u got %u", 2, lifetimeExtent.length); +} + +static void +verifyObjectPerHop(MetisTlvSkeleton *skeleton) +{ + MetisTlvExtent hoplimitExtent = metisTlvSkeleton_GetHopLimit(skeleton); + assertTrue(hoplimitExtent.offset == 12, "Incorrect hopLimit offset, expected %u got %u", 12, hoplimitExtent.offset); + assertTrue(hoplimitExtent.length == 1, "Incorrect hopLimit length, expected %u got %u", 1, hoplimitExtent.length); +} + +static void +verifyObjectSkeleton(MetisTlvSkeleton *skeleton) +{ + MetisTlvExtent nameExtent = metisTlvSkeleton_GetName(skeleton); + assertTrue(nameExtent.offset == metisTestDataV0_EncodedObject_name.offset, "Incorrect name offset, expected %u got %u", metisTestDataV0_EncodedObject_name.offset, nameExtent.offset); + assertTrue(nameExtent.length == metisTestDataV0_EncodedObject_name.length, "Incorrect name length, expected %u got %u", metisTestDataV0_EncodedObject_name.length, nameExtent.length); + + MetisTlvExtent keyidExtent = metisTlvSkeleton_GetKeyId(skeleton); + assertTrue(keyidExtent.offset == metisTestDataV0_EncodedObject_keyid.offset, "Incorrect keyId offset, expected %u got %u", metisTestDataV0_EncodedObject_keyid.offset, keyidExtent.offset); + assertTrue(keyidExtent.length == metisTestDataV0_EncodedObject_keyid.length, "Incorrect keyId length, expected %u got %u", metisTestDataV0_EncodedObject_keyid.length, keyidExtent.length); +} + +LONGBOW_TEST_RUNNER(metis_TlvSchemaV0) +{ + // 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(metis_TlvSchemaV0) +{ + 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(metis_TlvSchemaV0) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, metisTlvSchemaV0_ComputeContentObjectHash); + LONGBOW_RUN_TEST_CASE(Global, metisTlvSchemaV0_Skeleton_Interest); + LONGBOW_RUN_TEST_CASE(Global, metisTlvSchemaV0_Skeleton_Object); + LONGBOW_RUN_TEST_CASE(Global, metisTlvSchemaV0_Skeleton_Control); + + LONGBOW_RUN_TEST_CASE(Global, metisTlvSchemaV0_IsPacketTypeInterest_True); + LONGBOW_RUN_TEST_CASE(Global, metisTlvSchemaV0_IsPacketTypeContentObject_True); + LONGBOW_RUN_TEST_CASE(Global, metisTlvSchemaV0_IsPacketTypeInterest_False); + LONGBOW_RUN_TEST_CASE(Global, metisTlvSchemaV0_IsPacketTypeContentObject_False); + + LONGBOW_RUN_TEST_CASE(Global, metisTlvSchemaV0_EncodeControlPlaneInformation); +} + +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, metisTlvSchemaV0_ComputeContentObjectHash) +{ + _MetisTlvFixedHeaderV0 *hdr = (_MetisTlvFixedHeaderV0 *) metisTestDataV0_EncodedObject; + size_t headerLength = htons(hdr->headerLength); + size_t endHeaders = FIXED_HEADER_LEN + headerLength; + size_t endPacket = metisTlv_TotalPacketLength((uint8_t *) hdr); + + uint8_t *start = &metisTestDataV0_EncodedObject[endHeaders]; + size_t length = endPacket - endHeaders; + + PARCCryptoHasher *hasher = parcCryptoHasher_Create(PARCCryptoHashType_SHA256); + parcCryptoHasher_Init(hasher); + parcCryptoHasher_UpdateBytes(hasher, start, length); + + PARCCryptoHash *hash_truth = parcCryptoHasher_Finalize(hasher); + + PARCCryptoHash *hash_test = _computeContentObjectHash(metisTestDataV0_EncodedObject); + + assertTrue(parcCryptoHash_Equals(hash_truth, hash_test), + "Content object digests did not match: truth %s test %s", + parcBuffer_ToString(parcCryptoHash_GetDigest(hash_truth)), + parcBuffer_ToString(parcCryptoHash_GetDigest(hash_test))); + + parcCryptoHash_Release(&hash_truth); + parcCryptoHash_Release(&hash_test); + parcCryptoHasher_Release(&hasher); +} + +LONGBOW_TEST_CASE(Global, metisTlvSchemaV0_Skeleton_Interest) +{ + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize(skeleton, &MetisTlvSchemaV0_Ops, metisTestDataV0_EncodedInterest, logger); + _parse(&opaque); + verifyInterestPerHop(&opaque); + verifyInterestSkeleton(&opaque); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Global, metisTlvSchemaV0_Skeleton_Object) +{ + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize(skeleton, &MetisTlvSchemaV0_Ops, metisTestDataV0_EncodedObject, logger); + _parse(&opaque); + verifyObjectPerHop(&opaque); + verifyObjectSkeleton(&opaque); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Global, metisTlvSchemaV0_Skeleton_Control) +{ + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize(skeleton, &MetisTlvSchemaV0_Ops, metisTestDataV0_CPIMessage, logger); + _parse(&opaque); + + MetisTlvExtent cpiExtent = metisTlvSkeleton_GetCPI(&opaque); + assertTrue(cpiExtent.offset == 12, "cpi offset wrong, got %u expected %u", cpiExtent.offset, 12); + assertTrue(cpiExtent.length == 47, "cpi length wrong, got %u expected %u", cpiExtent.length, 47); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Global, metisTlvSchemaV0_IsPacketTypeInterest_True) +{ + bool result = _isPacketTypeInterest(metisTestDataV0_EncodedInterest); + assertTrue(result, "Interest packet type did not return true for IsInterest test"); +} + +LONGBOW_TEST_CASE(Global, metisTlvSchemaV0_IsPacketTypeContentObject_True) +{ + bool result = _isPacketTypeContentObject(metisTestDataV0_EncodedObject); + assertTrue(result, "ContentObject packet type did not return true for IsContentObject test"); +} + +LONGBOW_TEST_CASE(Global, metisTlvSchemaV0_IsPacketTypeInterest_False) +{ + bool result = _isPacketTypeInterest(metisTestDataV0_EncodedObject); + assertFalse(result, "ContentObject packet type did not return false for IsInterest test"); +} + +LONGBOW_TEST_CASE(Global, metisTlvSchemaV0_IsPacketTypeContentObject_False) +{ + bool result = _isPacketTypeContentObject(metisTestDataV0_EncodedInterest); + assertFalse(result, "Interest packet type did not return false for IsContentObject test"); +} + +LONGBOW_TEST_CASE(Global, metisTlvSchemaV0_EncodeControlPlaneInformation) +{ + CCNxControl *control = ccnxControl_CreateRouteListRequest(); + PARCBuffer *buffer = _encodeControlPlaneInformation(control); + PARCBuffer *truth = parcBuffer_Flip(parcBuffer_PutArray(parcBuffer_Allocate(sizeof(metisTestDataV0_CPIMessage)), sizeof(metisTestDataV0_CPIMessage), metisTestDataV0_CPIMessage)); + + assertTrue(parcBuffer_Equals(truth, buffer), "Buffers not equal") + { + printf("expected:\n"); + parcBuffer_Display(truth, 3); + printf("got:\n"); + parcBuffer_Display(buffer, 3); + } + ccnxControl_Release(&control); + parcBuffer_Release(&truth); + parcBuffer_Release(&buffer); +} + + +// ====================================================== + +LONGBOW_TEST_FIXTURE(Local) +{ + // computeHash and parseName Auth are tested called through by other tests + + LONGBOW_RUN_TEST_CASE(Local, _parseInterestV0); + LONGBOW_RUN_TEST_CASE(Local, _parseObjectV0); + LONGBOW_RUN_TEST_CASE(Local, _parsePerHopV0_Interest); + LONGBOW_RUN_TEST_CASE(Local, _parsePerHopV0_Object); +} + +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, _parseInterestV0) +{ + MetisTlvSkeleton skeleton; + memset(&skeleton, 0, sizeof(skeleton)); + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize((_InternalSkeleton *) &skeleton, &MetisTlvSchemaV0_Ops, metisTestDataV0_EncodedInterest, logger); + + _MetisTlvFixedHeaderV0 *hdr = (_MetisTlvFixedHeaderV0 *) metisTestDataV0_EncodedInterest; + size_t headerLength = htons(hdr->headerLength); + size_t endHeaders = FIXED_HEADER_LEN + headerLength; + size_t endPacket = metisTlv_TotalPacketLength((uint8_t *) hdr); + + _parseInterestV0(metisTestDataV0_EncodedInterest, endHeaders, endPacket, &skeleton); + verifyInterestSkeleton(&skeleton); + + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Local, _parseObjectV0) +{ + MetisTlvSkeleton skeleton; + memset(&skeleton, 0, sizeof(skeleton)); + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize((_InternalSkeleton *) &skeleton, &MetisTlvSchemaV0_Ops, metisTestDataV0_EncodedInterest, logger); + + _MetisTlvFixedHeaderV0 *hdr = (_MetisTlvFixedHeaderV0 *) metisTestDataV0_EncodedObject; + size_t headerLength = htons(hdr->headerLength); + size_t endHeaders = FIXED_HEADER_LEN + headerLength; + size_t endPacket = metisTlv_TotalPacketLength((uint8_t *) hdr); + + _parseObjectV0(metisTestDataV0_EncodedObject, endHeaders, endPacket, &skeleton); + verifyObjectSkeleton(&skeleton); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Local, _parsePerHopV0_Interest) +{ + MetisTlvSkeleton skeleton; + memset(&skeleton, 0, sizeof(skeleton)); + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize((_InternalSkeleton *) &skeleton, &MetisTlvSchemaV0_Ops, metisTestDataV0_EncodedInterest, logger); + + _parsePerHopV0(metisTestDataV0_EncodedInterest, 8, 29, &skeleton); + verifyInterestPerHop(&skeleton); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Local, _parsePerHopV0_Object) +{ + MetisTlvSkeleton skeleton; + memset(&skeleton, 0, sizeof(skeleton)); + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize((_InternalSkeleton *) &skeleton, &MetisTlvSchemaV0_Ops, metisTestDataV0_EncodedInterest, logger); + + _parsePerHopV0(metisTestDataV0_EncodedObject, 8, 29, &skeleton); + verifyObjectPerHop(&skeleton); + metisLogger_Release(&logger); +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(metis_TlvSchemaV0); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvSchemaV1.c b/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvSchemaV1.c new file mode 100644 index 00000000..75dcd68d --- /dev/null +++ b/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvSchemaV1.c @@ -0,0 +1,518 @@ +/* + * 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 "../metis_TlvSchemaV1.c" +#include "../metis_TlvSkeleton.c" +#include <LongBow/unit-test.h> +#include <parc/algol/parc_SafeMemory.h> +#include <parc/logging/parc_LogReporterTextStdout.h> + +#include <ccnx/forwarder/metis/testdata/metis_TestDataV1.h> + + +LONGBOW_TEST_RUNNER(metis_TlvSchemaV1) +{ + LONGBOW_RUN_TEST_FIXTURE(TlvOpsFunctions); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(metis_TlvSchemaV1) +{ + 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(metis_TlvSchemaV1) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// ====================================================== + +LONGBOW_TEST_FIXTURE(TlvOpsFunctions) +{ + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, _parse_Interest); + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, _parse_ContentObject); + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, _parse_Control); + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, _parse_InterestReturn); + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, _parse_Unknown); + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, _parse_HopByHopFragment); + + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, _computeContentObjectHash); + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, _encodeControlPlaneInformation); + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, _fixedHeaderLength); + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, _totalHeaderLength); + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, _totalPacketLength); + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, _isPacketTypeInterest); + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, _isPacketTypeContentObject); + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, _isPacketTypeInterestReturn); + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, _isPacketTypeControl); + LONGBOW_RUN_TEST_CASE(TlvOpsFunctions, _isPacketTypeHopByHopFragment); +} + +LONGBOW_TEST_FIXTURE_SETUP(TlvOpsFunctions) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(TlvOpsFunctions) +{ + 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(TlvOpsFunctions, _parse_Interest) +{ + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize((_InternalSkeleton *) &skeleton, &MetisTlvSchemaV1_Ops, metisTestDataV1_Interest_AllFields, logger); + bool success = _parse(&skeleton); + assertTrue(success, "_parse(Interest) did not succeed"); + + // spot check + { + MetisTlvExtent trueExtent = { .offset = 4, .length = 1 }; + MetisTlvExtent testExtent = metisTlvSkeleton_GetHopLimit(&skeleton); + assertTrue(metisTlvExtent_Equals(&trueExtent, &testExtent), "Wrong hoplimit extent, expected {%u, %u} got {%u, %u}", + trueExtent.offset, trueExtent.length, testExtent.offset, testExtent.length); + } + + { + MetisTlvExtent trueExtent = { .offset = 12, .length = 2 }; + MetisTlvExtent testExtent = metisTlvSkeleton_GetInterestLifetime(&skeleton); + assertTrue(metisTlvExtent_Equals(&trueExtent, &testExtent), "Wrong interest lifetime extent, expected {%u, %u} got {%u, %u}", + trueExtent.offset, trueExtent.length, testExtent.offset, testExtent.length); + } + + { + MetisTlvExtent trueExtent = { .offset = 22, .length = 8 }; + MetisTlvExtent testExtent = metisTlvSkeleton_GetName(&skeleton); + assertTrue(metisTlvExtent_Equals(&trueExtent, &testExtent), "Wrong name extent, expected {%u, %u} got {%u, %u}", + trueExtent.offset, trueExtent.length, testExtent.offset, testExtent.length); + } + + { + MetisTlvExtent trueExtent = { .offset = 34, .length = 16 }; + MetisTlvExtent testExtent = metisTlvSkeleton_GetKeyId(&skeleton); + assertTrue(metisTlvExtent_Equals(&trueExtent, &testExtent), "Wrong keyid extent, expected {%u, %u} got {%u, %u}", + trueExtent.offset, trueExtent.length, testExtent.offset, testExtent.length); + } + + { + MetisTlvExtent trueExtent = { .offset = 54, .length = 32 }; + MetisTlvExtent testExtent = metisTlvSkeleton_GetObjectHash(&skeleton); + assertTrue(metisTlvExtent_Equals(&trueExtent, &testExtent), "Wrong objhash extent, expected {%u, %u} got {%u, %u}", + trueExtent.offset, trueExtent.length, testExtent.offset, testExtent.length); + } + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(TlvOpsFunctions, _parse_ContentObject) +{ + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize((_InternalSkeleton *) &skeleton, &MetisTlvSchemaV1_Ops, metisTestDataV1_ContentObject_NameA_Crc32c, logger); + bool success = _parse(&skeleton); + assertTrue(success, "_parse(ContentObject) did not succeed"); + + // spot check + { + MetisTlvExtent trueExtent = { .offset = 36, .length = 8 }; + MetisTlvExtent testExtent = metisTlvSkeleton_GetCacheTimeHeader(&skeleton); + assertTrue(metisTlvExtent_Equals(&trueExtent, &testExtent), "Wrong cache time extent, expected {%u, %u} got {%u, %u}", + trueExtent.offset, trueExtent.length, testExtent.offset, testExtent.length); + } + + { + MetisTlvExtent trueExtent = { .offset = 52, .length = 17 }; + MetisTlvExtent testExtent = metisTlvSkeleton_GetName(&skeleton); + assertTrue(metisTlvExtent_Equals(&trueExtent, &testExtent), "Wrong name extent, expected {%u, %u} got {%u, %u}", + trueExtent.offset, trueExtent.length, testExtent.offset, testExtent.length); + } + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(TlvOpsFunctions, _parse_Control) +{ + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize((_InternalSkeleton *) &skeleton, &MetisTlvSchemaV1_Ops, metisTestDataV1_CPI_AddRoute_Crc32c, logger); + bool success = _parse(&skeleton); + assertTrue(success, "_parse(Control) did not succeed"); + + // spot check + { + MetisTlvExtent trueExtent = { .offset = 12, .length = 154 }; + MetisTlvExtent testExtent = metisTlvSkeleton_GetCPI(&skeleton); + assertTrue(metisTlvExtent_Equals(&trueExtent, &testExtent), "Wrong CPI extent, expected {%u, %u} got {%u, %u}", + trueExtent.offset, trueExtent.length, testExtent.offset, testExtent.length); + } + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(TlvOpsFunctions, _parse_HopByHopFragment) +{ + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize((_InternalSkeleton *) &skeleton, &MetisTlvSchemaV1_Ops, metisTestDataV1_HopByHopFrag_BeginEnd, logger); + bool success = _parse(&skeleton); + assertTrue(success, "_parse(Control) did not succeed"); + + // spot check + { + MetisTlvExtent trueExtent = { .offset = 12, .length = sizeof(metisTestDataV1_HopByHopFrag_BeginEnd_Fragment) }; + MetisTlvExtent testExtent = metisTlvSkeleton_GetFragmentPayload(&skeleton); + assertTrue(metisTlvExtent_Equals(&trueExtent, &testExtent), "Wrong fragment payload extent, expected {%u, %u} got {%u, %u}", + trueExtent.offset, trueExtent.length, testExtent.offset, testExtent.length); + } + metisLogger_Release(&logger); +} + + +LONGBOW_TEST_CASE(TlvOpsFunctions, _parse_InterestReturn) +{ + // not implemented yet +} + +LONGBOW_TEST_CASE(TlvOpsFunctions, _parse_Unknown) +{ + uint8_t unknown[] = { 0x01, 0x77, 0x00, 8, 0x00, 0x00, 0x00, 8 }; + + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize((_InternalSkeleton *) &skeleton, &MetisTlvSchemaV1_Ops, unknown, logger); + bool success = _parse(&skeleton); + assertFalse(success, "_parse(Unknown) should have failed"); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(TlvOpsFunctions, _computeContentObjectHash) +{ + _MetisTlvFixedHeaderV1 *hdr = (_MetisTlvFixedHeaderV1 *) metisTestDataV1_ContentObject_NameA_Crc32c; + size_t endHeaders = _totalHeaderLength(metisTestDataV1_ContentObject_NameA_Crc32c); + size_t endPacket = _totalPacketLength((uint8_t *) hdr); + + uint8_t *start = &metisTestDataV1_ContentObject_NameA_Crc32c[endHeaders]; + size_t length = endPacket - endHeaders; + + PARCCryptoHasher *hasher = parcCryptoHasher_Create(PARCCryptoHashType_SHA256); + parcCryptoHasher_Init(hasher); + parcCryptoHasher_UpdateBytes(hasher, start, length); + + PARCCryptoHash *hash_truth = parcCryptoHasher_Finalize(hasher); + + PARCCryptoHash *hash_test = _computeContentObjectHash(metisTestDataV1_ContentObject_NameA_Crc32c); + + assertTrue(parcCryptoHash_Equals(hash_truth, hash_test), + "Content object digests did not match") + { + parcBuffer_Display(parcCryptoHash_GetDigest(hash_truth), 3), + parcBuffer_Display(parcCryptoHash_GetDigest(hash_test), 3); + } + + parcCryptoHash_Release(&hash_truth); + parcCryptoHash_Release(&hash_test); + parcCryptoHasher_Release(&hasher); +} + +LONGBOW_TEST_CASE(TlvOpsFunctions, _encodeControlPlaneInformation) +{ + CCNxControl *control = ccnxControl_CreateRouteListRequest(); + + PARCBuffer *buffer = _encodeControlPlaneInformation(control); + ccnxControl_Release(&control); + + assertNotNull(buffer, "Got null encoding buffer"); + uint8_t *overlay = parcBuffer_Overlay(buffer, 0); + + assertTrue(_isPacketTypeControl(overlay), "PacketType is not Control"); + parcBuffer_Release(&buffer); +} + +LONGBOW_TEST_CASE(TlvOpsFunctions, _fixedHeaderLength) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5 }; + size_t test = _fixedHeaderLength(packet); + assertTrue(test == sizeof(_MetisTlvFixedHeaderV1), "wrong fixed header lenght, expected %zu got %zu", sizeof(_MetisTlvFixedHeaderV1), test); +} + +LONGBOW_TEST_CASE(TlvOpsFunctions, _totalHeaderLength) +{ + size_t test = _totalHeaderLength(metisTestDataV1_ContentObject_NameA_Crc32c); + assertTrue(test == metisTestDataV1_ContentObject_NameA_Crc32c[7], "Wrong header length, expected %u got %zu", metisTestDataV1_ContentObject_NameA_Crc32c[7], test); +} + +LONGBOW_TEST_CASE(TlvOpsFunctions, _totalPacketLength) +{ + size_t test = _totalPacketLength(metisTestDataV1_ContentObject_NameA_Crc32c); + assertTrue(test == sizeof(metisTestDataV1_ContentObject_NameA_Crc32c), "Wrong packet length, expected %zu got %zu", sizeof(metisTestDataV1_ContentObject_NameA_Crc32c), test); +} + +LONGBOW_TEST_CASE(TlvOpsFunctions, _isPacketTypeInterest) +{ + bool match = _isPacketTypeInterest(metisTestDataV1_Interest_AllFields); + assertTrue(match, "Interest did not match"); +} + +LONGBOW_TEST_CASE(TlvOpsFunctions, _isPacketTypeContentObject) +{ + bool match = _isPacketTypeContentObject(metisTestDataV1_ContentObject_NameA_Crc32c); + assertTrue(match, "Content object did not match"); +} + +LONGBOW_TEST_CASE(TlvOpsFunctions, _isPacketTypeInterestReturn) +{ +} + +LONGBOW_TEST_CASE(TlvOpsFunctions, _isPacketTypeControl) +{ + bool match = _isPacketTypeControl(metisTestDataV1_CPI_AddRoute_Crc32c); + assertTrue(match, "Control did not match"); +} + +LONGBOW_TEST_CASE(TlvOpsFunctions, _isPacketTypeHopByHopFragment) +{ + bool match = _isPacketTypeHopByHopFragment(metisTestDataV1_HopByHopFrag_Begin); + assertTrue(match, "HopByHop Fragment did not match"); +} + + +// ====================================================== + +LONGBOW_TEST_FIXTURE(Local) +{ + LONGBOW_RUN_TEST_CASE(Local, _parsePerHopV1); + LONGBOW_RUN_TEST_CASE(Local, _parseSignatureParameters); + LONGBOW_RUN_TEST_CASE(Local, _parseSignatureParameters_NoKeyid); + LONGBOW_RUN_TEST_CASE(Local, _parseValidationType); + LONGBOW_RUN_TEST_CASE(Local, _parseValidationType_NotSignature); + LONGBOW_RUN_TEST_CASE(Local, _parseValidationAlg); + LONGBOW_RUN_TEST_CASE(Local, _parseObjectV1); + LONGBOW_RUN_TEST_CASE(Local, _parseInterestV1); + LONGBOW_RUN_TEST_CASE(Local, _parseMessage); + LONGBOW_RUN_TEST_CASE(Local, _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, _parsePerHopV1) +{ +} + +LONGBOW_TEST_CASE(Local, _parseSignatureParameters) +{ + uint8_t encoded[] = { + 0x00, T_KEYID, 0x00, 6, + 0xa0, 0xa1, 0xa2, 0xa3,0xa4,0xa5, + + 0x00, T_PUBLICKEY, 0x00, 8, + 0xb1, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, + + 0x00, T_CERT, 0x00, 8, + 0xc1, 0xc2, 0xc3, 0xc4, + 0xc5, 0xc6, 0xc7, 0xc8, + + 0x00, 0xFF, 0x00, 2, + 0xb0, 0xb1 + }; + + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize((_InternalSkeleton *) &skeleton, &MetisTlvSchemaV1_Ops, encoded, logger); + _parseSignatureParameters(encoded, 0, sizeof(encoded), &skeleton); + + MetisTlvExtent truth = { .offset = 4, .length = 6 }; + MetisTlvExtent keyid = metisTlvSkeleton_GetKeyId(&skeleton); + assertTrue(metisTlvExtent_Equals(&truth, &keyid), "Wrong extent, expected {%u, %u} got {%u, %u}", + truth.offset, truth.length, keyid.offset, keyid.length); + + // Check the public key was found. + MetisTlvExtent pubKeyTruth = { .offset = 14, .length = 8 }; + MetisTlvExtent pubKey = metisTlvSkeleton_GetPublicKey(&skeleton); + assertTrue(metisTlvExtent_Equals(&pubKeyTruth, &pubKey), "Wrong extent, expected {%u, %u} got {%u, %u}", + pubKeyTruth.offset, pubKeyTruth.length, pubKey.offset, pubKey.length); + + // Check that the cert was found. + MetisTlvExtent certTruth = { .offset = 26, .length = 8 }; + MetisTlvExtent cert = metisTlvSkeleton_GetCertificate(&skeleton); + assertTrue(metisTlvExtent_Equals(&certTruth, &cert), "Wrong extent, expected {%u, %u} got {%u, %u}", + certTruth.offset, certTruth.length, cert.offset, cert.length); + + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Local, _parseSignatureParameters_NoKeyid) +{ + uint8_t encoded[] = { + 0x00, 0xFF, 0x00, 2, + 0xb0, 0xb1 + }; + + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize((_InternalSkeleton *) &skeleton, &MetisTlvSchemaV1_Ops, encoded, logger); + _parseSignatureParameters(encoded, 0, sizeof(encoded), &skeleton); + + MetisTlvExtent keyid = metisTlvSkeleton_GetKeyId(&skeleton); + assertTrue(metisTlvExtent_Equals(&metisTlvExtent_NotFound, &keyid), "Wrong extent, expected {%u, %u} got {%u, %u}", + metisTlvExtent_NotFound.offset, metisTlvExtent_NotFound.length, keyid.offset, keyid.length); + + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Local, _parseValidationType) +{ + uint8_t encoded[] = { + 0x00, T_RSA_SHA256, 0x00, 10, + 0x00, T_KEYID, 0x00, 6, + 0xa0, 0xa1, 0xa2, 0xa3,0xa4,0xa5, + 0x00, 0xFF, 0x00, 2, + 0xb0, 0xb1 + }; + + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize((_InternalSkeleton *) &skeleton, &MetisTlvSchemaV1_Ops, encoded, logger); + _parseValidationType(encoded, 0, sizeof(encoded), &skeleton); + + MetisTlvExtent truth = { .offset = 8, .length = 6 }; + MetisTlvExtent keyid = metisTlvSkeleton_GetKeyId(&skeleton); + assertTrue(metisTlvExtent_Equals(&truth, &keyid), "Wrong extent, expected {%u, %u} got {%u, %u}", + truth.offset, truth.length, keyid.offset, keyid.length); + + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Local, _parseValidationType_NotSignature) +{ + uint8_t encoded[] = { + 0x00, 0xFF, 0x00, 10, + 0x00, T_KEYID, 0x00, 6, + 0xa0, 0xa1, 0xa2, 0xa3,0xa4,0xa5, + 0x00, 0xFF, 0x00, 2, + 0xb0, 0xb1 + }; + + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize((_InternalSkeleton *) &skeleton, &MetisTlvSchemaV1_Ops, encoded, logger); + _parseValidationType(encoded, 0, sizeof(encoded), &skeleton); + + MetisTlvExtent keyid = metisTlvSkeleton_GetKeyId(&skeleton); + assertTrue(metisTlvExtent_Equals(&metisTlvExtent_NotFound, &keyid), "Wrong extent, expected {%u, %u} got {%u, %u}", + metisTlvExtent_NotFound.offset, metisTlvExtent_NotFound.length, keyid.offset, keyid.length); + + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Local, _parseValidationAlg) +{ +} + +LONGBOW_TEST_CASE(Local, _parseObjectV1) +{ + uint8_t encoded[] = { + 0x00, 0x00, 0x00, 8, // type = name, length = 8 + 0x00, 0x02, 0x00, 4, // type = binary, length = 4 + 'c', 'o', 'o', 'l', // "cool" + + 0x00, T_EXPIRYTIME, 0x00, 2, // type = name, length = 2 + 0xa0, 0xa1 + }; + + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize((_InternalSkeleton *) &skeleton, &MetisTlvSchemaV1_Ops, encoded, logger); + _parseObjectV1(encoded, 0, sizeof(encoded), &skeleton); + + MetisTlvExtent truth = { .offset = 16, .length = 2 }; + MetisTlvExtent expiryTime = metisTlvSkeleton_GetExpiryTime(&skeleton); + assertTrue(metisTlvExtent_Equals(&truth, &expiryTime), "Wrong extent, expected {%u, %u} got {%u, %u}", + truth.offset, truth.length, expiryTime.offset, expiryTime.length); + + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Local, _parseInterestV1) +{ +} + +LONGBOW_TEST_CASE(Local, _parseMessage) +{ +} + +LONGBOW_TEST_CASE(Local, _computeHash) +{ +} + +// ====================================================== + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(metis_TlvSchemaV1); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} + + + +// ==================================== + + + diff --git a/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvSkeleton.c b/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvSkeleton.c new file mode 100644 index 00000000..243b28f3 --- /dev/null +++ b/metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvSkeleton.c @@ -0,0 +1,860 @@ +/* + * 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 "../metis_TlvSkeleton.c" +#include <stdio.h> + +#include <LongBow/unit-test.h> +#include <parc/algol/parc_SafeMemory.h> +#include <parc/logging/parc_LogReporterTextStdout.h> + +#include <ccnx/forwarder/metis/testdata/metis_TestDataV0.h> +#include <ccnx/forwarder/metis/testdata/metis_TestDataV1.h> + +LONGBOW_TEST_RUNNER(metis_TlvSkeleton) +{ + // 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(Setters); + LONGBOW_RUN_TEST_FIXTURE(Getters); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(metis_TlvSkeleton) +{ + 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(metis_TlvSkeleton) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// =================================================== + +LONGBOW_TEST_FIXTURE(SchemaV1) +{ + LONGBOW_RUN_TEST_CASE(SchemaV1, metisTlvSkeleton_ComputeContentObjectHash); + LONGBOW_RUN_TEST_CASE(SchemaV1, metisTlvSkeleton_Skeleton_Interest); + LONGBOW_RUN_TEST_CASE(SchemaV1, metisTlvSkeleton_Skeleton_Object); + LONGBOW_RUN_TEST_CASE(SchemaV1, metisTlvSkeleton_IsPacketTypeInterest); + LONGBOW_RUN_TEST_CASE(SchemaV1, metisTlvSkeleton_IsPacketTypeContentObject); + LONGBOW_RUN_TEST_CASE(SchemaV1, metisTlvSkeleton_IsPacketTypeControl); + LONGBOW_RUN_TEST_CASE(SchemaV1, metisTlvSkeleton_IsPacketTypeInterestReturn); + LONGBOW_RUN_TEST_CASE(SchemaV1, metisTlvSkeleton_TotalPacketLength); +} + +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; +} + +static void +_schemaV1_verifyInterestPerHop(MetisTlvSkeleton *opaque) +{ + _InternalSkeleton *skeleton = (_InternalSkeleton *) opaque; + assertTrue(skeleton->array[INDEX_HOPLIMIT].offset == 4, "Incorrect hopLimit offset, expected %u got %u", 4, skeleton->array[INDEX_HOPLIMIT].offset); + assertTrue(skeleton->array[INDEX_HOPLIMIT].length == 1, "Incorrect hopLimit length, expected %u got %u", 1, skeleton->array[INDEX_HOPLIMIT].length); +} + +static void +_schemaV1_verifyInterestSkeleton(MetisTlvSkeleton *opaque) +{ + _InternalSkeleton *skeleton = (_InternalSkeleton *) opaque; + assertTrue(skeleton->array[INDEX_NAME].offset == 22, "Incorrect name offset, expected %u got %u", 2, skeleton->array[INDEX_NAME].offset); + assertTrue(skeleton->array[INDEX_NAME].length == 8, "Incorrect name length, expected %u got %u", 8, skeleton->array[INDEX_NAME].length); + + assertTrue(skeleton->array[INDEX_KEYID].offset == 34, "Incorrect keyId offset, expected %u got %u", 34, skeleton->array[INDEX_KEYID].offset); + assertTrue(skeleton->array[INDEX_KEYID].length == 16, "Incorrect keyId length, expected %u got %u", 16, skeleton->array[INDEX_KEYID].length); + + assertTrue(skeleton->array[INDEX_OBJHASH].offset == 54, "Incorrect objectHash offset, expected %u got %u", 54, skeleton->array[INDEX_OBJHASH].offset); + assertTrue(skeleton->array[INDEX_OBJHASH].length == 32, "Incorrect objectHash length, expected %u got %u", 32, skeleton->array[INDEX_OBJHASH].length); + + assertTrue(skeleton->array[INDEX_INTLIFETIME].offset == 12, "Incorrect interestLifetime offset, expected %u got %u", 12, skeleton->array[INDEX_INTLIFETIME].offset); + assertTrue(skeleton->array[INDEX_INTLIFETIME].length == 2, "Incorrect interestLifetime length, expected %u got %u", 2, skeleton->array[INDEX_INTLIFETIME].length); +} + +static void +_schemaV1_verifyObjectSkeleton(MetisTlvSkeleton *opaque) +{ + _InternalSkeleton *skeleton = (_InternalSkeleton *) opaque; + assertTrue(skeleton->array[INDEX_NAME].offset == 40, "Incorrect name offset, expected %u got %u", 40, skeleton->array[INDEX_NAME].offset); + assertTrue(skeleton->array[INDEX_NAME].length == 17, "Incorrect name length, expected %u got %u", 17, skeleton->array[INDEX_NAME].length); + + assertTrue(skeleton->array[INDEX_KEYID].offset == 106, "Incorrect keyId offset, expected %u got %u", 106, skeleton->array[INDEX_KEYID].offset); + assertTrue(skeleton->array[INDEX_KEYID].length == 32, "Incorrect keyId length, expected %u got %u", 32, skeleton->array[INDEX_KEYID].length); +} + + +LONGBOW_TEST_CASE(SchemaV1, metisTlvSkeleton_ComputeContentObjectHash) +{ + size_t endHeaders = metisTlv_TotalHeaderLength(metisTestDataV1_ContentObject_NameA_KeyId1_RsaSha256); + size_t endPacket = metisTlv_TotalPacketLength(metisTestDataV1_ContentObject_NameA_KeyId1_RsaSha256); + uint8_t *start = &metisTestDataV1_ContentObject_NameA_KeyId1_RsaSha256[endHeaders]; + + + size_t length = endPacket - endHeaders; + + PARCCryptoHasher *hasher = parcCryptoHasher_Create(PARCCryptoHashType_SHA256); + parcCryptoHasher_Init(hasher); + parcCryptoHasher_UpdateBytes(hasher, start, length); + + PARCCryptoHash *hash_truth = parcCryptoHasher_Finalize(hasher); + + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisTlvSkeleton_Parse(&skeleton, metisTestDataV1_ContentObject_NameA_KeyId1_RsaSha256, logger); + metisLogger_Release(&logger); + + PARCCryptoHash *hash_test = metisTlvSkeleton_ComputeContentObjectHash(&skeleton); + + assertTrue(parcCryptoHash_Equals(hash_truth, hash_test), + "Content object digests did not match") + { + printf("Expected:\n"); + parcBuffer_Display(parcCryptoHash_GetDigest(hash_truth), 3); + printf("Got:\n"); + parcBuffer_Display(parcCryptoHash_GetDigest(hash_test), 3); + } + + parcCryptoHash_Release(&hash_truth); + parcCryptoHash_Release(&hash_test); + parcCryptoHasher_Release(&hasher); +} + +LONGBOW_TEST_CASE(SchemaV1, metisTlvSkeleton_Skeleton_Interest) +{ + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisLogger_SetLogLevel(logger, MetisLoggerFacility_Message, PARCLogLevel_Debug); + + metisTlvSkeleton_Parse(&skeleton, metisTestDataV1_Interest_AllFields, logger); + metisLogger_Release(&logger); + _schemaV1_verifyInterestPerHop(&skeleton); + _schemaV1_verifyInterestSkeleton(&skeleton); +} + +LONGBOW_TEST_CASE(SchemaV1, metisTlvSkeleton_Skeleton_Object) +{ + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisLogger_SetLogLevel(logger, MetisLoggerFacility_Message, PARCLogLevel_Debug); + + metisTlvSkeleton_Parse(&skeleton, metisTestDataV1_ContentObject_NameA_KeyId1_RsaSha256, logger); + metisLogger_Release(&logger); + _schemaV1_verifyObjectSkeleton(&skeleton); +} + +LONGBOW_TEST_CASE(SchemaV1, metisTlvSkeleton_IsPacketTypeInterest) +{ + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + + metisTlvSkeleton_Parse(&skeleton, metisTestDataV1_Interest_AllFields, logger); + metisLogger_Release(&logger); + bool match = metisTlvSkeleton_IsPacketTypeInterest(&skeleton); + assertTrue(match, "Packet should have tested true as Interest"); +} + +LONGBOW_TEST_CASE(SchemaV1, metisTlvSkeleton_IsPacketTypeContentObject) +{ + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + + metisTlvSkeleton_Parse(&skeleton, metisTestDataV1_ContentObject_NameA_KeyId1_RsaSha256, logger); + metisLogger_Release(&logger); + bool match = metisTlvSkeleton_IsPacketTypeContentObject(&skeleton); + assertTrue(match, "Packet should have tested true as Content Object"); +} + +LONGBOW_TEST_CASE(SchemaV1, metisTlvSkeleton_IsPacketTypeControl) +{ + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisTlvSkeleton_Parse(&skeleton, metisTestDataV1_CPI_AddRoute_Crc32c, logger); + metisLogger_Release(&logger); + bool match = metisTlvSkeleton_IsPacketTypeControl(&skeleton); + assertTrue(match, "Packet should have tested true as Control"); +} + +LONGBOW_TEST_CASE(SchemaV1, metisTlvSkeleton_IsPacketTypeInterestReturn) +{ + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisTlvSkeleton_Parse(&skeleton, metisTestDataV1_CPI_AddRoute_Crc32c, logger); + metisLogger_Release(&logger); + bool match = metisTlvSkeleton_IsPacketTypeInterestReturn(&skeleton); + assertFalse(match, "Packet should have tested false as Interest Return"); +} + +LONGBOW_TEST_CASE(SchemaV1, metisTlvSkeleton_TotalPacketLength) +{ + MetisTlvSkeleton skeleton; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisLogger_SetLogLevel(logger, MetisLoggerFacility_Message, PARCLogLevel_Debug); + + metisTlvSkeleton_Parse(&skeleton, metisTestDataV1_Interest_AllFields, logger); + metisLogger_Release(&logger); + size_t truth = sizeof(metisTestDataV1_Interest_AllFields); + size_t test = metisTlvSkeleton_TotalPacketLength(&skeleton); + + assertTrue(truth == test, "Wrong value, expected %zu got %zu", truth, test); +} + +// ====================================================== + +LONGBOW_TEST_FIXTURE(Setters) +{ + LONGBOW_RUN_TEST_CASE(Setters, metisTlvSkeleton_SetName); + LONGBOW_RUN_TEST_CASE(Setters, metisTlvSkeleton_SetKeyId); + LONGBOW_RUN_TEST_CASE(Setters, metisTlvSkeleton_SetObjectHash); + LONGBOW_RUN_TEST_CASE(Setters, metisTlvSkeleton_SetHopLimit); + LONGBOW_RUN_TEST_CASE(Setters, metisTlvSkeleton_SetInterestLifetime); + LONGBOW_RUN_TEST_CASE(Setters, metisTlvSkeleton_SetCacheTimeHeader); + LONGBOW_RUN_TEST_CASE(Setters, metisTlvSkeleton_SetExpiryTime); + LONGBOW_RUN_TEST_CASE(Setters, metisTlvSkeleton_SetCPI); + LONGBOW_RUN_TEST_CASE(Setters, metisTlvSkeleton_SetFragmentPayload); + LONGBOW_RUN_TEST_CASE(Setters, metisTlvSkeleton_UpdateHopLimit); + + LONGBOW_RUN_TEST_CASE(Setters, metisTlvSkeleton_SetKeyId); + LONGBOW_RUN_TEST_CASE(Setters, metisTlvSkeleton_SetCertificate); + LONGBOW_RUN_TEST_CASE(Setters, metisTlvSkeleton_SetPublicKey); +} + +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, metisTlvSkeleton_SetName) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + size_t offset = 2; + size_t length = 4; + int element = INDEX_NAME; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisLogger_SetLogLevel(logger, MetisLoggerFacility_Message, PARCLogLevel_Debug); + + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetName(&opaque, offset, length); + + assertTrue(skeleton->array[element].offset == offset, "Wrong offset for index %d, expected %zu got %u", element, offset, skeleton->array[element].offset); + assertTrue(skeleton->array[element].length == length, "Wrong length for index %d, expected %zu got %u", element, length, skeleton->array[element].length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Setters, metisTlvSkeleton_SetKeyId) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + size_t offset = 2; + size_t length = 4; + int element = INDEX_KEYID; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisLogger_SetLogLevel(logger, MetisLoggerFacility_Message, PARCLogLevel_Debug); + + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetKeyId(&opaque, offset, length); + + assertTrue(skeleton->array[element].offset == offset, "Wrong offset for index %d, expected %zu got %u", element, offset, skeleton->array[element].offset); + assertTrue(skeleton->array[element].length == length, "Wrong length for index %d, expected %zu got %u", element, length, skeleton->array[element].length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Setters, metisTlvSkeleton_SetObjectHash) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + size_t offset = 2; + size_t length = 4; + int element = INDEX_OBJHASH; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisLogger_SetLogLevel(logger, MetisLoggerFacility_Message, PARCLogLevel_Debug); + + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetObjectHash(&opaque, offset, length); + + assertTrue(skeleton->array[element].offset == offset, "Wrong offset for index %d, expected %zu got %u", element, offset, skeleton->array[element].offset); + assertTrue(skeleton->array[element].length == length, "Wrong length for index %d, expected %zu got %u", element, length, skeleton->array[element].length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Setters, metisTlvSkeleton_SetHopLimit) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + size_t offset = 2; + size_t length = 1; + int element = INDEX_HOPLIMIT; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisLogger_SetLogLevel(logger, MetisLoggerFacility_Message, PARCLogLevel_Debug); + + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetHopLimit(&opaque, offset, length); + + assertTrue(skeleton->array[element].offset == offset, "Wrong offset for index %d, expected %zu got %u", element, offset, skeleton->array[element].offset); + assertTrue(skeleton->array[element].length == length, "Wrong length for index %d, expected %zu got %u", element, length, skeleton->array[element].length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Setters, metisTlvSkeleton_SetInterestLifetime) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + size_t offset = 2; + size_t length = 4; + int element = INDEX_INTLIFETIME; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisLogger_SetLogLevel(logger, MetisLoggerFacility_Message, PARCLogLevel_Debug); + + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetInterestLifetime(&opaque, offset, length); + + assertTrue(skeleton->array[element].offset == offset, "Wrong offset for index %d, expected %zu got %u", element, offset, skeleton->array[element].offset); + assertTrue(skeleton->array[element].length == length, "Wrong length for index %d, expected %zu got %u", element, length, skeleton->array[element].length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Setters, metisTlvSkeleton_SetCacheTimeHeader) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + size_t offset = 2; + size_t length = 4; + int element = INDEX_CACHETIME; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisLogger_SetLogLevel(logger, MetisLoggerFacility_Message, PARCLogLevel_Debug); + + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetCacheTimeHeader(&opaque, offset, length); + + assertTrue(skeleton->array[element].offset == offset, "Wrong offset for index %d, expected %zu got %u", element, offset, skeleton->array[element].offset); + assertTrue(skeleton->array[element].length == length, "Wrong length for index %d, expected %zu got %u", element, length, skeleton->array[element].length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Setters, metisTlvSkeleton_SetExpiryTime) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + size_t offset = 2; + size_t length = 4; + int element = INDEX_EXPIRYTIME; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisLogger_SetLogLevel(logger, MetisLoggerFacility_Message, PARCLogLevel_Debug); + + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetExpiryTime(&opaque, offset, length); + + assertTrue(skeleton->array[element].offset == offset, "Wrong offset for index %d, expected %zu got %u", element, offset, skeleton->array[element].offset); + assertTrue(skeleton->array[element].length == length, "Wrong length for index %d, expected %zu got %u", element, length, skeleton->array[element].length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Setters, metisTlvSkeleton_SetCPI) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + size_t offset = 2; + size_t length = 4; + int element = INDEX_CPI; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisLogger_SetLogLevel(logger, MetisLoggerFacility_Message, PARCLogLevel_Debug); + + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetCPI(&opaque, offset, length); + + assertTrue(skeleton->array[element].offset == offset, "Wrong offset for index %d, expected %zu got %u", element, offset, skeleton->array[element].offset); + assertTrue(skeleton->array[element].length == length, "Wrong length for index %d, expected %zu got %u", element, length, skeleton->array[element].length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Setters, metisTlvSkeleton_SetFragmentPayload) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + size_t offset = 2; + size_t length = 4; + int element = INDEX_FRAGMENTPAYLOAD; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisLogger_SetLogLevel(logger, MetisLoggerFacility_Message, PARCLogLevel_Debug); + + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetFragmentPayload(&opaque, offset, length); + + assertTrue(skeleton->array[element].offset == offset, "Wrong offset for index %d, expected %zu got %u", element, offset, skeleton->array[element].offset); + assertTrue(skeleton->array[element].length == length, "Wrong length for index %d, expected %zu got %u", element, length, skeleton->array[element].length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Setters, metisTlvSkeleton_UpdateHopLimit) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + size_t offset = 2; + size_t length = 1; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisLogger_SetLogLevel(logger, MetisLoggerFacility_Message, PARCLogLevel_Debug); + + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetHopLimit(&opaque, offset, length); + + metisTlvSkeleton_UpdateHopLimit(&opaque, 77); + + assertTrue(packet[offset] == 77, "Wrong hop limit, expected 77 got %u", packet[offset]); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Setters, metisTlvSkeleton_SetCertificate) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + size_t offset = 6; + size_t length = 2; + int element = INDEX_CERTIFICATE; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisLogger_SetLogLevel(logger, MetisLoggerFacility_Message, PARCLogLevel_Debug); + + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetCertificate(&opaque, offset, length); + + assertTrue(skeleton->array[element].offset == offset, "Wrong offset for index %d, expected %zu got %u", + element, offset, skeleton->array[element].offset); + assertTrue(skeleton->array[element].length == length, "Wrong length for index %d, expected %zu got %u", + element, length, skeleton->array[element].length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Setters, metisTlvSkeleton_SetPublicKey) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + size_t offset = 5; + size_t length = 3; + int element = INDEX_PUBKEY; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + metisLogger_SetLogLevel(logger, MetisLoggerFacility_Message, PARCLogLevel_Debug); + + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetPublicKey(&opaque, offset, length); + + assertTrue(skeleton->array[element].offset == offset, "Wrong offset for index %d, expected %zu got %u", element, offset, skeleton->array[element].offset); + assertTrue(skeleton->array[element].length == length, "Wrong length for index %d, expected %zu got %u", element, length, skeleton->array[element].length); + metisLogger_Release(&logger); +} + +// ====================================================== + +LONGBOW_TEST_FIXTURE(Getters) +{ + LONGBOW_RUN_TEST_CASE(Getters, metisTlvSkeleton_GetName); + LONGBOW_RUN_TEST_CASE(Getters, metisTlvSkeleton_GetKeyId); + LONGBOW_RUN_TEST_CASE(Getters, metisTlvSkeleton_GetObjectHash); + LONGBOW_RUN_TEST_CASE(Getters, metisTlvSkeleton_GetHopLimit); + LONGBOW_RUN_TEST_CASE(Getters, metisTlvSkeleton_GetInterestLifetime); + LONGBOW_RUN_TEST_CASE(Getters, metisTlvSkeleton_GetCacheTimeHeader); + LONGBOW_RUN_TEST_CASE(Getters, metisTlvSkeleton_GetExpiryTime); + LONGBOW_RUN_TEST_CASE(Getters, metisTlvSkeleton_GetCPI); + LONGBOW_RUN_TEST_CASE(Getters, metisTlvSkeleton_GetFragmentPayload); + LONGBOW_RUN_TEST_CASE(Getters, metisTlvSkeleton_GetPacket); + LONGBOW_RUN_TEST_CASE(Getters, metisTlvSkeleton_GetLogger); + + LONGBOW_RUN_TEST_CASE(Getters, metisTlvSkeleton_GetPublicKey); + LONGBOW_RUN_TEST_CASE(Getters, metisTlvSkeleton_GetCertificate); +} + +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(Getters, metisTlvSkeleton_GetName) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + MetisTlvExtent extent = { .offset = 3, .length = 2 }; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetName(&opaque, extent.offset, extent.length); + + MetisTlvExtent test = metisTlvSkeleton_GetName(&opaque); + + assertTrue(metisTlvExtent_Equals(&extent, &test), "Wrong extent, expected {%u, %u}, got {%u, %u}", + extent.offset, extent.length, test.offset, test.length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Getters, metisTlvSkeleton_GetKeyId) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + MetisTlvExtent extent = { .offset = 3, .length = 2 }; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetKeyId(&opaque, extent.offset, extent.length); + + MetisTlvExtent test = metisTlvSkeleton_GetKeyId(&opaque); + + assertTrue(metisTlvExtent_Equals(&extent, &test), "Wrong extent, expected {%u, %u}, got {%u, %u}", + extent.offset, extent.length, test.offset, test.length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Getters, metisTlvSkeleton_GetObjectHash) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + MetisTlvExtent extent = { .offset = 3, .length = 2 }; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetObjectHash(&opaque, extent.offset, extent.length); + + MetisTlvExtent test = metisTlvSkeleton_GetObjectHash(&opaque); + + assertTrue(metisTlvExtent_Equals(&extent, &test), "Wrong extent, expected {%u, %u}, got {%u, %u}", + extent.offset, extent.length, test.offset, test.length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Getters, metisTlvSkeleton_GetHopLimit) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + MetisTlvExtent extent = { .offset = 3, .length = 1 }; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetHopLimit(&opaque, extent.offset, extent.length); + + MetisTlvExtent test = metisTlvSkeleton_GetHopLimit(&opaque); + + assertTrue(metisTlvExtent_Equals(&extent, &test), "Wrong extent, expected {%u, %u}, got {%u, %u}", + extent.offset, extent.length, test.offset, test.length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Getters, metisTlvSkeleton_GetInterestLifetime) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + MetisTlvExtent extent = { .offset = 3, .length = 2 }; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetInterestLifetime(&opaque, extent.offset, extent.length); + + MetisTlvExtent test = metisTlvSkeleton_GetInterestLifetime(&opaque); + + assertTrue(metisTlvExtent_Equals(&extent, &test), "Wrong extent, expected {%u, %u}, got {%u, %u}", + extent.offset, extent.length, test.offset, test.length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Getters, metisTlvSkeleton_GetCacheTimeHeader) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + MetisTlvExtent extent = { .offset = 3, .length = 2 }; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetCacheTimeHeader(&opaque, extent.offset, extent.length); + + MetisTlvExtent test = metisTlvSkeleton_GetCacheTimeHeader(&opaque); + + assertTrue(metisTlvExtent_Equals(&extent, &test), "Wrong extent, expected {%u, %u}, got {%u, %u}", + extent.offset, extent.length, test.offset, test.length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Getters, metisTlvSkeleton_GetExpiryTime) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + MetisTlvExtent extent = { .offset = 3, .length = 2 }; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetExpiryTime(&opaque, extent.offset, extent.length); + + MetisTlvExtent test = metisTlvSkeleton_GetExpiryTime(&opaque); + + assertTrue(metisTlvExtent_Equals(&extent, &test), "Wrong extent, expected {%u, %u}, got {%u, %u}", + extent.offset, extent.length, test.offset, test.length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Getters, metisTlvSkeleton_GetCPI) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + MetisTlvExtent extent = { .offset = 3, .length = 2 }; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetCPI(&opaque, extent.offset, extent.length); + + MetisTlvExtent test = metisTlvSkeleton_GetCPI(&opaque); + + assertTrue(metisTlvExtent_Equals(&extent, &test), "Wrong extent, expected {%u, %u}, got {%u, %u}", + extent.offset, extent.length, test.offset, test.length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Getters, metisTlvSkeleton_GetFragmentPayload) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + MetisTlvExtent extent = { .offset = 3, .length = 2 }; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + metisTlvSkeleton_SetFragmentPayload(&opaque, extent.offset, extent.length); + + MetisTlvExtent test = metisTlvSkeleton_GetFragmentPayload(&opaque); + + assertTrue(metisTlvExtent_Equals(&extent, &test), "Wrong extent, expected {%u, %u}, got {%u, %u}", + extent.offset, extent.length, test.offset, test.length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Getters, metisTlvSkeleton_GetPacket) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + + const uint8_t *test = metisTlvSkeleton_GetPacket(&opaque); + + assertTrue(packet == test, "Wrong packet pointer, expected %p, got %p", + (void *) packet, (void *) test); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Getters, metisTlvSkeleton_GetLogger) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + + MetisLogger *test = metisTlvSkeleton_GetLogger(&opaque); + assertNotNull(test, "Got null logger from skeleton"); + + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Getters, metisTlvSkeleton_GetPublicKey) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + MetisTlvExtent extent = { .offset = 5, .length = 2 }; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + + metisTlvSkeleton_SetPublicKey(&opaque, extent.offset, extent.length); + + MetisTlvExtent test = metisTlvSkeleton_GetPublicKey(&opaque); + + assertTrue(metisTlvExtent_Equals(&extent, &test), "Wrong extent, expected {%u, %u}, got {%u, %u}", + extent.offset, extent.length, test.offset, test.length); + metisLogger_Release(&logger); +} + +LONGBOW_TEST_CASE(Getters, metisTlvSkeleton_GetCertificate) +{ + uint8_t packet[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + MetisTlvExtent extent = { .offset = 5, .length = 2 }; + + MetisTlvSkeleton opaque; + _InternalSkeleton *skeleton = (_InternalSkeleton *) &opaque; + PARCLogReporter *reporter = parcLogReporterTextStdout_Create(); + MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock()); + parcLogReporter_Release(&reporter); + _initialize(skeleton, &MetisTlvSchemaV1_Ops, packet, logger); + + metisTlvSkeleton_SetCertificate(&opaque, extent.offset, extent.length); + + MetisTlvExtent test = metisTlvSkeleton_GetCertificate(&opaque); + + assertTrue(metisTlvExtent_Equals(&extent, &test), "Wrong extent, expected {%u, %u}, got {%u, %u}", + extent.offset, extent.length, test.offset, test.length); + metisLogger_Release(&logger); +} + + + +// ====================================================== + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(metis_TlvSkeleton); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} + + + +// ==================================== + + |