diff --git a/core/store/dist/src/test/java/org/onosproject/store/mastership/impl/DistributedMastershipStoreTest.java b/core/store/dist/src/test/java/org/onosproject/store/mastership/impl/DistributedMastershipStoreTest.java
deleted file mode 100644
index 0b70401..0000000
--- a/core/store/dist/src/test/java/org/onosproject/store/mastership/impl/DistributedMastershipStoreTest.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright 2014-2015 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.store.mastership.impl;
-
-/**
- * Test of the Hazelcast-based distributed MastershipStore implementation.
- */
-public class DistributedMastershipStoreTest {
-/*
-    private static final DeviceId DID1 = DeviceId.deviceId("of:01");
-    private static final DeviceId DID2 = DeviceId.deviceId("of:02");
-    private static final DeviceId DID3 = DeviceId.deviceId("of:03");
-
-    private static final IpAddress IP = IpAddress.valueOf("127.0.0.1");
-
-    private static final NodeId N1 = new NodeId("node1");
-    private static final NodeId N2 = new NodeId("node2");
-
-    private static final ControllerNode CN1 = new DefaultControllerNode(N1, IP);
-    private static final ControllerNode CN2 = new DefaultControllerNode(N2, IP);
-
-    private DistributedMastershipStore dms;
-    private TestDistributedMastershipStore testStore;
-    private KryoSerializer serializationMgr;
-    private StoreManager storeMgr;
-
-    @BeforeClass
-    public static void setUpBeforeClass() throws Exception {
-    }
-
-    @AfterClass
-    public static void tearDownAfterClass() throws Exception {
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        // TODO should find a way to clean Hazelcast instance without shutdown.
-        TestStoreManager testStoreMgr = new TestStoreManager();
-        testStoreMgr.setHazelcastInstance(testStoreMgr.initSingleInstance());
-        storeMgr = testStoreMgr;
-        storeMgr.activate();
-
-        serializationMgr = new KryoSerializer();
-
-        dms = new TestDistributedMastershipStore(storeMgr, serializationMgr);
-        dms.clusterService = new TestClusterService();
-        dms.activate();
-
-        testStore = (TestDistributedMastershipStore) dms;
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        dms.deactivate();
-
-        storeMgr.deactivate();
-    }
-
-    @Test
-    @Ignore("Disabled this test due to intermittent failures seen on Jenkins runs")
-    public void getRole() {
-        assertEquals("wrong role:", NONE, dms.getRole(N1, DID1));
-        testStore.put(DID1, N1, true, false, true);
-        assertEquals("wrong role:", MASTER, dms.getRole(N1, DID1));
-        testStore.put(DID1, N2, false, true, false);
-        assertEquals("wrong role:", STANDBY, dms.getRole(N2, DID1));
-    }
-
-    @Test
-    public void getMaster() {
-        assertTrue("wrong store state:", dms.roleMap.isEmpty());
-
-        testStore.put(DID1, N1, true, false, false);
-        TestTools.assertAfter(100, () -> //wait for up to 100ms
-            assertEquals("wrong master:", N1, dms.getMaster(DID1)));
-        assertNull("wrong master:", dms.getMaster(DID2));
-    }
-
-    @Test
-    public void getDevices() {
-        assertTrue("wrong store state:", dms.roleMap.isEmpty());
-
-        testStore.put(DID1, N1, true, false, false);
-        testStore.put(DID2, N1, true, false, false);
-        testStore.put(DID3, N2, true, false, false);
-        assertEquals("wrong devices",
-                Sets.newHashSet(DID1, DID2), dms.getDevices(N1));
-    }
-
-    @Test
-    public void requestRoleAndTerm() {
-        //CN1 is "local"
-        testStore.setCurrent(CN1);
-
-        //if already MASTER, nothing should happen
-        testStore.put(DID2, N1, true, false, true);
-        assertEquals("wrong role for MASTER:", MASTER, Futures.getUnchecked(dms.requestRole(DID2)));
-
-        //populate maps with DID1, N1 thru NONE case
-        assertEquals("wrong role for NONE:", MASTER, Futures.getUnchecked(dms.requestRole(DID1)));
-        assertTrue("wrong state for store:", !dms.terms.isEmpty());
-        assertEquals("wrong term",
-                MastershipTerm.of(N1, 1), dms.getTermFor(DID1));
-
-        //CN2 now local. DID2 has N1 as MASTER so N2 is STANDBY
-        testStore.setCurrent(CN2);
-        assertEquals("wrong role for STANDBY:", STANDBY, Futures.getUnchecked(dms.requestRole(DID2)));
-        assertEquals("wrong number of entries:", 2, dms.terms.size());
-
-        //change term and requestRole() again; should persist
-        testStore.increment(DID2);
-        assertEquals("wrong role for STANDBY:", STANDBY, Futures.getUnchecked(dms.requestRole(DID2)));
-        assertEquals("wrong term", MastershipTerm.of(N1, 1), dms.getTermFor(DID2));
-    }
-
-    @Test
-    public void setMaster() {
-        //populate maps with DID1, N1 as MASTER thru NONE case
-        testStore.setCurrent(CN1);
-        assertEquals("wrong role for NONE:", MASTER, Futures.getUnchecked(dms.requestRole(DID1)));
-        assertNull("wrong event:", Futures.getUnchecked(dms.setMaster(N1, DID1)));
-
-        //switch over to N2
-        assertEquals("wrong event:", Type.MASTER_CHANGED, Futures.getUnchecked(dms.setMaster(N2, DID1)).type());
-        System.out.println(dms.getTermFor(DID1).master() + ":" + dms.getTermFor(DID1).termNumber());
-        assertEquals("wrong term", MastershipTerm.of(N2, 2), dms.getTermFor(DID1));
-
-        //orphan switch - should be rare case
-        assertEquals("wrong event:", Type.MASTER_CHANGED, Futures.getUnchecked(dms.setMaster(N2, DID2)).type());
-        assertEquals("wrong term", MastershipTerm.of(N2, 1), dms.getTermFor(DID2));
-        //disconnect and reconnect - sign of failing re-election or single-instance channel
-        dms.roleMap.clear();
-        dms.setMaster(N2, DID2);
-        assertEquals("wrong term", MastershipTerm.of(N2, 2), dms.getTermFor(DID2));
-    }
-
-    @Test
-    public void relinquishRole() {
-        //populate maps with DID1, N1 as MASTER thru NONE case
-        testStore.setCurrent(CN1);
-        assertEquals("wrong role for NONE:", MASTER, Futures.getUnchecked(dms.requestRole(DID1)));
-        //no backup, no new MASTER/event
-        assertNull("wrong event:", Futures.getUnchecked(dms.relinquishRole(N1, DID1)));
-
-        dms.requestRole(DID1);
-
-        //add backup CN2, get it elected MASTER by relinquishing
-        testStore.setCurrent(CN2);
-        assertEquals("wrong role for NONE:", STANDBY, Futures.getUnchecked(dms.requestRole(DID1)));
-        assertEquals("wrong event:", Type.MASTER_CHANGED, Futures.getUnchecked(dms.relinquishRole(N1, DID1)).type());
-        assertEquals("wrong master", N2, dms.getMaster(DID1));
-
-        //all nodes "give up" on device, which goes back to NONE.
-        assertNull("wrong event:", Futures.getUnchecked(dms.relinquishRole(N2, DID1)));
-        assertEquals("wrong role for node:", NONE, dms.getRole(N2, DID1));
-
-        assertEquals("wrong number of retired nodes", 2,
-                dms.roleMap.get(DID1).nodesOfRole(NONE).size());
-
-        //bring nodes back
-        assertEquals("wrong role for NONE:", MASTER, Futures.getUnchecked(dms.requestRole(DID1)));
-        testStore.setCurrent(CN1);
-        assertEquals("wrong role for NONE:", STANDBY, Futures.getUnchecked(dms.requestRole(DID1)));
-        assertEquals("wrong number of backup nodes", 1,
-                dms.roleMap.get(DID1).nodesOfRole(STANDBY).size());
-
-        //If STANDBY, should drop to NONE
-        assertEquals("wrong event:", Type.BACKUPS_CHANGED, Futures.getUnchecked(dms.relinquishRole(N1, DID1)).type());
-        assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID1));
-
-        //NONE - nothing happens
-        assertEquals("wrong event:", Type.BACKUPS_CHANGED, Futures.getUnchecked(dms.relinquishRole(N1, DID2)).type());
-        assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID2));
-
-    }
-
-    @Ignore("Ignore until Delegate spec. is clear.")
-    @Test
-    public void testEvents() throws InterruptedException {
-        //shamelessly copy other distributed store tests
-        final CountDownLatch addLatch = new CountDownLatch(1);
-
-        MastershipStoreDelegate checkAdd = new MastershipStoreDelegate() {
-            @Override
-            public void notify(MastershipEvent event) {
-                assertEquals("wrong event:", Type.MASTER_CHANGED, event.type());
-                assertEquals("wrong subject", DID1, event.subject());
-                assertEquals("wrong subject", N1, event.roleInfo().master());
-                addLatch.countDown();
-            }
-        };
-
-        dms.setDelegate(checkAdd);
-        dms.setMaster(N1, DID1);
-        //this will fail until we do something about single-instance-ness
-        assertTrue("Add event fired", addLatch.await(1, TimeUnit.SECONDS));
-    }
-
-    private class TestDistributedMastershipStore extends
-            DistributedMastershipStore {
-        public TestDistributedMastershipStore(StoreService storeService,
-                KryoSerializer kryoSerialization) {
-            this.storeService = storeService;
-            this.serializer = kryoSerialization;
-        }
-
-        //helper to populate master/backup structures
-        public void put(DeviceId dev, NodeId node,
-                boolean master, boolean backup, boolean term) {
-            RoleValue rv = dms.roleMap.get(dev);
-            if (rv == null) {
-                rv = new RoleValue();
-            }
-
-            if (master) {
-                rv.add(MASTER, node);
-                rv.reassign(node, STANDBY, NONE);
-            }
-            if (backup) {
-                rv.add(STANDBY, node);
-                rv.remove(MASTER, node);
-                rv.remove(NONE, node);
-            }
-            if (term) {
-                dms.terms.put(dev, 0);
-            }
-            dms.roleMap.put(dev, rv);
-        }
-
-        //a dumb utility function.
-        public void dump() {
-            for (Map.Entry<DeviceId, RoleValue> el : dms.roleMap.entrySet()) {
-                System.out.println("DID: " + el.getKey());
-                for (MastershipRole role : MastershipRole.values()) {
-                    System.out.println("\t" + role.toString() + ":");
-                    for (NodeId n : el.getValue().nodesOfRole(role)) {
-                        System.out.println("\t\t" + n);
-                    }
-                }
-            }
-        }
-
-        //increment term for a device
-        public void increment(DeviceId dev) {
-            Integer t = dms.terms.get(dev);
-            if (t != null) {
-                dms.terms.put(dev, ++t);
-            }
-        }
-
-        //sets the "local" node
-        public void setCurrent(ControllerNode node) {
-            ((TestClusterService) clusterService).current = node;
-        }
-    }
-
-    private class TestClusterService extends ClusterServiceAdapter {
-
-        protected ControllerNode current;
-
-        @Override
-        public ControllerNode getLocalNode() {
-            return current;
-        }
-
-        @Override
-        public Set<ControllerNode> getNodes() {
-            return Sets.newHashSet(CN1, CN2);
-        }
-
-    }
-*/
-}
diff --git a/core/store/dist/src/test/java/org/onosproject/store/resource/impl/HazelcastLinkResourceStoreTest.java b/core/store/dist/src/test/java/org/onosproject/store/resource/impl/HazelcastLinkResourceStoreTest.java
deleted file mode 100644
index a5f2fac..0000000
--- a/core/store/dist/src/test/java/org/onosproject/store/resource/impl/HazelcastLinkResourceStoreTest.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright 2014-2015 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.store.resource.impl;
-
-/**
- * Test of the simple LinkResourceStore implementation.
- */
-public class HazelcastLinkResourceStoreTest {
-/*
-    private LinkResourceStore store;
-    private HazelcastLinkResourceStore storeImpl;
-    private Link link1;
-    private Link link2;
-    private Link link3;
-    private TestStoreManager storeMgr;
-
-    /**
-     * Returns {@link Link} object.
-     *
-     * @param dev1 source device
-     * @param port1 source port
-     * @param dev2 destination device
-     * @param port2 destination port
-     * @return created {@link Link} object
-     * /
-    private Link newLink(String dev1, int port1, String dev2, int port2) {
-        Annotations annotations = DefaultAnnotations.builder()
-                .set(AnnotationKeys.OPTICAL_WAVES, "80")
-                .set(AnnotationKeys.BANDWIDTH, "1000")
-                .build();
-        return new DefaultLink(
-                new ProviderId("of", "foo"),
-                new ConnectPoint(deviceId(dev1), portNumber(port1)),
-                new ConnectPoint(deviceId(dev2), portNumber(port2)),
-                DIRECT, annotations);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-
-        TestStoreManager testStoreMgr = new TestStoreManager();
-        testStoreMgr.setHazelcastInstance(testStoreMgr.initSingleInstance());
-        storeMgr = testStoreMgr;
-        storeMgr.activate();
-
-
-        storeImpl = new TestHazelcastLinkResourceStore(storeMgr);
-        storeImpl.activate();
-        store = storeImpl;
-
-        link1 = newLink("of:1", 1, "of:2", 2);
-        link2 = newLink("of:2", 1, "of:3", 2);
-        link3 = newLink("of:3", 1, "of:4", 2);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        storeImpl.deactivate();
-
-        storeMgr.deactivate();
-    }
-
-    @Test
-    public void testConstructorAndActivate() {
-        final Iterable<LinkResourceAllocations> allAllocations = store.getAllocations();
-        assertNotNull(allAllocations);
-        assertFalse(allAllocations.iterator().hasNext());
-
-        final Iterable<LinkResourceAllocations> linkAllocations =
-                store.getAllocations(link1);
-        assertNotNull(linkAllocations);
-        assertFalse(linkAllocations.iterator().hasNext());
-
-        final Set<ResourceAllocation> res = store.getFreeResources(link2);
-        assertNotNull(res);
-    }
-
-    private BandwidthResourceAllocation getBandwidthObj(Set<ResourceAllocation> resources) {
-        for (ResourceAllocation res : resources) {
-            if (res.type() == ResourceType.BANDWIDTH) {
-                return ((BandwidthResourceAllocation) res);
-            }
-        }
-        return null;
-    }
-
-    private Set<LambdaResourceAllocation> getLambdaObjs(Set<ResourceAllocation> resources) {
-        Set<LambdaResourceAllocation> lambdaResources = new HashSet<>();
-        for (ResourceAllocation res : resources) {
-            if (res.type() == ResourceType.LAMBDA) {
-                lambdaResources.add((LambdaResourceAllocation) res);
-            }
-        }
-        return lambdaResources;
-    }
-
-    @Test
-    public void testInitialBandwidth() {
-        final Set<ResourceAllocation> freeRes = store.getFreeResources(link1);
-        assertNotNull(freeRes);
-
-        final BandwidthResourceAllocation alloc = getBandwidthObj(freeRes);
-        assertNotNull(alloc);
-
-        assertEquals(new BandwidthResource(Bandwidth.mbps(1000.0)), alloc.bandwidth());
-    }
-
-    @Test
-    public void testInitialLambdas() {
-        final Set<ResourceAllocation> freeRes = store.getFreeResources(link3);
-        assertNotNull(freeRes);
-
-        final Set<LambdaResourceAllocation> res = getLambdaObjs(freeRes);
-        assertNotNull(res);
-        assertEquals(80, res.size());
-    }
-
-    public static final class TestHazelcastLinkResourceStore
-            extends HazelcastLinkResourceStore {
-
-        public TestHazelcastLinkResourceStore(StoreService storeMgr) {
-            super.storeService = storeMgr;
-        }
-
-    }
-
-    @Test
-    public void testSuccessfulBandwidthAllocation() {
-        final Link link = newLink("of:1", 1, "of:2", 2);
-
-        final LinkResourceRequest request =
-                DefaultLinkResourceRequest.builder(IntentId.valueOf(1),
-                        ImmutableSet.of(link))
-                .build();
-        final ResourceAllocation allocation =
-                new BandwidthResourceAllocation(new BandwidthResource(Bandwidth.mbps(900.0)));
-        final Set<ResourceAllocation> allocationSet = ImmutableSet.of(allocation);
-
-        final LinkResourceAllocations allocations =
-                new DefaultLinkResourceAllocations(request, ImmutableMap.of(link, allocationSet));
-
-        store.allocateResources(allocations);
-    }
-
-    @Test
-    public void testUnsuccessfulBandwidthAllocation() {
-        final Link link = newLink("of:1", 1, "of:2", 2);
-
-        final LinkResourceRequest request =
-                DefaultLinkResourceRequest.builder(IntentId.valueOf(1),
-                        ImmutableSet.of(link))
-                        .build();
-        final ResourceAllocation allocation =
-                new BandwidthResourceAllocation(new BandwidthResource(Bandwidth.mbps(9000.0)));
-        final Set<ResourceAllocation> allocationSet = ImmutableSet.of(allocation);
-
-        final LinkResourceAllocations allocations =
-                new DefaultLinkResourceAllocations(request, ImmutableMap.of(link, allocationSet));
-
-        boolean gotException = false;
-        try {
-            store.allocateResources(allocations);
-        } catch (ResourceAllocationException rae) {
-            assertEquals(true, rae.getMessage().contains("Unable to allocate bandwidth for link"));
-            gotException = true;
-        }
-        assertEquals(true, gotException);
-    }
-
-    @Test
-    public void testSuccessfulLambdaAllocation() {
-        final Link link = newLink("of:1", 1, "of:2", 2);
-
-        final LinkResourceRequest request =
-                DefaultLinkResourceRequest.builder(IntentId.valueOf(1),
-                        ImmutableSet.of(link))
-                        .build();
-        final ResourceAllocation allocation =
-                new BandwidthResourceAllocation(new BandwidthResource(Bandwidth.mbps(900.0)));
-        final Set<ResourceAllocation> allocationSet = ImmutableSet.of(allocation);
-
-        final LinkResourceAllocations allocations =
-                new DefaultLinkResourceAllocations(request, ImmutableMap.of(link, allocationSet));
-
-        store.allocateResources(allocations);
-    }
-
-    @Test
-    public void testUnsuccessfulLambdaAllocation() {
-        final Link link = newLink("of:1", 1, "of:2", 2);
-
-        final LinkResourceRequest request =
-                DefaultLinkResourceRequest.builder(IntentId.valueOf(1),
-                        ImmutableSet.of(link))
-                        .build();
-        final ResourceAllocation allocation =
-                new LambdaResourceAllocation(LambdaResource.valueOf(33));
-        final Set<ResourceAllocation> allocationSet = ImmutableSet.of(allocation);
-
-        final LinkResourceAllocations allocations =
-                new DefaultLinkResourceAllocations(request, ImmutableMap.of(link, allocationSet));
-        store.allocateResources(allocations);
-
-        boolean gotException = false;
-        try {
-            store.allocateResources(allocations);
-        } catch (ResourceAllocationException rae) {
-            assertEquals(true, rae.getMessage().contains("Unable to allocate lambda for link"));
-            gotException = true;
-        }
-        assertEquals(true, gotException);
-    }
-    */
-}
