aboutsummaryrefslogtreecommitdiffstats
path: root/metis/ccnx/forwarder/metis/tlv/test
diff options
context:
space:
mode:
Diffstat (limited to 'metis/ccnx/forwarder/metis/tlv/test')
-rw-r--r--metis/ccnx/forwarder/metis/tlv/test/.gitignore8
-rw-r--r--metis/ccnx/forwarder/metis/tlv/test/CMakeLists.txt19
-rw-r--r--metis/ccnx/forwarder/metis/tlv/test/test_metis_Tlv.c249
-rw-r--r--metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvExtent.c90
-rw-r--r--metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvName.c470
-rw-r--r--metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvNameCodec.c172
-rw-r--r--metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvSchemaV0.c342
-rw-r--r--metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvSchemaV1.c518
-rw-r--r--metis/ccnx/forwarder/metis/tlv/test/test_metis_TlvSkeleton.c860
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(&copy);
+ 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(&copy);
+ 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(&copy);
+ 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(&copy);
+ 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(&copy);
+ 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);
+}
+
+
+
+// ====================================
+
+