/**
* 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.util;
import java.io.IOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* The InjectionHandler is an object provided to a class,
* which can perform custom actions for JUnit testing.
* JUnit test can implement custom version of the handler.
* For example, let's say we want to supervise FSImage object:
*
* // JUnit test code
* class MyInjectionHandler extends InjectionHandler {
* protected void _processEvent(InjectionEventInterface event,
* Object... args) {
* if (event = InjectionEventInterface.MY_EVENT) {
* LOG.info("Handling my event for fsImage: "
* + args[0].toString());
* }
* }
* }
*
* public void testMyEvent() {
* InjectionHandler ih = new MyInjectionHandler();
* InjectionHandler.set(ih);
* ...
*
* InjectionHandler.clear();
* }
*
* // supervised code example
*
* class FSImage {
*
* private doSomething() {
* ...
* if (condition1 && InjectionHandler.trueCondition(MY_EVENT1) {
* ...
* }
* if (condition2 || condition3
* || InjectionHandler.falseCondition(MY_EVENT1) {
* ...
* }
* ...
* InjectionHandler.processEvent(MY_EVENT2, this)
* ...
* try {
* read();
* InjectionHandler.processEventIO(MY_EVENT3, this, object);
* // might throw an exception when testing
* catch (IOEXception) {
* LOG.info("Exception")
* }
* ...
* }
* ...
* }
*
* Each unit test should use a unique event type.
* The types can be defined by adding them to
* InjectionEventInterface class.
*
* methods:
*
* // simulate actions
* void processEvent()
* // simulate exceptions
* void processEventIO() throws IOException
*
* // simulate conditions
* boolean trueCondition()
* boolean falseCondition()
*
* The class implementing InjectionHandler must
* override respective protected methods
* _processEvent()
* _processEventIO()
* _trueCondition()
* _falseCondition()
*/
public class InjectionHandler {
private static final Log LOG = LogFactory.getLog(InjectionHandler.class);
// the only handler to which everyone reports
private static InjectionHandler handler = new InjectionHandler();
// can not be instantiated outside, unless a testcase extends it
protected InjectionHandler() {}
// METHODS FOR PRODUCTION CODE
protected void _processEvent(InjectionEventI event, Object... args) {
// by default do nothing
}
protected void _processEventIO(InjectionEventI event, Object... args) throws IOException{
// by default do nothing
}
protected boolean _trueCondition(InjectionEventI event, Object... args) {
return true; // neutral in conjunction
}
protected boolean _falseCondition(InjectionEventI event, Object... args) {
return false; // neutral in alternative
}
////////////////////////////////////////////////////////////
/**
* Set to the empty/production implementation.
*/
public static void clear() {
handler = new InjectionHandler();
}
/**
* Set custom implementation of the handler.
*/
public static void set(InjectionHandler custom) {
LOG.warn("WARNING: SETTING INJECTION HANDLER" +
" - THIS SHOULD NOT BE USED IN PRODUCTION !!!");
handler = custom;
}
/*
* Static methods for reporting to the handler
*/
public static void processEvent(InjectionEventI event, Object... args) {
handler._processEvent(event, args);
}
public static void processEventIO(InjectionEventI event, Object... args)
throws IOException {
handler._processEventIO(event, args);
}
public static boolean trueCondition(InjectionEventI event, Object... args) {
return handler._trueCondition(event, args);
}
public static boolean falseCondition(InjectionEventI event, Object... args) {
return handler._falseCondition(event, args);
}
}