On Fri, Apr 8, 2022 at 3:17 AM <ohily...@iol.unh.edu> wrote:
>
> From: Owen Hilyard <ohily...@iol.unh.edu>
>
>     Currently, DTS uses Testpmd for most of its testing. This has been 
> successful in reducing the need to create more test apps, but it has a few 
> drawbacks. First, if some part of DPDK is not exposed via Testpmd or one of 
> the example applications, for the purposes of DTS it is not testable. This is 
> a situation I’d like to avoid. However, adding new functionality to Testpmd 
> is labor-intensive. Testpmd currently uses a hand-written LL(1) parser 
> (https://en.wikipedia.org/wiki/LL_parser) to parse command line options. This 
> makes adding new functionality difficult since the parser is stored as a 
> series of several thousand line long lookup tables. To look at it another 
> way, 64% of the 52238 lines in Testpmd are related to command line input in 
> some way. The command line interface of testpmd also presents several 
> challenges for the underlying implementation, since it requires that 
> everything a user might want to reference is identified via something that is 
> reasonable to ask a user to type. As of right now, this is handled via either 
> strings or integers. This can be handled by creating a global registry for 
> objects, but it is still extra work that I think can be avoided. In addition, 
> this leads to more places where things can go wrong.
>
> This is what DTS running a single command in testpmd looks like right now:
> https://drive.google.com/file/d/1hvTcjfVdh8-I3CUNoq6bx82EuNQSK6qW/view?usp=sharing
>
>     This approach has a number of disadvantages. First, it requires 
> assembling all commands as strings inside of the test suite and sending them 
> through a full round trip of SSH. This means that any non-trivial command, 
> such as creating an RTE flow, will involve a lot of string templating. This 
> normally wouldn’t be a big issue, except that some of the test suites are 
> designed to hundreds of commands over the course of a test, paying the cost 
> of an SSH round trip for each. Once Testpmd has the commands, it will then 
> call the appropriate functions inside of DPDK, and then print out all of the 
> state to standard out. All of this is sent back to DTS, where the author of 
> the test case then needs to handle all possible outputs of Trex, often by 
> either declaring the presence of a single word or short phrase in the output 
> as meaning success or failure. In my opinion, this is something that is 
> perfectly fine for humans to interact with, but it causes a lot of issues 
> with automation due to its inherent inflexibility and the less-than-ideal 
> methods of information transfer. This is why I am proposing the creation of 
> an automation-oriented pmd, with a focus on exposing as much.
>
> https://drive.google.com/file/d/1wj4-RnFPVERCzM8b68VJswAOEI9cg-X8/view?usp=sharing
>
>         That diagram is a high-level overview of the design, which explicitly 
> excludes implementation details. However, it already has some benefits. 
> First, making DPDK do something is a normal method call, instead of needing 
> to format things into a string. This provides a much better interface for 
> people working in both DTS and DPDK. Second, the ability to return structured 
> data means that there won’t be parsers on both sides of communication 
> anymore. Structured data also allows much more verbosity, since it is no 
> longer an interface designed for humans. If a test case author needs to 
> return the bytes of every received packet back to DTS for comparison with the 
> expected value, they can. If you need to return a pointer for DTS to use 
> later, that becomes reasonable. Simply moving to shuffling structured data 
> around and using RPC already provides a lot of benefits.
>         The next obvious question would be what to use for the 
> implementation. The initial attempt was made using Python on both sides and 
> the standard library xmlrpc module. The RPC aspect of this approach worked 
> very well, with the ability to send arbitrary python objects back and forth 
> between DTS and app. However, having Python interacting with DPDK has a few 
> issues. First, DPDK is generally very multi-threaded and the most common 
> implementation of Python, CPython, does not have concurrency. It has 
> something known as the global interpretr lock, which is a global mutex. This 
> makes it very difficult to interact with blocking, multi-threaded code. The 
> other issue is that I was not able to find a binding generator that I feel 
> would be sufficient for DPDK. Many generators assumed sizeof(int) == 4 or had 
> other portability issues such as assuming GCC or Clang as a C compiler. 
> Others focused on some subset of C, meaning they would throw errors on 
> alignment annotations.
>     Given this, I decided to look for cross-language RPC libraries. Although 
> libraries exist for performing xmlrpc in C, they generally appeared quite 
> difficult to use and required a lot of manual work. The next best option was 
> gRPC. gRPC allows using a simple language, protobuf, with a language 
> extension for rpc. It provides code generation to make it easy to use 
> multiple languages together, since it was developed to make polyglot 
> microservice interaction easier. The only drawback is that it considers C++ 
> good enough for C support. In this case, I was able to easily integrate DPDK 
> with C++, so that isn’t much of a concern. I used C++17 in the attached 
> patches, but the minimum requirements are C++11. If there is concern about 
> modern C++ causing too much mental overhead, a “C with classes” subset of C++ 
> could easily be used. I also added an on-by-default option to use a C++ 
> compiler, allowing anyone who does not have a C++ compiler available to them 
> to turn off everything that uses C++. This disables the application written 
> for this RFC.
>     One of the major benefits of gRPC is the asynchronous API. This allows 
> streaming data on both sides of an RPC call. This allows streaming logs back 
> to DTS, streaming large amounts of data from low-memory systems back to DTS 
> for processing, and would allow DTS to easily feed DPDK data, ending the test 
> quickly on a failure. Currently, due to the overhead of sending data to 
> Testpmd, it is common to just send all of the commands over and run 
> everything since that will be much faster when the test passes, but it can 
> cost a lot of time in the event of a failure. There are also optional 
> security features for requiring authentication before allowing code 
> execution. I think that a discussion on whether using them for DTS is 
> necessary is warranted, although I personally think that it’s not worth the 
> effort given the type of environment this sample application is expected to 
> run in.
>     For this RFC, I ported test-acl because it was mostly self-contained and 
> was something I could run on my laptop. It should be fairly easy to see how 
> you would expand this proof of concept to cover more of DPDK, and I think 
> that most of the functions currently used in testpmd could be ported over to 
> this approach, saving a lot of development time. However, I would like to see 
> some more interest before I take on a task like that. This will require a lot 
> of work on the DTS side to implement, but it will make it much easier to add 
> new features to DTS.


Thanks, Owen for POC.

In my view, May using this scheme is probably over-engineered. The
reason for thinking so is
-Now that, Test code is also part of DPDK, Exposing as services may
not be required.
-Now in DPDK, we have two types of existing test cases to verify the API
-- Noninteractive  - These test cases, can simply run over ssh with
bash invocation and return the test from a remote PC,
-- Interactive - Testpmd one, I believe, Feeding stdin
programmatically would suffice to test all the combinations.
-We need to add all test cases in this model and we need to maintain
two sets of programs.(Traditional tests and gRPC model-based tests).

Just my 2c.


>
> Owen Hilyard (4):
>   app/test-pmd-api: Add C++ Compiler
>   app/test-pmd-api: Add POC with gRPC deps
>   app/test-pmd-api: Add protobuf file
>   app/test-pmd-api: Implementation files for the API
>
>  app/meson.build              |   17 +
>  app/test-pmd-api/api.proto   |   12 +
>  app/test-pmd-api/api_impl.cc | 1160 ++++++++++++++++++++++++++++++++++
>  app/test-pmd-api/api_impl.h  |   10 +
>  app/test-pmd-api/main.c      |   11 +
>  app/test-pmd-api/meson.build |   96 +++
>  meson.build                  |    3 +
>  meson_options.txt            |    2 +
>  8 files changed, 1311 insertions(+)
>  create mode 100644 app/test-pmd-api/api.proto
>  create mode 100644 app/test-pmd-api/api_impl.cc
>  create mode 100644 app/test-pmd-api/api_impl.h
>  create mode 100644 app/test-pmd-api/main.c
>  create mode 100644 app/test-pmd-api/meson.build
>
> --
> 2.30.2
>

Reply via email to