summaryrefslogtreecommitdiffstats
path: root/container-core/src/test/java/com/yahoo/container/jdisc/state/MetricsPacketsHandlerTest.java
blob: ef700597537256526ac296d1fac8c836aad8348e (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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.jdisc.state;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yahoo.jdisc.Metric;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static com.yahoo.container.jdisc.state.MetricsPacketsHandler.APPLICATION_KEY;
import static com.yahoo.container.jdisc.state.MetricsPacketsHandler.DIMENSIONS_KEY;
import static com.yahoo.container.jdisc.state.MetricsPacketsHandler.METRICS_KEY;
import static com.yahoo.container.jdisc.state.MetricsPacketsHandler.PACKET_SEPARATOR;
import static com.yahoo.container.jdisc.state.MetricsPacketsHandler.STATUS_CODE_KEY;
import static com.yahoo.container.jdisc.state.MetricsPacketsHandler.STATUS_MSG_KEY;
import static com.yahoo.container.jdisc.state.MetricsPacketsHandler.TIMESTAMP_KEY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
 * @author gjoranv
 */
public class MetricsPacketsHandlerTest extends StateHandlerTestBase {

    @Test
    public void only_status_packet_is_returned_prior_to_first_snapshot() throws Exception {
        metric.add("not_included", 1, null);
        String response = requestAsString("http://localhost/metrics-packets");

        List<JsonNode> packets = toJsonPackets(response);
        assertEquals(1, packets.size());

        JsonNode statusPacket = packets.get(0);
        assertEquals(statusPacket.toString(), APPLICATION_NAME, statusPacket.get(APPLICATION_KEY).asText());
        assertEquals(statusPacket.toString(), 0, statusPacket.get(STATUS_CODE_KEY).asInt());
        assertEquals(statusPacket.toString(), "up", statusPacket.get(STATUS_MSG_KEY).asText());
    }

    @Test
    public void metrics_are_included_after_snapshot() throws Exception {
        metric.add("counter", 1, null);
        List<JsonNode> packets = incrementTimeAndGetJsonPackets();
        assertEquals(2, packets.size());

        JsonNode counterPacket = packets.get(1);
        assertCountMetric(counterPacket, "counter.count", 1);
    }

    @Test
    public void metadata_is_included_in_each_metrics_packet() throws Exception {
        metric.add("counter", 1, null);
        List<JsonNode> packets = incrementTimeAndGetJsonPackets();
        JsonNode counterPacket = packets.get(1);

        assertTrue(counterPacket.has(TIMESTAMP_KEY));
        assertTrue(counterPacket.has(APPLICATION_KEY));
        assertEquals(APPLICATION_NAME, counterPacket.get(APPLICATION_KEY).asText());
    }

    @Test
    public void timestamp_resolution_is_in_seconds() throws Exception {
        metric.add("counter", 1, null);
        List<JsonNode> packets = incrementTimeAndGetJsonPackets();
        JsonNode counterPacket = packets.get(1);

        assertEquals(SNAPSHOT_INTERVAL/1000L, counterPacket.get(TIMESTAMP_KEY).asLong());
    }

    @Test
    public void expected_aggregators_are_output_for_gauge_metrics() throws Exception{
        Metric.Context context = metric.createContext(Collections.singletonMap("dim1", "value1"));
        metric.set("gauge", 0.2, null);

        List<JsonNode> packets = incrementTimeAndGetJsonPackets();
        JsonNode gaugeMetric = packets.get(1).get(METRICS_KEY);

        assertEquals(0.2, gaugeMetric.get("gauge.last").asDouble(), 0.1);
        assertEquals(0.2, gaugeMetric.get("gauge.average").asDouble(), 0.1);
        assertEquals(0.2, gaugeMetric.get("gauge.max").asDouble(), 0.1);
    }

    @Test
    public void dimensions_from_context_are_included() throws Exception {
        Metric.Context context = metric.createContext(Collections.singletonMap("dim1", "value1"));
        metric.add("counter", 1, context);

        List<JsonNode> packets = incrementTimeAndGetJsonPackets();
        JsonNode counterPacket = packets.get(1);

        assertTrue(counterPacket.has(DIMENSIONS_KEY));
        JsonNode dimensions = counterPacket.get(DIMENSIONS_KEY);
        assertEquals("value1", dimensions.get("dim1").asText());
    }

    @Test
    public void metrics_with_identical_dimensions_are_contained_in_the_same_packet() throws Exception {
        Metric.Context context = metric.createContext(Collections.singletonMap("dim1", "value1"));
        metric.add("counter1", 1, context);
        metric.add("counter2", 2, context);

        List<JsonNode> packets = incrementTimeAndGetJsonPackets();
        assertEquals(2, packets.size());
        JsonNode countersPacket = packets.get(1);

        assertEquals("value1", countersPacket.get(DIMENSIONS_KEY).get("dim1").asText());
        assertCountMetric(countersPacket, "counter1.count", 1);
        assertCountMetric(countersPacket, "counter2.count", 2);
    }

    @Test
    public void metrics_with_different_dimensions_get_separate_packets() throws Exception {
        Metric.Context context1 = metric.createContext(Collections.singletonMap("dim1", "value1"));
        Metric.Context context2 = metric.createContext(Collections.singletonMap("dim2", "value2"));
        metric.add("counter1", 1, context1);
        metric.add("counter2", 1, context2);

        List<JsonNode> packets = incrementTimeAndGetJsonPackets();
        assertEquals(3, packets.size());
    }
    
    private List<JsonNode> incrementTimeAndGetJsonPackets() throws Exception {
        advanceToNextSnapshot();
        String response = requestAsString("http://localhost/metrics-packets");

        return toJsonPackets(response);
    }

    private List<JsonNode> toJsonPackets(String response) throws Exception {
        List<JsonNode> jsonPackets = new ArrayList<>();
        String[] packets = response.split(PACKET_SEPARATOR);
        ObjectMapper mapper = new ObjectMapper();
        for (String packet : packets) {
            jsonPackets.add(mapper.readTree(mapper.getFactory().createParser(packet)));
        }
        return jsonPackets;
    }

    private void assertCountMetric(JsonNode metricsPacket, String metricName, long expected) {
        assertTrue(metricsPacket.has(METRICS_KEY));
        JsonNode counterMetrics = metricsPacket.get(METRICS_KEY);
        assertTrue(counterMetrics.has(metricName));
        assertEquals(expected, counterMetrics.get(metricName).asLong());
    }

}