blob: 6aec6eee469b879ad6f8a852e40216381241e38d [file] [log] [blame]
Ray Milkey26921af2014-06-30 16:27:40 -07001package net.onrc.onos.api.rest;
2
Ray Milkey26921af2014-06-30 16:27:40 -07003import com.codahale.metrics.Reservoir;
4import com.codahale.metrics.SlidingWindowReservoir;
5import com.codahale.metrics.Timer;
Ray Milkey26921af2014-06-30 16:27:40 -07006import net.onrc.onos.core.metrics.OnosMetrics;
7import org.json.JSONArray;
8import org.json.JSONException;
9import org.json.JSONObject;
10import org.junit.After;
11import org.junit.Before;
12import org.junit.Test;
13import org.junit.runner.RunWith;
Ray Milkey26921af2014-06-30 16:27:40 -070014import org.powermock.modules.junit4.PowerMockRunner;
15import org.restlet.resource.ClientResource;
16
Ray Milkey26921af2014-06-30 16:27:40 -070017import static org.hamcrest.MatcherAssert.assertThat;
18import static org.hamcrest.Matchers.both;
19import static org.hamcrest.Matchers.equalTo;
20import static org.hamcrest.Matchers.greaterThanOrEqualTo;
21import static org.hamcrest.Matchers.is;
22import static org.hamcrest.Matchers.lessThan;
23import static org.hamcrest.Matchers.notNullValue;
24
25/**
26 * Unit tests for REST APIs for Timer Metrics.
27 */
Ray Milkey26921af2014-06-30 16:27:40 -070028@RunWith(PowerMockRunner.class)
Ray Milkey26921af2014-06-30 16:27:40 -070029public class TestRestMetricsTimers extends TestRestMetrics {
30
31 /**
32 * Create the web server and mocks required for
33 * all of the tests.
34 */
35 @Before
36 @SuppressWarnings("ununsed")
37 public void beforeTest() {
38 setRestPort(generateRandomPort());
39 setUp();
40 }
41
42 // Test data objects for Timers
43
Ray Milkey71cd2c82014-07-16 15:02:33 -070044 private static final OnosMetrics.MetricsComponent COMPONENT =
45 OnosMetrics.registerComponent("MetricsUnitTests");
46 private static final OnosMetrics.MetricsFeature FEATURE =
47 COMPONENT.registerFeature("Timers");
48
Ray Milkey26921af2014-06-30 16:27:40 -070049 // timer1 will be called 3 times
Ray Milkey49d67be2014-07-10 13:47:01 -070050 private static final String TIMER1_NAME = "timer1";
51 private static final String TIMER1_FULL_NAME =
Ray Milkey71cd2c82014-07-16 15:02:33 -070052 OnosMetrics.generateName(COMPONENT,
53 FEATURE,
Ray Milkey49d67be2014-07-10 13:47:01 -070054 TIMER1_NAME);
Ray Milkey26921af2014-06-30 16:27:40 -070055 private static final int TIMER1_COUNT = 3;
56
Ray Milkey49d67be2014-07-10 13:47:01 -070057 // timer2 will be called 10 times
58 private static final String TIMER2_NAME = "timer2";
59 private static final String TIMER2_FULL_NAME =
Ray Milkey71cd2c82014-07-16 15:02:33 -070060 OnosMetrics.generateName(COMPONENT,
61 FEATURE,
62 TIMER2_NAME);
Ray Milkey26921af2014-06-30 16:27:40 -070063 private static final int TIMER2_COUNT = 10;
64
65 private static final int RESERVOIR_SIZE = 100;
66 private Reservoir reservoir = new SlidingWindowReservoir(RESERVOIR_SIZE);
67
Ray Milkey40eb9c82014-07-18 10:28:11 -070068 private final Timer timer1 = new Timer(reservoir, getMockClock());
69 private final Timer timer2 = new Timer(reservoir, getMockClock());
Ray Milkey26921af2014-06-30 16:27:40 -070070
71 /**
72 * Fill in test data in the Timer objects.
73 */
74 private void fillTimers() {
75 // The mock clock will simulate ticks at MOCK_CLOCK_MILISECONDS_PER_TICK
76 // Each timer.time(), context.stop() pair will elapse
77 // MOCK_CLOCK_MILISECONDS_PER_TICK (currently 50 milliseconds)
78
79 // Initialize timer1 - 3 ticks, 50 milliseconds (simulted) apart
80 for (int i = 0; i < TIMER1_COUNT; i++) {
81 final Timer.Context context = timer1.time();
82 context.stop();
83 }
84
85 // Initialize timer2 - 10 ticks, 50 milliseconds (simulated) apart
86 for (int i = 0; i < TIMER2_COUNT; i++) {
87 final Timer.Context context = timer2.time();
88 context.stop();
89 }
90
91 // add the two timers to the registry so the REST APIs will pick them
92 // up
Ray Milkey49d67be2014-07-10 13:47:01 -070093
Ray Milkey71cd2c82014-07-16 15:02:33 -070094 OnosMetrics.registerMetric(COMPONENT,
95 FEATURE,
Ray Milkey49d67be2014-07-10 13:47:01 -070096 TIMER1_NAME,
97 timer1);
98
Ray Milkey71cd2c82014-07-16 15:02:33 -070099 OnosMetrics.registerMetric(COMPONENT,
100 FEATURE,
Ray Milkey49d67be2014-07-10 13:47:01 -0700101 TIMER2_NAME,
102 timer2);
Ray Milkey26921af2014-06-30 16:27:40 -0700103 }
104
105 /**
106 * Check that the time values for a JSON Timer object are within the
107 * allowed range.
108 *
109 * @param timer JSON Timer object
110 * @param timeValue expected time value
111 * @throws JSONException if any of the JSON operations fail
112 */
113 private void assertThatTimesAreInRange(JSONObject timer, int timeValue)
114 throws JSONException {
115
116 final double timerMax = timer.getDouble("max");
117 assertThat((int) timerMax,
118 is(both(greaterThanOrEqualTo(timeValue)).
119 and(lessThan(timeValue + 5))));
120
121 final double timerMin = timer.getDouble("min");
122 assertThat((int) timerMin,
123 is(both(greaterThanOrEqualTo(timeValue)).
124 and(lessThan(timeValue + 5))));
125
126 final double timerP99 = timer.getDouble("p99");
127 assertThat((int) timerP99,
128 is(both(greaterThanOrEqualTo(timeValue)).
129 and(lessThan(timeValue + 5))));
130
131 final double timerP999 = timer.getDouble("p999");
132 assertThat((int) timerP999,
133 is(both(greaterThanOrEqualTo(timeValue)).
134 and(lessThan(timeValue + 5))));
135 }
136
137 /**
138 * Remove anything that will interfere with the next test running correctly.
139 * Shuts down the test REST web server and removes the mocks.
140 */
141 @After
142 @SuppressWarnings("unused")
143 public void afterTest() {
144 tearDown();
145 }
146
147 /**
148 * Unit test for the REST APIs for Metrics Timers.
149 *
150 * @throws JSONException if any of the JSON processing fails.
151 */
152 @Test
153 public void testTimers() throws JSONException {
154 // Make some test data
155 fillTimers();
156
157 // Read the metrics from the REST API for the test data
158 final ClientResource client = new ClientResource(getBaseRestMetricsUrl());
159
160 final JSONObject metrics = getJSONObject(client);
161 assertThat(metrics.length(), is(equalTo(5)));
162
163 // There should be 2 timers
164 final JSONArray timers = metrics.getJSONArray("timers");
165 assertThat(timers, is(notNullValue()));
166 assertThat(timers.length(), is(2));
167
168
169 // There should be no historgramss, gauges, meters or counters
170 checkEmptyLists(metrics, "histograms", "gauges", "meters", "counters");
171
172 // Check the values for timer 1
173 final JSONObject timer1Values = timers.getJSONObject(0);
174 assertThat(timer1Values, is(notNullValue()));
175
176 final String timer1Name = timer1Values.getString("name");
177 assertThat(timer1Name, is(notNullValue()));
Ray Milkey49d67be2014-07-10 13:47:01 -0700178 assertThat(timer1Name, is(equalTo(TIMER1_FULL_NAME)));
Ray Milkey26921af2014-06-30 16:27:40 -0700179
180 final JSONObject timer1TimerObject = timer1Values.getJSONObject("timer");
181 assertThat(timer1TimerObject, is(notNullValue()));
182
183 final int timer1Count = timer1TimerObject.getInt("count");
184 assertThat(timer1Count, is(equalTo(TIMER1_COUNT)));
185
186 final String timer1DurationUnits = timer1TimerObject.getString("duration_units");
187 assertThat(timer1DurationUnits, is(equalTo("milliseconds")));
188
189 assertThatTimesAreInRange(timer1TimerObject,
190 MOCK_CLOCK_MILISECONDS_PER_TICK);
191
192 // Check the values for timer 2
193 final JSONObject timer2Values = timers.getJSONObject(1);
194 assertThat(timer2Values, is(notNullValue()));
195
196 final String timer2Name = timer2Values.getString("name");
197 assertThat(timer2Name, is(notNullValue()));
Ray Milkey49d67be2014-07-10 13:47:01 -0700198 assertThat(timer2Name, is(equalTo(TIMER2_FULL_NAME)));
Ray Milkey26921af2014-06-30 16:27:40 -0700199
200 final JSONObject timer2TimerObject = timer2Values.getJSONObject("timer");
201 assertThat(timer2TimerObject, is(notNullValue()));
202
203 final int timer2Count = timer2TimerObject.getInt("count");
204 assertThat(timer2Count, is(equalTo(TIMER2_COUNT)));
205
206 final String timer2DurationUnits = timer2TimerObject.getString("duration_units");
207 assertThat(timer2DurationUnits, is(equalTo("milliseconds")));
208
209 assertThatTimesAreInRange(timer2TimerObject,
210 MOCK_CLOCK_MILISECONDS_PER_TICK);
211 }
212
213}