diff --git a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PathComputationTest.java b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PathComputationTest.java
new file mode 100644
index 0000000..446aea2
--- /dev/null
+++ b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PathComputationTest.java
@@ -0,0 +1,1032 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.pce.pceservice;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.graph.AbstractGraphPathSearch;
+import org.onlab.graph.AdjacencyListsGraph;
+import org.onlab.graph.DijkstraGraphSearch;
+import org.onlab.graph.Graph;
+import org.onlab.graph.GraphPathSearch;
+import org.onlab.packet.ChassisId;
+import org.onlab.util.Bandwidth;
+import org.onlab.util.Tools;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.DefaultPath;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.IntentId;
+import org.onosproject.net.Device.Type;
+import org.onosproject.net.intent.constraint.BandwidthConstraint;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.resource.ContinuousResource;
+import org.onosproject.net.resource.ContinuousResourceId;
+import org.onosproject.net.resource.DiscreteResource;
+import org.onosproject.net.resource.DiscreteResourceId;
+import org.onosproject.net.resource.Resource;
+import org.onosproject.net.resource.ResourceAllocation;
+import org.onosproject.net.resource.ResourceConsumer;
+import org.onosproject.net.resource.ResourceId;
+import org.onosproject.net.resource.Resources;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.topology.DefaultTopologyEdge;
+import org.onosproject.net.topology.DefaultTopologyVertex;
+import org.onosproject.net.topology.LinkWeight;
+import org.onosproject.net.topology.TopologyEdge;
+import org.onosproject.net.topology.TopologyVertex;
+import org.onosproject.pce.pceservice.constraint.CapabilityConstraint;
+import org.onosproject.pce.pceservice.constraint.CostConstraint;
+import org.onosproject.pce.pceservice.constraint.SharedBandwidthConstraint;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
+import static org.onosproject.core.CoreService.CORE_PROVIDER_ID;
+import static com.google.common.collect.ImmutableSet.of;
+import static org.onosproject.net.resource.Resources.continuous;
+import static org.onosproject.net.Link.Type.DIRECT;
+import static org.onosproject.net.Link.State.ACTIVE;
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.pce.pceservice.constraint.CostConstraint.Type.COST;
+import static org.onosproject.pce.pceservice.constraint.CostConstraint.Type.TE_COST;
+
+/**
+ * Test for CSPF path computation.
+ */
+public class PathComputationTest {
+
+    private final MockPathResourceService resourceService = new MockPathResourceService();
+    private final MockDeviceService deviceService = new MockDeviceService();
+    private PceManager pceManager = new PceManager();
+    public static ProviderId providerId = new ProviderId("pce", "foo");
+    private static final String DEVICE1 = "D001";
+    private static final String DEVICE2 = "D002";
+    private static final String DEVICE3 = "D003";
+    private static final String DEVICE4 = "D004";
+    private static final String DEVICE5 = "D005";
+    public static final String PCEPDEVICE1 = "PD001";
+    public static final String PCEPDEVICE2 = "PD002";
+    public static final String PCEPDEVICE3 = "PD003";
+    public static final String PCEPDEVICE4 = "PD004";
+    private static final TopologyVertex D1 = new DefaultTopologyVertex(DeviceId.deviceId("D001"));
+    private static final TopologyVertex D2 = new DefaultTopologyVertex(DeviceId.deviceId("D002"));
+    private static final TopologyVertex D3 = new DefaultTopologyVertex(DeviceId.deviceId("D003"));
+    private static final TopologyVertex D4 = new DefaultTopologyVertex(DeviceId.deviceId("D004"));
+    private static final TopologyVertex D5 = new DefaultTopologyVertex(DeviceId.deviceId("D005"));
+    private static final String ANNOTATION_COST = "cost";
+    private static final String ANNOTATION_TE_COST = "teCost";
+    private static final String UNKNOWN = "unknown";
+    public static final String LSRID = "lsrId";
+    public static final String L3 = "L3";
+    public static final String PCECC_CAPABILITY = "pceccCapability";
+    public static final String SR_CAPABILITY = "srCapability";
+    public static final String LABEL_STACK_CAPABILITY = "labelStackCapability";
+
+    @Before
+    public void startUp() {
+        pceManager.resourceService = resourceService;
+        pceManager.deviceService = deviceService;
+    }
+
+    /**
+     * Selects path computation algorithm.
+     *
+     * @return graph path search algorithm
+     */
+    private AbstractGraphPathSearch<TopologyVertex, TopologyEdge> graphSearch() {
+        return new DijkstraGraphSearch<>();
+    }
+
+    /**
+     * Returns link for two devices.
+     *
+     * @param device source device
+     * @param port source port
+     * @param device2 destination device
+     * @param port2 destination port
+     * @return link
+     */
+    private Link addLink(String device, long port, String device2, long port2, boolean setCost, int value) {
+        ConnectPoint src = new ConnectPoint(DeviceId.deviceId(device), PortNumber.portNumber(port));
+        ConnectPoint dst = new ConnectPoint(DeviceId.deviceId(device2), PortNumber.portNumber(port2));
+        Link curLink;
+        DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
+        if (setCost) {
+            annotationBuilder.set(ANNOTATION_COST, String.valueOf(value));
+        } else {
+            annotationBuilder.set(ANNOTATION_TE_COST, String.valueOf(value));
+        }
+
+        //TODO:If cost not set cost : default value case
+        curLink = DefaultLink.builder().src(src).dst(dst).state(ACTIVE).type(DIRECT)
+                 .providerId(PathComputationTest.providerId).annotations(annotationBuilder.build()).build();
+        return curLink;
+    }
+
+    @After
+    public void tearDown() {
+        pceManager.resourceService = null;
+        pceManager.deviceService = null;
+    }
+
+    /**
+     * Returns an edge-weight capable of evaluating links on the basis of the
+     * specified constraints.
+     *
+     * @param constraints path constraints
+     * @return edge-weight function
+     */
+    private LinkWeight weight(List<Constraint> constraints) {
+        return new MockTeConstraintBasedLinkWeight(constraints);
+    }
+
+    private Set<Path> computePath(Link link1, Link link2, Link link3, Link link4, List<Constraint> constraints) {
+        Graph<TopologyVertex, TopologyEdge> graph = new AdjacencyListsGraph<>(of(D1, D2, D3, D4),
+                of(new DefaultTopologyEdge(D1, D2, link1),
+                   new DefaultTopologyEdge(D2, D4, link2),
+                   new DefaultTopologyEdge(D1, D3, link3),
+                   new DefaultTopologyEdge(D3, D4, link4)));
+
+        GraphPathSearch.Result<TopologyVertex, TopologyEdge> result =
+                graphSearch().search(graph, D1, D4, weight(constraints), ALL_PATHS);
+        ImmutableSet.Builder<Path> builder = ImmutableSet.builder();
+        for (org.onlab.graph.Path<TopologyVertex, TopologyEdge> path : result.paths()) {
+            builder.add(networkPath(path));
+        }
+        return builder.build();
+    }
+
+    private class MockDeviceService extends DeviceServiceAdapter {
+        List<Device> devices = new LinkedList<>();
+
+        private void addDevice(Device dev) {
+            devices.add(dev);
+        }
+
+        @Override
+        public Device getDevice(DeviceId deviceId) {
+            for (Device dev : devices) {
+                if (dev.id().equals(deviceId)) {
+                    return dev;
+                }
+            }
+            return null;
+        }
+
+        @Override
+        public Iterable<Device> getAvailableDevices() {
+            return devices;
+        }
+    }
+
+    private class MockTeConstraintBasedLinkWeight implements LinkWeight {
+
+        private final List<Constraint> constraints;
+
+        /**
+         * Creates a new edge-weight function capable of evaluating links
+         * on the basis of the specified constraints.
+         *
+         * @param constraints path constraints
+         */
+        MockTeConstraintBasedLinkWeight(List<Constraint> constraints) {
+            if (constraints == null) {
+                this.constraints = Collections.emptyList();
+            } else {
+                this.constraints = ImmutableList.copyOf(constraints);
+            }
+        }
+
+        public double weight(TopologyEdge edge) {
+            if (!constraints.iterator().hasNext()) {
+                //Takes default cost/hopcount as 1 if no constraints specified
+                return 1.0;
+            }
+
+            Iterator<Constraint> it = constraints.iterator();
+            double cost = 1;
+
+            //If any constraint fails return -1 also value of cost returned from cost constraint can't be negative
+            while (it.hasNext() && cost > 0) {
+                Constraint constraint = it.next();
+                if (constraint instanceof CapabilityConstraint) {
+                    cost = ((CapabilityConstraint) constraint).isValidLink(edge.link(), deviceService) ? 1 : -1;
+                } else {
+                    cost = constraint.cost(edge.link(), resourceService::isAvailable);
+                }
+            }
+            return cost;
+        }
+    }
+
+    private Path networkPath(org.onlab.graph.Path<TopologyVertex, TopologyEdge> path) {
+        List<Link> links = path.edges().stream().map(TopologyEdge::link).collect(Collectors.toList());
+        return new DefaultPath(CORE_PROVIDER_ID, links, path.cost());
+    }
+
+    /**
+     * Test Resource service for path computation.
+     */
+    private class MockPathResourceService extends ResourceServiceAdapter {
+        private final Map<Resource, ResourceConsumer> assignment = new HashMap<>();
+        private Map<ResourceId, List<ResourceAllocation>> resourcesAllocations = new HashMap<>();
+
+        @Override
+        public List<ResourceAllocation> allocate(ResourceConsumer consumer, List<Resource> resources) {
+            for (Resource resource: resources) {
+                if (resource instanceof ContinuousResource) {
+                    List<ResourceAllocation> allocs = new LinkedList<>();
+                    allocs.add(new ResourceAllocation(resource, consumer));
+                    resourcesAllocations.put(resource.id(), allocs);
+                }
+            }
+            return resources.stream()
+                    .map(x -> new ResourceAllocation(x, consumer))
+                    .collect(Collectors.toList());
+        }
+
+        @Override
+        public List<ResourceAllocation> getResourceAllocations(ResourceId id) {
+            if (id instanceof ContinuousResourceId) {
+                return resourcesAllocations.get(id);
+            }
+            DiscreteResource discrete = Resources.discrete((DiscreteResourceId) id).resource();
+            return Optional.ofNullable(assignment.get(discrete))
+                    .map(x -> ImmutableList.of(new ResourceAllocation(discrete, x)))
+                    .orElse(ImmutableList.of());
+        }
+
+        @Override
+        public <T> Set<Resource> getAvailableResources(DiscreteResourceId parent, Class<T> cls) {
+            return getAvailableResources(parent).stream()
+                    .filter(x -> x.isTypeOf(cls))
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public <T> Set<T> getAvailableResourceValues(DiscreteResourceId parent, Class<T> cls) {
+            return getAvailableResources(parent).stream()
+                    .filter(x -> x.isTypeOf(cls))
+                    .flatMap(x -> Tools.stream(x.valueAs(cls)))
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public boolean isAvailable(Resource resource) {
+            if (resource instanceof DiscreteResource) {
+                return true;
+            }
+
+            if (resource instanceof ContinuousResource) {
+                List<ResourceAllocation> resalloc = resourcesAllocations.get(resource.id());
+
+                if ((resalloc != null) && (!resalloc.isEmpty())) {
+                    if (((ContinuousResource) resalloc.iterator().next().resource()).value()
+                            >= ((ContinuousResource) resource).value()) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+     * All links with different costs with L1-L2 as least cost path.
+     */
+    @Test
+    public void testpathComputationCase1() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 50);
+
+        CostConstraint costConst = CostConstraint.of(COST);
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(costConst);
+
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+
+        links.add(link1);
+        links.add(link2);
+
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 70));
+    }
+
+    /**
+     * Links with same cost 100 except link3.
+     */
+    @Test
+    public void testpathComputationCase2() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 100);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 100);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 1000);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 100);
+
+        CostConstraint costConst = CostConstraint.of(COST);
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(costConst);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 200));
+    }
+
+    /**
+     * Path which satisfy bandwidth as a constraint with 10bps.
+     */
+    @Test
+    public void testpathComputationCase3() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 50);
+
+        List<Resource> resources = new LinkedList<>();
+
+        resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class)
+                .resource(50));
+        resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class)
+                .resource(50));
+        resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class)
+                .resource(100));
+        resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class)
+                .resource(100));
+
+        resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class)
+                .resource(50));
+        resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class)
+                .resource(50));
+        resources.add(continuous(link3.dst().deviceId(), link3.src().port(), Bandwidth.class)
+                .resource(100));
+        resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class)
+                .resource(100));
+
+        resourceService.allocate(IntentId.valueOf(70), resources);
+
+        BandwidthConstraint bandwidthConst = new BandwidthConstraint(Bandwidth.bps(10.0));
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(bandwidthConst);
+
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        assertThat(paths.iterator().next().cost(), is((double) 2));
+    }
+
+    /**
+     * Path which satisfy bandwidth as a constraint with 60bps.
+     */
+    @Test
+    public void testpathComputationCase4() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 50);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 100);
+
+        List<Resource> resources = new LinkedList<>();
+
+        resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class).resource(100));
+        resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class).resource(100));
+
+        resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link3.dst().deviceId(), link3.dst().port(), Bandwidth.class).resource(100));
+        resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class).resource(100));
+
+        resourceService.allocate(IntentId.valueOf(70), resources);
+
+        BandwidthConstraint bandwidthConst = new BandwidthConstraint(Bandwidth.bps(60.0));
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(bandwidthConst);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        assertThat(paths.iterator().next().cost(), is((double) 2));
+    }
+
+    /**
+     * Shared bandwidth as L1, L2 with its value 10 bps and bandwidth constraint as 20 bps.
+     */
+    @Test
+    public void testpathComputationCase5() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
+
+        List<Resource> resources = new LinkedList<>();
+
+        resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class).resource(100));
+        resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class).resource(100));
+
+        resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link3.dst().deviceId(), link3.dst().port(), Bandwidth.class).resource(100));
+        resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class).resource(100));
+        resourceService.allocate(IntentId.valueOf(70), resources);
+
+        List<Constraint> constraints = new LinkedList<>();
+
+        List<Link> sharedLinks = new LinkedList<>();
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+
+        CostConstraint costConst = CostConstraint.of(COST);
+        sharedLinks.addAll(links);
+        SharedBandwidthConstraint sharedBw = new SharedBandwidthConstraint(sharedLinks, Bandwidth.bps(10),
+                Bandwidth.bps(20.0));
+        constraints.add(sharedBw);
+        constraints.add(costConst);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 70));
+    }
+
+    /**
+     * Shared bandwidth as L1, L2 with its value 20 bps and bandwidth constraint as 10 bps.
+     */
+    @Test
+    public void testpathComputationCase6() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
+
+        List<Resource> resources = new LinkedList<>();
+
+        resources.add(continuous(link1.src().deviceId(), link1.src().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link2.src().deviceId(), link2.src().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link3.src().deviceId(), link3.src().port(), Bandwidth.class).resource(100));
+        resources.add(continuous(link4.src().deviceId(), link4.src().port(), Bandwidth.class).resource(100));
+
+        resources.add(continuous(link1.dst().deviceId(), link1.dst().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link2.dst().deviceId(), link2.dst().port(), Bandwidth.class).resource(50));
+        resources.add(continuous(link3.dst().deviceId(), link3.dst().port(), Bandwidth.class).resource(100));
+        resources.add(continuous(link4.dst().deviceId(), link4.dst().port(), Bandwidth.class).resource(100));
+        resourceService.allocate(IntentId.valueOf(70), resources);
+
+        List<Constraint> constraints = new LinkedList<>();
+
+        List<Link> sharedLinks = new LinkedList<>();
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+        CostConstraint costConst = CostConstraint.of(COST);
+        sharedLinks.addAll(links);
+        SharedBandwidthConstraint sharedBwConst = new SharedBandwidthConstraint(sharedLinks, Bandwidth.bps(20),
+                Bandwidth.bps(10.0));
+        constraints.add(sharedBwConst);
+        constraints.add(costConst);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 70));
+    }
+
+    /**
+     * Path without constraints.
+     */
+    @Test
+    public void testpathComputationCase7() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
+        List<Constraint> constraints = new LinkedList<>();
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        assertThat(paths.iterator().next().cost(), is((double) 2));
+    }
+
+    /**
+     * With TeCost as a constraints.
+     */
+    @Test
+    public void testpathComputationCase8() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
+
+        CostConstraint tecostConst = CostConstraint.of(TE_COST);
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(tecostConst);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 70));
+    }
+
+    /**
+     * With device supporting RSVP capability as a constraints.
+     */
+    @Test
+    public void testpathComputationCase9() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
+
+        CostConstraint tecostConst = CostConstraint.of(TE_COST);
+        CapabilityConstraint capabilityConst = CapabilityConstraint
+                .of(CapabilityConstraint.CapabilityType.WITH_SIGNALLING);
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(capabilityConst);
+        constraints.add(tecostConst);
+        //Device1
+        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "1.1.1.1");
+        addDevice(DEVICE1, builder);
+
+        //Device2
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "2.2.2.2");
+        addDevice(DEVICE2, builder);
+
+        //Device3
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "3.3.3.3");
+        addDevice(DEVICE3, builder);
+
+        //Device4
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "4.4.4.4");
+        addDevice(DEVICE4, builder);
+
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 70));
+    }
+
+    /**
+     * Devices supporting CR capability.
+     */
+    @Test
+    public void testpathComputationCase10() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
+
+        CapabilityConstraint capabilityConst = CapabilityConstraint
+                .of(CapabilityConstraint.CapabilityType.WITHOUT_SIGNALLING_AND_WITHOUT_SR);
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(capabilityConst);
+        CostConstraint costConst = CostConstraint.of(COST);
+        constraints.add(costConst);
+        //Device1
+        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "1.1.1.1");
+        addDevice(DEVICE1, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE1, builder);
+
+        //Device2
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "2.2.2.2");
+        addDevice(DEVICE2, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE2, builder);
+
+        //Device3
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "3.3.3.3");
+        addDevice(DEVICE3, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE3, builder);
+
+        //Device4
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "4.4.4.4");
+        addDevice(DEVICE4, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE4, builder);
+
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 70));
+    }
+
+    /**
+     * Device supporting SR capability.
+     */
+    @Test
+    public void testpathComputationCase11() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 80);
+
+        CapabilityConstraint capabilityConst = CapabilityConstraint
+                .of(CapabilityConstraint.CapabilityType.SR_WITHOUT_SIGNALLING);
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(capabilityConst);
+        CostConstraint costConst = CostConstraint.of(COST);
+        constraints.add(costConst);
+        //Device1
+        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "1.1.1.1");
+        addDevice(DEVICE1, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE1, builder);
+
+        //Device2
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "2.2.2.2");
+        addDevice(DEVICE2, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE2, builder);
+
+        //Device3
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "3.3.3.3");
+        addDevice(DEVICE3, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE3, builder);
+
+        //Device4
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "4.4.4.4");
+        addDevice(DEVICE4, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE4, builder);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 70));
+    }
+
+    /**
+     * Path with TE and SR capability constraint.
+     */
+    @Test
+    public void testpathComputationCase12() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
+
+        CostConstraint tecostConst = CostConstraint.of(TE_COST);
+        CapabilityConstraint capabilityConst = CapabilityConstraint
+                .of(CapabilityConstraint.CapabilityType.SR_WITHOUT_SIGNALLING);
+
+        List<Constraint> constraints = new LinkedList<>();
+
+        constraints.add(capabilityConst);
+        constraints.add(tecostConst);
+        //Device1
+        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "1.1.1.1");
+        addDevice(DEVICE1, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE1, builder);
+
+        //Device2
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "2.2.2.2");
+        addDevice(DEVICE2, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE2, builder);
+
+        //Device3
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "3.3.3.3");
+        addDevice(DEVICE3, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE3, builder);
+
+        //Device4
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "4.4.4.4");
+        addDevice(DEVICE4, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE4, builder);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 70));
+    }
+
+    /**
+     * Path with capability constraint and with default cost.
+     */
+    @Test
+    public void testpathComputationCase13() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
+
+        CapabilityConstraint capabilityConst = CapabilityConstraint
+                .of(CapabilityConstraint.CapabilityType.SR_WITHOUT_SIGNALLING);
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(capabilityConst);
+        //Device1
+        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "1.1.1.1");
+        addDevice(DEVICE1, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE1, builder);
+
+        //Device2
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "2.2.2.2");
+        addDevice(DEVICE2, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE2, builder);
+
+        //Device3
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "3.3.3.3");
+        addDevice(DEVICE3, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE3, builder);
+
+        //Device4
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "4.4.4.4");
+        addDevice(DEVICE4, builder);
+        builder.set(SR_CAPABILITY, "true");
+        builder.set(LABEL_STACK_CAPABILITY, "true");
+        addDevice(PCEPDEVICE4, builder);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+        assertThat(paths.iterator().next().cost(), is((double) 2));
+    }
+
+    /**
+     * Test case with empty constraints.
+     */
+    @Test
+    public void testpathComputationCase14() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
+
+        List<Constraint> constraints = new LinkedList<>();
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        assertThat(paths.iterator().next().cost(), is((double) 2));
+    }
+
+    /**
+     * Test case with constraints as null.
+     */
+    @Test
+    public void testpathComputationCase15() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
+
+        List<Constraint> constraints = null;
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        assertThat(paths.iterator().next().cost(), is((double) 2));
+    }
+
+    /**
+     * Path with cost constraint.
+     */
+    @Test
+    public void testpathComputationCase16() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, true, 100);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 10);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 10);
+        Link link5 = addLink(DEVICE4, 90, DEVICE5, 100, true, 20);
+
+        CostConstraint costConst = CostConstraint.of(COST);
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(costConst);
+        Graph<TopologyVertex, TopologyEdge> graph = new AdjacencyListsGraph<>(of(D1, D2, D3, D4, D5),
+                of(new DefaultTopologyEdge(D1, D2, link1),
+                   new DefaultTopologyEdge(D2, D4, link2),
+                   new DefaultTopologyEdge(D1, D3, link3),
+                   new DefaultTopologyEdge(D3, D4, link4),
+                   new DefaultTopologyEdge(D4, D5, link5)));
+
+        GraphPathSearch.Result<TopologyVertex, TopologyEdge> result =
+                graphSearch().search(graph, D1, D5, weight(constraints), ALL_PATHS);
+        ImmutableSet.Builder<Path> builder = ImmutableSet.builder();
+        for (org.onlab.graph.Path<TopologyVertex, TopologyEdge> path : result.paths()) {
+            builder.add(networkPath(path));
+        }
+
+        List<Link> links = new LinkedList<>();
+        links.add(link3);
+        links.add(link4);
+        links.add(link5);
+        assertThat(builder.build().iterator().next().links(), is(links));
+        assertThat(builder.build().iterator().next().cost(), is((double) 40));
+    }
+
+    /**
+     * D3 doesn't support capability constraint, so path is L1-L2.
+     */
+    @Test
+    public void testpathComputationCase17() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, false, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, false, 100);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, false, 80);
+
+        CapabilityConstraint capabilityConst = CapabilityConstraint
+                .of(CapabilityConstraint.CapabilityType.WITHOUT_SIGNALLING_AND_WITHOUT_SR);
+
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(capabilityConst);
+        //Device1
+        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "1.1.1.1");
+        addDevice(DEVICE1, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE1, builder);
+
+        //Device2
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "2.2.2.2");
+        addDevice(DEVICE2, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE2, builder);
+
+        //Device4
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "4.4.4.4");
+        addDevice(DEVICE4, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE4, builder);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        List<Link> links = new LinkedList<>();
+        links.add(link1);
+        links.add(link2);
+
+        assertThat(paths.iterator().next().links(), is(links));
+        assertThat(paths.iterator().next().cost(), is((double) 2));
+    }
+
+    /**
+     * L2 doesn't support cost constraint and D3 doesn't support capability constraint, both constraint fails hence no
+     * path.
+     */
+    @Test
+    public void testpathComputationCase18() {
+        Link link1 = addLink(DEVICE1, 10, DEVICE2, 20, true, 50);
+        Link link2 = addLink(DEVICE2, 30, DEVICE4, 40, false, 20);
+        Link link3 = addLink(DEVICE1, 80, DEVICE3, 70, true, 10);
+        Link link4 = addLink(DEVICE3, 60, DEVICE4, 50, true, 10);
+
+        CapabilityConstraint capabilityConst = CapabilityConstraint
+                .of(CapabilityConstraint.CapabilityType.WITHOUT_SIGNALLING_AND_WITHOUT_SR);
+        CostConstraint costConst = CostConstraint.of(COST);
+        List<Constraint> constraints = new LinkedList<>();
+        constraints.add(capabilityConst);
+        constraints.add(costConst);
+        //Device1
+        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "1.1.1.1");
+        addDevice(DEVICE2, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE1, builder);
+
+        //Device2
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "2.2.2.2");
+        addDevice(DEVICE2, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE2, builder);
+
+        //Device4
+        builder = DefaultAnnotations.builder();
+        builder.set(AnnotationKeys.TYPE, L3);
+        builder.set(LSRID, "4.4.4.4");
+        addDevice(DEVICE4, builder);
+        builder.set(PCECC_CAPABILITY, "true");
+        addDevice(PCEPDEVICE4, builder);
+        Set<Path> paths = computePath(link1, link2, link3, link4, constraints);
+
+        assertThat(paths, is(new HashSet<>()));
+    }
+
+    private void addDevice(String device, DefaultAnnotations.Builder builder) {
+        deviceService.addDevice(new DefaultDevice(ProviderId.NONE, deviceId(device), Type.ROUTER,
+        UNKNOWN, UNKNOWN, UNKNOWN,
+        UNKNOWN, new ChassisId(), builder.build()));
+    }
+}
\ No newline at end of file
