| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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. |
| */ |
| |
| #define _GNU_SOURCE |
| #include <stdio.h> |
| #include <assert.h> |
| #include <string.h> |
| #include <inttypes.h> |
| #include "test_case.h" |
| #include <qpid/dispatch.h> |
| #include "compose_private.h" |
| |
| |
| static char *vector0 = |
| "\x00\x53\x77" // amqp-value |
| "\xd0\x00\x00\x01\x26\x00\x00\x00\x0a" // list32 with ten items |
| "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs |
| "\xa1\x06key001" // str8-utf8 |
| "\x52\x0a" // smalluint |
| "\xa1\x06key002" // str8-utf8 |
| "\x52\x0b" // smalluint |
| "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs |
| "\xa1\x06key001" // str8-utf8 |
| "\x52\x14" // smalluint |
| "\xa1\x06key002" // str8-utf8 |
| "\x52\x15" // smalluint |
| "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs |
| "\xa1\x06key001" // str8-utf8 |
| "\x52\x14" // smalluint |
| "\xa1\x06key002" // str8-utf8 |
| "\x52\x15" // smalluint |
| "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs |
| "\xa1\x06key001" // str8-utf8 |
| "\x52\x14" // smalluint |
| "\xa1\x06key002" // str8-utf8 |
| "\x52\x15" // smalluint |
| "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs |
| "\xa1\x06key001" // str8-utf8 |
| "\x52\x14" // smalluint |
| "\xa1\x06key002" // str8-utf8 |
| "\x52\x15" // smalluint |
| "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs |
| "\xa1\x06key001" // str8-utf8 |
| "\x52\x14" // smalluint |
| "\xa1\x06key002" // str8-utf8 |
| "\x52\x15" // smalluint |
| "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs |
| "\xa1\x06key001" // str8-utf8 |
| "\x52\x14" // smalluint |
| "\xa1\x06key002" // str8-utf8 |
| "\x52\x15" // smalluint |
| "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs |
| "\xa1\x06key001" // str8-utf8 |
| "\x52\x14" // smalluint |
| "\xa1\x06key002" // str8-utf8 |
| "\x52\x15" // smalluint |
| "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs |
| "\xa1\x06key001" // str8-utf8 |
| "\x52\x14" // smalluint |
| "\xa1\x06key002" // str8-utf8 |
| "\x52\x15" // smalluint |
| "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs |
| "\xa1\x06key001" // str8-utf8 |
| "\x52\x14" // smalluint |
| "\xa1\x06key002" // str8-utf8 |
| "\x52\x15" // smalluint |
| ; |
| |
| static int vector0_length = 302; |
| |
| static char *test_compose_list_of_maps(void *context) |
| { |
| qd_composed_field_t *field = qd_compose(QD_PERFORMATIVE_BODY_AMQP_VALUE, 0); |
| |
| qd_compose_start_list(field); |
| |
| qd_compose_start_map(field); |
| qd_compose_insert_string(field, "key001"); |
| qd_compose_insert_uint(field, 10); |
| qd_compose_insert_string(field, "key002"); |
| qd_compose_insert_uint(field, 11); |
| qd_compose_end_map(field); |
| |
| for (int j = 0; j < 9; j++) { |
| qd_compose_start_map(field); |
| qd_compose_insert_string(field, "key001"); |
| qd_compose_insert_uint(field, 20); |
| qd_compose_insert_string(field, "key002"); |
| qd_compose_insert_uint(field, 21); |
| qd_compose_end_map(field); |
| } |
| |
| qd_compose_end_list(field); |
| |
| qd_buffer_t *buf = DEQ_HEAD(field->buffers); |
| |
| if (qd_buffer_size(buf) != vector0_length) return "Incorrect Length of Buffer"; |
| |
| char *left = vector0; |
| char *right = (char*) qd_buffer_base(buf); |
| int idx; |
| |
| for (idx = 0; idx < vector0_length; idx++) { |
| if (*left != *right) return "Pattern Mismatch"; |
| left++; |
| right++; |
| } |
| |
| qd_compose_free(field); |
| return 0; |
| } |
| |
| static char *vector1 = |
| "\x00\x53\x71" // delivery annotations |
| "\xd1\x00\x00\x00\x3d\x00\x00\x00\x04" // map32 with two item pairs |
| "\xa3\x06key001" // sym8 |
| "\x52\x0a" // smalluint |
| "\xa3\x06key002" // sym8 |
| "\xd0\x00\x00\x00\x22\x00\x00\x00\x04" // list32 with four items |
| "\xa1\x05item1" // str8-utf8 |
| "\xa1\x05item2" // str8-utf8 |
| "\xa1\x05item3" // str8-utf8 |
| "\xd0\x00\x00\x00\x04\x00\x00\x00\x00" // list32 empty |
| ; |
| |
| static int vector1_length = 69; |
| |
| static char *test_compose_nested_composites(void *context) |
| { |
| qd_composed_field_t *field = qd_compose(QD_PERFORMATIVE_DELIVERY_ANNOTATIONS, 0); |
| |
| qd_compose_start_map(field); |
| |
| qd_compose_insert_symbol(field, "key001"); |
| qd_compose_insert_uint(field, 10); |
| |
| qd_compose_insert_symbol(field, "key002"); |
| qd_compose_start_list(field); |
| |
| qd_compose_insert_string(field, "item1"); |
| qd_compose_insert_string(field, "item2"); |
| qd_compose_insert_string(field, "item3"); |
| |
| qd_compose_start_list(field); |
| qd_compose_end_list(field); |
| |
| qd_compose_end_list(field); |
| qd_compose_end_map(field); |
| |
| qd_buffer_t *buf = DEQ_HEAD(field->buffers); |
| |
| if (qd_buffer_size(buf) != vector1_length) return "Incorrect Length of Buffer"; |
| |
| char *left = vector1; |
| char *right = (char*) qd_buffer_base(buf); |
| int idx; |
| |
| for (idx = 0; idx < vector1_length; idx++) { |
| if (*left != *right) return "Pattern Mismatch"; |
| left++; |
| right++; |
| } |
| |
| qd_compose_free(field); |
| return 0; |
| } |
| |
| static char *vector2 = |
| "\x00\x53\x73" // properties |
| "\xd0\x00\x00\x00\x83\x00\x00\x00\x1c" // list32 with 28 items |
| "\x40" // null |
| "\x42" // false |
| "\x41" // true |
| "\x43" // uint0 |
| "\x52\x01" // smalluint |
| "\x52\xff" // smalluint |
| "\x70\x00\x00\x01\x00" // uint |
| "\x70\x10\x00\x00\x00" // uint |
| "\x44" // ulong0 |
| "\x53\x01" // smallulong |
| "\x53\xff" // smallulong |
| "\x80\x00\x00\x00\x00\x00\x00\x01\x00" // ulong |
| "\x80\x00\x00\x00\x00\x20\x00\x00\x00" // ulong |
| "\x54\x00" // smallint |
| "\x54\x01" // smallint |
| "\x54\xff" // smallint |
| "\x71\x00\x00\x00\xff" // int |
| "\x71\x00\x00\x01\x00" // int |
| "\x55\x00" // smalllong |
| "\x55\x01" // smalllong |
| "\x55\xff" // smalllong |
| "\x81\x00\x00\x00\x00\x00\x00\x00\xff" // long |
| "\x81\x00\x00\x00\x00\x00\x00\x01\x00" // long |
| "\x83\x00\x11\x22\x33\x44\x55\x66\x77" // timestamp |
| "\x98\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x00" // uuid |
| "\xa0\x02\x00\x11" // vbin8 |
| "\xa1\x06string" // str8-utf8 |
| "\xa3\x06symbol" // sym8 |
| ; |
| |
| static int vector2_length = 139; |
| |
| static char *test_compose_scalars(void *context) |
| { |
| qd_composed_field_t *field = qd_compose(QD_PERFORMATIVE_PROPERTIES, 0); |
| |
| qd_compose_start_list(field); |
| |
| qd_compose_insert_null(field); |
| |
| qd_compose_insert_bool(field, 0); |
| qd_compose_insert_bool(field, 1); |
| |
| qd_compose_insert_uint(field, 0); |
| qd_compose_insert_uint(field, 1); |
| qd_compose_insert_uint(field, 255); |
| qd_compose_insert_uint(field, 256); |
| qd_compose_insert_uint(field, 0x10000000); |
| |
| qd_compose_insert_ulong(field, 0); |
| qd_compose_insert_ulong(field, 1); |
| qd_compose_insert_ulong(field, 255); |
| qd_compose_insert_ulong(field, 256); |
| qd_compose_insert_ulong(field, 0x20000000); |
| |
| qd_compose_insert_int(field, 0); |
| qd_compose_insert_int(field, 1); |
| qd_compose_insert_int(field, -1); |
| qd_compose_insert_int(field, 255); |
| qd_compose_insert_int(field, 256); |
| |
| qd_compose_insert_long(field, 0); |
| qd_compose_insert_long(field, 1); |
| qd_compose_insert_long(field, -1); |
| qd_compose_insert_long(field, 255); |
| qd_compose_insert_long(field, 256); |
| |
| qd_compose_insert_timestamp(field, 0x0011223344556677); |
| qd_compose_insert_uuid(field, (uint8_t*) "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x00"); |
| qd_compose_insert_binary(field, (uint8_t*) "\x00\x11", 2); |
| qd_compose_insert_string(field, "string"); |
| qd_compose_insert_symbol(field, "symbol"); |
| |
| qd_compose_end_list(field); |
| |
| qd_buffer_t *buf = DEQ_HEAD(field->buffers); |
| |
| if (qd_buffer_size(buf) != vector2_length) return "Incorrect Length of Buffer"; |
| |
| char *left = vector2; |
| char *right = (char*) qd_buffer_base(buf); |
| int idx; |
| |
| for (idx = 0; idx < vector2_length; idx++) { |
| if (*left != *right) return "Pattern Mismatch"; |
| left++; |
| right++; |
| } |
| |
| qd_compose_free(field); |
| return 0; |
| } |
| |
| |
| // verify composition via a set of sub-fields |
| static char *vector3 = |
| "\x00\x53\x72" // message annotations |
| "\xD1\x00\x00\x00\x1A\x00\x00\x00\x04" // map32, 26 bytes, 4 fields |
| "\xA1\x04Key1" // str8 |
| "\x70\x00\x00\x03\xE7" // uint 999 |
| "\xA1\x04Key2" // str8 |
| "\x70\x00\x00\x03\x78"; // uint 888 |
| static int vector3_length = 34; |
| |
| static char *test_compose_subfields(void *context) |
| { |
| qd_composed_field_t *sub1 = qd_compose_subfield(0); |
| qd_compose_insert_string(sub1, "Key1"); |
| qd_composed_field_t *sub2 = qd_compose_subfield(0); |
| qd_compose_insert_uint(sub2, 999); |
| |
| qd_composed_field_t *sub3 = qd_compose_subfield(0); |
| qd_compose_insert_string(sub3, "Key2"); |
| |
| // |
| qd_composed_field_t *field = qd_compose(QD_PERFORMATIVE_MESSAGE_ANNOTATIONS, 0); |
| qd_compose_start_map(field); |
| qd_compose_insert_buffers(field, &sub1->buffers); |
| if (!DEQ_IS_EMPTY(sub1->buffers)) return "Buffer chain ownership not transferred!"; |
| qd_compose_free(sub1); |
| qd_compose_insert_buffers(field, &sub2->buffers); |
| qd_compose_free(sub2); |
| |
| qd_compose_insert_buffers(field, &sub3->buffers); |
| qd_compose_free(sub3); |
| qd_compose_insert_uint(field, 888); |
| qd_compose_end_map(field); |
| |
| qd_buffer_list_t list; |
| qd_compose_take_buffers(field, &list); |
| if (!DEQ_IS_EMPTY(field->buffers)) return "Buffer list not removed!"; |
| |
| qd_compose_free(field); |
| |
| if (qd_buffer_list_length(&list) != vector3_length) |
| return "Improper encoded length"; |
| |
| unsigned char *src = (unsigned char *)vector3; |
| qd_buffer_t *buf = DEQ_HEAD(list); |
| while (buf) { |
| unsigned char *c = qd_buffer_base(buf); |
| while (c != (qd_buffer_base(buf) + qd_buffer_size(buf))) { |
| if (*c != *src) return "Pattern Mismatch"; |
| c++; |
| src++; |
| } |
| buf = DEQ_NEXT(buf); |
| } |
| |
| qd_buffer_list_free_buffers(&list); |
| |
| return 0; |
| } |
| |
| |
| int compose_tests() |
| { |
| int result = 0; |
| |
| TEST_CASE(test_compose_list_of_maps, 0); |
| TEST_CASE(test_compose_nested_composites, 0); |
| TEST_CASE(test_compose_scalars, 0); |
| TEST_CASE(test_compose_subfields, 0); |
| |
| return result; |
| } |
| |