From 4dfb7b8cabef3097f822ac52f346cd6021cb35da Mon Sep 17 00:00:00 2001
From: Josh Blum <josh@joshknows.com>
Date: Wed, 13 Oct 2010 11:59:35 -0700
Subject: usrp: test async messages app randomly runs tests

---
 host/examples/test_async_messages.cpp | 84 ++++++++++++++++++++++++++++-------
 1 file changed, 67 insertions(+), 17 deletions(-)

(limited to 'host')

diff --git a/host/examples/test_async_messages.cpp b/host/examples/test_async_messages.cpp
index fa39bcde6..bdee7a504 100644
--- a/host/examples/test_async_messages.cpp
+++ b/host/examples/test_async_messages.cpp
@@ -19,8 +19,12 @@
 #include <uhd/utils/safe_main.hpp>
 #include <uhd/utils/static.hpp>
 #include <uhd/usrp/single_usrp.hpp>
+#include <boost/assign/list_of.hpp>
 #include <boost/program_options.hpp>
+#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
 #include <boost/format.hpp>
+#include <cstdlib>
 #include <complex>
 #include <iostream>
 
@@ -31,7 +35,7 @@ namespace po = boost::program_options;
  *    Send a burst of many samples that will fragment internally.
  *    We expect to get an eob ack async message.
  */
-void test_ack_async_message(uhd::usrp::single_usrp::sptr sdev){
+bool test_eob_ack_message(uhd::usrp::single_usrp::sptr sdev){
     uhd::device::sptr dev = sdev->get_device();
     std::cout << "Test eob ack message... " << std::flush;
 
@@ -55,7 +59,7 @@ void test_ack_async_message(uhd::usrp::single_usrp::sptr sdev){
             "failed:\n"
             "    Async message recv timed out.\n"
         ) << std::endl;
-        return;
+        return false;
     }
 
     switch(async_md.event_code){
@@ -64,13 +68,14 @@ void test_ack_async_message(uhd::usrp::single_usrp::sptr sdev){
             "success:\n"
             "    Got event code eob ack message.\n"
         ) << std::endl;
-        break;
+        return true;
 
     default:
         std::cout << boost::format(
             "failed:\n"
             "    Got unexpected event code 0x%x.\n"
         ) % async_md.event_code << std::endl;
+        return false;
     }
 }
 
