ONOS-1793  Moved trivial stores to onos-core-common/src/test; onos-core-trivial is no longer.

Change-Id: Ie4824db36e3a7eb6db3b953ee1f2786d3e22194f
diff --git a/core/common/src/test/java/org/onosproject/store/trivial/SimpleGroupStoreTest.java b/core/common/src/test/java/org/onosproject/store/trivial/SimpleGroupStoreTest.java
new file mode 100644
index 0000000..dd6c8a5
--- /dev/null
+++ b/core/common/src/test/java/org/onosproject/store/trivial/SimpleGroupStoreTest.java
@@ -0,0 +1,482 @@
+/*
+ * 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.trivial;
+
+import static org.junit.Assert.assertEquals;
+import static org.onosproject.net.DeviceId.deviceId;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.MplsLabel;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.core.GroupId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.group.DefaultGroup;
+import org.onosproject.net.group.DefaultGroupBucket;
+import org.onosproject.net.group.DefaultGroupDescription;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupEvent;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupOperation;
+import org.onosproject.net.group.GroupStore.UpdateType;
+import org.onosproject.net.group.GroupStoreDelegate;
+import org.onosproject.net.group.StoredGroupBucketEntry;
+import org.onosproject.net.group.StoredGroupEntry;
+
+import com.google.common.collect.Iterables;
+
+/**
+ * Test of the simple DeviceStore implementation.
+ */
+public class SimpleGroupStoreTest {
+
+    private SimpleGroupStore simpleGroupStore;
+    private final ApplicationId appId =
+            new DefaultApplicationId(2, "org.groupstore.test");
+
+    public static final DeviceId D1 = deviceId("of:1");
+
+    @Before
+    public void setUp() throws Exception {
+        simpleGroupStore = new SimpleGroupStore();
+        simpleGroupStore.activate();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        simpleGroupStore.deactivate();
+    }
+
+    private class InternalGroupStoreDelegate
+                implements GroupStoreDelegate {
+        private GroupId createdGroupId = null;
+        private GroupKey createdGroupKey;
+        private GroupBuckets createdBuckets;
+        private GroupEvent.Type expectedEvent;
+
+        public InternalGroupStoreDelegate(GroupKey key,
+                                          GroupBuckets buckets,
+                                          GroupEvent.Type expectedEvent) {
+            this.createdBuckets = buckets;
+            this.createdGroupKey = key;
+            this.expectedEvent = expectedEvent;
+        }
+        @Override
+        public void notify(GroupEvent event) {
+            assertEquals(expectedEvent, event.type());
+            assertEquals(Group.Type.SELECT, event.subject().type());
+            assertEquals(D1, event.subject().deviceId());
+            assertEquals(createdGroupKey, event.subject().appCookie());
+            assertEquals(createdBuckets.buckets(), event.subject().buckets().buckets());
+            if (expectedEvent == GroupEvent.Type.GROUP_ADD_REQUESTED) {
+                createdGroupId = event.subject().id();
+                assertEquals(Group.GroupState.PENDING_ADD,
+                             event.subject().state());
+            } else if (expectedEvent == GroupEvent.Type.GROUP_ADDED) {
+                createdGroupId = event.subject().id();
+                assertEquals(Group.GroupState.ADDED,
+                             event.subject().state());
+            } else if (expectedEvent == GroupEvent.Type.GROUP_UPDATED) {
+                createdGroupId = event.subject().id();
+                assertEquals(true,
+                             event.subject().buckets().
+                             buckets().containsAll(createdBuckets.buckets()));
+                assertEquals(true,
+                             createdBuckets.buckets().
+                             containsAll(event.subject().buckets().buckets()));
+                for (GroupBucket bucket:event.subject().buckets().buckets()) {
+                    Optional<GroupBucket> matched = createdBuckets.buckets()
+                            .stream()
+                            .filter((expected) -> expected.equals(bucket))
+                            .findFirst();
+                    assertEquals(matched.get().packets(),
+                                 bucket.packets());
+                    assertEquals(matched.get().bytes(),
+                                 bucket.bytes());
+                }
+                assertEquals(Group.GroupState.ADDED,
+                             event.subject().state());
+            } else if (expectedEvent == GroupEvent.Type.GROUP_UPDATE_REQUESTED) {
+                assertEquals(Group.GroupState.PENDING_UPDATE,
+                             event.subject().state());
+            } else if (expectedEvent == GroupEvent.Type.GROUP_REMOVE_REQUESTED) {
+                assertEquals(Group.GroupState.PENDING_DELETE,
+                             event.subject().state());
+            } else if (expectedEvent == GroupEvent.Type.GROUP_REMOVED) {
+                createdGroupId = event.subject().id();
+                assertEquals(Group.GroupState.PENDING_DELETE,
+                             event.subject().state());
+            } else if (expectedEvent == GroupEvent.Type.GROUP_ADD_FAILED) {
+                createdGroupId = event.subject().id();
+                assertEquals(Group.GroupState.PENDING_ADD,
+                        event.subject().state());
+            } else if (expectedEvent == GroupEvent.Type.GROUP_UPDATE_FAILED) {
+                createdGroupId = event.subject().id();
+                assertEquals(Group.GroupState.PENDING_UPDATE,
+                        event.subject().state());
+            } else if (expectedEvent == GroupEvent.Type.GROUP_REMOVE_FAILED) {
+                createdGroupId = event.subject().id();
+                assertEquals(Group.GroupState.PENDING_DELETE,
+                        event.subject().state());
+            }
+        }
+
+        public void verifyGroupId(GroupId id) {
+            assertEquals(createdGroupId, id);
+        }
+    }
+
+    /**
+     * Tests group store operations. The following operations are tested:
+     * a)Tests device group audit completion status change
+     * b)Tests storeGroup operation
+     * c)Tests getGroupCount operation
+     * d)Tests getGroup operation
+     * e)Tests getGroups operation
+     * f)Tests addOrUpdateGroupEntry operation from southbound
+     * g)Tests updateGroupDescription for ADD operation from northbound
+     * h)Tests updateGroupDescription for REMOVE operation from northbound
+     * i)Tests deleteGroupDescription operation from northbound
+     * j)Tests removeGroupEntry operation from southbound
+     */
+    @Test
+    public void testGroupStoreOperations() {
+        // Set the Device AUDIT completed in the store
+        simpleGroupStore.deviceInitialAuditCompleted(D1, true);
+
+        // Testing storeGroup operation
+        GroupKey newKey = new DefaultGroupKey("group1".getBytes());
+        testStoreAndGetGroup(newKey);
+
+        // Testing addOrUpdateGroupEntry operation from southbound
+        GroupKey currKey = newKey;
+        testAddGroupEntryFromSB(currKey);
+
+        // Testing updateGroupDescription for ADD operation from northbound
+        newKey = new DefaultGroupKey("group1AddBuckets".getBytes());
+        testAddBuckets(currKey, newKey);
+
+        // Testing updateGroupDescription for REMOVE operation from northbound
+        currKey = newKey;
+        newKey = new DefaultGroupKey("group1RemoveBuckets".getBytes());
+        testRemoveBuckets(currKey, newKey);
+
+        // Testing addOrUpdateGroupEntry operation from southbound
+        currKey = newKey;
+        testUpdateGroupEntryFromSB(currKey);
+
+        // Testing deleteGroupDescription operation from northbound
+        testDeleteGroup(currKey);
+
+        // Testing removeGroupEntry operation from southbound
+        testRemoveGroupFromSB(currKey);
+    }
+
+    // Testing storeGroup operation
+    private void testStoreAndGetGroup(GroupKey key) {
+        PortNumber[] ports = {PortNumber.portNumber(31),
+                              PortNumber.portNumber(32)};
+        List<PortNumber> outPorts = new ArrayList<PortNumber>();
+        outPorts.addAll(Arrays.asList(ports));
+
+        List<GroupBucket> buckets = new ArrayList<GroupBucket>();
+        for (PortNumber portNumber: outPorts) {
+            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+            tBuilder.setOutput(portNumber)
+                    .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
+                    .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
+                    .pushMpls()
+                    .setMpls(MplsLabel.mplsLabel(106));
+            buckets.add(DefaultGroupBucket.createSelectGroupBucket(
+                                                        tBuilder.build()));
+        }
+        GroupBuckets groupBuckets = new GroupBuckets(buckets);
+        GroupDescription groupDesc = new DefaultGroupDescription(
+                                                 D1,
+                                                 Group.Type.SELECT,
+                                                 groupBuckets,
+                                                 key,
+                                                 null,
+                                                 appId);
+        InternalGroupStoreDelegate checkStoreGroupDelegate =
+                new InternalGroupStoreDelegate(key,
+                                               groupBuckets,
+                                               GroupEvent.Type.GROUP_ADD_REQUESTED);
+        simpleGroupStore.setDelegate(checkStoreGroupDelegate);
+        // Testing storeGroup operation
+        simpleGroupStore.storeGroupDescription(groupDesc);
+
+        // Testing getGroupCount operation
+        assertEquals(1, simpleGroupStore.getGroupCount(D1));
+
+        // Testing getGroup operation
+        Group createdGroup = simpleGroupStore.getGroup(D1, key);
+        checkStoreGroupDelegate.verifyGroupId(createdGroup.id());
+
+        // Testing getGroups operation
+        Iterable<Group> createdGroups = simpleGroupStore.getGroups(D1);
+        int groupCount = 0;
+        for (Group group:createdGroups) {
+            checkStoreGroupDelegate.verifyGroupId(group.id());
+            groupCount++;
+        }
+        assertEquals(1, groupCount);
+        simpleGroupStore.unsetDelegate(checkStoreGroupDelegate);
+    }
+
+    // Testing addOrUpdateGroupEntry operation from southbound
+    private void testAddGroupEntryFromSB(GroupKey currKey) {
+        Group existingGroup = simpleGroupStore.getGroup(D1, currKey);
+
+        InternalGroupStoreDelegate addGroupEntryDelegate =
+                new InternalGroupStoreDelegate(currKey,
+                                               existingGroup.buckets(),
+                                               GroupEvent.Type.GROUP_ADDED);
+        simpleGroupStore.setDelegate(addGroupEntryDelegate);
+        simpleGroupStore.addOrUpdateGroupEntry(existingGroup);
+        simpleGroupStore.unsetDelegate(addGroupEntryDelegate);
+    }
+
+    // Testing addOrUpdateGroupEntry operation from southbound
+    private void testUpdateGroupEntryFromSB(GroupKey currKey) {
+        Group existingGroup = simpleGroupStore.getGroup(D1, currKey);
+        int totalPkts = 0;
+        int totalBytes = 0;
+        List<GroupBucket> newBucketList = new ArrayList<GroupBucket>();
+        for (GroupBucket bucket:existingGroup.buckets().buckets()) {
+            StoredGroupBucketEntry newBucket =
+                    (StoredGroupBucketEntry)
+                    DefaultGroupBucket.createSelectGroupBucket(bucket.treatment());
+            newBucket.setPackets(10);
+            newBucket.setBytes(10 * 256 * 8);
+            totalPkts += 10;
+            totalBytes += 10 * 256 * 8;
+            newBucketList.add(newBucket);
+        }
+        GroupBuckets updatedBuckets = new GroupBuckets(newBucketList);
+        Group updatedGroup = new DefaultGroup(existingGroup.id(),
+                                              existingGroup.deviceId(),
+                                              existingGroup.type(),
+                                              updatedBuckets);
+        ((StoredGroupEntry) updatedGroup).setPackets(totalPkts);
+        ((StoredGroupEntry) updatedGroup).setBytes(totalBytes);
+
+        InternalGroupStoreDelegate updateGroupEntryDelegate =
+                new InternalGroupStoreDelegate(currKey,
+                                               updatedBuckets,
+                                               GroupEvent.Type.GROUP_UPDATED);
+        simpleGroupStore.setDelegate(updateGroupEntryDelegate);
+        simpleGroupStore.addOrUpdateGroupEntry(updatedGroup);
+        simpleGroupStore.unsetDelegate(updateGroupEntryDelegate);
+    }
+
+    // Testing updateGroupDescription for ADD operation from northbound
+    private void testAddBuckets(GroupKey currKey, GroupKey addKey) {
+        Group existingGroup = simpleGroupStore.getGroup(D1, currKey);
+        List<GroupBucket> buckets = new ArrayList<GroupBucket>();
+        buckets.addAll(existingGroup.buckets().buckets());
+
+        PortNumber[] newNeighborPorts = {PortNumber.portNumber(41),
+                                         PortNumber.portNumber(42)};
+        List<PortNumber> newOutPorts = new ArrayList<PortNumber>();
+        newOutPorts.addAll(Collections.singletonList(newNeighborPorts[0]));
+
+        List<GroupBucket> toAddBuckets = new ArrayList<GroupBucket>();
+        for (PortNumber portNumber: newOutPorts) {
+            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+            tBuilder.setOutput(portNumber)
+                    .setEthDst(MacAddress.valueOf("00:00:00:00:00:03"))
+                    .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
+                    .pushMpls()
+                    .setMpls(MplsLabel.mplsLabel(106));
+            toAddBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
+                                                        tBuilder.build()));
+        }
+        GroupBuckets toAddGroupBuckets = new GroupBuckets(toAddBuckets);
+        buckets.addAll(toAddBuckets);
+        GroupBuckets updatedGroupBuckets = new GroupBuckets(buckets);
+        InternalGroupStoreDelegate updateGroupDescDelegate =
+                new InternalGroupStoreDelegate(addKey,
+                                               updatedGroupBuckets,
+                                               GroupEvent.Type.GROUP_UPDATE_REQUESTED);
+        simpleGroupStore.setDelegate(updateGroupDescDelegate);
+        simpleGroupStore.updateGroupDescription(D1,
+                                                currKey,
+                                                UpdateType.ADD,
+                                                toAddGroupBuckets,
+                                                addKey);
+        simpleGroupStore.unsetDelegate(updateGroupDescDelegate);
+    }
+
+    // Testing updateGroupDescription for REMOVE operation from northbound
+    private void testRemoveBuckets(GroupKey currKey, GroupKey removeKey) {
+        Group existingGroup = simpleGroupStore.getGroup(D1, currKey);
+        List<GroupBucket> buckets = new ArrayList<GroupBucket>();
+        buckets.addAll(existingGroup.buckets().buckets());
+
+        List<GroupBucket> toRemoveBuckets = new ArrayList<GroupBucket>();
+
+        // There should be 4 buckets in the current group
+        toRemoveBuckets.add(buckets.remove(0));
+        toRemoveBuckets.add(buckets.remove(1));
+        GroupBuckets toRemoveGroupBuckets = new GroupBuckets(toRemoveBuckets);
+
+        GroupBuckets remainingGroupBuckets = new GroupBuckets(buckets);
+        InternalGroupStoreDelegate removeGroupDescDelegate =
+                new InternalGroupStoreDelegate(removeKey,
+                                               remainingGroupBuckets,
+                                               GroupEvent.Type.GROUP_UPDATE_REQUESTED);
+        simpleGroupStore.setDelegate(removeGroupDescDelegate);
+        simpleGroupStore.updateGroupDescription(D1,
+                                                currKey,
+                                                UpdateType.REMOVE,
+                                                toRemoveGroupBuckets,
+                                                removeKey);
+        simpleGroupStore.unsetDelegate(removeGroupDescDelegate);
+    }
+
+    // Testing deleteGroupDescription operation from northbound
+    private void testDeleteGroup(GroupKey currKey) {
+        Group existingGroup = simpleGroupStore.getGroup(D1, currKey);
+        InternalGroupStoreDelegate deleteGroupDescDelegate =
+                new InternalGroupStoreDelegate(currKey,
+                                               existingGroup.buckets(),
+                                               GroupEvent.Type.GROUP_REMOVE_REQUESTED);
+        simpleGroupStore.setDelegate(deleteGroupDescDelegate);
+        simpleGroupStore.deleteGroupDescription(D1, currKey);
+        simpleGroupStore.unsetDelegate(deleteGroupDescDelegate);
+    }
+
+    // Testing removeGroupEntry operation from southbound
+    private void testRemoveGroupFromSB(GroupKey currKey) {
+        Group existingGroup = simpleGroupStore.getGroup(D1, currKey);
+        InternalGroupStoreDelegate removeGroupEntryDelegate =
+                new InternalGroupStoreDelegate(currKey,
+                                               existingGroup.buckets(),
+                                               GroupEvent.Type.GROUP_REMOVED);
+        simpleGroupStore.setDelegate(removeGroupEntryDelegate);
+        simpleGroupStore.removeGroupEntry(existingGroup);
+
+        // Testing getGroup operation
+        existingGroup = simpleGroupStore.getGroup(D1, currKey);
+        assertEquals(null, existingGroup);
+        assertEquals(0, Iterables.size(simpleGroupStore.getGroups(D1)));
+        assertEquals(0, simpleGroupStore.getGroupCount(D1));
+
+        simpleGroupStore.unsetDelegate(removeGroupEntryDelegate);
+    }
+
+    @Test
+    public void testGroupOperationFailure() {
+
+        simpleGroupStore.deviceInitialAuditCompleted(D1, true);
+
+        ApplicationId appId =
+                new DefaultApplicationId(2, "org.groupstore.test");
+        GroupKey key = new DefaultGroupKey("group1".getBytes());
+        PortNumber[] ports = {PortNumber.portNumber(31),
+                PortNumber.portNumber(32)};
+        List<PortNumber> outPorts = new ArrayList<PortNumber>();
+        outPorts.add(ports[0]);
+        outPorts.add(ports[1]);
+
+        List<GroupBucket> buckets = new ArrayList<GroupBucket>();
+        for (PortNumber portNumber: outPorts) {
+            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+            tBuilder.setOutput(portNumber)
+                    .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
+                    .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
+                    .pushMpls()
+                    .setMpls(MplsLabel.mplsLabel(106));
+            buckets.add(DefaultGroupBucket.createSelectGroupBucket(
+                    tBuilder.build()));
+        }
+        GroupBuckets groupBuckets = new GroupBuckets(buckets);
+        GroupDescription groupDesc = new DefaultGroupDescription(
+                D1,
+                Group.Type.SELECT,
+                groupBuckets,
+                key,
+                null,
+                appId);
+        InternalGroupStoreDelegate checkStoreGroupDelegate =
+                new InternalGroupStoreDelegate(key,
+                        groupBuckets,
+                        GroupEvent.Type.GROUP_ADD_REQUESTED);
+        simpleGroupStore.setDelegate(checkStoreGroupDelegate);
+        // Testing storeGroup operation
+        simpleGroupStore.storeGroupDescription(groupDesc);
+        simpleGroupStore.unsetDelegate(checkStoreGroupDelegate);
+
+        // Testing Group add operation failure
+        Group createdGroup = simpleGroupStore.getGroup(D1, key);
+        checkStoreGroupDelegate.verifyGroupId(createdGroup.id());
+
+        GroupOperation groupAddOp = GroupOperation.
+                createAddGroupOperation(createdGroup.id(),
+                        createdGroup.type(),
+                        createdGroup.buckets());
+        InternalGroupStoreDelegate checkGroupAddFailureDelegate =
+                new InternalGroupStoreDelegate(key,
+                        groupBuckets,
+                        GroupEvent.Type.GROUP_ADD_FAILED);
+        simpleGroupStore.setDelegate(checkGroupAddFailureDelegate);
+        simpleGroupStore.groupOperationFailed(D1, groupAddOp);
+
+
+        // Testing Group modify operation failure
+        simpleGroupStore.unsetDelegate(checkGroupAddFailureDelegate);
+        GroupOperation groupModOp = GroupOperation.
+                createModifyGroupOperation(createdGroup.id(),
+                        createdGroup.type(),
+                        createdGroup.buckets());
+        InternalGroupStoreDelegate checkGroupModFailureDelegate =
+                new InternalGroupStoreDelegate(key,
+                        groupBuckets,
+                        GroupEvent.Type.GROUP_UPDATE_FAILED);
+        simpleGroupStore.setDelegate(checkGroupModFailureDelegate);
+        simpleGroupStore.groupOperationFailed(D1, groupModOp);
+
+        // Testing Group modify operation failure
+        simpleGroupStore.unsetDelegate(checkGroupModFailureDelegate);
+        GroupOperation groupDelOp = GroupOperation.
+                createDeleteGroupOperation(createdGroup.id(),
+                        createdGroup.type());
+        InternalGroupStoreDelegate checkGroupDelFailureDelegate =
+                new InternalGroupStoreDelegate(key,
+                        groupBuckets,
+                        GroupEvent.Type.GROUP_REMOVE_FAILED);
+        simpleGroupStore.setDelegate(checkGroupDelFailureDelegate);
+        simpleGroupStore.groupOperationFailed(D1, groupDelOp);
+    }
+}
+