fix for https://trex-tgn.cisco.com/youtrack/issue/trex-226
authorimarom <[email protected]>
Wed, 3 Aug 2016 13:36:58 +0000 (16:36 +0300)
committerimarom <[email protected]>
Wed, 3 Aug 2016 13:38:25 +0000 (16:38 +0300)
commit #trex-226

scripts/automation/regression/stateless_tests/stl_client_test.py
src/stateless/cp/trex_dp_port_events.cpp
src/stateless/cp/trex_dp_port_events.h
src/stateless/cp/trex_stateless_port.cpp
src/stateless/cp/trex_stateless_port.h

index ed125cd..f3bb318 100644 (file)
@@ -297,3 +297,30 @@ class STLClient_Test(CStlGeneral_Test):
 
         finally:
             self.c.set_port_attr(ports = [self.tx_port, self.rx_port], promiscuous = False)
+
+
+    # see https://trex-tgn.cisco.com/youtrack/issue/trex-226
+    def test_latency_pause_resume (self):
+
+        try:    
+                                      
+            s1 = STLStream(name = 'latency',
+                           packet = self.pkt,
+                           mode = STLTXCont(percentage = self.percentage),
+                           flow_stats = STLFlowLatencyStats(pg_id = 1))
+
+            self.c.add_streams([s1], ports = self.tx_port)
+
+            self.c.clear_stats()
+
+            # mult has no meaning on latency - just messing around with the test
+            self.c.start(ports = self.tx_port, mult = "10mpps")
+
+            for i in range(100):
+                self.c.pause()
+                self.c.resume()
+
+            self.c.stop()
+
+        except STLError as e:
+            assert False , '{0}'.format(e)
index fc96e00..f06390c 100644 (file)
@@ -123,6 +123,20 @@ TrexDpPortEvents::on_core_reporting_in(int event_id, int thread_id, bool status)
 }
 
 
+/**
+ * return true if a core is still pending on an event 
+ */
+bool
+TrexDpPortEvents::is_core_pending_on_event(int event_id, int thread_id) {
+    TrexDpPortEvent *event = lookup(event_id);
+    /* event might have been deleted */
+    if (!event) {
+        return false;
+    }
+
+    return event->is_core_pending_on_event(thread_id);
+}
+
 /***************************
  * event
  * 
@@ -180,4 +194,8 @@ TrexDpPortEvent::on_core_reporting_in(int thread_id, bool status) {
     }
 }
 
-
+bool
+TrexDpPortEvent::is_core_pending_on_event(int thread_id) {
+    /* if the core has yet to mark its 'done' bit - it is still pending */
+    return !m_signal.at(thread_id);
+}
index 681e47a..be549a5 100644 (file)
@@ -64,6 +64,7 @@ protected:
 private:
     void init(TrexStatelessPort *port, int event_id, int timeout_ms);
     bool on_core_reporting_in(int thread_id, bool status = true);
+    bool is_core_pending_on_event(int thread_id);
 
     std::unordered_map<int, bool>  m_signal;
     int                            m_pending_cnt;
@@ -109,6 +110,13 @@ public:
      */
     void on_core_reporting_in(int event_id, int thread_id, bool status = true);
 
+    /**
+     * return true if core has yet to respond 
+     * to the event 
+     * 
+     */
+    bool is_core_pending_on_event(int event_id, int thread_id);
+
 private:
     TrexDpPortEvent *lookup(int event_id);
 
index 0fe4b41..376453b 100644 (file)
@@ -394,6 +394,17 @@ TrexStatelessPort::common_port_stop_actions(bool async) {
 
 }
 
+/**
+ * core is considered active if it has a pending for async stop
+ * 
+ */
+bool
+TrexStatelessPort::is_core_active(int core_id) {
+    return ( (m_pending_async_stop_event != TrexDpPortEvents::INVALID_ID) &&
+             (m_dp_events.is_core_pending_on_event(m_pending_async_stop_event, core_id))
+           );
+}
+
 void
 TrexStatelessPort::pause_traffic(void) {
 
@@ -409,7 +420,9 @@ TrexStatelessPort::pause_traffic(void) {
 
     /* send a pause message */
     TrexStatelessCpToDpMsgBase *pause_msg = new TrexStatelessDpPause(m_port_id);
-    send_message_to_all_dp(pause_msg);
+
+    /* send message to all cores */
+    send_message_to_all_dp(pause_msg, true);
 
     /* make sure all DP cores paused */
     m_dp_events.barrier();
@@ -431,10 +444,9 @@ TrexStatelessPort::resume_traffic(void) {
     /* generate a message to all the relevant DP cores to start transmitting */
     TrexStatelessCpToDpMsgBase *resume_msg = new TrexStatelessDpResume(m_port_id);
 
-    send_message_to_all_dp(resume_msg);
+    send_message_to_all_dp(resume_msg, true);
     change_state(PORT_STATE_TX);
 
-
     Json::Value data;
     data["port_id"] = m_port_id;
     get_stateless_obj()->get_publisher()->publish_event(TrexPublisher::EVENT_PORT_RESUMED, data);
@@ -609,9 +621,15 @@ TrexStatelessPort::encode_stats(Json::Value &port) {
 }
 
 void 
-TrexStatelessPort::send_message_to_all_dp(TrexStatelessCpToDpMsgBase *msg) {
+TrexStatelessPort::send_message_to_all_dp(TrexStatelessCpToDpMsgBase *msg, bool send_to_active_only) {
 
     for (auto core_id : m_cores_id_list) {
+
+        /* skip non active cores if requested */
+        if ( (send_to_active_only) && (!is_core_active(core_id)) ) {
+            continue;
+        }
+
         send_message_to_dp(core_id, msg->clone());
     }
 
index 915c532..b1f6ddf 100644 (file)
@@ -378,6 +378,7 @@ public:
 
 private:
 
+    bool is_core_active(int core_id);
 
     const std::vector<int> get_core_id_list () {
         return m_cores_id_list;
@@ -393,7 +394,7 @@ private:
      * send message to all cores using duplicate
      *
      */
-    void send_message_to_all_dp(TrexStatelessCpToDpMsgBase *msg);
+    void send_message_to_all_dp(TrexStatelessCpToDpMsgBase *msg, bool send_to_active_only = false);
 
     /**
      * send message to specific DP core