diff options
author | imarom <imarom@cisco.com> | 2016-03-30 17:46:02 +0300 |
---|---|---|
committer | imarom <imarom@cisco.com> | 2016-03-31 15:51:18 +0300 |
commit | 32b6b28437504ce80182f48cc99dd40f5feb626f (patch) | |
tree | 7fa0875839f6536e84168e55b67ab76636c4cc24 | |
parent | fc4620422d79d218170aad12fc55fa4a98076c13 (diff) |
STL tests (API)
-rw-r--r-- | scripts/automation/regression/stateless_tests/stl_client_test.py | 268 | ||||
-rw-r--r-- | scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py | 5 | ||||
-rw-r--r-- | scripts/stl/flow_stats.py | 6 | ||||
-rw-r--r-- | scripts/stl/udp_1pkt_pcap.py | 5 | ||||
-rw-r--r-- | scripts/stl/udp_3pkt_pcap.py | 9 | ||||
-rw-r--r-- | scripts/stl/yaml/imix_1pkt_vm_minus.yaml | 3 |
6 files changed, 289 insertions, 7 deletions
diff --git a/scripts/automation/regression/stateless_tests/stl_client_test.py b/scripts/automation/regression/stateless_tests/stl_client_test.py new file mode 100644 index 00000000..fa10be38 --- /dev/null +++ b/scripts/automation/regression/stateless_tests/stl_client_test.py @@ -0,0 +1,268 @@ +#!/router/bin/python +from stl_general_test import CStlGeneral_Test, CTRexScenario +from trex_stl_lib.api import * +import os, sys +import glob + +def get_error_in_percentage (golden, value): + return abs(golden - value) / float(golden) + +def get_stl_profiles (): + profiles_path = os.path.join(CTRexScenario.scripts_path, 'stl/') + profiles = glob.glob(profiles_path + "/*.py") + glob.glob(profiles_path + "yaml/*.yaml") + + + return profiles + + +class STLClient_Test(CStlGeneral_Test): + """Tests for stateless client""" + + def setUp(self): + CStlGeneral_Test.setUp(self) + assert 'bi' in CTRexScenario.stl_ports_map + + self.c = CTRexScenario.stl_trex + + self.tx_port, self.rx_port = CTRexScenario.stl_ports_map['bi'][0] + + self.c.connect() + self.c.reset(ports = [self.tx_port, self.rx_port]) + + self.pkt = STLPktBuilder(pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025)/IP()/'a_payload_example') + self.profiles = get_stl_profiles() + + + @classmethod + def tearDownClass(cls): + # connect back at end of tests + if not cls.is_connected(): + CTRexScenario.stl_trex.connect() + + + def test_basic_connect_disconnect (self): + try: + self.c.connect() + assert self.c.is_connected(), 'client should be connected' + self.c.disconnect() + assert not self.c.is_connected(), 'client should be disconnected' + + except STLError as e: + assert False , '{0}'.format(e) + + + def test_basic_single_burst (self): + try: + b1 = STLStream(name = 'burst', + packet = self.pkt, + mode = STLTXSingleBurst(total_pkts = 100, + pps = 1000) + ) + + for i in range(0, 5): + self.c.add_streams([b1], ports = [self.tx_port, self.rx_port]) + + self.c.clear_stats() + self.c.start(ports = [self.tx_port, self.rx_port]) + + assert self.c.ports[self.tx_port].is_transmitting(), 'port should be active' + assert self.c.ports[self.rx_port].is_transmitting(), 'port should be active' + + self.c.wait_on_traffic(ports = [self.tx_port, self.rx_port]) + stats = self.c.get_stats() + + assert self.tx_port in stats + assert self.rx_port in stats + + assert stats[self.tx_port]['opackets'] == 100 + assert stats[self.rx_port]['ipackets'] == 100 + + assert stats[self.rx_port]['opackets'] == 100 + assert stats[self.tx_port]['ipackets'] == 100 + + self.c.remove_all_streams(ports = [self.tx_port, self.rx_port]) + + + + except STLError as e: + assert False , '{0}'.format(e) + + + # + def test_basic_multi_burst (self): + try: + b1 = STLStream(name = 'burst', + packet = self.pkt, + mode = STLTXMultiBurst(pkts_per_burst = 10, + count = 20, + pps = 1000) + ) + + for i in range(0, 5): + self.c.add_streams([b1], ports = [self.tx_port, self.rx_port]) + + self.c.clear_stats() + self.c.start(ports = [self.tx_port, self.rx_port]) + + assert self.c.ports[self.tx_port].is_transmitting(), 'port should be active' + assert self.c.ports[self.rx_port].is_transmitting(), 'port should be active' + + self.c.wait_on_traffic(ports = [self.tx_port, self.rx_port]) + stats = self.c.get_stats() + + assert self.tx_port in stats + assert self.rx_port in stats + + assert stats[self.tx_port]['opackets'] == 200 + assert stats[self.rx_port]['ipackets'] == 200 + + assert stats[self.rx_port]['opackets'] == 200 + assert stats[self.tx_port]['ipackets'] == 200 + + self.c.remove_all_streams(ports = [self.tx_port, self.rx_port]) + + + + except STLError as e: + assert False , '{0}'.format(e) + + + # + def test_basic_cont (self): + pps = 49182 + duration = 0.1 + golden = pps * duration + + try: + b1 = STLStream(name = 'burst', + packet = self.pkt, + mode = STLTXCont(pps = pps) + ) + + for i in range(0, 5): + self.c.add_streams([b1], ports = [self.tx_port, self.rx_port]) + + self.c.clear_stats() + self.c.start(ports = [self.tx_port, self.rx_port], duration = duration) + + assert self.c.ports[self.tx_port].is_transmitting(), 'port should be active' + assert self.c.ports[self.rx_port].is_transmitting(), 'port should be active' + + self.c.wait_on_traffic(ports = [self.tx_port, self.rx_port]) + stats = self.c.get_stats() + + assert self.tx_port in stats + assert self.rx_port in stats + + # cont. with duration should be quite percise - 5% error is relaxed enough + assert get_error_in_percentage(stats[self.tx_port]['opackets'], golden) < 0.05 + assert get_error_in_percentage(stats[self.rx_port]['ipackets'], golden) < 0.05 + + assert get_error_in_percentage(stats[self.rx_port]['opackets'], golden) < 0.05 + assert get_error_in_percentage(stats[self.tx_port]['ipackets'], golden) < 0.05 + + + self.c.remove_all_streams(ports = [self.tx_port, self.rx_port]) + + + + except STLError as e: + assert False , '{0}'.format(e) + + + def test_stress_connect_disconnect (self): + try: + for i in range(0, 100): + self.c.connect() + assert self.c.is_connected(), 'client should be connected' + self.c.disconnect() + assert not self.c.is_connected(), 'client should be disconnected' + + + except STLError as e: + assert False , '{0}'.format(e) + + + + def test_stress_tx (self): + try: + s1 = STLStream(name = 'stress', + packet = self.pkt, + mode = STLTXCont(percentage = 60)) + + # add both streams to ports + self.c.add_streams([s1], ports = [self.tx_port, self.rx_port]) + for i in range(0, 100): + + self.c.start(ports = [self.tx_port, self.rx_port]) + + assert self.c.ports[self.tx_port].is_transmitting(), 'port should be active' + assert self.c.ports[self.rx_port].is_transmitting(), 'port should be active' + + self.c.pause(ports = [self.tx_port, self.rx_port]) + + assert self.c.ports[self.tx_port].is_paused(), 'port should be paused' + assert self.c.ports[self.rx_port].is_paused(), 'port should be paused' + + self.c.resume(ports = [self.tx_port, self.rx_port]) + + assert self.c.ports[self.tx_port].is_transmitting(), 'port should be active' + assert self.c.ports[self.rx_port].is_transmitting(), 'port should be active' + + self.c.stop(ports = [self.tx_port, self.rx_port]) + + assert not self.c.ports[self.tx_port].is_active(), 'port should be idle' + assert not self.c.ports[self.rx_port].is_active(), 'port should be idle' + + except STLError as e: + assert False , '{0}'.format(e) + + + def test_all_profiles (self): + try: + self.c.set_port_attr(ports = [self.tx_port, self.rx_port], promiscuous = True) + + for profile in self.profiles: + print("now testing profile {0}...\n").format(profile) + + p1 = STLProfile.load(profile, port_id = self.tx_port) + p2 = STLProfile.load(profile, port_id = self.rx_port) + + if p1.needs_rx_caps(): + print("profile needs RX caps - skipping...") + continue + + self.c.add_streams(p1, ports = self.tx_port) + self.c.add_streams(p2, ports = self.rx_port) + + self.c.clear_stats() + + self.c.start(ports = [self.tx_port, self.rx_port], mult = "50%") + time.sleep(100 / 1000.0) + + if p1.is_pauseable() and p2.is_pauseable(): + self.c.pause(ports = [self.tx_port, self.rx_port]) + time.sleep(100 / 1000.0) + + self.c.resume(ports = [self.tx_port, self.rx_port]) + time.sleep(100 / 1000.0) + + self.c.stop(ports = [self.tx_port, self.rx_port]) + + stats = self.c.get_stats() + + assert self.tx_port in stats + assert self.rx_port in stats + + assert stats[self.tx_port]['opackets'] == stats[self.rx_port]['ipackets'] + + assert stats[self.rx_port]['opackets'] == stats[self.tx_port]['ipackets'] + + self.c.remove_all_streams(ports = [self.tx_port, self.rx_port]) + + except STLError as e: + assert False , '{0}'.format(e) + + + finally: + self.c.set_port_attr(ports = [self.tx_port, self.rx_port], promiscuous = False) diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py index b6780c5e..a75ba044 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py @@ -832,6 +832,11 @@ class STLProfile(object): def __str__ (self): return '\n'.join([str(stream) for stream in self.streams]) + def is_pauseable (self): + return all([x.get_mode() == "Continuous" for x in (self.get_streams())]) + + def needs_rx_caps (self): + return any([x.has_flow_stats() for x in self.get_streams()]) @staticmethod def load_yaml (yaml_file): diff --git a/scripts/stl/flow_stats.py b/scripts/stl/flow_stats.py index 69e1166c..cbb5ac21 100644 --- a/scripts/stl/flow_stats.py +++ b/scripts/stl/flow_stats.py @@ -1,15 +1,17 @@ from trex_stl_lib.api import * +import os # stream from pcap file. continues pps 10 in sec +CP = os.path.join(os.path.dirname(__file__)) class STLS1(object): def get_streams (self, direction = 0, **kwargs): - return [STLStream(packet = STLPktBuilder(pkt ="stl/yaml/udp_64B_no_crc.pcap"), # path relative to pwd + return [STLStream(packet = STLPktBuilder(pkt = os.path.join(CP, "yaml/udp_64B_no_crc.pcap")), # path relative to pwd mode = STLTXCont(pps=1000), flow_stats = STLFlowStats(pg_id = 7)), - STLStream(packet = STLPktBuilder(pkt ="stl/yaml/udp_594B_no_crc.pcap"), # path relative to pwd + STLStream(packet = STLPktBuilder(pkt = os.path.join(CP, "yaml/udp_594B_no_crc.pcap")), # path relative to pwd mode = STLTXCont(pps=5000), flow_stats = STLFlowStats(pg_id = 12)) ] diff --git a/scripts/stl/udp_1pkt_pcap.py b/scripts/stl/udp_1pkt_pcap.py index 9fb0e269..2a364810 100644 --- a/scripts/stl/udp_1pkt_pcap.py +++ b/scripts/stl/udp_1pkt_pcap.py @@ -1,11 +1,14 @@ from trex_stl_lib.api import * +import os # stream from pcap file. continues pps 10 in sec +CP = os.path.join(os.path.dirname(__file__)) + class STLS1(object): def get_streams (self, direction = 0, **kwargs): - return [STLStream(packet = STLPktBuilder(pkt ="stl/yaml/udp_64B_no_crc.pcap"), # path relative to pwd + return [STLStream(packet = STLPktBuilder(pkt = os.path.join(CP, "yaml/udp_64B_no_crc.pcap")), mode = STLTXCont(pps=10)) ] #rate continues, could be STLTXSingleBurst,STLTXMultiBurst diff --git a/scripts/stl/udp_3pkt_pcap.py b/scripts/stl/udp_3pkt_pcap.py index fd2c609e..19ff46bc 100644 --- a/scripts/stl/udp_3pkt_pcap.py +++ b/scripts/stl/udp_3pkt_pcap.py @@ -1,26 +1,29 @@ from trex_stl_lib.api import * +import os # stream from pcap file. continues pps 10 in sec +CP = os.path.join(os.path.dirname(__file__)) + class STLS1(object): def create_stream (self): return STLProfile( [ STLStream( isg = 10.0, # star in delay name ='S0', - packet = STLPktBuilder(pkt ="stl/yaml/udp_64B_no_crc.pcap"), + packet = STLPktBuilder(pkt = os.path.join(CP, "yaml/udp_64B_no_crc.pcap")), mode = STLTXSingleBurst( pps = 10, total_pkts = 10), next = 'S1'), # point to next stream STLStream( self_start = False, # stream is disabled enable trow S0 name ='S1', - packet = STLPktBuilder(pkt ="stl/yaml/udp_594B_no_crc.pcap"), + packet = STLPktBuilder(pkt = os.path.join(CP, "yaml/udp_594B_no_crc.pcap")), mode = STLTXSingleBurst( pps = 10, total_pkts = 20), next = 'S2' ), STLStream( self_start = False, # stream is disabled enable trow S0 name ='S2', - packet = STLPktBuilder(pkt ="stl/yaml/udp_1518B_no_crc.pcap"), + packet = STLPktBuilder(pkt = os.path.join(CP, "yaml/udp_1518B_no_crc.pcap")), mode = STLTXSingleBurst( pps = 10, total_pkts = 30 ) ) ]).get_streams() diff --git a/scripts/stl/yaml/imix_1pkt_vm_minus.yaml b/scripts/stl/yaml/imix_1pkt_vm_minus.yaml index e83cfdd0..6d5345df 100644 --- a/scripts/stl/yaml/imix_1pkt_vm_minus.yaml +++ b/scripts/stl/yaml/imix_1pkt_vm_minus.yaml @@ -18,7 +18,8 @@ "min_value" : 1000, "name" : "l3_src", "op" : "inc", - "size" : 2, + "step": 1, + "size" : 4, "type" : "flow_var" }, { |