blob: f979f27d6c46ea24a527387b8eb2c4ce6abe19f7 [file] [log] [blame]
Yi Tsengc927a062017-05-02 15:02:37 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Yi Tsengc927a062017-05-02 15:02:37 -07003 *
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 */
16
17package org.onosproject.net.intent.impl.installer;
18
19import com.google.common.collect.ImmutableList;
20import com.google.common.collect.Lists;
21import com.google.common.collect.Sets;
22import org.junit.After;
23import org.junit.Before;
24import org.junit.Test;
25import org.onlab.packet.VlanId;
26import org.onosproject.net.NetworkResource;
27import org.onosproject.net.flow.DefaultFlowRule;
28import org.onosproject.net.flow.DefaultTrafficSelector;
29import org.onosproject.net.flow.DefaultTrafficTreatment;
30import org.onosproject.net.flow.FlowRule;
31import org.onosproject.net.flow.FlowRuleOperations;
32import org.onosproject.net.flow.FlowRuleServiceAdapter;
33import org.onosproject.net.flow.TrafficSelector;
34import org.onosproject.net.flow.TrafficTreatment;
35import org.onosproject.net.intent.FlowRuleIntent;
36import org.onosproject.net.intent.Intent;
37import org.onosproject.net.intent.IntentData;
38import org.onosproject.net.intent.IntentInstallationContext;
39import org.onosproject.net.intent.IntentOperationContext;
40import org.onosproject.net.intent.IntentState;
41import org.onosproject.net.intent.PathIntent;
42import org.onosproject.store.service.WallClockTimestamp;
43
44import java.util.Collection;
45import java.util.List;
46import java.util.Set;
47import java.util.stream.Collectors;
48
49import static org.junit.Assert.*;
50
51/**
52 * Tests for flow rule Intent installer.
53 */
54public class FlowRuleIntentInstallerTest extends AbstractIntentInstallerTest {
55
56 private TestFlowRuleService flowRuleService;
57 private FlowRuleIntentInstaller installer;
58
59 @Before
60 public void setup() {
61 super.setup();
62 flowRuleService = new TestFlowRuleService();
63 installer = new FlowRuleIntentInstaller();
64 installer.flowRuleService = flowRuleService;
65 installer.intentExtensionService = intentExtensionService;
66 installer.intentInstallCoordinator = intentInstallCoordinator;
67 installer.trackerService = trackerService;
68
69 installer.activate();
70 }
71
72 @After
73 public void tearDown() {
74 super.tearDown();
75 installer.deactivated();
76 }
77
78 /**
79 * Installs Intents only, no Intents to be uninstall.
80 */
81 @Test
82 public void testInstallOnly() {
83 List<Intent> intentsToUninstall = Lists.newArrayList();
84 List<Intent> intentsToInstall = createFlowRuleIntents();
85
86 IntentData toUninstall = null;
87 IntentData toInstall = new IntentData(createP2PIntent(),
88 IntentState.INSTALLING,
89 new WallClockTimestamp());
90 toInstall = new IntentData(toInstall, intentsToInstall);
91
92
93 IntentOperationContext<FlowRuleIntent> operationContext;
94 IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
95 operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
96
97 installer.apply(operationContext);
98
99 IntentOperationContext successContext = intentInstallCoordinator.successContext;
100 assertEquals(successContext, operationContext);
101
102 Set<FlowRule> expectedFlowRules = intentsToInstall.stream()
103 .map(intent -> (FlowRuleIntent) intent)
104 .map(FlowRuleIntent::flowRules)
105 .flatMap(Collection::stream)
106 .collect(Collectors.toSet());
107
108 assertEquals(expectedFlowRules, flowRuleService.flowRulesAdd);
109 }
110
111 /**
112 * Uninstalls Intents only, no Intents to be install.
113 */
114 @Test
115 public void testUninstallOnly() {
116 List<Intent> intentsToInstall = Lists.newArrayList();
117 List<Intent> intentsToUninstall = createFlowRuleIntents();
118
119 IntentData toInstall = null;
120 IntentData toUninstall = new IntentData(createP2PIntent(),
121 IntentState.WITHDRAWING,
122 new WallClockTimestamp());
123 toUninstall = new IntentData(toUninstall, intentsToUninstall);
124
125
126 IntentOperationContext<FlowRuleIntent> operationContext;
127 IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
128 operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
129
130 installer.apply(operationContext);
131
132 IntentOperationContext successContext = intentInstallCoordinator.successContext;
133 assertEquals(successContext, operationContext);
134
135 Set<FlowRule> expectedFlowRules = intentsToUninstall.stream()
136 .map(intent -> (FlowRuleIntent) intent)
137 .map(FlowRuleIntent::flowRules)
138 .flatMap(Collection::stream)
139 .collect(Collectors.toSet());
140
141 assertEquals(expectedFlowRules, flowRuleService.flowRulesRemove);
142 }
143
144 /**
145 * Do both install and uninstall Intents with different flow rules.
146 */
147 @Test
148 public void testUninstallAndInstall() {
149 List<Intent> intentsToInstall = createAnotherFlowRuleIntents();
150 List<Intent> intentsToUninstall = createFlowRuleIntents();
151
152 IntentData toInstall = new IntentData(createP2PIntent(),
153 IntentState.INSTALLING,
154 new WallClockTimestamp());
155 toInstall = new IntentData(toInstall, intentsToInstall);
156 IntentData toUninstall = new IntentData(createP2PIntent(),
157 IntentState.INSTALLED,
158 new WallClockTimestamp());
159 toUninstall = new IntentData(toUninstall, intentsToUninstall);
160
161 IntentOperationContext<FlowRuleIntent> operationContext;
162 IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
163 operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
164
165 installer.apply(operationContext);
166
167 IntentOperationContext successContext = intentInstallCoordinator.successContext;
168 assertEquals(successContext, operationContext);
169
170 Set<FlowRule> expectedFlowRules = intentsToUninstall.stream()
171 .map(intent -> (FlowRuleIntent) intent)
172 .map(FlowRuleIntent::flowRules)
173 .flatMap(Collection::stream)
174 .collect(Collectors.toSet());
175
176 assertEquals(expectedFlowRules, flowRuleService.flowRulesRemove);
177
178 expectedFlowRules = intentsToInstall.stream()
179 .map(intent -> (FlowRuleIntent) intent)
180 .map(FlowRuleIntent::flowRules)
181 .flatMap(Collection::stream)
182 .collect(Collectors.toSet());
183
184 assertEquals(expectedFlowRules, flowRuleService.flowRulesAdd);
185 }
186
187 /**
188 * Do both install and uninstall Intents with same flow rules.
189 */
190 @Test
191 public void testUninstallAndInstallUnchanged() {
192 List<Intent> intentsToInstall = createFlowRuleIntents();
193 List<Intent> intentsToUninstall = createFlowRuleIntents();
194
195 IntentData toInstall = new IntentData(createP2PIntent(),
196 IntentState.INSTALLING,
197 new WallClockTimestamp());
198 toInstall = new IntentData(toInstall, intentsToInstall);
199 IntentData toUninstall = new IntentData(createP2PIntent(),
200 IntentState.INSTALLED,
201 new WallClockTimestamp());
202 toUninstall = new IntentData(toUninstall, intentsToUninstall);
203
204 IntentOperationContext<FlowRuleIntent> operationContext;
205 IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
206 operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
207
208 installer.apply(operationContext);
209
210 IntentOperationContext successContext = intentInstallCoordinator.successContext;
211 assertEquals(successContext, operationContext);
212
213 assertEquals(0, flowRuleService.flowRulesRemove.size());
214 assertEquals(0, flowRuleService.flowRulesAdd.size());
Yi Tsengc29d8822017-10-25 16:19:25 -0700215 assertEquals(0, flowRuleService.flowRulesModify.size());
Yi Tsengc927a062017-05-02 15:02:37 -0700216 }
217
218 /**
219 * Do both install and uninstall Intents with same flow rule Intent.
220 */
221 @Test
222 public void testUninstallAndInstallSame() {
223 List<Intent> intentsToInstall = createFlowRuleIntents();
224 List<Intent> intentsToUninstall = intentsToInstall;
225
226 IntentData toInstall = new IntentData(createP2PIntent(),
227 IntentState.INSTALLING,
228 new WallClockTimestamp());
229 toInstall = new IntentData(toInstall, intentsToInstall);
230 IntentData toUninstall = new IntentData(createP2PIntent(),
231 IntentState.INSTALLED,
232 new WallClockTimestamp());
233 toUninstall = new IntentData(toUninstall, intentsToUninstall);
234
235 IntentOperationContext<FlowRuleIntent> operationContext;
236 IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
237 operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
238
239 installer.apply(operationContext);
240
241 IntentOperationContext successContext = intentInstallCoordinator.successContext;
242 assertEquals(successContext, operationContext);
243
244 assertEquals(0, flowRuleService.flowRulesRemove.size());
245 assertEquals(0, flowRuleService.flowRulesAdd.size());
Yi Tsengc29d8822017-10-25 16:19:25 -0700246 assertEquals(0, flowRuleService.flowRulesModify.size());
Yi Tsengc927a062017-05-02 15:02:37 -0700247 }
248
249 /**
250 * Nothing to uninstall or install.
251 */
252 @Test
253 public void testNoAnyIntentToApply() {
254 IntentData toInstall = null;
255 IntentData toUninstall = null;
256 IntentOperationContext<FlowRuleIntent> operationContext;
257 IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
258 operationContext = new IntentOperationContext<>(ImmutableList.of(), ImmutableList.of(), context);
259 installer.apply(operationContext);
260
261 IntentOperationContext successContext = intentInstallCoordinator.successContext;
262 assertEquals(successContext, operationContext);
263
264 assertEquals(0, flowRuleService.flowRulesRemove.size());
265 assertEquals(0, flowRuleService.flowRulesAdd.size());
Yi Tsengc29d8822017-10-25 16:19:25 -0700266 assertEquals(0, flowRuleService.flowRulesModify.size());
Yi Tsengc927a062017-05-02 15:02:37 -0700267 }
268
269 /**
270 * Test if the flow installation failed.
271 */
272 @Test
273 public void testFailed() {
274 installer.flowRuleService = new TestFailedFlowRuleService();
275 List<Intent> intentsToUninstall = Lists.newArrayList();
276 List<Intent> intentsToInstall = createFlowRuleIntents();
277
278 IntentData toUninstall = null;
279 IntentData toInstall = new IntentData(createP2PIntent(),
280 IntentState.INSTALLING,
281 new WallClockTimestamp());
282 toInstall = new IntentData(toInstall, intentsToInstall);
283
284
285 IntentOperationContext<FlowRuleIntent> operationContext;
286 IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
287 operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
288
289 installer.apply(operationContext);
290
291 IntentOperationContext failedContext = intentInstallCoordinator.failedContext;
292 assertEquals(failedContext, operationContext);
293 }
294
295 /**
Yi Tsengc29d8822017-10-25 16:19:25 -0700296 * Test intents with same match rules, should do modify instead of add.
297 */
298 @Test
299 public void testRuleModify() {
300 List<Intent> intentsToInstall = createFlowRuleIntents();
301 List<Intent> intentsToUninstall = createFlowRuleIntentsWithSameMatch();
302
303 IntentData toInstall = new IntentData(createP2PIntent(),
304 IntentState.INSTALLING,
305 new WallClockTimestamp());
306 toInstall = new IntentData(toInstall, intentsToInstall);
307 IntentData toUninstall = new IntentData(createP2PIntent(),
308 IntentState.INSTALLED,
309 new WallClockTimestamp());
310 toUninstall = new IntentData(toUninstall, intentsToUninstall);
311
312 IntentOperationContext<FlowRuleIntent> operationContext;
313 IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
314 operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
315
316 installer.apply(operationContext);
317
318 IntentOperationContext successContext = intentInstallCoordinator.successContext;
319 assertEquals(successContext, operationContext);
320
321 assertEquals(0, flowRuleService.flowRulesRemove.size());
322 assertEquals(0, flowRuleService.flowRulesAdd.size());
323 assertEquals(1, flowRuleService.flowRulesModify.size());
324
325 FlowRuleIntent installedIntent = (FlowRuleIntent) intentsToInstall.get(0);
326 assertEquals(flowRuleService.flowRulesModify.size(), installedIntent.flowRules().size());
327 assertTrue(flowRuleService.flowRulesModify.containsAll(installedIntent.flowRules()));
328 }
329
330 /**
Yi Tsengc927a062017-05-02 15:02:37 -0700331 * Generates FlowRuleIntents for test.
332 *
333 * @return the FlowRuleIntents for test
334 */
335 public List<Intent> createFlowRuleIntents() {
336 TrafficSelector selector = DefaultTrafficSelector.builder()
337 .matchInPhyPort(CP1.port())
338 .build();
339 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
340 .setOutput(CP2.port())
341 .build();
342
343 FlowRule flowRule = DefaultFlowRule.builder()
344 .forDevice(CP1.deviceId())
345 .withSelector(selector)
346 .withTreatment(treatment)
347 .fromApp(APP_ID)
348 .withPriority(DEFAULT_PRIORITY)
349 .makePermanent()
350 .build();
351
352 List<NetworkResource> resources = ImmutableList.of(CP1.deviceId());
353
354 FlowRuleIntent intent = new FlowRuleIntent(APP_ID,
355 KEY1,
356 ImmutableList.of(flowRule),
357 resources,
358 PathIntent.ProtectionType.PRIMARY,
359 RG1);
360
361 List<Intent> flowRuleIntents = Lists.newArrayList();
362 flowRuleIntents.add(intent);
363
364 return flowRuleIntents;
365 }
366
367 /**
Yi Tsengc29d8822017-10-25 16:19:25 -0700368 * Generates FlowRuleIntents for test. Flow rules in Intent should have same
369 * match as we created by createFlowRuleIntents method, but action will be
370 * different.
371 *
372 * @return the FlowRuleIntents for test
373 */
374 public List<Intent> createFlowRuleIntentsWithSameMatch() {
375 TrafficSelector selector = DefaultTrafficSelector.builder()
376 .matchInPhyPort(CP1.port())
377 .build();
378 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
379 .punt()
380 .build();
381
382 FlowRule flowRule = DefaultFlowRule.builder()
383 .forDevice(CP1.deviceId())
384 .withSelector(selector)
385 .withTreatment(treatment)
386 .fromApp(APP_ID)
387 .withPriority(DEFAULT_PRIORITY)
388 .makePermanent()
389 .build();
390
391 List<NetworkResource> resources = ImmutableList.of(CP1.deviceId());
392
393 FlowRuleIntent intent = new FlowRuleIntent(APP_ID,
394 KEY1,
395 ImmutableList.of(flowRule),
396 resources,
397 PathIntent.ProtectionType.PRIMARY,
398 RG1);
399
400 List<Intent> flowRuleIntents = Lists.newArrayList();
401 flowRuleIntents.add(intent);
402
403 return flowRuleIntents;
404 }
405
406 /**
Yi Tsengc927a062017-05-02 15:02:37 -0700407 * Generates another different FlowRuleIntents for test.
408 *
409 * @return the FlowRuleIntents for test
410 */
411 public List<Intent> createAnotherFlowRuleIntents() {
412 TrafficSelector selector = DefaultTrafficSelector.builder()
413 .matchVlanId(VlanId.vlanId("100"))
414 .matchInPhyPort(CP1.port())
415 .build();
416 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
417 .setOutput(CP2.port())
418 .build();
419
420 FlowRule flowRule = DefaultFlowRule.builder()
421 .forDevice(CP1.deviceId())
422 .withSelector(selector)
423 .withTreatment(treatment)
424 .fromApp(APP_ID)
425 .withPriority(DEFAULT_PRIORITY)
426 .makePermanent()
427 .build();
428
429 List<NetworkResource> resources = ImmutableList.of(CP1.deviceId());
430
431 FlowRuleIntent intent = new FlowRuleIntent(APP_ID,
432 KEY1,
433 ImmutableList.of(flowRule),
434 resources,
435 PathIntent.ProtectionType.PRIMARY,
436 RG1);
437
438 List<Intent> flowRuleIntents = Lists.newArrayList();
439 flowRuleIntents.add(intent);
440
441 return flowRuleIntents;
442 }
443
444 /**
445 * The FlowRuleService for test; always success for any flow rule operations.
446 */
447 class TestFlowRuleService extends FlowRuleServiceAdapter {
448
449 Set<FlowRule> flowRulesAdd = Sets.newHashSet();
Yi Tsengc29d8822017-10-25 16:19:25 -0700450 Set<FlowRule> flowRulesModify = Sets.newHashSet();
Yi Tsengc927a062017-05-02 15:02:37 -0700451 Set<FlowRule> flowRulesRemove = Sets.newHashSet();
452
453 public void record(FlowRuleOperations ops) {
454 flowRulesAdd.clear();
455 flowRulesRemove.clear();
456 ops.stages().forEach(stage -> {
457 stage.forEach(op -> {
458 switch (op.type()) {
459 case ADD:
460 flowRulesAdd.add(op.rule());
461 break;
462 case REMOVE:
463 flowRulesRemove.add(op.rule());
464 break;
Yi Tsengc29d8822017-10-25 16:19:25 -0700465 case MODIFY:
466 flowRulesModify.add(op.rule());
Yi Tsengc927a062017-05-02 15:02:37 -0700467 default:
468 break;
469 }
470 });
471 });
472 }
473
474 @Override
475 public void apply(FlowRuleOperations ops) {
476 record(ops);
477 ops.callback().onSuccess(ops);
478 }
479 }
480
481 /**
482 * The FlowRuleService for test; always failed for any flow rule operations.
483 */
484 class TestFailedFlowRuleService extends TestFlowRuleService {
485 @Override
486 public void apply(FlowRuleOperations ops) {
487 record(ops);
488 ops.callback().onError(ops);
489 }
490 }
491
492}