blob: 06aa4ad616abb3f32859688d59b69df03dc95598 [file] [log] [blame]
/*
* 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.
*/
package org.apache.ignite.internal.processors.failure;
import java.util.concurrent.atomic.AtomicBoolean;
import com.google.common.collect.ImmutableSet;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.IgniteSystemProperties;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.failure.FailureContext;
import org.apache.ignite.failure.FailureType;
import org.apache.ignite.failure.TestFailureHandler;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.testframework.ListeningTestLogger;
import org.apache.ignite.testframework.junits.WithSystemProperty;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.jetbrains.annotations.Nullable;
import org.junit.Test;
import static org.apache.ignite.internal.processors.failure.FailureProcessor.FAILURE_LOG_MSG;
import static org.apache.ignite.internal.processors.failure.FailureProcessor.IGNORED_FAILURE_LOG_MSG;
import static org.apache.ignite.internal.util.IgniteUtils.THREAD_DUMP_MSG;
/**
* Tests log messages of failure processor.
*/
@WithSystemProperty(key = IgniteSystemProperties.IGNITE_DUMP_THREADS_ON_FAILURE, value = "true")
public class FailureProcessorLoggingTest extends GridCommonAbstractTest {
/** Test logger. */
private static CustomTestLogger testLog;
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
TestFailureHandler hnd = new TestFailureHandler(false);
testLog = new CustomTestLogger(log);
hnd.setIgnoredFailureTypes(ImmutableSet.of(FailureType.SYSTEM_CRITICAL_OPERATION_TIMEOUT, FailureType.SYSTEM_WORKER_BLOCKED));
cfg.setFailureHandler(hnd);
cfg.setGridLogger(testLog);
return cfg;
}
/** {@inheritDoc} */
@Override protected void beforeTestsStarted() throws Exception {
super.beforeTestsStarted();
startGrid(0);
testLog.expectedThreadDumpMessage(THREAD_DUMP_MSG);
}
/** {@inheritDoc} */
@Override protected void afterTestsStopped() throws Exception {
super.afterTestsStopped();
stopAllGrids();
}
/** {@inheritDoc} */
@Override protected void beforeTest() throws Exception {
super.beforeTest();
testLog.resetAllFlags();
}
/** {@inheritDoc} */
@Override protected void afterTest() throws Exception {
super.afterTest();
testLog.resetAllFlags();
}
/**
* Tests log message for ignored failure types.
*/
@Test
public void testFailureProcessorLoggedIgnoredFailureTest() throws Exception {
IgniteEx ignite = grid(0);
testLog.expectedWarnMessage(IGNORED_FAILURE_LOG_MSG);
ignite.context().failure().process(
new FailureContext(FailureType.SYSTEM_CRITICAL_OPERATION_TIMEOUT, new Throwable("Failure context error"))
);
assertTrue(testLog.warnFlag().get());
assertTrue(testLog.threadDumpWarnFlag().get());
}
/**
* Tests log message for not ingnored failure types.
*/
@Test
public void testFailureProcessorLoggedFailureTest() throws Exception {
IgniteEx ignite = grid(0);
testLog.expectedErrorMessage(FAILURE_LOG_MSG);
ignite.context().failure().process(new FailureContext(FailureType.SEGMENTATION, new Throwable("Failure context error")));
assertTrue(testLog.errorFlag().get());
assertTrue(testLog.threadDumpErrorFlag().get());
}
/**
* Custom logger for checking if specified message and thread dump appeared at WARN and ERROR logging level.
*/
private static class CustomTestLogger extends ListeningTestLogger {
/** Warn flag. */
private AtomicBoolean warnFlag = new AtomicBoolean(false);
/** Error flag. */
private AtomicBoolean errorFlag = new AtomicBoolean(false);
/** Thread dump warn flag. */
private AtomicBoolean threadDumpWarnFlag = new AtomicBoolean(false);
/** Thread dump error flag. */
private AtomicBoolean threadDumpErrorFlag = new AtomicBoolean(false);
/** Expected warn message. */
private String expWarnMsg;
/** Expected error message. */
private String expErrorMsg;
/** Thread dump message. */
private String expThreadDumpMsg;
/**
* @param echo Echo.
*/
public CustomTestLogger(@Nullable IgniteLogger echo) {
super(echo);
}
/** {@inheritDoc} */
@Override public void warning(String msg, @Nullable Throwable t) {
super.warning(msg, t);
if (expWarnMsg != null && msg.contains(expWarnMsg))
warnFlag.set(true);
if (expThreadDumpMsg != null && msg.contains(expThreadDumpMsg))
threadDumpWarnFlag.set(true);
}
/** {@inheritDoc} */
@Override public void error(String msg, @Nullable Throwable t) {
super.error(msg, t);
if (expErrorMsg != null && msg.contains(expErrorMsg))
errorFlag.set(true);
if (expThreadDumpMsg != null && msg.contains(expThreadDumpMsg))
threadDumpErrorFlag.set(true);
}
/** {@inheritDoc} */
@Override public ListeningTestLogger getLogger(Object ctgr) {
return this;
}
/**
* Reset warn flag.
*/
public void resetWarnFlag() {
warnFlag.set(false);
}
/**
* Reset error flag.
*/
public void resetErrorFlag() {
errorFlag.set(false);
}
/**
* Reset thread dump warn flag.
*/
public void resetThreadDumpWarnFlag() {
threadDumpWarnFlag.set(false);
}
/**
* Reset thread dump error flag.
*/
public void resetThreadDumpErrorFlag() {
threadDumpErrorFlag.set(false);
}
/**
* Reset all flags.
*/
public void resetAllFlags() {
resetWarnFlag();
resetErrorFlag();
resetThreadDumpWarnFlag();
resetThreadDumpErrorFlag();
}
/**
* @param expWarnMsg New expected warn message.
*/
public void expectedWarnMessage(String expWarnMsg) {
this.expWarnMsg = expWarnMsg;
}
/**
* @param expErrorMsg New expected error message.
*/
public void expectedErrorMessage(String expErrorMsg) {
this.expErrorMsg = expErrorMsg;
}
/**
* @param expThreadDumpMsg New expected thread dump message.
*/
public void expectedThreadDumpMessage(String expThreadDumpMsg) {
this.expThreadDumpMsg = expThreadDumpMsg;
}
/**
* @return Warn flag.
*/
public AtomicBoolean warnFlag() {
return warnFlag;
}
/**
* @return Error flag.
*/
public AtomicBoolean errorFlag() {
return errorFlag;
}
/**
* @return Thread dump warn flag.
*/
public AtomicBoolean threadDumpWarnFlag() {
return threadDumpWarnFlag;
}
/**
* @return Thread dump error flag.
*/
public AtomicBoolean threadDumpErrorFlag() {
return threadDumpErrorFlag;
}
}
}