Output all failing bootstrap checks

This commit modifies the boostrap checks to output all failing checks
instead of early-failing on the first check and then possibly failing
again after the user resolves the first failing check.

Closes #17474
This commit is contained in:
Jason Tedor 2016-04-07 09:50:43 -04:00
parent cfc23a9d67
commit fc7442739c
2 changed files with 57 additions and 8 deletions

View File

@ -34,6 +34,7 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.stream.Collectors;
/** /**
* We enforce limits once any network host is configured. In this case we assume the node is running in production * We enforce limits once any network host is configured. In this case we assume the node is running in production
@ -72,14 +73,22 @@ final class BootstrapCheck {
static void check(final boolean enforceLimits, final List<Check> checks, final String nodeName) { static void check(final boolean enforceLimits, final List<Check> checks, final String nodeName) {
final ESLogger logger = Loggers.getLogger(BootstrapCheck.class, nodeName); final ESLogger logger = Loggers.getLogger(BootstrapCheck.class, nodeName);
for (final Check check : checks) { final List<String> errors =
final boolean fail = check.check(); checks.stream()
if (fail) { .filter(BootstrapCheck.Check::check)
if (enforceLimits) { .map(BootstrapCheck.Check::errorMessage)
throw new RuntimeException(check.errorMessage()); .collect(Collectors.toList());
} else {
logger.warn(check.errorMessage()); if (!errors.isEmpty()) {
} final List<String> messages = new ArrayList<>(1 + errors.size());
messages.add("bootstrap checks failed");
messages.addAll(errors);
if (enforceLimits) {
final RuntimeException re = new RuntimeException(String.join("\n", messages));
errors.stream().map(IllegalStateException::new).forEach(re::addSuppressed);
throw re;
} else {
messages.forEach(message -> logger.warn(message));
} }
} }
} }

View File

@ -26,12 +26,16 @@ import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.Matchers.hasToString;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -97,6 +101,42 @@ public class BootstrapCheckTests extends ESTestCase {
assertTrue(BootstrapCheck.enforceLimits(boundTransportAddress)); assertTrue(BootstrapCheck.enforceLimits(boundTransportAddress));
} }
public void testExceptionAggregation() {
final List<BootstrapCheck.Check> checks = Arrays.asList(
new BootstrapCheck.Check() {
@Override
public boolean check() {
return true;
}
@Override
public String errorMessage() {
return "first";
}
},
new BootstrapCheck.Check() {
@Override
public boolean check() {
return true;
}
@Override
public String errorMessage() {
return "second";
}
}
);
final RuntimeException e =
expectThrows(RuntimeException.class, () -> BootstrapCheck.check(true, checks, "testExceptionAggregation"));
assertThat(e, hasToString(allOf(containsString("bootstrap checks failed"), containsString("first"), containsString("second"))));
final Throwable[] suppressed = e.getSuppressed();
assertThat(suppressed.length, equalTo(2));
assertThat(suppressed[0], instanceOf(IllegalStateException.class));
assertThat(suppressed[0], hasToString(containsString("first")));
assertThat(suppressed[1], instanceOf(IllegalStateException.class));
assertThat(suppressed[1], hasToString(containsString("second")));
}
public void testFileDescriptorLimits() { public void testFileDescriptorLimits() {
final boolean osX = randomBoolean(); // simulates OS X versus non-OS X final boolean osX = randomBoolean(); // simulates OS X versus non-OS X
final int limit = osX ? 10240 : 1 << 16; final int limit = osX ? 10240 : 1 << 16;