I am trying to wrap my head around making junits threadsafe. I have a static class that is used across the entire codebase like so:
public class FaultList {
private static final String MESSAGE_CONTEXT_KEY = "FaultList";
private static ThreadLocal<ArrayList<Fault>> threadFaultList = new ThreadLocal();
private static final String[] ACCOUNT_NOT_FOUND_STRINGS = new String[]{"INVALID CARDHOLDER NUMBER", "INVALID CHECK DIGIT ENTERED", "RECORD NOT FOUND", "DATA REQUESTED IS RESTRICTED FOR TERMINAL"};
public FaultList() {
}
public static void init() {
threadFaultList.set(new ArrayList());
MessageContext.getMessageContext().put("FaultList", Collections.synchronizedList(new ArrayList()));
}
public static boolean isFDRExceptionAccountNotFound(String errorMessage) {
for(int i = 0; i < ACCOUNT_NOT_FOUND_STRINGS.length; ++i) {
if (errorMessage.indexOf(ACCOUNT_NOT_FOUND_STRINGS[i]) != -1) {
return true;
}
}
return false;
}
public static boolean isEmpty() {
return ((ArrayList)threadFaultList.get()).isEmpty();
}
public static void add(Fault fault) {
((ArrayList)threadFaultList.get()).add(fault);
getMessageContextFaults().add(fault);
}
public static void addAll(Collection<? extends Fault> faults) {
((ArrayList)threadFaultList.get()).addAll(faults);
getMessageContextFaults().addAll(faults);
}
public static List<Fault> getMessageContextFaults() {
return (List)MessageContext.getMessageContext().get("FaultList");
}
public static ArrayList<Fault> getList() {
return (ArrayList)threadFaultList.get();
}
public static boolean isSevereErrorPresent() {
Iterator var0 = ((ArrayList)threadFaultList.get()).iterator();
Fault f;
do {
if (!var0.hasNext()) {
return false;
}
f = (Fault)var0.next();
} while(!f.getSeverity().getValue().equalsIgnoreCase("ERROR") && !f.getSeverity().getValue().equalsIgnoreCase("CRITICAL_ERROR"));
return true;
}
public static boolean isPaymentDeniedFaultPresent() {
Iterator var0 = ((ArrayList)threadFaultList.get()).iterator();
Fault f;
do {
if (!var0.hasNext()) {
return false;
}
f = (Fault)var0.next();
} while(!f.getId().getName().contains("3179") && !f.getId().getName().contains("3180") && !f.getId().getName().contains("3184"));
return true;
}
public static boolean isAddressParsingFaultPresent() {
Iterator var0 = ((ArrayList)threadFaultList.get()).iterator();
Fault f;
do {
if (!var0.hasNext()) {
return false;
}
f = (Fault)var0.next();
} while(!f.getId().getName().contains("3500"));
return true;
}
public static boolean isMemoPostFailedPresent() {
Iterator var0 = ((ArrayList)threadFaultList.get()).iterator();
Fault f;
do {
if (!var0.hasNext()) {
return false;
}
f = (Fault)var0.next();
} while(!f.getId().getName().contains("3069"));
return true;
}
public static boolean isCreditCardTypeWarningPresent() {
Iterator var0 = ((ArrayList)threadFaultList.get()).iterator();
Fault f;
do {
if (!var0.hasNext()) {
return false;
}
f = (Fault)var0.next();
} while(!f.getId().getName().contains("3173"));
return true;
}
public static Fault getSevereFaultFromFaultList() {
Iterator var0 = getList().iterator();
Fault f;
do {
if (!var0.hasNext()) {
return null;
}
f = (Fault)var0.next();
} while(!f.getSeverity().getValue().equalsIgnoreCase("ERROR") && !f.getSeverity().getValue().equalsIgnoreCase("CRITICAL_ERROR"));
return f;
}
}
The class is written by using ThreadLocal which binds the faultList to every single thread so junits executed in separate threads do not interfere with each other. What happens to the junits executed in the same thread written as follow?
public void A(){
FaultList.init();
FaultList.add(fault1);
}
public void B(){
FaultList.init()
FaultList.add(faul2);
}
Will java execute these junits in the same thread sequentally? or it will for example execute both by taking an instruction from each at a time hence creating a concurrency issue?
By default Junit is executing test cases in deterministic, but unpredictable order.
Here are some good reads:
By default JUnit runs tests in one thread, i.e. sequentually. However, there are ways to run tests and test-methods in particular in parallel threads. For JUnit 5 this feature can be switched just by configuration parameters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With