diff --git a/apps/newoptical/BUCK b/apps/newoptical/BUCK
index c21f807..fd80f40 100644
--- a/apps/newoptical/BUCK
+++ b/apps/newoptical/BUCK
@@ -4,8 +4,13 @@
   '//cli:onos-cli',
 ]
 
+TEST_DEPS = [
+  '//lib:TEST_ADAPTERS',
+]
+
 osgi_jar_with_tests (
   deps = COMPILE_DEPS,
+  test_deps = TEST_DEPS,
 )
 
 onos_app (
diff --git a/apps/newoptical/pom.xml b/apps/newoptical/pom.xml
index 792d081..be1f415 100644
--- a/apps/newoptical/pom.xml
+++ b/apps/newoptical/pom.xml
@@ -89,6 +89,18 @@
             <version>${project.version}</version>
         </dependency>
 
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava-testlib</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
     </dependencies>
 
     <build>
diff --git a/apps/newoptical/src/main/java/org/onosproject/newoptical/OpticalPathProvisioner.java b/apps/newoptical/src/main/java/org/onosproject/newoptical/OpticalPathProvisioner.java
index 775eb51..f64e579 100644
--- a/apps/newoptical/src/main/java/org/onosproject/newoptical/OpticalPathProvisioner.java
+++ b/apps/newoptical/src/main/java/org/onosproject/newoptical/OpticalPathProvisioner.java
@@ -151,11 +151,7 @@
         deviceService = opticalView(deviceService);
         appId = coreService.registerApplication("org.onosproject.newoptical");
 
-        idCounter = storageService.atomicCounterBuilder()
-                .withName(OPTICAL_CONNECTIVITY_ID_COUNTER)
-                .withMeteringDisabled()
-                .build()
-                .asAtomicCounter();
+        idCounter = storageService.getAtomicCounter(OPTICAL_CONNECTIVITY_ID_COUNTER);
 
         eventDispatcher.addSink(OpticalPathEvent.class, listenerRegistry);
 
diff --git a/apps/newoptical/src/test/java/org/onosproject/newoptical/OpticalConnectivityTest.java b/apps/newoptical/src/test/java/org/onosproject/newoptical/OpticalConnectivityTest.java
new file mode 100644
index 0000000..8d0bc87
--- /dev/null
+++ b/apps/newoptical/src/test/java/org/onosproject/newoptical/OpticalConnectivityTest.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2016 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.newoptical;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.util.Bandwidth;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.net.CltSignalType;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.OduSignalType;
+import org.onosproject.net.Path;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.OpticalCircuitIntent;
+import org.onosproject.net.intent.OpticalConnectivityIntent;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.newoptical.api.OpticalConnectivityId;
+
+import java.time.Duration;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test class for OpticalConnectivity.
+ */
+public class OpticalConnectivityTest {
+
+    private final ApplicationId appId = new DefaultApplicationId(0, "PacketLinkRealizedByOpticalTest");
+    private ProviderId providerId = new ProviderId("of", "foo");
+    private IdGenerator idGenerator;
+
+    @Before
+    public void setUp() {
+        idGenerator = new IdGenerator() {
+            int counter = 1;
+
+            @Override
+            public long getNewId() {
+                return counter++;
+            }
+        };
+
+        Intent.bindIdGenerator(idGenerator);
+    }
+
+    @After
+    public void tearDown() {
+        Intent.unbindIdGenerator(idGenerator);
+    }
+
+    /**
+     * Checks the construction of OpticalConnectivity object.
+     */
+    @Test
+    public void testCreate() {
+        Bandwidth bandwidth = Bandwidth.bps(100);
+        Duration latency = Duration.ofMillis(10);
+
+        // Mock 3-nodes linear topology
+        ConnectPoint cp12 = createConnectPoint(1, 2);
+        ConnectPoint cp21 = createConnectPoint(2, 1);
+        ConnectPoint cp22 = createConnectPoint(2, 2);
+        ConnectPoint cp31 = createConnectPoint(3, 1);
+
+        Link link1 = createLink(cp12, cp21);
+        Link link2 = createLink(cp22, cp31);
+        List<Link> links = Stream.of(link1, link2).collect(Collectors.toList());
+
+        Path path = new MockPath(cp12, cp31, links);
+
+        OpticalConnectivityId cid = OpticalConnectivityId.of(1L);
+        OpticalConnectivity oc = new OpticalConnectivity(cid, path, bandwidth, latency);
+
+        assertNotNull(oc);
+        assertEquals(oc.id(), cid);
+        assertEquals(oc.links(), links);
+        assertEquals(oc.bandwidth(), bandwidth);
+        assertEquals(oc.latency(), latency);
+    }
+
+    /**
+     * Checks that isAllRealizingLink(Not)Established works for OpticalConnectivityIntent.
+     */
+    @Test
+    public void testLinkEstablishedByConnectivityIntent() {
+        // Mock 7-nodes linear topology
+        ConnectPoint cp12 = createConnectPoint(1, 2);
+        ConnectPoint cp21 = createConnectPoint(2, 1);
+        ConnectPoint cp22 = createConnectPoint(2, 2);
+        ConnectPoint cp31 = createConnectPoint(3, 1);
+        ConnectPoint cp32 = createConnectPoint(3, 2);
+        ConnectPoint cp41 = createConnectPoint(4, 1);
+        ConnectPoint cp42 = createConnectPoint(4, 2);
+        ConnectPoint cp51 = createConnectPoint(5, 1);
+        ConnectPoint cp52 = createConnectPoint(5, 2);
+        ConnectPoint cp61 = createConnectPoint(6, 1);
+        ConnectPoint cp62 = createConnectPoint(6, 2);
+        ConnectPoint cp71 = createConnectPoint(7, 1);
+
+        Link link1 = createLink(cp12, cp21);
+        Link link2 = createLink(cp22, cp31);
+        Link link3 = createLink(cp32, cp41);
+        Link link4 = createLink(cp42, cp51);
+        Link link5 = createLink(cp52, cp61);
+        Link link6 = createLink(cp62, cp71);
+        List<Link> links = Stream.of(link1, link2, link3, link4, link5, link6).collect(Collectors.toList());
+
+        Path path = new MockPath(cp12, cp71, links);
+
+        // Mocks 2 intents to create OduCtl connectivity
+        OpticalConnectivityIntent connIntent1 = createConnectivityIntent(cp21, cp32);
+        PacketLinkRealizedByOptical oduLink1 = PacketLinkRealizedByOptical.create(cp12, cp41,
+                connIntent1);
+
+        OpticalConnectivityIntent connIntent2 = createConnectivityIntent(cp51, cp62);
+        PacketLinkRealizedByOptical oduLink2 = PacketLinkRealizedByOptical.create(cp42, cp71,
+                connIntent2);
+
+        Bandwidth bandwidth = Bandwidth.bps(100);
+        Duration latency = Duration.ofMillis(10);
+
+        OpticalConnectivityId cid = OpticalConnectivityId.of(1L);
+        OpticalConnectivity oc = new OpticalConnectivity(cid, path, bandwidth, latency);
+
+        oc.addRealizingLink(oduLink1);
+        oc.addRealizingLink(oduLink2);
+
+        assertTrue(oc.isAllRealizingLinkNotEstablished());
+        assertFalse(oc.isAllRealizingLinkEstablished());
+
+        // Sets link realized by connIntent1 to be established
+        oc.setLinkEstablished(cp12, cp41);
+
+        assertFalse(oc.isAllRealizingLinkNotEstablished());
+        assertFalse(oc.isAllRealizingLinkEstablished());
+
+        // Sets link realized by connIntent2 to be established
+        oc.setLinkEstablished(cp42, cp71);
+
+        assertFalse(oc.isAllRealizingLinkNotEstablished());
+        assertTrue(oc.isAllRealizingLinkEstablished());
+    }
+
+    /**
+     * Checks that isAllRealizingLink(Not)Established works for OpticalCircuitIntent.
+     */
+    @Test
+    public void testLinkEstablishedByCircuitIntent() {
+        // Mock 7-nodes linear topology
+        ConnectPoint cp12 = createConnectPoint(1, 2);
+        ConnectPoint cp21 = createConnectPoint(2, 1);
+        ConnectPoint cp22 = createConnectPoint(2, 2);
+        ConnectPoint cp31 = createConnectPoint(3, 1);
+        ConnectPoint cp32 = createConnectPoint(3, 2);
+        ConnectPoint cp41 = createConnectPoint(4, 1);
+        ConnectPoint cp42 = createConnectPoint(4, 2);
+        ConnectPoint cp51 = createConnectPoint(5, 1);
+        ConnectPoint cp52 = createConnectPoint(5, 2);
+        ConnectPoint cp61 = createConnectPoint(6, 1);
+        ConnectPoint cp62 = createConnectPoint(6, 2);
+        ConnectPoint cp71 = createConnectPoint(7, 1);
+
+        Link link1 = createLink(cp12, cp21);
+        Link link2 = createLink(cp22, cp31);
+        Link link3 = createLink(cp32, cp41);
+        Link link4 = createLink(cp42, cp51);
+        Link link5 = createLink(cp52, cp61);
+        Link link6 = createLink(cp62, cp71);
+        List<Link> links = Stream.of(link1, link2, link3, link4, link5, link6).collect(Collectors.toList());
+
+        Path path = new MockPath(cp12, cp71, links);
+
+        // Mocks 2 intents to create Och connectivity
+        OpticalCircuitIntent circuitIntent1 = createCircuitIntent(cp21, cp32);
+        PacketLinkRealizedByOptical ochLink1 = PacketLinkRealizedByOptical.create(cp12, cp41,
+                circuitIntent1);
+
+        OpticalCircuitIntent circuitIntent2 = createCircuitIntent(cp51, cp62);
+        PacketLinkRealizedByOptical ochLink2 = PacketLinkRealizedByOptical.create(cp42, cp71,
+                circuitIntent2);
+
+        Bandwidth bandwidth = Bandwidth.bps(100);
+        Duration latency = Duration.ofMillis(10);
+
+        OpticalConnectivityId cid = OpticalConnectivityId.of(1L);
+        OpticalConnectivity oc = new OpticalConnectivity(cid, path, bandwidth, latency);
+
+        oc.addRealizingLink(ochLink1);
+        oc.addRealizingLink(ochLink2);
+
+        assertTrue(oc.isAllRealizingLinkNotEstablished());
+        assertFalse(oc.isAllRealizingLinkEstablished());
+
+        // Sets link realized by circuitIntent1 to be established
+        oc.setLinkEstablished(cp12, cp41);
+
+        assertFalse(oc.isAllRealizingLinkNotEstablished());
+        assertFalse(oc.isAllRealizingLinkEstablished());
+
+        // Sets link realized by circuitIntent2 to be established
+        oc.setLinkEstablished(cp42, cp71);
+
+        assertFalse(oc.isAllRealizingLinkNotEstablished());
+        assertTrue(oc.isAllRealizingLinkEstablished());
+    }
+
+    private ConnectPoint createConnectPoint(long devIdNum, long portIdNum) {
+        return new ConnectPoint(
+                DeviceId.deviceId(String.format("of:%016d", devIdNum)),
+                PortNumber.portNumber(portIdNum));
+    }
+
+    private Link createLink(ConnectPoint src, ConnectPoint dst) {
+        return DefaultLink.builder()
+                .providerId(providerId)
+                .src(src)
+                .dst(dst)
+                .type(Link.Type.DIRECT)
+                .annotations(DefaultAnnotations.EMPTY)
+                .build();
+    }
+
+    private OpticalCircuitIntent createCircuitIntent(ConnectPoint src, ConnectPoint dst) {
+        OpticalCircuitIntent intent = OpticalCircuitIntent.builder()
+                .appId(appId)
+                .bidirectional(true)
+                .src(src)
+                .dst(dst)
+                .signalType(CltSignalType.CLT_100GBE)
+                .build();
+
+        return intent;
+    }
+
+    private OpticalConnectivityIntent createConnectivityIntent(ConnectPoint src, ConnectPoint dst) {
+        OpticalConnectivityIntent intent = OpticalConnectivityIntent.builder()
+                .appId(appId)
+                .bidirectional(true)
+                .src(src)
+                .dst(dst)
+                .signalType(OduSignalType.ODU4)
+                .build();
+
+        return intent;
+    }
+
+    private class MockPath extends DefaultLink implements Path {
+        List<Link> links;
+
+        protected MockPath(ConnectPoint src, ConnectPoint dst, List<Link> links) {
+            super(providerId, src, dst, Type.INDIRECT, State.ACTIVE);
+            this.links = links;
+        }
+
+        @Override
+        public List<Link> links() {
+            return links;
+        }
+
+        @Override
+        public double cost() {
+            return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/newoptical/src/test/java/org/onosproject/newoptical/OpticalPathProvisionerTest.java b/apps/newoptical/src/test/java/org/onosproject/newoptical/OpticalPathProvisionerTest.java
new file mode 100644
index 0000000..efbaf77
--- /dev/null
+++ b/apps/newoptical/src/test/java/org/onosproject/newoptical/OpticalPathProvisionerTest.java
@@ -0,0 +1,681 @@
+/*
+ * Copyright 2016 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.newoptical;
+
+import javafx.util.Pair;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.ChassisId;
+import org.onlab.util.Bandwidth;
+import org.onlab.util.Frequency;
+import org.onosproject.cluster.ClusterServiceAdapter;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.event.DefaultEventSinkRegistry;
+import org.onosproject.event.Event;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.event.EventSink;
+import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.net.ChannelSpacing;
+import org.onosproject.net.CltSignalType;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.DefaultPath;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.ElementId;
+import org.onosproject.net.Link;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.OduSignalType;
+import org.onosproject.net.Path;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigServiceAdapter;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentEvent;
+import org.onosproject.net.intent.IntentListener;
+import org.onosproject.net.intent.IntentServiceAdapter;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.OpticalConnectivityIntent;
+import org.onosproject.net.link.LinkServiceAdapter;
+import org.onosproject.net.optical.impl.DefaultOchPort;
+import org.onosproject.net.optical.impl.DefaultOduCltPort;
+import org.onosproject.net.optical.impl.DefaultOmsPort;
+import org.onosproject.net.provider.ProviderId;
+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.ResourceListener;
+import org.onosproject.net.resource.ResourceService;
+import org.onosproject.net.topology.LinkWeight;
+import org.onosproject.net.topology.PathServiceAdapter;
+import org.onosproject.newoptical.api.OpticalConnectivityId;
+import org.onosproject.newoptical.api.OpticalPathEvent;
+import org.onosproject.newoptical.api.OpticalPathListener;
+import org.onosproject.store.service.AtomicCounter;
+import org.onosproject.store.service.StorageServiceAdapter;
+
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static com.google.common.base.Preconditions.checkState;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.NetTestTools.injectEventDispatcher;
+
+/**
+ * Tests for OpticalPathProvisioner class.
+ */
+public class OpticalPathProvisionerTest {
+
+    private static final ProviderId PROVIDER_ID = new ProviderId("of", "foo");
+
+    // 7-nodes linear topology containing packet/cross-connect/optical links
+    private static final ConnectPoint CP11 = createConnectPoint(1, 1);
+    private static final ConnectPoint CP12 = createConnectPoint(1, 2);
+    private static final ConnectPoint CP21 = createConnectPoint(2, 1);
+    private static final ConnectPoint CP22 = createConnectPoint(2, 2); // cross connect port (packet)
+    private static final ConnectPoint CP31 = createConnectPoint(3, 1); // cross connect port (oductl)
+    private static final ConnectPoint CP32 = createConnectPoint(3, 2);
+    private static final ConnectPoint CP41 = createConnectPoint(4, 1);
+    private static final ConnectPoint CP42 = createConnectPoint(4, 2);
+    private static final ConnectPoint CP51 = createConnectPoint(5, 1);
+    private static final ConnectPoint CP52 = createConnectPoint(5, 2); // cross connect port (oductl)
+    private static final ConnectPoint CP61 = createConnectPoint(6, 1); // cross connect port (packet)
+    private static final ConnectPoint CP62 = createConnectPoint(6, 2);
+    private static final ConnectPoint CP71 = createConnectPoint(7, 1);
+    private static final ConnectPoint CP72 = createConnectPoint(7, 2);
+
+    private static final Link LINK1 = createLink(CP12, CP21, Link.Type.DIRECT);
+    private static final Link LINK2 = createLink(CP22, CP31, Link.Type.OPTICAL); // cross connect link
+    private static final Link LINK3 = createLink(CP32, CP41, Link.Type.OPTICAL);
+    private static final Link LINK4 = createLink(CP42, CP51, Link.Type.OPTICAL);
+    private static final Link LINK5 = createLink(CP52, CP61, Link.Type.OPTICAL); // cross connect link
+    private static final Link LINK6 = createLink(CP62, CP71, Link.Type.DIRECT);
+
+    private static final Device DEVICE1 = createDevice(1, Device.Type.SWITCH);
+    private static final Device DEVICE2 = createDevice(2, Device.Type.SWITCH);
+    private static final Device DEVICE3 = createDevice(3, Device.Type.ROADM);
+    private static final Device DEVICE4 = createDevice(4, Device.Type.ROADM);
+    private static final Device DEVICE5 = createDevice(5, Device.Type.ROADM);
+    private static final Device DEVICE6 = createDevice(6, Device.Type.SWITCH);
+    private static final Device DEVICE7 = createDevice(7, Device.Type.SWITCH);
+
+    private static final Port PORT11 = createPacketPort(DEVICE1, CP11);
+    private static final Port PORT12 = createPacketPort(DEVICE1, CP12);
+    private static final Port PORT21 = createPacketPort(DEVICE2, CP21);
+    private static final Port PORT22 = createOduCltPort(DEVICE2, CP22);
+    private static final Port PORT31 = createOchPort(DEVICE3, CP31);
+    private static final Port PORT32 = createOmsPort(DEVICE3, CP32);
+    private static final Port PORT41 = createOmsPort(DEVICE4, CP41);
+    private static final Port PORT42 = createOmsPort(DEVICE4, CP42);
+    private static final Port PORT51 = createOmsPort(DEVICE5, CP51);
+    private static final Port PORT52 = createOchPort(DEVICE5, CP52);
+    private static final Port PORT61 = createOduCltPort(DEVICE6, CP61);
+    private static final Port PORT62 = createPacketPort(DEVICE6, CP62);
+    private static final Port PORT71 = createPacketPort(DEVICE7, CP71);
+    private static final Port PORT72 = createPacketPort(DEVICE7, CP72);
+
+    protected OpticalPathProvisioner target;
+    protected TestListener listener = new TestListener();
+    protected TestDeviceService deviceService;
+    protected TestLinkService linkService;
+    protected TestPathService pathService;
+    protected TestIntentService intentService;
+    protected IdGenerator idGenerator;
+
+    @Before
+    public void setUp() {
+        this.deviceService = new TestDeviceService();
+        deviceService.devMap.put(deviceIdOf(1), DEVICE1);
+        deviceService.devMap.put(deviceIdOf(2), DEVICE2);
+        deviceService.devMap.put(deviceIdOf(3), DEVICE3);
+        deviceService.devMap.put(deviceIdOf(4), DEVICE4);
+        deviceService.devMap.put(deviceIdOf(5), DEVICE5);
+        deviceService.devMap.put(deviceIdOf(6), DEVICE6);
+        deviceService.devMap.put(deviceIdOf(7), DEVICE7);
+        deviceService.portMap.put(CP11, PORT11);
+        deviceService.portMap.put(CP12, PORT12);
+        deviceService.portMap.put(CP21, PORT21);
+        deviceService.portMap.put(CP22, PORT22);
+        deviceService.portMap.put(CP31, PORT31);
+        deviceService.portMap.put(CP32, PORT32);
+        deviceService.portMap.put(CP41, PORT41);
+        deviceService.portMap.put(CP42, PORT42);
+        deviceService.portMap.put(CP51, PORT51);
+        deviceService.portMap.put(CP52, PORT52);
+        deviceService.portMap.put(CP61, PORT61);
+        deviceService.portMap.put(CP62, PORT62);
+        deviceService.portMap.put(CP71, PORT71);
+        deviceService.portMap.put(CP72, PORT72);
+
+        this.linkService = new TestLinkService();
+        linkService.links.addAll(Stream.of(LINK1, LINK2, LINK3, LINK4, LINK5, LINK6)
+            .collect(Collectors.toList()));
+
+        this.pathService = new TestPathService();
+        this.intentService = new TestIntentService();
+
+        this.target = new OpticalPathProvisioner();
+        target.coreService = new TestCoreService();
+        target.intentService = this.intentService;
+        target.pathService = this.pathService;
+        target.linkService = this.linkService;
+        target.mastershipService = new TestMastershipService();
+        target.clusterService = new TestClusterService();
+        target.storageService = new TestStorageService();
+        target.deviceService = this.deviceService;
+        target.networkConfigService = new TestNetworkConfigService();
+        target.resourceService = new TestResourceService();
+        injectEventDispatcher(target, new TestEventDispatcher());
+        target.addListener(listener);
+
+        target.activate();
+
+        // To overwrite opticalView-ed deviceService
+        target.deviceService = this.deviceService;
+
+        idGenerator = new IdGenerator() {
+            int counter = 1;
+
+            @Override
+            public long getNewId() {
+                return counter++;
+            }
+        };
+        Intent.bindIdGenerator(idGenerator);
+    }
+
+    @After
+    public void tearDown() {
+        Intent.unbindIdGenerator(idGenerator);
+        target.removeListener(listener);
+        target = null;
+    }
+
+    /**
+     * Checks setupConnectivity method works.
+     */
+    @Test
+    public void testSetupConnectivity() {
+        Bandwidth bandwidth = Bandwidth.bps(100);
+        Duration latency = Duration.ofMillis(10);
+
+        OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);
+        assertNotNull(cid);
+
+        // Checks path computation is called as expected
+        assertEquals(1, pathService.edges.size());
+        assertEquals(CP12.deviceId(), pathService.edges.get(0).getKey());
+        assertEquals(CP71.deviceId(), pathService.edges.get(0).getValue());
+
+        // Checks intents are installed as expected
+        assertEquals(1, intentService.submitted.size());
+        assertEquals(OpticalConnectivityIntent.class, intentService.submitted.get(0).getClass());
+        OpticalConnectivityIntent connIntent = (OpticalConnectivityIntent) intentService.submitted.get(0);
+        assertEquals(CP31, connIntent.getSrc());
+        assertEquals(CP52, connIntent.getDst());
+    }
+
+    /**
+     * Checks setupPath method works.
+     */
+    @Test
+    public void testSetupPath() {
+        Bandwidth bandwidth = Bandwidth.bps(100);
+        Duration latency = Duration.ofMillis(10);
+        List<Link> links = Stream.of(LINK1, LINK2, LINK3, LINK4, LINK5, LINK6)
+                .collect(Collectors.toList());
+        Path path = new DefaultPath(PROVIDER_ID, links, 0);
+
+        OpticalConnectivityId cid = target.setupPath(path, bandwidth, latency);
+        assertNotNull(cid);
+
+        // Checks intents are installed as expected
+        assertEquals(1, intentService.submitted.size());
+        assertEquals(OpticalConnectivityIntent.class, intentService.submitted.get(0).getClass());
+        OpticalConnectivityIntent connIntent = (OpticalConnectivityIntent) intentService.submitted.get(0);
+        assertEquals(CP31, connIntent.getSrc());
+        assertEquals(CP52, connIntent.getDst());
+    }
+
+    /**
+     * Checks removeConnectivity method works.
+     */
+    @Test
+    public void testRemoveConnectivity() {
+        Bandwidth bandwidth = Bandwidth.bps(100);
+        Duration latency = Duration.ofMillis(10);
+
+        OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);
+
+        // Checks intents are withdrawn
+        assertTrue(target.removeConnectivity(cid));
+        assertEquals(1, intentService.withdrawn.size());
+        assertEquals(OpticalConnectivityIntent.class, intentService.withdrawn.get(0).getClass());
+        OpticalConnectivityIntent connIntent = (OpticalConnectivityIntent) intentService.withdrawn.get(0);
+        assertEquals(CP31, connIntent.getSrc());
+        assertEquals(CP52, connIntent.getDst());
+    }
+
+    /**
+     * Checks getPath method works.
+     */
+    @Test
+    public void testGetPath() {
+        Bandwidth bandwidth = Bandwidth.bps(100);
+        Duration latency = Duration.ofMillis(10);
+        List<Link> links = Stream.of(LINK1, LINK2, LINK3, LINK4, LINK5, LINK6)
+                .collect(Collectors.toList());
+
+        OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);
+        Optional<List<Link>> path = target.getPath(cid);
+
+        // Checks returned path is as expected
+        assertTrue(path.isPresent());
+        assertEquals(links, path.get());
+    }
+
+    /**
+     * Checks if PATH_INSTALLED event comes up after intent is installed.
+     */
+    @Test
+    public void testInstalledEvent() {
+        Bandwidth bandwidth = Bandwidth.bps(100);
+        Duration latency = Duration.ofMillis(10);
+
+        OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);
+
+        intentService.notifyInstalled();
+
+        assertEquals(1, listener.events.size());
+        assertEquals(OpticalPathEvent.Type.PATH_INSTALLED, listener.events.get(0).type());
+        assertEquals(cid, listener.events.get(0).subject());
+    }
+
+    /**
+     * Checks if PATH_REMOVED event comes up after packet link is removed.
+     */
+    @Test
+    public void testRemovedEvent() {
+        Bandwidth bandwidth = Bandwidth.bps(100);
+        Duration latency = Duration.ofMillis(10);
+
+        OpticalConnectivityId cid = target.setupConnectivity(CP12, CP71, bandwidth, latency);
+
+        intentService.notifyInstalled();
+
+        target.removeConnectivity(cid);
+
+        intentService.notifyWithdrawn();
+
+        assertEquals(2, listener.events.size());
+        assertEquals(OpticalPathEvent.Type.PATH_REMOVED, listener.events.get(1).type());
+        assertEquals(cid, listener.events.get(1).subject());
+    }
+
+    private static ConnectPoint createConnectPoint(long devIdNum, long portIdNum) {
+        return new ConnectPoint(
+                deviceIdOf(devIdNum),
+                PortNumber.portNumber(portIdNum));
+    }
+
+    private static Link createLink(ConnectPoint src, ConnectPoint dst, Link.Type type) {
+        return DefaultLink.builder()
+                .providerId(PROVIDER_ID)
+                .src(src)
+                .dst(dst)
+                .state(Link.State.ACTIVE)
+                .type(type).build();
+    }
+
+    private static Device createDevice(long devIdNum, Device.Type type) {
+        return new DefaultDevice(PROVIDER_ID,
+                deviceIdOf(devIdNum),
+                type,
+                "manufacturer",
+                "hwVersion",
+                "swVersion",
+                "serialNumber",
+                new ChassisId(1));
+    }
+
+    private static Port createPacketPort(Device device, ConnectPoint cp) {
+        return new DefaultPort(device, cp.port(), true);
+    }
+
+    private static Port createOchPort(Device device, ConnectPoint cp) {
+        return new DefaultOchPort(new DefaultPort(device, cp.port(), true),
+                OduSignalType.ODU4,
+                true,
+                OchSignal.newDwdmSlot(ChannelSpacing.CHL_50GHZ, 1));
+    }
+
+    private static Port createOduCltPort(Device device, ConnectPoint cp) {
+        return new DefaultOduCltPort(new DefaultPort(device, cp.port(), true),
+                CltSignalType.CLT_100GBE);
+    }
+
+    private static Port createOmsPort(Device device, ConnectPoint cp) {
+        return new DefaultOmsPort(new DefaultPort(device, cp.port(), true),
+                Frequency.ofKHz(3),
+                Frequency.ofKHz(33),
+                Frequency.ofKHz(2));
+    }
+
+    private static DeviceId deviceIdOf(long devIdNum) {
+        return DeviceId.deviceId(String.format("of:%016d", devIdNum));
+    }
+
+    private static class TestListener implements OpticalPathListener {
+        final List<OpticalPathEvent> events = new ArrayList<>();
+
+        @Override
+        public void event(OpticalPathEvent event) {
+            events.add(event);
+        }
+    }
+
+    private static class TestPathService extends PathServiceAdapter {
+        List<Pair<DeviceId, DeviceId>> edges = new ArrayList<>();
+
+        @Override
+        public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) {
+            if (!(src instanceof DeviceId && dst instanceof DeviceId)) {
+                return Collections.emptySet();
+            }
+
+            edges.add(new Pair<>((DeviceId) src, (DeviceId) dst));
+
+            Set<Path> paths = new HashSet<>();
+            List<Link> links = Stream.of(LINK1, LINK2, LINK3, LINK4, LINK5, LINK6)
+                    .collect(Collectors.toList());
+            paths.add(new DefaultPath(PROVIDER_ID, links, 0));
+
+            // returns paths containing single path
+            return paths;
+        }
+
+    }
+
+    private static class TestIntentService extends IntentServiceAdapter {
+        List<Intent> submitted = new ArrayList<>();
+        List<Intent> withdrawn = new ArrayList<>();
+        List<IntentListener> listeners = new ArrayList<>();
+
+        @Override
+        public void submit(Intent intent) {
+            submitted.add(intent);
+        }
+
+        @Override
+        public void withdraw(Intent intent) {
+            withdrawn.add(intent);
+        }
+
+        @Override
+        public void addListener(IntentListener listener) {
+            listeners.add(listener);
+        }
+
+        @Override
+        public Intent getIntent(Key intentKey) {
+            Intent intent = submitted.stream().filter(i -> i.key().equals(intentKey))
+                    .findAny()
+                    .get();
+            return intent;
+        }
+
+        void notifyInstalled() {
+            submitted.forEach(i -> {
+                IntentEvent event = new IntentEvent(IntentEvent.Type.INSTALLED, i);
+                listeners.forEach(l -> l.event(event));
+            });
+        }
+
+        void notifyWithdrawn() {
+            withdrawn.forEach(i -> {
+                IntentEvent event = new IntentEvent(IntentEvent.Type.WITHDRAWN, i);
+                listeners.forEach(l -> l.event(event));
+            });
+        }
+
+    }
+
+    private static class TestLinkService extends LinkServiceAdapter {
+        List<Link> links = new ArrayList<>();
+
+        @Override
+        public Set<Link> getLinks(ConnectPoint connectPoint) {
+            return links.stream()
+                    .filter(l -> l.src().equals(connectPoint) || l.dst().equals(connectPoint))
+                    .collect(Collectors.toSet());
+        }
+
+    }
+
+    private static class TestCoreService extends CoreServiceAdapter {
+        @Override
+        public ApplicationId registerApplication(String name) {
+            return new DefaultApplicationId(0, name);
+        }
+    }
+
+    private static class TestMastershipService extends MastershipServiceAdapter {
+
+    }
+
+    private static class TestClusterService extends ClusterServiceAdapter {
+
+    }
+
+    private static class TestStorageService extends StorageServiceAdapter {
+        @Override
+        public AtomicCounter getAtomicCounter(String name) {
+            return new MockAtomicCounter();
+        }
+    }
+
+    private static class TestDeviceService extends DeviceServiceAdapter {
+        Map<DeviceId, Device> devMap = new HashMap<>();
+        Map<ConnectPoint, Port> portMap = new HashMap<>();
+
+        @Override
+        public Device getDevice(DeviceId deviceId) {
+            return devMap.get(deviceId);
+        }
+
+        @Override
+        public Port getPort(DeviceId deviceId, PortNumber portNumber) {
+            return portMap.get(new ConnectPoint(deviceId, portNumber));
+        }
+    }
+
+    private static class TestNetworkConfigService extends NetworkConfigServiceAdapter {
+
+    }
+
+    private static class TestResourceService implements ResourceService {
+
+        @Override
+        public List<ResourceAllocation> allocate(ResourceConsumer consumer, List<Resource> resources) {
+            List<ResourceAllocation> allocations = new ArrayList<>();
+
+            resources.forEach(r -> allocations.add(new ResourceAllocation(r, consumer.consumerId())));
+
+            return allocations;
+        }
+
+        @Override
+        public boolean release(List<ResourceAllocation> allocations) {
+            return false;
+        }
+
+        @Override
+        public boolean release(ResourceConsumer consumer) {
+
+            return true;
+        }
+
+        @Override
+        public void addListener(ResourceListener listener) {
+
+        }
+
+        @Override
+        public void removeListener(ResourceListener listener) {
+
+        }
+
+        @Override
+        public List<ResourceAllocation> getResourceAllocations(ResourceId id) {
+            return null;
+        }
+
+        @Override
+        public <T> Collection<ResourceAllocation> getResourceAllocations(DiscreteResourceId parent, Class<T> cls) {
+            return null;
+        }
+
+        @Override
+        public Collection<ResourceAllocation> getResourceAllocations(ResourceConsumer consumer) {
+            return null;
+        }
+
+        @Override
+        public Set<Resource> getAvailableResources(DiscreteResourceId parent) {
+            return null;
+        }
+
+        @Override
+        public <T> Set<Resource> getAvailableResources(DiscreteResourceId parent, Class<T> cls) {
+            return null;
+        }
+
+        @Override
+        public <T> Set<T> getAvailableResourceValues(DiscreteResourceId parent, Class<T> cls) {
+            return null;
+        }
+
+        @Override
+        public Set<Resource> getRegisteredResources(DiscreteResourceId parent) {
+            return null;
+        }
+
+        @Override
+        public boolean isAvailable(Resource resource) {
+            return true;
+        }
+    }
+
+    private static class MockAtomicCounter implements AtomicCounter {
+        long id = 0;
+
+        @Override
+        public long incrementAndGet() {
+            return ++id;
+        }
+
+        @Override
+        public long getAndIncrement() {
+            return id++;
+        }
+
+        @Override
+        public long getAndAdd(long delta) {
+            long oldId = id;
+            id += delta;
+            return oldId;
+        }
+
+        @Override
+        public long addAndGet(long delta) {
+            id += delta;
+            return id;
+        }
+
+        @Override
+        public void set(long value) {
+            id = value;
+        }
+
+        @Override
+        public boolean compareAndSet(long expectedValue, long updateValue) {
+            if (id == expectedValue) {
+                id = updateValue;
+                return true;
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public long get() {
+            return id;
+        }
+
+        @Override
+        public String name() {
+            return "MockAtomicCounter";
+        }
+    }
+
+    // copied from org.onosproject.common.event.impl.TestEventDispatcher
+    /**
+     * Implements event delivery system that delivers events synchronously, or
+     * in-line with the post method invocation.
+     */
+    public class TestEventDispatcher extends DefaultEventSinkRegistry
+            implements EventDeliveryService {
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public synchronized void post(Event event) {
+            EventSink sink = getSink(event.getClass());
+            checkState(sink != null, "No sink for event %s", event);
+            sink.process(event);
+        }
+
+        @Override
+        public void setDispatchTimeLimit(long millis) {
+        }
+
+        @Override
+        public long getDispatchTimeLimit() {
+            return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/newoptical/src/test/java/org/onosproject/newoptical/PacketLinkRealizedByOpticalTest.java b/apps/newoptical/src/test/java/org/onosproject/newoptical/PacketLinkRealizedByOpticalTest.java
new file mode 100644
index 0000000..e2570ed
--- /dev/null
+++ b/apps/newoptical/src/test/java/org/onosproject/newoptical/PacketLinkRealizedByOpticalTest.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2016 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.newoptical;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.util.Bandwidth;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.net.CltSignalType;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.OduSignalType;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.OpticalCircuitIntent;
+import org.onosproject.net.intent.OpticalConnectivityIntent;
+
+import static org.junit.Assert.*;
+
+/**
+ * Test class for PacketLinkRealizedByOptical class.
+ */
+public class PacketLinkRealizedByOpticalTest {
+
+    private final ApplicationId appId = new DefaultApplicationId(0, "PacketLinkRealizedByOpticalTest");
+    private IdGenerator idGenerator;
+
+    @Before
+    public void setUp() {
+        idGenerator = new IdGenerator() {
+            int counter = 1;
+
+            @Override
+            public long getNewId() {
+                return counter++;
+            }
+        };
+
+        Intent.bindIdGenerator(idGenerator);
+    }
+
+    @After
+    public void tearDown() {
+        Intent.unbindIdGenerator(idGenerator);
+    }
+
+    /**
+     * Checks the construction of PacketLinkRealizedByOptical object with all parameters specified.
+     */
+    @Test
+    public void testCreate() {
+        ConnectPoint cp1 = new ConnectPoint(DeviceId.deviceId("of:0000000000000001"), PortNumber.portNumber(1L));
+        ConnectPoint cp2 = new ConnectPoint(DeviceId.deviceId("of:0000000000000002"), PortNumber.portNumber(2L));
+        Key key = Key.of(10L, appId);
+        Bandwidth bandwidth = Bandwidth.bps(100L);
+
+        PacketLinkRealizedByOptical plink = new PacketLinkRealizedByOptical(cp1, cp2, key, bandwidth);
+
+        assertNotNull(plink);
+        assertEquals(plink.src(), cp1);
+        assertEquals(plink.dst(), cp2);
+        assertEquals((long) plink.bandwidth().bps(), 100L);
+    }
+
+    /**
+     * Checks the construction of OpticalConnectivityId object with OpticalCircuitIntent.
+     */
+    @Test
+    public void testCreateWithCircuitIntent() {
+        ConnectPoint cp1 = new ConnectPoint(DeviceId.deviceId("of:0000000000000001"), PortNumber.portNumber(1L));
+        ConnectPoint cp2 = new ConnectPoint(DeviceId.deviceId("of:0000000000000002"), PortNumber.portNumber(2L));
+        OpticalCircuitIntent circuitIntent = OpticalCircuitIntent.builder()
+                .appId(appId)
+                .src(cp1)
+                .dst(cp2)
+                .bidirectional(true)
+                .key(Key.of(0, appId))
+                .signalType(CltSignalType.CLT_1GBE)
+                .build();
+
+        PacketLinkRealizedByOptical plink = PacketLinkRealizedByOptical.create(cp1, cp2, circuitIntent);
+
+        assertNotNull(plink);
+        assertEquals(plink.src(), cp1);
+        assertEquals(plink.dst(), cp2);
+        assertEquals((long) plink.bandwidth().bps(), CltSignalType.CLT_1GBE.bitRate());
+    }
+
+    /**
+     * Checks the construction of OpticalConnectivityId object with OpticalConnectivityIntent.
+     */
+    @Test
+    public void testCreateWithConnectivityIntent() {
+        ConnectPoint cp1 = new ConnectPoint(DeviceId.deviceId("of:0000000000000001"), PortNumber.portNumber(1L));
+        ConnectPoint cp2 = new ConnectPoint(DeviceId.deviceId("of:0000000000000002"), PortNumber.portNumber(2L));
+        OpticalConnectivityIntent connIntent = OpticalConnectivityIntent.builder()
+                .appId(appId)
+                .src(cp1)
+                .dst(cp2)
+                .bidirectional(true)
+                .key(Key.of(0, appId))
+                .signalType(OduSignalType.ODU4)
+                .build();
+
+        PacketLinkRealizedByOptical plink = PacketLinkRealizedByOptical.create(cp1, cp2, connIntent);
+
+        assertNotNull(plink);
+        assertEquals(plink.src(), cp1);
+        assertEquals(plink.dst(), cp2);
+        assertEquals((long) plink.bandwidth().bps(), OduSignalType.ODU4.bitRate());
+    }
+
+    /**
+     * Checks that isBetween() method works.
+     */
+    @Test
+    public void testIsBetween() {
+        ConnectPoint cp1 = new ConnectPoint(DeviceId.deviceId("of:0000000000000001"), PortNumber.portNumber(1L));
+        ConnectPoint cp2 = new ConnectPoint(DeviceId.deviceId("of:0000000000000002"), PortNumber.portNumber(2L));
+        ConnectPoint cp3 = new ConnectPoint(DeviceId.deviceId("of:0000000000000003"), PortNumber.portNumber(3L));
+        OpticalCircuitIntent ochIntent = OpticalCircuitIntent.builder()
+                .appId(appId)
+                .src(cp1)
+                .dst(cp2)
+                .bidirectional(true)
+                .key(Key.of(0, appId))
+                .signalType(CltSignalType.CLT_1GBE)
+                .build();
+
+        PacketLinkRealizedByOptical plink = PacketLinkRealizedByOptical.create(cp1, cp2, ochIntent);
+
+        assertTrue(plink.isBetween(cp1, cp2));
+        assertFalse(plink.isBetween(cp1, cp3));
+    }
+}
\ No newline at end of file
diff --git a/apps/newoptical/src/test/java/org/onosproject/newoptical/api/OpticalConnectivityIdTest.java b/apps/newoptical/src/test/java/org/onosproject/newoptical/api/OpticalConnectivityIdTest.java
new file mode 100644
index 0000000..7407821
--- /dev/null
+++ b/apps/newoptical/src/test/java/org/onosproject/newoptical/api/OpticalConnectivityIdTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2016 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.newoptical.api;
+
+import org.junit.Test;
+import com.google.common.testing.EqualsTester;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+/**
+ * Test class for OpticalConnectivityId.
+ */
+public class OpticalConnectivityIdTest {
+
+    /**
+     * Checks that OpticalConnectivityId class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(OpticalConnectivityId.class);
+    }
+
+    /**
+     * Checks the construction of OpticalConnectivityId object.
+     */
+    @Test
+    public void testConstruction() {
+        OpticalConnectivityId tid = OpticalConnectivityId.of(1L);
+        assertNotNull(tid);
+        assertEquals(tid.id().longValue(), 1L);
+    }
+
+    /**
+     * Checks the equality of OpticalConnectivityId objects.
+     */
+    @Test
+    public void testEquality() {
+        OpticalConnectivityId tid1 = OpticalConnectivityId.of(1L);
+        OpticalConnectivityId tid2 = OpticalConnectivityId.of(1L);
+        OpticalConnectivityId tid3 = OpticalConnectivityId.of(2L);
+
+        new EqualsTester()
+                .addEqualityGroup(tid1, tid2)
+                .addEqualityGroup(tid3)
+                .testEquals();
+    }
+}
\ No newline at end of file
diff --git a/apps/newoptical/src/test/java/org/onosproject/newoptical/api/OpticalPathEventTest.java b/apps/newoptical/src/test/java/org/onosproject/newoptical/api/OpticalPathEventTest.java
new file mode 100644
index 0000000..3a9832a
--- /dev/null
+++ b/apps/newoptical/src/test/java/org/onosproject/newoptical/api/OpticalPathEventTest.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2016 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.newoptical.api;
+
+import org.junit.Test;
+import org.onosproject.event.AbstractEventTest;
+
+/**
+ * Test class for OpticalPathEvent class.
+ */
+public class OpticalPathEventTest extends AbstractEventTest {
+
+    @Override
+    @Test
+    public void withoutTime() {
+        OpticalConnectivityId cid = OpticalConnectivityId.of(1L);
+        long before = System.currentTimeMillis();
+        OpticalPathEvent event = new OpticalPathEvent(OpticalPathEvent.Type.PATH_INSTALLED, cid);
+        long after = System.currentTimeMillis();
+        validateEvent(event, OpticalPathEvent.Type.PATH_INSTALLED, cid, before, after);
+    }
+
+}
\ No newline at end of file
