ConcurrentUtilsTest.java
/*
* 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
*
* https://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.commons.lang3.concurrent;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.AbstractLangTest;
import org.easymock.EasyMock;
import org.junit.jupiter.api.Test;
/**
* Test class for {@link ConcurrentUtils}.
*/
class ConcurrentUtilsTest extends AbstractLangTest {
/**
* Tests constant future.
*
* @throws Exception so we don't have to catch it
*/
@Test
void testConstantFuture_Integer() throws Exception {
final Integer value = Integer.valueOf(5);
final Future<Integer> test = ConcurrentUtils.constantFuture(value);
assertTrue(test.isDone());
assertSame(value, test.get());
assertSame(value, test.get(1000, TimeUnit.SECONDS));
assertSame(value, test.get(1000, null));
assertFalse(test.isCancelled());
assertFalse(test.cancel(true));
assertFalse(test.cancel(false));
}
/**
* Tests constant future.
*
* @throws Exception so we don't have to catch it
*/
@Test
void testConstantFuture_null() throws Exception {
final Integer value = null;
final Future<Integer> test = ConcurrentUtils.constantFuture(value);
assertTrue(test.isDone());
assertSame(value, test.get());
assertSame(value, test.get(1000, TimeUnit.SECONDS));
assertSame(value, test.get(1000, null));
assertFalse(test.isCancelled());
assertFalse(test.cancel(true));
assertFalse(test.cancel(false));
}
/**
* Tests createIfAbsent() if the map does not contain the key in question.
*
* @throws org.apache.commons.lang3.concurrent.ConcurrentException so we don't have to catch it
*/
@Test
void testCreateIfAbsentKeyNotPresent() throws ConcurrentException {
final ConcurrentInitializer<Integer> init = EasyMock.createMock(ConcurrentInitializer.class);
final String key = "testKey";
final Integer value = 42;
EasyMock.expect(init.get()).andReturn(value);
EasyMock.replay(init);
final ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>();
assertEquals(value, ConcurrentUtils.createIfAbsent(map, key, init), "Wrong result");
assertEquals(value, map.get(key), "Wrong value in map");
EasyMock.verify(init);
}
/**
* Tests createIfAbsent() if the key is found in the map.
*
* @throws org.apache.commons.lang3.concurrent.ConcurrentException so we don't have to catch it
*/
@Test
void testCreateIfAbsentKeyPresent() throws ConcurrentException {
final ConcurrentInitializer<Integer> init = EasyMock.createMock(ConcurrentInitializer.class);
EasyMock.replay(init);
final String key = "testKey";
final Integer value = 42;
final ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>();
map.put(key, value);
assertEquals(value, ConcurrentUtils.createIfAbsent(map, key, init), "Wrong result");
assertEquals(value, map.get(key), "Wrong value in map");
EasyMock.verify(init);
}
/**
* Tests createIfAbsent() if a null initializer is passed in.
*
* @throws org.apache.commons.lang3.concurrent.ConcurrentException so we don't have to catch it
*/
@Test
void testCreateIfAbsentNullInit() throws ConcurrentException {
final ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>();
final String key = "testKey";
final Integer value = 42;
map.put(key, value);
assertNull(ConcurrentUtils.createIfAbsent(map, key, null), "Wrong result");
assertEquals(value, map.get(key), "Map was changed");
}
/**
* Tests createIfAbsent() if a null map is passed in.
*
* @throws org.apache.commons.lang3.concurrent.ConcurrentException so we don't have to catch it
*/
@Test
void testCreateIfAbsentNullMap() throws ConcurrentException {
final ConcurrentInitializer<Integer> init = EasyMock.createMock(ConcurrentInitializer.class);
EasyMock.replay(init);
assertNull(ConcurrentUtils.createIfAbsent(null, "test", init), "Wrong result");
EasyMock.verify(init);
}
/**
* Tests createIfAbsentUnchecked() if an exception is thrown.
*
* @throws org.apache.commons.lang3.concurrent.ConcurrentException so we don't have to catch it
*/
@Test
void testCreateIfAbsentUncheckedException() throws ConcurrentException {
final ConcurrentInitializer<Integer> init = EasyMock.createMock(ConcurrentInitializer.class);
final Exception ex = new Exception();
EasyMock.expect(init.get()).andThrow(new ConcurrentException(ex));
EasyMock.replay(init);
final ConcurrentRuntimeException crex = assertThrows(ConcurrentRuntimeException.class,
() -> ConcurrentUtils.createIfAbsentUnchecked(new ConcurrentHashMap<>(), "test", init));
assertEquals(ex, crex.getCause(), "Wrong cause");
EasyMock.verify(init);
}
/**
* Tests createIfAbsentUnchecked() if no exception is thrown.
*/
@Test
void testCreateIfAbsentUncheckedSuccess() {
final String key = "testKey";
final Integer value = 42;
final ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>();
assertEquals(value, ConcurrentUtils.createIfAbsentUnchecked(map, key, new ConstantInitializer<>(value)), "Wrong result");
assertEquals(value, map.get(key), "Wrong value in map");
}
/**
* Tests extractCause() if the cause is a checked exception.
*/
@Test
void testExtractCauseChecked() {
final Exception ex = new Exception("Test");
final ConcurrentException cex = ConcurrentUtils.extractCause(new ExecutionException(ex));
assertSame(ex, cex.getCause(), "Wrong cause");
}
/**
* Tests extractCause() if the cause is an error.
*/
@Test
void testExtractCauseError() {
final Error err = new AssertionError("Test");
final AssertionError e = assertThrows(AssertionError.class, () -> ConcurrentUtils.extractCause(new ExecutionException(err)));
assertEquals(err, e, "Wrong error");
}
/**
* Tests extractCause() for a null exception.
*/
@Test
void testExtractCauseNull() {
assertNull(ConcurrentUtils.extractCause(null), "Non null result");
}
/**
* Tests extractCause() if the cause of the passed in exception is null.
*/
@Test
void testExtractCauseNullCause() {
assertNull(ConcurrentUtils.extractCause(new ExecutionException("Test", null)), "Non null result");
}
/**
* Tests extractCauseUnchecked() if the cause is a checked exception.
*/
@Test
void testExtractCauseUncheckedChecked() {
final Exception ex = new Exception("Test");
final ConcurrentRuntimeException cex = ConcurrentUtils.extractCauseUnchecked(new ExecutionException(ex));
assertSame(ex, cex.getCause(), "Wrong cause");
}
/**
* Tests extractCauseUnchecked() if the cause is an error.
*/
@Test
void testExtractCauseUncheckedError() {
final Error err = new AssertionError("Test");
final Error e = assertThrows(Error.class, () -> ConcurrentUtils.extractCauseUnchecked(new ExecutionException(err)));
assertEquals(err, e, "Wrong error");
}
/**
* Tests extractCause() if the cause is an unchecked exception.
*/
@Test
void testExtractCauseUncheckedException() {
final RuntimeException rex = new RuntimeException("Test");
assertThrows(RuntimeException.class, () -> ConcurrentUtils.extractCause(new ExecutionException(rex)));
}
/**
* Tests extractCauseUnchecked() for a null exception.
*/
@Test
void testExtractCauseUncheckedNull() {
assertNull(ConcurrentUtils.extractCauseUnchecked(null), "Non null result");
}
/**
* Tests extractCauseUnchecked() if the cause of the passed in exception is null.
*/
@Test
void testExtractCauseUncheckedNullCause() {
assertNull(ConcurrentUtils.extractCauseUnchecked(new ExecutionException("Test", null)), "Non null result");
}
/**
* Tests extractCauseUnchecked() if the cause is an unchecked exception.
*/
@Test
void testExtractCauseUncheckedUncheckedException() {
final RuntimeException rex = new RuntimeException("Test");
final RuntimeException r = assertThrows(RuntimeException.class, () -> ConcurrentUtils.extractCauseUnchecked(new ExecutionException(rex)));
assertEquals(rex, r, "Wrong exception");
}
/**
* Tests handleCause() if the cause is a checked exception.
*/
@Test
void testHandleCauseChecked() {
final Exception ex = new Exception("Test");
final ConcurrentException cex = assertThrows(ConcurrentException.class, () -> ConcurrentUtils.handleCause(new ExecutionException(ex)));
assertEquals(ex, cex.getCause(), "Wrong cause");
}
/**
* Tests handleCause() if the cause is an error.
*/
@Test
void testHandleCauseError() {
final Error err = new AssertionError("Test");
final Error e = assertThrows(Error.class, () -> ConcurrentUtils.handleCause(new ExecutionException(err)));
assertEquals(err, e, "Wrong error");
}
/**
* Tests handleCause() for a null parameter or a null cause. In this case the method should do nothing. We can only test
* that no exception is thrown.
*
* @throws org.apache.commons.lang3.concurrent.ConcurrentException so we don't have to catch it
*/
@Test
void testHandleCauseNull() throws ConcurrentException {
ConcurrentUtils.handleCause(null);
ConcurrentUtils.handleCause(new ExecutionException("Test", null));
}
/**
* Tests handleCauseUnchecked() if the cause is a checked exception.
*/
@Test
void testHandleCauseUncheckedChecked() {
final Exception ex = new Exception("Test");
final ConcurrentRuntimeException crex = assertThrows(ConcurrentRuntimeException.class,
() -> ConcurrentUtils.handleCauseUnchecked(new ExecutionException(ex)));
assertEquals(ex, crex.getCause(), "Wrong cause");
}
/**
* Tests handleCauseUnchecked() if the cause is an error.
*/
@Test
void testHandleCauseUncheckedError() {
final Error err = new AssertionError("Test");
final Error e = assertThrows(Error.class, () -> ConcurrentUtils.handleCauseUnchecked(new ExecutionException(err)));
assertEquals(err, e, "Wrong error");
}
/**
* Tests handleCause() if the cause is an unchecked exception.
*/
@Test
void testHandleCauseUncheckedException() {
final RuntimeException rex = new RuntimeException("Test");
final RuntimeException r = assertThrows(RuntimeException.class, () -> ConcurrentUtils.handleCause(new ExecutionException(rex)));
assertEquals(rex, r, "Wrong exception");
}
/**
* Tests handleCauseUnchecked() for a null parameter or a null cause. In this case the method should do nothing. We can
* only test that no exception is thrown.
*/
@Test
void testHandleCauseUncheckedNull() {
ConcurrentUtils.handleCauseUnchecked(null);
ConcurrentUtils.handleCauseUnchecked(new ExecutionException("Test", null));
}
/**
* Tests handleCauseUnchecked() if the cause is an unchecked exception.
*/
@Test
void testHandleCauseUncheckedUncheckedException() {
final RuntimeException rex = new RuntimeException("Test");
final RuntimeException r = assertThrows(RuntimeException.class, () -> ConcurrentUtils.handleCauseUnchecked(new ExecutionException(rex)));
assertEquals(rex, r, "Wrong exception");
}
/**
* Tests a successful initialize() operation.
*
* @throws org.apache.commons.lang3.concurrent.ConcurrentException so we don't have to catch it
*/
@Test
void testInitialize() throws ConcurrentException {
final ConcurrentInitializer<Object> init = EasyMock.createMock(ConcurrentInitializer.class);
final Object result = new Object();
EasyMock.expect(init.get()).andReturn(result);
EasyMock.replay(init);
assertSame(result, ConcurrentUtils.initialize(init), "Wrong result object");
EasyMock.verify(init);
}
/**
* Tests initialize() for a null argument.
*
* @throws org.apache.commons.lang3.concurrent.ConcurrentException so we don't have to catch it
*/
@Test
void testInitializeNull() throws ConcurrentException {
assertNull(ConcurrentUtils.initialize(null), "Got a result");
}
/**
* Tests a successful initializeUnchecked() operation.
*
* @throws org.apache.commons.lang3.concurrent.ConcurrentException so we don't have to catch it
*/
@Test
void testInitializeUnchecked() throws ConcurrentException {
final ConcurrentInitializer<Object> init = EasyMock.createMock(ConcurrentInitializer.class);
final Object result = new Object();
EasyMock.expect(init.get()).andReturn(result);
EasyMock.replay(init);
assertSame(result, ConcurrentUtils.initializeUnchecked(init), "Wrong result object");
EasyMock.verify(init);
}
/**
* Tests whether exceptions are correctly handled by initializeUnchecked().
*
* @throws org.apache.commons.lang3.concurrent.ConcurrentException so we don't have to catch it
*/
@Test
void testInitializeUncheckedEx() throws ConcurrentException {
final ConcurrentInitializer<Object> init = EasyMock.createMock(ConcurrentInitializer.class);
final Exception cause = new Exception();
EasyMock.expect(init.get()).andThrow(new ConcurrentException(cause));
EasyMock.replay(init);
final ConcurrentRuntimeException crex = assertThrows(ConcurrentRuntimeException.class, () -> ConcurrentUtils.initializeUnchecked(init));
assertSame(cause, crex.getCause(), "Wrong cause");
EasyMock.verify(init);
}
/**
* Tests initializeUnchecked() for a null argument.
*/
@Test
void testInitializeUncheckedNull() {
assertNull(ConcurrentUtils.initializeUnchecked(null), "Got a result");
}
/**
* Tests putIfAbsent() if the map does not contain the key in question.
*/
@Test
void testPutIfAbsentKeyNotPresent() {
final String key = "testKey";
final Integer value = 42;
final ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>();
assertEquals(value, ConcurrentUtils.putIfAbsent(map, key, value), "Wrong result");
assertEquals(value, map.get(key), "Wrong value in map");
}
/**
* Tests putIfAbsent() if the map contains the key in question.
*/
@Test
void testPutIfAbsentKeyPresent() {
final String key = "testKey";
final Integer value = 42;
final ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>();
map.put(key, value);
assertEquals(value, ConcurrentUtils.putIfAbsent(map, key, 0), "Wrong result");
assertEquals(value, map.get(key), "Wrong value in map");
}
/**
* Tests putIfAbsent() if a null map is passed in.
*/
@Test
void testPutIfAbsentNullMap() {
assertNull(ConcurrentUtils.putIfAbsent(null, "test", 100), "Wrong result");
}
/**
* Tests creating ConcurrentRuntimeException with no arguments.
*/
@Test
void testUninitializedConcurrentRuntimeException() {
assertNotNull(new ConcurrentRuntimeException(), "Error creating empty ConcurrentRuntimeException");
}
}