Open Kilda Java Documentation
TestUtils.java
Go to the documentation of this file.
1 /* Copyright 2017 Telstra Open Source
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package org.openkilda.topo;
17 
18 import static java.lang.String.format;
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.fail;
21 
22 import org.openkilda.KafkaUtils;
26 
27 import com.google.common.base.Charsets;
28 import com.google.common.io.Resources;
29 import com.google.common.util.concurrent.Uninterruptibles;
30 
31 import java.io.IOException;
32 import java.net.URL;
33 import java.util.Set;
34 import java.util.TreeSet;
35 import java.util.concurrent.TimeUnit;
36 
40 public class TestUtils {
41 
42  public static void validateTopos(ITopology expected, ITopology actual) {
43  if (expected.getSwitches().keySet().size() != actual.getSwitches().keySet().size()) {
44  System.out.println("TOPOLOGY DISCOVERY: The number of SWITCHES don't match");
45  System.out.println("expected.getSwitches().keySet() = " + expected.getSwitches().keySet());
46  System.out.println("actual.getSwitches().keySet() = " + actual.getSwitches().keySet());
47 
48  assertEquals(expected.getSwitches().keySet().size()
49  , actual.getSwitches().keySet().size());
50  }
51  assertEquals("TOPOLOGY DISCOVERY: The number of LINKS don't match"
52  , expected.getLinks().keySet().size()
53  , actual.getLinks().keySet().size());
54  assertEquals("TOPOLOGY DISCOVERY: The IDs of SWITCHES don't match"
55  , toUpper(expected.getSwitches().keySet()), toUpper(actual.getSwitches().keySet()));
56  simpleLinkComparison(expected.getLinks().keySet(), actual.getLinks().keySet());
57  }
58 
59  /* ensure everything is uppercase .. useful for testing intent .. would prefer exactness */
60  private static Set<String> toUpper(Set<String> ss) {
61  Set<String> result = new TreeSet<>();
62  for (String s : ss) {
63  result.add(s.toUpperCase());
64  }
65  return result;
66  }
67 
68  private static Set<String> toUpperSubstring(Set<String> ss, int start, int end) {
69  Set<String> result = new TreeSet<>();
70  // break apart src->dst into src and dst, truncate each, then reassemble.
71  for (String s : ss) {
72  String[] trunc = s.toUpperCase().split(TopoSlug.EP_DELIM);
73  trunc[0] = trunc[0].substring(start, end);
74  trunc[1] = trunc[1].substring(start, end);
75  result.add(trunc[0] + TopoSlug.EP_DELIM + trunc[1]);
76  }
77  return result;
78  }
79 
80 
82  private static void simpleLinkComparison(Set<String> expected, Set<String> actual) {
83  // TODO: remove this comparison once port/queue info is used universally
84  String[] s1 = toUpperSubstring(expected, 0, 23).toArray(new String[expected.size()]); // upper case and sorted
85  String[] s2 = toUpperSubstring(actual, 0, 23).toArray(new String[actual.size()]); // upper case and sorted
86  for (int i = 0; i < s1.length; i++) {
87  assertEquals(format("Link IDs - test failed[%d]: %s,%s", i, s1[i], s2[i]), s1[i], s2[i]);
88  }
89  }
90 
91  public static String createMininetTopoFromFile(URL url) {
92  String doc;
93  try {
94  doc = Resources.toString(url, Charsets.UTF_8);
95  } catch (IOException ex) {
96  throw new TopologyProcessingException(format("Unable to read the topology file '%s'.", url), ex);
97  }
98  doc = doc.replaceAll("\"dpid\": \"SW", "\"dpid\": \""); // remove any SW characters
99  doc = doc.replaceAll("([0-9A-Fa-f]{2}):", "$1"); // remove ':' in id
101  return doc;
102  }
103 
107  private static ITopology translateTestTopo(String doc) {
109  return tDoc;
110  }
111 
116  public static ITopology translateTopoEngTopo(ITopology expected) throws InterruptedException {
117  long expectedSwitches = expected.getSwitches().keySet().size();
118  long expectedLinks = expected.getLinks().keySet().size();
119  return checkAndGetTopo(expectedSwitches, expectedLinks);
120  }
121 
122 
132  public static ITopology checkAndGetTopo(long expectedSwitches, long expectedLinks) throws
133  InterruptedException {
134  ITopology tTE = new Topology(); // ie null topology
135 
136  // try a couple of times to get the topology;
137  // TODO: this should be based off of a cucumber spec .. the cucumber tests as smoke!
138  long priorSwitches = 0, priorLinks = 0;
139  for (int i = 0; i < 4; i++) {
140  Thread.yield(); // let other threads do something ..
141  TimeUnit.SECONDS.sleep(10);
142  String jsonFromTE = TopologyHelp.GetTopology();
143  Thread.yield(); // let other threads do something ..
144 
145  tTE = TeTopologyParser.parseTopologyEngineJson(jsonFromTE);
146  long numSwitches = tTE.getSwitches().keySet().size();
147  long numLinks = tTE.getLinks().keySet().size();
148 
149  System.out.print("(" + numSwitches + "," + numLinks + ") ");
150  System.out.print("of (" + expectedSwitches + "," + expectedLinks + ") .. ");
151  System.out.flush();
152 
153  if (numSwitches != expectedSwitches) {
154  if (numSwitches > priorSwitches) {
155  priorSwitches = numSwitches;
156  i = 0; // reset the timeout
157  }
158  continue;
159  }
160 
161  if (numLinks != expectedLinks) {
162  if (numLinks > priorLinks) {
163  priorLinks = numLinks;
164  i = 0; // reset the timeout
165  }
166  continue;
167  }
168  break;
169  }
170  System.out.println("");
171  return tTE;
172  }
173 
174 
178  public static void clearEverything() throws InterruptedException, IOException {
179  clearEverything("localhost");
180  }
181 
185  public static void clearEverything(String endpoint) throws InterruptedException, IOException {
186  String expected = "{\"nodes\": []}";
188  // Give Mininet some time to clear things naturally
189  TimeUnit.MILLISECONDS.sleep(3000);
190 
191  // verify it is empty
192  String entity = TopologyHelp.ClearTopology();
193 
194  for (int i = 0; i < 2; i++) {
195  if (!expected.equals(entity)) {
196  TimeUnit.MILLISECONDS.sleep(2000);
197  entity = TopologyHelp.ClearTopology();
198  assertEquals("Default, initial, response from TopologyEngine", expected, entity);
199  } else {
200  break;
201  }
202  }
203 
204  KafkaUtils kafkaUtils = new KafkaUtils();
205  // TODO: the topology name is environment dependent and may be changed during deployment,
206  // so the solution on how to send a Ctrl request should be reconsidered.
207  kafkaUtils.clearTopologyComponentState("wfm", "OFELinkBolt");
208 
209  Uninterruptibles.sleepUninterruptibly(3, TimeUnit.SECONDS);
210  }
211 
215  public static void testTheTopo(URL url) {
216  try {
217  clearEverything();
218  String doc = createMininetTopoFromFile(url);
219  ITopology expected = translateTestTopo(doc);
220  ITopology actual = translateTopoEngTopo(expected);
221  validateTopos(expected, actual);
222  } catch (Exception e) {
223  fail("Unexpected Exception:" + e.getMessage());
224  }
225  }
226 
227  public static void main(String[] args) {
229  System.out.println("t1 = " + t);
230 
232  System.out.println("t2 = " + t.printSwitchConnections());
233 
234  System.out.println("t2.size = " + t.getSwitches().keySet().size());
235 
236  }
237 }
static void main(String[] args)
Definition: TestUtils.java:227
static void testTheTopo(URL url)
Definition: TestUtils.java:215
static ITopology checkAndGetTopo(long expectedSwitches, long expectedLinks)
Definition: TestUtils.java:132
static String createMininetTopoFromFile(URL url)
Definition: TestUtils.java:91
Map< String, Switch > getSwitches()
Map< String, Link > getLinks()
s1
Definition: plan-c.py:44
static void validateTopos(ITopology expected, ITopology actual)
Definition: TestUtils.java:42
static final Topology buildLinearTopo(int numSwitches)
static void clearEverything(String endpoint)
Definition: TestUtils.java:185
static final Topology buildTopoFromTestJson(String jsonDoc)
static boolean CreateMininetTopology(String json)
CtrlResponse clearTopologyComponentState(String topology, String componentId)
list result
Definition: plan-d.py:72
static ITopology translateTopoEngTopo(ITopology expected)
Definition: TestUtils.java:116
static boolean DeleteMininetTopology()
static Topology parseTopologyEngineJson(String json)
static final Topology buildTreeTopo(int depth, int fanout)