[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);
+    }
 
 }