X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fnorthbound%2Fintegrationtest%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnorthbound%2Fintegrationtest%2FNorthboundIntegrationTest.java;h=32a9c5a6fc7bb16705635635e0a52f3b85f96c13;hb=0f846fcbc207a4213ac133e1d08a305fc72168ba;hp=47dfa76b281408296c1d97ccf7c47ad4255c5304;hpb=771dea2b9c38cd8bd74ef56ecbdbe6143b60cecf;p=controller.git diff --git a/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIntegrationTest.java b/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIntegrationTest.java index 47dfa76b28..32a9c5a6fc 100644 --- a/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIntegrationTest.java +++ b/opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIntegrationTest.java @@ -19,14 +19,26 @@ import org.ops4j.pax.exam.util.PathUtils; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.nio.charset.Charset; +import java.util.Arrays; + import org.apache.commons.codec.binary.Base64; +import org.codehaus.jettison.json.JSONArray; +import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.codehaus.jettison.json.JSONTokener; +import org.opendaylight.controller.hosttracker.IfIptoHost; +import org.opendaylight.controller.sal.core.ConstructionException; +import org.opendaylight.controller.sal.core.Node; +import org.opendaylight.controller.sal.core.NodeConnector; +import org.opendaylight.controller.sal.core.UpdateType; +import org.opendaylight.controller.switchmanager.IInventoryListener; import org.opendaylight.controller.usermanager.IUserManager; @RunWith(PaxExam.class) @@ -37,6 +49,7 @@ public class NorthboundIntegrationTest { @Inject private BundleContext bc; private IUserManager users = null; + private IInventoryListener invtoryListener = null; private String stateToString(int state) { switch (state) { @@ -81,33 +94,51 @@ public class NorthboundIntegrationTest { // If UserManager is null, cannot login to run tests. assertNotNull(this.users); + r = bc.getServiceReference(IfIptoHost.class.getName()); + if (r != null) { + this.invtoryListener = (IInventoryListener)bc.getService(r); + } + + // If inventoryListener is null, cannot run hosttracker tests. + assertNotNull(this.invtoryListener); + } - @Test - public void testStatistics() { + // static variable to pass response code from getJsonResult() + private static Integer httpResponseCode = null; - System.out.println("Starting Statistics JAXB client."); + private String getJsonResult(String restUrl) { + return getJsonResult(restUrl, "GET"); + } + + private String getJsonResult(String restUrl, String method) { + // initialize response code to indicate error + httpResponseCode = 400; - String baseURL = "http://127.0.0.1:8080/controller/nb/v2/statistics/default/flowstats"; try { - URL url = new URL(baseURL); + URL url = new URL(restUrl); this.users.getAuthorizationList(); this.users.authenticate("admin", "admin"); String authString = "admin:admin"; byte[] authEncBytes = Base64.encodeBase64(authString.getBytes()); String authStringEnc = new String(authEncBytes); - URLConnection connection = url.openConnection(); + + HttpURLConnection connection = (HttpURLConnection) url + .openConnection(); + connection.setRequestMethod(method); connection.setRequestProperty("Authorization", "Basic " + authStringEnc); - connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Accept", "application/json"); connection.connect(); connection.getContentType(); + + // Response code for success should be 2xx + httpResponseCode = connection.getResponseCode(); + InputStream is = connection.getInputStream(); - // InputStream is = connection.getInputStream(); BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8"))); StringBuilder sb = new StringBuilder(); @@ -116,16 +147,118 @@ public class NorthboundIntegrationTest { sb.append((char) cp); } is.close(); - JSONTokener jt = new JSONTokener(sb.toString()); + connection.disconnect(); + return sb.toString(); + } catch (Exception e) { + return null; + } + + } + + @Test + public void testStatistics() { + String actionTypes[] = { "drop", "loopback", "flood", "floodAll", + "controller", "swPath", "hwPath", "output", "setDlSrc", + "setDlDst", "setDlType", "setVlanId", "setVlanPcp", + "setVlanCfi", "popVlan", "pushVlan", "setNwSrc", "setNwDst", + "setNwTos", "setTpSrc", "setTpDst" }; + System.out.println("Starting Statistics JAXB client."); + + String baseURL = "http://127.0.0.1:8080/controller/nb/v2/statistics/default/"; + try { + String result = getJsonResult(baseURL + "flowstats"); + JSONTokener jt = new JSONTokener(result); JSONObject json = new JSONObject(jt); - JSONObject flowStatistics = json.getJSONObject("flowStatistics"); + JSONObject flowStatistics = + getJsonInstance (json, "flowStatistics", 0xCAFE); JSONObject node = flowStatistics.getJSONObject("node"); // test that node was returned properly Assert.assertTrue(node.getInt("@id") == 0xCAFE); Assert.assertTrue(node.getString("@type").equals("STUB")); // test that flow statistics results are correct - JSONObject flowStat = flowStatistics.getJSONObject("flowStat"); + JSONArray flowStats = flowStatistics.getJSONArray("flowStat"); + for (int i = 0; i < flowStats.length(); i++) { + + JSONObject flowStat = flowStats.getJSONObject(i); + testFlowStat(flowStat, actionTypes[i]); + + } + + // for /controller/nb/v2/statistics/default/portstats + result = getJsonResult(baseURL + "portstats"); + jt = new JSONTokener(result); + json = new JSONObject(jt); + JSONObject portStatistics = + getJsonInstance (json, "portStatistics", 0xCAFE); + JSONObject node2 = portStatistics.getJSONObject("node"); + // test that node was returned properly + Assert.assertTrue(node2.getInt("@id") == 0xCAFE); + Assert.assertTrue(node2.getString("@type").equals("STUB")); + + // test that port statistic results are correct + JSONObject portStat = portStatistics.getJSONObject("portStat"); + Assert.assertTrue(portStat.getInt("receivePackets") == 250); + Assert.assertTrue(portStat.getInt("transmitPackets") == 500); + Assert.assertTrue(portStat.getInt("receiveBytes") == 1000); + Assert.assertTrue(portStat.getInt("transmitBytes") == 5000); + Assert.assertTrue(portStat.getInt("receiveDrops") == 2); + Assert.assertTrue(portStat.getInt("transmitDrops") == 50); + Assert.assertTrue(portStat.getInt("receiveErrors") == 3); + Assert.assertTrue(portStat.getInt("transmitErrors") == 10); + Assert.assertTrue(portStat.getInt("receiveFrameError") == 5); + Assert.assertTrue(portStat.getInt("receiveOverRunError") == 6); + Assert.assertTrue(portStat.getInt("receiveCrcError") == 1); + Assert.assertTrue(portStat.getInt("collisionCount") == 4); + + // test for getting one specific node's stats + result = getJsonResult(baseURL + "flowstats/STUB/51966"); + jt = new JSONTokener(result); + json = new JSONObject(jt); + node = json.getJSONObject("node"); + // test that node was returned properly + Assert.assertTrue(node.getInt("@id") == 0xCAFE); + Assert.assertTrue(node.getString("@type").equals("STUB")); + + // test that flow statistics results are correct + flowStats = json.getJSONArray("flowStat"); + for (int i = 0; i < flowStats.length(); i++) { + JSONObject flowStat = flowStats.getJSONObject(i); + testFlowStat(flowStat, actionTypes[i]); + } + + result = getJsonResult(baseURL + "portstats/STUB/51966"); + jt = new JSONTokener(result); + json = new JSONObject(jt); + node2 = json.getJSONObject("node"); + // test that node was returned properly + Assert.assertTrue(node2.getInt("@id") == 0xCAFE); + Assert.assertTrue(node2.getString("@type").equals("STUB")); + + // test that port statistic results are correct + portStat = json.getJSONObject("portStat"); + Assert.assertTrue(portStat.getInt("receivePackets") == 250); + Assert.assertTrue(portStat.getInt("transmitPackets") == 500); + Assert.assertTrue(portStat.getInt("receiveBytes") == 1000); + Assert.assertTrue(portStat.getInt("transmitBytes") == 5000); + Assert.assertTrue(portStat.getInt("receiveDrops") == 2); + Assert.assertTrue(portStat.getInt("transmitDrops") == 50); + Assert.assertTrue(portStat.getInt("receiveErrors") == 3); + Assert.assertTrue(portStat.getInt("transmitErrors") == 10); + Assert.assertTrue(portStat.getInt("receiveFrameError") == 5); + Assert.assertTrue(portStat.getInt("receiveOverRunError") == 6); + Assert.assertTrue(portStat.getInt("receiveCrcError") == 1); + Assert.assertTrue(portStat.getInt("collisionCount") == 4); + + } catch (Exception e) { + // Got an unexpected exception + Assert.assertTrue(false); + + } + } + + private void testFlowStat(JSONObject flowStat, String actionType) { + try { Assert.assertTrue(flowStat.getInt("tableId") == 1); Assert.assertTrue(flowStat.getInt("durationSeconds") == 40); Assert.assertTrue(flowStat.getInt("durationNanoseconds") == 400); @@ -144,16 +277,350 @@ public class NorthboundIntegrationTest { Assert.assertTrue(match.getString("type").equals("NW_DST")); Assert.assertTrue(match.getString("value").equals("1.1.1.1")); - Assert.assertTrue(flow.getJSONObject("actions").getString("@type") - .equals("drop")); + JSONObject act = flow.getJSONObject("actions"); + Assert.assertTrue(act.getString("@type").equals(actionType)); + + if (act.getString("@type").equals("output")) { + JSONObject port = act.getJSONObject("port"); + JSONObject port_node = port.getJSONObject("node"); + Assert.assertTrue(port.getInt("@id") == 51966); + Assert.assertTrue(port.getString("@type").equals("STUB")); + Assert.assertTrue(port_node.getInt("@id") == 51966); + Assert.assertTrue(port_node.getString("@type").equals("STUB")); + } + + if (act.getString("@type").equals("setDlSrc")) { + byte srcMatch[] = { (byte) 5, (byte) 4, (byte) 3, (byte) 2, + (byte) 1 }; + String src = act.getString("address"); + byte srcBytes[] = new byte[5]; + srcBytes[0] = Byte.parseByte(src.substring(0, 2)); + srcBytes[1] = Byte.parseByte(src.substring(2, 4)); + srcBytes[2] = Byte.parseByte(src.substring(4, 6)); + srcBytes[3] = Byte.parseByte(src.substring(6, 8)); + srcBytes[4] = Byte.parseByte(src.substring(8, 10)); + Assert.assertTrue(Arrays.equals(srcBytes, srcMatch)); + } + if (act.getString("@type").equals("setDlDst")) { + byte dstMatch[] = { (byte) 1, (byte) 2, (byte) 3, (byte) 4, + (byte) 5 }; + String dst = act.getString("address"); + byte dstBytes[] = new byte[5]; + dstBytes[0] = Byte.parseByte(dst.substring(0, 2)); + dstBytes[1] = Byte.parseByte(dst.substring(2, 4)); + dstBytes[2] = Byte.parseByte(dst.substring(4, 6)); + dstBytes[3] = Byte.parseByte(dst.substring(6, 8)); + dstBytes[4] = Byte.parseByte(dst.substring(8, 10)); + Assert.assertTrue(Arrays.equals(dstBytes, dstMatch)); + } + if (act.getString("@type").equals("setDlType")) + Assert.assertTrue(act.getInt("dlType") == 10); + if (act.getString("@type").equals("setVlanId")) + Assert.assertTrue(act.getInt("vlanId") == 2); + if (act.getString("@type").equals("setVlanPcp")) + Assert.assertTrue(act.getInt("pcp") == 3); + if (act.getString("@type").equals("setVlanCfi")) + Assert.assertTrue(act.getInt("cfi") == 1); + + if (act.getString("@type").equals("setNwSrc")) + Assert.assertTrue(act.getString("address").equals("2.2.2.2")); + if (act.getString("@type").equals("setNwDst")) + Assert.assertTrue(act.getString("address").equals("1.1.1.1")); + + if (act.getString("@type").equals("pushVlan")) { + int head = act.getInt("VlanHeader"); + // parsing vlan header + int id = head & 0xfff; + int cfi = (head >> 12) & 0x1; + int pcp = (head >> 13) & 0x7; + int tag = (head >> 16) & 0xffff; + Assert.assertTrue(id == 1234); + Assert.assertTrue(cfi == 1); + Assert.assertTrue(pcp == 1); + Assert.assertTrue(tag == 0x8100); + } + if (act.getString("@type").equals("setNwTos")) + Assert.assertTrue(act.getInt("tos") == 16); + if (act.getString("@type").equals("setTpSrc")) + Assert.assertTrue(act.getInt("port") == 4201); + if (act.getString("@type").equals("setTpDst")) + Assert.assertTrue(act.getInt("port") == 8080); + } catch (Exception e) { + Assert.assertTrue(false); + } + } + + // method to extract a JSONObject with specified node ID from a JSONObject + // that may contain an array of JSONObjects + // This is specifically written for statistics manager northbound REST interface + // array_name should be either "flowStatistics" or "portStatistics" + private JSONObject getJsonInstance (JSONObject json, String array_name, Integer nodeId) throws JSONException + { + JSONObject result = null; + if (json.get(array_name) instanceof JSONArray){ + JSONArray json_array = json.getJSONArray(array_name); + for (int i = 0; i < json_array.length(); i++) { + result = json_array.getJSONObject(i); + Integer nid = result.getJSONObject("node").getInt("@id"); + if ( nid.equals(nodeId) ) break; + } + } + else { + result = json.getJSONObject(array_name); + Integer nid = result.getJSONObject("node").getInt("@id"); + if ( ! nid.equals(nodeId) ) result = null; + } + return result; + } + + + // a class to construct query parameter for HTTP request + private class QueryParameter { + StringBuilder queryString = null; + + // constructor + QueryParameter (String key, String value) { + queryString = new StringBuilder(); + queryString.append("?").append(key).append("=").append(value); + } + + // method to add more query parameter + QueryParameter add (String key, String value){ + this.queryString.append("&").append(key).append("=").append(value); + return this; + } + + // method to get the query parameter string + String getString (){ + return this.queryString.toString(); + } + + } + + + @Test + public void testHostTracker() { + + System.out.println("Starting HostTracker JAXB client."); + + // setup 2 host models for @POST method + // 1st host + String networkAddress_1 = "192.168.0.8"; + String dataLayerAddress_1 = "11:22:33:44:55:66"; + String nodeType_1 = "STUB"; + Integer nodeId_1 = 3366; + String nodeConnectorType_1 = "STUB"; + Integer nodeConnectorId_1 = 12; + String vlan_1 = "4"; + + + // 2nd host + String networkAddress_2 = "10.1.1.1"; + String dataLayerAddress_2 = "1A:2B:3C:4D:5E:6F"; + String nodeType_2 = "STUB"; + Integer nodeId_2 = 4477; + String nodeConnectorType_2 = "STUB"; + Integer nodeConnectorId_2 = 34; + String vlan_2 = "0"; + + String baseURL = "http://127.0.0.1:8080/controller/nb/v2/host/default"; + + // test POST method: addHost() + try { + String queryParameter = + new QueryParameter("dataLayerAddress", dataLayerAddress_1) + .add("nodeType", nodeType_1) + .add("nodeId", nodeId_1.toString()) + .add("nodeConnectorType", nodeConnectorType_1) + .add("nodeConnectorId", nodeConnectorId_1.toString()) + .add("vlan", vlan_1) + .getString(); + + String result = getJsonResult(baseURL +"/" + networkAddress_1 + queryParameter, "POST"); + Assert.assertTrue (httpResponseCode.intValue() == (Integer) 201); + + // vlan is not passed through query parameter but should be defaulted to "0" + queryParameter = + new QueryParameter("dataLayerAddress", dataLayerAddress_2) + .add("nodeType", nodeType_2) + .add("nodeId", nodeId_2.toString()) + .add("nodeConnectorType", nodeConnectorType_2) + .add("nodeConnectorId", nodeConnectorId_2.toString()) + .getString(); + + result = getJsonResult(baseURL +"/" + networkAddress_2 + queryParameter, "POST"); + Assert.assertTrue (httpResponseCode.intValue() == (Integer) 201); + } catch (Exception e) { + // Got an unexpected exception + Assert.assertTrue(false); + } + + // define variables for decoding returned strings + String networkAddress; + JSONObject host_jo, dl_jo, nc_jo, node_jo; + + // the two hosts should be in inactive host DB + // test GET method: getInactiveHosts() + try { + String result = getJsonResult(baseURL +"/inactive", "GET"); + Assert.assertTrue (httpResponseCode.intValue() == (Integer) 200); + + JSONTokener jt = new JSONTokener(result); + JSONObject json = new JSONObject(jt); + // there should be at least two hosts in the DB + Assert.assertTrue (json.get("host") instanceof JSONArray); + JSONArray ja = json.getJSONArray("host"); + Integer count = ja.length(); + Assert.assertTrue (count == 2); + + for ( int i = 0; i < count; i++) { + host_jo = ja.getJSONObject(i); + dl_jo = host_jo.getJSONObject("dataLayerAddress"); + nc_jo = host_jo.getJSONObject("nodeConnector"); + node_jo = nc_jo.getJSONObject("node"); + + networkAddress = host_jo.getString("networkAddress"); + if (networkAddress.equalsIgnoreCase(networkAddress_1)) { + Assert.assertTrue (dl_jo.getString("macAddress").equalsIgnoreCase(dataLayerAddress_1)); + Assert.assertTrue (nc_jo.getString("@type").equalsIgnoreCase(nodeConnectorType_1)); + Assert.assertTrue (Integer.parseInt(nc_jo.getString("@id")) == nodeConnectorId_1); + Assert.assertTrue (node_jo.getString("@type").equalsIgnoreCase(nodeType_1)); + Assert.assertTrue (Integer.parseInt(node_jo.getString("@id")) == nodeId_1); + Assert.assertTrue (host_jo.getString("vlan").equalsIgnoreCase(vlan_1)); + } + else if (networkAddress.equalsIgnoreCase(networkAddress_2)) { + Assert.assertTrue (dl_jo.getString("macAddress").equalsIgnoreCase(dataLayerAddress_2)); + Assert.assertTrue (nc_jo.getString("@type").equalsIgnoreCase(nodeConnectorType_2)); + Assert.assertTrue (Integer.parseInt(nc_jo.getString("@id")) == nodeConnectorId_2); + Assert.assertTrue (node_jo.getString("@type").equalsIgnoreCase(nodeType_2)); + Assert.assertTrue (Integer.parseInt(node_jo.getString("@id")) == nodeId_2); + Assert.assertTrue (host_jo.getString("vlan").equalsIgnoreCase(vlan_2)); + } + else { + Assert.assertTrue(false); + } + } + } catch (Exception e) { + // Got an unexpected exception + Assert.assertTrue(false); + } + + // test GET method: getActiveHosts() - no host expected + try { + String result = getJsonResult(baseURL, "GET"); + Assert.assertTrue (httpResponseCode.intValue() == (Integer) 200); + + JSONTokener jt = new JSONTokener(result); + JSONObject json = new JSONObject(jt); + Assert.assertFalse(hostInJson(json, networkAddress_1)); + Assert.assertFalse(hostInJson(json, networkAddress_2)); + } catch (Exception e) { + // Got an unexpected exception + Assert.assertTrue(false); + } + + // put the 1st host into active host DB + Node nd; + NodeConnector ndc; + try { + nd = new Node(nodeType_1, nodeId_1); + ndc = new NodeConnector(nodeConnectorType_1, nodeConnectorId_1, nd); + this.invtoryListener.notifyNodeConnector(ndc, + UpdateType.ADDED, null); + }catch(ConstructionException e){ + ndc = null; + nd = null; + } + + // verify the host shows up in active host DB + try { + String result = getJsonResult(baseURL, "GET"); + Assert.assertTrue (httpResponseCode.intValue() == (Integer) 200); + + JSONTokener jt = new JSONTokener(result); + JSONObject json = new JSONObject(jt); + + Assert.assertTrue(hostInJson(json, networkAddress_1)); } catch (Exception e) { // Got an unexpected exception Assert.assertTrue(false); + } + + + // test GET method for getHostDetails() + try { + String result = getJsonResult(baseURL+"/"+networkAddress_1, "GET"); + Assert.assertTrue (httpResponseCode.intValue() == (Integer) 200); + + JSONTokener jt = new JSONTokener(result); + JSONObject json = new JSONObject(jt); + Assert.assertFalse(json.length() == 0); + + dl_jo = json.getJSONObject("dataLayerAddress"); + nc_jo = json.getJSONObject("nodeConnector"); + node_jo = nc_jo.getJSONObject("node"); + + Assert.assertTrue (json.getString("networkAddress").equalsIgnoreCase(networkAddress_1)); + Assert.assertTrue (dl_jo.getString("macAddress").equalsIgnoreCase(dataLayerAddress_1)); + Assert.assertTrue (nc_jo.getString("@type").equalsIgnoreCase(nodeConnectorType_1)); + Assert.assertTrue (Integer.parseInt(nc_jo.getString("@id")) == nodeConnectorId_1); + Assert.assertTrue (node_jo.getString("@type").equalsIgnoreCase(nodeType_1)); + Assert.assertTrue (Integer.parseInt(node_jo.getString("@id")) == nodeId_1); + Assert.assertTrue (json.getString("vlan").equalsIgnoreCase(vlan_1)); + } catch (Exception e) { + // Got an unexpected exception + Assert.assertTrue(false); + } + + // test DELETE method for deleteFlow() + try { + String result = getJsonResult(baseURL+"/"+networkAddress_1, "DELETE"); + Assert.assertTrue (httpResponseCode.intValue() == (Integer) 200); + + } catch (Exception e) { + // Got an unexpected exception + Assert.assertTrue(false); + } + + // verify host_1 removed from active host DB + // test GET method: getActiveHosts() - no host expected + try { + String result = getJsonResult(baseURL, "GET"); + Assert.assertTrue (httpResponseCode.intValue() == (Integer) 200); + + JSONTokener jt = new JSONTokener(result); + JSONObject json = new JSONObject(jt); + + Assert.assertFalse(hostInJson(json, networkAddress_1)); + } catch (Exception e) { + // Got an unexpected exception + Assert.assertTrue(false); + } + } + + private Boolean hostInJson (JSONObject json, String hostIp) throws JSONException { + // input JSONObject may be empty + if ( json.length() == 0 ) { + return false; + } + if (json.get("host") instanceof JSONArray){ + JSONArray ja = json.getJSONArray("host"); + for (int i = 0; i < ja.length(); i++) { + String na = ja.getJSONObject(i).getString("networkAddress"); + if (na.equalsIgnoreCase(hostIp)) + return true; + } + return false; + } + else { + String na = json.getJSONObject("host").getString("networkAddress"); + return (na.equalsIgnoreCase(hostIp)) ? true : false; } } + // Configure the OSGi container @Configuration public Option[] config() {