blob: cf89098173d5e5c12117d8e04d09f17da4aa8005 [file] [log] [blame]
Ray Milkey7c44c052014-12-05 10:34:54 -08001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
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;
19import java.util.HashSet;
20import java.util.LinkedList;
21import java.util.List;
22import java.util.concurrent.CountDownLatch;
23import java.util.concurrent.TimeUnit;
24
25import org.junit.After;
26import org.junit.Before;
27import org.junit.Test;
28import org.onlab.junit.TestUtils;
29import org.onosproject.core.IdGenerator;
30import org.onosproject.event.Event;
31import org.onosproject.net.Link;
32import org.onosproject.net.LinkKey;
33import org.onosproject.net.NetTestTools;
34import org.onosproject.net.NetworkResource;
35import org.onosproject.net.intent.Intent;
36import org.onosproject.net.intent.IntentBatchLeaderEvent;
37import org.onosproject.net.intent.IntentBatchListener;
38import org.onosproject.net.intent.IntentId;
39import org.onosproject.net.intent.IntentService;
40import org.onosproject.net.intent.MockIdGenerator;
41import org.onosproject.net.link.LinkEvent;
42import org.onosproject.net.resource.LinkResourceEvent;
43import org.onosproject.net.resource.LinkResourceListener;
44import org.onosproject.net.topology.Topology;
45import org.onosproject.net.topology.TopologyEvent;
46import org.onosproject.net.topology.TopologyListener;
47
48import com.google.common.collect.ImmutableList;
49import com.google.common.collect.ImmutableSet;
50import com.google.common.collect.Lists;
51import com.google.common.collect.SetMultimap;
52
53import static org.easymock.EasyMock.createMock;
54import static org.easymock.EasyMock.expect;
55import static org.easymock.EasyMock.replay;
56import static org.hamcrest.MatcherAssert.assertThat;
57import static org.hamcrest.Matchers.equalTo;
58import static org.hamcrest.Matchers.hasSize;
59import static org.hamcrest.Matchers.is;
60import static org.onosproject.net.NetTestTools.link;
61import org.onlab.junit.TestUtils.TestUtilsException;
62
63/**
64 * Tests for the objective tracker.
65 */
66public class ObjectiveTrackerTest {
67 private static final int WAIT_TIMEOUT_SECONDS = 2;
68 private Topology topology;
69 private ObjectiveTracker tracker;
70 private TestTopologyChangeDelegate delegate;
71 private List<Event> reasons;
72 private TopologyListener listener;
73 private LinkResourceListener linkResourceListener;
74 private IntentBatchListener leaderListener;
75 private IdGenerator mockGenerator;
76
77 /**
78 * Initialization shared by all test cases.
79 *
80 * @throws TestUtilsException if any filed look ups fail
81 */
82 @Before
83 public void setUp() throws TestUtilsException {
84 topology = createMock(Topology.class);
85 tracker = new ObjectiveTracker();
86 delegate = new TestTopologyChangeDelegate();
87 tracker.setDelegate(delegate);
88 reasons = new LinkedList<>();
89 listener = TestUtils.getField(tracker, "listener");
90 linkResourceListener = TestUtils.getField(tracker, "linkResourceListener");
91 leaderListener = TestUtils.getField(tracker, "leaderListener");
92 mockGenerator = new MockIdGenerator();
93 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);
113 List<IntentId> intentIdsFromEvent;
114 boolean compileAllFailedFromEvent;
115
116 @Override
117 public void triggerCompile(Iterable<IntentId> intentIds,
118 boolean compileAllFailed) {
119 intentIdsFromEvent = Lists.newArrayList(intentIds);
120 compileAllFailedFromEvent = compileAllFailed;
121 latch.countDown();
122 }
123 }
124
125 /**
126 * Mock compilable intent class.
127 */
128 private static class MockIntent extends Intent {
129
130 public MockIntent(Collection<NetworkResource> resources) {
131 super(NetTestTools.APP_ID, resources);
132 }
133
134 }
135
136 /**
137 * Mock installable intent class.
138 */
139 private static class MockInstallableIntent extends Intent {
140 public MockInstallableIntent(Collection<NetworkResource> resources) {
141 super(NetTestTools.APP_ID, resources);
142 }
143
144 @Override
145 public boolean isInstallable() {
146 return true;
147 }
148
149 }
150
151 /**
152 * Tests an event with no associated reasons.
153 *
154 * @throws InterruptedException if the latch wait fails.
155 */
156 @Test
157 public void testEventNoReasons() throws InterruptedException {
158 final TopologyEvent event = new TopologyEvent(
159 TopologyEvent.Type.TOPOLOGY_CHANGED,
160 topology,
161 null);
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(true));
170 }
171
172 /**
173 * Tests an event for a link down where none of the reasons match
174 * currently installed intents.
175 *
176 * @throws InterruptedException if the latch wait fails.
177 */
178 @Test
179 public void testEventLinkDownNoMatches() throws InterruptedException {
180 final Link link = link("src", 1, "dst", 2);
181 final LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link);
182 reasons.add(linkEvent);
183
184 final TopologyEvent event = new TopologyEvent(
185 TopologyEvent.Type.TOPOLOGY_CHANGED,
186 topology,
187 reasons);
188
189 listener.event(event);
190 assertThat(
191 delegate.latch.await(WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS),
192 is(true));
193
194 assertThat(delegate.intentIdsFromEvent, hasSize(0));
195 assertThat(delegate.compileAllFailedFromEvent, is(false));
196 }
197
198 /**
199 * Tests an event for a link being added.
200 *
201 * @throws InterruptedException if the latch wait fails.
202 */
203 @Test
204 public void testEventLinkAdded() throws InterruptedException {
205 final Link link = link("src", 1, "dst", 2);
206 final LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_ADDED, link);
207 reasons.add(linkEvent);
208
209 final TopologyEvent event = new TopologyEvent(
210 TopologyEvent.Type.TOPOLOGY_CHANGED,
211 topology,
212 reasons);
213
214 listener.event(event);
215 assertThat(
216 delegate.latch.await(WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS),
217 is(true));
218
219 assertThat(delegate.intentIdsFromEvent, hasSize(0));
220 assertThat(delegate.compileAllFailedFromEvent, is(true));
221 }
222
223 /**
224 * Tests an event for a link down where the link matches existing intents.
225 *
226 * @throws InterruptedException if the latch wait fails.
227 */
228 @Test
229 public void testEventLinkDownMatch() throws Exception {
230 final Link link = link("src", 1, "dst", 2);
231 final LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link);
232 reasons.add(linkEvent);
233
234 final TopologyEvent event = new TopologyEvent(
235 TopologyEvent.Type.TOPOLOGY_CHANGED,
236 topology,
237 reasons);
238
239 final IntentId intentId = IntentId.valueOf(0x333L);
240 Collection<NetworkResource> resources = ImmutableSet.of(link);
241 tracker.addTrackedResources(intentId, resources);
242
243 listener.event(event);
244 assertThat(
245 delegate.latch.await(WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS),
246 is(true));
247
248 assertThat(delegate.intentIdsFromEvent, hasSize(1));
249 assertThat(delegate.compileAllFailedFromEvent, is(false));
250 assertThat(delegate.intentIdsFromEvent.get(0).toString(),
251 equalTo("0x333"));
252 }
253
254 /**
255 * Tests a resource available event.
256 *
257 * @throws InterruptedException if the latch wait fails.
258 */
259 @Test
260 public void testResourceEvent() throws Exception {
261 LinkResourceEvent event = new LinkResourceEvent(
262 LinkResourceEvent.Type.ADDITIONAL_RESOURCES_AVAILABLE,
263 new HashSet<>());
264 linkResourceListener.event(event);
265
266 assertThat(
267 delegate.latch.await(WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS),
268 is(true));
269
270 assertThat(delegate.intentIdsFromEvent, hasSize(0));
271 assertThat(delegate.compileAllFailedFromEvent, is(true));
272 }
273
274 /**
275 * Tests leadership events.
276 *
277 * @throws InterruptedException if the latch wait fails.
278 */
279 @Test
280 public void testLeaderEvents() throws Exception {
281
282 final Link link = link("src", 1, "dst", 2);
283 final List<NetworkResource> resources = ImmutableList.of(link);
284
285 final List<Intent> intents = new LinkedList<>();
286 final List<Intent> installableIntents = new LinkedList<>();
287 installableIntents.add(new MockInstallableIntent(resources));
288 intents.add(new MockIntent(resources));
289
290 final SetMultimap<LinkKey, IntentId> intentsByLink =
291 TestUtils.getField(tracker, "intentsByLink");
292 assertThat(intentsByLink.size(), is(0));
293
294 final IntentService mockIntentManager = createMock(IntentService.class);
295 expect(mockIntentManager
296 .getIntents())
297 .andReturn(intents)
298 .anyTimes();
299 expect(mockIntentManager
300 .getIntent(IntentId.valueOf(0x0)))
301 .andReturn(intents.get(0))
302 .anyTimes();
303 expect(mockIntentManager
304 .getInstallableIntents(IntentId.valueOf(0x1)))
305 .andReturn(installableIntents)
306 .anyTimes();
307 replay(mockIntentManager);
308 tracker.bindIntentService(mockIntentManager);
309
310 final IntentBatchLeaderEvent electedEvent = new IntentBatchLeaderEvent(
311 IntentBatchLeaderEvent.Type.ELECTED, NetTestTools.APP_ID);
312 leaderListener.event(electedEvent);
313 assertThat(intentsByLink.size(), is(1));
314
315 final IntentBatchLeaderEvent bootedEvent = new IntentBatchLeaderEvent(
316 IntentBatchLeaderEvent.Type.BOOTED, NetTestTools.APP_ID);
317 leaderListener.event(bootedEvent);
318 assertThat(intentsByLink.size(), is(0));
319
320 tracker.unbindIntentService(mockIntentManager);
321 }
322}