Skip to content

Commit 1eb3645

Browse files
committed
working on distributed test automation - snapshot
1 parent 66f09d4 commit 1eb3645

6 files changed

Lines changed: 197 additions & 13 deletions

src/net/sharksystem/ui/messenger/cli/ProductionUI.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ public ProductionUI(String[] args) throws SharkException, IOException {
149149
smUI.addCommand(new UICommandBlock(snmTestSupport, smUI, "block", false));
150150
smUI.addCommand(new UICommandScriptRQ(snmTestSupport, smUI, "scriptRQ", false));
151151
smUI.addCommand(new UICommandRelease(snmTestSupport, smUI, "release", false));
152+
smUI.addCommand(new UICommandOrchestrateTest(snmTestSupport, smUI, "orchestrateTest", false));
152153

153154
smUI.addCommand(new UICommandSaveLog(sharkMessengerApp, smUI, "saveLog", false));
154155
smUI.addCommand(new UICommandShowLog(sharkMessengerApp, smUI, "showLog", false));

src/net/sharksystem/ui/messenger/cli/SNMDistributedTestsMessageReceivedListener.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ public void run() {
2323
}
2424
}).start();
2525
}
26+
else if(uri.toString().equalsIgnoreCase(
27+
SharkNetMessengerAppSupportingDistributedTesting.SCRIPT_RQ_CHANNEL.toString())) {
28+
new Thread(new Runnable() {
29+
@Override
30+
public void run() {
31+
SNMDistributedTestsMessageReceivedListener.this.sharkMessengerAppTestingVersion.
32+
scriptRQReceived(SharkNetMessengerAppSupportingDistributedTesting.SCRIPT_RQ_CHANNEL);
33+
}
34+
}).start();
35+
}
2636
}
2737

2838
}

src/net/sharksystem/ui/messenger/cli/SharkNetMessengerAppSupportingDistributedTesting.java

Lines changed: 135 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,18 @@
66
import net.sharksystem.app.messenger.SharkNetMessengerChannel;
77
import net.sharksystem.app.messenger.SharkNetMessengerException;
88
import net.sharksystem.asap.ASAPException;
9-
import net.sharksystem.ui.messenger.cli.commands.testing.ScriptRQMessage;
9+
import net.sharksystem.ui.messenger.cli.commands.testing.PeerHostingEnvironmentDescription;
1010
import net.sharksystem.utils.SerializationHelper;
1111

1212
import java.io.IOException;
1313
import java.io.PrintStream;
14-
import java.util.ArrayList;
15-
import java.util.HashSet;
16-
import java.util.List;
17-
import java.util.Set;
14+
import java.util.*;
1815

