@@ -1878,6 +1878,290 @@ void packet_test_offset(void)
CU_ASSERT_PTR_NOT_NULL(ptr);
}
+void packet_test_ref(void)
+{
+ odp_packet_t base_pkt, segmented_base_pkt, hdr_pkt[4],
+ ref_pkt[4], refhdr_pkt[4], hdr_cpy;
+ uint32_t pkt_len, segmented_pkt_len, hdr_len[4], offset[4], hr[4],
+ base_hr, ref_len[4];
+ int i;
+
+ base_pkt = odp_packet_copy(test_packet, odp_packet_pool(test_packet));
+ base_hr = odp_packet_headroom(base_pkt);
+ pkt_len = odp_packet_len(test_packet);
+ CU_ASSERT_FATAL(base_pkt != ODP_PACKET_INVALID);
+
+ segmented_base_pkt =
+ odp_packet_copy(segmented_test_packet,
+ odp_packet_pool(segmented_test_packet));
+ segmented_pkt_len = odp_packet_len(segmented_test_packet);
+ CU_ASSERT_FATAL(segmented_base_pkt != ODP_PACKET_INVALID);
+
+ CU_ASSERT(odp_packet_is_ref(base_pkt) == 0);
+ CU_ASSERT(odp_packet_has_ref(base_pkt) == 0);
+
+ hdr_pkt[0] =
+ odp_packet_copy_part(segmented_test_packet, 0,
+ odp_packet_len(segmented_test_packet) / 4,
+ odp_packet_pool(segmented_test_packet));
+ CU_ASSERT_FATAL(hdr_pkt[0] != ODP_PACKET_INVALID);
+ hdr_len[0] = odp_packet_len(hdr_pkt[0]);
+ offset[0] = 0;
+
+ hdr_pkt[1] =
+ odp_packet_copy_part(segmented_test_packet, 10,
+ odp_packet_len(segmented_test_packet) / 8,
+ odp_packet_pool(segmented_test_packet));
+ CU_ASSERT_FATAL(hdr_pkt[1] != ODP_PACKET_INVALID);
+ hdr_len[1] = odp_packet_len(hdr_pkt[1]);
+ offset[1] = 5;
+
+ hdr_pkt[2] = odp_packet_copy_part(test_packet, 0,
+ odp_packet_len(test_packet) / 4,
+ odp_packet_pool(test_packet));
+ CU_ASSERT_FATAL(hdr_pkt[2] != ODP_PACKET_INVALID);
+ hdr_len[2] = odp_packet_len(hdr_pkt[2]);
+ offset[2] = 64;
+
+ hdr_pkt[3] = odp_packet_copy_part(test_packet, 0,
+ odp_packet_len(test_packet) / 4,
+ odp_packet_pool(test_packet));
+ CU_ASSERT_FATAL(hdr_pkt[3] != ODP_PACKET_INVALID);
+ hdr_len[3] = odp_packet_len(hdr_pkt[3]);
+ offset[3] = 64;
+
+ /* Nothing is a ref or has a ref before we start */
+ for (i = 0; i < 4; i++) {
+ CU_ASSERT(odp_packet_is_ref(hdr_pkt[i]) == 0);
+ CU_ASSERT(odp_packet_has_ref(hdr_pkt[i]) == 0);
+ CU_ASSERT(odp_packet_len(hdr_pkt[i]) ==
+ odp_packet_unshared_len(hdr_pkt[i]));
+ }
+
+ /* Attempt an invalid ref */
+ refhdr_pkt[0] = odp_packet_ref_pkt(base_pkt, pkt_len, hdr_pkt[0]);
+ CU_ASSERT(refhdr_pkt[0] == ODP_PACKET_INVALID);
+ CU_ASSERT(odp_packet_is_ref(hdr_pkt[0]) == 0);
+ CU_ASSERT(odp_packet_is_ref(base_pkt) == 0);
+ CU_ASSERT(odp_packet_has_ref(hdr_pkt[0]) == 0);
+ CU_ASSERT(odp_packet_has_ref(base_pkt) == 0);
+
+ /* We can't ref to ourselves */
+ refhdr_pkt[0] = odp_packet_ref_pkt(hdr_pkt[0], 0, hdr_pkt[0]);
+ CU_ASSERT(refhdr_pkt[0] == ODP_PACKET_INVALID);
+ CU_ASSERT(odp_packet_is_ref(hdr_pkt[0]) == 0);
+ CU_ASSERT(odp_packet_has_ref(hdr_pkt[0]) == 0);
+
+ /* Now create a couple of valid refs */
+ refhdr_pkt[0] = odp_packet_ref_pkt(base_pkt, offset[0], hdr_pkt[0]);
+ refhdr_pkt[1] = odp_packet_ref_pkt(base_pkt, offset[1], hdr_pkt[1]);
+
+ CU_ASSERT(refhdr_pkt[0] != ODP_PACKET_INVALID);
+ CU_ASSERT(refhdr_pkt[1] != ODP_PACKET_INVALID);
+
+ CU_ASSERT(odp_packet_is_ref(refhdr_pkt[0]) == 1);
+ CU_ASSERT(odp_packet_is_ref(refhdr_pkt[1]) == 1);
+ CU_ASSERT(odp_packet_is_ref(base_pkt) == 0);
+
+ CU_ASSERT(odp_packet_has_ref(base_pkt) == 2);
+ CU_ASSERT(odp_packet_has_ref(refhdr_pkt[0]) == 0);
+ CU_ASSERT(odp_packet_has_ref(refhdr_pkt[1]) == 0);
+
+ /* Verify ref lengths and contents */
+ CU_ASSERT(odp_packet_unshared_len(base_pkt) == 0);
+
+ CU_ASSERT(odp_packet_len(refhdr_pkt[0]) ==
+ hdr_len[0] + pkt_len - offset[0]);
+ CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[0]) == hdr_len[0]);
+ CU_ASSERT(odp_packet_len(refhdr_pkt[1]) ==
+ hdr_len[1] + pkt_len - offset[1]);
+ CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[1]) == hdr_len[1]);
+
+ _packet_compare_offset(refhdr_pkt[0], hdr_len[0],
+ base_pkt, offset[0],
+ pkt_len - offset[0]);
+
+ _packet_compare_offset(refhdr_pkt[1], hdr_len[1],
+ base_pkt, offset[1],
+ pkt_len - offset[1]);
+
+ /* See if compound references are supported and if so that they
+ * operate properly */
+ hdr_cpy = odp_packet_copy(hdr_pkt[2], odp_packet_pool(hdr_pkt[2]));
+ if (hdr_cpy == ODP_PACKET_INVALID)
+ refhdr_pkt[2] = ODP_PACKET_INVALID;
+ else
+ refhdr_pkt[2] = odp_packet_ref_pkt(refhdr_pkt[0], 2, hdr_cpy);
+
+ if (refhdr_pkt[2] != ODP_PACKET_INVALID) {
+ CU_ASSERT(odp_packet_has_ref(base_pkt) == 3);
+ CU_ASSERT(odp_packet_is_ref(refhdr_pkt[2]) == 2);
+ CU_ASSERT(odp_packet_has_ref(refhdr_pkt[2]) == 0);
+ CU_ASSERT(odp_packet_is_ref(refhdr_pkt[0]) == 1);
+ CU_ASSERT(odp_packet_has_ref(refhdr_pkt[0]) == 1);
+ CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[2]) == hdr_len[2]);
+ CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[0]) == 2);
+
+ /* Free the compound ref and verify we're back to simple ref */
+ odp_packet_free(refhdr_pkt[2]);
+ CU_ASSERT(odp_packet_has_ref(base_pkt) == 2);
+ CU_ASSERT(odp_packet_is_ref(refhdr_pkt[0]) == 1);
+ CU_ASSERT(odp_packet_has_ref(refhdr_pkt[0]) == 0);
+ CU_ASSERT(odp_packet_unshared_len(refhdr_pkt[0]) == hdr_len[0]);
+ }
+
+ /* Delete the refs */
+ odp_packet_free(refhdr_pkt[0]);
+ odp_packet_free(refhdr_pkt[1]);
+
+ /* Verify that base_pkt no longer has a ref */
+ CU_ASSERT(odp_packet_is_ref(base_pkt) == 0);
+ CU_ASSERT(odp_packet_has_ref(base_pkt) == 0);
+
+ /* Now create a two more shared refs */
+ refhdr_pkt[2] = odp_packet_ref_pkt(base_pkt, offset[2], hdr_pkt[2]);
+ refhdr_pkt[3] = odp_packet_ref_pkt(base_pkt, offset[3], hdr_pkt[3]);
+
+ CU_ASSERT(hdr_pkt[2] != ODP_PACKET_INVALID);
+ CU_ASSERT(hdr_pkt[3] != ODP_PACKET_INVALID);
+ CU_ASSERT(odp_packet_is_ref(refhdr_pkt[2]) == 1);
+ CU_ASSERT(odp_packet_is_ref(refhdr_pkt[3]) == 1);
+ CU_ASSERT(odp_packet_has_ref(base_pkt) == 2);
+
+ CU_ASSERT(odp_packet_len(refhdr_pkt[2]) ==
+ odp_packet_len(refhdr_pkt[3]));
+
+ _packet_compare_offset(refhdr_pkt[2], 0,
+ refhdr_pkt[3], 0,
+ odp_packet_len(hdr_pkt[2]));
+
+ /* Delete the headers */
+ odp_packet_free(refhdr_pkt[2]);
+ odp_packet_free(refhdr_pkt[3]);
+
+ /* Verify that base_pkt is no longer ref'd */
+ CU_ASSERT(odp_packet_is_ref(base_pkt) == 0);
+ CU_ASSERT(odp_packet_has_ref(base_pkt) == 0);
+
+ /* Create a static reference */
+ ref_pkt[0] = odp_packet_ref_static(base_pkt);
+ CU_ASSERT(ref_pkt[0] != ODP_PACKET_INVALID);
+ CU_ASSERT(odp_packet_has_ref(base_pkt) > 0);
+ CU_ASSERT(odp_packet_len(ref_pkt[0]) == odp_packet_len(base_pkt));
+ _packet_compare_offset(ref_pkt[0], 0, base_pkt, 0,
+ odp_packet_len(base_pkt));
+
+ /* Now delete it */
+ odp_packet_free(ref_pkt[0]);
+ CU_ASSERT(odp_packet_has_ref(base_pkt) == 0);
+
+ /* Create an invalid basic reference */
+ ref_pkt[0] = odp_packet_ref(segmented_base_pkt, segmented_pkt_len);
+ CU_ASSERT(ref_pkt[0] == ODP_PACKET_INVALID);
+ CU_ASSERT(odp_packet_is_ref(segmented_base_pkt) == 0);
+ CU_ASSERT(odp_packet_has_ref(segmented_base_pkt) == 0);
+
+ /* Now create valid references */
+ ref_pkt[0] = odp_packet_ref(segmented_base_pkt, offset[0]);
+ CU_ASSERT(odp_packet_is_ref(ref_pkt[0]) == 1);
+ CU_ASSERT(odp_packet_is_ref(segmented_base_pkt) == 0);
+ CU_ASSERT(odp_packet_has_ref(segmented_base_pkt) == 1);
+
+ ref_pkt[1] = odp_packet_ref(segmented_base_pkt, offset[1]);
+ CU_ASSERT(odp_packet_is_ref(ref_pkt[1]) == 1);
+ CU_ASSERT(odp_packet_is_ref(segmented_base_pkt) == 0);
+ CU_ASSERT(odp_packet_has_ref(ref_pkt[1]) == 0);
+ CU_ASSERT(odp_packet_has_ref(segmented_base_pkt) == 2);
+
+ /* Verify reference lengths */
+ CU_ASSERT(odp_packet_len(ref_pkt[0]) == segmented_pkt_len - offset[0]);
+ CU_ASSERT(odp_packet_len(ref_pkt[1]) == segmented_pkt_len - offset[1]);
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0);
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0);
+
+ /* Free the base pkts -- references should still be valid */
+ odp_packet_free(base_pkt);
+ odp_packet_free(segmented_base_pkt);
+
+ CU_ASSERT(odp_packet_is_ref(ref_pkt[0]) == 1);
+ CU_ASSERT(odp_packet_is_ref(ref_pkt[1]) == 1);
+
+ _packet_compare_offset(ref_pkt[0], 0,
+ segmented_test_packet, offset[0],
+ segmented_pkt_len - offset[0]);
+ _packet_compare_offset(ref_pkt[1], 0,
+ segmented_test_packet, offset[1],
+ segmented_pkt_len - offset[1]);
+
+ /* Verify we can modify the refs */
+ hr[0] = odp_packet_headroom(ref_pkt[0]);
+ hr[1] = odp_packet_headroom(ref_pkt[1]);
+
+ CU_ASSERT(odp_packet_push_head(ref_pkt[0], hr[0]) != NULL);
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == hr[0]);
+ CU_ASSERT(odp_packet_len(ref_pkt[0]) ==
+ hr[0] + segmented_pkt_len - offset[0]);
+
+ CU_ASSERT(odp_packet_pull_head(ref_pkt[0], hr[0] / 2) != NULL);
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == hr[0] - (hr[0] / 2));
+
+ if (hr[1] > 0) {
+ CU_ASSERT(odp_packet_push_head(ref_pkt[1], 1) != NULL);
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 1);
+ CU_ASSERT(odp_packet_len(ref_pkt[1]) ==
+ 1 + segmented_pkt_len - offset[1]);
+ CU_ASSERT(odp_packet_pull_head(ref_pkt[1], 1) != NULL);
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0);
+ CU_ASSERT(odp_packet_len(ref_pkt[1]) ==
+ segmented_pkt_len - offset[1]);
+ }
+
+ odp_packet_free(ref_pkt[0]);
+ odp_packet_free(ref_pkt[1]);
+
+ /* Verify we can modify base packet after reference is created */
+ base_pkt = odp_packet_copy(test_packet, odp_packet_pool(test_packet));
+
+ ref_pkt[1] = odp_packet_ref(base_pkt, offset[1]);
+ CU_ASSERT_FATAL(ref_pkt[1] != ODP_PACKET_INVALID);
+ ref_len[1] = odp_packet_len(ref_pkt[1]);
+ CU_ASSERT(ref_len[1] == odp_packet_len(base_pkt) - offset[1]);
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0);
+
+ CU_ASSERT(odp_packet_push_head(base_pkt, base_hr / 2) != NULL);
+ CU_ASSERT(odp_packet_unshared_len(base_pkt) == base_hr / 2 + offset[1]);
+ CU_ASSERT(odp_packet_len(ref_pkt[1]) == ref_len[1]);
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0);
+
+ ref_pkt[0] = odp_packet_ref(base_pkt, offset[0]);
+ CU_ASSERT_FATAL(ref_pkt[0] != ODP_PACKET_INVALID);
+ ref_len[0] = odp_packet_len(ref_pkt[0]);
+ CU_ASSERT(ref_len[0] = odp_packet_len(base_pkt) - offset[0]);
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0);
+
+ CU_ASSERT(odp_packet_push_head(base_pkt,
+ base_hr - base_hr / 2) != NULL);
+ CU_ASSERT(odp_packet_unshared_len(base_pkt) ==
+ base_hr - base_hr / 2 + offset[0]);
+ CU_ASSERT(odp_packet_len(ref_pkt[1]) == ref_len[1]);
+ CU_ASSERT(odp_packet_len(ref_pkt[0]) == ref_len[0]);
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == 0);
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == 0);
+
+ hr[0] = odp_packet_headroom(ref_pkt[0]);
+ hr[1] = odp_packet_headroom(ref_pkt[1]);
+ CU_ASSERT(odp_packet_push_head(ref_pkt[0], hr[0]) != NULL);
+ CU_ASSERT(odp_packet_push_head(ref_pkt[1], hr[1]) != NULL);
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[0]) == hr[0]);
+ CU_ASSERT(odp_packet_unshared_len(ref_pkt[1]) == hr[1]);
+ CU_ASSERT(odp_packet_unshared_len(base_pkt) ==
+ base_hr - base_hr / 2 + offset[0]);
+
+ odp_packet_free(base_pkt);
+ odp_packet_free(ref_pkt[0]);
+ odp_packet_free(ref_pkt[1]);
+}
+
odp_testinfo_t packet_suite[] = {
ODP_TEST_INFO(packet_test_alloc_free),
ODP_TEST_INFO(packet_test_alloc_free_multi),
@@ -1906,6 +2190,7 @@ odp_testinfo_t packet_suite[] = {
ODP_TEST_INFO(packet_test_extend_mix),
ODP_TEST_INFO(packet_test_align),
ODP_TEST_INFO(packet_test_offset),
+ ODP_TEST_INFO(packet_test_ref),
ODP_TEST_INFO_NULL,
};
@@ -37,6 +37,7 @@ void packet_test_extend_large(void);
void packet_test_extend_mix(void);
void packet_test_align(void);
void packet_test_offset(void);
+void packet_test_ref(void);
/* test arrays: */
extern odp_testinfo_t packet_suite[];
Add validation tests for the new packet reference APIs: - odp_packet_ref_static() - odp_packet_ref() - odp_packet_ref_pkt() - odp_packet_is_ref() - odp_packet_has_ref() - odp_packet_unshared_len() Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org> --- test/common_plat/validation/api/packet/packet.c | 285 ++++++++++++++++++++++++ test/common_plat/validation/api/packet/packet.h | 1 + 2 files changed, 286 insertions(+) -- 2.7.4