tests docs: upgrade python packages
[vpp.git] / test / doc / overview.rst
index 7b70ede..0c07cb6 100644 (file)
@@ -5,6 +5,9 @@
 .. _virtualenv: http://docs.python-guide.org/en/latest/dev/virtualenvs/
 .. _scapy: http://www.secdev.org/projects/scapy/
 .. _logging: https://docs.python.org/2/library/logging.html
+.. _process: https://docs.python.org/2/library/multiprocessing.html#the-process-class
+.. _pipes: https://docs.python.org/2/library/multiprocessing.html#multiprocessing.Pipe
+.. _managed: https://docs.python.org/2/library/multiprocessing.html#managers
 
 .. |vtf| replace:: VPP Test Framework
 
@@ -70,6 +73,29 @@ To control the messages printed to console, specify the V= parameter.
    make test V=1     # moderate verbosity
    make test V=2     # maximum verbosity
 
+Parallel test execution
+#######################
+
+|vtf| test suites can be run in parallel. Each test suite is executed
+in a separate process spawned by Python multiprocessing process_.
+
+The results from child test suites are sent to parent through pipes_, which are
+aggregated and summarized at the end of the run.
+
+Stdout, stderr and logs logged in child processes are redirected to individual
+parent managed_ queues. The data from these queues are then emitted to stdout
+of the parent process in the order the test suites have finished. In case there
+are no finished test suites (such as at the beginning of the run), the data
+from last started test suite are emitted in real time.
+
+To enable parallel test run, specify the number of parallel processes:
+
+.. code-block:: shell
+
+   make test TEST_JOBS=n       # at most n processes will be spawned
+   make test TEST_JOBS=auto    # chosen based on the number of cores
+                               # and the size of shared memory
+
 Test temporary directory and VPP life cycle
 ###########################################
 
@@ -149,8 +175,8 @@ e.g. for the IPv4 address assigned to the VPP interface:
 * local_ip4n - Local IPv4 address - raw, suitable as API parameter.
 
 These addresses need to be configured in VPP to be usable using e.g.
-`config_ip4` API. Please see the documentation to `VppInterface` for more
-details.
+`VppInterface.config_ip4` API. Please see the documentation to
+`VppInterface` for more details.
 
 By default, there is one remote address of each kind created for L3:
 remote_ip4 and remote_ip6. If the test needs more addresses, because it's
@@ -169,9 +195,9 @@ using packet-generator interfaces, represented by the `VppPGInterface` class.
 Packets are written into a temporary .pcap file, which is then read by the VPP
 and the packets are injected into the VPP world.
 
-To add a list of packets to an interface, call the `add_stream` method on that
-interface. Once everything is prepared, call `pg_start` method to start
-the packet generator on the VPP side.
+To add a list of packets to an interface, call the `VppPGInterface.add_stream`
+method on that interface. Once everything is prepared, call `pg_start` method to
+start the packet generator on the VPP side.
 
 VPP -> test framework
 ~~~~~~~~~~~~~~~~~~~~~
@@ -182,39 +208,44 @@ which is then read and analyzed by the |vtf|.
 
 The following APIs are available to the test case for reading pcap files.
 