1916
public class SharkNetMessengerAppSupportingDistributedTesting extends SharkNetMessengerApp {
2017
public static final CharSequence TEST_BLOCK_RELEASE_CHANNEL = "snm://block_release";
2118
public static final CharSequence SCRIPT_RQ_CHANNEL = "snm://scriptRQ";
2219
public static final String PEER_HOST_DESCRIPTION_FORMAT = "snm/peerHostDesc";
2320

24-
2521
public SharkNetMessengerAppSupportingDistributedTesting(String peerName, PrintStream out, PrintStream err)
2622
throws SharkException, IOException {
2723
this(peerName, 60*10, out, err);
@@ -39,7 +35,7 @@ public SharkNetMessengerAppSupportingDistributedTesting(String peerName, int syn
3935
public String produceStringForMessage(CharSequence contentType, byte[] content) {
4036
if(contentType.toString().equalsIgnoreCase(PEER_HOST_DESCRIPTION_FORMAT)) {
4137
try {
42-
return new ScriptRQMessage(content).toString();
38+
return new PeerHostingEnvironmentDescription(content).toString();
4339
} catch (IOException | ASAPException e) {
4440
return "known format - malformed content";
4541
}
@@ -48,7 +44,7 @@ public String produceStringForMessage(CharSequence contentType, byte[] content)
4844
}
4945

5046
/////////////////////////////////////////////////////////////////////////////////////////////
51-
// test support //
47+
// block / release //
5248
/////////////////////////////////////////////////////////////////////////////////////////////
5349
private Set<String> receivedLabels = new HashSet<>(); // more instances of the same label has no specific semantics
5450
private List<Thread> blockedThreads = new ArrayList<>(); // a thread can wait for more labels - useful or not
@@ -94,4 +90,135 @@ void releaseReceived(CharSequence releaseChannelURI) {
9490
this.tellUIError(e.getLocalizedMessage());
9591
}
9692
}
93+
94+
/////////////////////////////////////////////////////////////////////////////////////////////
95+
// test orchestration //
96+
/////////////////////////////////////////////////////////////////////////////////////////////
97+
98+
private Map<String, PeerHostingEnvironmentDescription> availablePeers = new HashMap<>();
99+
100+
private class OrchestratedTest {
101+
List<PeerHostingEnvironmentDescription> requiredPeerEnvironment;
102+
List<String> scripts;
103+
OrchestratedTest(List<PeerHostingEnvironmentDescription> requiredPeerEnvironment, List<String> scripts) {
104+
this.requiredPeerEnvironment = requiredPeerEnvironment;
105+
this.scripts = scripts;
106+
}
107+
}
108+
109+
private List<OrchestratedTest> orchestratedTestsWaiting = new ArrayList<>();
110+
private List<OrchestratedTest> orchestratedTestsInLaunch = new ArrayList<>();
111+
112+
public void orchestrateTest(List<PeerHostingEnvironmentDescription> requiredPeerEnvironment, List<String> scripts) {
113+
this.orchestratedTestsWaiting.add(new OrchestratedTest(requiredPeerEnvironment, scripts));
114+
}
115+
116+
private int lastScriptRQIndex = -1;
117+
public void scriptRQReceived(CharSequence scriptRQChannel) {
118+
this.tellUI("ScriptRQ reached");
119+
synchronized (this) {
120+
try {
121+
SharkNetMessageList rqMessages =
122+
this.getSharkMessengerComponent().getChannel(scriptRQChannel).getMessages();
123+
for (int rqIndex = this.lastScriptRQIndex + 1; rqIndex < rqMessages.size(); rqIndex++) {
124+
this.lastScriptRQIndex = rqIndex; // update each round - before possible exceptions
125+
126+
SharkNetMessage rqSharkMessage = rqMessages.getSharkMessage(rqIndex, true);
127+
PeerHostingEnvironmentDescription peerHostDescription =
128+
new PeerHostingEnvironmentDescription(rqSharkMessage.getContent());
129+
130+
// add or replace information
131+
this.availablePeers.put(peerHostDescription.ipAddress, peerHostDescription);
132+
133+
// try to set up a test(s).
134+
this.stageTests();
135+
}
136+
} catch (SharkNetMessengerException | IOException | ASAPException e) {
137+
this.tellUIError("problems handling script RQ channel: " + e.getLocalizedMessage());
138+
}
139+
}
140+
}
141+
142+
private void stageTests() {
143+
TestEnsemble testEnsemble = null;
144+
do {
145+
testEnsemble = this.findFittingPeers();
146+
if (testEnsemble != null) {
147+
// we found an ensemble to run that test
148+
this.orchestratedTestsInLaunch.add(
149+
this.orchestratedTestsWaiting.get(testEnsemble.waitingTestIndex));
150+
151+
// TODO - does not work - why?
152+
this.orchestratedTestsWaiting.remove(testEnsemble.waitingTestIndex);
153+
154+
// make peers unavailable
155+
for(int i = 0; i < testEnsemble.peerIPAddresses.length; i++) {
156+
this.availablePeers.remove(testEnsemble.peerIPAddresses[i]);
157+
}
158+
}
159+
} while(testEnsemble != null); // do again until there is not further match
160+
161+
if(!this.orchestratedTestsInLaunch.isEmpty()) {
162+
// launch tests
163+
System.out.println("TODO: launch tests");
164+
}
165+
}
166+
167+
private class TestEnsemble {
168+
final Integer waitingTestIndex;
169+
final String[] peerIPAddresses;
170+
171+
TestEnsemble(Integer waitingTestIndex, String[] peerIPAddresses) {
172+
this.waitingTestIndex = waitingTestIndex;
173+
this.peerIPAddresses = peerIPAddresses;
174+
}
175+
}
176+
177+
// find fitting peers for any test - return null or waiting test index + list of ipAddresses of fitting peers
178+
private TestEnsemble findFittingPeers() {
179+
synchronized (this) {
180+
// walk through waiting tests - order of their appearance
181+
int waitingTestIndex = -1;
182+
for (OrchestratedTest waitingTest : this.orchestratedTestsWaiting) {
183+
waitingTestIndex++;
184+
// walk through required environments
185+
for (PeerHostingEnvironmentDescription requiredEnvironment : waitingTest.requiredPeerEnvironment) {
186+
// we need exactly that number of peers - underlined by using an array.
187+
String[] fittingPeers = new String[waitingTest.requiredPeerEnvironment.size()];
188+
int fittingPeerIndex = 0;
189+
190+
// let's walk through available peers to look for a match
191+
for (String ipAdress : this.availablePeers.keySet()) {
192+
PeerHostingEnvironmentDescription availableEnvironment = this.availablePeers.get(ipAdress);
193+
// match?
194+
boolean match = true;
195+
196+
// os required? if so - does available environment match?
197+
if (requiredEnvironment.osName != null && !requiredEnvironment.osName.isEmpty()) {
198+
if (!requiredEnvironment.osName.equalsIgnoreCase(availableEnvironment.osName)) {
199+
match = false;
200+
}
201+
}
202+
// version required? if so - does available environment match?
203+
if(match && requiredEnvironment.osVersion != null && !requiredEnvironment.osVersion.isEmpty()) {
204+
if (!requiredEnvironment.osVersion.equalsIgnoreCase(availableEnvironment.osVersion)) {
205+
match = false;
206+
}
207+
}
208+
209+
// found a fitting peer ?
210+
if(match) {
211+
// indeed - found one
212+
fittingPeers[fittingPeerIndex++] = ipAdress;
213+
if(fittingPeerIndex == fittingPeers.length) {
214+
// we have all required peers - done here.
215+
return new TestEnsemble(waitingTestIndex, fittingPeers);
216+
}
217+
}
218+
}
219+
}
220+
}
221+
}
222+
return null;
223+
}
97224
}

src/net/sharksystem/ui/messenger/cli/commands/testing/ScriptRQMessage.java renamed to src/net/sharksystem/ui/messenger/cli/commands/testing/PeerHostingEnvironmentDescription.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@
77
import java.io.ByteArrayOutputStream;
88
import java.io.IOException;
99

10-
public class ScriptRQMessage {
10+
public class PeerHostingEnvironmentDescription {
1111
public final String ipAddress;
1212
public final String osName;
1313
public final String osVersion;
1414

15-
ScriptRQMessage(String ipAddress, String osName, String osVersion) {
15+
PeerHostingEnvironmentDescription(String ipAddress, String osName, String osVersion) {
1616
this.ipAddress = ipAddress;
1717
this.osName = osName;
1818
this.osVersion = osVersion;
1919
}
2020

21-
public ScriptRQMessage(byte[] serializedMessage) throws IOException, ASAPException {
21+
public PeerHostingEnvironmentDescription(byte[] serializedMessage) throws IOException, ASAPException {
2222
ByteArrayInputStream bais = new ByteArrayInputStream(serializedMessage);
2323

2424
this.ipAddress = ASAPSerialization.readCharSequenceParameter(bais);
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package net.sharksystem.ui.messenger.cli.commands.testing;
2+
3+
import net.sharksystem.ui.messenger.cli.SharkNetMessengerApp;
4+
import net.sharksystem.ui.messenger.cli.SharkNetMessengerAppSupportingDistributedTesting;
5+
import net.sharksystem.ui.messenger.cli.SharkNetMessengerUI;
6+
import net.sharksystem.ui.messenger.cli.commands.helper.AbstractCommandWithSingleString;
7+
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
11+
public class UICommandOrchestrateTest extends AbstractCommandWithSingleString {
12+
SharkNetMessengerAppSupportingDistributedTesting snmTestSupport;
13+
14+
public UICommandOrchestrateTest(SharkNetMessengerAppSupportingDistributedTesting sharkMessengerApp, SharkNetMessengerUI smUI, String echo, boolean b) {
15+
super(sharkMessengerApp, smUI, echo, b);
16+
this.snmTestSupport = sharkMessengerApp;
17+
}
18+
19+
@Override
20+
protected void execute() throws Exception {
21+
/* need:
22+
* peers willing to run scripts
23+
* script for each peer
24+
*/
25+
26+
// Alice: orchestrateTest dummy; openTCP 9999
27+
// dann Bob: connectTCP localhost 9999; scriptRQ
28+
29+
List<PeerHostingEnvironmentDescription> requiredPeerEnvironment = new ArrayList<>();
30+
List<String> scripts = new ArrayList<>();
31+
32+
// fill with example data
33+
this.getSharkMessengerApp().tellUI("use sample data - todo: fill with real data");
34+
// anything will do
35+
requiredPeerEnvironment.add(new PeerHostingEnvironmentDescription(null, null, null));
36+
scripts.add("markstep RUN_TEST_:)");
37+
38+
this.snmTestSupport.orchestrateTest(requiredPeerEnvironment, scripts);
39+
40+
this.getSharkMessengerApp().tellUI("test is to be orchestrated");
41+
}
42+
43+
@Override
44+
public String getDescription() {
45+
return "orchestrate test scenario";
46+
}
47+
}

src/net/sharksystem/ui/messenger/cli/commands/testing/UICommandScriptRQ.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package net.sharksystem.ui.messenger.cli.commands.testing;
22

33
import net.sharksystem.SharkException;
4-
import net.sharksystem.app.messenger.SharkNetMessage;
54
import net.sharksystem.app.messenger.SharkNetMessengerComponent;
65
import net.sharksystem.ui.messenger.cli.SharkNetMessengerAppSupportingDistributedTesting;
76
import net.sharksystem.ui.messenger.cli.SharkNetMessengerUI;
@@ -29,7 +28,7 @@ protected void execute() throws Exception {
2928
SharkNetMessengerComponent messenger = this.getSharkMessengerApp().getSharkMessengerComponent();
3029

3130
// collect information
32-
ScriptRQMessage scriptRQMessage = new ScriptRQMessage(
31+
PeerHostingEnvironmentDescription scriptRQMessage = new PeerHostingEnvironmentDescription(
3332
InetAddress.getLocalHost().getHostAddress(), // IP Adresse
3433
System.getProperty("os.name"), // os name
3534
System.getProperty("os.version") // os version

0 commit comments

Comments
 (0)