diff options
Diffstat (limited to 'libccnx-common/ccnx/common/codec/schema_v1/test/test_ccnxCodecSchemaV1_PacketEncoder.c')
-rwxr-xr-x | libccnx-common/ccnx/common/codec/schema_v1/test/test_ccnxCodecSchemaV1_PacketEncoder.c | 1054 |
1 files changed, 1054 insertions, 0 deletions
diff --git a/libccnx-common/ccnx/common/codec/schema_v1/test/test_ccnxCodecSchemaV1_PacketEncoder.c b/libccnx-common/ccnx/common/codec/schema_v1/test/test_ccnxCodecSchemaV1_PacketEncoder.c new file mode 100755 index 00000000..eb79502e --- /dev/null +++ b/libccnx-common/ccnx/common/codec/schema_v1/test/test_ccnxCodecSchemaV1_PacketEncoder.c @@ -0,0 +1,1054 @@ +/* + * 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 "../ccnxCodecSchemaV1_PacketEncoder.c" +#include <parc/algol/parc_SafeMemory.h> +#include <LongBow/unit-test.h> +#include <ccnx/common/codec/schema_v1/testdata/v1_content_nameA_keyid1_rsasha256.h> +#include <ccnx/common/codec/schema_v1/testdata/v1_interest_all_fields.h> +#include <ccnx/common/codec/schema_v1/testdata/v1_interest_nameA_crc32c.h> + +#include "testrig_encoder.c" + +#include <ccnx/common/ccnx_Interest.h> +#include <ccnx/common/ccnx_InterestReturn.h> +#include <ccnx/common/ccnx_ContentObject.h> + +#include <ccnx/common/validation/ccnxValidation_CRC32C.h> + + +// ========================================================================= + +LONGBOW_TEST_RUNNER(ccnxCodecSchemaV1_PacketEncoder) +{ + LONGBOW_RUN_TEST_FIXTURE(ContentObject); + LONGBOW_RUN_TEST_FIXTURE(Interest); + LONGBOW_RUN_TEST_FIXTURE(InterestReturn); + LONGBOW_RUN_TEST_FIXTURE(Control); + LONGBOW_RUN_TEST_FIXTURE(UnknownType); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(ccnxCodecSchemaV1_PacketEncoder) +{ + 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(ccnxCodecSchemaV1_PacketEncoder) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + + +// ========================================================================= + +LONGBOW_TEST_FIXTURE(ContentObject) +{ + LONGBOW_RUN_TEST_CASE(ContentObject, v1_content_nameA_keyid1_rsasha256); + LONGBOW_RUN_TEST_CASE(ContentObject, zero_length_payload); + LONGBOW_RUN_TEST_CASE(ContentObject, null_payload); + LONGBOW_RUN_TEST_CASE(ContentObject, no_cryptosuite); +} + +LONGBOW_TEST_FIXTURE_SETUP(ContentObject) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(ContentObject) +{ + 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; +} + +/* + * Make a dictionary equivalent to v1_content_nameA_keyid1_rsasha256 and encode it then compare + */ +LONGBOW_TEST_CASE(ContentObject, v1_content_nameA_keyid1_rsasha256) +{ + CCNxName *name = ccnxName_CreateFromCString(v1_content_nameA_keyid1_rsasha256_URI); + + TlvExtent payloadExtent = + getTruthTableExtent(TRUTHTABLENAME(v1_content_nameA_keyid1_rsasha256), V1_MANIFEST_OBJ_PAYLOAD); + PARCBuffer *payload = parcBuffer_Wrap(v1_content_nameA_keyid1_rsasha256, + sizeof(v1_content_nameA_keyid1_rsasha256), + payloadExtent.offset, + payloadExtent.offset + payloadExtent.length); + + CCNxTlvDictionary *message = + ccnxContentObject_CreateWithImplAndPayload(&CCNxContentObjectFacadeV1_Implementation, + name, CCNxPayloadType_KEY, payload); + + TlvExtent fragmentExtent = + getTruthTableHeaderExtent(TRUTHTABLENAME(v1_content_nameA_keyid1_rsasha256), V1_MANIFEST_OBJ_E2EFRAG); + PARCBuffer *fragment = parcBuffer_Wrap(v1_content_nameA_keyid1_rsasha256, + sizeof(v1_content_nameA_keyid1_rsasha256), + fragmentExtent.offset, + fragmentExtent.offset + fragmentExtent.length); + ccnxTlvDictionary_PutBuffer(message, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_OBJFRAG, fragment); + + uint64_t expiryTime = 1388534400000ULL; + ccnxContentObject_SetExpiryTime(message, expiryTime); + + uint64_t endChunkNumber = 0x06050403; + ccnxContentObject_SetFinalChunkNumber(message, endChunkNumber); + + TlvExtent keyIdExtent = getTruthTableExtent(TRUTHTABLENAME(v1_content_nameA_keyid1_rsasha256), V1_MANIFEST_OBJ_KEYID); + PARCBuffer *keyid = parcBuffer_Wrap(v1_content_nameA_keyid1_rsasha256, + sizeof(v1_content_nameA_keyid1_rsasha256), + keyIdExtent.offset, + keyIdExtent.offset + keyIdExtent.length); + + TlvExtent keyExtent = getTruthTableExtent(TRUTHTABLENAME(v1_content_nameA_keyid1_rsasha256), V1_MANIFEST_OBJ_PUBKEY); + PARCBuffer *key = parcBuffer_Wrap(v1_content_nameA_keyid1_rsasha256, + sizeof(v1_content_nameA_keyid1_rsasha256), + keyExtent.offset, + keyExtent.offset + keyExtent.length); + + ccnxValidationFacadeV1_SetCryptoSuite(message, PARCCryptoSuite_RSA_SHA256); + ccnxValidationFacadeV1_SetKeyId(message, keyid); + ccnxValidationFacadeV1_SetPublicKey(message, key); + + TlvExtent sigExtent = + getTruthTableExtent(TRUTHTABLENAME(v1_content_nameA_keyid1_rsasha256), V1_MANIFEST_OBJ_SIGBITS); + PARCBuffer *sig = parcBuffer_Wrap(v1_content_nameA_keyid1_rsasha256, + sizeof(v1_content_nameA_keyid1_rsasha256), + sigExtent.offset, + sigExtent.offset + sigExtent.length); + + ccnxValidationFacadeV1_SetPayload(message, sig); + + // encode + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + ssize_t length = ccnxCodecSchemaV1PacketEncoder_Encode(encoder, message); + assertFalse(length < 0, "Got encoding error: %s", + ccnxCodecError_ToString(ccnxCodecTlvEncoder_GetError(encoder))); + assertTrue(length == sizeof(v1_content_nameA_keyid1_rsasha256), + "Wrong length, expected %zu got %zd", sizeof(v1_content_nameA_keyid1_rsasha256), length); + + // verify + PARCBuffer *truth = parcBuffer_Wrap(v1_content_nameA_keyid1_rsasha256, + sizeof(v1_content_nameA_keyid1_rsasha256), + 0, + sizeof(v1_content_nameA_keyid1_rsasha256)); + ccnxCodecTlvEncoder_Finalize(encoder); + PARCBuffer *test = ccnxCodecTlvEncoder_CreateBuffer(encoder); + assertTrue(parcBuffer_Equals(test, truth), "Buffers mismatch") + { + printf("Expected\n"); + parcBuffer_Display(truth, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + + uint8_t *truthOverlay = parcBuffer_Overlay(truth, 0); + uint8_t *testOverlay = parcBuffer_Overlay(test, 0); + + for (ssize_t i = 0; i < length; i++) { + if (truthOverlay[i] != testOverlay[i]) { + printf("Buffers differ at byte %zd, expected 0x%02x got 0x%02x\n", i, truthOverlay[i], testOverlay[i]); + break; + } + } + } + + // cleanup + parcBuffer_Release(&truth); + parcBuffer_Release(&test); + ccnxCodecTlvEncoder_Destroy(&encoder); + parcBuffer_Release(&sig); + parcBuffer_Release(&key); + parcBuffer_Release(&keyid); + parcBuffer_Release(&payload); + parcBuffer_Release(&fragment); + ccnxName_Release(&name); + ccnxTlvDictionary_Release(&message); +} + + +LONGBOW_TEST_CASE(ContentObject, zero_length_payload) +{ + CCNxName *name = ccnxName_CreateFromCString("lci:/no/payload"); + PARCBuffer *payload = parcBuffer_Allocate(0); + + CCNxTlvDictionary *message = + ccnxContentObject_CreateWithImplAndPayload(&CCNxContentObjectFacadeV1_Implementation, + name, CCNxPayloadType_DATA, payload); + + // encode + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + ssize_t length = ccnxCodecSchemaV1PacketEncoder_Encode(encoder, message); + assertFalse(length < 0, "Got encoding error: %s", ccnxCodecError_ToString(ccnxCodecTlvEncoder_GetError(encoder))); + + ccnxCodecTlvEncoder_Finalize(encoder); + PARCBuffer *encoded = ccnxCodecTlvEncoder_CreateBuffer(encoder); + assertNotNull(encoded, "got null output buffer"); + + parcBuffer_Display(encoded, 3); + + parcBuffer_Release(&encoded); + ccnxCodecTlvEncoder_Destroy(&encoder); + ccnxTlvDictionary_Release(&message); + parcBuffer_Release(&payload); + ccnxName_Release(&name); +} + +LONGBOW_TEST_CASE(ContentObject, null_payload) +{ + CCNxName *name = ccnxName_CreateFromCString("lci:/no/payload"); + + CCNxTlvDictionary *message = + ccnxContentObject_CreateWithImplAndPayload(&CCNxContentObjectFacadeV1_Implementation, + name, CCNxPayloadType_DATA, NULL); + // encode + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + ssize_t length = ccnxCodecSchemaV1PacketEncoder_Encode(encoder, message); + assertFalse(length < 0, "Got encoding error: %s", ccnxCodecError_ToString(ccnxCodecTlvEncoder_GetError(encoder))); + + ccnxCodecTlvEncoder_Finalize(encoder); + PARCBuffer *encoded = ccnxCodecTlvEncoder_CreateBuffer(encoder); + assertNotNull(encoded, "got null output buffer"); + + parcBuffer_Release(&encoded); + ccnxCodecTlvEncoder_Destroy(&encoder); + ccnxTlvDictionary_Release(&message); + ccnxName_Release(&name); +} + +/* + * A content object without a cryptosuite should not be signed + */ +LONGBOW_TEST_CASE(ContentObject, no_cryptosuite) +{ + CCNxName *name = ccnxName_CreateFromCString("lci:/no/payload"); + + CCNxTlvDictionary *message = + ccnxContentObject_CreateWithImplAndPayload(&CCNxContentObjectFacadeV1_Implementation, + name, CCNxPayloadType_DATA, NULL); + // encode + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + ssize_t length = ccnxCodecSchemaV1PacketEncoder_Encode(encoder, message); + assertFalse(length < 0, "Got encoding error: %s", ccnxCodecError_ToString(ccnxCodecTlvEncoder_GetError(encoder))); + + ccnxCodecTlvEncoder_Finalize(encoder); + PARCBuffer *encoded = ccnxCodecTlvEncoder_CreateBuffer(encoder); + assertNotNull(encoded, "got null output buffer"); + + // it should be 33 bytes without a signature + assertTrue(parcBuffer_Remaining(encoded) == 33, "Wrong length exepcted 33 got %zu", parcBuffer_Remaining(encoded)); + + parcBuffer_Release(&encoded); + ccnxCodecTlvEncoder_Destroy(&encoder); + ccnxTlvDictionary_Release(&message); + ccnxName_Release(&name); +} + +// ========================================================================= + +LONGBOW_TEST_FIXTURE(Interest) +{ + LONGBOW_RUN_TEST_CASE(Interest, v1_interest_nameA_crc32c); + LONGBOW_RUN_TEST_CASE(Interest, v1_interest_nameA_crc32c_IoVec); +} + +LONGBOW_TEST_FIXTURE_SETUP(Interest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Interest) +{ + 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; +} + +/* + * Make an interest equivalent to v1_interest_nameA_crc32c and encode it + */ +LONGBOW_TEST_CASE(Interest, v1_interest_nameA_crc32c) +{ + CCNxName *name = ccnxName_CreateFromCString(v1_interest_nameA_crc32c_URI); + + CCNxTlvDictionary *message = + ccnxInterest_CreateWithImpl(&CCNxInterestFacadeV1_Implementation, + name, CCNxInterestDefault_LifetimeMilliseconds, NULL, NULL, 32); + + TlvExtent fragmentExtent = getTruthTableHeaderExtent(TRUTHTABLENAME(v1_interest_nameA_crc32c), V1_MANIFEST_INT_E2EFRAG); + PARCBuffer *fragment = parcBuffer_Wrap(v1_interest_nameA_crc32c, sizeof(v1_interest_nameA_crc32c), fragmentExtent.offset, fragmentExtent.offset + fragmentExtent.length); + ccnxTlvDictionary_PutBuffer(message, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_INTFRAG, fragment); + + ccnxValidationFacadeV1_SetCryptoSuite(message, PARCCryptoSuite_NULL_CRC32C); + + TlvExtent sigExtent = getTruthTableExtent(TRUTHTABLENAME(v1_interest_nameA_crc32c), V1_MANIFEST_INT_ValidationPayload); + PARCBuffer *sig = parcBuffer_Wrap(v1_interest_nameA_crc32c, sizeof(v1_interest_nameA_crc32c), sigExtent.offset, sigExtent.offset + sigExtent.length); + + ccnxValidationFacadeV1_SetPayload(message, sig); + + // encode + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + ssize_t length = ccnxCodecSchemaV1PacketEncoder_Encode(encoder, message); + assertFalse(length < 0, "Got encoding error: %s", ccnxCodecError_ToString(ccnxCodecTlvEncoder_GetError(encoder))); + assertTrue(length == sizeof(v1_interest_nameA_crc32c), "Wrong length, expected %zu got %zd", sizeof(v1_interest_nameA_crc32c), length); + + // verify + PARCBuffer *truth = parcBuffer_Wrap(v1_interest_nameA_crc32c, sizeof(v1_interest_nameA_crc32c), 0, sizeof(v1_interest_nameA_crc32c)); + ccnxCodecTlvEncoder_Finalize(encoder); + PARCBuffer *test = ccnxCodecTlvEncoder_CreateBuffer(encoder); + assertTrue(parcBuffer_Equals(test, truth), "Buffers mismatch") + { + printf("Expected\n"); + parcBuffer_Display(truth, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + + uint8_t *truthOverlay = parcBuffer_Overlay(truth, 0); + uint8_t *testOverlay = parcBuffer_Overlay(test, 0); + + for (ssize_t i = 0; i < length; i++) { + if (truthOverlay[i] != testOverlay[i]) { + printf("Buffers differ at byte %zd, expected 0x%02x got 0x%02x", i, truthOverlay[i], testOverlay[i]); + break; + } + } + } + + // cleanup + parcBuffer_Release(&truth); + parcBuffer_Release(&test); + ccnxCodecTlvEncoder_Destroy(&encoder); + parcBuffer_Release(&sig); + parcBuffer_Release(&fragment); + ccnxName_Release(&name); + ccnxTlvDictionary_Release(&message); +} + +/* + * Make an interest equivalent to v1_interest_nameA_crc32c and encode it + */ +LONGBOW_TEST_CASE(Interest, v1_interest_nameA_crc32c_IoVec) +{ + CCNxName *name = ccnxName_CreateFromCString(v1_interest_nameA_crc32c_URI); + + CCNxTlvDictionary *message = + ccnxInterest_CreateWithImpl(&CCNxInterestFacadeV1_Implementation, + name, CCNxInterestDefault_LifetimeMilliseconds, NULL, NULL, 32); + + TlvExtent fragmentExtent = getTruthTableHeaderExtent(TRUTHTABLENAME(v1_interest_nameA_crc32c), V1_MANIFEST_INT_E2EFRAG); + PARCBuffer *fragment = parcBuffer_Wrap(v1_interest_nameA_crc32c, sizeof(v1_interest_nameA_crc32c), fragmentExtent.offset, fragmentExtent.offset + fragmentExtent.length); + ccnxTlvDictionary_PutBuffer(message, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_INTFRAG, fragment); + + ccnxValidationFacadeV1_SetCryptoSuite(message, PARCCryptoSuite_NULL_CRC32C); + + TlvExtent sigExtent = getTruthTableExtent(TRUTHTABLENAME(v1_interest_nameA_crc32c), V1_MANIFEST_INT_ValidationPayload); + PARCBuffer *sig = parcBuffer_Wrap(v1_interest_nameA_crc32c, sizeof(v1_interest_nameA_crc32c), sigExtent.offset, sigExtent.offset + sigExtent.length); + + ccnxValidationFacadeV1_SetPayload(message, sig); + + // encode + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + CCNxCodecNetworkBufferIoVec *iovec = ccnxCodecSchemaV1PacketEncoder_DictionaryEncode(message, NULL); + assertNotNull(iovec, "Got null iovec from ccnxCodecSchemaV1PacketEncoder_DictionaryEncode"); + + size_t length = ccnxCodecNetworkBufferIoVec_Length(iovec); + assertTrue(length == sizeof(v1_interest_nameA_crc32c), "Wrong length, expected %zu got %zd", sizeof(v1_interest_nameA_crc32c), length); + + // verify + PARCBuffer *truth = parcBuffer_Wrap(v1_interest_nameA_crc32c, sizeof(v1_interest_nameA_crc32c), 0, sizeof(v1_interest_nameA_crc32c)); + + int iovecCount = ccnxCodecNetworkBufferIoVec_GetCount(iovec); + PARCBuffer *test = parcBuffer_Allocate(length); + const struct iovec *array = ccnxCodecNetworkBufferIoVec_GetArray(iovec); + for (int i = 0; i < iovecCount; i++) { + parcBuffer_PutArray(test, array[i].iov_len, array[i].iov_base); + } + parcBuffer_Flip(test); + + assertTrue(parcBuffer_Equals(test, truth), "Buffers mismatch") + { + printf("Expected\n"); + parcBuffer_Display(truth, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + + uint8_t *truthOverlay = parcBuffer_Overlay(truth, 0); + uint8_t *testOverlay = parcBuffer_Overlay(test, 0); + + for (ssize_t i = 0; i < length; i++) { + if (truthOverlay[i] != testOverlay[i]) { + printf("Buffers differ at byte %zd, expected 0x%02x got 0x%02x", i, truthOverlay[i], testOverlay[i]); + break; + } + } + } + + // cleanup + ccnxCodecNetworkBufferIoVec_Release(&iovec); + parcBuffer_Release(&truth); + parcBuffer_Release(&test); + ccnxCodecTlvEncoder_Destroy(&encoder); + parcBuffer_Release(&sig); + parcBuffer_Release(&fragment); + ccnxName_Release(&name); + ccnxTlvDictionary_Release(&message); +} + +// ========================================================================= + +LONGBOW_TEST_FIXTURE(InterestReturn) +{ + LONGBOW_RUN_TEST_CASE(InterestReturn, v1_interest_return); +} + +LONGBOW_TEST_FIXTURE_SETUP(InterestReturn) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(InterestReturn) +{ + 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; +} + +/* + * Make an interest return and encode it + */ +LONGBOW_TEST_CASE(InterestReturn, v1_interest_return) +{ + CCNxName *name = ccnxName_CreateFromCString(v1_interest_nameA_crc32c_URI); + + CCNxInterest *interest = + ccnxInterest_CreateWithImpl(&CCNxInterestFacadeV1_Implementation, + name, CCNxInterestDefault_LifetimeMilliseconds, NULL, NULL, 32); + ccnxName_Release(&name); + + TlvExtent fragmentExtent = getTruthTableHeaderExtent(TRUTHTABLENAME(v1_interest_nameA_crc32c), V1_MANIFEST_INT_E2EFRAG); + PARCBuffer *fragment = parcBuffer_Wrap(v1_interest_nameA_crc32c, sizeof(v1_interest_nameA_crc32c), fragmentExtent.offset, fragmentExtent.offset + fragmentExtent.length); + ccnxTlvDictionary_PutBuffer(interest, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_INTFRAG, fragment); + parcBuffer_Release(&fragment); + + ccnxValidationFacadeV1_SetCryptoSuite(interest, PARCCryptoSuite_NULL_CRC32C); + + TlvExtent sigExtent = getTruthTableExtent(TRUTHTABLENAME(v1_interest_nameA_crc32c), V1_MANIFEST_INT_ValidationPayload); + PARCBuffer *sig = parcBuffer_Wrap(v1_interest_nameA_crc32c, sizeof(v1_interest_nameA_crc32c), sigExtent.offset, sigExtent.offset + sigExtent.length); + + ccnxValidationFacadeV1_SetPayload(interest, sig); + parcBuffer_Release(&sig); + + CCNxTlvDictionary *message = + ccnxInterestReturn_Create(interest, CCNxInterestReturn_ReturnCode_NoResources); + ccnxInterest_Release(&interest); + + // encode + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + ssize_t length = ccnxCodecSchemaV1PacketEncoder_Encode(encoder, message); + ssize_t expectedLength = sizeof(v1_interest_nameA_crc32c); + assertFalse(length < 0, "Got encoding error: %s", ccnxCodecError_ToString(ccnxCodecTlvEncoder_GetError(encoder))); + assertTrue(length == expectedLength, "Wrong length, expected %zu got %zd", expectedLength, length); + + // verify + PARCBuffer *truth = parcBuffer_Wrap(v1_interest_nameA_crc32c_returned, sizeof(v1_interest_nameA_crc32c_returned), 0, sizeof(v1_interest_nameA_crc32c_returned)); + ccnxCodecTlvEncoder_Finalize(encoder); + PARCBuffer *test = ccnxCodecTlvEncoder_CreateBuffer(encoder); + assertTrue(parcBuffer_Equals(test, truth), "Buffers mismatch") + { + printf("Expected\n"); + parcBuffer_Display(truth, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + + uint8_t *truthOverlay = parcBuffer_Overlay(truth, 0); + uint8_t *testOverlay = parcBuffer_Overlay(test, 0); + + for (ssize_t i = 0; i < length; i++) { + if (truthOverlay[i] != testOverlay[i]) { + printf("Buffers differ at byte %zd, expected 0x%02x got 0x%02x\n", i, truthOverlay[i], testOverlay[i]); + } + } + } + + // cleanup + parcBuffer_Release(&truth); + parcBuffer_Release(&test); + ccnxCodecTlvEncoder_Destroy(&encoder); + ccnxTlvDictionary_Release(&message); +} + +// ========================================================================= + +LONGBOW_TEST_FIXTURE(Control) +{ + LONGBOW_RUN_TEST_CASE(Control, payload); + LONGBOW_RUN_TEST_CASE(Control, cryptosuite); +} + +LONGBOW_TEST_FIXTURE_SETUP(Control) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Control) +{ + 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(Control, payload) +{ + uint8_t encoded[] = { + 0x01, 0xa4, 0x00, 0x22, + 0x00, 0x00, 0x00, 0x08, + + 0xbe, 0xef, 0x00, 0x16, // control message + + 0x7b, 0x22, 0x74, 0x68, // {"th + 0x69, 0x73, 0x20, 0x69, // is i + 0x73, 0x22, 0x3a, 0x22, // s":" + 0x61, 0x6e, 0x6e, 0x6f, // anno + 0x79, 0x69, 0x6e, 0x67, // ying + 0x22, 0x7d // "} + }; + + + CCNxTlvDictionary *message = ccnxCodecSchemaV1TlvDictionary_CreateControl(); + + PARCJSON *json = parcJSON_Create(); + parcJSON_AddString(json, "this is", "annoying"); + + ccnxTlvDictionary_PutJson(message, CCNxCodecSchemaV1TlvDictionary_MessageFastArray_PAYLOAD, json); + parcJSON_Release(&json); + + // encode + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + ssize_t length = ccnxCodecSchemaV1PacketEncoder_Encode(encoder, message); + + assertFalse(length < 0, "Got encoding error: %s", ccnxCodecError_ToString(ccnxCodecTlvEncoder_GetError(encoder))); + assertTrue(length == sizeof(encoded), "Wrong length, expected %zu got %zd", sizeof(encoded), length); + + // verify + ccnxCodecTlvEncoder_Finalize(encoder); + PARCBuffer *test = ccnxCodecTlvEncoder_CreateBuffer(encoder); + PARCBuffer *truth = parcBuffer_Wrap(encoded, sizeof(encoded), 0, sizeof(encoded)); + + assertTrue(parcBuffer_Equals(test, truth), "Buffers mismatch") + { + printf("Expected\n"); + parcBuffer_Display(truth, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + + uint8_t *truthOverlay = parcBuffer_Overlay(truth, 0); + uint8_t *testOverlay = parcBuffer_Overlay(test, 0); + + for (ssize_t i = 0; i < length; i++) { + if (truthOverlay[i] != testOverlay[i]) { + printf("Buffers differ at byte %zd, expected 0x%02x got 0x%02x", i, truthOverlay[i], testOverlay[i]); + break; + } + } + } + + parcBuffer_Release(&test); + ccnxCodecTlvEncoder_Destroy(&encoder); + ccnxTlvDictionary_Release(&message); + parcBuffer_Release(&truth); +} + +LONGBOW_TEST_CASE(Control, cryptosuite) +{ + uint8_t encoded[] = { + 0x01, 0xA4, 0x00, 16, + 0x00, 0x00, 0x00, 8, + 0xBE, 0xEF, 0x00, 4, + 'a', 'b', 'c', 'd', + 0x00, 0x03, 0x00, 4, + 0x00, 0x02, 0x00, 0 + }; + + PARCBuffer *truth = parcBuffer_Wrap(encoded, sizeof(encoded), 0, sizeof(encoded)); + PARCBuffer *payload = parcBuffer_Wrap(encoded, sizeof(encoded), 12, 16); + + CCNxTlvDictionary *message = ccnxCodecSchemaV1TlvDictionary_CreateControl(); + ccnxTlvDictionary_PutBuffer(message, CCNxCodecSchemaV1TlvDictionary_MessageFastArray_PAYLOAD, payload); + ccnxValidationCRC32C_Set(message); + + ccnxValidationCRC32C_Set(message); + + // encode + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + PARCSigner *signer = ccnxValidationCRC32C_CreateSigner(); + ccnxCodecTlvEncoder_SetSigner(encoder, signer); + + ssize_t length = ccnxCodecSchemaV1PacketEncoder_Encode(encoder, message); + assertFalse(length < 0, "Got encoding error: %s", ccnxCodecError_ToString(ccnxCodecTlvEncoder_GetError(encoder))); + + ccnxCodecTlvEncoder_Finalize(encoder); + PARCBuffer *test = ccnxCodecTlvEncoder_CreateBuffer(encoder); + assertNotNull(test, "Got null buffer from encoder"); + uint8_t testSuite = parcBuffer_GetAtIndex(test, 21); + assertTrue(testSuite == 2, "Wrong cryptosuite, expected 2 got %u", testSuite); + + parcSigner_Release(&signer); + parcBuffer_Release(&test); + ccnxCodecTlvEncoder_Destroy(&encoder); + ccnxTlvDictionary_Release(&message); + parcBuffer_Release(&payload); + parcBuffer_Release(&truth); +} + +// ========================================================================= + +LONGBOW_TEST_FIXTURE(UnknownType) +{ + LONGBOW_RUN_TEST_CASE(UnknownType, unknown); +} + +LONGBOW_TEST_FIXTURE_SETUP(UnknownType) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(UnknownType) +{ + 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; +} + +/* + * try to encode a message with unknown message type + */ +LONGBOW_TEST_CASE(UnknownType, unknown) +{ + // this initializes the dictionary to unknown type + CCNxTlvDictionary *message = ccnxTlvDictionary_Create(20, 20); + + // encode + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + ssize_t length = ccnxCodecSchemaV1PacketEncoder_Encode(encoder, message); + assertTrue(length < 0, "Did not get error condition for unknown type"); + + CCNxCodecError *error = ccnxCodecTlvEncoder_GetError(encoder); + assertNotNull(error, "Did not get an error for invalid encoding"); + + ccnxCodecTlvEncoder_Destroy(&encoder); + ccnxTlvDictionary_Release(&message); +} + +// ========================================================================= + +LONGBOW_TEST_FIXTURE(Local) +{ + LONGBOW_RUN_TEST_CASE(Local, _getHopLimit_Present); + LONGBOW_RUN_TEST_CASE(Local, _getHopLimit_Missing); + LONGBOW_RUN_TEST_CASE(Local, _encodeFixedHeader_ContentObject); + LONGBOW_RUN_TEST_CASE(Local, _encodeFixedHeader_Interest); + LONGBOW_RUN_TEST_CASE(Local, _encodeOptionalHeaders); + LONGBOW_RUN_TEST_CASE(Local, _encodeMessage_Interest); + LONGBOW_RUN_TEST_CASE(Local, _encodeMessage_ContentObject); + LONGBOW_RUN_TEST_CASE(Local, _encodeCPI); + LONGBOW_RUN_TEST_CASE(Local, _encodeMessage_Unknown); + LONGBOW_RUN_TEST_CASE(Local, _encodeValidationAlg_Present); + LONGBOW_RUN_TEST_CASE(Local, _encodeValidationAlg_Missing); + LONGBOW_RUN_TEST_CASE(Local, _encodeValidationPayload_Present); + LONGBOW_RUN_TEST_CASE(Local, _encodeValidationPayload_Missing); +} + +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, _getHopLimit_Present) +{ + uint8_t hoplimit = 77; + CCNxTlvDictionary *dict = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + ccnxTlvDictionary_PutInteger(dict, CCNxCodecSchemaV1TlvDictionary_MessageFastArray_HOPLIMIT, hoplimit); + + uint8_t test = _getHopLimit(dict); + assertTrue(test == hoplimit, "Got wrong hoplimit, expected %u got %u", hoplimit, test); + ccnxTlvDictionary_Release(&dict); +} + +LONGBOW_TEST_CASE(Local, _getHopLimit_Missing) +{ + CCNxTlvDictionary *dict = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + + uint8_t test = _getHopLimit(dict); + assertTrue(test == CCNxInterestDefault_HopLimit, "Got wrong hoplimit, expected %u got %u", CCNxInterestDefault_HopLimit, test); + ccnxTlvDictionary_Release(&dict); +} + +LONGBOW_TEST_CASE(Local, _encodeFixedHeader_ContentObject) +{ + uint8_t encoded[] = { + 0x01, 0x01, 0x00, 100, // ver = 1, type = content object, length = 100 + 0x00, 0x00, 0x00, 14, // reserved = 0x0000000, header length = 14 + }; + PARCBuffer *truth = parcBuffer_Wrap(encoded, sizeof(encoded), 0, sizeof(encoded)); + + CCNxTlvDictionary *dict = ccnxCodecSchemaV1TlvDictionary_CreateContentObject(); + + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + ssize_t length = _encodeFixedHeader(encoder, dict, CCNxCodecSchemaV1Types_PacketType_ContentObject, 14, 100); + assertTrue(length == 8, "wrong length, expected %d got %zd", 8, length); + + ccnxCodecTlvEncoder_Finalize(encoder); + PARCBuffer *test = ccnxCodecTlvEncoder_CreateBuffer(encoder); + assertTrue(parcBuffer_Equals(test, truth), "Buffers mismatch") + { + printf("Expected\n"); + parcBuffer_Display(truth, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + } + + parcBuffer_Release(&truth); + parcBuffer_Release(&test); + ccnxTlvDictionary_Release(&dict); + ccnxCodecTlvEncoder_Destroy(&encoder); +} + +LONGBOW_TEST_CASE(Local, _encodeFixedHeader_Interest) +{ + uint8_t encoded[] = { + 0x01, 0x00, 0x00, 100, // ver = 1, type = interest, length = 100 + 0x1f, 0x00, 0x00, 14, // hoplimit = 31, reserved = 0x0000, header length = 14 + }; + PARCBuffer *truth = parcBuffer_Wrap(encoded, sizeof(encoded), 0, sizeof(encoded)); + + CCNxTlvDictionary *dict = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + ccnxTlvDictionary_PutInteger(dict, CCNxCodecSchemaV1TlvDictionary_MessageFastArray_HOPLIMIT, 31); + + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + ssize_t length = _encodeFixedHeader(encoder, dict, CCNxCodecSchemaV1Types_PacketType_Interest, 14, 100); + assertTrue(length == 8, "wrong length, expected %d got %zd", 8, length); + + ccnxCodecTlvEncoder_Finalize(encoder); + PARCBuffer *test = ccnxCodecTlvEncoder_CreateBuffer(encoder); + assertTrue(parcBuffer_Equals(test, truth), "Buffers mismatch") + { + printf("Expected\n"); + parcBuffer_Display(truth, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + } + + parcBuffer_Release(&truth); + parcBuffer_Release(&test); + ccnxTlvDictionary_Release(&dict); + ccnxCodecTlvEncoder_Destroy(&encoder); +} + +LONGBOW_TEST_CASE(Local, _encodeOptionalHeaders) +{ + uint8_t encoded[] = { + 0x00, 0x01, 0x00, 2, // Interest Lifetime (2 bytes) + 0xEA, 0xEB, + }; + PARCBuffer *truth = parcBuffer_Wrap(encoded, sizeof(encoded), 0, sizeof(encoded)); + + CCNxTlvDictionary *dict = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + ccnxTlvDictionary_PutInteger(dict, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_InterestLifetime, 0xEAEB); + + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + ssize_t length = _encodeOptionalHeaders(encoder, dict); + assertTrue(length == sizeof(encoded), "wrong length, expected %zu got %zd", sizeof(encoded), length); + + ccnxCodecTlvEncoder_Finalize(encoder); + PARCBuffer *test = ccnxCodecTlvEncoder_CreateBuffer(encoder); + assertTrue(parcBuffer_Equals(test, truth), "Buffers mismatch") + { + printf("Expected\n"); + parcBuffer_Display(truth, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + } + + parcBuffer_Release(&truth); + parcBuffer_Release(&test); + ccnxTlvDictionary_Release(&dict); + ccnxCodecTlvEncoder_Destroy(&encoder); +} + +LONGBOW_TEST_CASE(Local, _encodeMessage_Interest) +{ + uint8_t encoded[] = { + 0x00, 0x01, 0x00, 13, + 0x00, 0x00, 0x00, 9, + 0x00, CCNxNameLabelType_NAME, 0x00, 5, + 'p', 'o', 'p', 'p', 'y' + }; + PARCBuffer *truth = parcBuffer_Wrap(encoded, sizeof(encoded), 0, sizeof(encoded)); + + CCNxName *name = ccnxName_CreateFromCString("lci:/poppy"); + CCNxTlvDictionary *dict = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + ccnxTlvDictionary_PutName(dict, CCNxCodecSchemaV1TlvDictionary_MessageFastArray_NAME, name); + + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + + CCNxCodecSchemaV1Types_PacketType packetType; + ssize_t length = _encodeMessage(encoder, dict, &packetType); + assertTrue(length == sizeof(encoded), "wrong length, expected %zu got %zd", sizeof(encoded), length); + assertTrue(packetType == CCNxCodecSchemaV1Types_PacketType_Interest, "Wrong packet type, expected %d got %d", + CCNxCodecSchemaV1Types_PacketType_Interest, packetType); + + ccnxCodecTlvEncoder_Finalize(encoder); + PARCBuffer *test = ccnxCodecTlvEncoder_CreateBuffer(encoder); + assertTrue(parcBuffer_Equals(test, truth), "Buffers mismatch") + { + printf("Expected\n"); + parcBuffer_Display(truth, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + } + + parcBuffer_Release(&truth); + parcBuffer_Release(&test); + ccnxName_Release(&name); + ccnxTlvDictionary_Release(&dict); + ccnxCodecTlvEncoder_Destroy(&encoder); +} + +LONGBOW_TEST_CASE(Local, _encodeMessage_ContentObject) +{ + uint8_t encoded[] = { + 0x00, 0x02, 0x00, 13, + 0x00, 0x00, 0x00, 9, + 0x00, CCNxNameLabelType_NAME, 0x00, 5, + 'p', 'o', 'p', 'p', 'y' + }; + PARCBuffer *truth = parcBuffer_Wrap(encoded, sizeof(encoded), 0, sizeof(encoded)); + + CCNxName *name = ccnxName_CreateFromCString("lci:/poppy"); + CCNxTlvDictionary *dict = ccnxCodecSchemaV1TlvDictionary_CreateContentObject(); + ccnxTlvDictionary_PutName(dict, CCNxCodecSchemaV1TlvDictionary_MessageFastArray_NAME, name); + + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + + CCNxCodecSchemaV1Types_PacketType packetType; + ssize_t length = _encodeMessage(encoder, dict, &packetType); + assertTrue(length == sizeof(encoded), "wrong length, expected %zu got %zd", sizeof(encoded), length); + assertTrue(packetType == CCNxCodecSchemaV1Types_PacketType_ContentObject, "Wrong packet type, expected %d got %d", + CCNxCodecSchemaV1Types_PacketType_ContentObject, packetType); + + ccnxCodecTlvEncoder_Finalize(encoder); + PARCBuffer *test = ccnxCodecTlvEncoder_CreateBuffer(encoder); + assertTrue(parcBuffer_Equals(test, truth), "Buffers mismatch") + { + printf("Expected\n"); + parcBuffer_Display(truth, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + } + + parcBuffer_Release(&truth); + parcBuffer_Release(&test); + ccnxName_Release(&name); + ccnxTlvDictionary_Release(&dict); + ccnxCodecTlvEncoder_Destroy(&encoder); +} + +LONGBOW_TEST_CASE(Local, _encodeCPI) +{ + uint8_t encoded [] = { + 0x00, 0x02, 0x03, 0x99, // + }; + PARCBuffer *truth = parcBuffer_Wrap(encoded, sizeof(encoded), 0, sizeof(encoded)); + + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + CCNxTlvDictionary *dict = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + ccnxValidationCRC32C_Set(dict); + ccnxTlvDictionary_PutBuffer(dict, CCNxCodecSchemaV1TlvDictionary_MessageFastArray_PAYLOAD, truth); + + ssize_t length = _encodeCPI(encoder, dict); + assertTrue(length == sizeof(encoded), "wrong length, expected %zu got %zd", sizeof(encoded), length); + + ccnxCodecTlvEncoder_Finalize(encoder); + PARCBuffer *test = ccnxCodecTlvEncoder_CreateBuffer(encoder); + assertTrue(parcBuffer_Equals(test, truth), "Buffers mismatch") + { + printf("Expected\n"); + parcBuffer_Display(truth, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + } + + parcBuffer_Release(&truth); + parcBuffer_Release(&test); + ccnxTlvDictionary_Release(&dict); + ccnxCodecTlvEncoder_Destroy(&encoder); +} + +/* + * This test requires that we set the message type to some unknown value, which we get if + * we create a dictionary with ccnxTlvDictionary_Create() and dont call anything to set + * the message type. It will be "CCNxTlvDictionary_Unknown". + */ +LONGBOW_TEST_CASE(Local, _encodeMessage_Unknown) +{ + CCNxTlvDictionary *dict = ccnxTlvDictionary_Create(20, 20); + + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + + CCNxCodecSchemaV1Types_PacketType packetType; + ssize_t length = _encodeMessage(encoder, dict, &packetType); + assertTrue(length < 0, "wrong length, expected negative got %zd", length); + + CCNxCodecError *error = ccnxCodecTlvEncoder_GetError(encoder); + assertNotNull(error, "Got null error when an error condition should have been set"); + + ccnxTlvDictionary_Release(&dict); + ccnxCodecTlvEncoder_Destroy(&encoder); +} + +LONGBOW_TEST_CASE(Local, _encodeValidationAlg_Present) +{ + uint8_t encoded [] = { + 0x00, 0x03, 0x00, 4, // validation alg, length = 4 + 0x00, 0x02, 0x00, 0x00, // CRC32C + }; + PARCBuffer *truth = parcBuffer_Wrap(encoded, sizeof(encoded), 0, sizeof(encoded)); + PARCBuffer *truePayload = parcBuffer_Wrap(encoded, sizeof(encoded), 4, sizeof(encoded)); + + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + CCNxTlvDictionary *dict = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + ccnxValidationCRC32C_Set(dict); + ccnxTlvDictionary_PutBuffer(dict, CCNxCodecSchemaV1TlvDictionary_ValidationFastArray_PAYLOAD, truePayload); + + ssize_t length = _encodeValidationAlg(encoder, dict); + assertTrue(length == sizeof(encoded), "wrong length, expected %zu got %zd", sizeof(encoded), length); + + ccnxCodecTlvEncoder_Finalize(encoder); + PARCBuffer *test = ccnxCodecTlvEncoder_CreateBuffer(encoder); + assertTrue(parcBuffer_Equals(test, truth), "Buffers mismatch") + { + printf("Expected\n"); + parcBuffer_Display(truth, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + } + + parcBuffer_Release(&truth); + parcBuffer_Release(&truePayload); + parcBuffer_Release(&test); + ccnxTlvDictionary_Release(&dict); + ccnxCodecTlvEncoder_Destroy(&encoder); +} + +LONGBOW_TEST_CASE(Local, _encodeValidationAlg_Missing) +{ + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + CCNxTlvDictionary *dict = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + + ssize_t length = _encodeValidationAlg(encoder, dict); + assertTrue(length == 0, "wrong length, expected %d got %zd", 0, length); + + ccnxTlvDictionary_Release(&dict); + ccnxCodecTlvEncoder_Destroy(&encoder); +} + +LONGBOW_TEST_CASE(Local, _encodeValidationPayload_Present) +{ + uint8_t encoded [] = { + 0x00, 0x04, 0x00, 4, // validation payload, length = 4 + 0x00, 0x02, 0x03, 0x99, // + }; + PARCBuffer *truth = parcBuffer_Wrap(encoded, sizeof(encoded), 0, sizeof(encoded)); + PARCBuffer *truePayload = parcBuffer_Wrap(encoded, sizeof(encoded), 4, sizeof(encoded)); + + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + CCNxTlvDictionary *dict = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + ccnxValidationCRC32C_Set(dict); + ccnxTlvDictionary_PutBuffer(dict, CCNxCodecSchemaV1TlvDictionary_ValidationFastArray_PAYLOAD, truePayload); + + ssize_t length = _encodeValidationPayload(encoder, dict); + assertTrue(length == sizeof(encoded), "wrong length, expected %zu got %zd", sizeof(encoded), length); + + ccnxCodecTlvEncoder_Finalize(encoder); + PARCBuffer *test = ccnxCodecTlvEncoder_CreateBuffer(encoder); + assertTrue(parcBuffer_Equals(test, truth), "Buffers mismatch") + { + printf("Expected\n"); + parcBuffer_Display(truth, 3); + printf("Got\n"); + parcBuffer_Display(test, 3); + } + + parcBuffer_Release(&truth); + parcBuffer_Release(&truePayload); + parcBuffer_Release(&test); + ccnxTlvDictionary_Release(&dict); + ccnxCodecTlvEncoder_Destroy(&encoder); +} + +LONGBOW_TEST_CASE(Local, _encodeValidationPayload_Missing) +{ + CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create(); + CCNxTlvDictionary *dict = ccnxCodecSchemaV1TlvDictionary_CreateInterest(); + + ssize_t length = _encodeValidationPayload(encoder, dict); + assertTrue(length == 0, "wrong length, expected %d got %zd", 0, length); + + ccnxTlvDictionary_Release(&dict); + ccnxCodecTlvEncoder_Destroy(&encoder); +} + + +// ================================================================================== + + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnxCodecSchemaV1_PacketEncoder); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} |