Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Implementation of test socket server for tcp, udp, unix #722

Closed
wants to merge 17 commits into from

Conversation

maxgolov
Copy link
Contributor

@maxgolov maxgolov commented May 4, 2021

Description

This is incremental addition on top of zPages HTTP / HTTP Test Server code that I originally contributed last year.

Since HTTP server already had an abstract Reactor class for handling TCP connections using accept / listen (WSA, kqueue, epoll), - I would like to incrementally add UDP and Unix Domain sockets support to it. Unix Domain stream is nearly identical to TCP, whereas UDP pretty much uses a tight-loop to receive - with receiver potentially implementing a thread-pool to swap and handle the data. There are no changes anticipated to any of OpenTelemetry API or SDK code. Only additional test components for future use and reuse.

What is the main motivation for this test framework addition?

We do not presently have any existing reliable way to inspect, packet level-inspect, E2E test payload for validity. This is quite limiting. Now I'm working on fluentd exporter in contrib repo - and it would be great to get the new exporter tested properly. As in functional-tested , against a local in-proc TCP, UDP and Unix Domain server running as part of our testsuit, in the same test process - to avoid spinning and configuring other processes or external containers of any kind. Basically letting plain CTest do its test job in one single run, with all E2E test code confined to C++.

I think this test framework contribution is generic enough , as it may be reused for any other 3rd party exporter that relies on TCP, UDP or Unix Domain sockets. Since most code applies nicely on top of existing test classes, it would be impractical to move it or refactor it entirely to contrib. I would've gladly renamed the classes though, to move some from http to sockets or net directory.

Scenario 1

Debugging fluentd telemetry for validity:

  • start Unix Domain socket server that accepts MsgPack format (can be decoded using json.hpp)
  • listen for incoming Fluent forward protocol events (MsgPack binary payloads).
  • gather them and decode them as they arrive.
  • echo them back to the client.
  • validate all fields for validity and consistency.

Scenario 2

Stress-test and compare TCP, UDP and Unix Domain encoder performance for fluent, e.g.

Now it can be done without actually installing fluent. Without needing a privileged agent running.. All from the same testsuit we already have. And we also already have HTTP server in, to validate the HTTP flow. What I'm now adding is the ability to inspect TCP, UDP and Unix Domain using about the same approach we used before for HTTP server validation.

Outcome

  • report test result as part of Google Test run.
  • early-detect compliance or semantic changes to any of the fields.
  • perform Google Benchmark runs to measure perf, TCP vs Unix Domain, to provide a recommendation about the most optimal transport for each concrete case.

All code is (c) OpenTelemetry Authors - Apache License v2.0, header-only, cross-platform (Windows, Linux, Mac). It is not hard to find alternatives to what I did here.. But most of these alternatives would be not header only. And not Apache License v2.

List of Changes

  • macros.h - handy macros for token pasting, lockguard, debug console logging to be used in test only.
  • socket_server.h - implementation of TCP, UDP and Unix Domain test server. Unix Domain actually works even on Windows 10 - latest.
  • socket_tools.h - basic header-only C++11 cross-plat abstraction layer for Windows and POSIX sockets.
  • sockets_test.cc - unit + functional test of the test framework itself.

Other projects, e.g. opentelemetry-cpp-contrib, then may use the framework for their own E2E tests entirely written in C++, with no external test server needed.

Usage Example

Shown in sockets_test.cc - simple echo server :

        SocketParams params{AF_INET, SOCK_DGRAM, 0};
        SocketAddr destination("127.0.0.1:4000");
        SocketServer server(destination, params);

        // Here we can add all sorts of test / mock logic to inspect the contents
        server.onRequest = [&](SocketServer::Connection& conn) {
            conn.buffer_sent.clear();
            conn.buffer_received.swap(conn.buffer_sent);
            conn.state.insert(SocketServer::Connection::Responding);
        };

        server.Start();
        Socket client(server.server_socket_params);
        client.connect(server.address());

        // ping ->
        std::string requestText("Hello!");
        int res = client.send(requestText.c_str(), requestText.length());

        // <- pong
        char responseText[1024] = {0};
        int size = client.recv(responseText, sizeof(responseText));
        EXPECT_TRUE(requestText == responseText);
        
        client.close();
        server.Stop();

Subsequently, the server handler server.onRequest may be instrumented with a mock that validates all records emitted, measures timing, checks records contents for validity, etc.. I tried implementing the new class using OpenTelemetry coding style. However, I (mostly) preserved the coding style of Socket client to minimize the changes. I also added thread-safety to this new server, plus to the old reactor class.

I can clean-up / refactor the old HTTP server code and the Socket class to better coding style separately, in a separate PR.

@maxgolov maxgolov requested a review from a team as a code owner May 4, 2021 06:44
@maxgolov maxgolov changed the title Initial implementation of test server for sockets (tcp, udp, unix) Implementation of test socket server for tcp, udp, unix May 4, 2021
@maxgolov maxgolov marked this pull request as draft May 4, 2021 08:03
@maxgolov maxgolov changed the title Implementation of test socket server for tcp, udp, unix [WIP] Implementation of test socket server for tcp, udp, unix May 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant