1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.lang3.concurrent;
18
19 import static org.apache.commons.lang3.LangAssertions.assertNullPointerException;
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertFalse;
22 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24 import static org.junit.jupiter.api.Assertions.assertTrue;
25 import static org.junit.jupiter.api.Assertions.fail;
26
27 import java.io.IOException;
28 import java.sql.SQLException;
29
30 import org.apache.commons.lang3.function.FailableConsumer;
31 import org.apache.commons.lang3.function.FailableSupplier;
32 import org.junit.jupiter.api.Test;
33
34
35
36
37
38
39
40
41
42
43
44 public abstract class AbstractConcurrentInitializerCloseAndExceptionsTest<T> extends AbstractConcurrentInitializerTest<T> {
45
46 protected static final class CloseableObject {
47 boolean closed;
48
49 public void close() {
50 closed = true;
51 }
52
53 public boolean isClosed() {
54 return closed;
55 }
56 }
57
58 protected enum ExceptionToThrow {
59 IOException,
60 SQLException,
61 NullPointerException
62 }
63
64
65
66 protected static CloseableObject methodThatThrowsException(final ExceptionToThrow input) throws IOException, SQLException, ConcurrentException {
67 switch (input) {
68 case IOException:
69 throw new IOException();
70 case SQLException:
71 throw new SQLException();
72 case NullPointerException:
73 throw new NullPointerException();
74 default:
75 fail();
76 return new CloseableObject();
77 }
78 }
79
80 protected abstract ConcurrentInitializer<CloseableObject> createInitializerThatThrowsException(
81 FailableSupplier<CloseableObject, ? extends Exception> supplier, FailableConsumer<CloseableObject, ? extends Exception> closer);
82
83
84
85
86
87 @SuppressWarnings("rawtypes")
88 @Test
89 void testCloserThrowsCheckedException() throws ConcurrentException {
90 final ConcurrentInitializer<CloseableObject> initializer = createInitializerThatThrowsException(
91 CloseableObject::new,
92 CloseableObject -> methodThatThrowsException(ExceptionToThrow.IOException));
93 try {
94 initializer.get();
95 ((AbstractConcurrentInitializer) initializer).close();
96 fail();
97 } catch (final Exception e) {
98 assertInstanceOf(ConcurrentException.class, e);
99 assertInstanceOf(IOException.class, e.getCause());
100 }
101 }
102
103
104
105
106
107 @SuppressWarnings("rawtypes")
108 @Test
109 void testCloserThrowsRuntimeException() throws ConcurrentException {
110 final ConcurrentInitializer<CloseableObject> initializer = createInitializerThatThrowsException(
111 CloseableObject::new,
112 CloseableObject -> methodThatThrowsException(ExceptionToThrow.NullPointerException));
113
114 initializer.get();
115 assertNullPointerException(() -> {
116 ((AbstractConcurrentInitializer) initializer).close();
117 });
118 }
119
120
121
122
123
124 @SuppressWarnings("unchecked")
125 @Test
126 void testSupplierThrowsCheckedException() {
127 final ConcurrentInitializer<CloseableObject> initializer = createInitializerThatThrowsException(
128 () -> methodThatThrowsException(ExceptionToThrow.IOException),
129 FailableConsumer.NOP);
130 assertThrows(ConcurrentException.class, () -> initializer.get());
131 }
132
133
134
135
136
137 @Test
138 void testSupplierThrowsConcurrentException() {
139 final ConcurrentException concurrentException = new ConcurrentException();
140 @SuppressWarnings("unchecked")
141 final ConcurrentInitializer<CloseableObject> initializer = createInitializerThatThrowsException(() -> {
142 if ("test".equals("test")) {
143 throw concurrentException;
144 }
145 return new CloseableObject();
146 }, FailableConsumer.NOP);
147 try {
148 initializer.get();
149 fail();
150 } catch (final ConcurrentException e) {
151 assertEquals(concurrentException, e);
152 }
153 }
154
155
156
157
158
159 @SuppressWarnings("unchecked")
160 @Test
161 void testSupplierThrowsRuntimeException() {
162 final ConcurrentInitializer<CloseableObject> initializer = createInitializerThatThrowsException(
163 () -> methodThatThrowsException(ExceptionToThrow.NullPointerException),
164 FailableConsumer.NOP);
165 assertNullPointerException(() -> initializer.get());
166 }
167
168
169
170
171 @SuppressWarnings("rawtypes")
172 @Test
173 void testWorkingCloser() throws Exception {
174 final ConcurrentInitializer<CloseableObject> initializer = createInitializerThatThrowsException(
175 CloseableObject::new,
176 CloseableObject::close);
177
178 final CloseableObject closeableObject = initializer.get();
179 assertFalse(closeableObject.isClosed());
180 ((AbstractConcurrentInitializer) initializer).close();
181 assertTrue(closeableObject.isClosed());
182 }
183 }