github.com/m3db/m3@v1.5.0/scripts/docker-integration-tests/coordinator_config_rules/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  SCRIPT_PATH="$M3_PATH"/scripts/docker-integration-tests/coordinator_config_rules
     8  COMPOSE_FILE=$SCRIPT_PATH/docker-compose.yml
     9  # quay.io/m3db/prometheus_remote_client_golang @ v0.4.3
    10  PROMREMOTECLI_IMAGE=quay.io/m3db/prometheus_remote_client_golang:v0.4.3
    11  JQ_IMAGE=realguess/jq:1.4@sha256:300c5d9fb1d74154248d155ce182e207cf6630acccbaadd0168e18b15bfaa786
    12  export REVISION
    13  
    14  echo "Pull containers required for test"
    15  docker pull $PROMREMOTECLI_IMAGE
    16  docker pull $JQ_IMAGE
    17  
    18  echo "Run m3dbnode and m3coordinator containers"
    19  docker-compose -f ${COMPOSE_FILE} up -d dbnode01
    20  docker-compose -f ${COMPOSE_FILE} up -d coordinator01
    21  
    22  # Think of this as a defer func() in golang
    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_long_namespaces
    29  
    30  function prometheus_remote_write {
    31    local metric_name=$1
    32    local datapoint_timestamp=$2
    33    local datapoint_value=$3
    34    local expect_success=$4
    35    local expect_success_err=$5
    36    local expect_status=$6
    37    local expect_status_err=$7
    38    local label0_name=${label0_name:-label0}
    39    local label0_value=${label0_value:-label0}
    40    local label1_name=${label1_name:-label1}
    41    local label1_value=${label1_value:-label1}
    42    local label2_name=${label2_name:-label2}
    43    local label2_value=${label2_value:-label2}
    44  
    45    network_name="coordinator_config_rules"
    46    network=$(docker network ls | fgrep $network_name | tr -s ' ' | cut -f 1 -d ' ' | tail -n 1)
    47    out=$((docker run -it --rm --network $network           \
    48      $PROMREMOTECLI_IMAGE                                  \
    49      -u http://coordinator01:7201/api/v1/prom/remote/write \
    50      -t __name__:${metric_name}                            \
    51      -t ${label0_name}:${label0_value}                     \
    52      -t ${label1_name}:${label1_value}                     \
    53      -t ${label2_name}:${label2_value}                     \
    54      -d ${datapoint_timestamp},${datapoint_value} | grep -v promremotecli_log) || true)
    55    success=$(echo $out | grep -v promremotecli_log | docker run --rm -i $JQ_IMAGE jq .success)
    56    status=$(echo $out | grep -v promremotecli_log | docker run --rm -i $JQ_IMAGE jq .statusCode)
    57    if [[ "$success" != "$expect_success" ]]; then
    58      echo $expect_success_err
    59      return 1
    60    fi
    61    if [[ "$status" != "$expect_status" ]]; then
    62      echo "${expect_status_err}: actual=${status}"
    63      return 1
    64    fi
    65    echo "Returned success=${success}, status=${status} as expected"
    66    return 0
    67  }
    68  
    69  function prometheus_query_native {
    70    local endpoint=${endpoint:-}
    71    local query=${query:-}
    72    local params=${params:-}
    73    local metrics_type=${metrics_type:-}
    74    local metrics_storage_policy=${metrics_storage_policy:-}
    75    local jq_path=${jq_path:-}
    76    local expected_value=${expected_value:-}
    77  
    78    params_prefixed=""
    79    if [[ "$params" != "" ]]; then
    80      params_prefixed='&'"${params}"
    81    fi
    82  
    83    result=$(curl -s                                    \
    84      -H "M3-Metrics-Type: ${metrics_type}"             \
    85      -H "M3-Storage-Policy: ${metrics_storage_policy}" \
    86      "0.0.0.0:7201/api/v1/${endpoint}?query=${query}${params_prefixed}" | jq -r "${jq_path}" | jq -s last)
    87    test "$result" = "$expected_value"
    88    return $?
    89  }
    90  
    91  function test_query_mapping_rule {
    92    now=$(date +"%s")
    93    now_truncate_by=$(( $now % 5 ))
    94    now_truncated=$(( $now - $now_truncate_by ))
    95    now_truncated_plus_second=$(( $now_truncated + 1 ))
    96  
    97    echo "Test write with mapping rule"
    98    # nginx metrics
    99    label0_name="app" label0_value="nginx_edge" \
   100      prometheus_remote_write \
   101      foo_metric $now_truncated 42.42 \
   102      true "Expected request to succeed" \
   103      200 "Expected request to return status code 200"
   104    label0_name="app" label0_value="nginx_edge" \
   105      prometheus_remote_write \
   106      foo_metric $now_truncated_plus_second 84.84 \
   107      true "Expected request to succeed" \
   108      200 "Expected request to return status code 200"
   109  
   110    # mysql metrics
   111    label0_name="app" label0_value="mysql_db" \
   112      prometheus_remote_write \
   113      foo_metric $now_truncated 45.42 \
   114      true "Expected request to succeed" \
   115      200 "Expected request to return status code 200"
   116    label0_name="app" label0_value="mysql_db" \
   117      prometheus_remote_write \
   118      foo_metric $now_truncated_plus_second 87.84 \
   119      true "Expected request to succeed" \
   120      200 "Expected request to return status code 200"
   121  
   122    start=$(( $now - 3600 ))
   123    end=$(( $now + 3600 ))
   124    step="30s"
   125    params_range="start=${start}"'&'"end=${end}"'&'"step=30s"
   126    jq_path=".data.result[0].values[0] | .[1] | select(. != null)"
   127  
   128    # Test values can be mapped to 30s:24h resolution namespace (for app="nginx")
   129    echo "Test query mapping rule"
   130    ATTEMPTS=50 TIMEOUT=2 MAX_TIMEOUT=4 \
   131      endpoint=query_range query=foo_metric params="$params_range" \
   132      jq_path="$jq_path" expected_value="84.84" \
   133      metrics_type="aggregated" metrics_storage_policy="30s:24h" \
   134      retry_with_backoff prometheus_query_native
   135  
   136    # Test values can be mapped to 1m:48h resolution namespace (for app="mysql")
   137    ATTEMPTS=50 TIMEOUT=2 MAX_TIMEOUT=4 \
   138      endpoint=query_range query=foo_metric params="$params_range" \
   139      jq_path="$jq_path" expected_value="87.84" \
   140      metrics_type="aggregated" metrics_storage_policy="1m:48h" \
   141      retry_with_backoff prometheus_query_native
   142  }
   143  
   144  function test_query_rollup_rule {
   145    if [ "$TEST_ROLLUP_RULE" != "true" ]; then
   146      echo "Skip testing rollup rule, timestamped metrics don't work with rollup rules just yet"
   147      return 0
   148    fi
   149  
   150    now=$(date +"%s")
   151    now_truncate_by=$(( $now % 5 ))
   152    now_truncated=$(( $now - $now_truncate_by ))
   153    now_truncated_plus_second=$(( $now_truncated + 1 ))
   154  
   155    echo "Test write with rollup rule"
   156  
   157    # Emit values for endpoint /foo/bar (to ensure right values aggregated)
   158    label0_name="app" label0_value="nginx_edge" \
   159      label1_name="status_code" label1_value="500" \
   160      label2_name="endpoint" label2_value="/foo/bar" \
   161      prometheus_remote_write \
   162      http_requests $now_truncated 42 \
   163      true "Expected request to succeed" \
   164      200 "Expected request to return status code 200"
   165    label0_name="app" label0_value="nginx_edge" \
   166      label1_name="status_code" label1_value="500" \
   167      label2_name="endpoint" label2_value="/foo/bar" \
   168      prometheus_remote_write \
   169      http_requests $now_truncated_plus_second 64 \
   170      true "Expected request to succeed" \
   171      200 "Expected request to return status code 200"
   172  
   173    # Emit values for endpoint /foo/baz (to ensure right values aggregated)
   174    label0_name="app" label0_value="nginx_edge" \
   175      label1_name="status_code" label1_value="500" \
   176      label2_name="endpoint" label2_value="/foo/baz" \
   177      prometheus_remote_write \
   178      http_requests $now_truncated 8 \
   179      true "Expected request to succeed" \
   180      200 "Expected request to return status code 200"
   181    label0_name="app" label0_value="nginx_edge" \
   182      label1_name="status_code" label1_value="500" \
   183      label2_name="endpoint" label2_value="/foo/baz" \
   184      prometheus_remote_write \
   185      http_requests $now_truncated_plus_second 12 \
   186      true "Expected request to succeed" \
   187      200 "Expected request to return status code 200"
   188  
   189    start=$(( $now - 3600 ))
   190    end=$(( $now + 3600 ))
   191    step="30s"
   192    params_range="start=${start}"'&'"end=${end}"'&'"step=30s"
   193    jq_path=".data.result[0].values | .[][1] | select(. != null)"
   194  
   195    echo "Test query rollup rule"
   196  
   197    # Test by values are rolled up by second, then sum (for endpoint="/foo/bar")
   198    ATTEMPTS=50 TIMEOUT=2 MAX_TIMEOUT=4 \
   199      endpoint=query_range query="http_requests_by_status_code\{endpoint=\"/foo/bar\"\}" \
   200      params="$params_range" \
   201      jq_path="$jq_path" expected_value="22" \
   202      metrics_type="aggregated" metrics_storage_policy="5s:10h" \
   203      retry_with_backoff prometheus_query_native
   204  
   205    # Test by values are rolled up by second, then sum (for endpoint="/foo/bar")
   206    ATTEMPTS=50 TIMEOUT=2 MAX_TIMEOUT=4 \
   207      endpoint=query_range query="http_requests_by_status_code\{endpoint=\"/foo/baz\"\}" \
   208      params="$params_range" \
   209      jq_path="$jq_path" expected_value="4" \
   210      metrics_type="aggregated" metrics_storage_policy="5s:10h" \
   211      retry_with_backoff prometheus_query_native
   212  }
   213  
   214  echo "Running prometheus mapping and rollup rule tests"
   215  test_query_mapping_rule
   216  test_query_rollup_rule