Signed-off-by: Taras Kondratiuk <taras.kondrat...@linaro.org>
---
 test/validation/Makefile.am                    |   1 +
 test/validation/buffer/odp_buffer_testsuites.h |   4 +
 test/validation/buffer/odp_packet_test.c       | 659 +++++++++++++++++++++++++
 test/validation/odp_buffer.c                   |   5 +
 4 files changed, 669 insertions(+)
 create mode 100644 test/validation/buffer/odp_packet_test.c

diff --git a/test/validation/Makefile.am b/test/validation/Makefile.am
index 41c48ec..2ceb27a 100644
--- a/test/validation/Makefile.am
+++ b/test/validation/Makefile.am
@@ -26,4 +26,5 @@ dist_odp_crypto_SOURCES = crypto/odp_crypto_test_async_inp.c \
 dist_odp_shm_SOURCES = odp_shm.c common/odp_cunit_common.c
 dist_odp_buffer_SOURCES = buffer/odp_buffer_pool_test.c \
                          buffer/odp_buffer_test.c \
+                         buffer/odp_packet_test.c \
                          odp_buffer.c common/odp_cunit_common.c
diff --git a/test/validation/buffer/odp_buffer_testsuites.h 
b/test/validation/buffer/odp_buffer_testsuites.h
index ca42c2d..715d9ac 100644
--- a/test/validation/buffer/odp_buffer_testsuites.h
+++ b/test/validation/buffer/odp_buffer_testsuites.h
@@ -16,10 +16,14 @@
 
 extern CU_TestInfo buffer_pool_tests[];
 extern CU_TestInfo buffer_tests[];
+extern CU_TestInfo packet_tests[];
 
 extern int buffer_testsuite_init(void);
 extern int buffer_testsuite_finalize(void);
 
+extern int packet_testsuite_init(void);
+extern int packet_testsuite_finalize(void);
+
 odp_buffer_pool_t pool_create(int buf_num, int buf_size, int buf_type);
 
 #endif /* ODP_BUFFER_TESTSUITES_H_ */
