blob: 34acd421f1ae12ae06a3afec2d138d5cf9705844 [file] [log] [blame]
/*
* Copyright 2015-present Open Networking Foundation
*
* 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.flowobjective;
import com.google.common.testing.EqualsTester;
import org.junit.Test;
import org.onosproject.TestApplicationId;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.Criteria;
import org.onosproject.net.flow.criteria.Criterion;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.not;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.flowobjective.FilteringObjective.Type.DENY;
import static org.onosproject.net.flowobjective.ForwardingObjective.Flag.SPECIFIC;
import static org.onosproject.net.flowobjective.ForwardingObjective.Flag.VERSATILE;
import static org.onosproject.net.flowobjective.NextObjective.Type.HASHED;
import static org.onosproject.net.flowobjective.Objective.Operation.ADD;
import static org.onosproject.net.flowobjective.Objective.Operation.ADD_TO_EXISTING;
import static org.onosproject.net.flowobjective.Objective.Operation.REMOVE;
import static org.onosproject.net.flowobjective.Objective.Operation.REMOVE_FROM_EXISTING;
/**
* Unit tests for forwarding objective class.
*/
public class ObjectiveTest {
private final TrafficTreatment treatment =
DefaultTrafficTreatment.emptyTreatment();
private final TrafficSelector selector =
DefaultTrafficSelector.emptySelector();
private final Criterion criterion = Criteria.dummy();
private final Criterion key = Criteria.dummy();
/**
* Checks immutability of objective classes.
*/
@Test
public void testImmutability() {
assertThatClassIsImmutable(DefaultFilteringObjective.class);
assertThatClassIsImmutable(DefaultForwardingObjective.class);
assertThatClassIsImmutable(DefaultNextObjective.class);
}
// Forwarding Objectives
/**
* Makes a forwarding objective builder with a set of default values.
*
* @return forwarding objective builder
*/
private ForwardingObjective.Builder baseForwardingBuilder() {
return DefaultForwardingObjective.builder()
.withSelector(selector)
.withTreatment(treatment)
.withFlag(SPECIFIC)
.withMeta(selector)
.fromApp(APP_ID)
.withPriority(22)
.makeTemporary(5)
.nextStep(33);
}
/**
* Checks the default values of a forwarding objective object.
*
* @param objective forwarding objective to check
*/
private void checkForwardingBase(ForwardingObjective objective,
Objective.Operation op,
ObjectiveContext expectedContext) {
assertThat(objective.permanent(), is(false));
assertThat(objective.timeout(), is(5));
assertThat(objective.selector(), is(selector));
assertThat(objective.meta(), is(selector));
assertThat(objective.treatment(), is(treatment));
assertThat(objective.flag(), is(SPECIFIC));
assertThat(objective.appId(), is(APP_ID));
assertThat(objective.nextId(), is(33));
assertThat(objective.id(), is(not(0)));
assertThat(objective.priority(), is(22));
assertThat(objective.op(), is(op));
if (objective.context().isPresent()) {
assertThat(objective.context().get(), is(expectedContext));
} else {
assertThat(expectedContext, nullValue());
}
}
/**
* Tests that forwarding objective objects are built correctly using the
* add() method.
*/
@Test
public void testForwardingAdd() {
checkForwardingBase(baseForwardingBuilder().add(), ADD, null);
}
/**
* Tests that forwarding objective objects are built correctly using the
* add(context) method.
*/
@Test
public void testForwardingAddWithContext() {
ObjectiveContext context = new DefaultObjectiveContext(null, null);
checkForwardingBase(baseForwardingBuilder().add(context), ADD, context);
}
/**
* Tests that forwarding objective objects are built correctly using the
* remove() method.
*/
@Test
public void testForwardingRemove() {
checkForwardingBase(baseForwardingBuilder().remove(), REMOVE, null);
}
/**
* Tests that forwarding objective objects are built correctly using the
* remove(context) method.
*/
@Test
public void testForwardingRemoveWithContext() {
ObjectiveContext context = new DefaultObjectiveContext(null, null);
checkForwardingBase(baseForwardingBuilder().remove(context), REMOVE, context);
}
// Filtering objectives
/**
* Makes a filtering objective builder with a set of default values.
*
* @return filtering objective builder
*/
private FilteringObjective.Builder baseFilteringBuilder() {
return DefaultFilteringObjective.builder()
.withKey(key)
.withPriority(5)
.withMeta(treatment)
.addCondition(criterion)
.fromApp(APP_ID)
.makeTemporary(2)
.deny();
}
/**
* Checks the default values of a filtering objective object.
*
* @param objective filtering objective to check
*/
private void checkFilteringBase(FilteringObjective objective,
Objective.Operation op,
ObjectiveContext expectedContext) {
assertThat(objective.key(), is(key));
assertThat(objective.conditions(), hasItem(criterion));
assertThat(objective.meta(), is(treatment));
assertThat(objective.permanent(), is(false));
assertThat(objective.timeout(), is(2));
assertThat(objective.priority(), is(5));
assertThat(objective.appId(), is(APP_ID));
assertThat(objective.type(), is(DENY));
assertThat(objective.id(), is(not(0)));
assertThat(objective.op(), is(op));
if (objective.context().isPresent()) {
assertThat(objective.context().get(), is(expectedContext));
} else {
assertThat(expectedContext, nullValue());
}
}
/**
* Tests that forwarding objective objects are built correctly using the
* add() method.
*/
@Test
public void testFilteringAdd() {
checkFilteringBase(baseFilteringBuilder().add(), ADD, null);
}
/**
* Tests that forwarding objective objects are built correctly using the
* add(context) method.
*/
@Test
public void testFilteringAddWithContext() {
ObjectiveContext context = new DefaultObjectiveContext(null, null);
checkFilteringBase(baseFilteringBuilder().add(context), ADD, context);
}
/**
* Tests that forwarding objective objects are built correctly using the
* remove() method.
*/
@Test
public void testFilteringRemove() {
checkFilteringBase(baseFilteringBuilder().remove(), REMOVE, null);
}
/**
* Tests that forwarding objective objects are built correctly using the
* remove(context) method.
*/
@Test
public void testFilteringRemoveWithContext() {
ObjectiveContext context = new DefaultObjectiveContext(null, null);
checkFilteringBase(baseFilteringBuilder().remove(context), REMOVE, context);
}
// Next objectives
/**
* Makes a next objective builder with a set of default values.
*
* @return next objective builder
*/
private NextObjective.Builder baseNextBuilder() {
return DefaultNextObjective.builder()
.addTreatment(treatment)
.withId(12)
.withType(HASHED)
.withMeta(selector)
.makeTemporary(777)
.withPriority(33)
.fromApp(APP_ID);
}
/**
* Checks the default values of a next objective object.
*
* @param objective next objective to check
*/
private void checkNextBase(NextObjective objective,
Objective.Operation op,
ObjectiveContext expectedContext) {
assertThat(objective.id(), is(12));
assertThat(objective.appId(), is(APP_ID));
assertThat(objective.type(), is(HASHED));
assertThat(objective.next(), hasItem(treatment));
assertThat(objective.meta(), is(selector));
assertThat(objective.permanent(), is(false));
assertThat(objective.timeout(), is(0));
assertThat(objective.priority(), is(0));
assertThat(objective.op(), is(op));
if (objective.context().isPresent()) {
assertThat(objective.context().get(), is(expectedContext));
} else {
assertThat(expectedContext, nullValue());
}
}
/**
* Tests that forwarding objective objects are built correctly using the
* add() method.
*/
@Test
public void testNextAdd() {
checkNextBase(baseNextBuilder().add(), ADD, null);
}
/**
* Tests that forwarding objective objects are built correctly using the
* add(context) method.
*/
@Test
public void testNextAddWithContext() {
ObjectiveContext context = new DefaultObjectiveContext(null, null);
checkNextBase(baseNextBuilder().add(context), ADD, context);
}
/**
* Tests that forwarding objective objects are built correctly using the
* remove() method.
*/
@Test
public void testNextRemove() {
checkNextBase(baseNextBuilder().remove(), REMOVE, null);
}
/**
* Tests that forwarding objective objects are built correctly using the
* remove(context) method.
*/
@Test
public void testNextRemoveWithContext() {
ObjectiveContext context = new DefaultObjectiveContext(null, null);
checkNextBase(baseNextBuilder().remove(context), REMOVE, context);
}
/**
* Tests equality, hash, and toString operations on next objectives.
*/
@Test
public void testEqualsNextObjective() {
NextObjective next1 = baseNextBuilder().add();
NextObjective sameAsNext1 = next1.copy().add();
NextObjective next2 = baseNextBuilder().verify();
NextObjective next3 = baseNextBuilder().fromApp(new TestApplicationId("foo2")).verify();
NextObjective next4 = baseNextBuilder().withType(NextObjective.Type.FAILOVER).verify();
NextObjective next5 = baseNextBuilder().addTreatment(DefaultTrafficTreatment.emptyTreatment()).verify();
new EqualsTester()
.addEqualityGroup(next1, sameAsNext1)
.addEqualityGroup(next2)
.addEqualityGroup(next3)
.addEqualityGroup(next4)
.addEqualityGroup(next5)
.testEquals();
}
/**
* Tests add to an existing next objective.
*/
@Test
public void testToFromExistingNextObjective() {
NextObjective next1 = baseNextBuilder().addToExisting();
checkNextBase(next1, ADD_TO_EXISTING, null);
}
/**
* Tests remove from an existing next objective.
*/
@Test
public void testRemoveFromExistingNextObjective() {
NextObjective next1 = baseNextBuilder().removeFromExisting();
checkNextBase(next1, REMOVE_FROM_EXISTING, null);
}
/**
* Tests equality, hash, and toString operations on filtering objectives.
*/
@Test
public void testEqualsFilteringObjective() {
FilteringObjective filter1 = baseFilteringBuilder().add();
FilteringObjective sameAsFilter1 = filter1.copy().add();
FilteringObjective filter2 = baseFilteringBuilder().permit().add();
FilteringObjective filter3 = baseFilteringBuilder().fromApp(new TestApplicationId("foo2")).add();
FilteringObjective filter4 = baseFilteringBuilder().permit().remove();
FilteringObjective filter5 = baseFilteringBuilder().withPriority(55).add();
FilteringObjective filter6 = baseFilteringBuilder().makePermanent().add();
new EqualsTester()
.addEqualityGroup(filter1, sameAsFilter1)
.addEqualityGroup(filter2)
.addEqualityGroup(filter3)
.addEqualityGroup(filter4)
.addEqualityGroup(filter5)
.addEqualityGroup(filter6)
.testEquals();
}
/**
* Tests add to an existing filtering objective.
*/
@Test
public void testToFromExistingFilteringObjective() {
FilteringObjective filter1 = baseFilteringBuilder().add(null);
checkFilteringBase(filter1, ADD, null);
}
/**
* Tests remove from an existing filtering objective.
*/
@Test
public void testRemoveFromExistingFilteringObjective() {
FilteringObjective filter1 = baseFilteringBuilder().remove(null);
checkFilteringBase(filter1, REMOVE, null);
}
/**
* Tests equality, hash, and toString operations on filtering objectives.
*/
@Test
public void testEqualsForwardingObjective() {
ForwardingObjective forward1 = baseForwardingBuilder().add();
ForwardingObjective sameAsForward1 = forward1.copy().add();
ForwardingObjective forward2 = baseForwardingBuilder().withFlag(VERSATILE).add();
ForwardingObjective forward3 = baseForwardingBuilder().fromApp(new TestApplicationId("foo2")).add();
ForwardingObjective forward4 = baseForwardingBuilder().remove();
ForwardingObjective forward5 = baseForwardingBuilder().withPriority(55).add();
ForwardingObjective forward6 = baseForwardingBuilder().makePermanent().add();
new EqualsTester()
.addEqualityGroup(forward1, sameAsForward1)
.addEqualityGroup(forward2)
.addEqualityGroup(forward3)
.addEqualityGroup(forward4)
.addEqualityGroup(forward5)
.addEqualityGroup(forward6)
.testEquals();
}
/**
* Tests add to an existing forwarding objective.
*/
@Test
public void testToFromExistingForwardingObjective() {
ForwardingObjective forward1 = baseForwardingBuilder().add(null);
checkForwardingBase(forward1, ADD, null);
}
/**
* Tests remove from an existing forwarding objective.
*/
@Test
public void testRemoveFromExistingForwardingObjective() {
ForwardingObjective forward1 = baseForwardingBuilder().remove(null);
checkForwardingBase(forward1, REMOVE, null);
}
enum ContextType {
BOTH,
ERROR_ONLY,
SUCCESS_ONLY
}
class ObjectiveContextAdapter implements ObjectiveContext {
DefaultObjectiveContext context;
int successCount = 0;
int errorCount = 0;
ObjectiveError objectiveError = ObjectiveError.UNKNOWN;
Objective objectiveInError = null;
ObjectiveContextAdapter(ContextType type) {
switch (type) {
case ERROR_ONLY:
context = new DefaultObjectiveContext(
(failedObjective, error) -> {
errorCount++;
objectiveInError = failedObjective;
objectiveError = error;
});
break;
case SUCCESS_ONLY:
context = new DefaultObjectiveContext(
(successfulObjective) -> successCount++);
break;
case BOTH:
default:
context = new DefaultObjectiveContext(
(successfulObjective) -> successCount++,
(failedObjective, error) -> {
errorCount++;
objectiveInError = failedObjective;
objectiveError = error;
});
break;
}
}
@Override
public void onSuccess(Objective objective) {
context.onSuccess(objective);
}
@Override
public void onError(Objective objective, ObjectiveError error) {
context.onError(objective, error);
}
int successCount() {
return successCount;
}
int errorCount() {
return errorCount;
}
ObjectiveError objectiveError() {
return objectiveError;
}
Objective objectiveInError() {
return objectiveInError;
}
}
/**
* Tests default objective context.
*/
@Test
public void testDefaultContext() {
Objective objective = baseFilteringBuilder().add();
ObjectiveContextAdapter context;
context = new ObjectiveContextAdapter(ContextType.BOTH);
context.onSuccess(objective);
assertThat(context.successCount(), is(1));
assertThat(context.errorCount(), is(0));
assertThat(context.objectiveError(), is(ObjectiveError.UNKNOWN));
assertThat(context.objectiveInError(), nullValue());
context = new ObjectiveContextAdapter(ContextType.BOTH);
context.onError(objective, ObjectiveError.UNSUPPORTED);
assertThat(context.successCount(), is(0));
assertThat(context.errorCount(), is(1));
assertThat(context.objectiveError(), is(ObjectiveError.UNSUPPORTED));
assertThat(context.objectiveInError(), equalTo(objective));
context = new ObjectiveContextAdapter(ContextType.SUCCESS_ONLY);
context.onSuccess(objective);
assertThat(context.successCount(), is(1));
assertThat(context.errorCount(), is(0));
assertThat(context.objectiveError(), is(ObjectiveError.UNKNOWN));
assertThat(context.objectiveInError(), nullValue());
context = new ObjectiveContextAdapter(ContextType.ERROR_ONLY);
context.onError(objective, ObjectiveError.UNSUPPORTED);
assertThat(context.successCount(), is(0));
assertThat(context.errorCount(), is(1));
assertThat(context.objectiveError(), is(ObjectiveError.UNSUPPORTED));
assertThat(context.objectiveInError(), equalTo(objective));
}
}