diff --git a/common/include/villas/hist.hpp b/common/include/villas/hist.hpp index 3c7acb33e..042524be5 100644 --- a/common/include/villas/hist.hpp +++ b/common/include/villas/hist.hpp @@ -7,6 +7,7 @@ #pragma once +#include #include #include @@ -60,6 +61,9 @@ class Hist { // Write the histogram in JSON format to file \p f. int dumpJson(FILE *f) const; + std::string toPrometheusText(const std::string &metric_name, + const std::string &node_name) const; + // Build a libjansson / JSON object of the histogram. json_t *toJson() const; diff --git a/common/lib/hist.cpp b/common/lib/hist.cpp index d2ad73df9..c18c13519 100644 --- a/common/lib/hist.cpp +++ b/common/lib/hist.cpp @@ -37,13 +37,16 @@ void Hist::put(double value) { if (data.size()) { if (total < warmup) { // We are still in warmup phase... Waiting for more samples... - } else if (data.size() && total == warmup && warmup != 0) { - low = getMean() - 3 * getStddev(); - high = getMean() + 3 * getStddev(); + } else if (total == warmup) { + if (warmup != 0) { + low = getMean() - 3 * getStddev(); + high = getMean() + 3 * getStddev(); + } else { + low = -10; + high = 10; + } + resolution = (high - low) / data.size(); - } else if (data.size() && (total == warmup) && (warmup == 0)) { - // There is no warmup phase - // TODO resolution = ? } else { idx_t idx = std::round((value - low) / resolution); @@ -136,7 +139,7 @@ void Hist::plot(Logger logger) const { table.header(); for (size_t i = 0; i < data.size(); i++) { - double value = low + (i)*resolution; + double value = low + (double)i * resolution; Hist::cnt_t cnt = data[i]; int bar = cols[2].getWidth() * ((double)cnt / max); @@ -150,6 +153,36 @@ void Hist::plot(Logger logger) const { } } +std::string Hist::toPrometheusText(const std::string &metric_name, + const std::string &node_name) const { + std::stringstream base; + base << "#TYPE HISTOGRAM " << metric_name; + + // Needed because Prometheus understands quantiles. + cnt_t cumsum = 0; + for (size_t i = 0; i < data.size(); i++) { + double value = low + ((double)i + 0.5) * resolution; + + if (cumsum <= UINTMAX_MAX - data[i]) { + cumsum += data[i]; + } else { + cumsum = UINTMAX_MAX; // Avoid overflow + } + + base << "\n" + << metric_name << " {node=\"" << node_name << "\" le=\"" << value + << "\"} " << cumsum; + } + + base << "\n" + << metric_name << " {node=\"" << node_name << "\" le=\"+Inf\"} " << total + << "\n" + << metric_name << "_count " + << " {node=\"" << node_name << "\"} " << total; + + return base.str(); +} + char *Hist::dump() const { char *buf = new char[128]; if (!buf) diff --git a/lib/api/CMakeLists.txt b/lib/api/CMakeLists.txt index b52e3eee1..70974bdeb 100644 --- a/lib/api/CMakeLists.txt +++ b/lib/api/CMakeLists.txt @@ -26,6 +26,7 @@ set(API_SRC requests/node_stats.cpp requests/node_stats_reset.cpp requests/node_file.cpp + requests/metrics.cpp requests/paths.cpp requests/path_info.cpp requests/path_action.cpp diff --git a/lib/api/requests/metrics.cpp b/lib/api/requests/metrics.cpp new file mode 100644 index 000000000..689e9ab74 --- /dev/null +++ b/lib/api/requests/metrics.cpp @@ -0,0 +1,70 @@ +/* The metrics API ressource. + * + * Author: Steffen Vogel + * Author: Youssef Nakti + * SPDX-FileCopyrightText: 2014-2023 Institute for Automation of Complex Power Systems, RWTH Aachen University + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace villas { +namespace node { +namespace api { + +class MetricsRequest : public Request { +public: + using Request::Request; + + virtual Response *execute() { + if (method != Session::Method::GET) { + throw InvalidMethod(this); + } + + if (body != nullptr) { + throw BadRequest("The metrics endpoint does not accept any body data"); + } + + std::stringstream ss; + NodeList node_list = session->getSuperNode()->getNodes(); + + for (Node *node : node_list) { + auto stats = node->getStats(); + if (!stats) + continue; + + std::string node_name = node->getNameShort(); + for (auto &metric : Stats::metrics) { + std::string metric_name = metric.second.name; + std::replace(metric_name.begin(), metric_name.end(), '.', '_'); + ss << stats->getHistogram(metric.first) + .toPrometheusText(metric_name, node->getNameShort()) + << "\n\n"; + } + } + + auto str = ss.str(); + return new Response(session, HTTP_STATUS_OK, "text/plain; charset=UTF-8", + Buffer(str.c_str(), str.size())); + } +}; + +// Register API request +static char n[] = "metrics"; +static char r[] = "/metrics"; +static char d[] = "Get stats of all nodes in Prometheus metrics format"; +static RequestPlugin p; + +} // namespace api +} // namespace node +} // namespace villas diff --git a/tests/integration/api-metrics.sh b/tests/integration/api-metrics.sh new file mode 100755 index 000000000..4ad3ffe06 --- /dev/null +++ b/tests/integration/api-metrics.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env bash +# +# Integration test for remote API +# +# Author: Steffen Vogel +# SPDX-FileCopyrightText: 2025 OPAL-RT Germany GmbH +# SPDX-License-Identifier: Apache-2.0 + +set -e + +DIR=$(mktemp -d) +pushd ${DIR} + +function finish { + popd + rm -rf ${DIR} +} +trap finish EXIT + +cat > config.json < expected +#TYPE HISTOGRAM rtp_jitter +rtp_jitter {node="node1" le="0"} 0 +rtp_jitter {node="node1" le="0"} 0 +rtp_jitter {node="node1" le="0"} 0 +rtp_jitter {node="node1" le="0"} 0 +rtp_jitter {node="node1" le="0"} 0 +rtp_jitter {node="node1" le="+Inf"} 0 +rtp_jitter_count {node="node1"} 0 + +#TYPE HISTOGRAM rtp_pkts_lost +rtp_pkts_lost {node="node1" le="0"} 0 +rtp_pkts_lost {node="node1" le="0"} 0 +rtp_pkts_lost {node="node1" le="0"} 0 +rtp_pkts_lost {node="node1" le="0"} 0 +rtp_pkts_lost {node="node1" le="0"} 0 +rtp_pkts_lost {node="node1" le="+Inf"} 0 +rtp_pkts_lost_count {node="node1"} 0 + +#TYPE HISTOGRAM rtp_loss_fraction +rtp_loss_fraction {node="node1" le="0"} 0 +rtp_loss_fraction {node="node1" le="0"} 0 +rtp_loss_fraction {node="node1" le="0"} 0 +rtp_loss_fraction {node="node1" le="0"} 0 +rtp_loss_fraction {node="node1" le="0"} 0 +rtp_loss_fraction {node="node1" le="+Inf"} 0 +rtp_loss_fraction_count {node="node1"} 0 + +#TYPE HISTOGRAM signal_cnt +signal_cnt {node="node1" le="-8"} 0 +signal_cnt {node="node1" le="-4"} 0 +signal_cnt {node="node1" le="0"} 0 +signal_cnt {node="node1" le="4"} 9 +signal_cnt {node="node1" le="8"} 9 +signal_cnt {node="node1" le="+Inf"} 10 +signal_cnt_count {node="node1"} 10 + +#TYPE HISTOGRAM age +age {node="node1" le="0"} 0 +age {node="node1" le="0"} 0 +age {node="node1" le="0"} 0 +age {node="node1" le="0"} 0 +age {node="node1" le="0"} 0 +age {node="node1" le="+Inf"} 0 +age_count {node="node1"} 0 + +#TYPE HISTOGRAM owd +owd {node="node1" le="-8"} 0 +owd {node="node1" le="-4"} 0 +owd {node="node1" le="0"} 0 +owd {node="node1" le="4"} 8 +owd {node="node1" le="8"} 8 +owd {node="node1" le="+Inf"} 9 +owd_count {node="node1"} 9 + +#TYPE HISTOGRAM gap_received +gap_received {node="node1" le="-8"} 0 +gap_received {node="node1" le="-4"} 0 +gap_received {node="node1" le="0"} 0 +gap_received {node="node1" le="4"} 8 +gap_received {node="node1" le="8"} 8 +gap_received {node="node1" le="+Inf"} 9 +gap_received_count {node="node1"} 9 + +#TYPE HISTOGRAM gap_sent +gap_sent {node="node1" le="-8"} 0 +gap_sent {node="node1" le="-4"} 0 +gap_sent {node="node1" le="0"} 0 +gap_sent {node="node1" le="4"} 8 +gap_sent {node="node1" le="8"} 8 +gap_sent {node="node1" le="+Inf"} 9 +gap_sent_count {node="node1"} 9 + +#TYPE HISTOGRAM reordered +reordered {node="node1" le="0"} 0 +reordered {node="node1" le="0"} 0 +reordered {node="node1" le="0"} 0 +reordered {node="node1" le="0"} 0 +reordered {node="node1" le="0"} 0 +reordered {node="node1" le="+Inf"} 0 +reordered_count {node="node1"} 0 + +#TYPE HISTOGRAM skipped +skipped {node="node1" le="0"} 0 +skipped {node="node1" le="0"} 0 +skipped {node="node1" le="0"} 0 +skipped {node="node1" le="0"} 0 +skipped {node="node1" le="0"} 0 +skipped {node="node1" le="+Inf"} 0 +skipped_count {node="node1"} 0 + +EOF + +# Start VILLASnode instance with local config +villas node config.json & + +# Wait for node to complete init +sleep 2 + +# Fetch config via API +curl -s http://localhost:8080/api/v2/metrics > metrics + +# Shutdown VILLASnode +kill $! + +# Check if metrics contain expected values +diff -u expected metrics diff --git a/tests/integration/api-nodes.sh b/tests/integration/api-nodes.sh index 054c58d19..576973c87 100755 --- a/tests/integration/api-nodes.sh +++ b/tests/integration/api-nodes.sh @@ -25,29 +25,29 @@ cat > config.json < config.json < local.json < config.json << EOF { "nodes": { "can_node1": { - "type": "can", - "interface_name": "${CAN_IF}", - "sample_rate": 500000, - "in": { - "signals": [ - { - "name": "sigin1", - "unit": "Volts", - "type": "float", - "enabled": true, - "can_id": 66, - "can_size": 4, - "can_offset": 0 - }, - { - "name": "sigin2", - "unit": "Volts", - "type": "float", - "enabled": true, - "can_id": 66, - "can_size": 4, - "can_offset": 4 - }, - { - "name": "sigin3", - "unit": "Volts", - "type": "float", - "enabled": true, - "can_id": 67, - "can_size": 8, - "can_offset": 0 - } - ] - }, - "out": { - "signals": [ - { - "type": "float", - "can_id": 66, - "can_size": 4, - "can_offset": 0 - }, - { - "type": "float", - "can_id": 66, - "can_size": 4, - "can_offset": 4 - }, - { - "type": "float", - "can_id": 67, - "can_size": 8, - "can_offset": 0 - } - ] - } + "type": "can", + "interface_name": "${CAN_IF}", + "sample_rate": 500000, + "in": { + "signals": [ + { + "name": "sigin1", + "unit": "Volts", + "type": "float", + "enabled": true, + "can_id": 66, + "can_size": 4, + "can_offset": 0 + }, + { + "name": "sigin2", + "unit": "Volts", + "type": "float", + "enabled": true, + "can_id": 66, + "can_size": 4, + "can_offset": 4 + }, + { + "name": "sigin3", + "unit": "Volts", + "type": "float", + "enabled": true, + "can_id": 67, + "can_size": 8, + "can_offset": 0 + } + ] + }, + "out": { + "signals": [ + { + "type": "float", + "can_id": 66, + "can_size": 4, + "can_offset": 0 + }, + { + "type": "float", + "can_id": 66, + "can_size": 4, + "can_offset": 4 + }, + { + "type": "float", + "can_id": 67, + "can_size": 8, + "can_offset": 0 + } + ] + } } } } diff --git a/tests/integration/node-hook.sh b/tests/integration/node-hook.sh index 3eec88abd..af1498add 100755 --- a/tests/integration/node-hook.sh +++ b/tests/integration/node-hook.sh @@ -30,43 +30,43 @@ cat > config.json < config.json < config.json < config.json < config.json < config.json < config.json < config.json < config.json < config.json < config.json < config.json < config.json < config.json << EOF { "nodes": { "node1": { - "type": "file", + "type": "file", - "uri": "file.dat", + "uri": "file.dat", - "in": { - "epoch_mode": "original", - "eof": "wait" - }, - "out": { - "flush": true - } + "in": { + "epoch_mode": "original", + "eof": "wait" + }, + "out": { + "flush": true + } } } } diff --git a/tests/integration/pipe-loopback-mqtt.sh b/tests/integration/pipe-loopback-mqtt.sh index 0be9923f1..54cfa10e2 100755 --- a/tests/integration/pipe-loopback-mqtt.sh +++ b/tests/integration/pipe-loopback-mqtt.sh @@ -32,21 +32,21 @@ cat > config.json << EOF { "nodes": { "node1": { - "type": "mqtt", - "format": "${FORMAT}", - "vectorize": ${VECTORIZE}, - - "username": "guest", - "password": "guest", - "host": "${HOST}", - "port": 1883, - - "out": { - "publish": "test-topic" - }, - "in": { - "subscribe": "test-topic" - } + "type": "mqtt", + "format": "${FORMAT}", + "vectorize": ${VECTORIZE}, + + "username": "guest", + "password": "guest", + "host": "${HOST}", + "port": 1883, + + "out": { + "publish": "test-topic" + }, + "in": { + "subscribe": "test-topic" + } } } } diff --git a/tests/integration/pipe-loopback-nanomsg.sh b/tests/integration/pipe-loopback-nanomsg.sh index 71a9b6584..dbf19bbd1 100755 --- a/tests/integration/pipe-loopback-nanomsg.sh +++ b/tests/integration/pipe-loopback-nanomsg.sh @@ -26,22 +26,22 @@ cat > config.json << EOF { "nodes": { "node1": { - "type": "nanomsg", - - "format": "${FORMAT}", - "vectorize": ${VECTORIZE}, - - "in": { - "endpoints": [ "tcp://127.0.0.1:12000" ], - - "signals": { - "type": "float", - "count": 5 - } - }, - "out": { - "endpoints": [ "tcp://127.0.0.1:12000" ] - } + "type": "nanomsg", + + "format": "${FORMAT}", + "vectorize": ${VECTORIZE}, + + "in": { + "endpoints": [ "tcp://127.0.0.1:12000" ], + + "signals": { + "type": "float", + "count": 5 + } + }, + "out": { + "endpoints": [ "tcp://127.0.0.1:12000" ] + } } } } diff --git a/tests/integration/pipe-loopback-rtp-dual.sh b/tests/integration/pipe-loopback-rtp-dual.sh index 93a990609..de52f205f 100755 --- a/tests/integration/pipe-loopback-rtp-dual.sh +++ b/tests/integration/pipe-loopback-rtp-dual.sh @@ -34,26 +34,26 @@ cat > src.json << EOF }, "nodes": { "rtp_node": { - "type": "rtp", - "format": "${FORMAT}", - "vectorize": ${VECTORIZE}, - "rate": ${RATE}, - "rtcp": true, - "aimd": { - "a": 10, - "b": 0.5, - "hook_type": "decimate" - }, - "in": { - "address": "0.0.0.0:12002", - "signals": { - "count": 5, - "type": "float" - } - }, - "out": { - "address": "127.0.0.1:12000" - } + "type": "rtp", + "format": "${FORMAT}", + "vectorize": ${VECTORIZE}, + "rate": ${RATE}, + "rtcp": true, + "aimd": { + "a": 10, + "b": 0.5, + "hook_type": "decimate" + }, + "in": { + "address": "0.0.0.0:12002", + "signals": { + "count": 5, + "type": "float" + } + }, + "out": { + "address": "127.0.0.1:12000" + } } } } @@ -72,20 +72,20 @@ cat > dest.json << EOF "rate": ${RATE}, "rtcp": true, "aimd": { - "a": 10, - "b": 0.5, + "a": 10, + "b": 0.5, - "hook_type": "decimate" + "hook_type": "decimate" }, "in": { - "address": "0.0.0.0:12000", - "signals": { - "count": 5, - "type": "float" - } + "address": "0.0.0.0:12000", + "signals": { + "count": 5, + "type": "float" + } }, "out": { - "address": "127.0.0.1:12002" + "address": "127.0.0.1:12002" } } } diff --git a/tests/integration/pipe-loopback-rtp-remote.sh b/tests/integration/pipe-loopback-rtp-remote.sh index 97c8ccc6b..f846065df 100755 --- a/tests/integration/pipe-loopback-rtp-remote.sh +++ b/tests/integration/pipe-loopback-rtp-remote.sh @@ -42,29 +42,29 @@ cat > src.json << EOF }, "nodes": { "rtp_node": { - "type": "rtp", - "format": "${FORMAT}", - "vectorize": ${VECTORIZE}, - "rate": ${RATE}, - "rtcp": { - "enabled": true, - "mode": "aimd", - "throttle_mode": "decimate" - }, - "aimd": { - "a": 10, - "b": 0.5 - }, - "in": { - "address": "0.0.0.0:33466", - "signals": { - "count": 5, - "type": "float" - } - }, - "out": { - "address": "${REMOTE_ADDR}:33464" - } + "type": "rtp", + "format": "${FORMAT}", + "vectorize": ${VECTORIZE}, + "rate": ${RATE}, + "rtcp": { + "enabled": true, + "mode": "aimd", + "throttle_mode": "decimate" + }, + "aimd": { + "a": 10, + "b": 0.5 + }, + "in": { + "address": "0.0.0.0:33466", + "signals": { + "count": 5, + "type": "float" + } + }, + "out": { + "address": "${REMOTE_ADDR}:33464" + } } } } @@ -84,23 +84,23 @@ cat > dest.json << EOF "vectorize": ${VECTORIZE}, "rate": ${RATE}, "rtcp": { - "enabled": true, - "mode": "aimd", - "throttle_mode": "decimate" + "enabled": true, + "mode": "aimd", + "throttle_mode": "decimate" }, "aimd": { - "a": 10, - "b": 0.5 + "a": 10, + "b": 0.5 }, "in": { - "address": "0.0.0.0:33464", - "signals": { - "count": 5, - "type": "float" - } + "address": "0.0.0.0:33464", + "signals": { + "count": 5, + "type": "float" + } }, "out": { - "address": "${LOCAL_ADDR}:33466" + "address": "${LOCAL_ADDR}:33466" } } } diff --git a/tests/integration/pipe-loopback-rtp-tbf.sh b/tests/integration/pipe-loopback-rtp-tbf.sh index c0187632e..97b741a67 100755 --- a/tests/integration/pipe-loopback-rtp-tbf.sh +++ b/tests/integration/pipe-loopback-rtp-tbf.sh @@ -35,31 +35,31 @@ cat > src.json << EOF }, "nodes": { "rtp_node": { - "type": "rtp", - "format": "${FORMAT}", - "vectorize": ${VECTORIZE}, - "rate": ${RATE}, - "rtcp": { - "enabled": true, - "mode": "aimd", - "throttle_mode": "decimate" - }, - "aimd": { - "a": 10, - "b": 0.75, - "start_rate": ${RATE} - }, - "in": { - "address": "0.0.0.0:12002", - "signals": { - "count": ${NUM_VALUES}, - "type": "float" - } - }, - "out": { - "address": "127.0.0.1:12000", - "fwmark": 123 - } + "type": "rtp", + "format": "${FORMAT}", + "vectorize": ${VECTORIZE}, + "rate": ${RATE}, + "rtcp": { + "enabled": true, + "mode": "aimd", + "throttle_mode": "decimate" + }, + "aimd": { + "a": 10, + "b": 0.75, + "start_rate": ${RATE} + }, + "in": { + "address": "0.0.0.0:12002", + "signals": { + "count": ${NUM_VALUES}, + "type": "float" + } + }, + "out": { + "address": "127.0.0.1:12000", + "fwmark": 123 + } } } } @@ -77,19 +77,19 @@ cat > dest.json << EOF "vectorize": ${VECTORIZE}, "rate": ${RATE}, "rtcp": { - "enabled": true, - "mode": "aimd", - "throttle_mode": "decimate" + "enabled": true, + "mode": "aimd", + "throttle_mode": "decimate" }, "in": { - "address": "0.0.0.0:12000", - "signals": { - "count": ${NUM_VALUES}, - "type": "float" - } + "address": "0.0.0.0:12000", + "signals": { + "count": ${NUM_VALUES}, + "type": "float" + } }, "out": { - "address": "127.0.0.1:12002" + "address": "127.0.0.1:12002" } } } diff --git a/tests/integration/pipe-loopback-rtp.sh b/tests/integration/pipe-loopback-rtp.sh index b42ef132f..426bdfeb9 100755 --- a/tests/integration/pipe-loopback-rtp.sh +++ b/tests/integration/pipe-loopback-rtp.sh @@ -33,33 +33,33 @@ cat > config.json << EOF }, "nodes": { "node1": { - "type": "rtp", + "type": "rtp", - "format": "${FORMAT}", - "vectorize": ${VECTORIZE}, + "format": "${FORMAT}", + "vectorize": ${VECTORIZE}, - "rtcp": { - "enabled": true, - "throttle_mode": "limit_rate" - }, + "rtcp": { + "enabled": true, + "throttle_mode": "limit_rate" + }, - "aimd": { - "start_rate": 1, - "a": 10, - "b": 0.5 - }, + "aimd": { + "start_rate": 1, + "a": 10, + "b": 0.5 + }, - "in": { - "address": "127.0.0.1:12000", + "in": { + "address": "127.0.0.1:12000", - "signals": { - "type": "float", - "count": 5 - } - }, - "out": { - "address": "127.0.0.1:12000" - } + "signals": { + "type": "float", + "count": 5 + } + }, + "out": { + "address": "127.0.0.1:12000" + } } } } diff --git a/tests/integration/pipe-loopback-shmem.sh b/tests/integration/pipe-loopback-shmem.sh index 8539d5d87..f88a3a6ee 100755 --- a/tests/integration/pipe-loopback-shmem.sh +++ b/tests/integration/pipe-loopback-shmem.sh @@ -27,16 +27,16 @@ cat > config.json << EOF { "nodes": { "node1": { - "type": "shmem", - "out": { - "name": "/villas-test" - }, - "in": { - "name": "/villas-test" - }, - "queuelen": 1024, - "mode": "${MODE}", - "vectorize": ${VECTORIZE} + "type": "shmem", + "out": { + "name": "/villas-test" + }, + "in": { + "name": "/villas-test" + }, + "queuelen": 1024, + "mode": "${MODE}", + "vectorize": ${VECTORIZE} } } } diff --git a/tests/integration/pipe-loopback-socket-multicast.sh b/tests/integration/pipe-loopback-socket-multicast.sh index ab8858b71..718387b39 100755 --- a/tests/integration/pipe-loopback-socket-multicast.sh +++ b/tests/integration/pipe-loopback-socket-multicast.sh @@ -23,22 +23,22 @@ cat > config.json << EOF { "nodes": { "node1": { - "type" : "socket", - "format": "protobuf", - - "in": { - "address": "*:12000", - - "multicast": { - "enabled": true, - - "group" : "224.1.2.3", - "loop" : true - } - }, - "out": { - "address": "224.1.2.3:12000" - } + "type": "socket", + "format": "protobuf", + + "in": { + "address": "*:12000", + + "multicast": { + "enabled": true, + + "group": "224.1.2.3", + "loop": true + } + }, + "out": { + "address": "224.1.2.3:12000" + } } } } diff --git a/tests/integration/pipe-loopback-socket-netem.sh b/tests/integration/pipe-loopback-socket-netem.sh index 6c6aae8ef..4c1810ee4 100755 --- a/tests/integration/pipe-loopback-socket-netem.sh +++ b/tests/integration/pipe-loopback-socket-netem.sh @@ -33,21 +33,21 @@ cat > config.json << EOF { "nodes": { "node1": { - "type" : "socket", - "format": "protobuf", - - "in": { - "address": "*:12000" - }, - "out": { - "address": "127.0.0.1:12000", - "netem": { - "enabled": true, - "delay": 100000, - "jitter": 30000, - "loss": 20 - } - } + "type" : "socket", + "format": "protobuf", + + "in": { + "address": "*:12000" + }, + "out": { + "address": "127.0.0.1:12000", + "netem": { + "enabled": true, + "delay": 100000, + "jitter": 30000, + "loss": 20 + } + } } } } diff --git a/tests/integration/pipe-loopback-socket.sh b/tests/integration/pipe-loopback-socket.sh index 8dee69d35..94121fd6f 100755 --- a/tests/integration/pipe-loopback-socket.sh +++ b/tests/integration/pipe-loopback-socket.sh @@ -57,22 +57,22 @@ cat > config.json << EOF { "nodes": { "node1": { - "type": "socket", - - "vectorize": ${VECTORIZE}, - "format": "${FORMAT}", - "layer": "${LAYER}", - - "out": { - "address": "${REMOTE}" - }, - "in": { - "address": "${LOCAL}", - "signals": { - "count": ${NUM_VALUES}, - "type": "float" - } - } + "type": "socket", + + "vectorize": ${VECTORIZE}, + "format": "${FORMAT}", + "layer": "${LAYER}", + + "out": { + "address": "${REMOTE}" + }, + "in": { + "address": "${LOCAL}", + "signals": { + "count": ${NUM_VALUES}, + "type": "float" + } + } } } } diff --git a/tests/integration/pipe-loopback-websocket.sh b/tests/integration/pipe-loopback-websocket.sh index 4e4d3ad90..812f917bd 100755 --- a/tests/integration/pipe-loopback-websocket.sh +++ b/tests/integration/pipe-loopback-websocket.sh @@ -29,13 +29,13 @@ cat > config1.json << EOF }, "nodes": { "node1": { - "type": "websocket", + "type": "websocket", - "destinations": [ - "ws://127.0.0.1:8080/node2.protobuf" - ], + "destinations": [ + "ws://127.0.0.1:8080/node2.protobuf" + ], - "wait_connected": true + "wait_connected": true } } } diff --git a/tests/integration/pipe-loopback-zeromq.sh b/tests/integration/pipe-loopback-zeromq.sh index 3fe9caa94..9e3c299b6 100755 --- a/tests/integration/pipe-loopback-zeromq.sh +++ b/tests/integration/pipe-loopback-zeromq.sh @@ -26,21 +26,21 @@ cat > config.json << EOF { "nodes": { "node1": { - "type": "zeromq", - - "format": "${FORMAT}", - "vectorize": ${VECTORIZE}, - "pattern": "pubsub", - "out": { - "publish": "tcp://127.0.0.1:12000" - }, - "in": { - "subscribe": "tcp://127.0.0.1:12000", - "signals": { - "type": "float", - "count": 5 - } - } + "type": "zeromq", + + "format": "${FORMAT}", + "vectorize": ${VECTORIZE}, + "pattern": "pubsub", + "out": { + "publish": "tcp://127.0.0.1:12000" + }, + "in": { + "subscribe": "tcp://127.0.0.1:12000", + "signals": { + "type": "float", + "count": 5 + } + } } } } diff --git a/tests/integration/pipe-python-protobuf.sh b/tests/integration/pipe-python-protobuf.sh index 0d5a32b71..57c5d3efb 100755 --- a/tests/integration/pipe-python-protobuf.sh +++ b/tests/integration/pipe-python-protobuf.sh @@ -42,16 +42,16 @@ cat > config.json << EOF { "nodes": { "py-client": { - "type": "socket", - "layer": "${LAYER}", - "format": "${FORMAT}", - - "in": { - "address": "${LOCAL}" - }, - "out": { - "address": "${REMOTE}" - } + "type": "socket", + "layer": "${LAYER}", + "format": "${FORMAT}", + + "in": { + "address": "${LOCAL}" + }, + "out": { + "address": "${REMOTE}" + } } } } diff --git a/tests/integration/relay.sh b/tests/integration/relay.sh index 99e4a603c..d8720b66d 100755 --- a/tests/integration/relay.sh +++ b/tests/integration/relay.sh @@ -27,18 +27,18 @@ cat > config.json << EOF { "nodes": { "relay1": { - "type": "websocket", + "type": "websocket", - "wait_connected": true, + "wait_connected": true, "destinations": [ "http://localhost:8123/node" ] }, "relay2": { - "type": "websocket", + "type": "websocket", - "wait_connected": true, + "wait_connected": true, "destinations": [ "http://localhost:8123/node" ]