diff --git a/test/validation/buffer/odp_packet_test.c 
b/test/validation/buffer/odp_packet_test.c
new file mode 100644
index 0000000..fbce0df
--- /dev/null
+++ b/test/validation/buffer/odp_packet_test.c
@@ -0,0 +1,659 @@
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ */
+
+#include "odp_buffer_testsuites.h"
+#include <stdlib.h>
+
+#define BUFFER_LENGTH  1500
+static odp_buffer_pool_t packet_pool;
+static const uint32_t packet_len = BUFFER_LENGTH;
+
+odp_packet_t test_packet;
+
+int packet_testsuite_init(void)
+{
+       odp_buffer_pool_param_t params = {
+               .buf_size  = BUFFER_LENGTH + ODP_CONFIG_PACKET_HEADROOM,
+               .buf_align = ODP_CACHE_LINE_SIZE,
+               .num_bufs  = 100,
+               .buf_type  = ODP_BUFFER_TYPE_PACKET,
+       };
+
+       packet_pool = odp_buffer_pool_create("packet_pool", ODP_SHM_INVALID,
+                                            &params);
+       if (packet_pool == ODP_BUFFER_POOL_INVALID)
+               return -1;
+
+       test_packet = odp_packet_alloc(packet_pool, packet_len);
+       if (odp_packet_is_valid(test_packet) == 0)
+               return -1;
+
+       return 0;
+}
+
+int packet_testsuite_finalize(void)
+{
+       odp_packet_free(test_packet);
+       if (odp_buffer_pool_destroy(packet_pool) != 0)
+               return -1;
+       return 0;
+}
+
+static void packet_alloc_free(void)
+{
+       odp_buffer_pool_t pool;
+       odp_packet_t packet;
+       const uint32_t length = 64;
+       pool = pool_create(1, length + ODP_CONFIG_PACKET_HEADROOM,
+                          ODP_BUFFER_TYPE_PACKET);
+
+       /* Allocate the only buffer from the pool */
+       packet = odp_packet_alloc(pool, length);
+       CU_ASSERT_FATAL(packet != ODP_PACKET_INVALID);
+       CU_ASSERT(odp_packet_len(packet) == length);
+       /** @todo: is it correct to assume the pool had only one buffer? */
+       CU_ASSERT_FATAL(odp_packet_alloc(pool, length) == ODP_PACKET_INVALID)
+
+       odp_packet_free(packet);
+
+       /* Check that the buffer was returned back to the pool */
+       packet = odp_packet_alloc(pool, length);
+       CU_ASSERT_FATAL(packet != ODP_PACKET_INVALID);
+       CU_ASSERT(odp_packet_len(packet) == length);
+
+       odp_packet_free(packet);
+       CU_ASSERT(odp_buffer_pool_destroy(pool) == 0);
+}
+
+static void packet_alloc_segmented(void)
+{
+       odp_packet_t pkt;
+       pkt = odp_packet_alloc(packet_pool, BUFFER_LENGTH * 10);
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       odp_packet_free(pkt);
+}
+
+static void packet_buffer_conversion(void)
+{
+       odp_packet_t pkt = test_packet;
+       odp_packet_t tmp_pkt;
+       odp_buffer_t buf;
+
+       buf = odp_packet_to_buffer(pkt);
+       CU_ASSERT_FATAL(buf != ODP_BUFFER_INVALID);
+       CU_ASSERT(odp_buffer_type(buf) == ODP_BUFFER_TYPE_PACKET);
+       CU_ASSERT(odp_buffer_size(buf) == odp_packet_buf_len(pkt));
+
+       tmp_pkt = odp_packet_from_buffer(buf);
+       CU_ASSERT_FATAL(tmp_pkt != ODP_PACKET_INVALID);
+       /** @todo: Need an API to compare packets */
+}
+
+static void packet_basic_metadata(void)
+{
+       odp_packet_t pkt = test_packet;
+       CU_ASSERT(odp_packet_head(pkt) != NULL);
+       CU_ASSERT(odp_packet_data(pkt) != NULL);
+
+       CU_ASSERT(odp_packet_pool(pkt) != ODP_BUFFER_POOL_INVALID);
+       /* Packet was allocated by application so shouldn't have valid pktio. */
+       CU_ASSERT(odp_packet_input(pkt) == ODP_PKTIO_INVALID);
+}
+
+static void packet_length(void)
+{
+       odp_packet_t pkt = test_packet;
+       uint32_t buf_len, headroom, tailroom;
+
+       buf_len = odp_packet_buf_len(pkt);
+       headroom = odp_packet_headroom(pkt);
+       tailroom = odp_packet_tailroom(pkt);
+
+       CU_ASSERT(odp_packet_len(pkt) == packet_len);
+       CU_ASSERT(headroom >= ODP_CONFIG_PACKET_HEADROOM);
+#if ODP_CONFIG_PACKET_TAILROOM != 0 /* Avoid 'always true' warning */
+       CU_ASSERT(tailroom >= ODP_CONFIG_PACKET_TAILROOM);
+#endif
+       CU_ASSERT(buf_len >= packet_len + headroom + tailroom);
+}
+
+static void packet_debug(void)
+{
+       CU_ASSERT(odp_packet_is_valid(test_packet) == 1);
+       odp_packet_print(test_packet);
+}
+
+static void packet_context(void)
+{
+       odp_packet_t pkt = test_packet;
+       char ptr_test_value = 2;
+       uint64_t u64_test_value = 0x0123456789abcdf;
+
+       void *prev_ptr;
+       uint64_t prev_u64;
+
+       prev_ptr = odp_packet_user_ptr(pkt);
+       odp_packet_user_ptr_set(pkt, &ptr_test_value);
+       CU_ASSERT(odp_packet_user_ptr(pkt) == &ptr_test_value);
+       odp_packet_user_ptr_set(pkt, prev_ptr);
+
+       prev_u64 = odp_packet_user_u64(pkt);
+       odp_packet_user_u64_set(pkt, u64_test_value);
+       CU_ASSERT(odp_packet_user_u64(pkt) == u64_test_value);
+       odp_packet_user_u64_set(pkt, prev_u64);
+
+       odp_packet_reset(pkt, packet_len);
+}
+
+static void packet_layer_offsets(void)
+{
+       odp_packet_t pkt = test_packet;
+       uint8_t *l2_addr, *l3_addr, *l4_addr;
+       uint32_t seg_len;
+       const uint32_t l2_off = 2;
+       const uint32_t l3_off = l2_off + 14;
+       const uint32_t l4_off = l3_off + 14;
+
+       /* Set offsets to the same value */
+       odp_packet_l2_offset_set(pkt, l2_off);
+       odp_packet_l3_offset_set(pkt, l2_off);
+       odp_packet_l4_offset_set(pkt, l2_off);
+
+       /* Addresses should be the same */
+       l2_addr = odp_packet_l2_ptr(pkt, &seg_len);
+       CU_ASSERT(seg_len != 0);
+       l3_addr = odp_packet_l3_ptr(pkt, &seg_len);
+       CU_ASSERT(seg_len != 0);
+       l4_addr = odp_packet_l4_ptr(pkt, &seg_len);
+       CU_ASSERT(seg_len != 0);
+       CU_ASSERT(l2_addr != NULL);
+       CU_ASSERT(l2_addr == l3_addr);
+       CU_ASSERT(l2_addr == l4_addr);
+
+       /* Set offsets to the different values */
+       odp_packet_l2_offset_set(pkt, l2_off);
+       CU_ASSERT(odp_packet_l2_offset(pkt) == l2_off);
+       odp_packet_l3_offset_set(pkt, l3_off);
+       CU_ASSERT(odp_packet_l3_offset(pkt) == l3_off);
+       odp_packet_l4_offset_set(pkt, l4_off);
+       CU_ASSERT(odp_packet_l4_offset(pkt) == l4_off);
+
+       /* Addresses should not be the same */
+       l2_addr = odp_packet_l2_ptr(pkt, NULL);
+       CU_ASSERT(l2_addr != NULL);
+       l3_addr = odp_packet_l3_ptr(pkt, NULL);
+       CU_ASSERT(l3_addr != NULL);
+       l4_addr = odp_packet_l4_ptr(pkt, NULL);
+       CU_ASSERT(l4_addr != NULL);
+
+       CU_ASSERT(l2_addr != l3_addr);
+       CU_ASSERT(l2_addr != l4_addr);
+       CU_ASSERT(l3_addr != l4_addr);
+}
+
+static void _verify_headroom_shift(odp_packet_t packet,
+                                  int shift)
+{
+       uint32_t room = odp_packet_headroom(packet);
+       uint32_t seg_data_len = odp_packet_seg_len(packet);
+       uint32_t pkt_data_len = odp_packet_len(packet);
+       void *data;
+       char *data_orig = odp_packet_data(packet);
+       char *head_orig = odp_packet_head(packet);
+
+       if (shift == 0)
+               return;
+
+       if (shift > 0)
+               data = odp_packet_push_head(packet, shift);
+       else
+               data = odp_packet_pull_head(packet, -shift);
+
+       CU_ASSERT(data != NULL);
+       CU_ASSERT(odp_packet_headroom(packet) == room - shift);
+       CU_ASSERT(odp_packet_seg_len(packet) == seg_data_len + shift);
+       CU_ASSERT(odp_packet_len(packet) == pkt_data_len + shift);
+       CU_ASSERT(odp_packet_data(packet) == data);
+       CU_ASSERT(odp_packet_head(packet) == head_orig);
+       CU_ASSERT(data == data_orig - shift);
+}
+
+static void packet_headroom(void)
+{
+       odp_packet_t pkt = test_packet;
+       uint32_t room;
+       uint32_t seg_data_len;
+       uint32_t push_val, pull_val;
+
+       room = odp_packet_headroom(pkt);
+       CU_ASSERT(room >= ODP_CONFIG_PACKET_HEADROOM);
+       seg_data_len = odp_packet_seg_len(pkt);
+       CU_ASSERT(seg_data_len >= 1);
+       /** @todo: should be len - 1 */
+       pull_val = seg_data_len / 2;
+       push_val = room;
+
+       _verify_headroom_shift(pkt, -pull_val);
+       _verify_headroom_shift(pkt, push_val + pull_val);
+       _verify_headroom_shift(pkt, -push_val);
+}
+
+static void _verify_tailroom_shift(odp_packet_t pkt,
+                                  int shift)
+{
+       odp_packet_seg_t seg;
+       uint32_t room;
+       uint32_t seg_data_len, pkt_data_len;
+       void *tail;
+       char *tail_orig;
+
+       if (shift == 0)
+               return;
+
+       room = odp_packet_tailroom(pkt);
+       pkt_data_len = odp_packet_len(pkt);
+       tail_orig = odp_packet_tail(pkt);
+
+       seg = odp_packet_last_seg(pkt);
+       CU_ASSERT(seg != ODP_SEGMENT_INVALID);
+       seg_data_len = odp_packet_seg_data_len(pkt, seg);
+
+       if (shift > 0)
+               tail = odp_packet_push_tail(pkt, shift);
+       else
+               tail = odp_packet_pull_tail(pkt, -shift);
+
+       CU_ASSERT(tail != NULL);
+       CU_ASSERT(odp_packet_seg_data_len(pkt, seg) == seg_data_len + shift);
+       CU_ASSERT(odp_packet_len(pkt) == pkt_data_len + shift);
+       CU_ASSERT(odp_packet_tailroom(pkt) == room - shift);
+       if (shift > 0) {
+               CU_ASSERT(odp_packet_tail(pkt) == tail_orig + shift);
+               CU_ASSERT(tail == tail_orig);
+       } else {
+               CU_ASSERT(odp_packet_tail(pkt) == tail);
+               CU_ASSERT(tail == tail_orig + shift);
+       }
+}
+
+static void packet_tailroom(void)
+{
+       odp_packet_t pkt = test_packet;
+       odp_packet_seg_t segment;
+       uint32_t room;
+       uint32_t seg_data_len;
+       uint32_t push_val, pull_val;
+
+       segment = odp_packet_last_seg(pkt);
+       CU_ASSERT(segment != ODP_SEGMENT_INVALID);
+       room = odp_packet_tailroom(pkt);
+#if ODP_CONFIG_PACKET_TAILROOM != 0 /* Avoid 'always true' warning */
+       CU_ASSERT(room >= ODP_CONFIG_PACKET_TAILROOM);
+#endif
+       seg_data_len = odp_packet_seg_data_len(pkt, segment);
+       CU_ASSERT(seg_data_len >= 1);
+       /** @todo: should be len - 1 */
+       pull_val = seg_data_len / 2;
+       /* Leave one byte in a tailroom for odp_packet_tail() to succeed */
+       push_val = room - 1;
+
+       _verify_tailroom_shift(pkt, -pull_val);
+       _verify_tailroom_shift(pkt, push_val + pull_val);
+       _verify_tailroom_shift(pkt, -push_val);
+}
+
+static void packet_segments(void)
+{
+       int num_segs, seg_index;
+       uint32_t data_len, buf_len;
+       odp_packet_seg_t seg;
+       odp_packet_t pkt = test_packet;
+
+       CU_ASSERT(odp_packet_is_valid(pkt) == 1);
+
+       num_segs = odp_packet_num_segs(pkt);
+       CU_ASSERT(num_segs != 0);
+
+       if (!odp_packet_is_segmented(pkt))
+               CU_ASSERT(num_segs == 1);
+
+       seg = odp_packet_first_seg(pkt);
+       buf_len = 0;
+       data_len = 0;
+       seg_index = 0;
+       while (seg_index < num_segs && seg != ODP_PACKET_SEG_INVALID) {
+               uint32_t seg_data_len, seg_buf_len;
+               void *seg_buf_addr, *seg_data;
+
+               seg_buf_addr = odp_packet_seg_buf_addr(pkt, seg);
+               seg_buf_len  = odp_packet_seg_buf_len(pkt, seg);
+               seg_data_len = odp_packet_seg_data_len(pkt, seg);
+               seg_data     = odp_packet_seg_data(pkt, seg);
+
+               CU_ASSERT(seg_buf_len > 0);
+               CU_ASSERT(seg_data_len > 0);
+               CU_ASSERT(seg_buf_len > seg_data_len);
+               CU_ASSERT(seg_data != NULL);
+               CU_ASSERT(seg_buf_addr != NULL);
+               CU_ASSERT(seg_data > seg_buf_addr);
+
+               buf_len += seg_buf_len;
+               data_len += seg_data_len;
+
+               /** @todo: touch memory in a segment */
+               seg_index++;
+               seg = odp_packet_next_seg(pkt, seg);
+       }
+
+       CU_ASSERT(seg_index == num_segs);
+       CU_ASSERT(buf_len == odp_buffer_size(odp_packet_to_buffer(pkt)));
+       CU_ASSERT(data_len == odp_packet_len(pkt));
+
+       if (seg_index == num_segs)
+               CU_ASSERT(seg == ODP_PACKET_SEG_INVALID);
+}
+
+static void packet_segment_last(void)
+{
+       odp_packet_t pkt = test_packet;
+       odp_packet_seg_t seg;
+
+       seg = odp_packet_last_seg(pkt);
+       CU_ASSERT_FATAL(seg != ODP_PACKET_SEG_INVALID);
+
+       seg = odp_packet_next_seg(pkt, seg);
+       CU_ASSERT(seg == ODP_PACKET_SEG_INVALID);
+}
+
+#define TEST_INFLAG(packet, flag) \
+do { \
+       odp_packet_has_##flag##_set(packet, 0);           \
+       CU_ASSERT(odp_packet_has_##flag(packet) == 0);    \
+       odp_packet_has_##flag##_set(packet, 1);           \
+       CU_ASSERT(odp_packet_has_##flag(packet) == 1);    \
+} while (0)
+
+static void packet_in_flags(void)
+{
+       odp_packet_t pkt = test_packet;
+
+       TEST_INFLAG(pkt, l2);
+       TEST_INFLAG(pkt, l3);
+       TEST_INFLAG(pkt, l4);
+       TEST_INFLAG(pkt, eth);
+       TEST_INFLAG(pkt, jumbo);
+       TEST_INFLAG(pkt, vlan);
+       TEST_INFLAG(pkt, vlan_qinq);
+       TEST_INFLAG(pkt, arp);
+       TEST_INFLAG(pkt, ipv4);
+       TEST_INFLAG(pkt, ipv6);
+       TEST_INFLAG(pkt, ipfrag);
+       TEST_INFLAG(pkt, ipopt);
+       TEST_INFLAG(pkt, ipsec);
+       TEST_INFLAG(pkt, udp);
+       TEST_INFLAG(pkt, tcp);
+       TEST_INFLAG(pkt, sctp);
+       TEST_INFLAG(pkt, icmp);
+}
+
+static void packet_error_flags(void)
+{
+       odp_packet_t pkt = test_packet;
+       int err;
+
+       /**
+        * The packet have not been classified so it doesn't have error flag
+        * properly set. Just check that function return one of allowed values.
+        * @todo: check classified packet when classifier is added in place.
+        */
+       err = odp_packet_error(pkt);
+       CU_ASSERT(err == 0 || err == 1);
+
+       err = odp_packet_errflag_frame_len(pkt);
+       CU_ASSERT(err == 0 || err == 1);
+}
+
+static void packet_out_flags(void)
+{
+       odp_packet_override_l4_chksum(test_packet);
+       CU_PASS("Current API doesn't return any error code\n");
+}
+
+static void packet_add_rem_data(void)
+{
+       odp_packet_t pkt, new_pkt;
+       uint32_t pkt_len, offset, add_len;
+
+       pkt = odp_packet_alloc(packet_pool, BUFFER_LENGTH);
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+
+       pkt_len = odp_packet_len(pkt);
+       /* Insert one more packet length in the middle of a packet */
+       offset = pkt_len / 2;
+       add_len = pkt_len;
+
+       new_pkt = odp_packet_add_data(pkt, offset, add_len);
+       CU_ASSERT(new_pkt != ODP_PACKET_INVALID);
+       if (new_pkt == ODP_PACKET_INVALID)
+               goto free_packet;
+       CU_ASSERT(odp_packet_len(new_pkt) == pkt_len + add_len);
+       pkt = new_pkt;
+
+       pkt_len = odp_packet_len(pkt);
+       new_pkt = odp_packet_rem_data(pkt, offset, add_len);
+       CU_ASSERT(new_pkt != ODP_PACKET_INVALID);
+       if (new_pkt == ODP_PACKET_INVALID)
+               goto free_packet;
+       CU_ASSERT(odp_packet_len(new_pkt) == pkt_len - add_len);
+       pkt = new_pkt;
+
+free_packet:
+       odp_packet_free(pkt);
+}
+
+
+#define COMPARE_INFLAG(p1, p2, flag) \
+       CU_ASSERT(odp_packet_has_##flag(p1) == odp_packet_has_##flag(p2))
+
+static void _packet_compare_inflags(odp_packet_t pkt1, odp_packet_t pkt2)
+{
+       COMPARE_INFLAG(pkt1, pkt2, l2);
+       COMPARE_INFLAG(pkt1, pkt2, l3);
+       COMPARE_INFLAG(pkt1, pkt2, l4);
+       COMPARE_INFLAG(pkt1, pkt2, eth);
+       COMPARE_INFLAG(pkt1, pkt2, jumbo);
+       COMPARE_INFLAG(pkt1, pkt2, eth);
+       COMPARE_INFLAG(pkt1, pkt2, vlan);
+       COMPARE_INFLAG(pkt1, pkt2, vlan_qinq);
+       COMPARE_INFLAG(pkt1, pkt2, arp);
+       COMPARE_INFLAG(pkt1, pkt2, ipv4);
+       COMPARE_INFLAG(pkt1, pkt2, ipv6);
+       COMPARE_INFLAG(pkt1, pkt2, ipfrag);
+       COMPARE_INFLAG(pkt1, pkt2, ipopt);
+       COMPARE_INFLAG(pkt1, pkt2, ipsec);
+       COMPARE_INFLAG(pkt1, pkt2, udp);
+       COMPARE_INFLAG(pkt1, pkt2, tcp);
+       COMPARE_INFLAG(pkt1, pkt2, sctp);
+       COMPARE_INFLAG(pkt1, pkt2, icmp);
+}
+
+struct pktcmp_ctx {
+       odp_packet_t pkt;
+       odp_packet_seg_t seg;
+       char *ptr;
+       uint32_t len;
+};
+
+static void _packet_compare_data(odp_packet_t pkt1, odp_packet_t pkt2)
+{
+       const int pkt_num = 2;
+       int i;
+       struct pktcmp_ctx info[pkt_num];
+       uint32_t pkt_len = odp_packet_len(pkt1);
+
+       CU_ASSERT_FATAL(pkt_len == odp_packet_len(pkt2));
+
+       info[0].pkt = pkt1;
+       info[1].pkt = pkt2;
+
+       for (i = 0; i < pkt_num; i++) {
+               info[i].seg = odp_packet_first_seg(info[i].pkt);
+               CU_ASSERT_FATAL(info[i].seg != ODP_PACKET_SEG_INVALID);
+
+               info[i].len = odp_packet_seg_data_len(info[i].pkt, info[i].seg);
+               info[i].ptr = odp_packet_seg_data(info[i].pkt, info[i].seg);
+               CU_ASSERT_FATAL(info[i].len > 0);
+               CU_ASSERT_FATAL(info[i].ptr != NULL);
+       }
+
+       while (pkt_len > 0) {
+               uint32_t min_seg_len = (info[0].len < info[1].len) ?
+                               info[0].len : info[1].len;
+
+               CU_ASSERT_FATAL(!memcmp(info[0].ptr, info[1].ptr, min_seg_len));
+
+               if (pkt_len <= min_seg_len)
+                       return;
+
+               pkt_len -= min_seg_len;
+               for (i = 0; i < pkt_num; i++) {
+                       info[i].len -= min_seg_len;
+                       if (info[i].len != 0) {
+                               info[i].ptr += min_seg_len;
+                               continue;
+                       }
+
+                       info[i].seg = odp_packet_next_seg(info[i].pkt,
+                                                         info[i].seg);
+                       CU_ASSERT_FATAL(info[i].seg != ODP_PACKET_SEG_INVALID);
+
+                       info[i].len = odp_packet_seg_data_len(info[i].pkt,
+                                                             info[i].seg);
+                       info[i].ptr = odp_packet_seg_data(info[i].pkt,
+                                                         info[i].seg);
+                       CU_ASSERT_FATAL(info[i].len > 0);
+                       CU_ASSERT_FATAL(info[i].ptr != NULL);
+               }
+       }
+}
+
+static void packet_copy(void)
+{
+       odp_packet_t pkt = test_packet;
+       odp_packet_t pkt_copy;
+       odp_buffer_pool_t pool;
+
+       /** @todo: fill original packet with some data */
+       pool = odp_packet_pool(pkt);
+       CU_ASSERT_FATAL(pool != ODP_BUFFER_POOL_INVALID);
+       pkt_copy = odp_packet_copy(pkt, odp_packet_pool(pkt));
+       CU_ASSERT_FATAL(pkt_copy != ODP_PACKET_INVALID);
+
+       CU_ASSERT(odp_packet_len(pkt) == odp_packet_len(pkt_copy));
+
+       _packet_compare_inflags(pkt, pkt_copy);
+       _packet_compare_data(pkt, pkt_copy);
+       odp_packet_free(pkt_copy);
+}
+
+static void packet_copydata(void)
+{
+       odp_packet_t pkt = test_packet;
+       uint32_t pkt_len = odp_packet_len(pkt);
+       uint8_t *data_buf;
+       uint32_t i;
+       int correct_memory;
+
+       CU_ASSERT_FATAL(pkt_len > 0);
+
+       data_buf = malloc(pkt_len);
+       CU_ASSERT_FATAL(data_buf != NULL);
+
+       for (i = 0; i < pkt_len; i++)
+               data_buf[i] = (uint8_t)i;
+
+       CU_ASSERT(!odp_packet_copydata_in(pkt, 0, pkt_len, data_buf));
+       memset(data_buf, 0, pkt_len);
+       CU_ASSERT(!odp_packet_copydata_out(pkt, 0, pkt_len, data_buf));
+
+       correct_memory = 1;
+       for (i = 0; i < pkt_len; i++)
+               if (data_buf[i] != (uint8_t)i) {
+                       correct_memory = 0;
+                       break;
+               }
+       CU_ASSERT(correct_memory);
+
+       free(data_buf);
+}
+
+static void packet_offset(void)
+{
+       odp_packet_t pkt = test_packet;
+       uint32_t seg_len, full_seg_len;
+       odp_packet_seg_t seg;
+       uint8_t *ptr, *start_ptr;
+       uint32_t offset;
+
+       ptr = odp_packet_offset(pkt, 0, &seg_len, &seg);
+       CU_ASSERT(seg_len > 1);
+       CU_ASSERT(seg_len == odp_packet_seg_len(pkt));
+       CU_ASSERT(seg_len == odp_packet_seg_data_len(pkt, seg));
+       CU_ASSERT(ptr != NULL);
+       CU_ASSERT(ptr == odp_packet_data(pkt));
+       CU_ASSERT(ptr == odp_packet_seg_data(pkt, seg));
+
+       /* Query a second byte */
+       start_ptr = ptr;
+       full_seg_len = seg_len;
+       offset = 1;
+
+       ptr = odp_packet_offset(pkt, offset, &seg_len, NULL);
+       CU_ASSERT(ptr != NULL);
+       CU_ASSERT(ptr == start_ptr + offset);
+       CU_ASSERT(seg_len == full_seg_len - offset);
+
+       /* Query the last byte in a segment */
+       offset = full_seg_len - 1;
+
+       ptr = odp_packet_offset(pkt, offset, &seg_len, NULL);
+       CU_ASSERT(ptr != NULL);
+       CU_ASSERT(ptr == start_ptr + offset);
+       CU_ASSERT(seg_len == full_seg_len - offset);
+
+       /* Query the last byte in a packet */
+       offset = odp_packet_len(pkt) - 1;
+       ptr = odp_packet_offset(pkt, offset, &seg_len, NULL);
+       CU_ASSERT(ptr != NULL);
+       CU_ASSERT(seg_len == 1);
+
+       /* Pass NULL to [out] arguments */
+       ptr = odp_packet_offset(pkt, 0, NULL, NULL);
+       CU_ASSERT(ptr != NULL);
+}
+
+CU_TestInfo packet_tests[] = {
+       _CU_TEST_INFO(packet_alloc_free),
+       _CU_TEST_INFO(packet_alloc_segmented),
+       _CU_TEST_INFO(packet_basic_metadata),
+       _CU_TEST_INFO(packet_debug),
+       _CU_TEST_INFO(packet_length),
+       _CU_TEST_INFO(packet_headroom),
+       _CU_TEST_INFO(packet_tailroom),
+       _CU_TEST_INFO(packet_context),
+       _CU_TEST_INFO(packet_buffer_conversion),
+       _CU_TEST_INFO(packet_layer_offsets),
+       _CU_TEST_INFO(packet_segments),
+       _CU_TEST_INFO(packet_segment_last),
+       _CU_TEST_INFO(packet_in_flags),
+       _CU_TEST_INFO(packet_out_flags),
+       _CU_TEST_INFO(packet_error_flags),
+       _CU_TEST_INFO(packet_add_rem_data),
+       _CU_TEST_INFO(packet_copy),
+       _CU_TEST_INFO(packet_copydata),
+       _CU_TEST_INFO(packet_offset),
+       CU_TEST_INFO_NULL,
+};
diff --git a/test/validation/odp_buffer.c b/test/validation/odp_buffer.c
index 8aa61a9..1102780 100644
--- a/test/validation/odp_buffer.c
+++ b/test/validation/odp_buffer.c
@@ -15,5 +15,10 @@ CU_SuiteInfo odp_testsuites[] = {
                        .pInitFunc = buffer_testsuite_init,
                        .pCleanupFunc = buffer_testsuite_finalize,
        },
+       { .pName = "packet tests",
+                       .pTests = packet_tests,
+                       .pInitFunc = packet_testsuite_init,
+                       .pCleanupFunc = packet_testsuite_finalize,
+       },
        CU_SUITE_INFO_NULL,
 };
-- 
1.9.1


_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to