get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/47517/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 47517,
    "url": "https://patches.dpdk.org/api/patches/47517/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20181027091750.17254-9-harry.van.haaren@intel.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20181027091750.17254-9-harry.van.haaren@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20181027091750.17254-9-harry.van.haaren@intel.com",
    "date": "2018-10-27T09:17:46",
    "name": "[v10,08/12] telemetry: format json response when sending stats",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "3fcf2ffb4240828d7cb6ce50fe55edd7b641a1b2",
    "submitter": {
        "id": 317,
        "url": "https://patches.dpdk.org/api/people/317/?format=api",
        "name": "Van Haaren, Harry",
        "email": "harry.van.haaren@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20181027091750.17254-9-harry.van.haaren@intel.com/mbox/",
    "series": [
        {
            "id": 2132,
            "url": "https://patches.dpdk.org/api/series/2132/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=2132",
            "date": "2018-10-27T09:17:38",
            "name": "Introduce Telemetry Library",
            "version": 10,
            "mbox": "https://patches.dpdk.org/series/2132/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/47517/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/47517/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 0C7795B12;\n\tSat, 27 Oct 2018 11:20:26 +0200 (CEST)",
            "from mga18.intel.com (mga18.intel.com [134.134.136.126])\n\tby dpdk.org (Postfix) with ESMTP id 4253B548B\n\tfor <dev@dpdk.org>; Sat, 27 Oct 2018 11:19:44 +0200 (CEST)",
            "from orsmga008.jf.intel.com ([10.7.209.65])\n\tby orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t27 Oct 2018 02:19:43 -0700",
            "from silpixa00399779.ir.intel.com (HELO\n\tsilpixa00399779.ger.corp.intel.com) ([10.237.223.188])\n\tby orsmga008.jf.intel.com with ESMTP; 27 Oct 2018 02:19:41 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.54,431,1534834800\"; d=\"scan'208\";a=\"84903902\"",
        "From": "Harry van Haaren <harry.van.haaren@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "thomas@monjalon.net, bruce.richardson@intel.com,\n\tstephen@networkplumber.org, gaetan.rivet@6wind.com,\n\tshreyansh.jain@nxp.com, \n\tmattias.ronnblom@ericsson.com, Ciara Power <ciara.power@intel.com>,\n\tBrian Archbold <brian.archbold@intel.com>,\n\tKevin Laatz <kevin.laatz@intel.com>",
        "Date": "Sat, 27 Oct 2018 10:17:46 +0100",
        "Message-Id": "<20181027091750.17254-9-harry.van.haaren@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20181027091750.17254-1-harry.van.haaren@intel.com>",
        "References": "<20181026235933.79779-1-harry.van.haaren@intel.com>\n\t<20181027091750.17254-1-harry.van.haaren@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v10 08/12] telemetry: format json response when\n\tsending stats",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Ciara Power <ciara.power@intel.com>\n\nThis patch adds functionality to create a JSON message in\norder to send it to a client socket.\n\nWhen stats are requested by a client, they are retrieved from\nthe metrics library and encoded in JSON format.\n\nSigned-off-by: Ciara Power <ciara.power@intel.com>\nSigned-off-by: Brian Archbold <brian.archbold@intel.com>\nSigned-off-by: Kevin Laatz <kevin.laatz@intel.com>\nAcked-by: Harry van Haaren <harry.van.haaren@intel.com>\n---\n lib/librte_telemetry/Makefile                 |   1 +\n lib/librte_telemetry/meson.build              |   4 +-\n lib/librte_telemetry/rte_telemetry.c          | 962 +++++++++++++++++-\n lib/librte_telemetry/rte_telemetry.h          |  15 +\n lib/librte_telemetry/rte_telemetry_internal.h |   3 +\n .../rte_telemetry_parser_test.c               | 534 ++++++++++\n .../rte_telemetry_parser_test.h               |  39 +\n .../rte_telemetry_socket_tests.h              |  36 +\n .../rte_telemetry_version.map                 |   1 +\n 9 files changed, 1591 insertions(+), 4 deletions(-)\n create mode 100644 lib/librte_telemetry/rte_telemetry_parser_test.c\n create mode 100644 lib/librte_telemetry/rte_telemetry_parser_test.h\n create mode 100644 lib/librte_telemetry/rte_telemetry_socket_tests.h",
    "diff": "diff --git a/lib/librte_telemetry/Makefile b/lib/librte_telemetry/Makefile\nindex 95c72963a..1a0506913 100644\n--- a/lib/librte_telemetry/Makefile\n+++ b/lib/librte_telemetry/Makefile\n@@ -22,6 +22,7 @@ LIBABIVER := 1\n # library source files\n SRCS-$(CONFIG_RTE_LIBRTE_TELEMETRY) := rte_telemetry.c\n SRCS-$(CONFIG_RTE_LIBRTE_TELEMETRY) += rte_telemetry_parser.c\n+SRCS-$(CONFIG_RTE_LIBRTE_TELEMETRY) += rte_telemetry_parser_test.c\n \n # export include files\n SYMLINK-$(CONFIG_RTE_LIBRTE_TELEMETRY)-include := rte_telemetry.h\ndiff --git a/lib/librte_telemetry/meson.build b/lib/librte_telemetry/meson.build\nindex e459d0b80..b3bbf5bd0 100644\n--- a/lib/librte_telemetry/meson.build\n+++ b/lib/librte_telemetry/meson.build\n@@ -1,8 +1,8 @@\n # SPDX-License-Identifier: BSD-3-Clause\n # Copyright(c) 2018 Intel Corporation\n \n-sources = files('rte_telemetry.c', 'rte_telemetry_parser.c')\n-headers = files('rte_telemetry.h', 'rte_telemetry_internal.h', 'rte_telemetry_parser.h')\n+sources = files('rte_telemetry.c', 'rte_telemetry_parser.c', 'rte_telemetry_parser_test.c')\n+headers = files('rte_telemetry.h', 'rte_telemetry_internal.h', 'rte_telemetry_parser.h', 'rte_telemetry_parser_test.h')\n deps += ['metrics', 'ethdev']\n cflags += '-DALLOW_EXPERIMENTAL_API'\n \ndiff --git a/lib/librte_telemetry/rte_telemetry.c b/lib/librte_telemetry/rte_telemetry.c\nindex 7616e7c91..5b66b71c4 100644\n--- a/lib/librte_telemetry/rte_telemetry.c\n+++ b/lib/librte_telemetry/rte_telemetry.c\n@@ -18,13 +18,32 @@\n #include \"rte_telemetry.h\"\n #include \"rte_telemetry_internal.h\"\n #include \"rte_telemetry_parser.h\"\n+#include \"rte_telemetry_parser_test.h\"\n+#include \"rte_telemetry_socket_tests.h\"\n \n #define BUF_SIZE 1024\n #define ACTION_POST 1\n #define SLEEP_TIME 10\n \n+#define SELFTEST_VALID_CLIENT \"/var/run/dpdk/valid_client\"\n+#define SELFTEST_INVALID_CLIENT \"/var/run/dpdk/invalid_client\"\n+#define SOCKET_TEST_CLIENT_PATH \"/var/run/dpdk/client\"\n+\n static telemetry_impl *static_telemetry;\n \n+struct telemetry_message_test {\n+\tchar *test_name;\n+\tint (*test_func_ptr)(struct telemetry_impl *telemetry, int fd);\n+};\n+\n+struct json_data {\n+\tchar *status_code;\n+\tchar *data;\n+\tint port;\n+\tchar *stat_name;\n+\tint stat_value;\n+};\n+\n static void\n rte_telemetry_get_runtime_dir(char *socket_path, size_t size)\n {\n@@ -190,7 +209,7 @@ rte_telemetry_send_error_response(struct telemetry_impl *telemetry,\n \t\treturn -EPERM;\n \t}\n \n-\tjson_buffer = json_dumps(root, JSON_INDENT(2));\n+\tjson_buffer = json_dumps(root, 0);\n \tjson_decref(root);\n \n \tret = rte_telemetry_write_to_socket(telemetry, json_buffer);\n@@ -202,6 +221,304 @@ rte_telemetry_send_error_response(struct telemetry_impl *telemetry,\n \treturn 0;\n }\n \n+static int\n+rte_telemetry_get_metrics(struct telemetry_impl *telemetry, uint32_t port_id,\n+\tstruct rte_metric_value *metrics, struct rte_metric_name *names,\n+\tint num_metrics)\n+{\n+\tint ret, num_values;\n+\n+\tif (num_metrics < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Invalid metrics count\");\n+\t\tgoto einval_fail;\n+\t} else if (num_metrics == 0) {\n+\t\tTELEMETRY_LOG_ERR(\"No metrics to display (none have been registered)\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tif (metrics == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Metrics must be initialised.\");\n+\t\tgoto einval_fail;\n+\t}\n+\n+\tif (names == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Names must be initialised.\");\n+\t\tgoto einval_fail;\n+\t}\n+\n+\tret = rte_metrics_get_names(names, num_metrics);\n+\tif (ret < 0 || ret > num_metrics) {\n+\t\tTELEMETRY_LOG_ERR(\"Cannot get metrics names\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tnum_values = rte_metrics_get_values(port_id, NULL, 0);\n+\tret = rte_metrics_get_values(port_id, metrics, num_values);\n+\tif (ret < 0 || ret > num_values) {\n+\t\tTELEMETRY_LOG_ERR(\"Cannot get metrics values\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\treturn 0;\n+\n+eperm_fail:\n+\tret = rte_telemetry_send_error_response(telemetry, -EPERM);\n+\tif (ret < 0)\n+\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n+\treturn -1;\n+\n+einval_fail:\n+\tret = rte_telemetry_send_error_response(telemetry, -EINVAL);\n+\tif (ret < 0)\n+\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n+\treturn -1;\n+\n+}\n+\n+static int32_t\n+rte_telemetry_json_format_stat(struct telemetry_impl *telemetry, json_t *stats,\n+\tconst char *metric_name, uint64_t metric_value)\n+{\n+\tint ret;\n+\tjson_t *stat = json_object();\n+\n+\tif (stat == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not create stat JSON object\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tret = json_object_set_new(stat, \"name\", json_string(metric_name));\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Stat Name field cannot be set\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tret = json_object_set_new(stat, \"value\", json_integer(metric_value));\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Stat Value field cannot be set\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tret = json_array_append_new(stats, stat);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Stat cannot be added to stats json array\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\treturn 0;\n+\n+eperm_fail:\n+\tret = rte_telemetry_send_error_response(telemetry, -EPERM);\n+\tif (ret < 0)\n+\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n+\treturn -1;\n+\n+}\n+\n+static int32_t\n+rte_telemetry_json_format_port(struct telemetry_impl *telemetry,\n+\tuint32_t port_id, json_t *ports, uint32_t *metric_ids,\n+\tuint32_t num_metric_ids)\n+{\n+\tstruct rte_metric_value *metrics = 0;\n+\tstruct rte_metric_name *names = 0;\n+\tint num_metrics, ret, err_ret;\n+\tjson_t *port, *stats;\n+\tuint32_t i;\n+\n+\tnum_metrics = rte_metrics_get_names(NULL, 0);\n+\tif (num_metrics < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Cannot get metrics count\");\n+\t\tgoto einval_fail;\n+\t} else if (num_metrics == 0) {\n+\t\tTELEMETRY_LOG_ERR(\"No metrics to display (none have been registered)\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tmetrics = malloc(sizeof(struct rte_metric_value) * num_metrics);\n+\tnames = malloc(sizeof(struct rte_metric_name) * num_metrics);\n+\tif (metrics == NULL || names == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Cannot allocate memory\");\n+\t\tfree(metrics);\n+\t\tfree(names);\n+\n+\t\terr_ret = rte_telemetry_send_error_response(telemetry, -ENOMEM);\n+\t\tif (err_ret < 0)\n+\t\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n+\t\treturn -1;\n+\t}\n+\n+\tret  = rte_telemetry_get_metrics(telemetry, port_id, metrics, names,\n+\t\tnum_metrics);\n+\tif (ret < 0) {\n+\t\tfree(metrics);\n+\t\tfree(names);\n+\t\tTELEMETRY_LOG_ERR(\"rte_telemetry_get_metrics failed\");\n+\t\treturn -1;\n+\t}\n+\n+\tport = json_object();\n+\tstats = json_array();\n+\tif (port == NULL || stats == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not create port/stats JSON objects\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tret = json_object_set_new(port, \"port\", json_integer(port_id));\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Port field cannot be set\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tfor (i = 0; i < num_metric_ids; i++) {\n+\t\tint metric_id = metric_ids[i];\n+\t\tint metric_index = -1;\n+\t\tint metric_name_key = -1;\n+\t\tint32_t j;\n+\t\tuint64_t metric_value;\n+\n+\t\tif (metric_id >= num_metrics) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Metric_id: %d is not valid\",\n+\t\t\t\t\tmetric_id);\n+\t\t\tgoto einval_fail;\n+\t\t}\n+\n+\t\tfor (j = 0; j < num_metrics; j++) {\n+\t\t\tif (metrics[j].key == metric_id) {\n+\t\t\t\tmetric_name_key = metrics[j].key;\n+\t\t\t\tmetric_index = j;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\n+\t\tconst char *metric_name = names[metric_name_key].name;\n+\t\tmetric_value = metrics[metric_index].value;\n+\n+\t\tif (metric_name_key < 0 || metric_index < 0) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Could not get metric name/index\");\n+\t\t\tgoto eperm_fail;\n+\t\t}\n+\n+\t\tret = rte_telemetry_json_format_stat(telemetry, stats,\n+\t\t\tmetric_name, metric_value);\n+\t\tif (ret < 0) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Format stat with id: %u failed\",\n+\t\t\t\t\tmetric_id);\n+\t\t\tfree(metrics);\n+\t\t\tfree(names);\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\tif (json_array_size(stats) == 0)\n+\t\tret = json_object_set_new(port, \"stats\", json_null());\n+\telse\n+\t\tret = json_object_set_new(port, \"stats\", stats);\n+\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Stats object cannot be set\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tret = json_array_append_new(ports, port);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Port object cannot be added to ports array\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tfree(metrics);\n+\tfree(names);\n+\treturn 0;\n+\n+eperm_fail:\n+\tfree(metrics);\n+\tfree(names);\n+\tret = rte_telemetry_send_error_response(telemetry, -EPERM);\n+\tif (ret < 0)\n+\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n+\treturn -1;\n+\n+einval_fail:\n+\tfree(metrics);\n+\tfree(names);\n+\tret = rte_telemetry_send_error_response(telemetry, -EINVAL);\n+\tif (ret < 0)\n+\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n+\treturn -1;\n+}\n+\n+static int32_t\n+rte_telemetry_encode_json_format(struct telemetry_impl *telemetry,\n+\tuint32_t *port_ids, uint32_t num_port_ids, uint32_t *metric_ids,\n+\tuint32_t num_metric_ids, char **json_buffer)\n+{\n+\tint ret;\n+\tjson_t *root, *ports;\n+\tuint32_t i;\n+\n+\tif (num_port_ids <= 0 || num_metric_ids <= 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Please provide port and metric ids to query\");\n+\t\tgoto einval_fail;\n+\t}\n+\n+\tports = json_array();\n+\tif (ports == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not create ports JSON array\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tfor (i = 0; i < num_port_ids; i++) {\n+\t\tif (!rte_eth_dev_is_valid_port(port_ids[i])) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Port: %d invalid\", port_ids[i]);\n+\t\t\tgoto einval_fail;\n+\t\t}\n+\t}\n+\n+\tfor (i = 0; i < num_port_ids; i++) {\n+\t\tret = rte_telemetry_json_format_port(telemetry, port_ids[i],\n+\t\t\tports, metric_ids, num_metric_ids);\n+\t\tif (ret < 0) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Format port in JSON failed\");\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\troot = json_object();\n+\tif (root == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not create root JSON object\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tret = json_object_set_new(root, \"status_code\",\n+\t\tjson_string(\"Status OK: 200\"));\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Status code field cannot be set\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\tret = json_object_set_new(root, \"data\", ports);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Data field cannot be set\");\n+\t\tgoto eperm_fail;\n+\t}\n+\n+\t*json_buffer = json_dumps(root, JSON_INDENT(2));\n+\tjson_decref(root);\n+\treturn 0;\n+\n+eperm_fail:\n+\tret = rte_telemetry_send_error_response(telemetry, -EPERM);\n+\tif (ret < 0)\n+\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n+\treturn -1;\n+\n+einval_fail:\n+\tret = rte_telemetry_send_error_response(telemetry, -EINVAL);\n+\tif (ret < 0)\n+\t\tTELEMETRY_LOG_ERR(\"Could not send error\");\n+\treturn -1;\n+}\n+\n int32_t\n rte_telemetry_send_ports_stats_values(uint32_t *metric_ids, int num_metric_ids,\n \tuint32_t *port_ids, int num_port_ids, struct telemetry_impl *telemetry)\n@@ -241,13 +558,20 @@ rte_telemetry_send_ports_stats_values(uint32_t *metric_ids, int num_metric_ids,\n \t\t}\n \n \t\tret = rte_telemetry_update_metrics_ethdev(telemetry,\n-\t\t\tport_ids[i], telemetry->reg_index);\n+\t\t\t\tport_ids[i], telemetry->reg_index);\n \t\tif (ret < 0) {\n \t\t\tTELEMETRY_LOG_ERR(\"Failed to update ethdev metrics\");\n \t\t\treturn -1;\n \t\t}\n \t}\n \n+\tret = rte_telemetry_encode_json_format(telemetry, port_ids,\n+\t\tnum_port_ids, metric_ids, num_metric_ids, &json_buffer);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"JSON encode function failed\");\n+\t\treturn -1;\n+\t}\n+\n \tret = rte_telemetry_write_to_socket(telemetry, json_buffer);\n \tif (ret < 0) {\n \t\tTELEMETRY_LOG_ERR(\"Could not write to socket\");\n@@ -335,6 +659,7 @@ static int32_t\n rte_telemetry_initial_accept(struct telemetry_impl *telemetry)\n {\n \tuint16_t pid;\n+\tint ret;\n \n \tRTE_ETH_FOREACH_DEV(pid) {\n \t\ttelemetry->reg_index = rte_telemetry_reg_ethdev_to_metrics(pid);\n@@ -347,6 +672,18 @@ rte_telemetry_initial_accept(struct telemetry_impl *telemetry)\n \t}\n \n \ttelemetry->metrics_register_done = 1;\n+\tret = rte_telemetry_socket_messaging_testing(telemetry->reg_index,\n+\t\ttelemetry->server_fd);\n+\tif (ret < 0)\n+\t\treturn -1;\n+\n+\tret = rte_telemetry_parser_test(telemetry);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Parser Tests Failed\");\n+\t\treturn -1;\n+\t}\n+\n+\tTELEMETRY_LOG_INFO(\"Success - All Parser Tests Passed\");\n \n \treturn 0;\n }\n@@ -834,6 +1171,627 @@ rte_telemetry_parse_client_message(struct telemetry_impl *telemetry, char *buf)\n \treturn -1;\n }\n \n+int32_t\n+rte_telemetry_dummy_client_socket(const char *valid_client_path)\n+{\n+\tint sockfd = socket(AF_UNIX, SOCK_SEQPACKET, 0);\n+\tstruct sockaddr_un addr = {0};\n+\n+\tif (sockfd < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Test socket creation failure\");\n+\t\treturn -1;\n+\t}\n+\n+\taddr.sun_family = AF_UNIX;\n+\tstrlcpy(addr.sun_path, valid_client_path, sizeof(addr.sun_path));\n+\tunlink(valid_client_path);\n+\n+\tif (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Test socket binding failure\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (listen(sockfd, 1) < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Listen failure\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn sockfd;\n+}\n+\n+int32_t __rte_experimental\n+rte_telemetry_selftest(void)\n+{\n+\tconst char *invalid_client_path = SELFTEST_INVALID_CLIENT;\n+\tconst char *valid_client_path = SELFTEST_VALID_CLIENT;\n+\tint ret, sockfd;\n+\n+\tTELEMETRY_LOG_INFO(\"Selftest\");\n+\n+\tret = rte_telemetry_init();\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Valid initialisation test failed\");\n+\t\treturn -1;\n+\t}\n+\n+\tTELEMETRY_LOG_INFO(\"Success - Valid initialisation test passed\");\n+\n+\tret = rte_telemetry_init();\n+\tif (ret != -EALREADY) {\n+\t\tTELEMETRY_LOG_ERR(\"Invalid initialisation test failed\");\n+\t\treturn -1;\n+\t}\n+\n+\tTELEMETRY_LOG_INFO(\"Success - Invalid initialisation test passed\");\n+\n+\tret = rte_telemetry_unregister_client(static_telemetry,\n+\t\t\tinvalid_client_path);\n+\tif (ret != -EPERM) {\n+\t\tTELEMETRY_LOG_ERR(\"Invalid unregister test failed\");\n+\t\treturn -1;\n+\t}\n+\n+\tTELEMETRY_LOG_INFO(\"Success - Invalid unregister test passed\");\n+\n+\tsockfd = rte_telemetry_dummy_client_socket(valid_client_path);\n+\tif (sockfd < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Test socket creation failed\");\n+\t\treturn -1;\n+\t}\n+\n+\tret = rte_telemetry_register_client(static_telemetry, valid_client_path);\n+\tif (ret != 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Valid register test failed: %i\", ret);\n+\t\treturn -1;\n+\t}\n+\n+\taccept(sockfd, NULL, NULL);\n+\tTELEMETRY_LOG_INFO(\"Success - Valid register test passed\");\n+\n+\tret = rte_telemetry_register_client(static_telemetry, valid_client_path);\n+\tif (ret != -EINVAL) {\n+\t\tTELEMETRY_LOG_ERR(\"Invalid register test failed: %i\", ret);\n+\t\treturn -1;\n+\t}\n+\n+\tTELEMETRY_LOG_INFO(\"Success - Invalid register test passed\");\n+\n+\tret = rte_telemetry_unregister_client(static_telemetry,\n+\t\tinvalid_client_path);\n+\tif (ret != -1) {\n+\t\tTELEMETRY_LOG_ERR(\"Invalid unregister test failed: %i\", ret);\n+\t\treturn -1;\n+\t}\n+\n+\tTELEMETRY_LOG_INFO(\"Success - Invalid unregister test passed\");\n+\n+\tret = rte_telemetry_unregister_client(static_telemetry, valid_client_path);\n+\tif (ret != 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Valid unregister test failed: %i\", ret);\n+\t\treturn -1;\n+\t}\n+\n+\tTELEMETRY_LOG_INFO(\"Success - Valid unregister test passed\");\n+\n+\tret = rte_telemetry_cleanup();\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Cleanup test failed\");\n+\t\treturn -1;\n+\t}\n+\n+\tTELEMETRY_LOG_INFO(\"Success - Valid cleanup test passed\");\n+\n+\treturn 0;\n+}\n+\n+int32_t\n+rte_telemetry_socket_messaging_testing(int index, int socket)\n+{\n+\tstruct telemetry_impl *telemetry = calloc(1, sizeof(telemetry_impl));\n+\tint fd, bad_send_fd, send_fd, bad_fd, bad_recv_fd, recv_fd, ret;\n+\n+\tif (telemetry == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not initialize Telemetry API\");\n+\t\treturn -1;\n+\t}\n+\n+\ttelemetry->server_fd = socket;\n+\ttelemetry->reg_index = index;\n+\tTELEMETRY_LOG_INFO(\"Beginning Telemetry socket message Selftest\");\n+\trte_telemetry_socket_test_setup(telemetry, &send_fd, &recv_fd);\n+\tTELEMETRY_LOG_INFO(\"Register valid client test\");\n+\n+\tret = rte_telemetry_socket_register_test(telemetry, &fd, send_fd,\n+\t\trecv_fd);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Register valid client test failed!\");\n+\t\tfree(telemetry);\n+\t\treturn -1;\n+\t}\n+\n+\tTELEMETRY_LOG_INFO(\"Success - Register valid client test passed!\");\n+\n+\tTELEMETRY_LOG_INFO(\"Register invalid/same client test\");\n+\tret = rte_telemetry_socket_test_setup(telemetry, &bad_send_fd,\n+\t\t&bad_recv_fd);\n+\tret = rte_telemetry_socket_register_test(telemetry, &bad_fd,\n+\t\tbad_send_fd, bad_recv_fd);\n+\tif (!ret) {\n+\t\tTELEMETRY_LOG_ERR(\"Register invalid/same client test failed!\");\n+\t\tfree(telemetry);\n+\t\treturn -1;\n+\t}\n+\n+\tTELEMETRY_LOG_INFO(\"Success - Register invalid/same client test passed!\");\n+\n+\tret = rte_telemetry_json_socket_message_test(telemetry, fd);\n+\tif (ret < 0) {\n+\t\tfree(telemetry);\n+\t\treturn -1;\n+\t}\n+\n+\tfree(telemetry);\n+\treturn 0;\n+}\n+\n+int32_t\n+rte_telemetry_socket_register_test(struct telemetry_impl *telemetry, int *fd,\n+\tint send_fd, int recv_fd)\n+{\n+\tint ret;\n+\tchar good_req_string[BUF_SIZE];\n+\n+\tsnprintf(good_req_string, sizeof(good_req_string),\n+\t\"{\\\"action\\\":1,\\\"command\\\":\\\"clients\\\",\\\"data\\\":{\\\"client_path\\\"\"\n+\t\t\":\\\"%s\\\"}}\", SOCKET_TEST_CLIENT_PATH);\n+\n+\tlisten(recv_fd, 1);\n+\n+\tret = send(send_fd, good_req_string, strlen(good_req_string), 0);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not send message over socket\");\n+\t\treturn -1;\n+\t}\n+\n+\trte_telemetry_run(telemetry);\n+\n+\tif (telemetry->register_fail_count != 0)\n+\t\treturn -1;\n+\n+\t*fd = accept(recv_fd, NULL, NULL);\n+\n+\treturn 0;\n+}\n+\n+int32_t\n+rte_telemetry_socket_test_setup(struct telemetry_impl *telemetry, int *send_fd,\n+\tint *recv_fd)\n+{\n+\tint ret;\n+\tconst char *client_path = SOCKET_TEST_CLIENT_PATH;\n+\tchar socket_path[BUF_SIZE];\n+\tstruct sockaddr_un addr = {0};\n+\tstruct sockaddr_un addrs = {0};\n+\t*send_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);\n+\t*recv_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);\n+\n+\tlisten(telemetry->server_fd, 5);\n+\taddr.sun_family = AF_UNIX;\n+\trte_telemetry_get_runtime_dir(socket_path, sizeof(socket_path));\n+\tstrlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));\n+\n+\tret = connect(*send_fd, (struct sockaddr *) &addr, sizeof(addr));\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not connect socket\");\n+\t\treturn -1;\n+\t}\n+\n+\ttelemetry->accept_fd = accept(telemetry->server_fd, NULL, NULL);\n+\n+\taddrs.sun_family = AF_UNIX;\n+\tstrlcpy(addrs.sun_path, client_path, sizeof(addrs.sun_path));\n+\tunlink(client_path);\n+\n+\tret = bind(*recv_fd, (struct sockaddr *)&addrs, sizeof(addrs));\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not bind socket\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int32_t\n+rte_telemetry_stat_parse(char *buf, struct json_data *json_data_struct)\n+{\n+\tjson_error_t error;\n+\tjson_t *root = json_loads(buf, 0, &error);\n+\tint arraylen, i;\n+\tjson_t *status, *dataArray, *port, *stats, *name, *value, *dataArrayObj,\n+\t       *statsArrayObj;\n+\n+\tstats = NULL;\n+\tport = NULL;\n+\tname = NULL;\n+\n+\tif (buf == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"JSON message is NULL\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (root == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not load JSON object from data passed in : %s\",\n+\t\t\t\terror.text);\n+\t\treturn -EPERM;\n+\t} else if (!json_is_object(root)) {\n+\t\tTELEMETRY_LOG_ERR(\"JSON Request is not a JSON object\");\n+\t\tjson_decref(root);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tstatus = json_object_get(root, \"status_code\");\n+\tif (!status) {\n+\t\tTELEMETRY_LOG_ERR(\"Request does not have status field\");\n+\t\treturn -EINVAL;\n+\t} else if (!json_is_string(status)) {\n+\t\tTELEMETRY_LOG_ERR(\"Status value is not a string\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tjson_data_struct->status_code = strdup(json_string_value(status));\n+\n+\tdataArray = json_object_get(root, \"data\");\n+\tif (dataArray == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Request does not have data field\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tarraylen = json_array_size(dataArray);\n+\tif (arraylen == 0) {\n+\t\tjson_data_struct->data = \"null\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tfor (i = 0; i < arraylen; i++) {\n+\t\tdataArrayObj = json_array_get(dataArray, i);\n+\t\tport = json_object_get(dataArrayObj, \"port\");\n+\t\tstats = json_object_get(dataArrayObj, \"stats\");\n+\t}\n+\n+\tif (port == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Request does not have port field\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!json_is_integer(port)) {\n+\t\tTELEMETRY_LOG_ERR(\"Port value is not an integer\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tjson_data_struct->port = json_integer_value(port);\n+\n+\tif (stats == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Request does not have stats field\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tarraylen = json_array_size(stats);\n+\tfor (i = 0; i < arraylen; i++) {\n+\t\tstatsArrayObj = json_array_get(stats, i);\n+\t\tname = json_object_get(statsArrayObj, \"name\");\n+\t\tvalue = json_object_get(statsArrayObj, \"value\");\n+\t}\n+\n+\tif (name == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Request does not have name field\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!json_is_string(name)) {\n+\t\tTELEMETRY_LOG_ERR(\"Stat name value is not a string\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tjson_data_struct->stat_name = strdup(json_string_value(name));\n+\n+\tif (value == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Request does not have value field\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!json_is_integer(value)) {\n+\t\tTELEMETRY_LOG_ERR(\"Stat value is not an integer\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tjson_data_struct->stat_value = json_integer_value(value);\n+\n+\treturn 0;\n+}\n+\n+static void\n+rte_telemetry_free_test_data(struct json_data *data)\n+{\n+\tfree(data->status_code);\n+\tfree(data->stat_name);\n+\tfree(data);\n+}\n+\n+int32_t\n+rte_telemetry_valid_json_test(struct telemetry_impl *telemetry, int fd)\n+{\n+\tint ret;\n+\tint port = 0;\n+\tint value = 0;\n+\tint fail_count = 0;\n+\tint buffer_read = 0;\n+\tchar buf[BUF_SIZE];\n+\tstruct json_data *data_struct;\n+\terrno = 0;\n+\tconst char *status = \"Status OK: 200\";\n+\tconst char *name = \"rx_good_packets\";\n+\tconst char *valid_json_message = \"{\\\"action\\\":0,\\\"command\\\":\"\n+\t\"\\\"ports_stats_values_by_name\\\",\\\"data\\\":{\\\"ports\\\"\"\n+\t\":[0],\\\"stats\\\":[\\\"rx_good_packets\\\"]}}\";\n+\n+\tret = send(fd, valid_json_message, strlen(valid_json_message), 0);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not send message over socket\");\n+\t\treturn -1;\n+\t}\n+\n+\trte_telemetry_run(telemetry);\n+\tbuffer_read = recv(fd, buf, BUF_SIZE-1, 0);\n+\n+\tif (buffer_read == -1) {\n+\t\tTELEMETRY_LOG_ERR(\"Read error\");\n+\t\treturn -1;\n+\t}\n+\n+\tbuf[buffer_read] = '\\0';\n+\tdata_struct = calloc(1, sizeof(struct json_data));\n+\tret = rte_telemetry_stat_parse(buf, data_struct);\n+\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not parse stats\");\n+\t\tfail_count++;\n+\t}\n+\n+\tif (strcmp(data_struct->status_code, status) != 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Status code is invalid\");\n+\t\tfail_count++;\n+\t}\n+\n+\tif (data_struct->port != port) {\n+\t\tTELEMETRY_LOG_ERR(\"Port is invalid\");\n+\t\tfail_count++;\n+\t}\n+\n+\tif (strcmp(data_struct->stat_name, name) != 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Stat name is invalid\");\n+\t\tfail_count++;\n+\t}\n+\n+\tif (data_struct->stat_value != value) {\n+\t\tTELEMETRY_LOG_ERR(\"Stat value is invalid\");\n+\t\tfail_count++;\n+\t}\n+\n+\trte_telemetry_free_test_data(data_struct);\n+\tif (fail_count > 0)\n+\t\treturn -1;\n+\n+\tTELEMETRY_LOG_INFO(\"Success - Passed valid JSON message test passed\");\n+\n+\treturn 0;\n+}\n+\n+int32_t\n+rte_telemetry_invalid_json_test(struct telemetry_impl *telemetry, int fd)\n+{\n+\tint ret;\n+\tchar buf[BUF_SIZE];\n+\tint fail_count = 0;\n+\tconst char *invalid_json = \"{]\";\n+\tconst char *status = \"Status Error: Unknown\";\n+\tconst char *data = \"null\";\n+\tstruct json_data *data_struct;\n+\tint buffer_read = 0;\n+\terrno = 0;\n+\n+\tret = send(fd, invalid_json, strlen(invalid_json), 0);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not send message over socket\");\n+\t\treturn -1;\n+\t}\n+\n+\trte_telemetry_run(telemetry);\n+\tbuffer_read = recv(fd, buf, BUF_SIZE-1, 0);\n+\n+\tif (buffer_read == -1) {\n+\t\tTELEMETRY_LOG_ERR(\"Read error\");\n+\t\treturn -1;\n+\t}\n+\n+\tbuf[buffer_read] = '\\0';\n+\n+\tdata_struct = calloc(1, sizeof(struct json_data));\n+\tret = rte_telemetry_stat_parse(buf, data_struct);\n+\n+\tif (ret < 0)\n+\t\tTELEMETRY_LOG_ERR(\"Could not parse stats\");\n+\n+\tif (strcmp(data_struct->status_code, status) != 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Status code is invalid\");\n+\t\tfail_count++;\n+\t}\n+\n+\tif (strcmp(data_struct->data, data) != 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Data status is invalid\");\n+\t\tfail_count++;\n+\t}\n+\n+\trte_telemetry_free_test_data(data_struct);\n+\tif (fail_count > 0)\n+\t\treturn -1;\n+\n+\tTELEMETRY_LOG_INFO(\"Success - Passed invalid JSON message test\");\n+\n+\treturn 0;\n+}\n+\n+int32_t\n+rte_telemetry_json_contents_test(struct telemetry_impl *telemetry, int fd)\n+{\n+\tint ret;\n+\tchar buf[BUF_SIZE];\n+\tint fail_count = 0;\n+\tchar *status = \"Status Error: Invalid Argument 404\";\n+\tchar *data = \"null\";\n+\tstruct json_data *data_struct;\n+\tconst char *invalid_contents = \"{\\\"action\\\":0,\\\"command\\\":\"\n+\t\"\\\"ports_stats_values_by_name\\\",\\\"data\\\":{\\\"ports\\\"\"\n+\t\":[0],\\\"stats\\\":[\\\"some_invalid_param\\\",\"\n+\t\"\\\"another_invalid_param\\\"]}}\";\n+\tint buffer_read = 0;\n+\terrno = 0;\n+\n+\tret = send(fd, invalid_contents, strlen(invalid_contents), 0);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not send message over socket\");\n+\t\treturn -1;\n+\t}\n+\n+\trte_telemetry_run(telemetry);\n+\tbuffer_read = recv(fd, buf, BUF_SIZE-1, 0);\n+\n+\tif (buffer_read == -1) {\n+\t\tTELEMETRY_LOG_ERR(\"Read error\");\n+\t\treturn -1;\n+\t}\n+\n+\tbuf[buffer_read] = '\\0';\n+\tdata_struct = calloc(1, sizeof(struct json_data));\n+\tret = rte_telemetry_stat_parse(buf, data_struct);\n+\n+\tif (ret < 0)\n+\t\tTELEMETRY_LOG_ERR(\"Could not parse stats\");\n+\n+\tif (strcmp(data_struct->status_code, status) != 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Status code is invalid\");\n+\t\tfail_count++;\n+\t}\n+\n+\tif (strcmp(data_struct->data, data) != 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Data status is invalid\");\n+\t\tfail_count++;\n+\t}\n+\n+\trte_telemetry_free_test_data(data_struct);\n+\tif (fail_count > 0)\n+\t\treturn -1;\n+\n+\tTELEMETRY_LOG_INFO(\"Success - Passed invalid JSON content test\");\n+\n+\treturn 0;\n+}\n+\n+int32_t\n+rte_telemetry_json_empty_test(struct telemetry_impl *telemetry, int fd)\n+{\n+\tint ret;\n+\tchar buf[BUF_SIZE];\n+\tint fail_count = 0;\n+\tconst char *status = \"Status Error: Invalid Argument 404\";\n+\tchar *data = \"null\";\n+\tstruct json_data *data_struct;\n+\tconst char *empty_json  = \"{}\";\n+\tint buffer_read = 0;\n+\terrno = 0;\n+\n+\tret = (send(fd, empty_json, strlen(empty_json), 0));\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not send message over socket\");\n+\t\treturn -1;\n+\t}\n+\n+\trte_telemetry_run(telemetry);\n+\tbuffer_read = recv(fd, buf, BUF_SIZE-1, 0);\n+\n+\tif (buffer_read == -1) {\n+\t\tTELEMETRY_LOG_ERR(\"Read error\");\n+\t\treturn -1;\n+\t}\n+\n+\tbuf[buffer_read] = '\\0';\n+\tdata_struct = calloc(1, sizeof(struct json_data));\n+\tret = rte_telemetry_stat_parse(buf, data_struct);\n+\n+\tif (ret < 0)\n+\t\tTELEMETRY_LOG_ERR(\"Could not parse stats\");\n+\n+\tif (strcmp(data_struct->status_code, status) != 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Status code is invalid\");\n+\t\tfail_count++;\n+\t}\n+\n+\tif (strcmp(data_struct->data, data) != 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Data status is invalid\");\n+\t\tfail_count++;\n+\t}\n+\n+\trte_telemetry_free_test_data(data_struct);\n+\n+\tif (fail_count > 0)\n+\t\treturn -1;\n+\n+\tTELEMETRY_LOG_INFO(\"Success - Passed JSON empty message test\");\n+\n+\treturn 0;\n+}\n+\n+int32_t\n+rte_telemetry_json_socket_message_test(struct telemetry_impl *telemetry, int fd)\n+{\n+\tuint16_t i;\n+\tint ret, fail_count;\n+\n+\tfail_count = 0;\n+\tstruct telemetry_message_test socket_json_tests[] = {\n+\t\t{.test_name = \"Invalid JSON test\",\n+\t\t\t.test_func_ptr = rte_telemetry_invalid_json_test},\n+\t\t{.test_name = \"Valid JSON test\",\n+\t\t\t.test_func_ptr = rte_telemetry_valid_json_test},\n+\t\t{.test_name = \"JSON contents test\",\n+\t\t\t.test_func_ptr = rte_telemetry_json_contents_test},\n+\t\t{.test_name = \"JSON empty tests\",\n+\t\t\t.test_func_ptr = rte_telemetry_json_empty_test}\n+\t\t};\n+\n+#define NUM_TESTS RTE_DIM(socket_json_tests)\n+\n+\tfor (i = 0; i < NUM_TESTS; i++) {\n+\t\tTELEMETRY_LOG_INFO(\"%s\", socket_json_tests[i].test_name);\n+\t\tret = (socket_json_tests[i].test_func_ptr)\n+\t\t\t(telemetry, fd);\n+\t\tif (ret < 0) {\n+\t\t\tTELEMETRY_LOG_ERR(\"%s failed\",\n+\t\t\t\t\tsocket_json_tests[i].test_name);\n+\t\t\tfail_count++;\n+\t\t}\n+\t}\n+\n+\tif (fail_count > 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Failed %i JSON socket message test(s)\",\n+\t\t\t\tfail_count);\n+\t\treturn -1;\n+\t}\n+\n+\tTELEMETRY_LOG_INFO(\"Success - All JSON tests passed\");\n+\n+\treturn 0;\n+}\n+\n int telemetry_log_level;\n RTE_INIT(rte_telemetry_register);\n \ndiff --git a/lib/librte_telemetry/rte_telemetry.h b/lib/librte_telemetry/rte_telemetry.h\nindex 97674ae2d..119db16fe 100644\n--- a/lib/librte_telemetry/rte_telemetry.h\n+++ b/lib/librte_telemetry/rte_telemetry.h\n@@ -48,4 +48,19 @@ rte_telemetry_init(void);\n int32_t __rte_experimental\n rte_telemetry_cleanup(void);\n \n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice\n+ *\n+ * Runs various tests to ensure telemetry initialisation and register/unregister\n+ * functions are working correctly.\n+ *\n+ * @return\n+ *  0 on success when all tests have passed\n+ * @return\n+ *  -1 on failure when the test has failed\n+ */\n+int32_t __rte_experimental\n+rte_telemetry_selftest(void);\n+\n #endif\ndiff --git a/lib/librte_telemetry/rte_telemetry_internal.h b/lib/librte_telemetry/rte_telemetry_internal.h\nindex 0082cb2ca..de7afda30 100644\n--- a/lib/librte_telemetry/rte_telemetry_internal.h\n+++ b/lib/librte_telemetry/rte_telemetry_internal.h\n@@ -75,4 +75,7 @@ int32_t\n rte_telemetry_send_ports_stats_values(uint32_t *metric_ids, int num_metric_ids,\n \tuint32_t *port_ids, int num_port_ids, struct telemetry_impl *telemetry);\n \n+int32_t\n+rte_telemetry_socket_messaging_testing(int index, int socket);\n+\n #endif\ndiff --git a/lib/librte_telemetry/rte_telemetry_parser_test.c b/lib/librte_telemetry/rte_telemetry_parser_test.c\nnew file mode 100644\nindex 000000000..5fe93fa6e\n--- /dev/null\n+++ b/lib/librte_telemetry/rte_telemetry_parser_test.c\n@@ -0,0 +1,534 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018 Intel Corporation\n+ */\n+\n+#include <stdio.h>\n+#include <stdint.h>\n+#include <string.h>\n+#include <errno.h>\n+#include <jansson.h>\n+#include <sys/socket.h>\n+#include <sys/un.h>\n+#include <unistd.h>\n+\n+#include <rte_common.h>\n+#include <rte_tailq.h>\n+#include <rte_string_fns.h>\n+\n+#include \"rte_telemetry_parser.h\"\n+\n+enum choices {\n+\tINV_ACTION_VAL,\n+\tINV_COMMAND_VAL,\n+\tINV_DATA_VAL,\n+\tINV_ACTION_FIELD,\n+\tINV_COMMAND_FIELD,\n+\tINV_DATA_FIELD,\n+\tINV_JSON_FORMAT,\n+\tVALID_REQ\n+};\n+\n+\n+#define TEST_CLIENT \"/var/run/dpdk/test_client\"\n+\n+int32_t\n+rte_telemetry_create_test_socket(struct telemetry_impl *telemetry,\n+\tconst char *test_client_path)\n+{\n+\tint ret, sockfd;\n+\tstruct sockaddr_un addr = {0};\n+\tstruct telemetry_client *client;\n+\n+\tif (telemetry == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Telemetry argument has not been initialised\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tsockfd = socket(AF_UNIX, SOCK_SEQPACKET, 0);\n+\tif (sockfd < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Test socket creation failure\");\n+\t\treturn -1;\n+\t}\n+\n+\taddr.sun_family = AF_UNIX;\n+\tstrlcpy(addr.sun_path, test_client_path, sizeof(addr.sun_path));\n+\tunlink(test_client_path);\n+\n+\tif (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Test socket binding failure\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (listen(sockfd, 1) < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Listen failure\");\n+\t\treturn -1;\n+\t}\n+\n+\tret = rte_telemetry_register_client(telemetry, test_client_path);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Register dummy client failed: %i\", ret);\n+\t\treturn -1;\n+\t}\n+\n+\tret = accept(sockfd, NULL, NULL);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Socket accept failed\");\n+\t\treturn -1;\n+\t}\n+\n+\tTAILQ_FOREACH(client, &telemetry->client_list_head, client_list)\n+\t\ttelemetry->request_client = client;\n+\n+\treturn 0;\n+}\n+\n+int32_t\n+rte_telemetry_format_port_stat_ids(int *port_ids, int num_port_ids,\n+\tconst char * const *stat_names, int num_stat_names, json_t **data)\n+{\n+\n+\tint ret;\n+\tjson_t *stat_names_json_array = NULL;\n+\tjson_t *port_ids_json_array = NULL;\n+\tuint32_t i;\n+\n+\tif (num_port_ids < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Port Ids Count invalid\");\n+\t\tgoto fail;\n+\t}\n+\n+\t*data = json_object();\n+\tif (*data == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Data json object creation failed\");\n+\t\tgoto fail;\n+\t}\n+\n+\tport_ids_json_array = json_array();\n+\tif (port_ids_json_array == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"port_ids_json_array creation failed\");\n+\t\tgoto fail;\n+\t}\n+\n+\tfor (i = 0; i < (uint32_t)num_port_ids; i++) {\n+\t\tret = json_array_append(port_ids_json_array,\n+\t\t\t\tjson_integer(port_ids[i]));\n+\t\tif (ret < 0) {\n+\t\t\tTELEMETRY_LOG_ERR(\"JSON array creation failed\");\n+\t\t\tgoto fail;\n+\t\t}\n+\t}\n+\n+\tret = json_object_set_new(*data, \"ports\", port_ids_json_array);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Setting 'ports' value in data object failed\");\n+\t\tgoto fail;\n+\t}\n+\n+\tif (stat_names) {\n+\t\tif (num_stat_names < 0) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Stat Names Count invalid\");\n+\t\t\tgoto fail;\n+\t\t}\n+\n+\t\tstat_names_json_array = json_array();\n+\t\tif (stat_names_json_array == NULL) {\n+\t\t\tTELEMETRY_LOG_ERR(\"stat_names_json_array creation failed\");\n+\t\t\tgoto fail;\n+\t\t}\n+\n+\t\tuint32_t i;\n+\t\tfor (i = 0; i < (uint32_t)num_stat_names; i++) {\n+\t\t\tret = json_array_append(stat_names_json_array,\n+\t\t\t\t json_string(stat_names[i]));\n+\t\t\tif (ret < 0) {\n+\t\t\t\tTELEMETRY_LOG_ERR(\"JSON array creation failed\");\n+\t\t\t\tgoto fail;\n+\t\t\t}\n+\t\t}\n+\n+\t\tret = json_object_set_new(*data, \"stats\", stat_names_json_array);\n+\t\tif (ret < 0) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Setting 'stats' value in data object failed\");\n+\t\t\tgoto fail;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+\n+fail:\n+\tif (*data)\n+\t\tjson_decref(*data);\n+\tif (stat_names_json_array)\n+\t\tjson_decref(stat_names_json_array);\n+\tif (port_ids_json_array)\n+\t\tjson_decref(port_ids_json_array);\n+\treturn -1;\n+}\n+\n+int32_t\n+rte_telemetry_create_json_request(int action, char *command,\n+\tconst char *client_path, int *port_ids, int num_port_ids,\n+\tconst char * const *stat_names, int num_stat_names, char **request,\n+\tint inv_choice)\n+{\n+\tint ret;\n+\tjson_t *root = json_object();\n+\tjson_t *data;\n+\n+\tif (root == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not create root json object\");\n+\t\tgoto fail;\n+\t}\n+\n+\tif (inv_choice == INV_ACTION_FIELD) {\n+\t\tret = json_object_set_new(root, \"ac--on\", json_integer(action));\n+\t\tif (ret < 0) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Setting invalid action field in root object failed\");\n+\t\t\tgoto fail;\n+\t\t}\n+\t} else {\n+\t\tret = json_object_set_new(root, \"action\", json_integer(action));\n+\t\tif (ret < 0) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Setting valid action field in root object failed\");\n+\t\t\tgoto fail;\n+\t\t}\n+\t}\n+\n+\tif (inv_choice == INV_COMMAND_FIELD) {\n+\t\tret = json_object_set_new(root, \"co---nd\", json_string(command));\n+\t\tif (ret < 0) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Setting invalid command field in root object failed\");\n+\t\t\tgoto fail;\n+\t\t}\n+\t} else {\n+\t\tret = json_object_set_new(root, \"command\", json_string(command));\n+\t\tif (ret < 0) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Setting valid command field in root object failed\");\n+\t\t\tgoto fail;\n+\t\t}\n+\t}\n+\n+\tdata = json_null();\n+\tif (client_path) {\n+\t\tdata = json_object();\n+\t\tif (data == NULL) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Data json object creation failed\");\n+\t\t\tgoto fail;\n+\t\t}\n+\n+\t\tret = json_object_set_new(data, \"client_path\",\n+\t\t\t\tjson_string(client_path));\n+\t\tif (ret < 0) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Setting valid client_path field in data object failed\");\n+\t\t\tgoto fail;\n+\t\t}\n+\n+\t} else if (port_ids) {\n+\t\tret = rte_telemetry_format_port_stat_ids(port_ids, num_port_ids,\n+\t\t\t\tstat_names, num_stat_names, &data);\n+\t\tif (ret < 0) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Formatting Port/Stat arrays failed\");\n+\t\t\tgoto fail;\n+\t\t}\n+\n+\t}\n+\n+\tif (inv_choice == INV_DATA_FIELD) {\n+\t\tret = json_object_set_new(root, \"d--a\", data);\n+\t\tif (ret < 0) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Setting invalid data field in data object failed\");\n+\t\t\tgoto fail;\n+\t\t}\n+\t} else {\n+\t\tret = json_object_set_new(root, \"data\", data);\n+\t\tif (ret < 0) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Setting valid data field in data object failed\");\n+\t\t\tgoto fail;\n+\t\t}\n+\t}\n+\n+\t*request = json_dumps(root, 0);\n+\tif (*request == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Converting JSON root object to char* failed\");\n+\t\tgoto fail;\n+\t}\n+\n+\tjson_decref(root);\n+\treturn 0;\n+\n+fail:\n+\tif (root)\n+\t\tjson_decref(root);\n+\treturn -1;\n+}\n+\n+int32_t\n+rte_telemetry_send_get_ports_and_stats_request(struct telemetry_impl *telemetry,\n+\tint action_choice, char *command_choice, int inv_choice)\n+{\n+\tint ret;\n+\tchar *request;\n+\tchar *client_path_data = NULL;\n+\n+\tif (telemetry == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Telemetry argument has not been initialised\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\n+\tif (inv_choice == INV_ACTION_VAL)\n+\t\taction_choice = -1;\n+\telse if (inv_choice == INV_COMMAND_VAL)\n+\t\tcommand_choice = \"INVALID_COMMAND\";\n+\telse if (inv_choice == INV_DATA_VAL)\n+\t\tclient_path_data = \"INVALID_DATA\";\n+\n+\tret = rte_telemetry_create_json_request(action_choice, command_choice,\n+\t\tclient_path_data, NULL, -1, NULL, -1, &request, inv_choice);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not create JSON Request\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (inv_choice == INV_JSON_FORMAT)\n+\t\trequest++;\n+\n+\tret = rte_telemetry_parse(telemetry, request);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_WARN(\"Could not parse JSON Request\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int32_t\n+rte_telemetry_send_get_ports_details_request(struct telemetry_impl *telemetry,\n+\tint action_choice, int *port_ids, int num_port_ids, int inv_choice)\n+{\n+\tint ret;\n+\tchar *request;\n+\tif (telemetry == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Telemetry argument has not been initialised\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tchar *command = \"ports_details\";\n+\n+\tif (inv_choice == INV_ACTION_VAL)\n+\t\taction_choice = -1;\n+\telse if (inv_choice == INV_COMMAND_VAL)\n+\t\tcommand = \"INVALID_COMMAND\";\n+\telse if (inv_choice == INV_DATA_VAL)\n+\t\tport_ids = NULL;\n+\n+\n+\tret = rte_telemetry_create_json_request(action_choice, command, NULL,\n+\t\tport_ids, num_port_ids, NULL, -1, &request, inv_choice);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not create JSON Request\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (inv_choice == INV_JSON_FORMAT)\n+\t\trequest++;\n+\n+\tret = rte_telemetry_parse(telemetry, request);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_WARN(\"Could not parse JSON Request\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int32_t\n+rte_telemetry_send_stats_values_by_name_request(struct telemetry_impl\n+\t*telemetry, int action_choice, int *port_ids, int num_port_ids,\n+\tconst char * const *stat_names, int num_stat_names,\n+\tint inv_choice)\n+{\n+\tint ret;\n+\tchar *request;\n+\tchar *command = \"ports_stats_values_by_name\";\n+\n+\tif (telemetry == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Telemetry argument has not been initialised\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (inv_choice == INV_ACTION_VAL)\n+\t\taction_choice = -1;\n+\telse if (inv_choice == INV_COMMAND_VAL)\n+\t\tcommand = \"INVALID_COMMAND\";\n+\telse if (inv_choice == INV_DATA_VAL) {\n+\t\tport_ids = NULL;\n+\t\tstat_names = NULL;\n+\t}\n+\n+\tret = rte_telemetry_create_json_request(action_choice, command, NULL,\n+\t\tport_ids, num_port_ids, stat_names, num_stat_names, &request,\n+\t\tinv_choice);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not create JSON Request\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (inv_choice == INV_JSON_FORMAT)\n+\t\trequest++;\n+\n+\tret = rte_telemetry_parse(telemetry, request);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_WARN(\"Could not parse JSON Request\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int32_t\n+rte_telemetry_send_unreg_request(struct telemetry_impl *telemetry,\n+\tint action_choice, const char *client_path, int inv_choice)\n+{\n+\tint ret;\n+\tchar *request;\n+\n+\tif (telemetry == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Telemetry argument has not been initialised\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tchar *command = \"clients\";\n+\n+\tif (inv_choice == INV_ACTION_VAL)\n+\t\taction_choice = -1;\n+\telse if (inv_choice == INV_COMMAND_VAL)\n+\t\tcommand = \"INVALID_COMMAND\";\n+\telse if (inv_choice == INV_DATA_VAL)\n+\t\tclient_path = NULL;\n+\n+\tret = rte_telemetry_create_json_request(action_choice, command,\n+\t\tclient_path, NULL, -1, NULL, -1, &request, inv_choice);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not create JSON Request\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (inv_choice == INV_JSON_FORMAT)\n+\t\trequest++;\n+\n+\tret = rte_telemetry_parse(telemetry, request);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_WARN(\"Could not parse JSON Request\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int32_t\n+rte_telemetry_parser_test(struct telemetry_impl *telemetry)\n+{\n+\tint ret;\n+\tconst char *client_path = TEST_CLIENT;\n+\n+\tif (telemetry == NULL) {\n+\t\tTELEMETRY_LOG_ERR(\"Telemetry argument has not been initialised\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tret = rte_telemetry_create_test_socket(telemetry, client_path);\n+\tif (ret < 0) {\n+\t\tTELEMETRY_LOG_ERR(\"Could not create test request client socket\");\n+\t\treturn -1;\n+\t}\n+\n+\tint port_ids[] = {0, 1};\n+\tint num_port_ids = RTE_DIM(port_ids);\n+\n+\tstatic const char * const stat_names[] = {\"tx_good_packets\",\n+\t\t\"rx_good_packets\"};\n+\tint num_stat_names = RTE_DIM(stat_names);\n+\n+\tstatic const char * const test_types[] = {\n+\t\t\"INVALID ACTION VALUE TESTS\",\n+\t\t\"INVALID COMMAND VALUE TESTS\",\n+\t\t\"INVALID DATA VALUE TESTS\",\n+\t\t\"INVALID ACTION FIELD TESTS\",\n+\t\t\"INVALID COMMAND FIELD TESTS\",\n+\t\t\"INVALID DATA FIELD TESTS\",\n+\t\t\"INVALID JSON FORMAT TESTS\",\n+\t\t\"VALID TESTS\"\n+\t};\n+\n+\n+#define NUM_TEST_TYPES (sizeof(test_types)/sizeof(const char * const))\n+\n+\tuint32_t i;\n+\tfor (i = 0; i < NUM_TEST_TYPES; i++) {\n+\t\tTELEMETRY_LOG_INFO(\"%s\", test_types[i]);\n+\n+\t\tret = rte_telemetry_send_get_ports_and_stats_request(telemetry,\n+\t\t\tACTION_GET, \"ports\", i);\n+\t\tif (ret != 0 && i == VALID_REQ) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Get ports valid test failed\");\n+\t\t\treturn -EPERM;\n+\t\t} else if (ret != -1 && i != VALID_REQ) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Get ports invalid test failed\");\n+\t\t\treturn -EPERM;\n+\t\t}\n+\n+\t\tTELEMETRY_LOG_INFO(\"Success - Get ports test passed\");\n+\n+\t\tret = rte_telemetry_send_get_ports_details_request(telemetry,\n+\t\t\tACTION_GET, port_ids, num_port_ids, i);\n+\t\tif (ret != 0 && i == VALID_REQ) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Get ports details valid\");\n+\t\t\treturn -EPERM;\n+\t\t} else if (ret != -1 && i != VALID_REQ) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Get ports details invalid\");\n+\t\t\treturn -EPERM;\n+\t\t}\n+\n+\t\tTELEMETRY_LOG_INFO(\"Success - Get ports details test passed\");\n+\n+\t\tret = rte_telemetry_send_get_ports_and_stats_request(telemetry,\n+\t\t\tACTION_GET, \"port_stats\", i);\n+\t\tif (ret != 0  && i == VALID_REQ) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Get port stats valid test\");\n+\t\t\treturn -EPERM;\n+\t\t} else if (ret != -1 && i != VALID_REQ) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Get ports stats invalid test failed\");\n+\t\t\treturn -EPERM;\n+\t\t}\n+\n+\t\tTELEMETRY_LOG_INFO(\"Success - Get ports stats test passed\");\n+\n+\t\tret = rte_telemetry_send_stats_values_by_name_request(telemetry,\n+\t\t\tACTION_GET, port_ids, num_port_ids, stat_names,\n+\t\t\tnum_stat_names, i);\n+\t\tif (ret != 0 && i == VALID_REQ) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Get ports stats values by name valid test failed\");\n+\t\t\treturn -EPERM;\n+\t\t} else if (ret != -1 && i != VALID_REQ) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Get ports stats values by name invalid test failed\");\n+\t\t\treturn -EPERM;\n+\t\t}\n+\n+\t\tTELEMETRY_LOG_INFO(\"Success - Get ports stats values by name test passed\");\n+\n+\t\tret = rte_telemetry_send_unreg_request(telemetry, ACTION_DELETE,\n+\t\t\tclient_path, i);\n+\t\tif (ret != 0 && i == VALID_REQ) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Deregister valid test failed\");\n+\t\t\treturn -EPERM;\n+\t\t} else if (ret != -1 && i != VALID_REQ) {\n+\t\t\tTELEMETRY_LOG_ERR(\"Deregister invalid test failed\");\n+\t\t\treturn -EPERM;\n+\t\t}\n+\n+\t\tTELEMETRY_LOG_INFO(\"Success - Deregister test passed\");\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/lib/librte_telemetry/rte_telemetry_parser_test.h b/lib/librte_telemetry/rte_telemetry_parser_test.h\nnew file mode 100644\nindex 000000000..6ada85276\n--- /dev/null\n+++ b/lib/librte_telemetry/rte_telemetry_parser_test.h\n@@ -0,0 +1,39 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018 Intel Corporation\n+ */\n+\n+#ifndef _RTE_TELEMETRY_PARSER_TEST_H_\n+#define _RTE_TELEMETRY_PARSER_TEST_H_\n+\n+int32_t\n+rte_telemetry_parser_test(struct telemetry_impl *telemetry);\n+\n+int32_t\n+rte_telemetry_format_port_stat_ids(int *port_ids, int num_port_ids,\n+\tconst char * const stat_names, int num_stat_names, json_t **data);\n+\n+int32_t\n+rte_telemetry_create_json_request(int action, char *command,\n+\tconst char *client_path, int *port_ids, int num_port_ids,\n+\tconst char * const stat_names, int num_stat_names, char **request,\n+\tint inv_choice);\n+\n+int32_t\n+rte_telemetry_send_get_ports_and_stats_request(struct telemetry_impl *telemetry,\n+\tint action_choice, char *command_choice, int inv_choice);\n+\n+int32_t\n+rte_telemetry_send_get_ports_details_request(struct telemetry_impl *telemetry,\n+\tint action_choice, int *port_ids, int num_port_ids, int inv_choice);\n+\n+int32_t\n+rte_telemetry_send_stats_values_by_name_request(struct telemetry_impl\n+\t*telemetry, int action_choice, int *port_ids, int num_port_ids,\n+\tconst char * const stat_names, int num_stat_names,\n+\tint inv_choice);\n+\n+int32_t\n+rte_telemetry_send_unreg_request(int action_choice, const char *client_path,\n+\tint inv_choice);\n+\n+#endif\ndiff --git a/lib/librte_telemetry/rte_telemetry_socket_tests.h b/lib/librte_telemetry/rte_telemetry_socket_tests.h\nnew file mode 100644\nindex 000000000..db9167c5d\n--- /dev/null\n+++ b/lib/librte_telemetry/rte_telemetry_socket_tests.h\n@@ -0,0 +1,36 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2018 Intel Corporation\n+ */\n+\n+#include <stdbool.h>\n+\n+#include \"rte_telemetry_internal.h\"\n+\n+#ifndef _RTE_TELEMETRY_SOCKET_TESTING_H_\n+#define _RTE_TELEMETRY_SOCKET_TESTING_H_\n+\n+int32_t\n+rte_telemetry_json_socket_message_test(struct telemetry_impl *telemetry,\n+\tint fd);\n+\n+int32_t\n+rte_telemetry_invalid_json_test(struct telemetry_impl *telemetry, int fd);\n+\n+int32_t\n+rte_telemetry_valid_json_test(struct telemetry_impl *telemetry, int fd);\n+\n+int32_t\n+rte_telemetry_json_contents_test(struct telemetry_impl *telemetry, int fd);\n+\n+int32_t\n+rte_telemetry_json_empty_test(struct telemetry_impl *telemetry, int fd);\n+\n+int32_t\n+rte_telemetry_socket_register_test(struct telemetry_impl *telemetry, int *fd,\n+\tint send_fd, int recv_fd);\n+\n+int32_t\n+rte_telemetry_socket_test_setup(struct telemetry_impl *telemetry, int *send_fd,\n+\tint *recv_fd);\n+\n+#endif\ndiff --git a/lib/librte_telemetry/rte_telemetry_version.map b/lib/librte_telemetry/rte_telemetry_version.map\nindex fb0b5be62..fa62d7718 100644\n--- a/lib/librte_telemetry/rte_telemetry_version.map\n+++ b/lib/librte_telemetry/rte_telemetry_version.map\n@@ -4,6 +4,7 @@ EXPERIMENTAL {\n \trte_telemetry_cleanup;\n \trte_telemetry_init;\n \trte_telemetry_parse;\n+\trte_telemetry_selftest;\n \n \tlocal: *;\n };\n",
    "prefixes": [
        "v10",
        "08/12"
    ]
}