blob: e697529c8446c9484af34077f122d5fcb1505c32 [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.hadoop.ozone.upgrade;
import static org.apache.hadoop.ozone.upgrade.InjectedUpgradeFinalizationExecutor.UpgradeTestInjectionPoints.AFTER_COMPLETE_FINALIZATION;
import static org.apache.hadoop.ozone.upgrade.InjectedUpgradeFinalizationExecutor.UpgradeTestInjectionPoints.AFTER_POST_FINALIZE_UPGRADE;
import static org.apache.hadoop.ozone.upgrade.InjectedUpgradeFinalizationExecutor.UpgradeTestInjectionPoints.AFTER_PRE_FINALIZE_UPGRADE;
import static org.apache.hadoop.ozone.upgrade.InjectedUpgradeFinalizationExecutor.UpgradeTestInjectionPoints.BEFORE_PRE_FINALIZE_UPGRADE;
import static org.apache.hadoop.ozone.upgrade.UpgradeFinalizer.Status.FINALIZATION_IN_PROGRESS;
import static org.apache.hadoop.ozone.upgrade.UpgradeFinalizer.Status.FINALIZATION_REQUIRED;
import java.io.IOException;
import java.util.concurrent.Callable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Failure injected extension of DefaultUpgradeFinalizationExecutor that
* can be used by Unit/Integration Tests.
*/
public class InjectedUpgradeFinalizationExecutor<T> extends
DefaultUpgradeFinalizationExecutor<T> {
static final Logger LOG =
LoggerFactory.getLogger(InjectedUpgradeFinalizationExecutor.class);
private Callable<Boolean> injectTestFunction;
private UpgradeTestInjectionPoints testInjectionPoint;
/**
* Enum to denote failure injection points in finalization.
*/
public enum UpgradeTestInjectionPoints {
BEFORE_PRE_FINALIZE_UPGRADE(1),
AFTER_PRE_FINALIZE_UPGRADE(2),
AFTER_COMPLETE_FINALIZATION(4),
AFTER_POST_FINALIZE_UPGRADE(5);
private int val;
UpgradeTestInjectionPoints(int value) {
val = value;
}
public int getValue() {
return val;
}
}
static class UpgradeTestInjectionAbort extends Exception {
UpgradeTestInjectionAbort() {
}
}
@Override
public void execute(T component, BasicUpgradeFinalizer finalizer)
throws IOException {
try {
injectTestFunctionAtThisPoint(BEFORE_PRE_FINALIZE_UPGRADE);
finalizer.emitStartingMsg();
finalizer.getVersionManager()
.setUpgradeState(FINALIZATION_IN_PROGRESS);
finalizer.preFinalizeUpgrade(component);
injectTestFunctionAtThisPoint(AFTER_PRE_FINALIZE_UPGRADE);
finalizer.finalizeUpgrade(component);
injectTestFunctionAtThisPoint(AFTER_COMPLETE_FINALIZATION);
finalizer.postFinalizeUpgrade(component);
injectTestFunctionAtThisPoint(AFTER_POST_FINALIZE_UPGRADE);
finalizer.emitFinishedMsg();
} catch (Exception e) {
LOG.warn("Upgrade Finalization failed with following Exception.", e);
if (finalizer.getVersionManager().needsFinalization()) {
finalizer.getVersionManager()
.setUpgradeState(FINALIZATION_REQUIRED);
}
} finally {
finalizer.markFinalizationDone();
}
}
/**
* Interface to inject arbitrary failures for stress testing.
* @param injectedTestFunction that will be called
* code execution reached injectTestFunctionAtThisPoint() location.
* @param pointIndex code execution point for a given thread.
*/
public void configureTestInjectionFunction(
UpgradeTestInjectionPoints pointIndex,
Callable<Boolean> injectedTestFunction) {
injectTestFunction = injectedTestFunction;
testInjectionPoint = pointIndex;
}
/**
* Interface to inject error at a given point in an upgrade thread.
* @param pointIndex TestFunction Injection point in an upgrade thread.
* @return "true" if the calling thread should not continue with further
* upgrade processing, "false" otherwise.
*/
public void injectTestFunctionAtThisPoint(
UpgradeTestInjectionPoints pointIndex) throws Exception {
if ((testInjectionPoint != null) &&
(pointIndex.getValue() == testInjectionPoint.getValue()) &&
(injectTestFunction != null) && injectTestFunction.call()) {
throw new UpgradeTestInjectionAbort();
}
return;
}
}