blob: 108cd732d50e5cd388c8eb69ad323eb4f93c1c52 [file] [log] [blame]
Ray Milkey26921af2014-06-30 16:27:40 -07001package net.onrc.onos.api.rest;
2
3import com.codahale.metrics.Histogram;
4import net.onrc.onos.core.intent.runtime.PathCalcRuntimeModule;
5import net.onrc.onos.core.metrics.OnosMetrics;
6import org.json.JSONArray;
7import org.json.JSONException;
8import org.json.JSONObject;
9import org.junit.After;
10import org.junit.Before;
11import org.junit.Test;
12import org.junit.runner.RunWith;
13import org.powermock.core.classloader.annotations.PrepareForTest;
14import org.powermock.modules.junit4.PowerMockRunner;
15import org.restlet.resource.ClientResource;
16
17import java.util.Arrays;
18
19import static org.hamcrest.MatcherAssert.assertThat;
20import static org.hamcrest.Matchers.both;
21import static org.hamcrest.Matchers.equalTo;
22import static org.hamcrest.Matchers.greaterThanOrEqualTo;
23import static org.hamcrest.Matchers.is;
24import static org.hamcrest.Matchers.lessThanOrEqualTo;
25import static org.hamcrest.Matchers.notNullValue;
26
27/**
28 * Unit tests for REST APIs for Histogram Metrics.
29 */
30
31@RunWith(PowerMockRunner.class)
32@PrepareForTest(PathCalcRuntimeModule.class)
33public class TestRestMetricsHistograms extends TestRestMetrics {
34
35 /**
36 * Create the web server and mocks required for
37 * all of the tests.
38 */
39 @Before
40 @SuppressWarnings("ununsed")
41 public void beforeTest() {
42 setRestPort(generateRandomPort());
43 setUp();
44 }
45
46 /**
47 * Remove anything that will interfere with the next test running correctly.
48 * Shuts down the test REST web server and removes the mocks.
49 */
50 @After
51 @SuppressWarnings("unused")
52 public void afterTest() {
53 tearDown();
54 }
55
56 // Test data for Histograms
57
Ray Milkey71cd2c82014-07-16 15:02:33 -070058 private static final OnosMetrics.MetricsComponent COMPONENT =
59 OnosMetrics.registerComponent("MetricsUnitTests");
60 private static final OnosMetrics.MetricsFeature FEATURE =
61 COMPONENT.registerFeature("Histograms");
62
Ray Milkey26921af2014-06-30 16:27:40 -070063 private static final String HISTOGRAM1_NAME = "HISTOGRAM1";
Ray Milkey49d67be2014-07-10 13:47:01 -070064 private static final String HISTOGRAM1_FULL_NAME =
Ray Milkey71cd2c82014-07-16 15:02:33 -070065 OnosMetrics.generateName(COMPONENT, FEATURE, HISTOGRAM1_NAME);
66
Ray Milkey26921af2014-06-30 16:27:40 -070067 private static final int[] HISTOGRAM1_VALUES =
68 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
69
70 private static final String HISTOGRAM2_NAME = "HISTOGRAM2";
Ray Milkey49d67be2014-07-10 13:47:01 -070071 private static final String HISTOGRAM2_FULL_NAME =
Ray Milkey71cd2c82014-07-16 15:02:33 -070072 OnosMetrics.generateName(COMPONENT, FEATURE, HISTOGRAM2_NAME);
Ray Milkey26921af2014-06-30 16:27:40 -070073 private static final int[] HISTOGRAM2_VALUES =
74 {100, 100, 100, 100, 100, 100, 100};
75
76 private static final String HISTOGRAM3_NAME = "HISTOGRAM3";
Ray Milkey49d67be2014-07-10 13:47:01 -070077 private static final String HISTOGRAM3_FULL_NAME =
Ray Milkey71cd2c82014-07-16 15:02:33 -070078 OnosMetrics.generateName(COMPONENT, FEATURE, HISTOGRAM3_NAME);
Ray Milkey26921af2014-06-30 16:27:40 -070079 private static final int[] HISTOGRAM3_VALUES =
80 {555};
81
82 private final Histogram histogram1 =
Ray Milkey49d67be2014-07-10 13:47:01 -070083 OnosMetrics.createHistogram(
Ray Milkey71cd2c82014-07-16 15:02:33 -070084 COMPONENT,
85 FEATURE,
Ray Milkey49d67be2014-07-10 13:47:01 -070086 HISTOGRAM1_NAME);
87
Ray Milkey26921af2014-06-30 16:27:40 -070088 private final Histogram histogram2 =
Ray Milkey49d67be2014-07-10 13:47:01 -070089 OnosMetrics.createHistogram(
Ray Milkey71cd2c82014-07-16 15:02:33 -070090 COMPONENT,
91 FEATURE,
Ray Milkey49d67be2014-07-10 13:47:01 -070092 HISTOGRAM2_NAME);
93
Ray Milkey26921af2014-06-30 16:27:40 -070094 private final Histogram histogram3 =
Ray Milkey49d67be2014-07-10 13:47:01 -070095 OnosMetrics.createHistogram(
Ray Milkey71cd2c82014-07-16 15:02:33 -070096 COMPONENT,
97 FEATURE,
Ray Milkey49d67be2014-07-10 13:47:01 -070098 HISTOGRAM3_NAME);
Ray Milkey26921af2014-06-30 16:27:40 -070099
100 /**
101 * Add each int in an array to a Histogram.
102 *
103 * @param histogram Histogram object to update
104 * @param values list of values to add to the Histogram
105 */
106 private void updateHistogramFromArray(final Histogram histogram,
107 final int[] values) {
108 for (final int value : values) {
109 histogram.update(value);
110 }
111 }
112
113 /**
114 * Initialize all the Histograms.
115 */
116 private void fillHistograms() {
117 updateHistogramFromArray(histogram1, HISTOGRAM1_VALUES);
118 updateHistogramFromArray(histogram2, HISTOGRAM2_VALUES);
119 updateHistogramFromArray(histogram3, HISTOGRAM3_VALUES);
120 }
121
122 /**
123 * Check that a JSON object representing a histogram contains the correct
124 * data.
125 *
126 * @param histogramContainer JSON object for the Histogram
127 * @param name the name of the Histogram
128 * @param values the array of expected values in the histogram
129 * @throws JSONException if any of the JSON processing generates an error
130 */
131 private void checkHistogram(final JSONObject histogramContainer,
132 final String name,
133 final int[] values) throws JSONException {
134
135 // Check that the name is correct
136 final String histogramName = histogramContainer.getString("name");
137 assertThat(histogramName, is(notNullValue()));
138 assertThat(histogramName, is(equalTo(name)));
139
140 // Make sure a histogram is present
141 final JSONObject histogramObject = histogramContainer.getJSONObject("histogram");
142 assertThat(histogramObject, is(notNullValue()));
143
144 // The histogram count should equal the length of the array used to
145 // initialize it.
146 final int histogramCount = histogramObject.getInt("count");
147 assertThat(histogramCount, is(equalTo(values.length)));
148
149 final int[] sortedValues = Arrays.copyOf(values, values.length);
150 Arrays.sort(sortedValues);
151
152 // max should be the largest value from the array
153 final int max = histogramObject.getInt("max");
154 assertThat(max, is(equalTo(sortedValues[sortedValues.length - 1])));
155
156 // min should be the smallest value from the array
157 final int min = histogramObject.getInt("min");
158 assertThat(min, is(equalTo(sortedValues[0])));
159
160 // Each of the probability values should be between the min and the max
161 // value
162 final double p999 = histogramObject.getDouble("p999");
163 assertThat((int) p999,
164 is(both(greaterThanOrEqualTo(min)).and(lessThanOrEqualTo(max))));
165
166 final double p99 = histogramObject.getDouble("p99");
167 assertThat((int) p99,
168 is(both(greaterThanOrEqualTo(min)).and(lessThanOrEqualTo(max))));
169
170 final double p98 = histogramObject.getDouble("p98");
171 assertThat((int) p98,
172 is(both(greaterThanOrEqualTo(min)).and(lessThanOrEqualTo(max))));
173
174 final double p95 = histogramObject.getDouble("p95");
175 assertThat((int) p95,
176 is(both(greaterThanOrEqualTo(min)).and(lessThanOrEqualTo(max))));
177
178 final double p75 = histogramObject.getDouble("p75");
179 assertThat((int) p75,
180 is(both(greaterThanOrEqualTo(min)).and(lessThanOrEqualTo(max))));
181
182 final double p50 = histogramObject.getDouble("p50");
183 assertThat((int) p50,
184 is(both(greaterThanOrEqualTo(min)).and(lessThanOrEqualTo(max))));
185
186 }
187
188 /**
189 * Unit test for REST APIs for Histogram Metrics.
190 *
191 * @throws JSONException if any JSON processing causes an error
192 */
193 @Test
194 public void testHistograms() throws JSONException {
195
196 fillHistograms();
197
198 // Read the metrics from the REST API for the test data
199 final ClientResource client = new ClientResource(getBaseRestMetricsUrl());
200
201 final JSONObject metrics = getJSONObject(client);
202 assertThat(metrics.length(), is(equalTo(5)));
203
204 // There should be 3 histograms
205 final JSONArray histograms = metrics.getJSONArray("histograms");
206 assertThat(histograms, is(notNullValue()));
207 assertThat(histograms.length(), is(3));
208
209 // There should be no timers, gauges, meters or counters
210 checkEmptyLists(metrics, "timers", "gauges", "meters", "counters");
211
212 // Check the values for histogram 1
213 final JSONObject histogram1Container = histograms.getJSONObject(0);
Ray Milkey49d67be2014-07-10 13:47:01 -0700214 checkHistogram(histogram1Container, HISTOGRAM1_FULL_NAME, HISTOGRAM1_VALUES);
Ray Milkey26921af2014-06-30 16:27:40 -0700215
216 // Check the values for histogram 2
217 final JSONObject histogram2Container = histograms.getJSONObject(1);
Ray Milkey49d67be2014-07-10 13:47:01 -0700218 checkHistogram(histogram2Container, HISTOGRAM2_FULL_NAME, HISTOGRAM2_VALUES);
Ray Milkey26921af2014-06-30 16:27:40 -0700219
220 // Check the values for histogram 3
221 final JSONObject histogram3Container = histograms.getJSONObject(2);
Ray Milkey49d67be2014-07-10 13:47:01 -0700222 checkHistogram(histogram3Container, HISTOGRAM3_FULL_NAME, HISTOGRAM3_VALUES);
Ray Milkey26921af2014-06-30 16:27:40 -0700223
224 }
225
226}
227