aboutsummaryrefslogtreecommitdiffstats
path: root/container-core/src/test/java/com/yahoo/container/handler/metrics/PrometheusHandlerTest.java
blob: 31b21651fdc4bda96021955de3c81921b12f2702 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.handler.metrics;

import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.yahoo.container.jdisc.RequestHandlerTestDriver;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static com.yahoo.container.handler.metrics.MetricsV2Handler.V2_PATH;
import static com.yahoo.container.handler.metrics.MetricsV2Handler.VALUES_PATH;
import static com.yahoo.container.handler.metrics.MetricsV2Handler.consumerQuery;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
 * @author gjoranv
 */
public class PrometheusHandlerTest {

    private static final String URI_BASE = "http://localhost";

    private static final String V2_URI = URI_BASE + PrometheusHandler.V1_PATH;
    private static final String VALUES_URI = URI_BASE + PrometheusHandler.VALUES_PATH;

    // Mock applicationmetrics api
    private static final String MOCK_METRICS_PATH = "/node0";

    private static final String TEST_FILE = "application-metrics.json";
    private static final String RESPONSE = getFileContents(TEST_FILE);
    private static final String CPU_METRIC = "cpu.util";
    private static final String REPLACED_CPU_METRIC = "replaced_cpu_util";
    private static final String CUSTOM_CONSUMER = "custom-consumer";

    private static RequestHandlerTestDriver testDriver;

    @Rule
    public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort());

    @Before
    public void setup() {
        setupWireMock();
        var handler = new PrometheusHandler(Executors.newSingleThreadExecutor(),
                new MetricsProxyApiConfig.Builder()
                        .prometheusPort(wireMockRule.port())
                        .prometheusApiPath(MOCK_METRICS_PATH)
                        .metricsPort(0)
                        .metricsApiPath("/Not/In/Use")
                        .build());
        testDriver = new RequestHandlerTestDriver(handler);

    }

    private void setupWireMock() {
        wireMockRule.stubFor(get(urlPathEqualTo(MOCK_METRICS_PATH))
                .willReturn(aResponse().withBody(RESPONSE)));

        // Add a slightly different response for a custom consumer.
        String myConsumerResponse = RESPONSE.replaceAll(CPU_METRIC, REPLACED_CPU_METRIC);
        wireMockRule.stubFor(get(urlPathEqualTo(MOCK_METRICS_PATH))
                .withQueryParam("consumer", equalTo(CUSTOM_CONSUMER))
                .willReturn(aResponse().withBody(myConsumerResponse)));
    }

    @Test
    public void v2_response_contains_values_uri() throws Exception {
        String response = testDriver.sendRequest(V2_URI).readAll();
        JSONObject root = new JSONObject(response);
        assertTrue(root.has("resources"));

        JSONArray resources = root.getJSONArray("resources");
        assertEquals(1, resources.length());

        JSONObject valuesUri = resources.getJSONObject(0);
        assertEquals(VALUES_URI, valuesUri.getString("url"));
    }

    @Test
    public void visually_inspect_values_response() throws Exception {
        String response = testDriver.sendRequest(VALUES_URI).readAll();
        System.out.println(response);
    }

    @Test
    public void invalid_path_yields_error_response() throws Exception {
        String response = testDriver.sendRequest(V2_URI + "/invalid").readAll();
        JSONObject root = new JSONObject(response);
        assertTrue(root.has("error"));
        assertTrue(root.getString("error" ).startsWith("No content"));
    }

    //Currently broken as no way to convert to Prometheus format around here
    @Ignore
    @Test
    public void values_response_is_equal_to_test_file() {
        String response = testDriver.sendRequest(VALUES_URI).readAll();
        assertEquals(RESPONSE, response);
    }

    @Test
    public void consumer_is_propagated_to_metrics_proxy_api() throws JSONException {
        String response = testDriver.sendRequest(VALUES_URI + consumerQuery(CUSTOM_CONSUMER)).readAll();

        assertTrue(response.contains(REPLACED_CPU_METRIC));
    }

    private static String getFileContents(String filename) {
        InputStream in = PrometheusHandlerTest.class.getClassLoader().getResourceAsStream(filename);
        if (in == null) {
            throw new RuntimeException("File not found: " + filename);
        }
        return new BufferedReader(new InputStreamReader(in)).lines().collect(Collectors.joining("\n"));
    }

}