-* `get_capture`: this API is suitable for bulk & batch style of test, where
-  a list of packets is prepared & sent, then the received packets are read
-  and verified. The API needs the number of packets which are expected to
-  be captured (ignoring filtered packets - see below) to know when the pcap
-  file is completely written by the VPP. If using packet infos for verifying
-  packets, then the counts of the packet infos can be automatically used
-  by `get_capture` to get the proper count (in this case the default value
-  None can be supplied as expected_count or ommitted altogether).
-* `wait_for_packet`: this API is suitable for interactive style of test,
-  e.g. when doing session management, three-way handsakes, etc. This API waits
-  for and returns a single packet, keeping the capture file in place
-  and remembering context. Repeated invocations return following packets
-  (or raise Exception if timeout is reached) from the same capture file
-  (= packets arriving on the same interface).
-
-*NOTE*: it is not recommended to mix these APIs unless you understand how they
-work internally. None of these APIs rotate the pcap capture file, so calling
-e.g. `get_capture` after `wait_for_packet` will return already read packets.
-It is safe to switch from one API to another after calling `enable_capture`
-as that API rotates the capture file.
+* `VppPGInterface.get_capture`: this API is suitable for bulk & batch
+  style of test, where a list of packets is prepared & sent, then the
+  received packets are read and verified. The API needs the number of
+  packets which are expected to be captured (ignoring filtered
+  packets - see below) to know when the pcap file is completely
+  written by the VPP. If using packet infos for verifying packets,
+  then the counts of the packet infos can be automatically used by
+  `VppPGInterface.get_capture` to get the proper count (in this case
+  the default value None can be supplied as expected_count or ommitted
+  altogether).
+* `VppPGInterface.wait_for_packet`: this API is suitable for
+  interactive style of test, e.g. when doing session management,
+  three-way handshakes, etc. This API waits for and returns a single
+  packet, keeping the capture file in place and remembering
+  context. Repeated invocations return following packets (or raise
+  Exception if timeout is reached) from the same capture file (=
+  packets arriving on the same interface).
+
+*NOTE*: it is not recommended to mix these APIs unless you understand
+how they work internally. None of these APIs rotate the pcap capture
+file, so calling e.g. `VppPGInterface.get_capture` after
+`VppPGInterface.wait_for_packet` will return already read packets.  It
+is safe to switch from one API to another after calling
+`VppPGInterface.enable_capture` as that API rotates the capture file.
 
 Automatic filtering of packets:
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Both APIs (`get_capture` and `wait_for_packet`) by default filter the packet
-capture, removing known uninteresting packets from it - these are IPv6 Router
-Advertisments and IPv6 Router Alerts. These packets are unsolicitated
-and from the point of |vtf| are random. If a test wants to receive these
-packets, it should specify either None or a custom filtering function
-as the value to the 'filter_out_fn' argument.
+Both APIs (`VppPGInterface.get_capture` and
+`VppPGInterface.wait_for_packet`) by default filter the packet
+capture, removing known uninteresting packets from it - these are IPv6
+Router Advertisments and IPv6 Router Alerts. These packets are
+unsolicitated and from the point of |vtf| are random. If a test wants
+to receive these packets, it should specify either None or a custom
+filtering function as the value to the 'filter_out_fn' argument.
 
 Common API flow for sending/receiving packets:
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 We will describe a simple scenario, where packets are sent from pg0 to pg1
 interface, assuming that the interfaces were created using
@@ -318,7 +349,7 @@ basic IPv4 forwarding.
      class IP4FwdTestCase(VppTestCase):
          """ IPv4 simple forwarding test case """
 
-2. Add a setUpClass function containing the setup needed for our test to run::
+3. Add a setUpClass function containing the setup needed for our test to run::
 
          @classmethod
          def setUpClass(self):
@@ -329,7 +360,7 @@ basic IPv4 forwarding.
                  i.config_ip4()  # configure IPv4 address on the interface
                  i.resolve_arp()  # resolve ARP, so that we know VPP MAC
 
-3. Create a helper method to create the packets to send::
+4. Create a helper method to create the packets to send::
 
          def create_stream(self, src_if, dst_if, count):
              packets = []
@@ -351,7 +382,7 @@ basic IPv4 forwarding.
              # return the created packet list
              return packets
 
-4. Create a helper method to verify the capture::
+5. Create a helper method to verify the capture::
 
          def verify_capture(self, src_if, dst_if, capture):
              packet_info = None
@@ -360,7 +391,7 @@ basic IPv4 forwarding.
                      ip = packet[IP]
                      udp = packet[UDP]
                      # convert the payload to packet info object
-                     payload_info = self.payload_to_info(str(packet[Raw]))
+                     payload_info = self.payload_to_info(packet[Raw])
                      # make sure the indexes match
                      self.assert_equal(payload_info.src, src_if.sw_if_index,
                                        "source sw_if_index")
@@ -393,7 +424,7 @@ basic IPv4 forwarding.
                                "Interface %s: Packet expected from interface "
                                "%s didn't arrive" % (dst_if.name, src_if.name))
 
-5. Add the test code to test_basic function::
+6. Add the test code to test_basic function::
 
          def test_basic(self):
              count = 10
@@ -415,4 +446,5 @@ basic IPv4 forwarding.
              # verify capture
              self.verify_capture(self.pg0, self.pg1, capture)
 
-6. Run the test by issuing 'make test'.
+7. Run the test by issuing 'make test' or, to run only this specific
+   test, issue 'make test TEST=test_ip4_fwd'.