66import net .sharksystem .app .messenger .SharkNetMessengerChannel ;
77import net .sharksystem .app .messenger .SharkNetMessengerException ;
88import net .sharksystem .asap .ASAPException ;
9- import net .sharksystem .ui .messenger .cli .commands .testing .ScriptRQMessage ;
9+ import net .sharksystem .ui .messenger .cli .commands .testing .PeerHostingEnvironmentDescription ;
1010import net .sharksystem .utils .SerializationHelper ;
1111
1212import java .io .IOException ;
1313import 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
1916public 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}
0 commit comments