ONOS-6082
Change-Id: I245168114e97a9dac8f7f9e8ded2f51b858f423d
(cherry picked from commit 12c08c07dbb6ca9f54a8be7f96ac2bd6d80c709d)
diff --git a/core/store/dist/src/test/java/org/onosproject/store/flow/impl/DistributedFlowRuleStoreTest.java b/core/store/dist/src/test/java/org/onosproject/store/flow/impl/DistributedFlowRuleStoreTest.java
new file mode 100644
index 0000000..28755dd
--- /dev/null
+++ b/core/store/dist/src/test/java/org/onosproject/store/flow/impl/DistributedFlowRuleStoreTest.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.store.flow.impl;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.onosproject.cfg.ComponentConfigAdapter;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ControllerNode;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.flow.FlowRuleOperation;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleBatchEntry;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.FlowRuleBatchOperation;
+import org.onosproject.net.intent.IntentTestsMocks;
+import org.onosproject.store.cluster.messaging.ClusterCommunicationServiceAdapter;
+import org.onosproject.store.persistence.PersistenceServiceAdapter;
+import org.onosproject.store.service.TestStorageService;
+
+import org.onlab.packet.Ip4Address;
+import java.util.Iterator;
+import org.osgi.service.component.ComponentContext;
+
+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.emptyIterable;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertEquals;
+import static org.onosproject.net.NetTestTools.APP_ID;
+import static org.onosproject.net.NetTestTools.did;
+
+/**
+ * Test class for DistributedFlowRuleStore.
+ */
+public class DistributedFlowRuleStoreTest {
+
+ DistributedFlowRuleStore flowStoreImpl;
+ ComponentContext context = null;
+ private ClusterService mockClusterService;
+ private ControllerNode mockControllerNode;
+
+ private NodeId nodeId;
+
+ private static final IntentTestsMocks.MockSelector SELECTOR =
+ new IntentTestsMocks.MockSelector();
+ private static final IntentTestsMocks.MockTreatment TREATMENT =
+ new IntentTestsMocks.MockTreatment();
+ DeviceId deviceId = did("device1");
+ FlowRule flowRule =
+ DefaultFlowRule.builder()
+ .forDevice(deviceId)
+ .withSelector(SELECTOR)
+ .withTreatment(TREATMENT)
+ .withPriority(22)
+ .makeTemporary(44)
+ .fromApp(APP_ID)
+ .build();
+ FlowRule flowRule1 =
+ DefaultFlowRule.builder()
+ .forDevice(deviceId)
+ .withSelector(SELECTOR)
+ .withTreatment(TREATMENT)
+ .withPriority(33)
+ .makeTemporary(44)
+ .fromApp(APP_ID)
+ .build();
+
+ static class MasterOfAll extends MastershipServiceAdapter {
+ @Override
+ public MastershipRole getLocalRole(DeviceId deviceId) {
+ return MastershipRole.MASTER;
+ }
+
+ @Override
+ public NodeId getMasterFor(DeviceId deviceId) {
+ return new NodeId("1");
+ }
+ }
+
+
+ private static class MockControllerNode implements ControllerNode {
+ final NodeId id;
+
+ public MockControllerNode(NodeId id) {
+ this.id = id;
+ }
+
+ @Override
+ public NodeId id() {
+ return this.id;
+ }
+
+ @Override
+ public Ip4Address ip() {
+ return Ip4Address.valueOf("127.0.0.1");
+ }
+
+ @Override
+ public int tcpPort() {
+ return 0;
+ }
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ flowStoreImpl = new DistributedFlowRuleStore();
+ flowStoreImpl.storageService = new TestStorageService();
+ flowStoreImpl.replicaInfoManager = new ReplicaInfoManager();
+ mockClusterService = createMock(ClusterService.class);
+ flowStoreImpl.clusterService = mockClusterService;
+ nodeId = new NodeId("1");
+ mockControllerNode = new MockControllerNode(nodeId);
+
+ expect(mockClusterService.getLocalNode())
+ .andReturn(mockControllerNode).anyTimes();
+ replay(mockClusterService);
+
+ flowStoreImpl.clusterCommunicator = new ClusterCommunicationServiceAdapter();
+ flowStoreImpl.mastershipService = new MasterOfAll();
+ flowStoreImpl.deviceService = new DeviceServiceAdapter();
+ flowStoreImpl.coreService = new CoreServiceAdapter();
+ flowStoreImpl.configService = new ComponentConfigAdapter();
+ flowStoreImpl.persistenceService = new PersistenceServiceAdapter();
+ flowStoreImpl.activate(context);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ flowStoreImpl.deactivate(context);
+ }
+
+ /**
+ * Tests the initial state of the store.
+ */
+ @Test
+ public void testEmptyStore() {
+ assertThat(flowStoreImpl.getFlowRuleCount(), is(0));
+ assertThat(flowStoreImpl.getFlowEntries(deviceId), is(emptyIterable()));
+ }
+
+ /**
+ * Tests initial state of flowrule.
+ */
+ @Test
+ public void testStoreBatch() {
+ FlowRuleOperation op = new FlowRuleOperation(flowRule, FlowRuleOperation.Type.ADD);
+ Multimap<DeviceId, FlowRuleBatchEntry> perDeviceBatches = ArrayListMultimap.create();
+ perDeviceBatches.put(op.rule().deviceId(),
+ new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.ADD, op.rule()));
+ FlowRuleBatchOperation b = new FlowRuleBatchOperation(perDeviceBatches.get(deviceId),
+ deviceId, 1);
+ flowStoreImpl.storeBatch(b);
+ FlowEntry flowEntry1 = flowStoreImpl.getFlowEntry(flowRule);
+ assertEquals("PENDING_ADD", flowEntry1.state().toString());
+ }
+
+ /**
+ * Tests adding a flowrule.
+ */
+ @Test
+ public void testAddFlow() {
+ FlowEntry flowEntry = new DefaultFlowEntry(flowRule);
+ FlowRuleOperation op = new FlowRuleOperation(flowRule, FlowRuleOperation.Type.ADD);
+ Multimap<DeviceId, FlowRuleBatchEntry> perDeviceBatches = ArrayListMultimap.create();
+ perDeviceBatches.put(op.rule().deviceId(),
+ new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.ADD, op.rule()));
+ FlowRuleBatchOperation b = new FlowRuleBatchOperation(perDeviceBatches.get(deviceId),
+ deviceId, 1);
+ flowStoreImpl.storeBatch(b);
+ FlowEntry flowEntry1 = flowStoreImpl.getFlowEntry(flowRule);
+ assertEquals("PENDING_ADD", flowEntry1.state().toString());
+
+ flowStoreImpl.addOrUpdateFlowRule(flowEntry);
+ Iterable<FlowEntry> flows = flowStoreImpl.getFlowEntries(deviceId);
+ int sum = 0;
+ Iterator it = flows.iterator();
+ while (it.hasNext()) {
+ it.next();
+ sum++;
+ }
+ assertThat(sum, is(1));
+
+ FlowEntry flowEntry2 = flowStoreImpl.getFlowEntry(flowRule);
+ assertEquals("ADDED", flowEntry2.state().toString());
+ assertThat(flowStoreImpl.getTableStatistics(deviceId), notNullValue());
+ }
+
+ /**
+ * Tests flow removal.
+ */
+ @Test
+ public void testRemoveFlow() {
+ Iterable<FlowEntry> flows1 = flowStoreImpl.getFlowEntries(deviceId);
+ for (FlowEntry flow : flows1) {
+ flowStoreImpl.removeFlowRule(flow);
+ }
+
+ Iterable<FlowEntry> flows2 = flowStoreImpl.getFlowEntries(deviceId);
+ int sum = 0;
+ Iterator it = flows2.iterator();
+ while (it.hasNext()) {
+ it.next();
+ sum++;
+ }
+ assertThat(sum, is(0));
+ }
+
+ /**
+ * Tests purge flow for a device.
+ */
+ @Test
+ public void testPurgeFlow() {
+ FlowEntry flowEntry = new DefaultFlowEntry(flowRule);
+ flowStoreImpl.addOrUpdateFlowRule(flowEntry);
+
+ FlowEntry flowEntry1 = new DefaultFlowEntry(flowRule1);
+ flowStoreImpl.addOrUpdateFlowRule(flowEntry1);
+ Iterable<FlowEntry> flows1 = flowStoreImpl.getFlowEntries(deviceId);
+ int sum2 = 0;
+ Iterator it1 = flows1.iterator();
+ while (it1.hasNext()) {
+ it1.next();
+ sum2++;
+ }
+ assertThat(sum2, is(2));
+ flowStoreImpl.purgeFlowRule(deviceId);
+
+ Iterable<FlowEntry> flows3 = flowStoreImpl.getFlowEntries(deviceId);
+ int sum3 = 0;
+ Iterator it3 = flows3.iterator();
+ while (it3.hasNext()) {
+ it3.next();
+ sum3++;
+ }
+ assertThat(sum3, is(0));
+ }
+}