You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by ct...@apache.org on 2020/12/17 04:24:46 UTC
[accumulo] branch 1.10 updated: Fix #1792 flaky/broken GcMetricsIT
This is an automated email from the ASF dual-hosted git repository.
ctubbsii pushed a commit to branch 1.10
in repository https://gitbox.apache.org/repos/asf/accumulo.git
The following commit(s) were added to refs/heads/1.10 by this push:
new 0773baa Fix #1792 flaky/broken GcMetricsIT
0773baa is described below
commit 0773baac791ab2055d949bd62948d2ba39cca1a3
Author: Christopher Tubbs <ct...@apache.org>
AuthorDate: Wed Dec 16 22:29:17 2020 -0500
Fix #1792 flaky/broken GcMetricsIT
Rewrite portions of GcMetricsIT to improve its reliability and to add
comments and rename methods to make it more clear how it is intended to
work, so it's easier to debug in future.
Also use daemon threads for the tailer, and ensure it is started
consistently (using a dedicated method) and closed properly when done.
Remove unnecessary catching of exceptions, and allow them to be thrown
from the tests instead, because they will be handled by the test
framework.
---
.../accumulo/test/functional/GcMetricsIT.java | 313 ++++++++-------------
.../accumulo/test/functional/MasterMetricsIT.java | 14 +-
.../accumulo/test/metrics/MetricsFileTailer.java | 25 +-
.../resources/hadoop-metrics2-accumulo.properties | 36 +--
.../test/metrics/MetricsFileTailerTest.java | 75 +++--
5 files changed, 185 insertions(+), 278 deletions(-)
diff --git a/test/src/main/java/org/apache/accumulo/test/functional/GcMetricsIT.java b/test/src/main/java/org/apache/accumulo/test/functional/GcMetricsIT.java
index 51a4136..120ac35 100644
--- a/test/src/main/java/org/apache/accumulo/test/functional/GcMetricsIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/functional/GcMetricsIT.java
@@ -1,22 +1,27 @@
/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
*/
package org.apache.accumulo.test.functional;
+import static java.util.stream.Collectors.toMap;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
import java.util.Collections;
import java.util.Map;
@@ -25,13 +30,15 @@ import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Stream;
import org.apache.accumulo.core.conf.Property;
import org.apache.accumulo.gc.metrics.GcMetrics;
-import org.apache.accumulo.harness.AccumuloClusterHarness;
import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
import org.apache.accumulo.test.metrics.MetricsFileTailer;
import org.apache.hadoop.conf.Configuration;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,22 +47,22 @@ import org.slf4j.LoggerFactory;
* Functional test that uses a hadoop metrics 2 file sink to read published metrics for
* verification.
*/
-public class GcMetricsIT extends AccumuloClusterHarness {
+public class GcMetricsIT extends ConfigurableMacBase {
private static final Logger log = LoggerFactory.getLogger(GcMetricsIT.class);
-
private static final int NUM_TAIL_ATTEMPTS = 20;
private static final long TAIL_DELAY = 5_000;
-
+ private static final Pattern metricLinePattern = Pattern.compile("^(?<timestamp>\\d+).*");
private static final String[] EXPECTED_METRIC_KEYS = new String[] {"AccGcCandidates",
"AccGcDeleted", "AccGcErrors", "AccGcFinished", "AccGcInUse", "AccGcPostOpDuration",
"AccGcRunCycleCount", "AccGcStarted", "AccGcWalCandidates", "AccGcWalDeleted",
"AccGcWalErrors", "AccGcWalFinished", "AccGcWalInUse", "AccGcWalStarted"};
@Override
- public void configureMiniCluster(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
- cfg.setProperty(Property.GENERAL_LEGACY_METRICS, "false");
+ protected void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
cfg.setProperty(Property.GC_METRICS_ENABLED, "true");
+ cfg.setProperty(Property.GC_CYCLE_START, "5s");
+ cfg.setProperty(Property.GC_CYCLE_DELAY, "15s");
}
@Override
@@ -63,229 +70,131 @@ public class GcMetricsIT extends AccumuloClusterHarness {
return 4 * 60;
}
- @Test
- public void gcMetricsPublished() {
-
- boolean gcMetricsEnabled =
- cluster.getSiteConfiguration().getBoolean(Property.GC_METRICS_ENABLED);
- boolean useLegacyMetrics =
- cluster.getSiteConfiguration().getBoolean(Property.GENERAL_LEGACY_METRICS);
-
- if (!gcMetricsEnabled || useLegacyMetrics) {
- log.info("gc metrics are disabled with GC_METRICS_ENABLED={}, GENERAL_LEGACY_METRICS={}",
- gcMetricsEnabled, useLegacyMetrics);
- return;
- }
-
- // log.trace("Client started, properties:{}", accumuloClient.properties());
-
- MetricsFileTailer gcTail = new MetricsFileTailer("accumulo.sink.file-gc");
- Thread t1 = new Thread(gcTail);
- t1.start();
-
- // uncomment for manual jmx / jconsole validation - not for automated testing
- // manualValidationPause();
-
- try {
-
- long updateTimestamp = System.currentTimeMillis();
-
- // Get next update after current time
- LineUpdate firstUpdate = waitForUpdate(updateTimestamp, gcTail);
-
- Map<String,Long> firstSeenMap = parseLine(firstUpdate.getLine());
-
- log.trace("L:{}", firstUpdate.getLine());
- log.trace("M:{}", firstSeenMap);
+ private final MetricsFileTailer gcTail = new MetricsFileTailer("accumulo.sink.file-gc");
- assertTrue(lookForExpectedKeys(firstSeenMap));
- sanity(updateTimestamp, firstSeenMap);
-
- // Get next update after the first one
- updateTimestamp = firstUpdate.getLastUpdate();
- LineUpdate nextUpdate = waitForUpdate(updateTimestamp, gcTail);
-
- Map<String,Long> updateSeenMap = parseLine(nextUpdate.getLine());
-
- log.debug("Line received:{}", nextUpdate.getLine());
- log.trace("Mapped values:{}", updateSeenMap);
-
- assertTrue(lookForExpectedKeys(updateSeenMap));
- sanity(updateTimestamp, updateSeenMap);
-
- validate(firstSeenMap, updateSeenMap);
-
- } catch (Exception ex) {
- throw new IllegalStateException("gc metrics file read failed", ex);
- }
+ @Before
+ public void startTailer() {
+ gcTail.startDaemonThread();
}
- /**
- * This method just sleeps for a while (test will likely time out) The pause is to allow manual
- * validation of metrics by connecting to the running gc process with jconsole (or other jmx
- * utility). It should not be used for automatic testing.
- */
- @SuppressWarnings("unused")
- private void manualValidationPause() {
- try {
- Thread.sleep(320_000);
- } catch (InterruptedException ex) {
- Thread.currentThread().interrupt();
- }
+ @After
+ public void stopTailer() {
+ gcTail.close();
}
- /**
- * Validate metrics for consistency withing a run cycle.
- *
- * @param values
- * map of values from one run cycle.
- */
- private void sanity(final long testStart, final Map<String,Long> values) {
-
- long start = values.get("AccGcStarted");
- long finished = values.get("AccGcFinished");
-
- log.debug("test start: {}, gc start: {}, gc finished: {}", testStart, start, finished);
-
- assertTrue(start >= testStart);
- assertTrue(finished >= start);
-
- start = values.get("AccGcWalStarted");
- finished = values.get("AccGcWalFinished");
-
- log.debug("test start: {}, walgc start: {}, walgc finished: {}", testStart, start, finished);
-
- assertTrue(start >= testStart);
- assertTrue(finished >= start);
-
- }
-
- /**
- * A series of sanity checks for the metrics between different update cycles, some values should
- * be at least different, and some of the checks can include ordering.
- *
- * @param firstSeen
- * map of first metric update
- * @param update
- * map of a later metric update.
- */
- private void validate(Map<String,Long> firstSeen, Map<String,Long> update) {
-
- log.debug("First: {}, Update: {}", firstSeen, update);
-
- assertTrue("update should start after first",
- update.get("AccGcStarted") > firstSeen.get("AccGcStarted"));
- assertTrue("update should finish after first ",
- update.get("AccGcFinished") > firstSeen.get("AccGcFinished"));
- assertTrue("wal collect should start after gc cycle",
- firstSeen.get("AccGcWalStarted") >= firstSeen.get("AccGcFinished"));
- assertTrue("wal collect should start after gc cycle",
- update.get("AccGcWalStarted") >= update.get("AccGcFinished"));
- assertTrue("cycle count should increment",
- update.get("AccGcRunCycleCount") > firstSeen.get("AccGcRunCycleCount"));
- }
+ @Test
+ public void gcMetricsPublished() throws Exception {
+ assumeTrue("gc metrics are disabled with GC_METRICS_ENABLED=false",
+ cluster.getSiteConfiguration().getBoolean(Property.GC_METRICS_ENABLED));
+ assumeFalse("gc metrics are disabled because GENERAL_LEGACY_METRICS=true",
+ cluster.getSiteConfiguration().getBoolean(Property.GENERAL_LEGACY_METRICS));
- /**
- * The hadoop metrics file sink published records as a line with comma separated key=value pairs.
- * This method parses the line and extracts the key, value pair from metrics that start with AccGc
- * and returns them in a sort map.
- *
- * @param line
- * a line from the metrics system file sink.
- * @return a map of the metrics that start with AccGc
- */
- private Map<String,Long> parseLine(final String line) {
+ // uncomment for manual jmx / jconsole validation - not for automated testing
+ // Thread.sleep(320_000);
- if (line == null) {
- return Collections.emptyMap();
- }
+ long testStart = System.currentTimeMillis();
+ log.debug("Test started: {}", testStart);
- Map<String,Long> m = new TreeMap<>();
+ LineUpdate firstGc = captureMetricsAfterTimestamp(testStart);
+ log.debug("First captured metrics finished at {}", firstGc.gcWalFinished);
- String[] csvTokens = line.split(",");
+ LineUpdate secondGc = captureMetricsAfterTimestamp(firstGc.gcWalFinished);
+ log.debug("Second captured metrics finished at {}", secondGc.gcWalFinished);
- for (String token : csvTokens) {
- token = token.trim();
- if (token.startsWith(GcMetrics.GC_METRIC_PREFIX)) {
- String[] parts = token.split("=");
- m.put(parts[0], Long.parseLong(parts[1]));
- }
- }
- return m;
+ firstGc.compareWithSubsequentRun(secondGc);
}
private static class LineUpdate {
- private final long lastUpdate;
- private final String line;
-
- LineUpdate(long lastUpdate, String line) {
- this.lastUpdate = lastUpdate;
- this.line = line;
+ private final long gcStarted;
+ private final long gcFinished;
+ private final long gcWalStarted;
+ private final long gcWalFinished;
+ private final long gcRunCycleCount;
+ private final Map<String,Long> values;
+
+ LineUpdate(String line) {
+ values = parseLine(line);
+ gcStarted = values.get("AccGcStarted");
+ gcFinished = values.get("AccGcFinished");
+ gcWalStarted = values.get("AccGcWalStarted");
+ gcWalFinished = values.get("AccGcWalFinished");
+ gcRunCycleCount = values.get("AccGcRunCycleCount");
+
+ // ensure internal consistency
+ assertTrue(Stream.of(EXPECTED_METRIC_KEYS).allMatch(values::containsKey));
+ assertTrue(gcStarted <= gcFinished);
+ assertTrue(gcWalStarted <= gcWalFinished);
}
- long getLastUpdate() {
- return lastUpdate;
+ void compareWithSubsequentRun(LineUpdate update) {
+ log.debug("First run: {}, Second run: {}", values, update.values);
+ assertTrue("first gc should finish before second starts", gcFinished < update.gcStarted);
+ assertTrue("first gcWal should finish before second starts",
+ gcWalFinished < update.gcWalStarted);
+ assertTrue("cycle count should increment", gcRunCycleCount < update.gcRunCycleCount);
}
- String getLine() {
- return line;
+ /**
+ * The hadoop metrics file sink published records as a line with comma separated key=value
+ * pairs. This method parses the line and extracts the key, value pair from metrics that start
+ * with AccGc and returns them in a sorted map.
+ *
+ * @return a map of the metrics that start with AccGc
+ */
+ private static Map<String,Long> parseLine(String line) {
+ log.debug("Line received:{}", line);
+ Map<String,Long> values = Collections.emptyMap();
+ if (line != null) {
+ values = Stream.of(line.split(",")).map(String::trim)
+ .filter(s -> s.startsWith(GcMetrics.GC_METRIC_PREFIX)).map(s -> s.split("="))
+ .collect(toMap(a -> a[0], a -> Long.parseLong(a[1]), (a, b) -> {
+ throw new IllegalArgumentException("Metric field found with two values '" + a
+ + "' and '" + b + "' in GC Metrics line: " + line);
+ }, TreeMap::new));
+ }
+ log.debug("Mapped values:{}", values);
+ return values;
}
}
- private LineUpdate waitForUpdate(final long prevUpdate, final MetricsFileTailer tail) {
-
+ private LineUpdate captureMetricsAfterTimestamp(final long timestamp) throws Exception {
for (int count = 0; count < NUM_TAIL_ATTEMPTS; count++) {
-
- String line = tail.getLast();
- long currUpdate = tail.getLastUpdate();
-
- if (line != null && (currUpdate != prevUpdate) && isValidTimestamp(line, prevUpdate)) {
- return new LineUpdate(tail.getLastUpdate(), line);
- }
-
- try {
- Thread.sleep(TAIL_DELAY);
- } catch (InterruptedException ex) {
- Thread.currentThread().interrupt();
- throw new IllegalStateException(ex);
+ String line = gcTail.getLast();
+ // check for valid metrics line update since the previous update
+ if (line != null && isValidRecentMetricsLine(line, timestamp)) {
+ LineUpdate lineUpdate = new LineUpdate(line);
+ // capture metrics for a regular gc event and a wal gc event that both occurred
+ // after the specified timestamp, and not just the same entry in the metrics file
+ // from a subsequent poll that represents the previous gc events;
+ // note that regular gc events can be updated in the metrics before the subsequent
+ // wal gc event that follows it, so the wal gc timestamps may be earlier than the
+ // regular gc timestamps; that's okay, as long as they both occur after the provided
+ // timestamp, and are internally consistent (start times < finish times)
+ if (timestamp < lineUpdate.gcStarted && timestamp < lineUpdate.gcWalStarted) {
+ return lineUpdate;
+ }
}
+ Thread.sleep(TAIL_DELAY);
}
- // not found - throw exception.
throw new IllegalStateException(
String.format("File source update not received after %d tries in %d sec", NUM_TAIL_ATTEMPTS,
TimeUnit.MILLISECONDS.toSeconds(TAIL_DELAY * NUM_TAIL_ATTEMPTS)));
}
- private static final Pattern timestampPattern = Pattern.compile("^\\s*(?<timestamp>\\d+).*");
-
- private boolean isValidTimestamp(final String line, final long prevTimestamp) {
-
+ private boolean isValidRecentMetricsLine(final String line, final long prevTimestamp) {
if (Objects.isNull(line)) {
return false;
}
-
- Matcher m = timestampPattern.matcher(line);
-
+ Matcher m = metricLinePattern.matcher(line);
if (m.matches()) {
try {
long timestamp = Long.parseLong(m.group("timestamp"));
return timestamp > prevTimestamp;
} catch (NumberFormatException ex) {
- log.trace("Could not parse timestamp from line '{}", line);
+ log.debug("Could not parse timestamp from line '{}", line);
return false;
}
}
return false;
}
-
- private boolean lookForExpectedKeys(final Map<String,Long> received) {
-
- for (String e : EXPECTED_METRIC_KEYS) {
- if (!received.containsKey(e)) {
- return false;
- }
- }
-
- return true;
- }
}
diff --git a/test/src/main/java/org/apache/accumulo/test/functional/MasterMetricsIT.java b/test/src/main/java/org/apache/accumulo/test/functional/MasterMetricsIT.java
index 367d0e0..c6b9a19 100644
--- a/test/src/main/java/org/apache/accumulo/test/functional/MasterMetricsIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/functional/MasterMetricsIT.java
@@ -69,7 +69,7 @@ public class MasterMetricsIT extends AccumuloClusterHarness {
private static final Set<String> OPTIONAL_METRIC_KEYS =
new HashSet<>(Collections.singletonList("FateTxOpType_CompactRange"));
- private MetricsFileTailer metricsTail = null;
+ private final MetricsFileTailer metricsTail = new MetricsFileTailer("accumulo.sink.file-master");
@Override
public void configureMiniCluster(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
@@ -80,24 +80,16 @@ public class MasterMetricsIT extends AccumuloClusterHarness {
@Before
public void setup() {
-
if (testDisabled()) {
return;
}
-
maxWait = defaultTimeoutSeconds() <= 0 ? 60_000 : ((defaultTimeoutSeconds() * 1000) / 2);
-
- metricsTail = new MetricsFileTailer("accumulo.sink.file-master");
- Thread t1 = new Thread(metricsTail);
- t1.start();
-
+ metricsTail.startDaemonThread();
}
@After
public void cleanup() {
- if (metricsTail != null) {
- metricsTail.close();
- }
+ metricsTail.close();
}
@Override
diff --git a/test/src/main/java/org/apache/accumulo/test/metrics/MetricsFileTailer.java b/test/src/main/java/org/apache/accumulo/test/metrics/MetricsFileTailer.java
index 1929f19..5b4dfc5 100644
--- a/test/src/main/java/org/apache/accumulo/test/metrics/MetricsFileTailer.java
+++ b/test/src/main/java/org/apache/accumulo/test/metrics/MetricsFileTailer.java
@@ -45,7 +45,7 @@ import org.slf4j.LoggerFactory;
* underlying file has data written, the value returned by getLastUpdate will change, and the last
* line can be retrieved with getLast().
*/
-public class MetricsFileTailer implements Runnable, AutoCloseable {
+public class MetricsFileTailer implements AutoCloseable {
private static final Logger log = LoggerFactory.getLogger(MetricsFileTailer.class);
@@ -54,7 +54,7 @@ public class MetricsFileTailer implements Runnable, AutoCloseable {
private final String metricsPrefix;
private final Lock lock = new ReentrantLock();
- private final AtomicBoolean running = new AtomicBoolean(Boolean.TRUE);
+ private final AtomicBoolean running = new AtomicBoolean(Boolean.FALSE);
private final AtomicLong lastUpdate = new AtomicLong(0);
private final long startTime = System.nanoTime();
@@ -153,10 +153,14 @@ public class MetricsFileTailer implements Runnable, AutoCloseable {
}
/**
- * Creates a marker value that changes each time a new line is detected. Clients can use this to
- * determine if a call to getLast() will return a new value.
+ * Creates a marker value that increases each time a new line is detected. Clients can use this to
+ * determine if a call to getLast() will return a new value. However, this value is <b>NOT</b> a
+ * timestamp and should not be interpreted as such. Furthermore, it does not indicate that the
+ * metrics being reported have changed, only that a new metrics poll took place and was written to
+ * the file. So, if clients need to observe new metrics from a new event, they need to parse the
+ * line themselves to look for changed metrics values.
*
- * @return a marker value set when a line is available.
+ * @return a marker value set when a new line is available.
*/
public long getLastUpdate() {
return lastUpdate.get();
@@ -228,8 +232,7 @@ public class MetricsFileTailer implements Runnable, AutoCloseable {
* A loop that polls for changes and when the file changes, put the last line in a buffer that can
* be retrieved by clients using getLast().
*/
- @Override
- public void run() {
+ private void run() {
long filePos = 0;
@@ -288,6 +291,14 @@ public class MetricsFileTailer implements Runnable, AutoCloseable {
}
}
+ public void startDaemonThread() {
+ if (running.compareAndSet(false, true)) {
+ Thread t = new Thread(() -> this.run());
+ t.setDaemon(true);
+ t.start();
+ }
+ }
+
@Override
public void close() {
running.set(Boolean.FALSE);
diff --git a/test/src/main/resources/hadoop-metrics2-accumulo.properties b/test/src/main/resources/hadoop-metrics2-accumulo.properties
index e869144..a7a99ac 100644
--- a/test/src/main/resources/hadoop-metrics2-accumulo.properties
+++ b/test/src/main/resources/hadoop-metrics2-accumulo.properties
@@ -1,19 +1,23 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Poll collectors every thirty seconds
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# Poll collectors period in seconds
*.period=5
#
diff --git a/test/src/test/java/org/apache/accumulo/test/metrics/MetricsFileTailerTest.java b/test/src/test/java/org/apache/accumulo/test/metrics/MetricsFileTailerTest.java
index 59359a2..c2658e9 100644
--- a/test/src/test/java/org/apache/accumulo/test/metrics/MetricsFileTailerTest.java
+++ b/test/src/test/java/org/apache/accumulo/test/metrics/MetricsFileTailerTest.java
@@ -1,18 +1,20 @@
/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
*/
package org.apache.accumulo.test.metrics;
@@ -49,42 +51,31 @@ public class MetricsFileTailerTest {
* Create a file tailer and then write some lines and validate the tailer returns the last line.
*/
@Test
- public void fileUpdates() {
-
- MetricsFileTailer tailer = new MetricsFileTailer("foo", TEST_OUTFILE_NAME);
-
- Thread t = new Thread(tailer);
- t.start();
-
- long lastUpdate = tailer.getLastUpdate();
-
- writeToFile();
+ public void fileUpdates() throws InterruptedException {
boolean passed = Boolean.FALSE;
-
- int count = 0;
- while (count++ < 5) {
- if (lastUpdate != tailer.getLastUpdate()) {
- lastUpdate = tailer.getLastUpdate();
- log.trace("{} - {}", tailer.getLastUpdate(), tailer.getLast());
- if (SUCCESS.compareTo(tailer.getLast()) == 0) {
- passed = Boolean.TRUE;
- break;
+ try (MetricsFileTailer tailer = new MetricsFileTailer("foo", TEST_OUTFILE_NAME)) {
+ tailer.startDaemonThread();
+
+ long lastUpdate = tailer.getLastUpdate();
+
+ writeToFile();
+
+ int count = 0;
+ while (count++ < 5) {
+ if (lastUpdate == tailer.getLastUpdate()) {
+ log.trace("no change");
+ } else {
+ lastUpdate = tailer.getLastUpdate();
+ log.trace("{} - {}", tailer.getLastUpdate(), tailer.getLast());
+ if (SUCCESS.compareTo(tailer.getLast()) == 0) {
+ passed = Boolean.TRUE;
+ break;
+ }
}
- } else {
- log.trace("no change");
- }
- try {
Thread.sleep(5_000);
- } catch (InterruptedException ex) {
- // empty
}
- }
- try {
- tailer.close();
- } catch (Exception ex) {
- log.trace("Failed to close file tailer on " + TEST_OUTFILE_NAME, ex);
}
assertTrue(passed);
}