diff mbox

[API-NEXT,PATCHv4,6/7] validation: test odp_pktio_start and odp_pktio_stop

Message ID 1440580237-21578-7-git-send-email-maxim.uvarov@linaro.org
State New
Headers show

Commit Message

Maxim Uvarov Aug. 26, 2015, 9:10 a.m. UTC
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
---
 test/validation/pktio/pktio.c | 124 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 124 insertions(+)

Comments

Stuart Haslam Aug. 26, 2015, 12:39 p.m. UTC | #1
On Wed, Aug 26, 2015 at 12:10:36PM +0300, Maxim Uvarov wrote:
> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
> ---
>  test/validation/pktio/pktio.c | 124 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 124 insertions(+)
> 
> diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c
> index ebe34fa..e995de7 100644
> --- a/test/validation/pktio/pktio.c
> +++ b/test/validation/pktio/pktio.c
> @@ -109,6 +109,9 @@ static uint32_t pktio_pkt_seq(odp_packet_t pkt)
>  	pkt_head_t head;
>  	pkt_tail_t tail;
>  
> +	if (pkt == ODP_PACKET_INVALID)
> +		return -1;
> +
>  	off = odp_packet_l4_offset(pkt);
>  	if (off ==  ODP_PACKET_OFFSET_INVALID)
>  		return TEST_SEQ_INVALID;
> @@ -626,6 +629,126 @@ void pktio_test_inq(void)
>  	CU_ASSERT(odp_pktio_close(pktio) == 0);
>  }
>  
> +static void pktio_test_start_stop(void)
> +{
> +	odp_pktio_t pktio[MAX_NUM_IFACES];
> +	odp_packet_t pkt;
> +	odp_event_t tx_ev[1000];
> +	odp_event_t ev;
> +	int i, pkts, ret, alloc = 0;
> +	odp_queue_t outq;
> +
> +	for (i = 0; i < num_ifaces; i++) {
> +		pktio[i] = create_pktio(iface_name[i], ODP_QUEUE_TYPE_SCHED, 0);
> +		CU_ASSERT(pktio[i] != ODP_PKTIO_INVALID);
> +		create_inq(pktio[i],  ODP_QUEUE_TYPE_SCHED);
> +	}
> +
> +	for (alloc = 0; alloc < 1000; alloc++) {
> +		pkt = odp_packet_alloc(default_pkt_pool, packet_len);
> +		if (pkt == ODP_PACKET_INVALID)
> +			break;
> +		pktio_init_packet(pkt);
> +		tx_ev[alloc] = odp_packet_to_event(pkt);
> +	}
> +
> +	outq = odp_pktio_outq_getdef(pktio[0]);
> +
> +	/* stop and check that we can not transmit*/
> +	ret = odp_pktio_stop(pktio[0]);
> +	CU_ASSERT(ret == 0);
> +	odp_errno_zero();
> +	ret = odp_queue_enq_multi(outq, tx_ev, 10);
> +	/* return of enqueue function to stopped pktio undefined.
> +	 *  error might be returned, packets can be queued but not
> +	 * actually sent, no packets queued due to stopped pktio or
> +	 * queue is full.
> +	 * CU_ASSERT(ret == undefined);
> +	 */

We can't invoke undefined behaviour in the test suite, crashing would be
a valid thing for the implementation to do.
Maxim Uvarov Aug. 26, 2015, 1:22 p.m. UTC | #2
On 08/26/15 15:39, Stuart Haslam wrote:
>> +	/* stop and check that we can not transmit*/
>> >+	ret = odp_pktio_stop(pktio[0]);
>> >+	CU_ASSERT(ret == 0);
>> >+	odp_errno_zero();
>> >+	ret = odp_queue_enq_multi(outq, tx_ev, 10);
>> >+	/* return of enqueue function to stopped pktio undefined.
>> >+	 *  error might be returned, packets can be queued but not
>> >+	 * actually sent, no packets queued due to stopped pktio or
>> >+	 * queue is full.
>> >+	 * CU_ASSERT(ret == undefined);
>> >+	 */
> We can't invoke undefined behaviour in the test suite, crashing would be
> a valid thing for the implementation to do.

Ok. But crash where? Some packets might be already in queue and they 
will call pktio send.
So crash in enqueue function will not work due to no reference to pktio. 
Crash inside pktio will
not work due to packets might be in queue. Condition for crash in test 
is also unclear.


Maxim.
Stuart Haslam Aug. 26, 2015, 1:31 p.m. UTC | #3
On Wed, Aug 26, 2015 at 04:22:16PM +0300, Maxim Uvarov wrote:
> On 08/26/15 15:39, Stuart Haslam wrote:
> >>+	/* stop and check that we can not transmit*/
> >>>+	ret = odp_pktio_stop(pktio[0]);
> >>>+	CU_ASSERT(ret == 0);
> >>>+	odp_errno_zero();
> >>>+	ret = odp_queue_enq_multi(outq, tx_ev, 10);
> >>>+	/* return of enqueue function to stopped pktio undefined.
> >>>+	 *  error might be returned, packets can be queued but not
> >>>+	 * actually sent, no packets queued due to stopped pktio or
> >>>+	 * queue is full.
> >>>+	 * CU_ASSERT(ret == undefined);
> >>>+	 */
> >We can't invoke undefined behaviour in the test suite, crashing would be
> >a valid thing for the implementation to do.
> 
> Ok. But crash where? Some packets might be already in queue and they
> will call pktio send.
> So crash in enqueue function will not work due to no reference to
> pktio. Crash inside pktio will
> not work due to packets might be in queue. Condition for crash in
> test is also unclear.
> 

It's undefined, but for example you could replace the current check and
return -1 in the linux-generic implementation with an ODP_ASSERT().
diff mbox

Patch

diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c
index ebe34fa..e995de7 100644
--- a/test/validation/pktio/pktio.c
+++ b/test/validation/pktio/pktio.c
@@ -109,6 +109,9 @@  static uint32_t pktio_pkt_seq(odp_packet_t pkt)
 	pkt_head_t head;
 	pkt_tail_t tail;
 
+	if (pkt == ODP_PACKET_INVALID)
+		return -1;
+
 	off = odp_packet_l4_offset(pkt);
 	if (off ==  ODP_PACKET_OFFSET_INVALID)
 		return TEST_SEQ_INVALID;
@@ -626,6 +629,126 @@  void pktio_test_inq(void)
 	CU_ASSERT(odp_pktio_close(pktio) == 0);
 }
 
