Skip to content

Commit 92aabc5

Browse files
committed
Cleanup state after future has completed - tests
- Fix and improve tests (cherry picked from commit 6179a4e2530e432c867a28a32d58bcfe5d639a91)
1 parent 03b8a2a commit 92aabc5

File tree

2 files changed

+167
-11
lines changed

2 files changed

+167
-11
lines changed

ocpp-common/src/test/java/eu/chargetime/ocpp/test/ClientTest.java

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,30 @@ of this software and associated documentation files (the "Software"), to deal
2626
SOFTWARE.
2727
*/
2828

29-
import static org.hamcrest.CoreMatchers.instanceOf;
30-
import static org.junit.Assert.assertThat;
31-
import static org.mockito.Mockito.*;
32-
3329
import eu.chargetime.ocpp.*;
3430
import eu.chargetime.ocpp.feature.Feature;
3531
import eu.chargetime.ocpp.model.Confirmation;
3632
import eu.chargetime.ocpp.model.Request;
3733
import eu.chargetime.ocpp.model.TestConfirmation;
38-
import java.util.Optional;
39-
import java.util.concurrent.CompletableFuture;
4034
import org.junit.Before;
4135
import org.junit.Test;
4236
import org.junit.runner.RunWith;
4337
import org.mockito.Mock;
4438
import org.mockito.junit.MockitoJUnitRunner;
4539

40+
import java.util.Optional;
41+
import java.util.UUID;
42+
import java.util.concurrent.CompletableFuture;
43+
import java.util.concurrent.ExecutionException;
44+
import java.util.concurrent.TimeUnit;
45+
import java.util.concurrent.TimeoutException;
46+
47+
import static org.hamcrest.CoreMatchers.*;
48+
import static org.hamcrest.MatcherAssert.assertThat;
49+
import static org.junit.Assert.assertThrows;
50+
import static org.mockito.Mockito.any;
51+
import static org.mockito.Mockito.*;
52+
4653
@RunWith(MockitoJUnitRunner.class)
4754
public class ClientTest {
4855
private Client client;
@@ -63,8 +70,10 @@ public void setup() {
6370
.when(session)
6471
.open(any(), any());
6572

73+
when(promiseRepository.createPromise(any())).then(invocation -> new CompletableFuture<Confirmation>());
6674
when(featureRepository.findFeature(any())).thenReturn(Optional.of(feature));
6775
when(session.getFeatureRepository()).thenReturn(featureRepository);
76+
when(session.storeRequest(any())).then(invocation -> UUID.randomUUID().toString());
6877
client = new Client(session, promiseRepository);
6978
}
7079

@@ -164,4 +173,68 @@ public void send_aMessage_validatesMessage() throws Exception {
164173
// Then
165174
verify(request, times(1)).validate();
166175
}
176+
177+
@Test
178+
public void send_aMessage_promiseCompletes() throws Exception {
179+
// Given
180+
CompletableFuture<Confirmation> internalFuture = new CompletableFuture<>();
181+
when(promiseRepository.createPromise(any())).thenReturn(internalFuture);
182+
183+
// When
184+
CompletableFuture<Confirmation> returnedFuture = client.send(request);
185+
TestConfirmation confirmation = new TestConfirmation();
186+
internalFuture.complete(confirmation);
187+
188+
// Then
189+
assertThat(returnedFuture, is(internalFuture));
190+
assertThat(returnedFuture.isDone(), is(true));
191+
assertThat(returnedFuture.get(), is(confirmation));
192+
verify(session, times(1)).removeRequest(any());
193+
verify(promiseRepository, times(1)).removePromise(any());
194+
}
195+
196+
@Test
197+
public void send_aMessage_promiseCompletesExceptionally() throws Exception {
198+
// Given
199+
CompletableFuture<Confirmation> internalFuture = new CompletableFuture<>();
200+
when(promiseRepository.createPromise(any())).thenReturn(internalFuture);
201+
202+
// When
203+
CompletableFuture<Confirmation> returnedFuture = client.send(request);
204+
internalFuture.completeExceptionally(new IllegalStateException());
205+
206+
// Then
207+
assertThat(returnedFuture, is(internalFuture));
208+
assertThat(returnedFuture.isDone(), is(true));
209+
assertThat(returnedFuture.isCompletedExceptionally(), is(true));
210+
ExecutionException executionException = assertThrows(ExecutionException.class, returnedFuture::get);
211+
assertThat(executionException.getCause().getClass(), is(equalTo(IllegalStateException.class)));
212+
verify(session, times(1)).removeRequest(any());
213+
verify(promiseRepository, times(1)).removePromise(any());
214+
}
215+
216+
@Test
217+
public void send_aMessage_promiseCompletesWithTimeout() throws Exception {
218+
// Given
219+
CompletableFuture<Confirmation> internalFuture = new CompletableFuture<>();
220+
when(promiseRepository.createPromise(any())).thenReturn(internalFuture);
221+
222+
// When
223+
CompletableFuture<Confirmation> returnedFuture = client.send(request);
224+
// If the client uses at least Java 9, it could use CompletableFuture::orTimeout(..) ..
225+
returnedFuture.orTimeout(50, TimeUnit.MILLISECONDS);
226+
assertThat(returnedFuture.isDone(), is(false));
227+
Thread.sleep(100);
228+
// .. alternatively, it can be implemented manually
229+
// returnedFuture.completeExceptionally(new TimeoutException());
230+
231+
// Then
232+
assertThat(returnedFuture, is(internalFuture));
233+
assertThat(returnedFuture.isDone(), is(true));
234+
assertThat(returnedFuture.isCompletedExceptionally(), is(true));
235+
ExecutionException executionException = assertThrows(ExecutionException.class, returnedFuture::get);
236+
assertThat(executionException.getCause().getClass(), is(equalTo(TimeoutException.class)));
237+
verify(session, times(1)).removeRequest(any());
238+
verify(promiseRepository, times(1)).removePromise(any());
239+
}
167240
}

