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