[ONOS-6865] enforcing same label and [ONOS-6895] minimize label swapping
- Re design label allocator to allow several opt. behavior
- Implements NO Swap algorithm in label allocator
- Implements MIN Swap algorithm in label allocator
- Improve unit tests
Change-Id: I39eb8570cb83734b9c2b106f9c48bf50a4e69499
diff --git a/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java b/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java
index 9952e46..62613e0 100644
--- a/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java
+++ b/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java
@@ -40,6 +40,7 @@
private final Map<Resource, ResourceConsumer> assignment = new HashMap<>();
public Set<Short> availableVlanLabels = new HashSet<>();
public Set<Integer> availableMplsLabels = new HashSet<>();
+ public boolean filterAssignment = false;
public MockResourceService(){}
@@ -169,7 +170,11 @@
resources.add(Resources.discrete(parent).resource().child(TributarySlot.of(6)));
resources.add(Resources.discrete(parent).resource().child(TributarySlot.of(7)));
resources.add(Resources.discrete(parent).resource().child(TributarySlot.of(8)));
- return ImmutableSet.copyOf(resources);
+ return filterAssignment ? ImmutableSet.copyOf(
+ resources.stream().filter(
+ resource -> assignment.get(resource) == null
+ ).collect(Collectors.toSet())
+ ) : ImmutableSet.copyOf(resources);
}
@Override
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/IntentConfigurableRegistrator.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/IntentConfigurableRegistrator.java
index e873fa8..d1b44ca 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/IntentConfigurableRegistrator.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/IntentConfigurableRegistrator.java
@@ -69,6 +69,12 @@
label = "Defines the label selection algorithm - RANDOM or FIRST_FIT")
private String labelSelection = DEFAULT_LABEL_SELECTION;
+ private static final String DEFAULT_OPT_LABEL_SELECTION = "NONE";
+ @Property(name = "optLabelSelection",
+ value = DEFAULT_OPT_LABEL_SELECTION,
+ label = "Defines the optimization for label selection algorithm - NONE, NO_SWAP, MIN_SWAP")
+ private String optLabelSelection = DEFAULT_OPT_LABEL_SELECTION;
+
private static final boolean DEFAULT_FLOW_OPTIMIZATION = false;
@Property(name = "optimizeInstructions",
boolValue = DEFAULT_FLOW_OPTIMIZATION,
@@ -117,6 +123,7 @@
log.info("Settings: labelSelection={}", labelSelection);
log.info("Settings: useFlowOptimization={}", optimizeInstructions);
log.info("Settings: useCopyTtl={}", useCopyTtl);
+ log.info("Settings: optLabelSelection={}", optLabelSelection);
// FIXME: temporary code for switching old compiler to new compiler
log.info("Settings: defaultFlowObjectiveCompiler={}", defaultFlowObjectiveCompiler);
@@ -160,12 +167,28 @@
newLabelSelection = labelSelection;
}
- if (!labelSelection.equals(newLabelSelection) && LabelAllocator.isInEnum(newLabelSelection)) {
+ if (!labelSelection.equals(newLabelSelection) && LabelAllocator.isInSelEnum(newLabelSelection)) {
labelSelection = newLabelSelection;
changeLabelSelections();
log.info("Settings: labelSelection={}", labelSelection);
}
+ String newOptLabelSelection;
+ try {
+ // The optimization behavior provided by the user
+ String optLabelSelected = Tools.get(context.getProperties(), "optLabelSelection");
+ // Parse the content of the string
+ newOptLabelSelection = isNullOrEmpty(optLabelSelected) ? optLabelSelection : optLabelSelected.trim();
+ } catch (ClassCastException e) {
+ newOptLabelSelection = optLabelSelection;
+ }
+
+ if (!optLabelSelection.equals(newOptLabelSelection) && LabelAllocator.isInOptEnum(newOptLabelSelection)) {
+ optLabelSelection = newOptLabelSelection;
+ changeOptLabelSelections();
+ log.info("Settings: optLabelSelection={}", optLabelSelection);
+ }
+
boolean newFlowOptimization;
try {
String s = Tools.get(context.getProperties(), "useFlowOptimization");
@@ -265,6 +288,10 @@
LinkCollectionCompiler.labelAllocator.setLabelSelection(labelSelection);
}
+ private void changeOptLabelSelections() {
+ LinkCollectionCompiler.labelAllocator.setOptLabelSelection(optLabelSelection);
+ }
+
private void changeFlowOptimization() {
LinkCollectionCompiler.optimizeInstructions = optimizeInstructions;
}
diff --git a/core/net/src/main/java/org/onosproject/net/resource/impl/LabelAllocator.java b/core/net/src/main/java/org/onosproject/net/resource/impl/LabelAllocator.java
index 34c8285..bc41fb1 100644
--- a/core/net/src/main/java/org/onosproject/net/resource/impl/LabelAllocator.java
+++ b/core/net/src/main/java/org/onosproject/net/resource/impl/LabelAllocator.java
@@ -34,10 +34,13 @@
import org.onosproject.net.resource.ResourceConsumer;
import org.onosproject.net.resource.ResourceService;
import org.onosproject.net.resource.Resources;
+import org.slf4j.Logger;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
import java.util.Collections;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -50,7 +53,12 @@
*/
public final class LabelAllocator {
- private enum Behavior {
+ private final Logger log = getLogger(getClass());
+
+ /**
+ * Defines possible behaviors for the selection of the labels.
+ */
+ private enum SelectionBehavior {
/**
* Random selection.
*/
@@ -61,30 +69,67 @@
FIRST_FIT
}
- private static final Behavior[] BEHAVIORS = Behavior.values();
+ /**
+ * Defines possible optimizations for the selection of the labels.
+ */
+ enum OptimizationBehavior {
+ /**
+ * Allocator does not try to optimize, it defines a new candidates
+ * set at each hop and select label according to the selection strategy.
+ */
+ NONE,
+ /**
+ * Allocator enforces same label along the path, it builds a common
+ * set of candidate and select a common label according to the selection
+ * strategy.
+ */
+ NO_SWAP,
+ /**
+ * Allocator try to minimize the swapping of labels along the path. If
+ * it is possible try to reuse the label of the previous hop.
+ */
+ MIN_SWAP
+ }
private ResourceService resourceService;
private LabelSelection labelSelection;
+ private OptimizationBehavior optLabelSelection;
/**
- * Creates a new label allocator. Random is the
- * default behavior.
+ * Creates a new label allocator. Random is the default selection behavior.
+ * None is the default optimization behavior
*
* @param rs the resource service
*/
public LabelAllocator(ResourceService rs) {
this.resourceService = checkNotNull(rs);
- this.labelSelection = this.getLabelSelection(Behavior.RANDOM);
+ this.labelSelection = this.getLabelSelection(SelectionBehavior.RANDOM);
+ this.optLabelSelection = OptimizationBehavior.NONE;
}
/**
- * Checks if a given string is a valid Behavior.
+ * Checks if a given string is a valid Selection Behavior.
*
* @param value the string to check
- * @return true if value is a valid Behavior, false otherwise
+ * @return true if value is a valid Selection Behavior, false otherwise
*/
- public static boolean isInEnum(String value) {
- for (Behavior b : BEHAVIORS) {
+ public static boolean isInSelEnum(String value) {
+ for (SelectionBehavior b : SelectionBehavior.values()) {
+ if (b.name().equals(value)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks if a given string is a valid Optimization Behavior.
+ *
+ * @param value the string to check
+ * @return true if value is a valid Optimization Behavior, false otherwise
+ */
+ public static boolean isInOptEnum(String value) {
+ for (OptimizationBehavior b : OptimizationBehavior.values()) {
if (b.name().equals(value)) {
return true;
}
@@ -98,40 +143,60 @@
* @param type the behavior type
*/
public void setLabelSelection(String type) {
- if (isInEnum(type)) {
+ if (isInSelEnum(type)) {
this.labelSelection = this.getLabelSelection(type);
}
}
/**
- * Retrieves the label selection behavior.
+ * Retrieves the selection behavior.
*
- * @return the label selection behavior in use
+ * @return the selection behavior in use
*/
public LabelSelection getLabelSelection() {
return this.labelSelection;
}
/**
+ * Changes the optimization behavior.
+ *
+ * @param type the optimization type
+ */
+ public void setOptLabelSelection(String type) {
+ if (isInOptEnum(type)) {
+ this.optLabelSelection = OptimizationBehavior.valueOf(type);
+ }
+ }
+
+ /**
+ * Retrieves the optimization behavior.
+ *
+ * @return the optimization behavior in use
+ */
+ public OptimizationBehavior getOptLabelSelection() {
+ return this.optLabelSelection;
+ }
+
+ /**
* Returns the label selection behavior, given a behavior type.
*
* @param type the behavior type
* @return the label selection behavior in use
*/
private LabelSelection getLabelSelection(String type) {
- Behavior behavior = Behavior.valueOf(type);
+ SelectionBehavior behavior = SelectionBehavior.valueOf(type);
return this.getLabelSelection(behavior);
}
/**
- * Creates a new LabelSelection. Random is
- * the default label selection behavior.
+ * Creates a new LabelSelection. Random is the default
+ * label selection behavior.
*
* @param type the behavior type
* @return the object implementing the behavior
*/
- private LabelSelection getLabelSelection(Behavior type) {
- LabelSelection selection = null;
+ private LabelSelection getLabelSelection(SelectionBehavior type) {
+ LabelSelection selection;
switch (type) {
case FIRST_FIT:
selection = new FirstFitSelection();
@@ -144,6 +209,96 @@
return selection;
}
+ // Given a link and a encapsulation type, returns a set of candidates
+ private Set<Identifier<?>> getCandidates(LinkKey link, EncapsulationType type) {
+ // Available ids on src port
+ Set<Identifier<?>> availableIDsatSrc = getAvailableIDs(link.src(), type);
+ // Available ids on dst port
+ Set<Identifier<?>> availableIDsatDst = getAvailableIDs(link.dst(), type);
+ // Create the candidate set doing an intersection of the previous sets
+ return Sets.intersection(availableIDsatSrc, availableIDsatDst);
+ }
+
+ // Implements NONE behavior
+ private Map<LinkKey, Identifier<?>> noOptimizeBehavior(Set<LinkKey> links, EncapsulationType type) {
+ // Init step
+ Map<LinkKey, Identifier<?>> ids = Maps.newHashMap();
+ Set<Identifier<?>> candidates;
+ Identifier<?> selected;
+ // Iterates for each link selecting a label in the candidate set
+ for (LinkKey link : links) {
+ // Get candidates set for the current link
+ candidates = getCandidates(link, type);
+ // Select a label for the current link
+ selected = labelSelection.select(candidates);
+ // If candidates is empty, selected is null
+ if (selected == null) {
+ log.warn("No labels for {}", link);
+ return Collections.emptyMap();
+ }
+ // Selected is associated to link
+ ids.put(link, selected);
+ }
+ return ids;
+ }
+
+ // Implements NO_SWAP behavior
+ private Map<LinkKey, Identifier<?>> noSwapBehavior(Set<LinkKey> links, EncapsulationType type) {
+ // Init steps
+ Map<LinkKey, Identifier<?>> ids = Maps.newHashMap();
+ Identifier<?> selected;
+ Set<Identifier<?>> candidates = null;
+ Set<Identifier<?>> linkCandidates;
+ // Iterates for each link building the candidate set
+ for (LinkKey link : links) {
+ // Get candidates set for the current link
+ linkCandidates = getCandidates(link, type);
+ // Warm up
+ if (candidates == null) {
+ candidates = linkCandidates;
+ // Build step by step the intersection
+ } else {
+ candidates = Sets.intersection(candidates, linkCandidates);
+ }
+ }
+ // Pick a label according to the defined strategy
+ selected = labelSelection.select(candidates);
+ if (selected == null) {
+ // If there are no candidates, exit. This will throw a compile exception
+ log.warn("No common label for path");
+ return Collections.emptyMap();
+ }
+ // For each link create an entry
+ links.forEach(linkKey -> ids.put(linkKey, selected));
+ return ids;
+ }
+
+ // Implements MIN_SWAP behavior
+ private Map<LinkKey, Identifier<?>> minSwapBehavior(Set<LinkKey> links, EncapsulationType type) {
+ // Init step
+ Map<LinkKey, Identifier<?>> ids = Maps.newHashMap();
+ Set<Identifier<?>> candidates;
+ Identifier<?> selected = null;
+ // Iterates for each link selecting a label in the candidate set
+ for (LinkKey link : links) {
+ // Get candidates set for the current link
+ candidates = getCandidates(link, type);
+ // If we are in the first link or selected is not available
+ if (selected == null || !candidates.contains(selected)) {
+ // Select a label for the current link
+ selected = labelSelection.select(candidates);
+ // If candidates is empty, selected is null
+ if (selected == null) {
+ log.warn("No labels for {}", link);
+ return Collections.emptyMap();
+ }
+ }
+ // Selected is associated to link
+ ids.put(link, selected);
+ }
+ return ids;
+ }
+
/**
* Looks for available Ids.
*
@@ -152,21 +307,24 @@
* @return the mappings between key and id
*/
private Map<LinkKey, Identifier<?>> findAvailableIDs(Set<LinkKey> links, EncapsulationType type) {
-
- Map<LinkKey, Identifier<?>> ids = Maps.newHashMap();
- for (LinkKey link : links) {
- Set<Identifier<?>> availableIDsatSrc = getAvailableIDs(link.src(), type);
- Set<Identifier<?>> availableIDsatDst = getAvailableIDs(link.dst(), type);
- Set<Identifier<?>> common = Sets.intersection(availableIDsatSrc, availableIDsatDst);
- if (common.isEmpty()) {
- continue;
- }
- Identifier<?> selected = labelSelection.select(common);
- if (selected == null) {
- continue;
- }
- ids.put(link, selected);
+ // Init step
+ Map<LinkKey, Identifier<?>> ids;
+ // Performs label selection according to the defined optimization behavior
+ switch (optLabelSelection) {
+ // No swapping of the labels
+ case NO_SWAP:
+ ids = noSwapBehavior(links, type);
+ break;
+ // Swapping is minimized
+ case MIN_SWAP:
+ ids = minSwapBehavior(links, type);
+ break;
+ // No optimizations are in place
+ case NONE:
+ default:
+ ids = noOptimizeBehavior(links, type);
}
+ // Done exit
return ids;
}
@@ -214,9 +372,10 @@
public Map<LinkKey, Identifier<?>> assignLabelToLinks(Set<Link> links,
ResourceConsumer resourceConsumer,
EncapsulationType type) {
+ // To preserve order of the links. This is important for MIN_SWAP behavior
Set<LinkKey> linkRequest = links.stream()
.map(LinkKey::linkKey)
- .collect(Collectors.toSet());
+ .collect(Collectors.toCollection(LinkedHashSet::new));
Map<LinkKey, Identifier<?>> availableIds = findAvailableIDs(linkRequest, type);
if (availableIds.isEmpty()) {
@@ -319,7 +478,7 @@
/**
* Selects an identifier from a given set of values using
- * the first fir selection algorithm.
+ * the first fit selection algorithm.
*
* @param values the values to select from
* @return the selected identifier if values are present, null otherwise.
diff --git a/core/net/src/test/java/org/onosproject/net/resource/impl/LabelAllocatorTest.java b/core/net/src/test/java/org/onosproject/net/resource/impl/LabelAllocatorTest.java
index e069473..fe54a66 100644
--- a/core/net/src/test/java/org/onosproject/net/resource/impl/LabelAllocatorTest.java
+++ b/core/net/src/test/java/org/onosproject/net/resource/impl/LabelAllocatorTest.java
@@ -36,6 +36,7 @@
import org.onosproject.net.resource.impl.LabelAllocator.LabelSelection;
import org.onosproject.net.resource.impl.LabelAllocator.RandomSelection;
+
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -43,6 +44,7 @@
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
import static org.onosproject.net.Link.Type.DIRECT;
@@ -62,17 +64,36 @@
private final ConnectPoint d1p1 = connectPoint("s1", 1);
private final ConnectPoint d2p0 = connectPoint("s2", 0);
private final ConnectPoint d2p1 = connectPoint("s2", 1);
+ private final ConnectPoint d3p0 = connectPoint("s3", 0);
+ private final ConnectPoint d3p1 = connectPoint("s3", 1);
+ private final ConnectPoint d4p0 = connectPoint("s4", 0);
+ private final ConnectPoint d4p1 = connectPoint("s4", 1);
private final List<Link> links = Arrays.asList(
createEdgeLink(d1p0, true),
- DefaultLink.builder().providerId(PID).src(d1p1).dst(d2p1).type(DIRECT).build(),
+ DefaultLink.builder().providerId(PID).src(d1p1).dst(d3p1).type(DIRECT).build(),
+ DefaultLink.builder().providerId(PID).src(d3p0).dst(d2p1).type(DIRECT).build(),
createEdgeLink(d2p0, false)
);
+ private final List<Link> links2 = Arrays.asList(
+ createEdgeLink(d1p0, true),
+ DefaultLink.builder().providerId(PID).src(d1p1).dst(d3p1).type(DIRECT).build(),
+ DefaultLink.builder().providerId(PID).src(d3p0).dst(d4p1).type(DIRECT).build(),
+ DefaultLink.builder().providerId(PID).src(d4p0).dst(d2p1).type(DIRECT).build(),
+ createEdgeLink(d2p0, false)
+ );
+
+ // Selection behavior
private final String firstFit = "FIRST_FIT";
private final String random = "RANDOM";
private final String wrong = "BLAHBLAHBLAH";
+ // Optimization behavior
+ private final String none = "NONE";
+ private final String noswap = "NO_SWAP";
+ private final String minswap = "MIN_SWAP";
+
@Before
public void setUp() {
this.resourceService = new MockResourceService();
@@ -88,7 +109,7 @@
* To test changes to the selection behavior.
*/
@Test
- public void testChangeBehavior() {
+ public void testChangeSelBehavior() {
// It has to be an instance of LabelSelection
assertThat(this.allocator.getLabelSelection(), instanceOf(LabelSelection.class));
// By default we have Random Selection
@@ -102,174 +123,337 @@
// We put a wrong type and we should have a Random selection
this.allocator.setLabelSelection(wrong);
assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
+ // We change to first_fit and we test the change
+ this.allocator.setLabelSelection("first_fit");
+ // The change does not happen
+ assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
+ this.allocator.setLabelSelection(firstFit);
+ // We change to Random and we test the change
+ this.allocator.setLabelSelection("random");
+ // The change does not happen
+ assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
}
/**
- * To test the first fit behavior with VLAN Id. In the First step
- * we use the default set, for the first selection the selected label
- * has to be 1. In the Second step we change the default set and for
- * the first fit selection the selected has to be 2.
+ * To test changes to the optimization behavior.
*/
@Test
- public void testFirstFitBehaviorVlan() {
+ public void testChangeOptBehavior() {
+ // It has to be an instance of NONE
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NONE);
+ // Change to MIN_SWAP
+ this.allocator.setOptLabelSelection(minswap);
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.MIN_SWAP);
+ // Change to NO_SWAP
+ this.allocator.setOptLabelSelection(noswap);
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NO_SWAP);
+ // Change to NONE
+ this.allocator.setOptLabelSelection(none);
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NONE);
+ // Change to MIN_SWAP
+ this.allocator.setOptLabelSelection("miN_swap");
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NONE);
+ this.allocator.setOptLabelSelection(minswap);
+ // Change to NO_SWAP
+ this.allocator.setOptLabelSelection("No_swap");
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.MIN_SWAP);
+ this.allocator.setOptLabelSelection(noswap);
+ // Change to NONE
+ this.allocator.setOptLabelSelection("none");
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NO_SWAP);
+ }
+
+ /**
+ * To test the first fit behavior. Using NONE optimization
+ */
+ @Test
+ public void testFirstFitBehaviorNone() {
// We change to FirstFit and we test the change
this.allocator.setLabelSelection(firstFit);
assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
- // We test the behavior for VLAN
+ // It has to be an instance of NONE
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NONE);
+ // Filter reservations
+ this.resourceService.filterAssignment = true;
+ // We change the available Ids
+ this.resourceService.availableVlanLabels = ImmutableSet.of(
+ (short) 1,
+ (short) 20,
+ (short) 100
+ );
+ // First allocation on a subset of links
Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
- ImmutableSet.copyOf(links.subList(1, 2)),
+ ImmutableSet.copyOf(links.subList(2, 3)),
IntentId.valueOf(idGenerator.getNewId()),
EncapsulationType.VLAN);
- Identifier<?> id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
- // value has to be a VlanId
+ Identifier<?> id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ // value has to be a Vlan Id
assertThat(id, instanceOf(VlanId.class));
// value should not be a forbidden value
VlanId vlanId = (VlanId) id;
assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
- // value will be always 1
- assertEquals(1, vlanId.toShort());
-
- // We change the available Ids
- this.resourceService.availableVlanLabels = ImmutableSet.of(
- (short) 100,
- (short) 11,
- (short) 20,
- (short) 2,
- (short) 3
- );
- // We test again the behavior for VLAN
+ // We test the behavior for VLAN
allocation = this.allocator.assignLabelToLinks(
- ImmutableSet.copyOf(links.subList(1, 2)),
+ ImmutableSet.copyOf(links.subList(1, 3)),
IntentId.valueOf(idGenerator.getNewId()),
EncapsulationType.VLAN);
- id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
- // value has to be a VlanId
+ id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
assertThat(id, instanceOf(VlanId.class));
- // value should not be a forbidden value
vlanId = (VlanId) id;
assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
- // value will be always 2
- assertEquals(2, vlanId.toShort());
+ id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ assertThat(id, instanceOf(VlanId.class));
+ vlanId = (VlanId) id;
+ assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
}
/**
- * To test the first fit behavior with MPLS label. In the First step
- * we use the default set, for the first selection the selected label
- * has to be 1. In the Second step we change the default set and for
- * the first fit selection the selected has to be 100.
+ * To test the first fit behavior. Using NO_SWAP optimization
*/
@Test
- public void testFirstFitBehaviorMpls() {
+ public void testFirstFitBehaviorNoSwap() {
// We change to FirstFit and we test the change
this.allocator.setLabelSelection(firstFit);
assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
- // We test the behavior for MPLS
+ /// Change to NO_SWAP
+ this.allocator.setOptLabelSelection(noswap);
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NO_SWAP);
+ // Filter reservations
+ this.resourceService.filterAssignment = true;
+ // We change the available Ids
+ this.resourceService.availableMplsLabels = ImmutableSet.of(
+ 1,
+ 100,
+ 1000
+ );
+ // First allocation on a subset of links
Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
- ImmutableSet.copyOf(links.subList(1, 2)),
+ ImmutableSet.copyOf(links.subList(2, 3)),
IntentId.valueOf(idGenerator.getNewId()),
EncapsulationType.MPLS);
- Identifier<?> id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
- // value has to be a Mplslabel
+ Identifier<?> id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ // value has to be a MPLS label
assertThat(id, instanceOf(MplsLabel.class));
// value should not be a forbidden value
MplsLabel mplsLabel = (MplsLabel) id;
assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
- // value will be always 1
- assertEquals(1, mplsLabel.toInt());
-
- // We change the available Ids
- this.resourceService.availableMplsLabels = ImmutableSet.of(
- 100,
- 200,
- 1000
- );
- // We test again the behavior for MPLS
+ // We test the behavior for MPLS
allocation = this.allocator.assignLabelToLinks(
- ImmutableSet.copyOf(links.subList(1, 2)),
+ ImmutableSet.copyOf(links.subList(1, 3)),
IntentId.valueOf(idGenerator.getNewId()),
EncapsulationType.MPLS);
- id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
- // value has to be a Mplslabel
+ id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
assertThat(id, instanceOf(MplsLabel.class));
- // value should not be a forbidden value
mplsLabel = (MplsLabel) id;
assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
- // value will be always 100
- assertEquals(100, mplsLabel.toInt());
+ id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ assertThat(id, instanceOf(MplsLabel.class));
+ mplsLabel = (MplsLabel) id;
+ assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
}
/**
- * To test the random behavior with VLAN Id. We make two selection,
- * we test that these two selection are different.
+ * To test the first fit behavior. Using MIN_SWAP optimization
*/
@Test
- public void testRandomBehaviorVlan() {
- // Verify the random behavior
- assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
- // We test the behavior for VLAN
+ public void testFirstFitBehaviorMinSwap() {
+ // We change to FirstFit and we test the change
+ this.allocator.setLabelSelection(firstFit);
+ assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
+ /// Change to MIN_SWAP
+ this.allocator.setOptLabelSelection(minswap);
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.MIN_SWAP);
+ // Filter reservations
+ this.resourceService.filterAssignment = true;
+ // We change the available Ids
+ this.resourceService.availableVlanLabels = ImmutableSet.of(
+ (short) 2,
+ (short) 20,
+ (short) 200
+ );
+ // First allocation on a subset of links
Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
- ImmutableSet.copyOf(links.subList(1, 2)),
+ ImmutableSet.copyOf(links2.subList(2, 3)),
IntentId.valueOf(idGenerator.getNewId()),
EncapsulationType.VLAN);
- Identifier<?> id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
- // value has to be a VlanId
- assertThat(id, instanceOf(VlanId.class));
- // value should not be a forbidden value
- Short value = Short.parseShort(id.toString());
- VlanId prevVlanId = VlanId.vlanId(value);
- assertTrue(VlanId.NO_VID <= prevVlanId.toShort() && prevVlanId.toShort() <= VlanId.MAX_VLAN);
-
- allocation = this.allocator.assignLabelToLinks(
- ImmutableSet.copyOf(links.subList(1, 2)),
- IntentId.valueOf(idGenerator.getNewId()),
- EncapsulationType.VLAN);
- id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
- // value has to be a VlanId
+ Identifier<?> id = allocation.get(LinkKey.linkKey(d3p0, d4p1));
+ // value has to be a VLAN id
assertThat(id, instanceOf(VlanId.class));
// value should not be a forbidden value
VlanId vlanId = (VlanId) id;
- assertTrue(VlanId.NO_VID <= vlanId.toShort() && vlanId.toShort() <= VlanId.MAX_VLAN);
-
+ assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
+ // We test the behavior for VLAN
+ allocation = this.allocator.assignLabelToLinks(
+ ImmutableSet.copyOf(links2.subList(1, 4)),
+ IntentId.valueOf(idGenerator.getNewId()),
+ EncapsulationType.VLAN);
+ id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+ assertThat(id, instanceOf(VlanId.class));
+ vlanId = (VlanId) id;
+ assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
+ id = allocation.get(LinkKey.linkKey(d3p0, d4p1));
+ assertThat(id, instanceOf(VlanId.class));
+ vlanId = (VlanId) id;
+ assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
+ id = allocation.get(LinkKey.linkKey(d4p0, d2p1));
+ assertThat(id, instanceOf(VlanId.class));
+ vlanId = (VlanId) id;
+ assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
}
/**
- * To test random behavior with MPLS label. We make two selection,
- * we test that these two selection are different.
+ * To test random behavior. Using NONE optimization
*/
@Test
- public void testRandomBehaviorMpls() {
- // Verify the random behavior
+ public void testRandomBehaviorNone() {
+ // By default Random is the selection behavior used
assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
- // We test the behavior for MPLS
+ // It has to be an instance of NONE
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NONE);
+ // Filter reservations
+ this.resourceService.filterAssignment = true;
+ // We change the available Ids
+ this.resourceService.availableMplsLabels = ImmutableSet.of(
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6
+ );
+ // First allocation on a subset of links
Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
- ImmutableSet.copyOf(links.subList(1, 2)),
+ ImmutableSet.copyOf(links.subList(2, 3)),
IntentId.valueOf(idGenerator.getNewId()),
EncapsulationType.MPLS);
- Identifier<?> id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
- // value has to be a Mplslabel
+ Identifier<?> id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ // value has to be a MPLS label
assertThat(id, instanceOf(MplsLabel.class));
// value should not be a forbidden value
- MplsLabel prevMplsId = (MplsLabel) id;
- assertTrue(0 <= prevMplsId.toInt() && prevMplsId.toInt() <= MplsLabel.MAX_MPLS);
-
+ MplsLabel mplsLabel = (MplsLabel) id;
+ assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
+ // We test the behavior for MPLS
allocation = this.allocator.assignLabelToLinks(
- ImmutableSet.copyOf(links.subList(1, 2)),
+ ImmutableSet.copyOf(links.subList(1, 3)),
IntentId.valueOf(idGenerator.getNewId()),
EncapsulationType.MPLS);
- id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
- // value has to be a Mplslabel
+ id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+ assertThat(id, instanceOf(MplsLabel.class));
+ mplsLabel = (MplsLabel) id;
+ assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
+ id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ assertThat(id, instanceOf(MplsLabel.class));
+ mplsLabel = (MplsLabel) id;
+ assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
+ }
+
+ /**
+ * To test random behavior. Using NO_SWAP optimization
+ */
+ @Test
+ public void testRandomBehaviorNoSwap() {
+ // By default Random is the selection behavior used
+ assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
+ // Change to NO_SWAP
+ this.allocator.setOptLabelSelection(noswap);
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NO_SWAP);
+ // Filter reservations
+ this.resourceService.filterAssignment = true;
+ // We change the available Ids
+ this.resourceService.availableVlanLabels = ImmutableSet.of(
+ (short) 1,
+ (short) 2,
+ (short) 3,
+ (short) 4,
+ (short) 5,
+ (short) 6
+ );
+ // First allocation on a subset of links
+ Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
+ ImmutableSet.copyOf(links.subList(2, 3)),
+ IntentId.valueOf(idGenerator.getNewId()),
+ EncapsulationType.VLAN);
+ Identifier<?> id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ // value has to be a VLAN Id
+ assertThat(id, instanceOf(VlanId.class));
+ // value should not be a forbidden value
+ VlanId vlanId = (VlanId) id;
+ assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
+ // We test the behavior for VLAN
+ allocation = this.allocator.assignLabelToLinks(
+ ImmutableSet.copyOf(links.subList(1, 3)),
+ IntentId.valueOf(idGenerator.getNewId()),
+ EncapsulationType.VLAN);
+ id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+ assertThat(id, instanceOf(VlanId.class));
+ vlanId = (VlanId) id;
+ assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
+ id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ assertThat(id, instanceOf(VlanId.class));
+ vlanId = (VlanId) id;
+ assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
+ }
+
+ /**
+ * To test the random behavior. Using MIN_SWAP optimization
+ */
+ @Test
+ public void testRandomBehaviorMinSwap() {
+ // By default Random is the selection behavior used
+ assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
+ // Change to MIN_SWAP
+ this.allocator.setOptLabelSelection(minswap);
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.MIN_SWAP);
+ // Filter reservations
+ this.resourceService.filterAssignment = true;
+ // We change the available Ids
+ this.resourceService.availableMplsLabels = ImmutableSet.of(
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8
+ );
+ // First allocation on a subset of links
+ Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
+ ImmutableSet.copyOf(links2.subList(2, 3)),
+ IntentId.valueOf(idGenerator.getNewId()),
+ EncapsulationType.MPLS);
+ Identifier<?> id = allocation.get(LinkKey.linkKey(d3p0, d4p1));
+ // value has to be a MPLS label
assertThat(id, instanceOf(MplsLabel.class));
// value should not be a forbidden value
- MplsLabel mplsId = (MplsLabel) id;
- assertTrue(0 <= mplsId.toInt() && mplsId.toInt() <= MplsLabel.MAX_MPLS);
+ MplsLabel mplsLabel = (MplsLabel) id;
+ assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
+ // We test the behavior for MPLS
+ allocation = this.allocator.assignLabelToLinks(
+ ImmutableSet.copyOf(links2.subList(1, 4)),
+ IntentId.valueOf(idGenerator.getNewId()),
+ EncapsulationType.MPLS);
+ id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+ assertThat(id, instanceOf(MplsLabel.class));
+ mplsLabel = (MplsLabel) id;
+ assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
+ id = allocation.get(LinkKey.linkKey(d3p0, d4p1));
+ assertThat(id, instanceOf(MplsLabel.class));
+ mplsLabel = (MplsLabel) id;
+ assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
+ id = allocation.get(LinkKey.linkKey(d4p0, d2p1));
+ assertThat(id, instanceOf(MplsLabel.class));
+ mplsLabel = (MplsLabel) id;
+ assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
}
+
/**
* To test the port key based API.
*/
@Test
public void testPortKey() {
- // Verify the first behavior
+ // Verify the first fit behavior
this.allocator.setLabelSelection(firstFit);
assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
// We test the behavior for VLAN
@@ -286,7 +470,7 @@
// value has to be 1
assertEquals(1, prevVlanId.toShort());
// verify same applies for d2p1
- id = allocation.get(new ConnectPoint(d2p1.elementId(), d2p1.port()));
+ id = allocation.get(new ConnectPoint(d3p1.elementId(), d3p1.port()));
assertThat(id, instanceOf(VlanId.class));
// value should not be a forbidden value
VlanId vlanId = (VlanId) id;
@@ -295,6 +479,232 @@
assertEquals(prevVlanId, vlanId);
}
+ /**
+ * To test the developed algorithms when there are no labels.
+ */
+ @Test
+ public void noLabelsTest() {
+ // Verify the first fit behavior with NONE optimization
+ this.allocator.setLabelSelection(firstFit);
+ assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
+ // It has to be an instance of NONE
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NONE);
+ // We change the available Ids
+ this.resourceService.availableVlanLabels = ImmutableSet.of(
+ (short) 10
+ );
+ // Enable filtering of the reservation
+ this.resourceService.filterAssignment = true;
+ // We test the behavior for VLAN
+ Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
+ ImmutableSet.copyOf(links.subList(1, 3)),
+ IntentId.valueOf(idGenerator.getNewId()),
+ EncapsulationType.VLAN);
+ Identifier<?> id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+ // value has to be a VlanId
+ assertThat(id, instanceOf(VlanId.class));
+ // value should not be a forbidden value
+ VlanId label = (VlanId) id;
+ assertTrue(VlanId.NO_VID < label.toShort() && label.toShort() < VlanId.MAX_VLAN);
+ // Next hop
+ id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ assertThat(id, instanceOf(VlanId.class));
+ label = (VlanId) id;
+ assertTrue(VlanId.NO_VID < label.toShort() && label.toShort() < VlanId.MAX_VLAN);
+ // No labels are available, reservation is not possible
+ allocation = this.allocator.assignLabelToLinks(
+ ImmutableSet.copyOf(links.subList(1, 3)),
+ IntentId.valueOf(idGenerator.getNewId()),
+ EncapsulationType.VLAN);
+ id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+ // value has to be null
+ assertNull(id);
+ id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ // value has to be null
+ assertNull(id);
+ // Verify the random behavior with NONE_SWAP optimization
+ this.allocator.setLabelSelection(random);
+ assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
+ // Change to NO_SWAP
+ this.allocator.setOptLabelSelection(noswap);
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NO_SWAP);
+ // We change the available Ids
+ this.resourceService.availableMplsLabels = ImmutableSet.of(
+ 2000
+ );
+ // Enable filtering of the reservation
+ this.resourceService.filterAssignment = true;
+ // We test the behavior for MPLS
+ allocation = this.allocator.assignLabelToLinks(
+ ImmutableSet.copyOf(links.subList(1, 3)),
+ IntentId.valueOf(idGenerator.getNewId()),
+ EncapsulationType.MPLS);
+ id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+ // value has to be a Mplslabel
+ assertThat(id, instanceOf(MplsLabel.class));
+ // value should not be a forbidden value
+ MplsLabel mplsLabel = (MplsLabel) id;
+ assertTrue(0 <= mplsLabel.toInt() && mplsLabel.toInt() <= MplsLabel.MAX_MPLS);
+ id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ assertThat(id, instanceOf(MplsLabel.class));
+ mplsLabel = (MplsLabel) id;
+ assertTrue(0 <= mplsLabel.toInt() && mplsLabel.toInt() <= MplsLabel.MAX_MPLS);
+ // No labels are available, reservation is not possible
+ allocation = this.allocator.assignLabelToLinks(
+ ImmutableSet.copyOf(links.subList(1, 3)),
+ IntentId.valueOf(idGenerator.getNewId()),
+ EncapsulationType.MPLS);
+ id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+ // value has to be null
+ assertNull(id);
+ id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ // value has to be null
+ assertNull(id);
+
+ // Verify the first fit behavior with MIN optimization
+ this.allocator.setLabelSelection(firstFit);
+ assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
+ // Change to MIN_SWAP
+ this.allocator.setOptLabelSelection(minswap);
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.MIN_SWAP);
+ // We change the available Ids
+ this.resourceService.availableVlanLabels = ImmutableSet.of(
+ (short) 11
+ );
+ // Enable filtering of the reservation
+ this.resourceService.filterAssignment = true;
+ // We test the behavior for VLAN
+ allocation = this.allocator.assignLabelToLinks(
+ ImmutableSet.copyOf(links.subList(1, 3)),
+ IntentId.valueOf(idGenerator.getNewId()),
+ EncapsulationType.VLAN);
+ id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+ // value has to be a VlanId
+ assertThat(id, instanceOf(VlanId.class));
+ // value should not be a forbidden value
+ label = (VlanId) id;
+ assertTrue(VlanId.NO_VID < label.toShort() && label.toShort() < VlanId.MAX_VLAN);
+ // Next hop
+ id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ assertThat(id, instanceOf(VlanId.class));
+ label = (VlanId) id;
+ assertTrue(VlanId.NO_VID < label.toShort() && label.toShort() < VlanId.MAX_VLAN);
+ // No labels are available, reservation is not possible
+ allocation = this.allocator.assignLabelToLinks(
+ ImmutableSet.copyOf(links.subList(1, 3)),
+ IntentId.valueOf(idGenerator.getNewId()),
+ EncapsulationType.VLAN);
+ id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+ // value has to be null
+ assertNull(id);
+ id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ // value has to be null
+ assertNull(id);
+ }
+
+ /**
+ * To test the developed algorithms when there are no labels on a specific link.
+ */
+ @Test
+ public void noLabelsOnLinkTest() {
+ // Verify the first fit behavior with NONE optimization
+ this.allocator.setLabelSelection(firstFit);
+ assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
+ // It has to be an instance of NONE
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NONE);
+ // We change the available Ids
+ this.resourceService.availableVlanLabels = ImmutableSet.of(
+ (short) 10
+ );
+ // Enable filtering of the reservation
+ this.resourceService.filterAssignment = true;
+ // We test the behavior for VLAN
+ Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
+ ImmutableSet.copyOf(links.subList(2, 3)),
+ IntentId.valueOf(idGenerator.getNewId()),
+ EncapsulationType.VLAN);
+ Identifier<?> id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ assertThat(id, instanceOf(VlanId.class));
+ VlanId label = (VlanId) id;
+ assertTrue(VlanId.NO_VID < label.toShort() && label.toShort() < VlanId.MAX_VLAN);
+ // No labels are available, reservation is not possible
+ allocation = this.allocator.assignLabelToLinks(
+ ImmutableSet.copyOf(links.subList(1, 3)),
+ IntentId.valueOf(idGenerator.getNewId()),
+ EncapsulationType.VLAN);
+ id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+ // value has to be null
+ assertNull(id);
+ id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ // value has to be null
+ assertNull(id);
+
+ // Verify the random behavior with NONE_SWAP optimization
+ this.allocator.setLabelSelection(random);
+ assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
+ // Change to NO_SWAP
+ this.allocator.setOptLabelSelection(noswap);
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NO_SWAP);
+ // We change the available Ids
+ this.resourceService.availableMplsLabels = ImmutableSet.of(
+ 2000
+ );
+ // Enable filtering of the reservation
+ this.resourceService.filterAssignment = true;
+ // We test the behavior for MPLS
+ allocation = this.allocator.assignLabelToLinks(
+ ImmutableSet.copyOf(links.subList(2, 3)),
+ IntentId.valueOf(idGenerator.getNewId()),
+ EncapsulationType.MPLS);
+ id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ assertThat(id, instanceOf(MplsLabel.class));
+ MplsLabel mplsLabel = (MplsLabel) id;
+ assertTrue(0 <= mplsLabel.toInt() && mplsLabel.toInt() <= MplsLabel.MAX_MPLS);
+ // No labels are available, reservation is not possible
+ allocation = this.allocator.assignLabelToLinks(
+ ImmutableSet.copyOf(links.subList(1, 3)),
+ IntentId.valueOf(idGenerator.getNewId()),
+ EncapsulationType.MPLS);
+ id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+ // value has to be null
+ assertNull(id);
+ id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ // value has to be null
+ assertNull(id);
+
+ // Verify the first fit behavior with MIN optimization
+ this.allocator.setLabelSelection(firstFit);
+ assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
+ // Change to MIN_SWAP
+ this.allocator.setOptLabelSelection(minswap);
+ assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.MIN_SWAP);
+ // We change the available Ids
+ this.resourceService.availableVlanLabels = ImmutableSet.of(
+ (short) 11
+ );
+ // Enable filtering of the reservation
+ this.resourceService.filterAssignment = true;
+ // We test the behavior for VLAN
+ allocation = this.allocator.assignLabelToLinks(
+ ImmutableSet.copyOf(links.subList(2, 3)),
+ IntentId.valueOf(idGenerator.getNewId()),
+ EncapsulationType.VLAN);
+ id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ assertThat(id, instanceOf(VlanId.class));
+ label = (VlanId) id;
+ assertTrue(VlanId.NO_VID < label.toShort() && label.toShort() < VlanId.MAX_VLAN);
+ // No labels are available, reservation is not possible
+ allocation = this.allocator.assignLabelToLinks(
+ ImmutableSet.copyOf(links.subList(1, 3)),
+ IntentId.valueOf(idGenerator.getNewId()),
+ EncapsulationType.VLAN);
+ id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+ // value has to be null
+ assertNull(id);
+ id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+ // value has to be null
+ assertNull(id);
+ }
}