blob: 6ed50af3227c9286c527631d927ee98d194bbe99 [file] [log] [blame]
Ray Milkey7c44c052014-12-05 10:34:54 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2014-present Open Networking Laboratory
Ray Milkey7c44c052014-12-05 10:34:54 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.net.intent.impl;
17
18import java.util.Collection;
Ray Milkey7c44c052014-12-05 10:34:54 -080019import java.util.LinkedList;
20import java.util.List;
21import java.util.concurrent.CountDownLatch;
22import java.util.concurrent.TimeUnit;
23
24import org.junit.After;
25import org.junit.Before;
26import org.junit.Test;
27import org.onlab.junit.TestUtils;
Ray Milkey2da272b2015-02-03 19:52:08 -080028import org.onlab.junit.TestUtils.TestUtilsException;
Ray Milkey7c44c052014-12-05 10:34:54 -080029import org.onosproject.core.IdGenerator;
30import org.onosproject.event.Event;
Brian O'Connorb5dcc512015-03-24 17:28:00 -070031import org.onosproject.net.Device;
Sho SHIMIZU44f37612015-11-25 16:23:22 -080032import org.onosproject.net.DeviceId;
Ray Milkey7c44c052014-12-05 10:34:54 -080033import org.onosproject.net.Link;
Ray Milkey7c44c052014-12-05 10:34:54 -080034import org.onosproject.net.NetworkResource;
Sho SHIMIZU44f37612015-11-25 16:23:22 -080035import org.onosproject.net.PortNumber;
Brian O'Connorb5dcc512015-03-24 17:28:00 -070036import org.onosproject.net.device.DeviceEvent;
37import org.onosproject.net.device.DeviceListener;
Ray Milkey7c44c052014-12-05 10:34:54 -080038import org.onosproject.net.intent.Intent;
Ray Milkeyf9af43c2015-02-09 16:45:48 -080039import org.onosproject.net.intent.Key;
Ray Milkey7c44c052014-12-05 10:34:54 -080040import org.onosproject.net.intent.MockIdGenerator;
41import org.onosproject.net.link.LinkEvent;
Sho SHIMIZUe18cb122016-02-22 21:04:56 -080042import org.onosproject.net.resource.ResourceEvent;
43import org.onosproject.net.resource.ResourceListener;
44import org.onosproject.net.resource.Resources;
Ray Milkey7c44c052014-12-05 10:34:54 -080045import org.onosproject.net.topology.Topology;
46import org.onosproject.net.topology.TopologyEvent;
47import org.onosproject.net.topology.TopologyListener;
48
Ray Milkey7c44c052014-12-05 10:34:54 -080049import com.google.common.collect.ImmutableSet;
50import com.google.common.collect.Lists;
Ray Milkey7c44c052014-12-05 10:34:54 -080051
52import static org.easymock.EasyMock.createMock;
Ray Milkey7c44c052014-12-05 10:34:54 -080053import static org.hamcrest.MatcherAssert.assertThat;
54import static org.hamcrest.Matchers.equalTo;
55import static org.hamcrest.Matchers.hasSize;
56import static org.hamcrest.Matchers.is;
Sho SHIMIZUe18cb122016-02-22 21:04:56 -080057import static org.onosproject.net.resource.ResourceEvent.Type.*;
Ray Milkeyf9af43c2015-02-09 16:45:48 -080058import static org.onosproject.net.NetTestTools.APP_ID;
Brian O'Connorb5dcc512015-03-24 17:28:00 -070059import static org.onosproject.net.NetTestTools.device;
Ray Milkey7c44c052014-12-05 10:34:54 -080060import static org.onosproject.net.NetTestTools.link;
Ray Milkey7c44c052014-12-05 10:34:54 -080061
62/**
63 * Tests for the objective tracker.
64 */
65public class ObjectiveTrackerTest {
66 private static final int WAIT_TIMEOUT_SECONDS = 2;
67 private Topology topology;
68 private ObjectiveTracker tracker;
69 private TestTopologyChangeDelegate delegate;
70 private List<Event> reasons;
71 private TopologyListener listener;
Brian O'Connorb5dcc512015-03-24 17:28:00 -070072 private DeviceListener deviceListener;
Sho SHIMIZU0b9c4682015-11-02 18:30:34 -080073 private ResourceListener resourceListener;
Ray Milkey7c44c052014-12-05 10:34:54 -080074 private IdGenerator mockGenerator;
75
76 /**
77 * Initialization shared by all test cases.
78 *
79 * @throws TestUtilsException if any filed look ups fail
80 */
81 @Before
82 public void setUp() throws TestUtilsException {
83 topology = createMock(Topology.class);
84 tracker = new ObjectiveTracker();
85 delegate = new TestTopologyChangeDelegate();
86 tracker.setDelegate(delegate);
87 reasons = new LinkedList<>();
88 listener = TestUtils.getField(tracker, "listener");
Brian O'Connorb5dcc512015-03-24 17:28:00 -070089 deviceListener = TestUtils.getField(tracker, "deviceListener");
Sho SHIMIZU0b9c4682015-11-02 18:30:34 -080090 resourceListener = TestUtils.getField(tracker, "resourceListener");
Ray Milkey7c44c052014-12-05 10:34:54 -080091 mockGenerator = new MockIdGenerator();
Thomas Vachuska23235962017-02-03 11:44:15 -080092 Intent.unbindIdGenerator(mockGenerator);
Ray Milkey7c44c052014-12-05 10:34:54 -080093 Intent.bindIdGenerator(mockGenerator);
94 }
95
96 /**
97 * Code to clean up shared by all test case.
98 */
99 @After
100 public void tearDown() {
101 tracker.unsetDelegate(delegate);
102 Intent.unbindIdGenerator(mockGenerator);
103 }
104
105 /**
106 * Topology change delegate mock that tracks the events coming into it
107 * and saves them. It provides a latch so that tests can wait for events
108 * to be generated.
109 */
110 static class TestTopologyChangeDelegate implements TopologyChangeDelegate {
111
112 CountDownLatch latch = new CountDownLatch(1);
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800113 List<Key> intentIdsFromEvent;
Ray Milkey7c44c052014-12-05 10:34:54 -0800114 boolean compileAllFailedFromEvent;
115
116 @Override
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800117 public void triggerCompile(Iterable<Key> intentKeys,
Ray Milkey7c44c052014-12-05 10:34:54 -0800118 boolean compileAllFailed) {
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800119 intentIdsFromEvent = Lists.newArrayList(intentKeys);
Ray Milkey7c44c052014-12-05 10:34:54 -0800120 compileAllFailedFromEvent = compileAllFailed;
121 latch.countDown();
122 }
123 }
124
125 /**
Ray Milkey7c44c052014-12-05 10:34:54 -0800126 * Tests an event with no associated reasons.
127 *
128 * @throws InterruptedException if the latch wait fails.
129 */
130 @Test
131 public void testEventNoReasons() throws InterruptedException {
132 final TopologyEvent event = new TopologyEvent(
133 TopologyEvent.Type.TOPOLOGY_CHANGED,
134 topology,
135 null);
136
137 listener.event(event);
138 assertThat(
139 delegate.latch.await(WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS),
140 is(true));
141
142 assertThat(delegate.intentIdsFromEvent, hasSize(0));
143 assertThat(delegate.compileAllFailedFromEvent, is(true));
144 }
145
146 /**
147 * Tests an event for a link down where none of the reasons match
148 * currently installed intents.
149 *
150 * @throws InterruptedException if the latch wait fails.
151 */
152 @Test
153 public void testEventLinkDownNoMatches() throws InterruptedException {
154 final Link link = link("src", 1, "dst", 2);
155 final LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link);
156 reasons.add(linkEvent);
157
158 final TopologyEvent event = new TopologyEvent(
159 TopologyEvent.Type.TOPOLOGY_CHANGED,
160 topology,
161 reasons);
162
163 listener.event(event);
164 assertThat(
165 delegate.latch.await(WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS),
166 is(true));
167
168 assertThat(delegate.intentIdsFromEvent, hasSize(0));
169 assertThat(delegate.compileAllFailedFromEvent, is(false));
170 }
171
172 /**
173 * Tests an event for a link being added.
174 *
175 * @throws InterruptedException if the latch wait fails.
176 */
177 @Test
178 public void testEventLinkAdded() throws InterruptedException {
179 final Link link = link("src", 1, "dst", 2);
180 final LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_ADDED, link);
181 reasons.add(linkEvent);
182
183 final TopologyEvent event = new TopologyEvent(
184 TopologyEvent.Type.TOPOLOGY_CHANGED,
185 topology,
186 reasons);
187
188 listener.event(event);
189 assertThat(
190 delegate.latch.await(WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS),
191 is(true));
192
193 assertThat(delegate.intentIdsFromEvent, hasSize(0));
194 assertThat(delegate.compileAllFailedFromEvent, is(true));
195 }
196
197 /**
198 * Tests an event for a link down where the link matches existing intents.
199 *
200 * @throws InterruptedException if the latch wait fails.
201 */
202 @Test
203 public void testEventLinkDownMatch() throws Exception {
204 final Link link = link("src", 1, "dst", 2);
205 final LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link);
206 reasons.add(linkEvent);
207
208 final TopologyEvent event = new TopologyEvent(
209 TopologyEvent.Type.TOPOLOGY_CHANGED,
210 topology,
211 reasons);
212
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800213 final Key key = Key.of(0x333L, APP_ID);
Ray Milkey7c44c052014-12-05 10:34:54 -0800214 Collection<NetworkResource> resources = ImmutableSet.of(link);
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800215 tracker.addTrackedResources(key, resources);
Ray Milkey7c44c052014-12-05 10:34:54 -0800216
217 listener.event(event);
218 assertThat(
219 delegate.latch.await(WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS),
220 is(true));
221
222 assertThat(delegate.intentIdsFromEvent, hasSize(1));
223 assertThat(delegate.compileAllFailedFromEvent, is(false));
224 assertThat(delegate.intentIdsFromEvent.get(0).toString(),
225 equalTo("0x333"));
226 }
227
228 /**
229 * Tests a resource available event.
230 *
231 * @throws InterruptedException if the latch wait fails.
232 */
233 @Test
234 public void testResourceEvent() throws Exception {
Sho SHIMIZU0b9c4682015-11-02 18:30:34 -0800235 ResourceEvent event = new ResourceEvent(RESOURCE_ADDED,
Sho SHIMIZU460b9722016-01-28 10:48:26 -0800236 Resources.discrete(DeviceId.deviceId("a"), PortNumber.portNumber(1)).resource());
Sho SHIMIZU0b9c4682015-11-02 18:30:34 -0800237 resourceListener.event(event);
Ray Milkey7c44c052014-12-05 10:34:54 -0800238
239 assertThat(
240 delegate.latch.await(WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS),
241 is(true));
242
243 assertThat(delegate.intentIdsFromEvent, hasSize(0));
244 assertThat(delegate.compileAllFailedFromEvent, is(true));
245 }
246
Brian O'Connorb5dcc512015-03-24 17:28:00 -0700247 /**
248 * Tests an event for a host becoming available that matches an intent.
249 *
250 * @throws InterruptedException if the latch wait fails.
251 */
252
253 @Test
254 public void testEventHostAvailableMatch() throws Exception {
255 final Device host = device("host1");
256
257 final DeviceEvent deviceEvent =
258 new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, host);
259 reasons.add(deviceEvent);
260
261 final Key key = Key.of(0x333L, APP_ID);
262 Collection<NetworkResource> resources = ImmutableSet.of(host.id());
263 tracker.addTrackedResources(key, resources);
264
265 deviceListener.event(deviceEvent);
266 assertThat(
267 delegate.latch.await(WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS),
268 is(true));
269
270 assertThat(delegate.intentIdsFromEvent, hasSize(1));
271 assertThat(delegate.compileAllFailedFromEvent, is(true));
272 assertThat(delegate.intentIdsFromEvent.get(0).toString(),
273 equalTo("0x333"));
274 }
275
276 /**
277 * Tests an event for a host becoming unavailable that matches an intent.
278 *
279 * @throws InterruptedException if the latch wait fails.
280 */
281
282 @Test
283 public void testEventHostUnavailableMatch() throws Exception {
284 final Device host = device("host1");
285
286 final DeviceEvent deviceEvent =
287 new DeviceEvent(DeviceEvent.Type.DEVICE_REMOVED, host);
288 reasons.add(deviceEvent);
289
290 final Key key = Key.of(0x333L, APP_ID);
291 Collection<NetworkResource> resources = ImmutableSet.of(host.id());
292 tracker.addTrackedResources(key, resources);
293
294 deviceListener.event(deviceEvent);
295 assertThat(
296 delegate.latch.await(WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS),
297 is(true));
298
299 assertThat(delegate.intentIdsFromEvent, hasSize(1));
300 assertThat(delegate.compileAllFailedFromEvent, is(false));
301 assertThat(delegate.intentIdsFromEvent.get(0).toString(),
302 equalTo("0x333"));
303 }
304
305 /**
306 * Tests an event for a host becoming available that matches an intent.
307 *
308 * @throws InterruptedException if the latch wait fails.
309 */
310
311 @Test
312 public void testEventHostAvailableNoMatch() throws Exception {
313 final Device host = device("host1");
314
315 final DeviceEvent deviceEvent =
316 new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, host);
317 reasons.add(deviceEvent);
318
319 deviceListener.event(deviceEvent);
320 assertThat(
321 delegate.latch.await(WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS),
322 is(true));
323
324 assertThat(delegate.intentIdsFromEvent, hasSize(0));
325 assertThat(delegate.compileAllFailedFromEvent, is(true));
326 }
327
328
Ray Milkey7c44c052014-12-05 10:34:54 -0800329}