END_TEST START_TEST (_strlcat) { size_t len; char s1[12]; char s2[24]; /* Concat */ strncpy (s1, "hi ", sizeof(s1)); strncpy (s2, "there!", sizeof(s2)); len = strlcat (s1, s2, sizeof(s1)); ch_assert_str_eq (s1, "hi there!"); ch_assert (len == strlen("hi there!")); /* Too long */ strncpy (s2, "12345678901234567890", sizeof(s2)); len = strlcat (s1, s2, sizeof(s1)); ch_assert (len > sizeof(s1)); }
END_TEST START_TEST (_add_some_evacs) { ret_t ret; hpack_header_table_t *table; hpack_set_t evicted_set; hpack_header_field_t fields[6]; hpack_header_field_t field; uint64_t size; uint16_t max_size; ret = hpack_header_table_new (&table); ch_assert (ret == ret_ok); for (int i=0; i<6; i++) { hpack_header_field_init (&fields[i]); chula_buffer_add_va (&fields[i].name, "%c-%d", 'a'+i, i); chula_buffer_add_va (&fields[i].value, "foobar-%d", i); } ret = hpack_header_field_get_size (&fields[0], &size); ch_assert (ret == ret_ok); max_size = (uint16_t) size * 4.5; ret = hpack_header_table_set_max (table, max_size, evicted_set); ch_assert (ret == ret_ok); for (int i=0; i<6; i++) { ret = hpack_header_table_add (table, &fields[i], evicted_set); ch_assert (ret_ok == ret); if (i < 4) { ch_assert (hpack_set_is_empty (evicted_set)); } else { /* Since only 4 items fit, whenever we add more we lose the oldest one, that is the fifth element */ ch_assert (hpack_header_table_set_exists (table, evicted_set, 5)); } } ch_assert (table->num_headers == 4); /* Make sure relevant contents are in there */ hpack_header_field_init (&field); for (int i=1; i<5; ++i) { bool is_static; ret = hpack_header_table_get (table, i, false, &field, &is_static); ch_assert (ret == ret_ok); ch_assert_str_eq (field.name.buf, fields[6-i].name.buf); ch_assert_str_eq (field.value.buf, fields[6-i].value.buf); ch_assert (field.flags.rep == fields[6-i].flags.rep); ch_assert (field.flags.name == fields[6-i].flags.name); ch_assert (field.flags.value == fields[6-i].flags.value); hpack_header_field_clean (&field); } /* Check that table's contents are OK*/ ch_assert (table->used_data == size * 4); ch_assert (table->headers_offsets.head == 2); ch_assert (table->headers_offsets.head == table->headers_offsets.tail - 4); /* Calculate the size of each field in table->headers_data */ size -= HPACK_HEADER_ENTRY_OVERHEAD - sizeof(hpack_header_table_field_info_t); ch_assert (table->headers_data.head == size * 2); ch_assert (table->headers_data.head == table->headers_data.tail - (size * 4)); /* Clean up */ hpack_header_field_mrproper (&field); for (int i=0; i<6; ++i) { hpack_header_field_mrproper (&fields[i]); } hpack_header_table_free (table); }
END_TEST START_TEST (_add_fits) { ret_t ret; hpack_header_table_t *table; hpack_set_t evicted_set; hpack_header_field_t fields[6]; hpack_header_field_t field; uint64_t size; uint16_t real_size; ret = hpack_header_table_new (&table); ch_assert (ret == ret_ok); for (int i=0; i<6; i++) { hpack_header_field_init (&fields[i]); chula_buffer_add_va (&fields[i].name, "%c-%d", 'a'+i, i); chula_buffer_add_va (&fields[i].value, "foobar-%d", i); } ret = hpack_header_field_get_size (&fields[0], &size); ch_assert (ret == ret_ok); real_size = fields[0].name.len + fields[0].value.len + sizeof(hpack_header_table_field_info_t); for (int i=0; i<6; i++) { ret = hpack_header_table_add (table, &fields[i], evicted_set); ch_assert (ret_ok == ret); /* Confirm that there's been no evictions */ ch_assert (hpack_set_is_empty (evicted_set)); /* Confirm that the number of headers in the table is OK */ ch_assert (i+1 == table->num_headers); /* Confirm that the "used data" is correct */ ch_assert ((i+1) * size == table->used_data); /* Confirm that the offset head is in place */ ch_assert (0 == table->headers_offsets.head); /* Confirm that the offsets tail is ok */ ch_assert (i+1 == table->headers_offsets.tail); /* Confirm that the data head is in place */ ch_assert (0 == table->headers_data.head); /* Confirm that the data tail is ok */ ch_assert ((i+1) * real_size == table->headers_data.tail); /* Confirm that the offset reference is correct */ ch_assert (table->headers_offsets.buffer[i] == i * real_size); } ch_assert (table->num_headers == 6); /* Check that returned fields are OK */ hpack_header_field_init (&field); for (int i=1; i<7; ++i) { bool is_static; ret = hpack_header_table_get (table, i, false, &field, &is_static); ch_assert (ret == ret_ok); ch_assert (field.flags.rep == fields[6-i].flags.rep); ch_assert (field.flags.name == fields[6-i].flags.name); ch_assert (field.flags.value == fields[6-i].flags.value); ch_assert_str_eq (field.name.buf, fields[6-i].name.buf); ch_assert_str_eq (field.value.buf, fields[6-i].value.buf); hpack_header_field_clean (&field); } /* Check that table's contents are OK*/ ret = hpack_header_field_get_size (&fields[0], &size); ch_assert (ret == ret_ok); ch_assert (table->used_data == 6 * size); ch_assert (table->headers_offsets.head == 0); ch_assert (table->headers_offsets.head + 6 == table->headers_offsets.tail); /* Calculate the size of each field in table->headers_data */ size -= HPACK_HEADER_ENTRY_OVERHEAD - sizeof(hpack_header_table_field_info_t); ch_assert (table->headers_data.head == 0); ch_assert (table->headers_data.head == table->headers_data.tail - (size *6)); /* Clean up */ hpack_header_field_mrproper (&field); for (int i=0; i<6; ++i) { hpack_header_field_mrproper (&fields[i]); } hpack_header_table_free (table); }