On 2016-08-08 09:59, Maxim Uvarov wrote:
> Hello Anders,
> 
> thanks for review, there are 2 comments bellow. Will send v2.
> 
> Maxim.
> 
> On 08/06/16 22:30, Anders Roxell wrote:
> >On 2016-08-02 19:08, Maxim Uvarov wrote:
> >>add pcap play back test which takes 2 arguments: 1 - pcap file,
> >>2 - packet mask to match. Intend is to test odp with different
> >>input traffic to check internal implementation functions. In
> >>current case it's test for vlan tag instertion for packet mmap:
> >>pkt_mmap_vlan_insert().
> >>
> >>Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org>
> >>---
> >>  v2: up the patch, dirrect execution looks like works.
> >>
> >>  test/linux-generic/.gitignore       |   1 +
> >>  test/linux-generic/Makefile.am      |  10 +-
> >>  test/linux-generic/cls/.gitignore   |   3 +
> >>  test/linux-generic/cls/Makefile.am  |  13 ++
> >>  test/linux-generic/cls/cls.c        | 349 
> >> ++++++++++++++++++++++++++++++++++++
> >>  test/linux-generic/cls/cls_main.c   |  12 ++
> >>  test/linux-generic/cls/cls_suites.h |   1 +
> >>  test/linux-generic/cls/vlan.pcap    | Bin 0 -> 9728 bytes
> >>  test/linux-generic/cls/vlan_run.sh  |  49 +++++
> >>  test/linux-generic/m4/configure.m4  |   1 +
> >>  10 files changed, 435 insertions(+), 4 deletions(-)
> >>  create mode 100644 test/linux-generic/cls/.gitignore
> >>  create mode 100644 test/linux-generic/cls/Makefile.am
> >>  create mode 100644 test/linux-generic/cls/cls.c
> >>  create mode 100644 test/linux-generic/cls/cls_main.c
> >>  create mode 100644 test/linux-generic/cls/cls_suites.h
> >>  create mode 100644 test/linux-generic/cls/vlan.pcap
> >>  create mode 100755 test/linux-generic/cls/vlan_run.sh
> >>
> >>diff --git a/test/linux-generic/.gitignore b/test/linux-generic/.gitignore
> >>index 5dabf91..f65c7c1 100644
> >>--- a/test/linux-generic/.gitignore
> >>+++ b/test/linux-generic/.gitignore
> >>@@ -1,3 +1,4 @@
> >>  *.log
> >>  *.trs
> >>  tests-validation.env
> >>+test_out.pcap
> >>diff --git a/test/linux-generic/Makefile.am b/test/linux-generic/Makefile.am
> >>index f5cc52d..9acbab0 100644
> >>--- a/test/linux-generic/Makefile.am
> >>+++ b/test/linux-generic/Makefile.am
> >>@@ -1,5 +1,8 @@
> >>  include $(top_srcdir)/test/Makefile.inc
> >>  TESTS_ENVIRONMENT += TEST_DIR=${top_builddir}/test/common_plat/validation
> >>+TEST_EXTENSIONS = .sh
> >>+
> >>+dist_check_SCRIPTS = run-test tests-validation.env $(LOG_COMPILER)
> >>  ALL_API_VALIDATION_DIR = ${top_builddir}/test/common_plat/validation/api
> >>@@ -37,11 +40,14 @@ TESTS = validation/api/pktio/pktio_run.sh \
> >>  SUBDIRS += validation/api/pktio\
> >>       validation/api/shmem\
> >>+      cls\
> >>       pktio_ipc\
> >>       ring
> >>  if HAVE_PCAP
> >>  TESTS += validation/api/pktio/pktio_run_pcap.sh
> >>+TESTS += cls/vlan_run.sh
> >>+dist_check_SCRIPTS += cls/vlan_run.sh cls/vlan.pcap
> >>  endif
> >>  if netmap_support
> >>  TESTS += validation/api/pktio/pktio_run_netmap.sh
> >>@@ -61,10 +67,6 @@ SUBDIRS += validation/api/pktio
> >>  endif
> >>  endif
> >>-TEST_EXTENSIONS = .sh
> >>-
> >>-dist_check_SCRIPTS = run-test tests-validation.env $(LOG_COMPILER)
> >>-
> >>  test_SCRIPTS = $(dist_check_SCRIPTS)
> >>  tests-validation.env:
> >>diff --git a/test/linux-generic/cls/.gitignore 
> >>b/test/linux-generic/cls/.gitignore
> >>new file mode 100644
> >>index 0000000..9447625
> >>--- /dev/null
> >>+++ b/test/linux-generic/cls/.gitignore
> >>@@ -0,0 +1,3 @@
> >>+cls_main
> >>+*.log
> >>+*.trs
> >log and trs shouldn't be needed here, since its in
> >test/linux-generic/.gitignore.
> >
> >This isn't done in a common way anywhere... Maybe we need to look into
> >it?
> >
> >>diff --git a/test/linux-generic/cls/Makefile.am 
> >>b/test/linux-generic/cls/Makefile.am
> >>new file mode 100644
> >>index 0000000..43fb0bc
> >>--- /dev/null
> >>+++ b/test/linux-generic/cls/Makefile.am
> >>@@ -0,0 +1,13 @@
> >>+include ../Makefile.inc
> >>+
> >>+noinst_LTLIBRARIES = libtestcls.la
> >Why do we need to create a library?
> 
> we do it everywhere, I just follow existence Makefiles. As Christophe
> explained me it's because all tests
> will be combined to one library and later be executed.

