2 * Copyright (c) 2013 Plexxi, Inc. All rights reserved.
\r
4 * This program and the accompanying materials are made available under the
\r
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
\r
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
\r
9 package org.opendaylight.affinity.analytics.internal;
\r
11 import java.net.InetAddress;
\r
12 import java.net.UnknownHostException;
\r
13 import java.util.ArrayList;
\r
14 import java.util.Arrays;
\r
15 import java.util.HashSet;
\r
16 import java.util.List;
\r
17 import java.util.Map;
\r
18 import java.util.Set;
\r
20 import junit.framework.TestCase;
\r
21 import org.junit.Assert;
\r
22 import org.junit.Test;
\r
24 import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
\r
25 import org.opendaylight.controller.sal.core.ConstructionException;
\r
26 import org.opendaylight.controller.sal.core.Host;
\r
27 import org.opendaylight.controller.sal.core.Node;
\r
28 import org.opendaylight.controller.sal.core.NodeConnector;
\r
29 import org.opendaylight.controller.sal.flowprogrammer.Flow;
\r
30 import org.opendaylight.controller.sal.match.Match;
\r
31 import org.opendaylight.controller.sal.match.MatchField;
\r
32 import org.opendaylight.controller.sal.match.MatchType;
\r
33 import org.opendaylight.controller.sal.reader.FlowOnNode;
\r
34 import org.opendaylight.controller.sal.utils.EtherTypes;
\r
35 import org.opendaylight.controller.sal.utils.IPProtocols;
\r
37 public class AnalyticsManagerTest extends TestCase {
\r
40 public void testAnalyticsManagerCreation() {
\r
41 AnalyticsManager am = new AnalyticsManager();
\r
42 Assert.assertTrue(am != null);
\r
46 public void testGetHostsFromFlows() {
\r
48 AnalyticsManager am = new AnalyticsManager();
\r
53 Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(100L));
\r
54 Node n2 = new Node(Node.NodeIDType.OPENFLOW, new Long(101L));
\r
55 Node n3 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
\r
56 Node n4 = new Node(Node.NodeIDType.OPENFLOW, new Long(111L));
\r
58 // Set up node connectors
\r
59 NodeConnector nc1 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW, new Short((short) 0xCAFC), n1);
\r
60 NodeConnector nc2 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW, new Short((short) 0xCAFD), n2);
\r
61 NodeConnector nc3 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW, new Short((short) 0xCAFE), n3);
\r
62 NodeConnector nc4 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW, new Short((short) 0xCAFF), n4);
\r
64 // Set up host node connectors
\r
65 HostNodeConnector hnc1 = new HostNodeConnector(new byte[]{0,0,0,0,0,1}, InetAddress.getByName("10.0.0.1"), nc1, (short) 1);
\r
66 HostNodeConnector hnc2 = new HostNodeConnector(new byte[]{0,0,0,0,0,2}, InetAddress.getByName("10.0.0.2"), nc2, (short) 1);
\r
67 HostNodeConnector hnc3 = new HostNodeConnector(new byte[]{0,0,0,0,0,3}, InetAddress.getByName("10.0.0.3"), nc3, (short) 1);
\r
68 Set<HostNodeConnector> hosts = new HashSet<HostNodeConnector>(Arrays.asList(hnc1, hnc2, hnc3));
\r
70 // Set up a flow from nc1 to nc2
\r
71 Match match = new Match();
\r
72 match.setField(new MatchField(MatchType.IN_PORT, nc1));
\r
73 match.setField(new MatchField(MatchType.DL_DST, new byte[]{0,0,0,0,0,2}));
\r
74 Flow f = new Flow();
\r
77 Host dstHost = am.getDestinationHostFromFlow(f, hosts);
\r
78 Host srcHost = am.getSourceHostFromFlow(f, hosts);
\r
80 Assert.assertTrue(dstHost.equals(hnc2));
\r
81 Assert.assertTrue(srcHost.equals(hnc1));
\r
83 // Set up a flow from nc3 to nc1
\r
84 match = new Match();
\r
85 match.setField(new MatchField(MatchType.IN_PORT, nc3));
\r
86 match.setField(new MatchField(MatchType.DL_DST, new byte[]{0,0,0,0,0,1}));
\r
90 dstHost = am.getDestinationHostFromFlow(f, hosts);
\r
91 srcHost = am.getSourceHostFromFlow(f, hosts);
\r
93 Assert.assertTrue(dstHost.equals(hnc1));
\r
94 Assert.assertTrue(srcHost.equals(hnc3));
\r
96 // Set up a flow from a switch to a non-host..
\r
97 match = new Match();
\r
98 match.setField(new MatchField(MatchType.IN_PORT, nc4));
\r
99 match.setField(new MatchField(MatchType.DL_DST, new byte[]{0,0,0,0,0,2}));
\r
103 dstHost = am.getDestinationHostFromFlow(f, hosts);
\r
104 srcHost = am.getSourceHostFromFlow(f, hosts);
\r
106 Assert.assertTrue(dstHost.equals(hnc2));
\r
107 Assert.assertTrue(srcHost == null);
\r
108 } catch (ConstructionException e) {
\r
109 Assert.assertTrue(false);
\r
110 } catch (UnknownHostException e ) {
\r
111 Assert.assertTrue(false);
\r
118 public void testSubnetMatching() {
\r
120 AnalyticsManager am = new AnalyticsManager();
\r
125 Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(100L));
\r
126 Node n2 = new Node(Node.NodeIDType.OPENFLOW, new Long(101L));
\r
127 Node n3 = new Node(Node.NodeIDType.OPENFLOW, new Long(110L));
\r
128 Node n4 = new Node(Node.NodeIDType.OPENFLOW, new Long(111L));
\r
130 // Set up node connectors
\r
131 NodeConnector nc1 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW, new Short((short) 0xCAFC), n1);
\r
132 NodeConnector nc2 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW, new Short((short) 0xCAFD), n2);
\r
133 NodeConnector nc3 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW, new Short((short) 0xCAFE), n3);
\r
134 NodeConnector nc4 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW, new Short((short) 0xCAFF), n4);
\r
136 // Set up host node connectors
\r
137 HostNodeConnector hnc1 = new HostNodeConnector(InetAddress.getByName("128.0.0.1"), nc1);
\r
138 HostNodeConnector hnc2 = new HostNodeConnector(InetAddress.getByName("128.0.0.2"), nc2);
\r
139 HostNodeConnector hnc3 = new HostNodeConnector(InetAddress.getByName("129.0.0.1"), nc3);
\r
140 HostNodeConnector hnc4 = new HostNodeConnector(InetAddress.getByName("129.0.0.2"), nc4);
\r
141 Set<HostNodeConnector> allHosts = new HashSet<HostNodeConnector>(Arrays.asList(hnc1, hnc2, hnc3, hnc4));
\r
143 String subnet1 = "128.0.0.0/8"; // matches 128.*
\r
144 Set<Host> matchedHosts = am.getHostsInSubnet(subnet1, allHosts);
\r
145 Set<Host> unmatchedHosts = am.getHostsNotInSubnet(subnet1, allHosts);
\r
146 Assert.assertTrue(matchedHosts.size() == 2);
\r
147 Assert.assertTrue(matchedHosts.contains(hnc1));
\r
148 Assert.assertTrue(matchedHosts.contains(hnc2));
\r
149 Assert.assertTrue(unmatchedHosts.size() == 2);
\r
150 Assert.assertTrue(unmatchedHosts.contains(hnc3));
\r
151 Assert.assertTrue(unmatchedHosts.contains(hnc4));
\r
153 String subnet2 = "128.0.0.0/7"; // matches 128.* and 129.*
\r
154 matchedHosts = am.getHostsInSubnet(subnet2, allHosts);
\r
155 unmatchedHosts = am.getHostsNotInSubnet(subnet2, allHosts);
\r
156 Assert.assertTrue(matchedHosts.size() == 4);
\r
157 Assert.assertTrue(matchedHosts.contains(hnc1));
\r
158 Assert.assertTrue(matchedHosts.contains(hnc2));
\r
159 Assert.assertTrue(matchedHosts.contains(hnc3));
\r
160 Assert.assertTrue(matchedHosts.contains(hnc4));
\r
161 Assert.assertTrue(unmatchedHosts.size() == 0);
\r
163 String subnet3 = "128.0.0.2/32"; // matches 128.0.0.2
\r
164 matchedHosts = am.getHostsInSubnet(subnet3, allHosts);
\r
165 unmatchedHosts = am.getHostsNotInSubnet(subnet3, allHosts);
\r
166 Assert.assertTrue(matchedHosts.size() == 1);
\r
167 Assert.assertTrue(matchedHosts.contains(hnc2));
\r
168 Assert.assertTrue(unmatchedHosts.size() == 3);
\r
169 Assert.assertTrue(unmatchedHosts.contains(hnc1));
\r
170 Assert.assertTrue(unmatchedHosts.contains(hnc3));
\r
171 Assert.assertTrue(unmatchedHosts.contains(hnc4));
\r
173 String subnet4 = "128.0.0.1/31"; // matches 128.0.0.1
\r
174 matchedHosts = am.getHostsInSubnet(subnet4, allHosts);
\r
175 unmatchedHosts = am.getHostsNotInSubnet(subnet4, allHosts);
\r
176 Assert.assertTrue(matchedHosts.size() == 1);
\r
177 Assert.assertTrue(matchedHosts.contains(hnc1));
\r
178 Assert.assertTrue(unmatchedHosts.size() == 3);
\r
179 Assert.assertTrue(unmatchedHosts.contains(hnc2));
\r
180 Assert.assertTrue(unmatchedHosts.contains(hnc3));
\r
181 Assert.assertTrue(unmatchedHosts.contains(hnc4));
\r
183 String subnet5 = "10.0.0.0/8"; // matches none
\r
184 matchedHosts = am.getHostsInSubnet(subnet5, allHosts);
\r
185 unmatchedHosts = am.getHostsNotInSubnet(subnet5, allHosts);
\r
186 Assert.assertTrue(matchedHosts.size() == 0);
\r
187 Assert.assertTrue(unmatchedHosts.size() == 4);
\r
188 Assert.assertTrue(unmatchedHosts.contains(hnc1));
\r
189 Assert.assertTrue(unmatchedHosts.contains(hnc2));
\r
190 Assert.assertTrue(unmatchedHosts.contains(hnc3));
\r
191 Assert.assertTrue(unmatchedHosts.contains(hnc4));
\r
192 } catch (ConstructionException e) {
\r
193 Assert.assertTrue(false);
\r
194 } catch (UnknownHostException e ) {
\r
195 Assert.assertTrue(false);
\r
202 public void testGetStatsBetweenHosts() {
\r
203 AnalyticsManager am = new AnalyticsManager();
\r
206 // Set up the network
\r
207 Node n1 = new Node(Node.NodeIDType.OPENFLOW, new Long(100L));
\r
208 Node n2 = new Node(Node.NodeIDType.OPENFLOW, new Long(101L));
\r
209 NodeConnector nc1 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW, new Short((short) 0xCAFC), n1);
\r
210 NodeConnector nc2 = new NodeConnector(NodeConnector.NodeConnectorIDType.OPENFLOW, new Short((short) 0xCAFD), n2);
\r
211 HostNodeConnector hnc1 = new HostNodeConnector(new byte[]{0,0,0,0,0,1}, InetAddress.getByName("10.0.0.1"), nc1, (short) 1);
\r
212 HostNodeConnector hnc2 = new HostNodeConnector(new byte[]{0,0,0,0,0,2}, InetAddress.getByName("10.0.0.2"), nc2, (short) 1);
\r
213 Set<HostNodeConnector> allHosts = new HashSet<HostNodeConnector>(Arrays.asList(hnc1, hnc2));
\r
215 // Two flows between the hosts; different protocols
\r
216 Match match1 = new Match();
\r
217 match1.setField(new MatchField(MatchType.IN_PORT, nc1));
\r
218 match1.setField(new MatchField(MatchType.DL_DST, new byte[]{0,0,0,0,0,2}));
\r
219 match1.setField(new MatchField(MatchType.DL_TYPE, EtherTypes.IPv4.shortValue()));
\r
220 match1.setField(new MatchField(MatchType.NW_PROTO, IPProtocols.ICMP.byteValue()));
\r
221 Flow f1 = new Flow();
\r
222 f1.setMatch(match1);
\r
223 FlowOnNode fon1 = new FlowOnNode(f1);
\r
224 fon1.setByteCount(200);
\r
225 fon1.setDurationSeconds(1);
\r
226 fon1.setDurationNanoseconds(100000000); // 1.1s
\r
227 List<FlowOnNode> flowStatsList = new ArrayList<FlowOnNode>();
\r
228 flowStatsList.add(fon1);
\r
230 Match match2 = new Match();
\r
231 match2.setField(new MatchField(MatchType.IN_PORT, nc1));
\r
232 match2.setField(new MatchField(MatchType.DL_DST, new byte[]{0,0,0,0,0,2}));
\r
233 match2.setField(new MatchField(MatchType.DL_TYPE, EtherTypes.IPv4.shortValue()));
\r
234 match2.setField(new MatchField(MatchType.NW_PROTO, IPProtocols.UDP.byteValue()));
\r
235 Flow f2 = new Flow();
\r
236 f2.setMatch(match2);
\r
237 FlowOnNode fon2 = new FlowOnNode(f2);
\r
238 fon2.setByteCount(76);
\r
239 fon2.setDurationSeconds(2);
\r
240 fon2.setDurationNanoseconds(0);
\r
241 flowStatsList.add(fon2);
\r
244 am.nodeFlowStatisticsUpdated(n1, flowStatsList, allHosts);
\r
245 Assert.assertTrue(am.getByteCount(hnc1, hnc2) == 276);
\r
246 Assert.assertTrue(am.getBitRate(hnc1, hnc2) == (276 * 8.0) / 2.0);
\r
248 // Per-protocol stats
\r
249 Assert.assertTrue(am.getByteCount(hnc1, hnc2, IPProtocols.ICMP.byteValue()) == 200);
\r
250 Assert.assertTrue(am.getBitRate(hnc1, hnc2, IPProtocols.ICMP.byteValue()) == (200 * 8.0) / 1.1);
\r
251 Assert.assertTrue(am.getByteCount(hnc1, hnc2, IPProtocols.UDP.byteValue()) == 76);
\r
252 Assert.assertTrue(am.getBitRate(hnc1, hnc2, IPProtocols.UDP.byteValue()) == (76 * 8.0) / 2.0);
\r
253 Assert.assertTrue(am.getByteCount(hnc1, hnc2, IPProtocols.TCP.byteValue()) == 0);
\r
254 Assert.assertTrue(am.getBitRate(hnc1, hnc2, IPProtocols.TCP.byteValue()) == 0.0);
\r
257 Map<Byte, Long> byteCounts = am.getAllByteCounts(hnc1, hnc2);
\r
258 Map<Byte, Double> bitRates = am.getAllBitRates(hnc1, hnc2);
\r
259 Assert.assertTrue(byteCounts.get(IPProtocols.ICMP.byteValue()) == am.getByteCount(hnc1, hnc2, IPProtocols.ICMP.byteValue()));
\r
260 Assert.assertTrue(bitRates.get(IPProtocols.ICMP.byteValue()) == am.getBitRate(hnc1, hnc2, IPProtocols.ICMP.byteValue()));
\r
261 Assert.assertTrue(byteCounts.get(IPProtocols.UDP.byteValue()) == am.getByteCount(hnc1, hnc2, IPProtocols.UDP.byteValue()));
\r
262 Assert.assertTrue(bitRates.get(IPProtocols.UDP.byteValue()) == am.getBitRate(hnc1, hnc2, IPProtocols.UDP.byteValue()));
\r
263 Assert.assertTrue(byteCounts.get(IPProtocols.TCP.byteValue()) == null);
\r
264 Assert.assertTrue(bitRates.get(IPProtocols.TCP.byteValue()) == null);
\r
266 // Correct flow over-writing
\r
267 FlowOnNode fon3 = new FlowOnNode(f1);
\r
268 fon3.setByteCount(300);
\r
269 fon3.setDurationSeconds(3);
\r
270 fon3.setDurationNanoseconds(100000000); // 3.1s
\r
271 flowStatsList.add(fon3);
\r
272 am.nodeFlowStatisticsUpdated(n2, flowStatsList, allHosts);
\r
273 Assert.assertTrue(am.getByteCount(hnc1, hnc2) == 376);
\r
274 Assert.assertTrue(am.getBitRate(hnc1, hnc2) == (376 * 8.0) / 3.1);
\r
275 Assert.assertTrue(am.getByteCount(hnc1, hnc2, IPProtocols.ICMP.byteValue()) == 300);
\r
276 } catch (ConstructionException e) {
\r
277 Assert.assertTrue(false);
\r
278 } catch (UnknownHostException e) {
\r
279 Assert.assertTrue(false);
\r