From 8db62c0b1e7c8fcf6e0c42589d9e15205504589f Mon Sep 17 00:00:00 2001 From: "Eduardo Ramos Testillano (ert)" Date: Tue, 26 Mar 2024 17:20:29 +0100 Subject: [PATCH] Improve server/client data helpers Improve surf mode, and add dump mode to helpers functions. Also, implements the possibility to track the provisions processed for every server data event. Issue: https://github.com/testillano/h2agent/issues/118 --- README.md | 14 +- .../sdo_get_data_test.py | 4 +- src/http2/MyTrafficHttp2Server.cpp | 2 + src/model/AdminServerProvision.hpp | 10 + src/model/keys.hpp | 9 + tools/helpers.src | 243 +++++++++++------- ut/model/Keys/keys.cpp | 14 + 7 files changed, 194 insertions(+), 102 deletions(-) diff --git a/README.md b/README.md index 280b485..c1f5552 100644 --- a/README.md +++ b/README.md @@ -4291,10 +4291,9 @@ Usage: server_data [-h|--help]; Inspects server data events (http://localhost:80 Displayed keys (method/uri) could be limited (5 by default, -1: no limit). [--clean] [query filters] ; Removes server data events. Admits additional query filters to narrow the selection. - [--surf] ; Interactive sorted server data navigation. -Usage: server_data_sequence [-h|--help] [value (available values by default)]; Extract server sequence document from json - retrieved in previous server_data() call. - + [--surf] ; Interactive sorted (regardless method/uri) server data navigation. + [--dump] ; Dumps all sequences detected for server data under 'server-data-sequences' + directory. === Traffic client === Usage: client_endpoint [-h|--help] [--clean] [file]; Cleans/gets/updates current client endpoint configuration (http://localhost:8074/admin/v1/client-endpoint). @@ -4316,10 +4315,9 @@ Usage: client_data [-h|--help]; Inspects client data events (http://localhost:80 (5 by default, -1: no limit). [--clean] [query filters] ; Removes client data events. Admits additional query filters to narrow the selection. - [--surf] ; Interactive sorted client data navigation. -Usage: client_data_sequence [-h|--help] [value (available values by default)]; Extract client sequence document from json - retrieved in previous client_data() call. - + [--surf] ; Interactive sorted (regardless endpoint/method/uri) client data navigation. + [--dump] ; Dumps all sequences detected for client data under 'client-data-sequences' + directory. === Schemas === Usage: schema_schema [-h|--help]; Gets the schema configuration schema (http://localhost:8074/admin/v1/schema/schema). diff --git a/ct/src/server-data_operation/sdo_get_data_test.py b/ct/src/server-data_operation/sdo_get_data_test.py index 414a9fb..43f1024 100644 --- a/ct/src/server-data_operation/sdo_get_data_test.py +++ b/ct/src/server-data_operation/sdo_get_data_test.py @@ -24,7 +24,7 @@ def test_001_i_want_to_get_internal_data_on_admin_interface(h2ac_admin, h2ac_tra # Check server data response = h2ac_admin.get(ADMIN_SERVER_DATA_URI) - responseBodyRef = [{'method': 'GET', 'events': [{'previousState': 'initial', 'receptionTimestampUs': 1623552535012124, 'responseBody': {'foo': 'bar-1'}, 'responseDelayMs': 0, 'responseHeaders': {'content-type': 'application/json', 'x-version': '1.0.0'}, 'responseStatusCode': 200, 'serverSequence': 32, 'state': 'initial'}], 'uri': '/app/v1/foo/bar/1'}] + responseBodyRef = [{'method': 'GET', 'events': [{'previousState': 'initial', 'receptionTimestampUs': 1623552535012124, 'responseBody': {'foo': 'bar-1'}, 'responseDelayMs': 0, 'responseHeaders': {'content-type': 'application/json', 'x-version': '1.0.0'}, 'responseStatusCode': 200, 'serverSequence': 32, 'state': 'initial'}], 'uri': '/app/v1/foo/bar/1', 'provisionUri': '/app/v1/foo/bar/1'}] # Response will be something like: [{"method":"GET","events":[{"responseBody":{"foo":"bar-1"},"receptionTimestampUs":1623439423163143,"state":"initial"}],"uri":"/app/v1/foo/bar/1"}] # We have a variable field 'receptionTimestampUs' and we don't know its real value. # So, we will remove it from both reference and response python dictionaries: @@ -47,7 +47,7 @@ def test_002_i_want_to_get_speficic_internal_data_on_admin_interface(h2ac_admin, # Check server data response = h2ac_admin.get(ADMIN_SERVER_DATA_URI + "?requestMethod=GET&requestUri=/app/v1/foo/bar/2") - responseBodyRef = { "method": "GET", "events": [{'previousState': 'initial', 'responseBody': {'foo': 'bar-2'}, 'responseDelayMs': 0, 'responseHeaders': {'content-type': 'application/json', 'x-version': '1.0.0'}, 'responseStatusCode': 200, 'state': 'initial'}], "uri": "/app/v1/foo/bar/2" } + responseBodyRef = { "method": "GET", "events": [{'previousState': 'initial', 'responseBody': {'foo': 'bar-2'}, 'responseDelayMs': 0, 'responseHeaders': {'content-type': 'application/json', 'x-version': '1.0.0'}, 'responseStatusCode': 200, 'state': 'initial'}], "uri": "/app/v1/foo/bar/2", "provisionUri": "/app/v1/foo/bar/2" } # serverSequence and receptionTimestampUs have been removed from reference and also will be removed from response as they are not predictable: # hyper does not add headers on traffic as curl does, so we don't have to remove 'headers' key. del response["body"]["events"][0]["serverSequence"] # depends on the server sequence since the h2agent was started diff --git a/src/http2/MyTrafficHttp2Server.cpp b/src/http2/MyTrafficHttp2Server.cpp index f25b7eb..385fd03 100644 --- a/src/http2/MyTrafficHttp2Server.cpp +++ b/src/http2/MyTrafficHttp2Server.cpp @@ -336,6 +336,7 @@ ss << "TRAFFIC REQUEST RECEIVED" // Store event context information if (server_data_) { + normalizedKey.setProvisionUri(provision->getRequestUri()); // additional context getMockServerData()->loadEvent(normalizedKey, inState, (hasVirtualMethod ? provision->getOutState():outState), receptionTimestampUs, statusCode, req.header(), headers, requestBodyDataPart, responseBody, receptionId, responseDelayMs, server_data_key_history_ /* history enabled */); // Virtual storage: @@ -348,6 +349,7 @@ ss << "TRAFFIC REQUEST RECEIVED" } h2agent::model::DataKey foreignKey(outStateMethod /* foreign method */, outStateUri /* foreign uri */); + foreignKey.setProvisionUri(provision->getRequestUri()); // additional context getMockServerData()->loadEvent(foreignKey, inState, outState, receptionTimestampUs, statusCode, req.header(), headers, requestBodyDataPart, responseBody, receptionId, responseDelayMs, server_data_key_history_ /* history enabled */, method /* virtual method origin*/, normalizedUri /* virtual uri origin */); } } diff --git a/src/model/AdminServerProvision.hpp b/src/model/AdminServerProvision.hpp index b0f174c..41fc8e3 100644 --- a/src/model/AdminServerProvision.hpp +++ b/src/model/AdminServerProvision.hpp @@ -272,6 +272,16 @@ class AdminServerProvision // getters: + /** + * Gets the provision request uri which could be a regular expression + * or a full-matched URI string + * + * @return Provision request URI + */ + const admin_server_provision_key_t &getRequestUri() const { + return request_uri_; + } + /** * Gets the provision key as '||' * diff --git a/src/model/keys.hpp b/src/model/keys.hpp index 0a72e54..a8b9554 100644 --- a/src/model/keys.hpp +++ b/src/model/keys.hpp @@ -58,6 +58,7 @@ class DataKey { std::string client_endpoint_id_{}; std::string method_{}; std::string uri_{}; + std::string provision_uri_{}; // for requests mock_events_key_t key_{}; int nkeys_; @@ -152,6 +153,7 @@ class DataKey { void keyToJson(nlohmann::json &doc) const { doc["method"] = method_; doc["uri"] = uri_; + if (!provision_uri_.empty()) doc["provisionUri"] = provision_uri_; if (getNKeys() == 3) { doc["clientEndpointId"] = client_endpoint_id_; } @@ -174,6 +176,13 @@ class DataKey { return (complete() || empty()); } + + /** + * Set provision URI (additional context data for requests in mock server mode) + */ + void setProvisionUri(const std::string &provisionUri) { + provision_uri_ = provisionUri; + } }; /** diff --git a/tools/helpers.src b/tools/helpers.src index 880467c..136ab2a 100644 --- a/tools/helpers.src +++ b/tools/helpers.src @@ -237,18 +237,20 @@ server_provision_schema() { } server_data() { - local curl_method= + local clean= local surf= + local dump= if [ "$1" = "-h" -o "$1" = "--help" ] then echo "Usage: server_data [-h|--help]; Inspects server data events (${ADMIN_URL}/server-data)." - echo " [method] [uri] [[-]event number] [event path] ; Restricts shown data with given positional filters." + echo " [method] [uri] [[-]event number] [event path] ; Positional filters to narrow the server data selection." echo " Event number may be negative to access by reverse chronological order." echo " [--summary] [max keys] ; Gets current server data summary to guide further queries." echo " Displayed keys (method/uri) could be limited (5 by default, -1: no limit)." - echo " [--clean] [query filters] ; Removes server data events. Admits additional query filters to narrow the selection." - echo " [--surf] ; Interactive sorted (regardless method/uri) server data navigation." + echo " [--clean] [query filters] ; Removes server data events." + echo " [--surf] [query filters] ; Interactive sorted (regardless method/uri) server data navigation." + echo " [--dump] [query filters] ; Dumps all sequences detected for server data under 'server-data-sequences' directory." return 0 elif [ "$1" = "--summary" ] then @@ -260,12 +262,16 @@ server_data() { return 0 elif [ "$1" = "--clean" ] then - curl_method="-XDELETE" + clean=yes shift elif [ "$1" = "--surf" ] then surf=yes shift + elif [ "$1" = "--dump" ] + then + dump=yes + shift fi local requestMethod=$1 @@ -276,67 +282,118 @@ server_data() { local keyIndicators="" [ -n "${requestMethod}" ] && keyIndicators+="x" [ -n "${requestUri}" ] && keyIndicators+="x" - [ "${keyIndicators}" = "x" -a -z "${surf}" ] && echo "Error: both method & uri must be provided" && return 1 + [ "${keyIndicators}" = "x" ] && echo "Error: both method & uri must be provided" && return 1 [ -n "${eventNumber}" -a -z "${keyIndicators}" ] && echo "Error: method/uri are also required when eventNumber is provided" && return 1 [ -n "${eventPath}" -a -z "${eventNumber}" ] && echo "Error: eventNumber is required when eventPath is provided" && return 1 local queryParams= [ -n "${requestMethod}" ] && queryParams="?requestMethod=${requestMethod}" # request URI not added here (it must be encoded with --data-urlencode) [ -n "${eventNumber}" ] && queryParams="${queryParams}&eventNumber=${eventNumber}" - if [ -z "${curl_method}" -a -z "${queryParams}" ] + + local curl_method= + [ -n "${clean}" ] && curl_method="-XDELETE" + + local devnull= + [ -n "${dump}" -o -n "${surf}" ] && devnull=">/dev/null" + + if [ -n "${requestUri}" ] then - if [ -n "${surf}" ] + local urlencode= + [ -n "${requestUri}" ] && urlencode="--data-urlencode requestUri=${requestUri}" + [ -n "${eventPath}" ] && urlencode+=" --data-urlencode eventPath=${eventPath}" + eval do_curl ${curl_method} -G ${urlencode} "${ADMIN_URL}/server-data${queryParams}" ${devnull} + else + if [ -z "${clean}${dump}${surf}" ] then - do_curl ${ADMIN_URL}/server-data >/dev/null - pretty | jq 'map(. as $parent | .events |= sort_by(.serverSequence) | .events[] | {events: [.], method: $parent.method, uri: $parent.uri}) | sort_by(.events[].serverSequence)' > /tmp/curl.out.sorted - local indx_max=$(jq '.[].events[].serverSequence' /tmp/curl.out.sorted | wc -l) - local indx=0 - [ ! -s /tmp/curl.out.sorted ] && echo && cat /tmp/curl.out && return 0 - while true - do - echo -e "\nMessage $((indx+1)):\n" - jq ".[$indx]" /tmp/curl.out.sorted - indx=$((indx+1)) - [ $indx -eq $indx_max ] && echo -e "\n\nThat's all ! ($indx_max events)\n" && return 0 - echo -e "\n\nPress ENTER to print next sequence ..." - read -r dummy - done - else echo echo "Take care about storage size when querying without filters." echo "You may want to check the summary before: server_data --summary" echo echo "Press ENTER to continue, CTRL-C to abort ..." read -r dummy - do_curl ${ADMIN_URL}/server-data fi - else - local urlencode= - [ -n "${requestUri}" ] && urlencode="--data-urlencode requestUri=${requestUri}" - [ -n "${eventPath}" ] && urlencode+=" --data-urlencode eventPath=${eventPath}" + eval do_curl ${curl_method} "${ADMIN_URL}/server-data" ${devnull} + fi + + [ -z "${clean}${dump}${surf}" ] && return 0 + + local sequences= + if [ -n "${requestUri}" ]; then sequences=( $(pretty ".events[].serverSequence" | sort -n) ) ; else sequences=( $(pretty ".[].events[].serverSequence" | sort -n) ) ; fi + local indx_max=${#sequences[@]} + + if [ -n "${dump}" ] + then + mkdir -p server-data-sequences + local arrayPrefix= + [ -z "${requestUri}" ] && arrayPrefix=".[] | " + for s in ${sequences[@]}; do pretty | jq "${arrayPrefix}select (.events[].serverSequence == $s) | del (.events[] | select (.serverSequence != $s))" > server-data-sequences/$(printf "%02d\n" "$s").json ; done + + elif [ -n "${surf}" ] + then if [ -n "${requestUri}" ] then - do_curl ${curl_method} -G ${urlencode} "${ADMIN_URL}/server-data${queryParams}" + pretty | jq '.method as $method | .uri as $uri | .provisionUri as $provisionUri | .events | map({events: [.], method: $method, uri: $uri, provisionUri: $provisionUri})' > /tmp/curl.out.sorted else - do_curl ${curl_method} "${ADMIN_URL}/server-data" + pretty | jq 'map(. as $parent | .events |= sort_by(.serverSequence) | .events[] | {events: [.], method: $parent.method, uri: $parent.uri, provisionUri: $parent.provisionUri}) | sort_by(.events[].serverSequence)' > /tmp/curl.out.sorted fi + + local indx=0 + [ ! -s /tmp/curl.out.sorted ] && echo && cat /tmp/curl.out && return 0 + echo + echo "Show also corresponding (p)rovisions or just show server [d]ata:" + read -r opt + [ -z "${opt}" ] && opt=d + [ "${opt}" = "p" ] && server_provision >/dev/null + while true + do + echo -e "\nMessage $((indx+1)):\n" + jq ".[$indx]" /tmp/curl.out.sorted + + # Corresponding provision: + if [ "${opt}" = "p" ] + then + local requestUri=$(jq -r ".[$indx].provisionUri" /tmp/curl.out.sorted) + if [ "${requestUri}" != "null" ] + then + echo -e "\nCorresponding provision processed:\n" + local inState=$(jq -r ".[$indx].events[0].previousState" /tmp/curl.out.sorted) + local requestMethod=$(jq -r ".[$indx].method" /tmp/curl.out.sorted) + if [ "${inState}" == "initial" ] + then + local cond="(.inState == \"initial\" or .inState == null) and .requestMethod == \""${requestMethod}"\" and .requestUri == \""${requestUri}"\"" + pretty | jq ".[] | select (${cond})" | sed 's/^/ /' + else + local cond=".inState == \""${inState}"\" and .requestMethod == \""${requestMethod}"\" and .requestUri == \""${requestUri}"\"" + pretty | jq ".[] | select (${cond})" | sed 's/^/ /' + fi + fi + fi + + indx=$((indx+1)) + [ $indx -eq $indx_max ] && echo -e "\n\nThat's all ! ($indx_max events)\n" && return 0 + echo -e "\n\nPress ENTER to print next sequence ..." + read -r dummy + done fi } client_data() { - local curl_method= + local clean= local surf= + local dump= if [ "$1" = "-h" -o "$1" = "--help" ] then echo "Usage: client_data [-h|--help]; Inspects client data events (${ADMIN_URL}/client-data)." - echo " [client endpoint id] [method] [uri] [[-]event number] [event path] ; Restricts shown data with given positional filters." + echo " [client endpoint id] [method] [uri] [[-]event number] [event path] ; Positional filters to narrow the client data selection." echo " Event number may be negative to access by reverse chronological order." echo " [--summary] [max keys] ; Gets current client data summary to guide further queries." echo " Displayed keys (client endpoint id/method/uri) could be limited (5 by default, -1: no limit)." - echo " [--clean] [query filters] ; Removes client data events. Admits additional query filters to narrow the selection." - echo " [--surf] ; Interactive sorted (regardless endpoint/method/uri) client data navigation." + echo " [--clean] [query filters] ; Removes client data events." + echo " [--surf] [query filters] ; Interactive sorted (regardless endpoint/method/uri) client data navigation." + echo " [--dump] [query filters] ; Dumps all sequences detected for client data under 'client-data-sequences' directory." return 0 + elif [ "$1" = "--summary" ] then local maxKeys=${2:-5} @@ -347,12 +404,16 @@ client_data() { return 0 elif [ "$1" = "--clean" ] then - curl_method="-XDELETE" + clean=yes shift elif [ "$1" = "--surf" ] then surf=yes shift + elif [ "$1" = "--dump" ] + then + dump=yes + shift fi local clientEndpointId=$1 @@ -365,7 +426,7 @@ client_data() { [ -n "${clientEndpointId}" ] && keyIndicators+="x" [ -n "${requestMethod}" ] && keyIndicators+="x" [ -n "${requestUri}" ] && keyIndicators+="x" - [ "${keyIndicators}" != "" -a "${keyIndicators}" != "xxx" -a -z "${surf}" ] && echo "Error: client endpoint id & method & uri must be provided" && return 1 + [ "${keyIndicators}" != "" -a "${keyIndicators}" != "xxx" ] && echo "Error: client endpoint id & method & uri must be provided" && return 1 [ -n "${eventNumber}" -a -z "${keyIndicators}" ] && echo "Error: client endpoint id/method/uri are also required when eventNumber is provided" && return 1 [ -n "${eventPath}" -a -z "${eventNumber}" ] && echo "Error: eventNumber is required when eventPath is provided" && return 1 @@ -373,56 +434,66 @@ client_data() { [ -n "${clientEndpointId}" ] && queryParams="?clientEndpointId=${clientEndpointId}" [ -n "${requestMethod}" ] && queryParams="${queryParams}&requestMethod=${requestMethod}" # request URI not added here (it must be encoded with --data-urlencode) [ -n "${eventNumber}" ] && queryParams="${queryParams}&eventNumber=${eventNumber}" - if [ -z "${curl_method}" -a -z "${queryParams}" ] + + local curl_method= + [ -n "${clean}" ] && curl_method="-XDELETE" + + local devnull= + [ -n "${dump}" -o -n "${surf}" ] && devnull=">/dev/null" + + if [ -n "${requestUri}" ] then - if [ -n "${surf}" ] + local urlencode= + [ -n "${requestUri}" ] && urlencode="--data-urlencode requestUri=${requestUri}" + [ -n "${eventPath}" ] && urlencode+=" --data-urlencode eventPath=${eventPath}" + eval do_curl ${curl_method} -G ${urlencode} "${ADMIN_URL}/client-data${queryParams}" ${devnull} + else + if [ -z "${clean}${dump}${surf}" ] then - do_curl ${ADMIN_URL}/client-data >/dev/null - pretty | jq 'map(. as $parent | .events |= sort_by(.clientSequence) | .events[] | {events: [.], method: $parent.method, uri: $parent.uri}) | sort_by(.events[].clientSequence)' > /tmp/curl.out.sorted - local indx_max=$(jq '.[].events[].clientSequence' /tmp/curl.out.sorted | wc -l) - local indx=0 - [ ! -s /tmp/curl.out.sorted ] && echo && cat /tmp/curl.out && return 0 - while true - do - echo -e "\nMessage $((indx+1)):\n" - jq ".[$indx]" /tmp/curl.out.sorted - indx=$((indx+1)) - [ $indx -eq $indx_max ] && echo -e "\n\nThat's all ! ($indx_max events)\n" && return 0 - echo -e "\n\nPress ENTER to print next sequence ..." - read -r dummy - done - else echo echo "Take care about storage size when querying without filters." echo "You may want to check the summary before: client_data --summary" echo echo "Press ENTER to continue, CTRL-C to abort ..." read -r dummy - do_curl ${ADMIN_URL}/client-data fi - else - local urlencode= - [ -n "${requestUri}" ] && urlencode="--data-urlencode requestUri=${requestUri}" - [ -n "${eventPath}" ] && urlencode+=" --data-urlencode eventPath=${eventPath}" + eval do_curl ${curl_method} "${ADMIN_URL}/client-data" ${devnull} + fi + + [ -z "${clean}${dump}${surf}" ] && return 0 + + local sequences= + if [ -n "${requestUri}" ]; then sequences=( $(pretty ".events[].clientSequence" | sort -n) ) ; else sequences=( $(pretty ".[].events[].clientSequence" | sort -n) ) ; fi + local indx_max=${#sequences[@]} + + if [ -n "${dump}" ] + then + mkdir -p client-data-sequences + local arrayPrefix= + [ -z "${requestUri}" ] && arrayPrefix=".[] | " + for s in ${sequences[@]}; do pretty | jq "${arrayPrefix}select (.events[].clientSequence == $s) | del (.events[] | select (.clientSequence != $s))" > client-data-sequences/$(printf "%02d\n" "$s").json ; done + + elif [ -n "${surf}" ] + then if [ -n "${requestUri}" ] then - do_curl ${curl_method} -G ${urlencode} "${ADMIN_URL}/client-data${queryParams}" + pretty | jq '.method as $method | .uri as $uri | .events | map({events: [.], method: $method, uri: $uri})' > /tmp/curl.out.sorted else - do_curl ${curl_method} "${ADMIN_URL}/client-data" + pretty | jq 'map(. as $parent | .events |= sort_by(.clientSequence) | .events[] | {events: [.], method: $parent.method, uri: $parent.uri}) | sort_by(.events[].clientSequence)' > /tmp/curl.out.sorted fi - fi -} - -server_data_sequence() { - [ "$1" = "-h" -o "$1" = "--help" ] && echo "Usage: server_data_sequence [-h|--help] [value (available values by default)]; Extract server sequence document from json retrieved in previous server_data() call." && return 0 - [ -z "$1" ] && pretty ".[].events[].serverSequence" | sort -n && return 0 - pretty ".[] | select (.events[].serverSequence == $1) | del (.events[] | select (.serverSequence != $1))" 2>/dev/null -} -client_data_sequence() { - [ "$1" = "-h" -o "$1" = "--help" ] && echo "Usage: client_data_sequence [-h|--help] [value (available values by default)]; Extract client sequence document from json retrieved in previous client_data() call." && return 0 - [ -z "$1" ] && pretty ".[].events[].clientSequence" | sort -n && return 0 - pretty ".[] | select (.events[].clientSequence == $1) | del (.events[] | select (.clientSequence != $1))" 2>/dev/null + local indx=0 + [ ! -s /tmp/curl.out.sorted ] && echo && cat /tmp/curl.out && return 0 + while true + do + echo -e "\nMessage $((indx+1)):\n" + jq ".[$indx]" /tmp/curl.out.sorted + indx=$((indx+1)) + [ $indx -eq $indx_max ] && echo -e "\n\nThat's all ! ($indx_max events)\n" && return 0 + echo -e "\n\nPress ENTER to print next sequence ..." + read -r dummy + done + fi } client_endpoint() { @@ -562,41 +633,31 @@ snapshot() { files_configuration && pretty > ${dir}/files-configuration.json udp_sockets && pretty > ${dir}/udp-sockets.json configuration && pretty > ${dir}/configuration.json - server_configuration && pretty > ${dir}/server-configuration.json server_data_configuration && pretty > ${dir}/server-data-configuration.json client_data_configuration && pretty > ${dir}/client-data-configuration.json + server_matching && pretty > ${dir}/server-matching.json server_matching_schema && pretty > ${dir}/server-matching_schema.json + server_provision && pretty > ${dir}/server-provision.json server_provision_unused && pretty > ${dir}/server-provision_unused.json server_provision_schema && pretty > ${dir}/server-provision_schema.json + server_data --summary -1 && pretty > ${dir}/server-data-summary.json echo | server_data && pretty > ${dir}/server-data.json - mkdir ${dir}/server-data-sequences - (jq '.[].events[].serverSequence' ${dir}/server-data.json | sort -nu | tr '\n' ' ' && echo) > ${dir}/server-data-sequences.txt - for s in $(cat ${dir}/server-data-sequences.txt); do - jq ".[] | select (.events[].serverSequence == $s) | del (.events[] | select (.serverSequence != $s))" ${dir}/server-data.json > ${dir}/server-data-sequences/${s}.json - done + pushd ${dir} ; server_data --dump ; popd + client_data --summary -1 && pretty > ${dir}/client-data-summary.json echo | client_data && pretty > ${dir}/client-data.json - mkdir ${dir}/client-data-sequences - (jq '.[].events[].clientSequence' ${dir}/client-data.json | sort -nu | tr '\n' ' ' && echo) > ${dir}/client-data-sequences.txt - for s in $(cat ${dir}/client-data-sequences.txt); do - jq ".[] | select (.events[].clientSequence == $s) | del (.events[] | select (.clientSequence != $s))" ${dir}/client-data.json > ${dir}/client-data-sequences/${s}.json - done + pushd ${dir} ; client_data --dump ; popd + client_endpoint && pretty > ${dir}/client_endpoint.json client_endpoint_schema && pretty > ${dir}/client_endpoint_schema.json client_provision && pretty > ${dir}/client-provision.json client_provision_unused && pretty > ${dir}/client-provision_unused.json client_provision_schema && pretty > ${dir}/client-provision_schema.json - client_data --summary -1 && pretty > ${dir}/client-data-summary.json - echo | client_data && pretty > ${dir}/client-data.json - mkdir ${dir}/client-data-sequences - (jq '.[].events[].clientSequence' ${dir}/client-data.json | sort -nu | tr '\n' ' ' && echo) > ${dir}/client-data-sequences.txt - for s in $(cat ${dir}/client-data-sequences.txt); do - jq ".[] | select (.events[].clientSequence == $s) | del (.events[] | select (.clientSequence != $s))" ${dir}/client-data.json > ${dir}/client-data-sequences/${s}.json - done + metrics > ${dir}/metrics.txt echo @@ -708,14 +769,12 @@ help() { server_provision -h server_provision_unused -h server_data -h - server_data_sequence -h echo echo "=== Traffic client ===" client_endpoint -h client_provision -h client_provision_unused -h client_data -h - client_data_sequence -h echo echo "=== Schemas ===" schema_schema -h diff --git a/ut/model/Keys/keys.cpp b/ut/model/Keys/keys.cpp index 3821f00..cb3c80e 100644 --- a/ut/model/Keys/keys.cpp +++ b/ut/model/Keys/keys.cpp @@ -106,6 +106,20 @@ TEST(keys, dataKeyThreePartsKeyToJson) { EXPECT_EQ(asserted, expected); } +TEST(keys, dataKeyWithProvisionUri) { + h2agent::model::DataKey key("POST", "/foo/bar/1234"); + key.setProvisionUri("(/foo/bar/)([0-9]*)"); + + nlohmann::json asserted; + key.keyToJson(asserted); + + nlohmann::json expected; + expected["method"] = "POST"; + expected["uri"] = "/foo/bar/1234"; + expected["provisionUri"] = "(/foo/bar/)([0-9]*)"; + EXPECT_EQ(asserted, expected); +} + TEST(keys, eventKeyDataKeyConstructorTwoPartsGetters) { h2agent::model::DataKey key("POST", "/foo/bar"); h2agent::model::EventKey ekey(key, "1");