diff --git a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/service/instrumentation/InstrumentationService.java b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/service/instrumentation/InstrumentationService.java index ee4455c9998df..0cd07db4be03b 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/service/instrumentation/InstrumentationService.java +++ b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/service/instrumentation/InstrumentationService.java @@ -226,6 +226,9 @@ long[] getValues() { lock.lock(); try { long[] values = new long[4]; + if (last < 0) { + return values; + } values[LAST_TOTAL] = total[last]; values[LAST_OWN] = own[last]; int limit = (full) ? size : (last + 1); diff --git a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/service/instrumentation/TestInstrumentationService.java b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/service/instrumentation/TestInstrumentationService.java index 86d42ccdf2d79..6a7e1e731fe0e 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/service/instrumentation/TestInstrumentationService.java +++ b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/service/instrumentation/TestInstrumentationService.java @@ -232,6 +232,24 @@ public void timer() throws Exception { assertEquals(json.get("avgOwn"), values[InstrumentationService.Timer.AVG_OWN]); } + @Test + public void timerGetValuesBeforeAnyCron() throws Exception { + // HDFS-16029: getValues() on a fresh Timer (last == -1) must not throw + // ArrayIndexOutOfBoundsException or divide-by-zero; it should return zeros. + InstrumentationService.Timer timer = new InstrumentationService.Timer(2); + long[] values = timer.getValues(); + assertEquals(4, values.length); + assertEquals(0, values[InstrumentationService.Timer.LAST_TOTAL]); + assertEquals(0, values[InstrumentationService.Timer.LAST_OWN]); + assertEquals(0, values[InstrumentationService.Timer.AVG_TOTAL]); + assertEquals(0, values[InstrumentationService.Timer.AVG_OWN]); + + // toJSONString() also calls getValues() via getJSON() — must not throw either + String json = timer.toJSONString(); + assertNotNull(json); + assertTrue(json.contains("lastTotal")); + } + @Test public void sampler() throws Exception { final long value[] = new long[1];