@@ -79,7 +84,7 @@ void test_ack_async_message(uhd::usrp::single_usrp::sptr sdev){
  *    Send a start of burst packet with no following end of burst.
  *    We expect to get an underflow(within a burst) async message.
  */
-void test_underflow_message(uhd::usrp::single_usrp::sptr sdev){
+bool test_underflow_message(uhd::usrp::single_usrp::sptr sdev){
     uhd::device::sptr dev = sdev->get_device();
     std::cout << "Test underflow message... " << std::flush;
 
@@ -88,18 +93,21 @@ void test_underflow_message(uhd::usrp::single_usrp::sptr sdev){
     md.end_of_burst   = false;
     md.has_time_spec  = false;
 
-    dev->send(NULL, 0, md,
+    std::vector<std::complex<float> > buff(1); //minimum 1 sample
+
+    dev->send(
+        &buff.front(), buff.size(), md,
         uhd::io_type_t::COMPLEX_FLOAT32,
         uhd::device::SEND_MODE_FULL_BUFF
     );
 
     uhd::async_metadata_t async_md;
-    if (not dev->recv_async_msg(async_md)){
+    if (not dev->recv_async_msg(async_md, 1)){
         std::cout << boost::format(
             "failed:\n"
             "    Async message recv timed out.\n"
         ) << std::endl;
-        return;
+        return false;
     }
 
     switch(async_md.event_code){
@@ -108,13 +116,14 @@ void test_underflow_message(uhd::usrp::single_usrp::sptr sdev){
             "success:\n"
             "    Got event code underflow message.\n"
         ) << std::endl;
-        break;
+        return true;
 
     default:
         std::cout << boost::format(
             "failed:\n"
             "    Got unexpected event code 0x%x.\n"
         ) % async_md.event_code << std::endl;
+        return false;
     }
 }
 
@@ -123,7 +132,7 @@ void test_underflow_message(uhd::usrp::single_usrp::sptr sdev){
  *    Send a burst packet that occurs at a time in the past.
  *    We expect to get a time error async message.
  */
-void test_time_error_message(uhd::usrp::single_usrp::sptr sdev){
+bool test_time_error_message(uhd::usrp::single_usrp::sptr sdev){
     uhd::device::sptr dev = sdev->get_device();
     std::cout << "Test time error message... " << std::flush;
 
@@ -135,7 +144,10 @@ void test_time_error_message(uhd::usrp::single_usrp::sptr sdev){
 
     sdev->set_time_now(uhd::time_spec_t(200.0)); //time at 200s
 
-    dev->send(NULL, 0, md,
+    std::vector<std::complex<float> > buff(1); //minimum 1 sample
+
+    dev->send(
+        &buff.front(), buff.size(), md,
         uhd::io_type_t::COMPLEX_FLOAT32,
         uhd::device::SEND_MODE_FULL_BUFF
     );
@@ -146,7 +158,7 @@ void test_time_error_message(uhd::usrp::single_usrp::sptr sdev){
             "failed:\n"
             "    Async message recv timed out.\n"
         ) << std::endl;
-        return;
+        return false;
     }
 
     switch(async_md.event_code){
@@ -155,29 +167,38 @@ void test_time_error_message(uhd::usrp::single_usrp::sptr sdev){
             "success:\n"
             "    Got event code time error message.\n"
         ) << std::endl;
-        break;
+        return true;
 
     default:
         std::cout << boost::format(
             "failed:\n"
             "    Got unexpected event code 0x%x.\n"
         ) % async_md.event_code << std::endl;
+        return false;
     }
 }
 
+void flush_async_md(uhd::usrp::single_usrp::sptr sdev){
+    uhd::device::sptr dev = sdev->get_device();
+    uhd::async_metadata_t async_md;
+    while (dev->recv_async_msg(async_md, 1.0)){}
+}
+
 int UHD_SAFE_MAIN(int argc, char *argv[]){
     uhd::set_thread_priority_safe();
 
     //variables to be set by po
     std::string args;
     double rate;
+    size_t ntests;
 
     //setup the program options
     po::options_description desc("Allowed options");
     desc.add_options()
         ("help", "help message")
-        ("args", po::value<std::string>(&args)->default_value(""), "single uhd device address args")
-        ("rate", po::value<double>(&rate)->default_value(1.5e6), "rate of outgoing samples")
+        ("args",   po::value<std::string>(&args)->default_value(""), "single uhd device address args")
+        ("rate",   po::value<double>(&rate)->default_value(1.5e6),   "rate of outgoing samples")
+        ("ntests", po::value<size_t>(&ntests)->default_value(10),    "number of tests to run")
     ;
     po::variables_map vm;
     po::store(po::parse_command_line(argc, argv, desc), vm);
@@ -203,9 +224,38 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
     //------------------------------------------------------------------
     // begin asyc messages test
     //------------------------------------------------------------------
-    test_ack_async_message(sdev);
-    test_underflow_message(sdev);
-    test_time_error_message(sdev);
+    static const uhd::dict<std::string, boost::function<bool(uhd::usrp::single_usrp::sptr)> >
+        tests = boost::assign::map_list_of
+        ("Test EOB ACK   ",    &test_eob_ack_message)
+        ("Test Underflow ",  &test_underflow_message)
+        ("Test Time Error", &test_time_error_message)
+    ;
+
+    //init result counts
+    uhd::dict<std::string, size_t> failures, successes;
+    BOOST_FOREACH(const std::string &key, tests.keys()){
+        failures[key] = 0;
+        successes[key] = 0;
+    }
+
+    //run the tests, pick at random
+    for (size_t n = 0; n < ntests; n++){
+        std::string key = tests.keys()[std::rand() % tests.size()];
+        bool pass = tests[key](sdev);
+        flush_async_md(sdev);
+
+        //store result
+        if (pass) successes[key]++;
+        else      failures[key]++;
+    }
+
+    //print the result summary
+    std::cout << std::endl << "Summary:" << std::endl << std::endl;
+    BOOST_FOREACH(const std::string &key, tests.keys()){
+        std::cout << boost::format(
+            "%s   ->   %3d successes, %3d failures"
+        ) % key % successes[key] % failures[key] << std::endl;
+    }
 
     //finished
     std::cout << std::endl << "Done!" << std::endl << std::endl;
-- 
cgit v1.2.3