@Test
public void testTimelineMetricCachePrecisionUpdates() throws Exception {

  Configuration configuration = createNiceMock(Configuration.class);
  expect(configuration.getMetricCacheTTLSeconds()).andReturn(3600);
  expect(configuration.getMetricCacheIdleSeconds()).andReturn(100);
  expect(configuration.getMetricsCacheManagerHeapPercent()).andReturn("10%").anyTimes();
  expect(configuration.getMetricRequestBufferTimeCatchupInterval()).andReturn(1000l).anyTimes();
  replay(configuration);
  final long now = System.currentTimeMillis();
  long second = 1000;
  long min = 60 * second;
  long hour = 60 * min;
  long day = 24 * hour;
  long year = 365 * day;
  //Original Values
  Map<String, TimelineMetric> valueMap = new HashMap<String, TimelineMetric>();
  TimelineMetric timelineMetric = new TimelineMetric();
  timelineMetric.setMetricName("cpu_user");
  timelineMetric.setAppId("app1");
  TreeMap<Long, Double> metricValues = new TreeMap<Long, Double>();
  for (long i = 1 * year - 1 * day; i >= 0; i -= 1 * day) {
    metricValues.put(now-i, 1.0);
  }
  timelineMetric.setMetricValues(metricValues);
  valueMap.put("cpu_user", timelineMetric);
  List<TimelineMetric> timelineMetricList = new ArrayList<>();
  timelineMetricList.add(timelineMetric);
  TimelineMetrics metrics = new TimelineMetrics();
  metrics.setMetrics(timelineMetricList);
  TimelineAppMetricCacheKey key = new TimelineAppMetricCacheKey(
      Collections.singleton("cpu_user"),
      "app1",
      new TemporalInfoImpl(now-1*year, now, 1)
  );
  key.setSpec("");
  //Updated values
  Map<String, TimelineMetric> newValueMap = new HashMap<String, TimelineMetric>();
  TimelineMetric newTimelineMetric = new TimelineMetric();
  newTimelineMetric.setMetricName("cpu_user");
  newTimelineMetric.setAppId("app1");
  TreeMap<Long, Double> newMetricValues = new TreeMap<Long, Double>();
  for(long i=1*hour;i<=2*day;i+=hour) {
    newMetricValues.put(now-1*day+i, 2.0);
  }
  newTimelineMetric.setMetricValues(newMetricValues);
  newValueMap.put("cpu_user", newTimelineMetric);
  List<TimelineMetric> newTimelineMetricList = new ArrayList<>();
  newTimelineMetricList.add(newTimelineMetric);
  TimelineMetrics newMetrics = new TimelineMetrics();
  newMetrics.setMetrics(newTimelineMetricList);
  TimelineAppMetricCacheKey newKey = new TimelineAppMetricCacheKey(
      Collections.singleton("cpu_user"),
      "app1",
      new TemporalInfoImpl(now - 1 * day, now + 2 * day, 1)
  );
  newKey.setSpec("");
  MetricsRequestHelper metricsRequestHelperForGets = createMock(MetricsRequestHelper.class);
  expect(metricsRequestHelperForGets.fetchTimelineMetrics(EasyMock.isA(URIBuilder.class), anyLong(), anyLong()))
    .andReturn(metrics).andReturn(newMetrics);
  replay(metricsRequestHelperForGets);
  TimelineMetricCacheEntryFactory cacheEntryFactory =
    createMockBuilder(TimelineMetricCacheEntryFactory.class)
      .withConstructor(configuration).createMock();
  Field requestHelperField = TimelineMetricCacheEntryFactory.class.getDeclaredField("requestHelperForGets");
  requestHelperField.setAccessible(true);
  requestHelperField.set(cacheEntryFactory, metricsRequestHelperForGets);
  requestHelperField = TimelineMetricCacheEntryFactory.class.getDeclaredField("requestHelperForUpdates");
  requestHelperField.setAccessible(true);
  requestHelperField.set(cacheEntryFactory, metricsRequestHelperForGets);
  replay(cacheEntryFactory);
  TimelineMetricCacheProvider cacheProvider = createMockBuilder(TimelineMetricCacheProvider.class)
    .addMockedMethod("createCacheConfiguration")
    .withConstructor(configuration, cacheEntryFactory)
    .createNiceMock();
  expect(cacheProvider.createCacheConfiguration()).andReturn(createTestCacheConfiguration(configuration)).anyTimes();
  replay(cacheProvider);
  TimelineMetricCache cache = cacheProvider.getTimelineMetricsCache();
  // call to get
  metrics = cache.getAppTimelineMetricsFromCache(key);
  List<TimelineMetric> metricsList = metrics.getMetrics();
  Assert.assertEquals(1, metricsList.size());
  TimelineMetric metric = metricsList.iterator().next();
  Assert.assertEquals("cpu_user", metric.getMetricName());
  Assert.assertEquals("app1", metric.getAppId());
  Assert.assertEquals(metricValues, metric.getMetricValues());
  // call to update with new key
  metrics = cache.getAppTimelineMetricsFromCache(newKey);
  metricsList = metrics.getMetrics();
  Assert.assertEquals(1, metricsList.size());
  Assert.assertEquals("cpu_user", metric.getMetricName());
  Assert.assertEquals("app1", metric.getAppId());
  Assert.assertEquals(newMetricValues, metric.getMetricValues());
  verify(configuration, metricsRequestHelperForGets, cacheEntryFactory);
}