diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/OpticalOduIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/OpticalOduIntentCompilerTest.java
new file mode 100644
index 0000000..d5053b3
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/OpticalOduIntentCompilerTest.java
@@ -0,0 +1,433 @@
+/*
+ * 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.net.intent.impl.compiler;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.ChassisId;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.DefaultAnnotations;
+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.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.OduCltPort;
+import org.onosproject.net.OduSignalId;
+import org.onosproject.net.OduSignalType;
+import org.onosproject.net.OduSignalUtils;
+import org.onosproject.net.OtuPort;
+import org.onosproject.net.OtuSignalType;
+import org.onosproject.net.Path;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TributarySlot;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.intent.FlowRuleIntent;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentExtensionService;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MockIdGenerator;
+import org.onosproject.net.intent.OpticalOduIntent;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.topology.LinkWeight;
+import org.onosproject.net.topology.Topology;
+import org.onosproject.net.topology.TopologyServiceAdapter;
+import org.onosproject.net.device.DeviceServiceAdapter;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.onosproject.net.AnnotationKeys.STATIC_PORT;
+import static org.onosproject.net.AnnotationKeys.PORT_NAME;
+import static org.onosproject.net.Device.Type.OTN;
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.Link.Type.OPTICAL;
+import static org.onosproject.net.NetTestTools.APP_ID;
+import static org.onosproject.net.NetTestTools.PID;
+
+public class OpticalOduIntentCompilerTest {
+
+    private static final String DEV1 = "of:1";
+    private static final String DEV2 = "of:2";
+    private static final String DEV3 = "of:3";
+
+    static final Key KEY1 = Key.of(5L, APP_ID);
+
+    private static final String STATIC_TRUE = "true";
+    private static final String PNAME = "p2";
+
+    private CoreService coreService;
+    private IntentExtensionService intentExtensionService;
+    private final IdGenerator idGenerator = new MockIdGenerator();
+    private OpticalOduIntentCompiler sut;
+
+    private final ApplicationId appId = new TestApplicationId("test");
+    private static Device device1 = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), OTN,
+            "m", "h", "s", "n", new ChassisId(0L));
+    private static Device device2 = new DefaultDevice(ProviderId.NONE, deviceId(DEV2), OTN,
+            "m", "h", "s", "n", new ChassisId(1L));
+    private static Device device3 = new DefaultDevice(ProviderId.NONE, deviceId(DEV3), OTN,
+            "m", "h", "s", "n", new ChassisId(2L));
+
+    private static Annotations annotations1 = DefaultAnnotations.builder().set(STATIC_PORT, STATIC_TRUE).build();
+    private static Annotations annotations2 = DefaultAnnotations.builder().set(PORT_NAME, PNAME).build();
+
+    // OduClt ports with signalType=1GBE
+    private static final OduCltPort D1P1 =
+            new OduCltPort(device1, PortNumber.portNumber(1), true, CltSignalType.CLT_1GBE, annotations1);
+    private static final OduCltPort D3P2 =
+            new OduCltPort(device3, PortNumber.portNumber(2), true, CltSignalType.CLT_1GBE, annotations1);
+
+    // Otu ports with signalType=ODU2
+    private static final OtuPort D1P2 =
+            new OtuPort(device1, PortNumber.portNumber(2), true, OtuSignalType.OTU2, annotations2);
+    private static final OtuPort D2P1 =
+            new OtuPort(device2, PortNumber.portNumber(1), true, OtuSignalType.OTU2, annotations2);
+    private static final OtuPort D2P2 =
+            new OtuPort(device2, PortNumber.portNumber(2), true, OtuSignalType.OTU2, annotations2);
+    private static final OtuPort D3P1 =
+            new OtuPort(device3, PortNumber.portNumber(1), true, OtuSignalType.OTU2, annotations2);
+
+    // OduClt ports with signalType=10GBE
+    private static final OduCltPort D1P3 =
+            new OduCltPort(device1, PortNumber.portNumber(3), true, CltSignalType.CLT_10GBE, annotations1);
+    private static final OduCltPort D3P3 =
+            new OduCltPort(device3, PortNumber.portNumber(3), true, CltSignalType.CLT_10GBE, annotations1);
+
+    // OduCltPort ConnectPoints
+    private final ConnectPoint d1p1 = new ConnectPoint(device1.id(), D1P1.number());
+    private final ConnectPoint d1p3 = new ConnectPoint(device1.id(), D1P3.number());
+    private final ConnectPoint d3p2 = new ConnectPoint(device3.id(), D3P2.number());
+    private final ConnectPoint d3p3 = new ConnectPoint(device3.id(), D3P3.number());
+
+    // OtuPort ConnectPoints
+    private final ConnectPoint d1p2 = new ConnectPoint(device1.id(), D1P2.number());
+    private final ConnectPoint d2p1 = new ConnectPoint(device2.id(), D2P1.number());
+    private final ConnectPoint d2p2 = new ConnectPoint(device2.id(), D2P2.number());
+    private final ConnectPoint d3p1 = new ConnectPoint(device3.id(), D3P1.number());
+
+    private final List<Link> links = Arrays.asList(
+            DefaultLink.builder().providerId(PID).src(d1p2).dst(d2p1).type(OPTICAL).build(),
+            DefaultLink.builder().providerId(PID).src(d2p2).dst(d3p1).type(OPTICAL).build()
+    );
+    private final Path path = new DefaultPath(PID, links, 3);
+
+    private OpticalOduIntent intent;
+
+    /**
+     * Mocks the topology service to give paths in the test.
+     */
+    private class MockTopologyService extends TopologyServiceAdapter {
+        Set<Path> paths = Sets.newHashSet(path);
+
+        @Override
+        public Topology currentTopology() {
+            return null;
+        }
+
+        @Override
+        public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight) {
+            return paths;
+        }
+    }
+
+    /**
+     * Mocks the device service so that devices and ports appear available in the test.
+     */
+    private static class MockDeviceService extends DeviceServiceAdapter {
+        @Override
+        public boolean isAvailable(DeviceId deviceId) {
+            return true;
+        }
+
+        @Override
+        public List<Port> getPorts(DeviceId deviceId) {
+            if (deviceId.equals(deviceId(DEV1))) {
+                return ImmutableList.of((Port) D1P1, (Port) D1P2, (Port) D1P3);
+            }
+
+            if (deviceId.equals(deviceId(DEV2))) {
+                return ImmutableList.of((Port) D2P1, (Port) D2P2);
+            }
+
+            if (deviceId.equals(deviceId(DEV3))) {
+                return ImmutableList.of((Port) D3P1, (Port) D3P2, (Port) D3P3);
+            }
+
+            return Collections.emptyList();
+        }
+
+        @Override
+        public Port getPort(DeviceId deviceId, PortNumber portNumber) {
+            if (deviceId.equals(deviceId(DEV1))) {
+                switch (portNumber.toString()) {
+                    case "1":
+                        return (Port) D1P1;
+                    case "2":
+                        return (Port) D1P2;
+                    case "3":
+                        return (Port) D1P3;
+                    default:
+                        return null;
+                }
+            }
+            if (deviceId.equals(deviceId(DEV2))) {
+                switch (portNumber.toString()) {
+                    case "1":
+                        return (Port) D2P1;
+                    case "2":
+                        return (Port) D2P2;
+                    default:
+                        return null;
+                }
+            }
+            if (deviceId.equals(deviceId(DEV3))) {
+                switch (portNumber.toString()) {
+                    case "1":
+                        return (Port) D3P1;
+                    case "2":
+                        return (Port) D3P2;
+                    case "3":
+                        return (Port) D3P3;
+                    default:
+                        return null;
+                }
+            }
+            return null;
+        }
+    }
+
+    @Before
+    public void setUp() {
+        sut =  new OpticalOduIntentCompiler();
+        coreService = createMock(CoreService.class);
+        expect(coreService.registerApplication("org.onosproject.net.intent"))
+                .andReturn(appId);
+        sut.coreService = coreService;
+        sut.deviceService = new MockDeviceService();
+        sut.resourceService = new MockResourceService();
+        sut.topologyService = new MockTopologyService();
+
+        Intent.bindIdGenerator(idGenerator);
+
+        intentExtensionService = createMock(IntentExtensionService.class);
+        intentExtensionService.registerCompiler(OpticalOduIntent.class, sut);
+        intentExtensionService.unregisterCompiler(OpticalOduIntent.class);
+        sut.intentManager = intentExtensionService;
+
+        replay(coreService, intentExtensionService);
+    }
+
+    @After
+    public void tearDown() {
+        Intent.unbindIdGenerator(idGenerator);
+    }
+
+    /**
+     * Tests compile of OpticalOduIntent with allocation of TributarySlots.
+     * Compile two ODUCLT ports (with CLT_1GBE), over OTU ports (with OTU2):
+     *   - only one TributarySlot is used
+     */
+    @Test
+    public void test1GbeMultiplexOverOdu2() {
+
+        intent = OpticalOduIntent.builder()
+                .appId(APP_ID)
+                .key(KEY1)
+                .src(d1p1)
+                .dst(d3p2)
+                .signalType(D1P1.signalType())
+                .bidirectional(false)
+                .build();
+
+        sut.activate();
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+
+        // 1st Device
+        FlowRule rule1 = rules.stream()
+                .filter(x -> x.deviceId().equals(device1.id()))
+                .findFirst()
+                .get();
+        // validate SRC selector
+        TrafficSelector.Builder selectorBuilder1 = DefaultTrafficSelector.builder();
+        selectorBuilder1.matchInPort(d1p1.port());
+        selectorBuilder1.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
+        assertThat(rule1.selector(), is(selectorBuilder1.build()));
+
+        // validate SRC treatment  (with OduSignalId, where 1 TributarySlot is used)
+        TrafficTreatment.Builder treatmentBuilder1 = DefaultTrafficTreatment.builder();
+        Set<TributarySlot> slots = new HashSet<>();
+        slots.add(TributarySlot.of(1));
+        OduSignalId oduSignalId = OduSignalUtils.buildOduSignalId(OduSignalType.ODU2, slots);
+        treatmentBuilder1.add(Instructions.modL1OduSignalId(oduSignalId));
+        treatmentBuilder1.setOutput(d1p2.port());
+        assertThat(rule1.treatment(), is(treatmentBuilder1.build()));
+
+        // 2nd Device
+        FlowRule rule2 = rules.stream()
+                .filter(x -> x.deviceId().equals(device2.id()))
+                .findFirst()
+                .get();
+        // validate SRC selector
+        TrafficSelector.Builder selectorBuilder2 = DefaultTrafficSelector.builder();
+        selectorBuilder2.matchInPort(d2p1.port());
+        selectorBuilder2.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
+        selectorBuilder2.add(Criteria.matchOduSignalId(oduSignalId));
+        assertThat(rule2.selector(), is(selectorBuilder2.build()));
+
+        // validate SRC treatment  (with OduSignalId, where 1 TributarySlot is used)
+        TrafficTreatment.Builder treatmentBuilder2 = DefaultTrafficTreatment.builder();
+        treatmentBuilder2.add(Instructions.modL1OduSignalId(oduSignalId));
+        treatmentBuilder2.setOutput(d2p2.port());
+        assertThat(rule2.treatment(), is(treatmentBuilder2.build()));
+
+
+        // 3rd Device
+        FlowRule rule3 = rules.stream()
+                .filter(x -> x.deviceId().equals(device3.id()))
+                .findFirst()
+                .get();
+        // validate DST selector (with OduSignalId, where the same TributarySlot is used)
+        TrafficSelector.Builder selectorBuilder3 = DefaultTrafficSelector.builder();
+        selectorBuilder3.matchInPort(d3p1.port());
+        selectorBuilder3.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
+        selectorBuilder3.add(Criteria.matchOduSignalId(oduSignalId));
+        assertThat(rule3.selector(), is(selectorBuilder3.build()));
+
+        // validate DST treatment
+        assertThat(rule3.treatment(), is(
+                DefaultTrafficTreatment.builder().setOutput(d3p2.port()).build()
+                ));
+
+        rules.forEach(rule -> assertEquals("FlowRule priority is incorrect",
+                intent.priority(), rule.priority()));
+
+        sut.deactivate();
+    }
+
+    /**
+     * Tests compile of OpticalOduIntent with allocation of TributarySlots.
+     * Compile two ODUCLT ports (with CLT_10GBE), over OTU ports (with OTU2):
+     *   - All TributarySlots are used
+     */
+    @Test
+    public void test10GbeMultiplexOverOdu2() {
+
+        intent = OpticalOduIntent.builder()
+                .appId(APP_ID)
+                .key(KEY1)
+                .src(d1p3)
+                .dst(d3p3)
+                .signalType(D1P3.signalType())
+                .bidirectional(false)
+                .build();
+
+        sut.activate();
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+
+        // 1st Device
+        FlowRule rule1 = rules.stream()
+                .filter(x -> x.deviceId().equals(device1.id()))
+                .findFirst()
+                .get();
+        // validate SRC selector
+        TrafficSelector.Builder selectorBuilder1 = DefaultTrafficSelector.builder();
+        selectorBuilder1.matchInPort(d1p3.port());
+        selectorBuilder1.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
+        assertThat(rule1.selector(), is(selectorBuilder1.build()));
+
+        // validate SRC treatment  (without OduSignalId - all TributarySlots are used)
+        TrafficTreatment.Builder treatmentBuilder1 = DefaultTrafficTreatment.builder();
+        treatmentBuilder1.setOutput(d1p2.port());
+        assertThat(rule1.treatment(), is(treatmentBuilder1.build()));
+
+        // 2nd Device
+        FlowRule rule2 = rules.stream()
+                .filter(x -> x.deviceId().equals(device2.id()))
+                .findFirst()
+                .get();
+        // validate SRC selector
+        TrafficSelector.Builder selectorBuilder2 = DefaultTrafficSelector.builder();
+        selectorBuilder2.matchInPort(d2p1.port());
+        selectorBuilder2.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
+        assertThat(rule2.selector(), is(selectorBuilder2.build()));
+
+        // validate SRC treatment  (without OduSignalId - all TributarySlots are used)
+        TrafficTreatment.Builder treatmentBuilder2 = DefaultTrafficTreatment.builder();
+        treatmentBuilder2.setOutput(d2p2.port());
+        assertThat(rule2.treatment(), is(treatmentBuilder2.build()));
+
+
+        // 3rd Device
+        FlowRule rule3 = rules.stream()
+                .filter(x -> x.deviceId().equals(device3.id()))
+                .findFirst()
+                .get();
+        // validate DST selector (without OduSignalId - all TributarySlots are used)
+        TrafficSelector.Builder selectorBuilder3 = DefaultTrafficSelector.builder();
+        selectorBuilder3.matchInPort(d3p1.port());
+        selectorBuilder3.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
+        assertThat(rule3.selector(), is(selectorBuilder3.build()));
+
+        // validate DST treatment
+        assertThat(rule3.treatment(), is(
+                DefaultTrafficTreatment.builder().setOutput(d3p3.port()).build()
+                ));
+
+        rules.forEach(rule -> assertEquals("FlowRule priority is incorrect",
+                intent.priority(), rule.priority()));
+
+        sut.deactivate();
+    }
+
+}
\ No newline at end of file
