@Test
public void testFetchTimelineMetrics() throws Exception {

  EasyMockSupport easyMockSupport = new EasyMockSupport();
  final long now = System.currentTimeMillis();
  TimelineMetrics metrics = new TimelineMetrics();
  TimelineMetric timelineMetric = new TimelineMetric();
  timelineMetric.setMetricName("cpu_user");
  timelineMetric.setAppId("app1");
  TreeMap<Long, Double> metricValues = new TreeMap<Long, Double>();
  metricValues.put(now + 100, 1.0);
  metricValues.put(now + 200, 2.0);
  metricValues.put(now + 300, 3.0);
  timelineMetric.setMetricValues(metricValues);
  metrics.getMetrics().add(timelineMetric);
  ObjectMapper mapper = new ObjectMapper();
  AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();
  mapper.setAnnotationIntrospector(introspector);
  ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
  String metricsResponse = writer.writeValueAsString(metrics);
  InputStream inputStream = IOUtils.toInputStream(metricsResponse);
  HttpURLConnection httpURLConnectionMock = createMock(HttpURLConnection.class);
  expect(httpURLConnectionMock.getInputStream()).andReturn(inputStream).once();
  expect(httpURLConnectionMock.getResponseCode()).andReturn(HttpStatus.SC_OK).once();
  URLStreamProvider urlStreamProviderMock = createMock(URLStreamProvider.class);
  expect(urlStreamProviderMock.processURL(EasyMock.isA(String.class), EasyMock.isA(String.class),
    isNull(String.class), EasyMock.<Map<String, List<String>>>anyObject())).andReturn(httpURLConnectionMock).once();
  replay(httpURLConnectionMock, urlStreamProviderMock);
  //Case 1 : No error.
  String randomSpec = "http://localhost:6188/ws/v1/timeline/metrics?metricNames=cpu_wio&hostname=host1&appId=HOST" +
    "&startTime=1447912834&endTime=1447990034&precision=SECONDS";
  MetricsRequestHelper metricsRequestHelper = new MetricsRequestHelper(urlStreamProviderMock);
  metricsRequestHelper.fetchTimelineMetrics(new URIBuilder(randomSpec), now, now + 300);
  easyMockSupport.verifyAll();
  //Case 2 : Precision Error returned first time.
  String metricsPrecisionErrorResponse = "{\"exception\": \"PrecisionLimitExceededException\",\n" +
    "\"message\": \"Requested precision (SECONDS) for given time range causes result set size of 169840, " +
    "which exceeds the limit - 15840. Please request higher precision.\",\n" +
    "\"javaClassName\": \"org.apache.hadoop.metrics2.sink.timeline.PrecisionLimitExceededException\"\n" +
    "}";
  InputStream errorStream = IOUtils.toInputStream(metricsPrecisionErrorResponse);
  inputStream = IOUtils.toInputStream(metricsResponse); //Reloading stream.
  httpURLConnectionMock = createMock(HttpURLConnection.class);
  expect(httpURLConnectionMock.getErrorStream()).andReturn(errorStream).once();
  expect(httpURLConnectionMock.getInputStream()).andReturn(inputStream).once();
  expect(httpURLConnectionMock.getResponseCode())
    .andReturn(HttpStatus.SC_BAD_REQUEST).once()
    .andReturn(HttpStatus.SC_OK).once();
  urlStreamProviderMock = createMock(URLStreamProvider.class);
  expect(urlStreamProviderMock.processURL(EasyMock.isA(String.class), EasyMock.isA(String.class),
    isNull(String.class), EasyMock.<Map<String, List<String>>>anyObject())).andReturn(httpURLConnectionMock).times(2);
  replay(httpURLConnectionMock, urlStreamProviderMock);
  metricsRequestHelper = new MetricsRequestHelper(urlStreamProviderMock);
  metricsRequestHelper.fetchTimelineMetrics(new URIBuilder(randomSpec), now, now + 300);
  easyMockSupport.verifyAll();
}