OK.

> 
> >>+libtestcls_la_SOURCES = cls.c
> >>+libtestcls_la_CFLAGS = $(AM_CFLAGS) $(INCCUNIT_COMMON) $(INCODP)
> >>+
> >>+test_PROGRAMS = cls_main$(EXEEXT)
> >>+dist_cls_main_SOURCES = cls_main.c
> >>+
> >>+cls_main_LDFLAGS = $(AM_LDFLAGS)
> >>+cls_main_LDADD = libtestcls.la $(LIBCUNIT_COMMON) $(LIBODP)
> >>+
> >>+noinst_HEADERS = cls_suites.h
> >>diff --git a/test/linux-generic/cls/cls.c b/test/linux-generic/cls/cls.c
> >>new file mode 100644
> >>index 0000000..d527ec8
> >>--- /dev/null
> >>+++ b/test/linux-generic/cls/cls.c
> >>@@ -0,0 +1,349 @@
> >>+/* Copyright (c) 2016, Linaro Limited
> >>+ * All rights reserved.
> >>+ *
> >>+ * SPDX-License-Identifier:     BSD-3-Clause
> >>+ */
> >>+
> >>+#include <stdlib.h>
> >>+#include <string.h>
> >>+#include <getopt.h>
> >>+#include <unistd.h>
> >>+#include <inttypes.h>
> >>+
> >>+#include <test_debug.h>
> >>+
> >>+#include <odp_api.h>
> >>+#include <odp/helper/linux.h>
> >>+#include <odp/helper/eth.h>
> >>+#include <odp/helper/ip.h>
> >>+
> >>+#include <odp_packet_internal.h>
> >why do we include an internal header file?
> >
> 
> because we need access to classifier bits, that is why this test is under
> linux-generic.

OK, but do we really have to fiddle with internal classifier bits?

> 
> >>+
> >>+#include "cls_suites.h"
> >>+
> >>+/** Get rid of path in filename - only for unix-type paths using '/' */
> >>+#define NO_PATH(file_name) (strrchr((file_name), '/') ? \
> >>+                       strrchr((file_name), '/') + 1 : (file_name))
> >Maybe its enough basename?
> >http://linux.die.net/man/3/basename
> 
> yes, but again this define in almost each our test file.

Oh, I missed that.

> Probably separate
> patch to change all NO_PATH
> to basename().

OK.