+static void pktio_test_start_stop(void)
+{
+	odp_pktio_t pktio[MAX_NUM_IFACES];
+	odp_packet_t pkt;
+	odp_event_t tx_ev[1000];
+	odp_event_t ev;
+	int i, pkts, ret, alloc = 0;
+	odp_queue_t outq;
+
+	for (i = 0; i < num_ifaces; i++) {
+		pktio[i] = create_pktio(iface_name[i], ODP_QUEUE_TYPE_SCHED, 0);
+		CU_ASSERT(pktio[i] != ODP_PKTIO_INVALID);
+		create_inq(pktio[i],  ODP_QUEUE_TYPE_SCHED);
+	}
+
+	for (alloc = 0; alloc < 1000; alloc++) {
+		pkt = odp_packet_alloc(default_pkt_pool, packet_len);
+		if (pkt == ODP_PACKET_INVALID)
+			break;
+		pktio_init_packet(pkt);
+		tx_ev[alloc] = odp_packet_to_event(pkt);
+	}
+
+	outq = odp_pktio_outq_getdef(pktio[0]);
+
+	/* stop and check that we can not transmit*/
+	ret = odp_pktio_stop(pktio[0]);
+	CU_ASSERT(ret == 0);
+	odp_errno_zero();
+	ret = odp_queue_enq_multi(outq, tx_ev, 10);
+	/* return of enqueue function to stopped pktio undefined.
+	 *  error might be returned, packets can be queued but not
+	 * actually sent, no packets queued due to stopped pktio or
+	 * queue is full.
+	 * CU_ASSERT(ret == undefined);
+	 */
+
+	/* start first and queue packets */
+	ret = odp_pktio_start(pktio[0]);
+	CU_ASSERT(ret == 0);
+	/* stop second and send packets*/
+	if (num_ifaces > 1) {
+		ret = odp_pktio_stop(pktio[1]);
+		CU_ASSERT(ret == 0);
+	}
+	for (pkts = 0; pkts != alloc; ) {
+		ret = odp_queue_enq_multi(outq, &tx_ev[pkts], alloc - pkts);
+		if (ret < 0) {
+			CU_FAIL("unable to enqueue packet\n");
+			break;
+		}
+		pkts += ret;
+	}
+	/* check that packets did not arrive */
+	for (i = 0, pkts = 0; i < 1000; i++) {
+		ev = odp_schedule(NULL, ODP_TIME_MSEC);
+		if (ev != ODP_EVENT_INVALID) {
+			if (odp_event_type(ev) == ODP_EVENT_PACKET) {
+				if (pktio_pkt_seq(pkt) != TEST_SEQ_INVALID)
+					pkts++;
+			}
+			odp_event_free(ev);
+		}
+	}
+	if (pkts)
+		CU_FAIL("pktio stopped, received unexpected events");
+
+	/* start both, send and get packets */
+	/* 0 already started */
+	if (num_ifaces > 1) {
+		ret = odp_pktio_start(pktio[1]);
+		CU_ASSERT(ret == 0);
+	}
+
+	/* flush packets with magic number in pipes */
+	for (i = 0; i < 1000; i++) {
+		ev = odp_schedule(NULL, ODP_TIME_MSEC);
+		if (ev != ODP_EVENT_INVALID)
+			odp_event_free(ev);
+	}
+
+	/* alloc */
+	for (alloc = 0; alloc < 1000; alloc++) {
+		pkt = odp_packet_alloc(default_pkt_pool, packet_len);
+		if (pkt == ODP_PACKET_INVALID)
+			break;
+		pktio_init_packet(pkt);
+		tx_ev[alloc] = odp_packet_to_event(pkt);
+	}
+
+	/* send */
+	for (pkts = 0; pkts != alloc; ) {
+		ret = odp_queue_enq_multi(outq, &tx_ev[pkts], alloc - pkts);
+		if (ret < 0) {
+			CU_FAIL("unable to enqueue packet\n");
+			break;
+		}
+		pkts += ret;
+	}
+
+	/* get */
+	for (i = 0, pkts = 0; i < 1000; i++) {
+		ev = odp_schedule(NULL, ODP_TIME_MSEC);
+		if (ev != ODP_EVENT_INVALID) {
+			if (odp_event_type(ev) == ODP_EVENT_PACKET) {
+				pkt = odp_packet_from_event(ev);
+				if (pktio_pkt_seq(pkt) != TEST_SEQ_INVALID)
+					pkts++;
+			}
+			odp_event_free(ev);
+		}
+	}
+	CU_ASSERT(pkts == alloc);
+
+	for (i = 0; i < num_ifaces; i++) {
+		destroy_inq(pktio[i]);
+		CU_ASSERT(odp_pktio_close(pktio[i]) == 0);
+	}
+}
+
 static int create_pool(const char *iface, int num)
 {
 	char pool_name[ODP_POOL_NAME_LEN];
@@ -722,6 +845,7 @@  CU_TestInfo pktio_suite[] = {
 	{"pktio promisc mode",	pktio_test_promisc},
 	{"pktio mac",		pktio_test_mac},
 	{"pktio inq_remdef",	pktio_test_inq_remdef},
+	{"pktio start stop",	pktio_test_start_stop},
 	CU_TEST_INFO_NULL
 };