diff --git a/core/net/src/test/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManagerTest.java b/core/net/src/test/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManagerTest.java
new file mode 100644
index 0000000..5360e10
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManagerTest.java
@@ -0,0 +1,416 @@
+/*
+ * 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.flowobjective.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.packet.ChassisId;
+import org.onosproject.mastership.MastershipEvent;
+import org.onosproject.mastership.MastershipListener;
+import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.behaviour.DefaultNextGroup;
+import org.onosproject.net.behaviour.NextGroup;
+import org.onosproject.net.behaviour.PipelinerAdapter;
+import org.onosproject.net.behaviour.PipelinerContext;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.driver.AbstractDriverLoader;
+import org.onosproject.net.driver.Behaviour;
+import org.onosproject.net.driver.DefaultDriverData;
+import org.onosproject.net.driver.DefaultDriverHandler;
+import org.onosproject.net.driver.DefaultDriverProviderService;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverData;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.DefaultNextObjective;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveStoreDelegate;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.ObjectiveEvent;
+import org.onosproject.net.intent.TestTools;
+import org.onosproject.openflow.DriverAdapter;
+import org.onosproject.openflow.DriverServiceAdapter;
+
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.TestUtils.TestUtilsException;
+
+/**
+ * Tests for the flow objective manager.
+ */
+public class FlowObjectiveManagerTest {
+
+    private static final int RETRY_MS = 250;
+    private FlowObjectiveManager manager;
+    DeviceId id1 = NetTestTools.did("d1");
+    DefaultDevice d1 = new DefaultDevice(NetTestTools.PID, id1, Device.Type.SWITCH,
+                                         "test", "1.0", "1.0",
+                                         "abacab", new ChassisId("c"),
+                                         DefaultAnnotations.EMPTY);
+
+    DeviceId id2 = NetTestTools.did("d2");
+    DefaultDevice d2 = new DefaultDevice(NetTestTools.PID, id2, Device.Type.SWITCH,
+                                         "test", "1.0", "1.0",
+                                         "abacab", new ChassisId("c"),
+                                         DefaultAnnotations.EMPTY);
+
+    List<String> filteringObjectives;
+    List<String> forwardingObjectives;
+    List<String> nextObjectives;
+
+    private class TestDeviceService extends DeviceServiceAdapter {
+
+        List<Device> deviceList;
+
+        TestDeviceService() {
+            deviceList = new ArrayList<>();
+
+            deviceList.add(d1);
+        }
+
+        @Override
+        public Iterable<Device> getDevices() {
+            return deviceList;
+        }
+
+        @Override
+        public boolean isAvailable(DeviceId deviceId) {
+            return true;
+        }
+    }
+
+    private class TestFlowObjectiveStore extends FlowObjectiveStoreAdapter {
+        @Override
+        public NextGroup getNextGroup(Integer nextId) {
+            if (nextId != 4) {
+                byte[] data = new byte[1];
+                data[0] = 5;
+                return new DefaultNextGroup(data);
+            } else {
+                return null;
+            }
+        }
+
+    }
+
+    private class TestDriversLoader extends AbstractDriverLoader implements DefaultDriverProviderService {
+        public TestDriversLoader() {
+            super("/onos-drivers.xml");
+        }
+    }
+
+    private class TestDriver extends DriverAdapter {
+
+        @Override
+        public boolean hasBehaviour(Class<? extends Behaviour> behaviourClass) {
+            return true;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public <T extends Behaviour> T createBehaviour(DriverData data, Class<T> behaviourClass) {
+            return (T) new TestPipeliner();
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public <T extends Behaviour> T createBehaviour(DriverHandler handler, Class<T> behaviourClass) {
+            return (T) new TestPipeliner();
+        }
+
+    }
+
+    private class TestPipeliner extends PipelinerAdapter {
+        DeviceId deviceId;
+
+        @Override
+        public void init(DeviceId deviceId, PipelinerContext context) {
+            this.deviceId = deviceId;
+        }
+
+        @Override
+        public void filter(FilteringObjective filterObjective) {
+            filteringObjectives.add(deviceId.toString());
+        }
+
+        @Override
+        public void forward(ForwardingObjective forwardObjective) {
+            forwardingObjectives.add(deviceId.toString());
+        }
+
+        @Override
+        public void next(NextObjective nextObjective) {
+            nextObjectives.add(deviceId.toString());
+        }
+    }
+
+    private class TestDriverService extends DriverServiceAdapter {
+        @Override
+        public DriverHandler createHandler(DeviceId deviceId, String... credentials) {
+            Driver driver = new TestDriver();
+            return new DefaultDriverHandler(new DefaultDriverData(driver, id1));
+        }
+    }
+
+    @Before
+    public void initializeTest() {
+        manager = new FlowObjectiveManager();
+        manager.flowObjectiveStore = new TestFlowObjectiveStore();
+        manager.mastershipService = new MastershipServiceAdapter();
+        manager.deviceService = new TestDeviceService();
+        manager.defaultDriverService = new TestDriversLoader();
+        manager.driverService = new TestDriverService();
+
+        filteringObjectives = new ArrayList<>();
+        forwardingObjectives = new ArrayList<>();
+        nextObjectives = new ArrayList<>();
+        manager.activate();
+    }
+
+    @After
+    public void tearDownTest() {
+        manager.deactivate();
+        manager = null;
+        filteringObjectives.clear();
+        forwardingObjectives.clear();
+        nextObjectives.clear();
+    }
+
+    /**
+     * Tests adding a forwarding objective.
+     */
+    @Test
+    public void forwardingObjective() {
+        TrafficSelector selector = DefaultTrafficSelector.emptySelector();
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+        ForwardingObjective forward =
+                DefaultForwardingObjective.builder()
+                        .fromApp(NetTestTools.APP_ID)
+                        .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                        .withSelector(selector)
+                        .withTreatment(treatment)
+                        .makePermanent()
+                        .add();
+
+        manager.forward(id1, forward);
+
+        TestTools.assertAfter(RETRY_MS, () ->
+            assertThat(forwardingObjectives, hasSize(1)));
+
+        assertThat(forwardingObjectives, hasItem("of:d1"));
+        assertThat(filteringObjectives, hasSize(0));
+        assertThat(nextObjectives, hasSize(0));
+    }
+
+    /**
+     * Tests adding a filtering objective.
+     */
+    @Test
+    public void filteringObjective() {
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+        FilteringObjective filter =
+                DefaultFilteringObjective.builder()
+                        .fromApp(NetTestTools.APP_ID)
+                        .withMeta(treatment)
+                        .makePermanent()
+                        .deny()
+                        .addCondition(Criteria.matchEthType(12))
+                        .add();
+
+        manager.activate();
+        manager.filter(id1, filter);
+
+        TestTools.assertAfter(RETRY_MS, () ->
+                assertThat(filteringObjectives, hasSize(1)));
+
+        assertThat(forwardingObjectives, hasSize(0));
+        assertThat(filteringObjectives, hasItem("of:d1"));
+        assertThat(nextObjectives, hasSize(0));
+    }
+
+    /**
+     * Tests adding a next objective.
+     */
+    @Test
+    public void nextObjective() {
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+        NextObjective next =
+                DefaultNextObjective.builder()
+                        .withId(manager.allocateNextId())
+                        .addTreatment(treatment)
+                        .withType(NextObjective.Type.BROADCAST)
+                        .fromApp(NetTestTools.APP_ID)
+                        .makePermanent()
+                        .add();
+
+        manager.next(id1, next);
+
+        TestTools.assertAfter(RETRY_MS, () ->
+                assertThat(nextObjectives, hasSize(1)));
+
+        assertThat(forwardingObjectives, hasSize(0));
+        assertThat(filteringObjectives, hasSize(0));
+        assertThat(nextObjectives, hasItem("of:d1"));
+    }
+
+    /**
+     * Tests adding a pending forwarding objective.
+     *
+     * @throws TestUtilsException if lookup of a field fails
+     */
+    @Test
+    public void pendingForwardingObjective() throws TestUtilsException {
+        TrafficSelector selector = DefaultTrafficSelector.emptySelector();
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+
+        ForwardingObjective forward4 =
+                DefaultForwardingObjective.builder()
+                        .fromApp(NetTestTools.APP_ID)
+                        .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                        .withSelector(selector)
+                        .withTreatment(treatment)
+                        .makePermanent()
+                        .nextStep(4)
+                        .add();
+        ForwardingObjective forward5 =
+                DefaultForwardingObjective.builder()
+                        .fromApp(NetTestTools.APP_ID)
+                        .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                        .withSelector(selector)
+                        .withTreatment(treatment)
+                        .makePermanent()
+                        .nextStep(5)
+                        .add();
+
+        //  multiple pending forwards should be combined
+        manager.forward(id1, forward4);
+        manager.forward(id1, forward4);
+        manager.forward(id1, forward5);
+
+
+        //  1 should be complete, 1 pending
+        TestTools.assertAfter(RETRY_MS, () ->
+                assertThat(forwardingObjectives, hasSize(1)));
+
+        assertThat(forwardingObjectives, hasItem("of:d1"));
+        assertThat(filteringObjectives, hasSize(0));
+        assertThat(nextObjectives, hasSize(0));
+
+        // Now send events to trigger the objective still in the queue
+        ObjectiveEvent event1 = new ObjectiveEvent(ObjectiveEvent.Type.ADD, 4);
+        FlowObjectiveStoreDelegate delegate = TestUtils.getField(manager, "delegate");
+        delegate.notify(event1);
+
+        // all should be processed now
+        TestTools.assertAfter(RETRY_MS, () ->
+                assertThat(forwardingObjectives, hasSize(2)));
+        assertThat(forwardingObjectives, hasItem("of:d1"));
+        assertThat(filteringObjectives, hasSize(0));
+        assertThat(nextObjectives, hasSize(0));
+    }
+
+    /**
+     * Tests receipt of a device up event.
+     *
+     * @throws TestUtilsException if lookup of a field fails
+     */
+    @Test
+    public void deviceUpEvent() throws TestUtilsException {
+        TrafficSelector selector = DefaultTrafficSelector.emptySelector();
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+
+        DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, d2);
+        DeviceListener listener = TestUtils.getField(manager, "deviceListener");
+        assertThat(listener, notNullValue());
+
+        listener.event(event);
+
+        ForwardingObjective forward =
+                DefaultForwardingObjective.builder()
+                        .fromApp(NetTestTools.APP_ID)
+                        .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                        .withSelector(selector)
+                        .withTreatment(treatment)
+                        .makePermanent()
+                        .add();
+        manager.forward(id2, forward);
+
+        // new device should have an objective now
+        TestTools.assertAfter(RETRY_MS, () ->
+                assertThat(forwardingObjectives, hasSize(1)));
+
+        assertThat(forwardingObjectives, hasItem("of:d2"));
+        assertThat(filteringObjectives, hasSize(0));
+        assertThat(nextObjectives, hasSize(0));
+    }
+
+    /**
+     * Tests recepit of a device mastership event.
+     *
+     * @throws TestUtilsException if lookup of a field fails
+     */
+    @Test
+    public void deviceMastershipEvent() throws TestUtilsException {
+        TrafficSelector selector = DefaultTrafficSelector.emptySelector();
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+
+        MastershipEvent event =
+                new MastershipEvent(MastershipEvent.Type.MASTER_CHANGED, id2, null);
+        MastershipListener listener = TestUtils.getField(manager, "mastershipListener");
+        assertThat(listener, notNullValue());
+
+        listener.event(event);
+
+        ForwardingObjective forward =
+                DefaultForwardingObjective.builder()
+                        .fromApp(NetTestTools.APP_ID)
+                        .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                        .withSelector(selector)
+                        .withTreatment(treatment)
+                        .makePermanent()
+                        .add();
+        manager.forward(id2, forward);
+
+        // new device should have an objective now
+        TestTools.assertAfter(RETRY_MS, () ->
+                assertThat(forwardingObjectives, hasSize(1)));
+
+        assertThat(forwardingObjectives, hasItem("of:d2"));
+        assertThat(filteringObjectives, hasSize(0));
+        assertThat(nextObjectives, hasSize(0));
+    }
+}