> 
> >>+
> >>+/**
> >>+ * Print usage information
> >>+ */
> >>+static void usage(char *progname)
> >>+{
> >>+   printf("\n"
> >>+          "This is test application to verify that linux-generic 
> >>classifier\n"
> >>+          "correctly classifies packets on input. Main intend is add more 
> >>code\n"
> >>+          "coverage for internal functions playing different traffic 
> >>recorded to\n"
> >>+          "pcap files."
> >>+          "\n"
> >>+          "Usage: %s OPTIONS\n"
> >>+          "  E.g. %s -i pcap_file -e expected_bitmask\n"
> >Maybe expected_pkt_bitmask ?
> 
> I don't mind, if you think it's better will change in v2.

Do as you please.


Cheers,
Anders

> 
> >>+          "\n"
> >>+          "Mandatory OPTIONS:\n"
> >>+          "  -i, pcap file name\n"
> >>+          "  -e, expected packet bitmask\n"
> >>+          "\n", NO_PATH(progname), NO_PATH(progname)
> >>+       );
> >>+}
> >>+
> >>+/** @def SHM_PKT_POOL_SIZE
> >>+ * @brief Size of the shared memory block
> >>+ */
> >>+#define SHM_PKT_POOL_SIZE      512
> >>+
> >>+/** @def SHM_PKT_POOL_BUF_SIZE
> >>+ * @brief Buffer size of the packet pool buffer
> >>+ */
> >>+#define SHM_PKT_POOL_BUF_SIZE  1856
> >>+
> >>+/**
> >>+ * Parsed command line application arguments
> >>+ */
> >>+typedef struct {
> >>+   char *file_name;     /**< File name for pcap pktio */
> >>+   odp_pktio_t pktio;  /**< Pktio dev */
> >>+   input_flags_t expected_bits; /**< Expected bits from test run */
> >>+} appl_args_t;
> >>+
> >>+/**
> >>+ * Grouping of both parsed CL args and thread specific args - alloc 
> >>together
> >>+ */
> >>+typedef struct {
> >>+   /** Application (parsed) arguments */
> >>+   appl_args_t appl;
> >>+} args_t;
> >>+
> >>+/** Global pointer to args */
> >>+static args_t *args;
> >>+/** Fill this bit struct to check which packet fields were classified */
> >>+static input_flags_t packet_flags;
> >>+
> >>+/**
> >>+ * Parse and store the command line arguments
> >>+ *
> >>+ * @param argc       argument count
> >>+ * @param argv[]     argument vector
> >>+ * @param appl_args  Store application arguments here
> >>+ */
> >>+static void parse_args(int argc, char *argv[], appl_args_t *appl_args)
> >>+{
> >>+   int opt;
> >>+   int long_index;
> >>+   static const struct option longopts[] = {
> >>+           {"interface", required_argument, NULL, 'i'},    /* return 'i' */
> >>+           {"extected", required_argument, NULL, 'e'},     /* return 'e' */
> >>+           {"help", no_argument, NULL, 'h'},               /* return 'h' */
> >>+           {NULL, 0, NULL, 0}
> >>+   };
> >>+
> >>+   static const char *shortopts = ":i:e:h";
> >>+
> >>+   /* let helper collect its own arguments (e.g. --odph_proc) */
> >>+   odph_parse_options(argc, argv, shortopts, longopts);
> >>+
> >>+   appl_args->file_name = NULL;
> >>+   opterr = 0; /* do not issue errors on helper options */
> >>+   appl_args->expected_bits.all = 0;
> >>+
> >>+   while (1) {
> >>+           opt = getopt_long(argc, argv, shortopts, longopts, &long_index);
> >>+
> >>+           if (opt == -1)
> >>+                   break;  /* No more options */
> >>+
> >>+           switch (opt) {
> >>+           case 'i':
> >>+                   appl_args->file_name =  optarg;
> >>+                   break;
> >>+           case 'e':
> >>+                   appl_args->expected_bits.all = atoll(optarg);
> >>+                   break;
> >>+
> >>+           case 'h':
> >>+                   usage(argv[0]);
> >>+                   exit(EXIT_SUCCESS);
> >>+                   break;
> >>+           default:
> >>+                   break;
> >>+           }
> >>+   }
> >>+
> >>+   if (!appl_args->file_name) {
> >>+           usage(argv[0]);
> >>+           exit(EXIT_SUCCESS);
> >>+   }
> >>+
> >>+   optind = 1;             /* reset 'extern optind' from the getopt lib */
> >>+}
> >>+
> >>+/**
> >>+ * Create a pktio handle, optionally associating a default input queue.
> >>+ *
> >>+ * @param dev Name of device to open
> >>+ * @param pool Pool to associate with device for packet RX/TX
> >>+ * @param mode Packet processing mode for this device (BURST or QUEUE)
> >>+ *
> >>+ * @return The handle of the created pktio object.
> >>+ * @retval ODP_PKTIO_INVALID if the create fails.
> >>+ */
> >The doxygen text match the function definition.
> >
> >>+static odp_pktio_t create_pktio(const char *fname, odp_pool_t pool)
> >>+{
> >>+   odp_pktio_t pktio;
> >>+   int ret;
> >>+   odp_pktio_param_t pktio_param;
> >>+   odp_pktin_queue_param_t pktin_param;
> >>+   char dev[255];
> >>+
> >>+   odp_pktio_param_init(&pktio_param);
> >>+   pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
> >>+
> >>+   memset(dev, 0, 255);
> >>+   sprintf(dev, "pcap:in=%s:out=test_out.pcap",  fname);
> >>+
> >>+   /* Open a packet IO instance */
> >>+   pktio = odp_pktio_open(dev, pool, &pktio_param);
> >>+   if (pktio == ODP_PKTIO_INVALID)
> >>+           LOG_ABORT("Error: pktio create failed for %s\n", dev);
> >>+
> >>+   odp_pktin_queue_param_init(&pktin_param);
> >>+
> >>+   pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC;
> >>+
> >>+   if (odp_pktin_queue_config(pktio, &pktin_param))
> >>+           LOG_ABORT("Error: pktin config failed for %s\n", dev);
> >>+
> >>+   if (odp_pktout_queue_config(pktio, NULL))
> >>+           LOG_ABORT("Error: pktout config failed for %s\n", dev);
> >>+
> >>+   ret = odp_pktio_start(pktio);
> >>+   if (ret != 0)
> >>+           LOG_ABORT("Error: unable to start %s\n", dev);
> >>+
> >>+   printf("  created pktio:%02" PRIu64
> >>+          ", dev:%s, queue mode (ATOMIC queues)\n"
> >>+          "  \tdefault pktio%02" PRIu64 "\n",
> >>+          odp_pktio_to_u64(pktio), dev,
> >>+          odp_pktio_to_u64(pktio));
> >>+
> >>+   return pktio;
> >>+}
> >>+
> >>+/**
> >>+ * Packet IO loopback worker thread using ODP queues
> >>+ *
> >>+ * @param arg  thread arguments of type 'thread_args_t *'
> >>+ */
> >Document what we return ?
> >
> >>+static int pktio_queue_thread(void *arg ODP_UNUSED)
> >>+{
> >>+   int thr = odp_thread_id();
> >>+   odp_pktout_queue_t pktout;
> >>+   odp_packet_t pkt;
> >>+   odp_event_t ev;
> >>+   uint64_t sched_wait = odp_schedule_wait_time(ODP_TIME_MSEC_IN_NS * 100);
> >>+
> >>+   packet_flags.all = 0;
> >>+
> >>+   /* Loop packets */
> >>+   while (1) {
> >>+           odp_pktio_t pktio_tmp;
> >>+
> >>+           ev = odp_schedule(NULL, sched_wait);
> >>+           if (ev == ODP_EVENT_INVALID)
> >>+                   break;
> >>+
> >>+           pkt = odp_packet_from_event(ev);
> >>+           if (!odp_packet_is_valid(pkt))
> >>+                   continue;
> >>+
> >>+           pktio_tmp = odp_packet_input(pkt);
> >>+
> >>+           if (odp_pktout_queue(pktio_tmp, &pktout, 1) != 1) {
> >>+                   LOG_ERR("  [%02i] Error: no pktout queue\n", thr);
> >>+                   return -1;
> >>+           }
> >>+
> >>+           /* Extend bits here for more additional tests */
> >>+           if (odp_packet_has_l2(pkt))
> >>+                   packet_flags.parsed_l2 = 1;
> >>+           if (odp_packet_has_vlan(pkt))
> >>+                   packet_flags.vlan = 1;
> >>+
> >>+           /* Enqueue the packet for output */
> >>+           if (odp_pktout_send(pktout, &pkt, 1) != 1) {
> >>+                   LOG_ERR("  [%i] Packet send failed.\n", thr);
> >>+                   odp_packet_free(pkt);
> >>+                   continue;
> >>+           }
> >>+   }
> >>+
> >>+   return 0;
> >>+}
> >>+
> >>+int cls_main(int argc, char *argv[])
> >>+{
> >>+   odph_odpthread_t thread_tbl[1];
> >>+   odp_pool_t pool;
> >>+   int num_workers;
> >>+   int i;
> >>+   int cpu;
> >>+   odp_cpumask_t cpumask;
> >>+   char cpumaskstr[ODP_CPUMASK_STR_SIZE];
> >>+   odp_pool_param_t params;
> >>+   odp_instance_t instance;
> >>+   odph_odpthread_params_t thr_params;
> >>+
> >>+   args = calloc(1, sizeof(args_t));
> >>+   if (args == NULL) {
> >>+           LOG_ERR("Error: args mem alloc failed.\n");
> >>+           exit(EXIT_FAILURE);
> >>+   }
> >>+
> >>+   parse_args(argc, argv, &args->appl);
> >>+
> >>+   /* Init ODP before calling anything else */
> >>+   if (odp_init_global(&instance, NULL, NULL)) {
> >>+           LOG_ERR("Error: ODP global init failed.\n");
> >>+           exit(EXIT_FAILURE);
> >>+   }
> >>+
> >>+   /* Init this thread */
> >>+   if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
> >>+           LOG_ERR("Error: ODP local init failed.\n");
> >>+           exit(EXIT_FAILURE);
> >>+   }
> >>+
> >>+   num_workers = odp_cpumask_default_worker(&cpumask, 1);
> >>+   (void)odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr));
> >>+
> >>+   /* Create packet pool */
> >>+   odp_pool_param_init(&params);
> >>+   params.pkt.seg_len = SHM_PKT_POOL_BUF_SIZE;
> >>+   params.pkt.len     = SHM_PKT_POOL_BUF_SIZE;
> >>+   params.pkt.num     = SHM_PKT_POOL_SIZE;
> >>+   params.type        = ODP_POOL_PACKET;
> >>+
> >>+   pool = odp_pool_create("packet_pool", &params);
> >>+   if (pool == ODP_POOL_INVALID) {
> >>+           LOG_ERR("Error: packet pool create failed.\n");
> >>+           exit(EXIT_FAILURE);
> >>+   }
> >>+
> >>+   args->appl.pktio = create_pktio(args->appl.file_name, pool);
> >>+
> >>+   /* Create and init worker threads */
> >>+   memset(thread_tbl, 0, sizeof(thread_tbl));
> >>+
> >>+   memset(&thr_params, 0, sizeof(thr_params));
> >>+   thr_params.thr_type = ODP_THREAD_WORKER;
> >>+   thr_params.instance = instance;
> >>+
> >>+   cpu = odp_cpumask_first(&cpumask);
> >>+   for (i = 0; i < num_workers; ++i) {
> >>+           odp_cpumask_t thd_mask;
> >>+           int (*thr_run_func)(void *);
> >>+
> >>+           thr_run_func = pktio_queue_thread;
> >>+           /*
> >>+            * Create threads one-by-one instead of all-at-once,
> >>+            * because each thread might get different arguments.
> >>+            * Calls odp_thread_create(cpu) for each thread
> >>+            */
> >>+           odp_cpumask_zero(&thd_mask);
> >>+           odp_cpumask_set(&thd_mask, cpu);
> >>+
> >>+           thr_params.start = thr_run_func;
> >>+           thr_params.arg   = &args;
> >>+
> >>+           odph_odpthreads_create(&thread_tbl[i], &thd_mask, &thr_params);
> >>+           cpu = odp_cpumask_next(&cpumask, cpu);
> >>+   }
> >>+
> >>+   /* Master thread waits for other threads to exit */
> >>+   for (i = 0; i < num_workers; ++i)
> >>+           odph_odpthreads_join(&thread_tbl[i]);
> >>+
> >>+   odp_pktio_stop(args->appl.pktio);
> >>+   odp_pktio_close(args->appl.pktio);
> >>+
> >>+   while (1) {
> >>+           odp_event_t ev;
> >>+
> >>+           ev = odp_schedule(NULL, 0);
> >>+           if (ev == ODP_EVENT_INVALID)
> >>+                   break;
> >>+   }
> >>+
> >>+   odp_pool_destroy(pool);
> >>+   odp_term_local();
> >>+   odp_term_global(instance);
> >>+
> >>+   if (packet_flags.all != args->appl.expected_bits.all) {
> >>+           LOG_ERR("Flags %" PRIu64 " expected %" PRIu64 "\n",
> >>+                   packet_flags.all, args->appl.expected_bits.all);
> >>+           free(args);
> >>+           return -1;
> >>+   }
> >>+
> >>+   free(args);
> >>+   return 0;
> >>+}
> >>diff --git a/test/linux-generic/cls/cls_main.c 
> >>b/test/linux-generic/cls/cls_main.c
> >>new file mode 100644
> >>index 0000000..40179b9
> >>--- /dev/null
> >>+++ b/test/linux-generic/cls/cls_main.c
> >>@@ -0,0 +1,12 @@
> >>+/* Copyright (c) 2016, Linaro Limited
> >>+ * All rights reserved.
> >>+ *
> >>+ * SPDX-License-Identifier:     BSD-3-Clause
> >>+ */
> >>+
> >>+#include "cls_suites.h"
> >>+
> >>+int main(int argc, char *argv[])
> >>+{
> >>+   return cls_main(argc, argv);
> >>+}
> >>diff --git a/test/linux-generic/cls/cls_suites.h 
> >>b/test/linux-generic/cls/cls_suites.h
> >>new file mode 100644
> >>index 0000000..94c9b55
> >>--- /dev/null
> >>+++ b/test/linux-generic/cls/cls_suites.h
> >>@@ -0,0 +1 @@
> >>+int cls_main(int argc, char *argv[]);
> >>diff --git a/test/linux-generic/cls/vlan.pcap 
> >>b/test/linux-generic/cls/vlan.pcap
> >>new file mode 100644
> >>index 
> >>0000000000000000000000000000000000000000..106ccb682e51495b4025337518a0bce63c2c7681
> >>GIT binary patch
> >>literal 9728
> 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
> >>H$A|v_$relS
> >>
> >>literal 0
> >>HcmV?d00001
> >>
> >>diff --git a/test/linux-generic/cls/vlan_run.sh 
> >>b/test/linux-generic/cls/vlan_run.sh
> >>new file mode 100755
> >>index 0000000..7875eaf
> >>--- /dev/null
> >>+++ b/test/linux-generic/cls/vlan_run.sh
> >>@@ -0,0 +1,49 @@
> >>+#!/bin/sh
> >>+#
> >>+# Copyright (c) 2016, Linaro Limited
> >>+# All rights reserved.
> >>+#
> >>+# SPDX-License-Identifier:      BSD-3-Clause
> >>+#
> >>+
> >>+# directories where binary can be found:
> >>+# -in the validation dir when running make check (intree or out of tree)
> >>+# -in the script directory, when running after 'make install', or
> >>+# -in the validation when running standalone intree,
> >>+# -in the _build directory, when running after 'make distcheck',
> >>+# -in the current directory.
> >>+# running stand alone out of tree requires setting PATH
> >>+PATH=${TEST_DIR}/linux-generic/cls:$PATH
> >>+PATH=$(dirname $0):$PATH
> >>+PATH=$(dirname $0)/../../../../test/linux-generic/cls:$PATH
> >>+PATH=$(dirname $0)/../../../../_build/test/linux-generic/cls:$PATH
> >>+PATH=.:$PATH
> >>+
> >>+bin_path=$(which cls_main${EXEEXT})
> >>+if [ -x "$bin_path" ] ; then
> >>+   echo "Running with $bin_path"
> >>+else
> >>+   echo "Cannot find cls_main${EXEEXT}"
> >>+   echo "Please set you PATH for it. PATH=$PATH"
> >>+fi
> >>+
> >>+# Test1: find vlan packets in pcap file and test internal 
> >>pkt_mmap_vlan_insert()
> >>+#   function. Load packets from vlan.pcap file and check that classifier
> >>+#   set vlan bits fisible with odp_packet_has_vlan().
> >>+
> >>+PCAP=`find . ${TEST_DIR} $(dirname $0) -name vlan.pcap -print -quit`
> >>+
> >>+cls_main -i $PCAP -e 4097
> >>+ret=$?
> >>+
> >>+PCAP_IN_SIZE=`stat -c %s $PCAP`
> >>+PCAP_OUT_SIZE=`stat -c %s test_out.pcap`
> >>+
> >>+rm -f test_out.pcap
> >>+
> >>+if [ ${ret} -ne 0 ] || [ ${PCAP_IN_SIZE} -ne ${PCAP_OUT_SIZE} ]; then
> >>+   echo "Error: status ${ret}, in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}"
> >>+   exit 3
> >>+fi
> >>+
> >>+echo "PASS: test 1 passed"
> >>diff --git a/test/linux-generic/m4/configure.m4 
> >>b/test/linux-generic/m4/configure.m4
> >>index 9eec545..375ead2 100644
> >>--- a/test/linux-generic/m4/configure.m4
> >>+++ b/test/linux-generic/m4/configure.m4
> >>@@ -1,5 +1,6 @@
> >>  AC_CONFIG_FILES([test/linux-generic/Makefile
> >>             test/linux-generic/validation/api/shmem/Makefile
> >>             test/linux-generic/validation/api/pktio/Makefile
> >>+            test/linux-generic/cls/Makefile
> >Alphabetic order?
> >
> >Cheers,
> >Anders
> 

Reply via email to