Pingping
Committed by Pavlin Radoslavov

port SdnIpTest.java to onos-next

Change-Id: Iec9de810b168e3fbc8f1aa447778d3883fba03a1
This diff is collapsed. Click to expand it.
1 +package org.onlab.onos.sdnip;
2 +
3 +import java.util.HashSet;
4 +import java.util.Random;
5 +import java.util.Set;
6 +import java.util.concurrent.Executors;
7 +import java.util.concurrent.ScheduledExecutorService;
8 +import java.util.concurrent.TimeUnit;
9 +
10 +import org.onlab.onos.net.ConnectPoint;
11 +import org.onlab.onos.net.DefaultHost;
12 +import org.onlab.onos.net.DeviceId;
13 +import org.onlab.onos.net.Host;
14 +import org.onlab.onos.net.HostId;
15 +import org.onlab.onos.net.HostLocation;
16 +import org.onlab.onos.net.host.HostEvent;
17 +import org.onlab.onos.net.host.HostListener;
18 +import org.onlab.onos.net.host.HostService;
19 +import org.onlab.onos.net.host.PortAddresses;
20 +import org.onlab.onos.net.provider.ProviderId;
21 +import org.onlab.onos.sdnip.Router.InternalHostListener;
22 +import org.onlab.packet.IpAddress;
23 +import org.onlab.packet.MacAddress;
24 +import org.onlab.packet.VlanId;
25 +
26 +import com.google.common.collect.Sets;
27 +
28 +/**
29 + * Test version of the HostService which is used to simulate delays in
30 + * receiving ARP replies, as you would see in a real system due to the time
31 + * it takes to proxy ARP packets to/from the host. Requests are asynchronous,
32 + * and replies may come back to the requestor in a different order than the
33 + * requests were sent, which again you would expect to see in a real system.
34 + */
35 +public class TestHostService implements HostService {
36 +
37 + /**
38 + * The maximum possible delay before an ARP reply is received.
39 + */
40 + private static final int MAX_ARP_REPLY_DELAY = 30; // milliseconds
41 +
42 + /**
43 + * The probability that we already have the MAC address cached when the
44 + * caller calls {@link #getHostsByIp(IpAddress ipAddress)}.
45 + */
46 + private static final float MAC_ALREADY_KNOWN_PROBABILITY = 0.3f;
47 +
48 + private final ScheduledExecutorService replyTaskExecutor;
49 + private final Random random;
50 +
51 + /**
52 + * Class constructor.
53 + */
54 + public TestHostService() {
55 + replyTaskExecutor = Executors.newSingleThreadScheduledExecutor();
56 + random = new Random();
57 + }
58 +
59 + /**
60 + * Task used to reply to ARP requests from a different thread. Replies
61 + * usually come on a different thread in the real system, so we need to
62 + * ensure we test this behavior.
63 + */
64 + private class ReplyTask implements Runnable {
65 + private HostListener listener;
66 + private IpAddress ipAddress;
67 +
68 + /**
69 + * Class constructor.
70 + *
71 + * @param listener the client who requests and waits the MAC address
72 + * @param ipAddress the target IP address of the request
73 + */
74 + public ReplyTask(InternalHostListener listener,
75 + IpAddress ipAddress) {
76 + this.listener = listener;
77 + this.ipAddress = ipAddress;
78 + }
79 +
80 + @Override
81 + public void run() {
82 + Host host = getHostsByIp(ipAddress).iterator().next();
83 + HostEvent hostevent =
84 + new HostEvent(HostEvent.Type.HOST_ADDED, host);
85 + listener.event(hostevent);
86 + }
87 + }
88 +
89 + @Override
90 + public Set<Host> getHostsByIp(IpAddress ipAddress) {
91 + float replyChance = random.nextFloat();
92 +
93 + // We don't care what the attachment point is in the test,
94 + // so for all the hosts, we use a same ConnectPoint.
95 + Host host = new DefaultHost(ProviderId.NONE, HostId.NONE,
96 + SdnIpTest.generateMacAddress(ipAddress), VlanId.NONE,
97 + new HostLocation(SdnIpTest.SW1_ETH1, 1),
98 + Sets.newHashSet(ipAddress));
99 +
100 + if (replyChance < MAC_ALREADY_KNOWN_PROBABILITY) {
101 + // Some percentage of the time we already know the MAC address, so
102 + // we reply directly when the requestor asks for the MAC address
103 + return Sets.newHashSet(host);
104 + }
105 + return new HashSet<Host>();
106 + }
107 +
108 + @Override
109 + public void startMonitoringIp(IpAddress ipAddress) {
110 +
111 + // Randomly select an amount of time to delay the reply coming back to
112 + int delay = random.nextInt(MAX_ARP_REPLY_DELAY);
113 + ReplyTask replyTask = new ReplyTask(
114 + (SdnIpTest.router.new InternalHostListener()), ipAddress);
115 + replyTaskExecutor.schedule(replyTask, delay, TimeUnit.MILLISECONDS);
116 + }
117 +
118 + @Override
119 + public int getHostCount() {
120 + return 0;
121 + }
122 +
123 + @Override
124 + public Iterable<Host> getHosts() {
125 + return null;
126 + }
127 +
128 + @Override
129 + public Host getHost(HostId hostId) {
130 + return null;
131 + }
132 +
133 + @Override
134 + public Set<Host> getHostsByVlan(VlanId vlanId) {
135 + return null;
136 + }
137 +
138 + @Override
139 + public Set<Host> getHostsByMac(MacAddress mac) {
140 + return null;
141 + }
142 +
143 + @Override
144 + public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
145 + return null;
146 + }
147 +
148 + @Override
149 + public Set<Host> getConnectedHosts(DeviceId deviceId) {
150 + return null;
151 + }
152 +
153 + @Override
154 + public void stopMonitoringIp(IpAddress ip) {
155 +
156 + }
157 +
158 + @Override
159 + public void requestMac(IpAddress ip) {
160 +
161 + }
162 +
163 + @Override
164 + public Set<PortAddresses> getAddressBindings() {
165 + return null;
166 + }
167 +
168 + @Override
169 + public Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint) {
170 + return null;
171 + }
172 +
173 + @Override
174 + public void addListener(HostListener listener) {
175 +
176 + }
177 +
178 + @Override
179 + public void removeListener(HostListener listener) {
180 +
181 + }
182 +
183 +}
...@@ -42,6 +42,10 @@ ...@@ -42,6 +42,10 @@
42 <groupId>org.onlab.onos</groupId> 42 <groupId>org.onlab.onos</groupId>
43 <artifactId>onlab-misc</artifactId> 43 <artifactId>onlab-misc</artifactId>
44 </dependency> 44 </dependency>
45 + <dependency>
46 + <groupId>org.onlab.onos</groupId>
47 + <artifactId>onlab-junit</artifactId>
48 + </dependency>
45 </dependencies> 49 </dependencies>
46 50
47 <build> 51 <build>
......
...@@ -388,6 +388,7 @@ ...@@ -388,6 +388,7 @@
388 <redirectTestOutputToFile>true 388 <redirectTestOutputToFile>true
389 </redirectTestOutputToFile> 389 </redirectTestOutputToFile>
390 <printSummary>true</printSummary> 390 <printSummary>true</printSummary>
391 + <excludedGroups>org.onlab.junit.IntegrationTest</excludedGroups>
391 </configuration> 392 </configuration>
392 </plugin> 393 </plugin>
393 394
......
...@@ -49,6 +49,11 @@ ...@@ -49,6 +49,11 @@
49 </dependency> 49 </dependency>
50 50
51 <dependency> 51 <dependency>
52 + <groupId>org.onlab.onos</groupId>
53 + <artifactId>onlab-junit</artifactId>
54 + </dependency>
55 +
56 + <dependency>
52 <groupId>org.apache.felix</groupId> 57 <groupId>org.apache.felix</groupId>
53 <artifactId>org.apache.felix.scr.annotations</artifactId> 58 <artifactId>org.apache.felix.scr.annotations</artifactId>
54 </dependency> 59 </dependency>
......
1 +package org.onlab.junit;
2 +
3 +/**
4 + * Marker interface used to separate unit tests from integration tests. All
5 + * integration tests should be marked with:
6 + * {@literal @Category}(IntegrationTest.class)
7 + * so that they can be run separately.
8 + */
9 +public interface IntegrationTest {
10 +}
...@@ -57,6 +57,11 @@ ...@@ -57,6 +57,11 @@
57 <artifactId>onlab-rest</artifactId> 57 <artifactId>onlab-rest</artifactId>
58 <version>${project.version}</version> 58 <version>${project.version}</version>
59 </dependency> 59 </dependency>
60 + <dependency>
61 + <groupId>org.onlab.onos</groupId>
62 + <artifactId>onlab-junit</artifactId>
63 + <scope>test</scope>
64 + </dependency>
60 65
61 <dependency> 66 <dependency>
62 <groupId>com.google.guava</groupId> 67 <groupId>com.google.guava</groupId>
......