github.com/m3db/m3@v1.5.0/scripts/docker-integration-tests/simple_v2_batch_apis/test.sh (about) 1 #!/usr/bin/env bash 2 3 set -xe 4 5 source "$M3_PATH"/scripts/docker-integration-tests/common.sh 6 REVISION=$(git rev-parse HEAD) 7 COMPOSE_FILE="$M3_PATH"/scripts/docker-integration-tests/prometheus/docker-compose.yml 8 # quay.io/m3db/prometheus_remote_client_golang @ v0.4.3 9 PROMREMOTECLI_IMAGE=quay.io/m3db/prometheus_remote_client_golang:v0.4.3 10 JQ_IMAGE=realguess/jq:1.4@sha256:300c5d9fb1d74154248d155ce182e207cf6630acccbaadd0168e18b15bfaa786 11 METRIC_NAME_TEST_TOO_OLD=foo 12 METRIC_NAME_TEST_RESTRICT_WRITE=bar 13 export REVISION 14 15 echo "Pull containers required for test" 16 docker pull $PROMREMOTECLI_IMAGE 17 docker pull $JQ_IMAGE 18 19 echo "Run m3dbnode and m3coordinator containers" 20 docker-compose -f ${COMPOSE_FILE} up -d dbnode01 21 docker-compose -f ${COMPOSE_FILE} up -d coordinator01 22 23 function defer { 24 docker-compose -f ${COMPOSE_FILE} down || echo "unable to shutdown containers" # CI fails to stop all containers sometimes 25 } 26 trap defer EXIT 27 28 setup_single_m3db_node 29 30 echo "Start Prometheus containers" 31 docker-compose -f ${COMPOSE_FILE} up -d prometheus01 32 33 function test_prometheus_remote_read { 34 # Ensure Prometheus can proxy a Prometheus query 35 echo "Wait until the remote write endpoint generates and allows for data to be queried" 36 ATTEMPTS=50 TIMEOUT=2 MAX_TIMEOUT=4 retry_with_backoff \ 37 '[[ $(curl -sSf 0.0.0.0:9090/api/v1/query?query=prometheus_remote_storage_samples_total | jq -r .data.result[0].value[1]) -gt 100 ]]' 38 } 39 40 function test_prometheus_remote_write_multi_namespaces { 41 # Make sure we're proxying writes to the unaggregated namespace 42 echo "Wait until data begins being written to remote storage for the unaggregated namespace" 43 ATTEMPTS=50 TIMEOUT=2 MAX_TIMEOUT=4 retry_with_backoff \ 44 '[[ $(curl -sSf 0.0.0.0:9090/api/v1/query?query=database_write_tagged_success\\{namespace=\"unagg\"\\} | jq -r .data.result[0].value[1]) -gt 0 ]]' 45 46 # Make sure we're proxying writes to the aggregated namespace 47 echo "Wait until data begins being written to remote storage for the aggregated namespace" 48 ATTEMPTS=50 TIMEOUT=2 MAX_TIMEOUT=4 retry_with_backoff \ 49 '[[ $(curl -sSf 0.0.0.0:9090/api/v1/query?query=database_write_tagged_success\\{namespace=\"agg\"\\} | jq -r .data.result[0].value[1]) -gt 0 ]]' 50 } 51 52 function prometheus_remote_write { 53 local metric_name=$1 54 local datapoint_timestamp=$2 55 local datapoint_value=$3 56 local expect_success=$4 57 local expect_success_err=$5 58 local expect_status=$6 59 local expect_status_err=$7 60 local metrics_type=$8 61 local metrics_storage_policy=$9 62 63 network_name="simple_v2_batch_apis" 64 network=$(docker network ls | fgrep $network_name | tr -s ' ' | cut -f 1 -d ' ' | tail -n 1) 65 out=$((docker run -it --rm --network $network \ 66 $PROMREMOTECLI_IMAGE \ 67 -u http://dbnode01:7201/api/v1/prom/remote/write \ 68 -t __name__:${metric_name} \ 69 -h "M3-Metrics-Type: ${metrics_type}" \ 70 -h "M3-Storage-Policy: ${metrics_storage_policy}" \ 71 -d ${datapoint_timestamp},${datapoint_value} | grep -v promremotecli_log) || true) 72 success=$(echo $out | grep -v promremotecli_log | docker run --rm -i $JQ_IMAGE jq .success) 73 status=$(echo $out | grep -v promremotecli_log | docker run --rm -i $JQ_IMAGE jq .statusCode) 74 if [[ "$success" != "$expect_success" ]]; then 75 echo $expect_success_err 76 return 1 77 fi 78 if [[ "$status" != "$expect_status" ]]; then 79 echo "${expect_status_err}: actual=${status}" 80 return 1 81 fi 82 echo "Returned success=${success}, status=${status} as expected" 83 return 0 84 } 85 86 function test_prometheus_remote_write_too_old_returns_400_status_code { 87 # Test writing too far into the past returns an HTTP 400 status code 88 echo "Test write into the past returns HTTP 400" 89 now=$(date +"%s") 90 hour_ago=$(( now - 3600 )) 91 prometheus_remote_write \ 92 $METRIC_NAME_TEST_TOO_OLD $hour_ago 3.142 \ 93 false "Expected request to fail" \ 94 400 "Expected request to return status code 400" 95 } 96 97 function test_prometheus_remote_write_restrict_metrics_type { 98 # Test we can specify metrics type 99 echo "Test write with unaggregated metrics type works as expected" 100 prometheus_remote_write \ 101 $METRIC_NAME_TEST_RESTRICT_WRITE now 42.42 \ 102 true "Expected request to succeed" \ 103 200 "Expected request to return status code 200" \ 104 unaggregated 105 106 echo "Test write with aggregated metrics type works as expected" 107 prometheus_remote_write \ 108 $METRIC_NAME_TEST_RESTRICT_WRITE now 84.84 \ 109 true "Expected request to succeed" \ 110 200 "Expected request to return status code 200" \ 111 aggregated 15s:10h 112 } 113 114 function test_query_limits_applied { 115 # Test the default series limit applied when directly querying 116 # coordinator (limit set to 100 in m3coordinator.yml) 117 echo "Test query limit with coordinator defaults" 118 ATTEMPTS=50 TIMEOUT=2 MAX_TIMEOUT=4 retry_with_backoff \ 119 '[[ $(curl -s 0.0.0.0:7201/api/v1/query?query=\\{name!=\"\"\\} | jq -r ".data.result | length") -eq 100 ]]' 120 121 # Test the default series limit applied when directly querying 122 # coordinator (limit set by header) 123 echo "Test query limit with coordinator limit header" 124 ATTEMPTS=50 TIMEOUT=2 MAX_TIMEOUT=4 retry_with_backoff \ 125 '[[ $(curl -s -H "M3-Limit-Max-Series: 10" -H "M3-Limit-Require-Exhaustive: false" 0.0.0.0:7201/api/v1/query?query=\\{name!=\"\"\\} | jq -r ".data.result | length") -eq 10 ]]' 126 } 127 128 function prometheus_query_native { 129 local endpoint=${endpoint:-} 130 local query=${query:-} 131 local params=${params:-} 132 local metrics_type=${metrics_type:-} 133 local metrics_storage_policy=${metrics_storage_policy:-} 134 local jq_path=${jq_path:-} 135 local expected_value=${expected_value:-} 136 137 params_prefixed="" 138 if [[ "$params" != "" ]]; then 139 params_prefixed='&'"${params}" 140 fi 141 142 result=$(curl -s \ 143 -H "M3-Metrics-Type: ${metrics_type}" \ 144 -H "M3-Storage-Policy: ${metrics_storage_policy}" \ 145 "0.0.0.0:7201/api/v1/${endpoint}?query=${query}${params_prefixed}" | jq -r "${jq_path}") 146 test "$result" = "$expected_value" 147 return $? 148 } 149 150 function test_query_restrict_metrics_type { 151 now=$(date +"%s") 152 hour_ago=$(( now - 3600 )) 153 154 step="30s" 155 params_instant="" 156 params_range="start=${hour_ago}"'&'"end=${now}"'&'"step=30s" 157 jq_path_instant=".data.result[0].value[1]" 158 jq_path_range=".data.result[0].values[][1]" 159 160 # Test restricting to unaggregated metrics 161 echo "Test query restrict to unaggregated metrics type (instant)" 162 ATTEMPTS=50 TIMEOUT=2 MAX_TIMEOUT=4 \ 163 endpoint=query query="$METRIC_NAME_TEST_RESTRICT_WRITE" params="$params_instant" \ 164 metrics_type="unaggregated" jq_path="$jq_path_instant" expected_value="42.42" \ 165 retry_with_backoff prometheus_query_native 166 echo "Test query restrict to unaggregated metrics type (range)" 167 ATTEMPTS=50 TIMEOUT=2 MAX_TIMEOUT=4 \ 168 endpoint=query_range query="$METRIC_NAME_TEST_RESTRICT_WRITE" params="$params_range" \ 169 metrics_type="unaggregated" jq_path="$jq_path_range" expected_value="42.42" \ 170 retry_with_backoff prometheus_query_native 171 172 # Test restricting to aggregated metrics 173 echo "Test query restrict to aggregated metrics type (instant)" 174 ATTEMPTS=50 TIMEOUT=2 MAX_TIMEOUT=4 \ 175 endpoint=query query="$METRIC_NAME_TEST_RESTRICT_WRITE" params="$params_instant" \ 176 metrics_type="aggregated" metrics_storage_policy="15s:10h" jq_path="$jq_path_instant" expected_value="84.84" \ 177 retry_with_backoff prometheus_query_native 178 echo "Test query restrict to aggregated metrics type (range)" 179 ATTEMPTS=50 TIMEOUT=2 MAX_TIMEOUT=4 \ 180 endpoint=query_range query="$METRIC_NAME_TEST_RESTRICT_WRITE" params="$params_range" \ 181 metrics_type="aggregated" metrics_storage_policy="15s:10h" jq_path="$jq_path_range" expected_value="84.84" \ 182 retry_with_backoff prometheus_query_native 183 } 184 185 # Run all tests 186 test_prometheus_remote_read 187 test_prometheus_remote_write_multi_namespaces 188 test_prometheus_remote_write_too_old_returns_400_status_code 189 test_prometheus_remote_write_restrict_metrics_type 190 test_query_limits_applied 191 test_query_restrict_metrics_type