Skip to content

Commit bd314bf

Browse files
committed
improve test / mocking support
1 parent abe2df7 commit bd314bf

File tree

3 files changed

+207
-35
lines changed

3 files changed

+207
-35
lines changed

src/net/sharksystem/asap/apps/mock/ASAPSessionMock.java renamed to src/net/sharksystem/asap/apps/mock/ASAPPeerMock.java

Lines changed: 122 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package net.sharksystem.asap.apps.mock;
22

3+
import net.sharksystem.asap.ASAP;
34
import net.sharksystem.asap.ASAPException;
45
import net.sharksystem.asap.ASAPMessages;
56
import net.sharksystem.asap.apps.*;
@@ -8,28 +9,107 @@
89

910
import java.util.*;
1011

11-
public class ASAPSessionMock implements ASAPPeerServices {
12+
/**
13+
* This class mocks an ASAPApplication. The ASAP protocol stack is bypassed completely. You can
14+
* test your applications logic without any fear of ASAP bugs.
15+
*
16+
*/
17+
public class ASAPPeerMock implements ASAPPeerServices {
18+
private final CharSequence peerName;
1219
private boolean connected = false;
1320

14-
/**
15-
* Simulate a connection - this mock will notify all registered listeners and remove messages.
16-
* After connected - any sendASAPMessage call will immediately lead to a listener call.
17-
*/
18-
public void connect() {
19-
this.connected = true;
20-
this.notifyMessageReceived();
21+
public ASAPPeerMock(CharSequence peerName) {
22+
this.peerName = peerName;
2123
}
2224

23-
/**
24-
* disconnect - opposite of connect
25-
*/
26-
public void disconnect() {
27-
this.connected = false;
25+
public ASAPPeerMock() {
26+
this(ASAP.createUniqueID());
27+
}
28+
29+
////////////////////////////////////////////////////////////////////////////////////////////////////////
30+
// Encounter simulation //
31+
////////////////////////////////////////////////////////////////////////////////////////////////////////
32+
33+
/** peer name, era of last encounter */
34+
private HashMap<CharSequence, Integer> encounterEra = new HashMap<>();
35+
private int currentEra = ASAP.INITIAL_ERA;
36+
37+
private void newEra() {
38+
synchronized(this.appMsgStorage) {
39+
if(!this.appMsgStorage.isEmpty()) {
40+
this.log("messages were stored in this era");
41+
this.currentEra = ASAP.nextEra(this.currentEra);
42+
this.log("we enter a new era: " + this.currentEra);
43+
this.previousErasMsgStorage.add(this.appMsgStorage);
44+
this.appMsgStorage = new HashMap<>();
45+
} else {
46+
this.log("no new messages - era remains unchanged: " + this.currentEra);
47+
}
48+
}
49+
}
50+
51+
public void startEncounter(ASAPPeerMock otherPeer) {
52+
this.startEncounter(otherPeer, true);
53+
}
54+
55+
private void startEncounter(ASAPPeerMock otherPeer, boolean callOtherSide) {
56+
this.log("start simulation of encounter with: " + otherPeer.getPeerName());
57+
58+
this.newEra();
59+
60+
// already met this peer?
61+
Integer lastMetEra = this.encounterEra.get(otherPeer.getPeerName());
62+
if(lastMetEra == null) { // never met
63+
this.log("never met before: " + otherPeer.getPeerName());
64+
lastMetEra = ASAP.INITIAL_ERA;
65+
} else {
66+
this.log("last encounter: " + otherPeer.getPeerName() + " | " + lastMetEra);
67+
}
68+
69+
// remember this encounter
70+
this.encounterEra.put(otherPeer.getPeerName(), this.currentEra);
71+
72+
// simulate message sending
73+
for(int tmpEra = lastMetEra; tmpEra < this.currentEra; tmpEra++) {
74+
otherPeer.takeMessages(this, tmpEra, this.previousErasMsgStorage.get(tmpEra));
75+
}
76+
77+
if(callOtherSide) {
78+
otherPeer.startEncounter(this, false);
79+
}
80+
}
81+
82+
private void takeMessages(ASAPPeerMock asapPeerMock, int tmpEra, Map<CharSequence, Map<CharSequence, List<byte[]>>> appMessages) {
83+
if(appMessages != null && !appMessages.isEmpty()) {
84+
this.log("handle received messages (sender | era): " + asapPeerMock.getPeerName() + " | " + tmpEra);
85+
this.notifyMessagesReceived(appMessages);
86+
}
87+
}
88+
89+
private CharSequence getPeerName() {
90+
return this.peerName;
91+
}
92+
93+
public void stopEncounter(ASAPPeerMock otherPeer) {
94+
this.stopEncounter(otherPeer, true);
95+
}
96+
97+
public void stopEncounter(ASAPPeerMock otherPeer, boolean callOtherSide) {
98+
this.log("stop encounter with " + otherPeer.getPeerName());
99+
this.newEra();
100+
if(callOtherSide) {
101+
otherPeer.stopEncounter(this, false);
102+
}
28103
}
29104

30105
////////////////////////////////////////////////////////////////////////////////////////////////////////
31106
// ASAPMessageManagement //
32107
////////////////////////////////////////////////////////////////////////////////////////////////////////
108+
109+
/** appName, <uri, messageBytes> */
110+
private List< Map<CharSequence, Map<CharSequence, List<byte[]> > > > previousErasMsgStorage = new ArrayList<>();
111+
112+
/** appName, <uri, messageBytes> */
33113
private Map<CharSequence, Map<CharSequence, List<byte[]>>> appMsgStorage = new HashMap<>();
34114

35115
private List<byte[]> getStorage(CharSequence appName, CharSequence uri) {
@@ -68,6 +148,21 @@ public void addASAPMessageReceivedListener(CharSequence format, ASAPMessageRecei
68148
this.asapMessageReceivedListenerManager.addASAPMessageReceivedListener(format, listener);
69149
}
70150

151+
private void notifyMessagesReceived(Map<CharSequence, Map<CharSequence, List<byte[]>>> appUriMessages) {
152+
// notify about new messages == simulate sending
153+
for(CharSequence appName : appUriMessages.keySet()) {
154+
Map<CharSequence, List<byte[]>> appMap = appUriMessages.get(appName);
155+
if(appMap != null) {
156+
Set<CharSequence> uris = appMap.keySet();
157+
for(CharSequence uri : uris) {
158+
List<byte[]> serializedAppPDUs = appMap.get(uri);
159+
ASAPMessages messagesMock = new ASAPMessagesMock(appName, uri, serializedAppPDUs);
160+
this.asapMessageReceivedListenerManager.notifyReceived(appName, messagesMock, true);
161+
}
162+
}
163+
}
164+
}
165+
71166
private void notifyMessageReceived() {
72167
Map<CharSequence, Map<CharSequence, List<byte[]>>> appUriMessages = null;
73168
synchronized(this.appMsgStorage) {
@@ -81,17 +176,7 @@ private void notifyMessageReceived() {
81176
}
82177

83178
// notify about new messages == simulate sending
84-
for(CharSequence appName : appUriMessages.keySet()) {
85-
Map<CharSequence, List<byte[]>> appMap = appUriMessages.get(appName);
86-
if(appMap != null) {
87-
Set<CharSequence> uris = appMap.keySet();
88-
for(CharSequence uri : uris) {
89-
List<byte[]> serializedAppPDUs = appMap.get(uri);
90-
ASAPMessages messagesMock = new ASAPMessagesMock(appName, uri, serializedAppPDUs);
91-
this.asapMessageReceivedListenerManager.notifyReceived(appName, messagesMock, true);
92-
}
93-
}
94-
}
179+
this.notifyMessagesReceived(appUriMessages);
95180
}
96181

97182
////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -110,4 +195,17 @@ public void addASAPEnvironmentChangesListener(ASAPEnvironmentChangesListener cha
110195
public void removeASAPEnvironmentChangesListener(ASAPEnvironmentChangesListener changesListener) {
111196
this.environmentChangesListenerManager.removeASAPEnvironmentChangesListener(changesListener);
112197
}
198+
199+
////////////////////////////////////////////////////////////////////////////////////////////////////////
200+
// util //
201+
////////////////////////////////////////////////////////////////////////////////////////////////////////
202+
203+
private void log(String msg) {
204+
StringBuilder sb = new StringBuilder();
205+
sb.append(this.peerName);
206+
sb.append(": ");
207+
sb.append(msg);
208+
209+
System.out.println(sb.toString());
210+
}
113211
}

src/net/sharksystem/asap/listenermanager/ASAPMessageReceivedListenerManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public void addASAPMessageReceivedListener(CharSequence format, ASAPMessageRecei
1616
GenericListenerImplementation<ASAPMessageReceivedListener> listenerList = this.listenerMap.get(format);
1717
if(listenerList == null) {
1818
listenerList = new GenericListenerImplementation<ASAPMessageReceivedListener>();
19+
this.listenerMap.put(format, listenerList);
1920
}
2021

2122
listenerList.addListener(listener);

test/net/sharksystem/asap/mock/ASAPMockUsage.java

Lines changed: 84 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import net.sharksystem.asap.ASAPMessages;
55
import net.sharksystem.asap.apps.ASAPMessageSender;
66
import net.sharksystem.asap.apps.ASAPMessageReceivedListener;
7-
import net.sharksystem.asap.apps.mock.ASAPSessionMock;
7+
import net.sharksystem.asap.apps.mock.ASAPPeerMock;
88
import org.junit.Test;
99

1010
import java.io.*;
@@ -14,7 +14,8 @@
1414
* How to mock ASAP communication
1515
*/
1616
public class ASAPMockUsage {
17-
17+
private static final CharSequence ALICE = "Alice";
18+
private static final CharSequence BOB = "Bob";
1819
private static final CharSequence YOUR_APP_NAME = "yourAppName";
1920
private static final CharSequence YOUR_URI = "yourSchema://example";
2021

@@ -55,19 +56,17 @@ private static void deserializeExample(byte[] serializedData) throws IOException
5556
System.out.println("received: " + exampleLong + " | " + exampleString + " | " + exampleBoolean);
5657
}
5758

59+
/* I'm sorry. I changed mock implementation - it closer to the real implementation now, see usageTest2
5860
@Test
5961
public void usageTest1() throws IOException, ASAPException, InterruptedException {
60-
/* Imagine we are here inside your application code. Data are to be transmitted. You implemented
61-
a methode that serializes your data (PDU) into an array of bytes
62-
*/
6362
6463
// example - this should be produced by your application
6564
byte[] serializedData = ASAPMockUsage.serializeExample(42, "don't panic", true);
6665
6766
// now: ASAP is used to deliver those data - we mock it
68-
ASAPSessionMock asapSessionMock = new ASAPSessionMock();
67+
ASAPPeerMock asapPeerMock = new ASAPPeerMock();
6968
70-
ASAPMessageSender asapMessageSender = asapSessionMock;
69+
ASAPMessageSender asapMessageSender = asapPeerMock;
7170
7271
asapMessageSender.sendASAPMessage(YOUR_APP_NAME, YOUR_URI, serializedData);
7372
@@ -78,10 +77,10 @@ a methode that serializes your data (PDU) into an array of bytes
7877
new ASAPMessageReceivedListenerExample();
7978
8079
// register your listener (or that mock) with asap connection mock
81-
asapSessionMock.addASAPMessageReceivedListener(YOUR_APP_NAME, asapMessageReceivedListenerExample);
80+
asapPeerMock.addASAPMessageReceivedListener(YOUR_APP_NAME, asapMessageReceivedListenerExample);
8281
8382
// simulate ASAP encounter
84-
asapSessionMock.connect();
83+
asapPeerMock.connect();
8584
8685
// give your app a moment to process
8786
Thread.sleep(1000);
@@ -90,7 +89,7 @@ a methode that serializes your data (PDU) into an array of bytes
9089
asapMessageSender.sendASAPMessage(YOUR_APP_NAME, YOUR_URI,
9190
ASAPMockUsage.serializeExample(43, "second message", false));
9291
93-
asapSessionMock.disconnect();
92+
asapPeerMock.disconnect();
9493
System.out.println("send message without connection");
9594
asapMessageSender.sendASAPMessage(YOUR_APP_NAME, YOUR_URI,
9695
ASAPMockUsage.serializeExample(44, "third message", false));
@@ -99,15 +98,89 @@ a methode that serializes your data (PDU) into an array of bytes
9998
Thread.sleep(1000);
10099
101100
System.out.println("re-connect");
102-
asapSessionMock.connect();
101+
asapPeerMock.connect();
102+
Thread.sleep(1000);
103+
}
104+
*/
105+
106+
@Test
107+
public void usageTest2() throws IOException, ASAPException, InterruptedException {
108+
///////////////// ALICE //////////////////////////////////////////////////////////////
109+
// setup mocked peer / asap application and activity in android
110+
ASAPPeerMock alicePeerMock = new ASAPPeerMock(ALICE);
111+
ASAPMessageSender aliceMessageSender = alicePeerMock;
112+
113+
// setup message received listener - this should be replaced with your code - you implement a listener.
114+
ASAPMessageReceivedListenerExample aliceMessageReceivedListenerExample =
115+
new ASAPMessageReceivedListenerExample();
116+
117+
alicePeerMock.addASAPMessageReceivedListener(YOUR_APP_NAME, aliceMessageReceivedListenerExample);
118+
119+
// example - this should be produced by your application
120+
byte[] serializedData = ASAPMockUsage.serializeExample(42, "from alice", true);
121+
122+
aliceMessageSender.sendASAPMessage(YOUR_APP_NAME, YOUR_URI, serializedData);
123+
124+
///////////////// BOB //////////////////////////////////////////////////////////////
125+
// listens
126+
ASAPPeerMock bobPeerMock = new ASAPPeerMock(BOB);
127+
128+
// this should be replaced with your code - you must implement a listener.
129+
ASAPMessageReceivedListenerExample asapMessageReceivedListenerExample =
130+
new ASAPMessageReceivedListenerExample();
131+
132+
// register your listener (or that mock) with asap connection mock
133+
bobPeerMock.addASAPMessageReceivedListener(YOUR_APP_NAME, asapMessageReceivedListenerExample);
134+
135+
// bob writes something
136+
bobPeerMock.sendASAPMessage(YOUR_APP_NAME, YOUR_URI,
137+
ASAPMockUsage.serializeExample(43, "from bob", false));
138+
bobPeerMock.sendASAPMessage(YOUR_APP_NAME, YOUR_URI,
139+
ASAPMockUsage.serializeExample(44, "from bob again", false));
140+
141+
// simulate ASAP first encounter
142+
System.out.println("+++++++++++++++++++ 1st encounter starts soon ++++++++++++++++++++");
143+
Thread.sleep(50);
144+
alicePeerMock.startEncounter(bobPeerMock);
145+
146+
// give your app a moment to process
147+
Thread.sleep(1000);
148+
149+
// stop encounter
150+
bobPeerMock.stopEncounter(alicePeerMock);
151+
152+
// bob writes something
153+
bobPeerMock.sendASAPMessage(YOUR_APP_NAME, YOUR_URI,
154+
ASAPMockUsage.serializeExample(43, "third message from bob", false));
155+
156+
// simulate second encounter
157+
System.out.println("+++++++++++++++++++ 2nd encounter starts soon ++++++++++++++++++++");
158+
Thread.sleep(50);
159+
alicePeerMock.startEncounter(bobPeerMock);
160+
161+
// give your app a moment to process
103162
Thread.sleep(1000);
104163
}
105164

106165
private class ASAPMessageReceivedListenerExample implements ASAPMessageReceivedListener {
166+
private final String peerName;
167+
168+
ASAPMessageReceivedListenerExample(String peerName) {
169+
this.peerName = peerName;
170+
}
171+
172+
ASAPMessageReceivedListenerExample() {
173+
this(null);
174+
}
175+
107176
@Override
108177
public void asapMessagesReceived(ASAPMessages messages) throws IOException {
109178
CharSequence format = messages.getFormat();
110179
CharSequence uri = messages.getURI();
180+
if(peerName != null) {
181+
System.out.print(peerName);
182+
}
183+
111184
System.out.println("asap message received (" + format + " | " + uri + "). size == " + messages.size());
112185
Iterator<byte[]> yourPDUIter = messages.getMessages();
113186
while (yourPDUIter.hasNext()) {

0 commit comments

Comments
 (0)