1 package org.apache.onami.persist.test.transaction.testframework;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import com.google.common.annotations.VisibleForTesting;
23 import com.google.inject.Injector;
24 import org.apache.onami.persist.EntityManagerProvider;
25 import org.apache.onami.persist.Transactional;
26 import org.apache.onami.persist.UnitOfWork;
27 import org.apache.onami.persist.test.TestEntity;
28 import org.apache.onami.persist.test.transaction.testframework.exceptions.RuntimeTestException;
29 import org.apache.onami.persist.test.transaction.testframework.exceptions.TestException;
30
31 import javax.inject.Inject;
32 import java.lang.reflect.Method;
33 import java.util.ArrayList;
34 import java.util.List;
35
36 import static com.google.common.base.Preconditions.checkNotNull;
37 import static com.google.common.base.Preconditions.checkState;
38 import static org.junit.Assert.assertNotNull;
39 import static org.junit.Assert.assertNull;
40
41
42
43
44
45 public class TransactionalWorker
46 {
47
48 private static final String DO_TRANSACTIONAL = "doTransactional";
49
50 private final TransactionalTasks tasks = new TransactionalTasks();
51
52 private final List<TestEntity> storedEntities = new ArrayList<TestEntity>();
53
54 @Inject
55 private Injector injector;
56
57 @Inject
58 private UnitOfWork unitOfWork;
59
60 @Inject
61 private EntityManagerProvider emProvider;
62
63
64
65
66
67
68
69
70 public void scheduleTask( Class<? extends TransactionalTask> taskType )
71 {
72 checkTransactionalAnnotation( taskType );
73 final TransactionalTask task = injector.getInstance( taskType );
74 task.setWorker( this );
75 tasks.add( task );
76 }
77
78 private void checkTransactionalAnnotation( Class<? extends TransactionalTask> taskType )
79 {
80 try
81 {
82 final Method method = taskType.getMethod( DO_TRANSACTIONAL );
83 final Transactional annotation = method.getAnnotation( Transactional.class );
84 checkNotNull( annotation, "@Transactional annotation missing on %s.%s", taskType.getSimpleName(),
85 method.getName() );
86 }
87 catch ( NoSuchMethodException e )
88 {
89
90 throw new RuntimeException( e );
91 }
92 }
93
94
95
96
97
98 public void doTasks()
99 {
100 checkState( tasks.hasTasks(), "no tasks have been added to the worker." );
101 checkState( tasks.hasNext(), "doTasks() has already been executed." );
102 checkState( !unitOfWork.isActive(), "Active UnitOfWork found." );
103
104 try
105 {
106 doNextTask();
107 }
108 catch ( TestException e )
109 {
110
111 }
112 catch ( RuntimeTestException e )
113 {
114
115 }
116
117 checkState( !tasks.hasNext(), "One of the tasks forgot to call doOtherTasks()." );
118 checkState( !unitOfWork.isActive(), "Active UnitOfWork after tasks found." );
119 }
120
121
122
123
124 @Transactional
125 public void assertAllEntitiesHaveBeenPersisted()
126 {
127 checkState( !storedEntities.isEmpty(), "no entities to check" );
128 for ( TestEntity storedEntity : storedEntities )
129 {
130 assertNotNull( "At least one entity which should have been persisted was NOT found in the DB. " + tasks,
131 emProvider.get().find( TestEntity.class, storedEntity.getId() ) );
132 }
133 }
134
135
136
137
138 @Transactional
139 public void assertNoEntityHasBeenPersisted()
140 {
141 checkState( !storedEntities.isEmpty(), "no entities to check" );
142 for ( TestEntity storedEntity : storedEntities )
143 {
144 assertNull( "At least one entity which should NOT have been persisted was found in the DB. " + tasks,
145 emProvider.get().find( TestEntity.class, storedEntity.getId() ) );
146 }
147 }
148
149 @VisibleForTesting
150 void doNextTask()
151 throws TestException
152 {
153 if ( tasks.hasNext() )
154 {
155 final TransactionalTask task = tasks.next();
156 try
157 {
158 task.doTransactional();
159 }
160 finally
161 {
162 storedEntities.addAll( task.getPersistedEntities() );
163 }
164 }
165 }
166
167
168
169
170
171 private static class TransactionalTasks
172 {
173
174 private final List<TransactionalTask> tasks = new ArrayList<TransactionalTask>();
175
176 private int pos = 0;
177
178
179
180
181 public boolean hasTasks()
182 {
183 return !tasks.isEmpty();
184 }
185
186
187
188
189
190
191
192 public void add( TransactionalTask task )
193 {
194 checkState( pos == 0 );
195 tasks.add( task );
196 }
197
198
199
200
201 public boolean hasNext()
202 {
203 return pos < tasks.size();
204 }
205
206
207
208
209
210 public TransactionalTask next()
211 {
212 final TransactionalTask result = tasks.get( pos );
213 pos++;
214 return result;
215 }
216
217 @Override
218 public String toString()
219 {
220 final StringBuilder sb = new StringBuilder( "Tasks[" );
221 String separator = "";
222 for ( TransactionalTask t : tasks )
223 {
224 sb.append( separator );
225 final String taskType = t.getClass().getSimpleName();
226 sb.append( taskType.replaceAll( "\\$\\$EnhancerByGuice\\$\\$.*", "" ) );
227 separator = ", ";
228 }
229 sb.append( "]" );
230 return sb.toString();
231 }
232 }
233
234 }