ocpp-common/src/test/java/eu/chargetime/ocpp/test/ServerTest.java

Lines changed: 88 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,30 @@
11
package eu.chargetime.ocpp.test;
22

3-
import static org.mockito.Mockito.*;
4-
53
import eu.chargetime.ocpp.*;
64
import eu.chargetime.ocpp.feature.Feature;
5+
import eu.chargetime.ocpp.model.Confirmation;
76
import eu.chargetime.ocpp.model.Request;
87
import eu.chargetime.ocpp.model.SessionInformation;
9-
import java.util.Optional;
10-
import java.util.UUID;
8+
import eu.chargetime.ocpp.model.TestConfirmation;
119
import org.junit.Before;
1210
import org.junit.Test;
1311
import org.junit.runner.RunWith;
1412
import org.mockito.Mock;
1513
import org.mockito.junit.MockitoJUnitRunner;
1614

15+
import java.util.Optional;
16+
import java.util.UUID;
17+
import java.util.concurrent.CompletableFuture;
18+
import java.util.concurrent.ExecutionException;
19+
import java.util.concurrent.TimeUnit;
20+
import java.util.concurrent.TimeoutException;
21+
22+
import static org.hamcrest.CoreMatchers.equalTo;
23+
import static org.hamcrest.CoreMatchers.is;
24+
import static org.hamcrest.MatcherAssert.assertThat;
25+
import static org.junit.Assert.assertThrows;
26+
import static org.mockito.Mockito.*;
27+
1728
/*
1829
ChargeTime.eu - Java-OCA-OCPP
1930
@@ -58,7 +69,7 @@ public class ServerTest {
5869
@Mock private Request request;
5970
@Mock private SessionInformation information;
6071
@Mock private IFeatureRepository featureRepository;
61-
@Mock private IPromiseRepository promiseRepository;
72+
@Mock IPromiseRepository promiseRepository;
6273

6374
@Before
6475
public void setup() {
@@ -75,8 +86,10 @@ public void setup() {
7586
.when(serverEvents)
7687
.newSession(any(), any());
7788

89+
when(promiseRepository.createPromise(any())).then(invocation -> new CompletableFuture<Confirmation>());
7890
when(featureRepository.findFeature(any())).thenReturn(Optional.of(feature));
7991
when(session.getFeatureRepository()).thenReturn(featureRepository);
92+
when(session.storeRequest(any())).thenAnswer(invocation -> UUID.randomUUID().toString());
8093
server = new Server(listener, promiseRepository);
8194
}
8295

@@ -143,4 +156,74 @@ public void send_aMessage_validatesMessage() throws Exception {
143156
// Then
144157
verify(request, times(1)).validate();
145158
}
159+
160+
@Test
161+
public void send_aMessage_promiseCompletes() throws Exception {
162+
// Given
163+
server.open(LOCALHOST, PORT, serverEvents);
164+
listenerEvents.newSession(session, information);
165+
CompletableFuture<Confirmation> internalFuture = new CompletableFuture<>();
166+
when(promiseRepository.createPromise(any())).thenReturn(internalFuture);
167+
168+
// When
169+
CompletableFuture<Confirmation> returnedFuture = server.send(sessionIndex, request);
170+
TestConfirmation confirmation = new TestConfirmation();
171+
internalFuture.complete(confirmation);
172+
173+
// Then
174+
assertThat(returnedFuture, is(internalFuture));
175+
assertThat(returnedFuture.isDone(), is(true));
176+
assertThat(returnedFuture.get(), is(confirmation));
177+
verify(session, times(1)).removeRequest(any());
178+
verify(promiseRepository, times(1)).removePromise(any());
179+
}
180+
181+
@Test
182+
public void send_aMessage_promiseCompletesExceptionally() throws Exception {
183+
// Given
184+
server.open(LOCALHOST, PORT, serverEvents);
185+
listenerEvents.newSession(session, information);
186+
CompletableFuture<Confirmation> internalFuture = new CompletableFuture<>();
187+
when(promiseRepository.createPromise(any())).thenReturn(internalFuture);
188+
189+
// When
190+
CompletableFuture<Confirmation> returnedFuture = server.send(sessionIndex, request);
191+
internalFuture.completeExceptionally(new IllegalStateException());
192+
193+
// Then
194+
assertThat(returnedFuture, is(internalFuture));
195+
assertThat(returnedFuture.isDone(), is(true));
196+
assertThat(returnedFuture.isCompletedExceptionally(), is(true));
197+
ExecutionException executionException = assertThrows(ExecutionException.class, returnedFuture::get);
198+
assertThat(executionException.getCause().getClass(), is(equalTo(IllegalStateException.class)));
199+
verify(session, times(1)).removeRequest(any());
200+
verify(promiseRepository, times(1)).removePromise(any());
201+
}
202+
203+
@Test
204+
public void send_aMessage_promiseCompletesWithTimeout() throws Exception {
205+
// Given
206+
server.open(LOCALHOST, PORT, serverEvents);
207+
listenerEvents.newSession(session, information);
208+
CompletableFuture<Confirmation> internalFuture = new CompletableFuture<>();
209+
when(promiseRepository.createPromise(any())).thenReturn(internalFuture);
210+
211+
// When
212+
CompletableFuture<Confirmation> returnedFuture = server.send(sessionIndex, request);
213+
// If the client uses at least Java 9, it could use CompletableFuture::orTimeout(..).
214+
returnedFuture.orTimeout(50, TimeUnit.MILLISECONDS);
215+
assertThat(returnedFuture.isDone(), is(false));
216+
Thread.sleep(100);
217+
// .. alternatively, it can be implemented manually
218+
// returnedFuture.completeExceptionally(new TimeoutException());
219+
220+
// Then
221+
assertThat(returnedFuture, is(internalFuture));
222+
assertThat(returnedFuture.isDone(), is(true));
223+
assertThat(returnedFuture.isCompletedExceptionally(), is(true));
224+
ExecutionException executionException = assertThrows(ExecutionException.class, returnedFuture::get);
225+
assertThat(executionException.getCause().getClass(), is(equalTo(TimeoutException.class)));
226+
verify(session, times(1)).removeRequest(any());
227+
verify(promiseRepository, times(1)).removePromise(any());
228+
}
146229
}

0 commit comments

Comments
 (0)