blob: 418392b46b6d340a966dcf8acdea833f6b9338d3 [file] [log] [blame]
/*
* Copyright 2017-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.net.intent.impl.installer;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.VlanId;
import org.onosproject.net.NetworkResource;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.FlowRuleOperations;
import org.onosproject.net.flow.FlowRuleServiceAdapter;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.FlowRuleIntent;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentData;
import org.onosproject.net.intent.IntentInstallationContext;
import org.onosproject.net.intent.IntentOperationContext;
import org.onosproject.net.intent.IntentState;
import org.onosproject.net.intent.PathIntent;
import org.onosproject.store.service.WallClockTimestamp;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static org.junit.Assert.*;
/**
* Tests for flow rule Intent installer.
*/
public class FlowRuleIntentInstallerTest extends AbstractIntentInstallerTest {
private TestFlowRuleService flowRuleService;
private FlowRuleIntentInstaller installer;
@Before
public void setup() {
super.setup();
flowRuleService = new TestFlowRuleService();
installer = new FlowRuleIntentInstaller();
installer.flowRuleService = flowRuleService;
installer.intentExtensionService = intentExtensionService;
installer.intentInstallCoordinator = intentInstallCoordinator;
installer.trackerService = trackerService;
installer.activate();
}
@After
public void tearDown() {
super.tearDown();
installer.deactivated();
}
/**
* Installs Intents only, no Intents to be uninstall.
*/
@Test
public void testInstallOnly() {
List<Intent> intentsToUninstall = Lists.newArrayList();
List<Intent> intentsToInstall = createFlowRuleIntents();
IntentData toUninstall = null;
IntentData toInstall = new IntentData(createP2PIntent(),
IntentState.INSTALLING,
new WallClockTimestamp());
toInstall = new IntentData(toInstall, intentsToInstall);
IntentOperationContext<FlowRuleIntent> operationContext;
IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
installer.apply(operationContext);
IntentOperationContext successContext = intentInstallCoordinator.successContext;
assertEquals(successContext, operationContext);
Set<FlowRule> expectedFlowRules = intentsToInstall.stream()
.map(intent -> (FlowRuleIntent) intent)
.map(FlowRuleIntent::flowRules)
.flatMap(Collection::stream)
.collect(Collectors.toSet());
assertEquals(expectedFlowRules, flowRuleService.flowRulesAdd);
}
/**
* Uninstalls Intents only, no Intents to be install.
*/
@Test
public void testUninstallOnly() {
List<Intent> intentsToInstall = Lists.newArrayList();
List<Intent> intentsToUninstall = createFlowRuleIntents();
IntentData toInstall = null;
IntentData toUninstall = new IntentData(createP2PIntent(),
IntentState.WITHDRAWING,
new WallClockTimestamp());
toUninstall = new IntentData(toUninstall, intentsToUninstall);
IntentOperationContext<FlowRuleIntent> operationContext;
IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
installer.apply(operationContext);
IntentOperationContext successContext = intentInstallCoordinator.successContext;
assertEquals(successContext, operationContext);
Set<FlowRule> expectedFlowRules = intentsToUninstall.stream()
.map(intent -> (FlowRuleIntent) intent)
.map(FlowRuleIntent::flowRules)
.flatMap(Collection::stream)
.collect(Collectors.toSet());
assertEquals(expectedFlowRules, flowRuleService.flowRulesRemove);
}
/**
* Do both install and uninstall Intents with different flow rules.
*/
@Test
public void testUninstallAndInstall() {
List<Intent> intentsToInstall = createAnotherFlowRuleIntents();
List<Intent> intentsToUninstall = createFlowRuleIntents();
IntentData toInstall = new IntentData(createP2PIntent(),
IntentState.INSTALLING,
new WallClockTimestamp());
toInstall = new IntentData(toInstall, intentsToInstall);
IntentData toUninstall = new IntentData(createP2PIntent(),
IntentState.INSTALLED,
new WallClockTimestamp());
toUninstall = new IntentData(toUninstall, intentsToUninstall);
IntentOperationContext<FlowRuleIntent> operationContext;
IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
installer.apply(operationContext);
IntentOperationContext successContext = intentInstallCoordinator.successContext;
assertEquals(successContext, operationContext);
Set<FlowRule> expectedFlowRules = intentsToUninstall.stream()
.map(intent -> (FlowRuleIntent) intent)
.map(FlowRuleIntent::flowRules)
.flatMap(Collection::stream)
.collect(Collectors.toSet());
assertEquals(expectedFlowRules, flowRuleService.flowRulesRemove);
expectedFlowRules = intentsToInstall.stream()
.map(intent -> (FlowRuleIntent) intent)
.map(FlowRuleIntent::flowRules)
.flatMap(Collection::stream)
.collect(Collectors.toSet());
assertEquals(expectedFlowRules, flowRuleService.flowRulesAdd);
}
/**
* Do both install and uninstall Intents with same flow rules.
*/
@Test
public void testUninstallAndInstallUnchanged() {
List<Intent> intentsToInstall = createFlowRuleIntents();
List<Intent> intentsToUninstall = createFlowRuleIntents();
IntentData toInstall = new IntentData(createP2PIntent(),
IntentState.INSTALLING,
new WallClockTimestamp());
toInstall = new IntentData(toInstall, intentsToInstall);
IntentData toUninstall = new IntentData(createP2PIntent(),
IntentState.INSTALLED,
new WallClockTimestamp());
toUninstall = new IntentData(toUninstall, intentsToUninstall);
IntentOperationContext<FlowRuleIntent> operationContext;
IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
installer.apply(operationContext);
IntentOperationContext successContext = intentInstallCoordinator.successContext;
assertEquals(successContext, operationContext);
assertEquals(0, flowRuleService.flowRulesRemove.size());
assertEquals(0, flowRuleService.flowRulesAdd.size());
}
/**
* Do both install and uninstall Intents with same flow rule Intent.
*/
@Test
public void testUninstallAndInstallSame() {
List<Intent> intentsToInstall = createFlowRuleIntents();
List<Intent> intentsToUninstall = intentsToInstall;
IntentData toInstall = new IntentData(createP2PIntent(),
IntentState.INSTALLING,
new WallClockTimestamp());
toInstall = new IntentData(toInstall, intentsToInstall);
IntentData toUninstall = new IntentData(createP2PIntent(),
IntentState.INSTALLED,
new WallClockTimestamp());
toUninstall = new IntentData(toUninstall, intentsToUninstall);
IntentOperationContext<FlowRuleIntent> operationContext;
IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
installer.apply(operationContext);
IntentOperationContext successContext = intentInstallCoordinator.successContext;
assertEquals(successContext, operationContext);
assertEquals(0, flowRuleService.flowRulesRemove.size());
assertEquals(0, flowRuleService.flowRulesAdd.size());
}
/**
* Nothing to uninstall or install.
*/
@Test
public void testNoAnyIntentToApply() {
IntentData toInstall = null;
IntentData toUninstall = null;
IntentOperationContext<FlowRuleIntent> operationContext;
IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
operationContext = new IntentOperationContext<>(ImmutableList.of(), ImmutableList.of(), context);
installer.apply(operationContext);
IntentOperationContext successContext = intentInstallCoordinator.successContext;
assertEquals(successContext, operationContext);
assertEquals(0, flowRuleService.flowRulesRemove.size());
assertEquals(0, flowRuleService.flowRulesAdd.size());
}
/**
* Test if the flow installation failed.
*/
@Test
public void testFailed() {
installer.flowRuleService = new TestFailedFlowRuleService();
List<Intent> intentsToUninstall = Lists.newArrayList();
List<Intent> intentsToInstall = createFlowRuleIntents();
IntentData toUninstall = null;
IntentData toInstall = new IntentData(createP2PIntent(),
IntentState.INSTALLING,
new WallClockTimestamp());
toInstall = new IntentData(toInstall, intentsToInstall);
IntentOperationContext<FlowRuleIntent> operationContext;
IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
installer.apply(operationContext);
IntentOperationContext failedContext = intentInstallCoordinator.failedContext;
assertEquals(failedContext, operationContext);
}
/**
* Generates FlowRuleIntents for test.
*
* @return the FlowRuleIntents for test
*/
public List<Intent> createFlowRuleIntents() {
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchInPhyPort(CP1.port())
.build();
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
.setOutput(CP2.port())
.build();
FlowRule flowRule = DefaultFlowRule.builder()
.forDevice(CP1.deviceId())
.withSelector(selector)
.withTreatment(treatment)
.fromApp(APP_ID)
.withPriority(DEFAULT_PRIORITY)
.makePermanent()
.build();
List<NetworkResource> resources = ImmutableList.of(CP1.deviceId());
FlowRuleIntent intent = new FlowRuleIntent(APP_ID,
KEY1,
ImmutableList.of(flowRule),
resources,
PathIntent.ProtectionType.PRIMARY,
RG1);
List<Intent> flowRuleIntents = Lists.newArrayList();
flowRuleIntents.add(intent);
return flowRuleIntents;
}
/**
* Generates another different FlowRuleIntents for test.
*
* @return the FlowRuleIntents for test
*/
public List<Intent> createAnotherFlowRuleIntents() {
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchVlanId(VlanId.vlanId("100"))
.matchInPhyPort(CP1.port())
.build();
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
.setOutput(CP2.port())
.build();
FlowRule flowRule = DefaultFlowRule.builder()
.forDevice(CP1.deviceId())
.withSelector(selector)
.withTreatment(treatment)
.fromApp(APP_ID)
.withPriority(DEFAULT_PRIORITY)
.makePermanent()
.build();
List<NetworkResource> resources = ImmutableList.of(CP1.deviceId());
FlowRuleIntent intent = new FlowRuleIntent(APP_ID,
KEY1,
ImmutableList.of(flowRule),
resources,
PathIntent.ProtectionType.PRIMARY,
RG1);
List<Intent> flowRuleIntents = Lists.newArrayList();
flowRuleIntents.add(intent);
return flowRuleIntents;
}
/**
* The FlowRuleService for test; always success for any flow rule operations.
*/
class TestFlowRuleService extends FlowRuleServiceAdapter {
Set<FlowRule> flowRulesAdd = Sets.newHashSet();
Set<FlowRule> flowRulesRemove = Sets.newHashSet();
public void record(FlowRuleOperations ops) {
flowRulesAdd.clear();
flowRulesRemove.clear();
ops.stages().forEach(stage -> {
stage.forEach(op -> {
switch (op.type()) {
case ADD:
flowRulesAdd.add(op.rule());
break;
case REMOVE:
flowRulesRemove.add(op.rule());
break;
default:
break;
}
});
});
}
@Override
public void apply(FlowRuleOperations ops) {
record(ops);
ops.callback().onSuccess(ops);
}
}
/**
* The FlowRuleService for test; always failed for any flow rule operations.
*/
class TestFailedFlowRuleService extends TestFlowRuleService {
@Override
public void apply(FlowRuleOperations ops) {
record(ops);
ops.callback().onError(ops);
}
}
}