Committed by
Gerrit Code Review
Unit tests for the distributed group store.
Change-Id: Ie8f00b9bbc1ba46a6f80e70f63d1fd853d64154b
Showing
5 changed files
with
549 additions
and
79 deletions
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onosproject.store.cluster.messaging; | ||
17 | + | ||
18 | +import java.util.Set; | ||
19 | +import java.util.concurrent.CompletableFuture; | ||
20 | +import java.util.concurrent.Executor; | ||
21 | +import java.util.concurrent.ExecutorService; | ||
22 | +import java.util.function.Consumer; | ||
23 | +import java.util.function.Function; | ||
24 | + | ||
25 | +import org.onosproject.cluster.NodeId; | ||
26 | + | ||
27 | +/** | ||
28 | + * Testing adapter for the cluster communication service. | ||
29 | + */ | ||
30 | +public class ClusterCommunicationServiceAdapter | ||
31 | + implements ClusterCommunicationService { | ||
32 | + | ||
33 | + @Override | ||
34 | + public void addSubscriber(MessageSubject subject, | ||
35 | + ClusterMessageHandler subscriber, | ||
36 | + ExecutorService executor) { | ||
37 | + } | ||
38 | + | ||
39 | + @Override | ||
40 | + public void removeSubscriber(MessageSubject subject) {} | ||
41 | + | ||
42 | + @Override | ||
43 | + public <M> void broadcast(M message, MessageSubject subject, | ||
44 | + Function<M, byte[]> encoder) { | ||
45 | + } | ||
46 | + | ||
47 | + @Override | ||
48 | + public <M> void broadcastIncludeSelf(M message, | ||
49 | + MessageSubject subject, Function<M, byte[]> encoder) { | ||
50 | + } | ||
51 | + | ||
52 | + @Override | ||
53 | + public <M> CompletableFuture<Void> unicast(M message, MessageSubject subject, | ||
54 | + Function<M, byte[]> encoder, NodeId toNodeId) { | ||
55 | + return null; | ||
56 | + } | ||
57 | + | ||
58 | + @Override | ||
59 | + public <M> void multicast(M message, MessageSubject subject, | ||
60 | + Function<M, byte[]> encoder, Set<NodeId> nodes) { | ||
61 | + } | ||
62 | + | ||
63 | + @Override | ||
64 | + public <M, R> CompletableFuture<R> sendAndReceive(M message, | ||
65 | + MessageSubject subject, Function<M, byte[]> encoder, | ||
66 | + Function<byte[], R> decoder, NodeId toNodeId) { | ||
67 | + return null; | ||
68 | + } | ||
69 | + | ||
70 | + @Override | ||
71 | + public <M, R> void addSubscriber(MessageSubject subject, | ||
72 | + Function<byte[], M> decoder, Function<M, R> handler, | ||
73 | + Function<R, byte[]> encoder, Executor executor) { | ||
74 | + } | ||
75 | + | ||
76 | + @Override | ||
77 | + public <M, R> void addSubscriber(MessageSubject subject, | ||
78 | + Function<byte[], M> decoder, Function<M, CompletableFuture<R>> handler, | ||
79 | + Function<R, byte[]> encoder) { | ||
80 | + } | ||
81 | + | ||
82 | + @Override | ||
83 | + public <M> void addSubscriber(MessageSubject subject, | ||
84 | + Function<byte[], M> decoder, Consumer<M> handler, | ||
85 | + Executor executor) { | ||
86 | + | ||
87 | + } | ||
88 | +} |
... | @@ -91,8 +91,10 @@ public final class TestEventuallyConsistentMap<K, V> extends EventuallyConsisten | ... | @@ -91,8 +91,10 @@ public final class TestEventuallyConsistentMap<K, V> extends EventuallyConsisten |
91 | EventuallyConsistentMapEvent<K, V> addEvent = | 91 | EventuallyConsistentMapEvent<K, V> addEvent = |
92 | new EventuallyConsistentMapEvent<>(mapName, PUT, key, value); | 92 | new EventuallyConsistentMapEvent<>(mapName, PUT, key, value); |
93 | notifyListeners(addEvent); | 93 | notifyListeners(addEvent); |
94 | + if (peerUpdateFunction != null) { | ||
94 | peerUpdateFunction.apply(key, value); | 95 | peerUpdateFunction.apply(key, value); |
95 | } | 96 | } |
97 | + } | ||
96 | 98 | ||
97 | @Override | 99 | @Override |
98 | public V remove(K key) { | 100 | public V remove(K key) { | ... | ... |
... | @@ -1014,7 +1014,7 @@ public class DistributedGroupStore | ... | @@ -1014,7 +1014,7 @@ public class DistributedGroupStore |
1014 | /** | 1014 | /** |
1015 | * Flattened map key to be used to store group entries. | 1015 | * Flattened map key to be used to store group entries. |
1016 | */ | 1016 | */ |
1017 | - private class GroupStoreMapKey { | 1017 | + protected static class GroupStoreMapKey { |
1018 | private final DeviceId deviceId; | 1018 | private final DeviceId deviceId; |
1019 | 1019 | ||
1020 | public GroupStoreMapKey(DeviceId deviceId) { | 1020 | public GroupStoreMapKey(DeviceId deviceId) { |
... | @@ -1047,7 +1047,7 @@ public class DistributedGroupStore | ... | @@ -1047,7 +1047,7 @@ public class DistributedGroupStore |
1047 | } | 1047 | } |
1048 | } | 1048 | } |
1049 | 1049 | ||
1050 | - private class GroupStoreKeyMapKey extends GroupStoreMapKey { | 1050 | + protected static class GroupStoreKeyMapKey extends GroupStoreMapKey { |
1051 | private final GroupKey appCookie; | 1051 | private final GroupKey appCookie; |
1052 | public GroupStoreKeyMapKey(DeviceId deviceId, | 1052 | public GroupStoreKeyMapKey(DeviceId deviceId, |
1053 | GroupKey appCookie) { | 1053 | GroupKey appCookie) { |
... | @@ -1078,7 +1078,7 @@ public class DistributedGroupStore | ... | @@ -1078,7 +1078,7 @@ public class DistributedGroupStore |
1078 | } | 1078 | } |
1079 | } | 1079 | } |
1080 | 1080 | ||
1081 | - private class GroupStoreIdMapKey extends GroupStoreMapKey { | 1081 | + protected static class GroupStoreIdMapKey extends GroupStoreMapKey { |
1082 | private final GroupId groupId; | 1082 | private final GroupId groupId; |
1083 | public GroupStoreIdMapKey(DeviceId deviceId, | 1083 | public GroupStoreIdMapKey(DeviceId deviceId, |
1084 | GroupId groupId) { | 1084 | GroupId groupId) { | ... | ... |
... | @@ -15,10 +15,22 @@ | ... | @@ -15,10 +15,22 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.store.ecmap; | 16 | package org.onosproject.store.ecmap; |
17 | 17 | ||
18 | -import com.google.common.collect.ComparisonChain; | 18 | +import java.util.ArrayList; |
19 | -import com.google.common.collect.ImmutableList; | 19 | +import java.util.Collection; |
20 | -import com.google.common.collect.ImmutableSet; | 20 | +import java.util.HashMap; |
21 | -import com.google.common.util.concurrent.MoreExecutors; | 21 | +import java.util.HashSet; |
22 | +import java.util.List; | ||
23 | +import java.util.Map; | ||
24 | +import java.util.Objects; | ||
25 | +import java.util.Optional; | ||
26 | +import java.util.Set; | ||
27 | +import java.util.concurrent.CompletableFuture; | ||
28 | +import java.util.concurrent.CountDownLatch; | ||
29 | +import java.util.concurrent.Executor; | ||
30 | +import java.util.concurrent.TimeUnit; | ||
31 | +import java.util.concurrent.atomic.AtomicLong; | ||
32 | +import java.util.function.Consumer; | ||
33 | +import java.util.function.Function; | ||
22 | 34 | ||
23 | import org.junit.After; | 35 | import org.junit.After; |
24 | import org.junit.Before; | 36 | import org.junit.Before; |
... | @@ -32,38 +44,35 @@ import org.onosproject.cluster.NodeId; | ... | @@ -32,38 +44,35 @@ import org.onosproject.cluster.NodeId; |
32 | import org.onosproject.event.AbstractEvent; | 44 | import org.onosproject.event.AbstractEvent; |
33 | import org.onosproject.store.Timestamp; | 45 | import org.onosproject.store.Timestamp; |
34 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | 46 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; |
35 | -import org.onosproject.store.cluster.messaging.ClusterMessageHandler; | 47 | +import org.onosproject.store.cluster.messaging.ClusterCommunicationServiceAdapter; |
36 | import org.onosproject.store.cluster.messaging.MessageSubject; | 48 | import org.onosproject.store.cluster.messaging.MessageSubject; |
37 | import org.onosproject.store.impl.LogicalTimestamp; | 49 | import org.onosproject.store.impl.LogicalTimestamp; |
38 | -import org.onosproject.store.service.WallClockTimestamp; | ||
39 | import org.onosproject.store.serializers.KryoNamespaces; | 50 | import org.onosproject.store.serializers.KryoNamespaces; |
40 | import org.onosproject.store.serializers.KryoSerializer; | 51 | import org.onosproject.store.serializers.KryoSerializer; |
41 | import org.onosproject.store.service.EventuallyConsistentMap; | 52 | import org.onosproject.store.service.EventuallyConsistentMap; |
42 | import org.onosproject.store.service.EventuallyConsistentMapEvent; | 53 | import org.onosproject.store.service.EventuallyConsistentMapEvent; |
43 | import org.onosproject.store.service.EventuallyConsistentMapListener; | 54 | import org.onosproject.store.service.EventuallyConsistentMapListener; |
55 | +import org.onosproject.store.service.WallClockTimestamp; | ||
44 | 56 | ||
45 | -import java.util.ArrayList; | 57 | +import com.google.common.collect.ComparisonChain; |
46 | -import java.util.Collection; | 58 | +import com.google.common.collect.ImmutableList; |
47 | -import java.util.HashMap; | 59 | +import com.google.common.collect.ImmutableSet; |
48 | -import java.util.HashSet; | 60 | +import com.google.common.util.concurrent.MoreExecutors; |
49 | -import java.util.List; | ||
50 | -import java.util.Map; | ||
51 | -import java.util.Objects; | ||
52 | -import java.util.Optional; | ||
53 | -import java.util.Set; | ||
54 | -import java.util.concurrent.CompletableFuture; | ||
55 | -import java.util.concurrent.CountDownLatch; | ||
56 | -import java.util.concurrent.Executor; | ||
57 | -import java.util.concurrent.ExecutorService; | ||
58 | -import java.util.concurrent.TimeUnit; | ||
59 | -import java.util.concurrent.atomic.AtomicLong; | ||
60 | -import java.util.function.Consumer; | ||
61 | -import java.util.function.Function; | ||
62 | 61 | ||
63 | import static com.google.common.base.Preconditions.checkArgument; | 62 | import static com.google.common.base.Preconditions.checkArgument; |
64 | import static junit.framework.TestCase.assertFalse; | 63 | import static junit.framework.TestCase.assertFalse; |
65 | -import static org.easymock.EasyMock.*; | 64 | +import static org.easymock.EasyMock.anyObject; |
66 | -import static org.junit.Assert.*; | 65 | +import static org.easymock.EasyMock.createMock; |
66 | +import static org.easymock.EasyMock.eq; | ||
67 | +import static org.easymock.EasyMock.expect; | ||
68 | +import static org.easymock.EasyMock.expectLastCall; | ||
69 | +import static org.easymock.EasyMock.replay; | ||
70 | +import static org.easymock.EasyMock.reset; | ||
71 | +import static org.easymock.EasyMock.verify; | ||
72 | +import static org.junit.Assert.assertEquals; | ||
73 | +import static org.junit.Assert.assertNull; | ||
74 | +import static org.junit.Assert.assertTrue; | ||
75 | +import static org.junit.Assert.fail; | ||
67 | 76 | ||
68 | /** | 77 | /** |
69 | * Unit tests for EventuallyConsistentMapImpl. | 78 | * Unit tests for EventuallyConsistentMapImpl. |
... | @@ -697,7 +706,7 @@ public class EventuallyConsistentMapImplTest { | ... | @@ -697,7 +706,7 @@ public class EventuallyConsistentMapImplTest { |
697 | * Sets up a mock ClusterCommunicationService to expect a specific cluster | 706 | * Sets up a mock ClusterCommunicationService to expect a specific cluster |
698 | * message to be broadcast to the cluster. | 707 | * message to be broadcast to the cluster. |
699 | * | 708 | * |
700 | - * @param m message we expect to be sent | 709 | + * @param message message we expect to be sent |
701 | * @param clusterCommunicator a mock ClusterCommunicationService to set up | 710 | * @param clusterCommunicator a mock ClusterCommunicationService to set up |
702 | */ | 711 | */ |
703 | //FIXME rename | 712 | //FIXME rename |
... | @@ -776,56 +785,7 @@ public class EventuallyConsistentMapImplTest { | ... | @@ -776,56 +785,7 @@ public class EventuallyConsistentMapImplTest { |
776 | * events coming in from other instances. | 785 | * events coming in from other instances. |
777 | */ | 786 | */ |
778 | private final class TestClusterCommunicationService | 787 | private final class TestClusterCommunicationService |
779 | - implements ClusterCommunicationService { | 788 | + extends ClusterCommunicationServiceAdapter { |
780 | - | ||
781 | - @Override | ||
782 | - public void addSubscriber(MessageSubject subject, | ||
783 | - ClusterMessageHandler subscriber, | ||
784 | - ExecutorService executor) { | ||
785 | - } | ||
786 | - | ||
787 | - @Override | ||
788 | - public void removeSubscriber(MessageSubject subject) {} | ||
789 | - | ||
790 | - @Override | ||
791 | - public <M> void broadcast(M message, MessageSubject subject, | ||
792 | - Function<M, byte[]> encoder) { | ||
793 | - } | ||
794 | - | ||
795 | - @Override | ||
796 | - public <M> void broadcastIncludeSelf(M message, | ||
797 | - MessageSubject subject, Function<M, byte[]> encoder) { | ||
798 | - } | ||
799 | - | ||
800 | - @Override | ||
801 | - public <M> CompletableFuture<Void> unicast(M message, MessageSubject subject, | ||
802 | - Function<M, byte[]> encoder, NodeId toNodeId) { | ||
803 | - return null; | ||
804 | - } | ||
805 | - | ||
806 | - @Override | ||
807 | - public <M> void multicast(M message, MessageSubject subject, | ||
808 | - Function<M, byte[]> encoder, Set<NodeId> nodes) { | ||
809 | - } | ||
810 | - | ||
811 | - @Override | ||
812 | - public <M, R> CompletableFuture<R> sendAndReceive(M message, | ||
813 | - MessageSubject subject, Function<M, byte[]> encoder, | ||
814 | - Function<byte[], R> decoder, NodeId toNodeId) { | ||
815 | - return null; | ||
816 | - } | ||
817 | - | ||
818 | - @Override | ||
819 | - public <M, R> void addSubscriber(MessageSubject subject, | ||
820 | - Function<byte[], M> decoder, Function<M, R> handler, | ||
821 | - Function<R, byte[]> encoder, Executor executor) { | ||
822 | - } | ||
823 | - | ||
824 | - @Override | ||
825 | - public <M, R> void addSubscriber(MessageSubject subject, | ||
826 | - Function<byte[], M> decoder, Function<M, CompletableFuture<R>> handler, | ||
827 | - Function<R, byte[]> encoder) { | ||
828 | - } | ||
829 | 789 | ||
830 | @Override | 790 | @Override |
831 | public <M> void addSubscriber(MessageSubject subject, | 791 | public <M> void addSubscriber(MessageSubject subject, | ... | ... |
core/store/dist/src/test/java/org/onosproject/store/group/impl/DistributedGroupStoreTest.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onosproject.store.group.impl; | ||
17 | + | ||
18 | +import java.util.ArrayList; | ||
19 | +import java.util.LinkedList; | ||
20 | +import java.util.List; | ||
21 | + | ||
22 | +import org.junit.After; | ||
23 | +import org.junit.Before; | ||
24 | +import org.junit.Test; | ||
25 | +import org.onlab.junit.TestUtils; | ||
26 | +import org.onosproject.core.DefaultGroupId; | ||
27 | +import org.onosproject.core.GroupId; | ||
28 | +import org.onosproject.mastership.MastershipServiceAdapter; | ||
29 | +import org.onosproject.net.DeviceId; | ||
30 | +import org.onosproject.net.MastershipRole; | ||
31 | +import org.onosproject.net.PortNumber; | ||
32 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
33 | +import org.onosproject.net.flow.TrafficTreatment; | ||
34 | +import org.onosproject.net.group.DefaultGroup; | ||
35 | +import org.onosproject.net.group.DefaultGroupBucket; | ||
36 | +import org.onosproject.net.group.DefaultGroupDescription; | ||
37 | +import org.onosproject.net.group.DefaultGroupKey; | ||
38 | +import org.onosproject.net.group.Group; | ||
39 | +import org.onosproject.net.group.GroupBucket; | ||
40 | +import org.onosproject.net.group.GroupBuckets; | ||
41 | +import org.onosproject.net.group.GroupDescription; | ||
42 | +import org.onosproject.net.group.GroupEvent; | ||
43 | +import org.onosproject.net.group.GroupKey; | ||
44 | +import org.onosproject.net.group.GroupOperation; | ||
45 | +import org.onosproject.net.group.GroupStore; | ||
46 | +import org.onosproject.net.group.GroupStoreDelegate; | ||
47 | +import org.onosproject.store.cluster.messaging.ClusterCommunicationServiceAdapter; | ||
48 | +import org.onosproject.store.service.EventuallyConsistentMap; | ||
49 | +import org.onosproject.store.service.TestStorageService; | ||
50 | + | ||
51 | +import com.google.common.collect.ImmutableList; | ||
52 | +import com.google.common.collect.Lists; | ||
53 | +import com.google.common.testing.EqualsTester; | ||
54 | + | ||
55 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
56 | +import static org.hamcrest.Matchers.hasSize; | ||
57 | +import static org.hamcrest.Matchers.instanceOf; | ||
58 | +import static org.hamcrest.Matchers.is; | ||
59 | +import static org.hamcrest.Matchers.notNullValue; | ||
60 | +import static org.hamcrest.Matchers.nullValue; | ||
61 | +import static org.onosproject.net.NetTestTools.APP_ID; | ||
62 | +import static org.onosproject.net.NetTestTools.did; | ||
63 | + | ||
64 | +/** | ||
65 | + * Distributed group store test. | ||
66 | + */ | ||
67 | +public class DistributedGroupStoreTest { | ||
68 | + | ||
69 | + DeviceId deviceId1 = did("dev1"); | ||
70 | + DeviceId deviceId2 = did("dev2"); | ||
71 | + GroupId groupId1 = new DefaultGroupId(1); | ||
72 | + GroupId groupId2 = new DefaultGroupId(2); | ||
73 | + GroupKey groupKey1 = new DefaultGroupKey("abc".getBytes()); | ||
74 | + GroupKey groupKey2 = new DefaultGroupKey("def".getBytes()); | ||
75 | + | ||
76 | + TrafficTreatment treatment = | ||
77 | + DefaultTrafficTreatment.emptyTreatment(); | ||
78 | + GroupBucket selectGroupBucket = | ||
79 | + DefaultGroupBucket.createSelectGroupBucket(treatment); | ||
80 | + GroupBucket failoverGroupBucket = | ||
81 | + DefaultGroupBucket.createFailoverGroupBucket(treatment, | ||
82 | + PortNumber.IN_PORT, groupId1); | ||
83 | + | ||
84 | + GroupBuckets buckets = new GroupBuckets(ImmutableList.of(selectGroupBucket)); | ||
85 | + GroupDescription groupDescription1 = new DefaultGroupDescription( | ||
86 | + deviceId1, | ||
87 | + GroupDescription.Type.INDIRECT, | ||
88 | + buckets, | ||
89 | + groupKey1, | ||
90 | + groupId1.id(), | ||
91 | + APP_ID); | ||
92 | + GroupDescription groupDescription2 = new DefaultGroupDescription( | ||
93 | + deviceId2, | ||
94 | + GroupDescription.Type.INDIRECT, | ||
95 | + buckets, | ||
96 | + groupKey2, | ||
97 | + groupId2.id(), | ||
98 | + APP_ID); | ||
99 | + | ||
100 | + DistributedGroupStore groupStoreImpl; | ||
101 | + GroupStore groupStore; | ||
102 | + EventuallyConsistentMap auditPendingReqQueue; | ||
103 | + | ||
104 | + static class MasterOfAll extends MastershipServiceAdapter { | ||
105 | + @Override | ||
106 | + public MastershipRole getLocalRole(DeviceId deviceId) { | ||
107 | + return MastershipRole.MASTER; | ||
108 | + } | ||
109 | + } | ||
110 | + | ||
111 | + @Before | ||
112 | + public void setUp() throws Exception { | ||
113 | + groupStoreImpl = new DistributedGroupStore(); | ||
114 | + groupStoreImpl.storageService = new TestStorageService(); | ||
115 | + groupStoreImpl.clusterCommunicator = new ClusterCommunicationServiceAdapter(); | ||
116 | + groupStoreImpl.mastershipService = new MasterOfAll(); | ||
117 | + groupStoreImpl.activate(); | ||
118 | + groupStore = groupStoreImpl; | ||
119 | + auditPendingReqQueue = | ||
120 | + TestUtils.getField(groupStoreImpl, "auditPendingReqQueue"); | ||
121 | + } | ||
122 | + | ||
123 | + @After | ||
124 | + public void tearDown() throws Exception { | ||
125 | + groupStoreImpl.deactivate(); | ||
126 | + } | ||
127 | + | ||
128 | + /** | ||
129 | + * Tests the initial state of the store. | ||
130 | + */ | ||
131 | + @Test | ||
132 | + public void testEmptyStore() { | ||
133 | + assertThat(groupStore.getGroupCount(deviceId1), is(0)); | ||
134 | + assertThat(groupStore.getGroup(deviceId1, groupId1), nullValue()); | ||
135 | + assertThat(groupStore.getGroup(deviceId1, groupKey1), nullValue()); | ||
136 | + } | ||
137 | + | ||
138 | + /** | ||
139 | + * Tests adding a pending group. | ||
140 | + */ | ||
141 | + @Test | ||
142 | + public void testAddPendingGroup() throws Exception { | ||
143 | + // Make sure the pending list starts out empty | ||
144 | + assertThat(auditPendingReqQueue.size(), is(0)); | ||
145 | + | ||
146 | + // Add a new pending group. Make sure that the store remains empty | ||
147 | + groupStore.storeGroupDescription(groupDescription1); | ||
148 | + assertThat(groupStore.getGroupCount(deviceId1), is(0)); | ||
149 | + assertThat(groupStore.getGroup(deviceId1, groupId1), nullValue()); | ||
150 | + assertThat(groupStore.getGroup(deviceId1, groupKey1), nullValue()); | ||
151 | + | ||
152 | + // Make sure the group is pending | ||
153 | + assertThat(auditPendingReqQueue.size(), is(1)); | ||
154 | + | ||
155 | + groupStore.deviceInitialAuditCompleted(deviceId1, true); | ||
156 | + | ||
157 | + // Make sure the group isn't pending anymore | ||
158 | + assertThat(auditPendingReqQueue.size(), is(0)); | ||
159 | + } | ||
160 | + | ||
161 | + | ||
162 | + /** | ||
163 | + * Tests adding and removing a group. | ||
164 | + */ | ||
165 | + @Test | ||
166 | + public void testAddRemoveGroup() throws Exception { | ||
167 | + groupStore.deviceInitialAuditCompleted(deviceId1, true); | ||
168 | + assertThat(groupStore.deviceInitialAuditStatus(deviceId1), is(true)); | ||
169 | + | ||
170 | + // Make sure the pending list starts out empty | ||
171 | + assertThat(auditPendingReqQueue.size(), is(0)); | ||
172 | + | ||
173 | + groupStore.storeGroupDescription(groupDescription1); | ||
174 | + assertThat(groupStore.getGroupCount(deviceId1), is(1)); | ||
175 | + assertThat(groupStore.getGroup(deviceId1, groupId1), notNullValue()); | ||
176 | + assertThat(groupStore.getGroup(deviceId1, groupKey1), notNullValue()); | ||
177 | + | ||
178 | + // Make sure that nothing is pending | ||
179 | + assertThat(auditPendingReqQueue.size(), is(0)); | ||
180 | + | ||
181 | + Group groupById = groupStore.getGroup(deviceId1, groupId1); | ||
182 | + Group groupByKey = groupStore.getGroup(deviceId1, groupKey1); | ||
183 | + assertThat(groupById, notNullValue()); | ||
184 | + assertThat(groupByKey, notNullValue()); | ||
185 | + assertThat(groupById, is(groupByKey)); | ||
186 | + assertThat(groupById.deviceId(), is(did("dev1"))); | ||
187 | + | ||
188 | + groupStore.removeGroupEntry(groupById); | ||
189 | + | ||
190 | + assertThat(groupStore.getGroupCount(deviceId1), is(0)); | ||
191 | + assertThat(groupStore.getGroup(deviceId1, groupId1), nullValue()); | ||
192 | + assertThat(groupStore.getGroup(deviceId1, groupKey1), nullValue()); | ||
193 | + | ||
194 | + // Make sure that nothing is pending | ||
195 | + assertThat(auditPendingReqQueue.size(), is(0)); | ||
196 | + } | ||
197 | + | ||
198 | + /** | ||
199 | + * Tests adding and removing a group. | ||
200 | + */ | ||
201 | + @Test | ||
202 | + public void testRemoveGroupDescription() throws Exception { | ||
203 | + groupStore.deviceInitialAuditCompleted(deviceId1, true); | ||
204 | + | ||
205 | + groupStore.storeGroupDescription(groupDescription1); | ||
206 | + | ||
207 | + groupStore.deleteGroupDescription(deviceId1, groupKey1); | ||
208 | + | ||
209 | + // Group should still be there, marked for removal | ||
210 | + assertThat(groupStore.getGroupCount(deviceId1), is(1)); | ||
211 | + Group queriedGroup = groupStore.getGroup(deviceId1, groupId1); | ||
212 | + assertThat(queriedGroup.state(), is(Group.GroupState.PENDING_DELETE)); | ||
213 | + | ||
214 | + } | ||
215 | + | ||
216 | + /** | ||
217 | + * Tests pushing group metrics. | ||
218 | + */ | ||
219 | + @Test | ||
220 | + public void testPushGroupMetrics() { | ||
221 | + groupStore.deviceInitialAuditCompleted(deviceId1, true); | ||
222 | + groupStore.deviceInitialAuditCompleted(deviceId2, true); | ||
223 | + | ||
224 | + GroupDescription groupDescription3 = new DefaultGroupDescription( | ||
225 | + deviceId1, | ||
226 | + GroupDescription.Type.SELECT, | ||
227 | + buckets, | ||
228 | + new DefaultGroupKey("aaa".getBytes()), | ||
229 | + null, | ||
230 | + APP_ID); | ||
231 | + | ||
232 | + groupStore.storeGroupDescription(groupDescription1); | ||
233 | + groupStore.storeGroupDescription(groupDescription2); | ||
234 | + groupStore.storeGroupDescription(groupDescription3); | ||
235 | + Group group1 = groupStore.getGroup(deviceId1, groupId1); | ||
236 | + | ||
237 | + assertThat(group1, instanceOf(DefaultGroup.class)); | ||
238 | + DefaultGroup defaultGroup1 = (DefaultGroup) group1; | ||
239 | + defaultGroup1.setPackets(55L); | ||
240 | + defaultGroup1.setBytes(66L); | ||
241 | + groupStore.pushGroupMetrics(deviceId1, ImmutableList.of(group1)); | ||
242 | + | ||
243 | + // Make sure the group was updated. | ||
244 | + | ||
245 | + Group requeryGroup1 = groupStore.getGroup(deviceId1, groupId1); | ||
246 | + assertThat(requeryGroup1.packets(), is(55L)); | ||
247 | + assertThat(requeryGroup1.bytes(), is(66L)); | ||
248 | + | ||
249 | + } | ||
250 | + | ||
251 | + class TestDelegate implements GroupStoreDelegate { | ||
252 | + private List<GroupEvent> eventsSeen = new LinkedList<>(); | ||
253 | + @Override | ||
254 | + public void notify(GroupEvent event) { | ||
255 | + eventsSeen.add(event); | ||
256 | + } | ||
257 | + | ||
258 | + public List<GroupEvent> eventsSeen() { | ||
259 | + return eventsSeen; | ||
260 | + } | ||
261 | + | ||
262 | + public void resetEvents() { | ||
263 | + eventsSeen.clear(); | ||
264 | + } | ||
265 | + } | ||
266 | + | ||
267 | + /** | ||
268 | + * Tests group operation failed interface. | ||
269 | + */ | ||
270 | + @Test | ||
271 | + public void testGroupOperationFailed() { | ||
272 | + TestDelegate delegate = new TestDelegate(); | ||
273 | + groupStore.setDelegate(delegate); | ||
274 | + groupStore.deviceInitialAuditCompleted(deviceId1, true); | ||
275 | + groupStore.deviceInitialAuditCompleted(deviceId2, true); | ||
276 | + | ||
277 | + groupStore.storeGroupDescription(groupDescription1); | ||
278 | + groupStore.storeGroupDescription(groupDescription2); | ||
279 | + | ||
280 | + List<GroupEvent> eventsAfterAdds = delegate.eventsSeen(); | ||
281 | + assertThat(eventsAfterAdds, hasSize(2)); | ||
282 | + eventsAfterAdds.stream().forEach(event -> assertThat(event.type(), is(GroupEvent.Type.GROUP_ADD_REQUESTED))); | ||
283 | + delegate.resetEvents(); | ||
284 | + | ||
285 | + GroupOperation opAdd = | ||
286 | + GroupOperation.createAddGroupOperation(groupId1, | ||
287 | + GroupDescription.Type.INDIRECT, | ||
288 | + buckets); | ||
289 | + groupStore.groupOperationFailed(deviceId1, opAdd); | ||
290 | + | ||
291 | + List<GroupEvent> eventsAfterAddFailed = delegate.eventsSeen(); | ||
292 | + assertThat(eventsAfterAddFailed, hasSize(2)); | ||
293 | + assertThat(eventsAfterAddFailed.get(0).type(), | ||
294 | + is(GroupEvent.Type.GROUP_ADD_FAILED)); | ||
295 | + assertThat(eventsAfterAddFailed.get(1).type(), | ||
296 | + is(GroupEvent.Type.GROUP_REMOVED)); | ||
297 | + delegate.resetEvents(); | ||
298 | + | ||
299 | + GroupOperation opModify = | ||
300 | + GroupOperation.createModifyGroupOperation(groupId2, | ||
301 | + GroupDescription.Type.INDIRECT, | ||
302 | + buckets); | ||
303 | + groupStore.groupOperationFailed(deviceId2, opModify); | ||
304 | + List<GroupEvent> eventsAfterModifyFailed = delegate.eventsSeen(); | ||
305 | + assertThat(eventsAfterModifyFailed, hasSize(1)); | ||
306 | + assertThat(eventsAfterModifyFailed.get(0).type(), | ||
307 | + is(GroupEvent.Type.GROUP_UPDATE_FAILED)); | ||
308 | + delegate.resetEvents(); | ||
309 | + | ||
310 | + GroupOperation opDelete = | ||
311 | + GroupOperation.createDeleteGroupOperation(groupId2, | ||
312 | + GroupDescription.Type.INDIRECT); | ||
313 | + groupStore.groupOperationFailed(deviceId2, opDelete); | ||
314 | + List<GroupEvent> eventsAfterDeleteFailed = delegate.eventsSeen(); | ||
315 | + assertThat(eventsAfterDeleteFailed, hasSize(1)); | ||
316 | + assertThat(eventsAfterDeleteFailed.get(0).type(), | ||
317 | + is(GroupEvent.Type.GROUP_REMOVE_FAILED)); | ||
318 | + delegate.resetEvents(); | ||
319 | + } | ||
320 | + | ||
321 | + /** | ||
322 | + * Tests extraneous group operations. | ||
323 | + */ | ||
324 | + @Test | ||
325 | + public void testExtraneousOperations() { | ||
326 | + ArrayList<Group> extraneous; | ||
327 | + groupStore.deviceInitialAuditCompleted(deviceId1, true); | ||
328 | + | ||
329 | + groupStore.storeGroupDescription(groupDescription1); | ||
330 | + Group group1 = groupStore.getGroup(deviceId1, groupId1); | ||
331 | + | ||
332 | + extraneous = Lists.newArrayList(groupStore.getExtraneousGroups(deviceId1)); | ||
333 | + assertThat(extraneous, hasSize(0)); | ||
334 | + | ||
335 | + groupStore.addOrUpdateExtraneousGroupEntry(group1); | ||
336 | + extraneous = Lists.newArrayList(groupStore.getExtraneousGroups(deviceId1)); | ||
337 | + assertThat(extraneous, hasSize(1)); | ||
338 | + | ||
339 | + groupStore.removeExtraneousGroupEntry(group1); | ||
340 | + extraneous = Lists.newArrayList(groupStore.getExtraneousGroups(deviceId1)); | ||
341 | + assertThat(extraneous, hasSize(0)); | ||
342 | + } | ||
343 | + | ||
344 | + /** | ||
345 | + * Tests updating of group descriptions. | ||
346 | + */ | ||
347 | + @Test | ||
348 | + public void testUpdateGroupDescription() { | ||
349 | + | ||
350 | + GroupBuckets buckets = | ||
351 | + new GroupBuckets(ImmutableList.of(failoverGroupBucket)); | ||
352 | + | ||
353 | + groupStore.deviceInitialAuditCompleted(deviceId1, true); | ||
354 | + groupStore.storeGroupDescription(groupDescription1); | ||
355 | + | ||
356 | + GroupKey newKey = new DefaultGroupKey("123".getBytes()); | ||
357 | + groupStore.updateGroupDescription(deviceId1, | ||
358 | + groupKey1, | ||
359 | + GroupStore.UpdateType.ADD, | ||
360 | + buckets, | ||
361 | + newKey); | ||
362 | + Group group1 = groupStore.getGroup(deviceId1, groupId1); | ||
363 | + assertThat(group1.appCookie(), is(newKey)); | ||
364 | + assertThat(group1.buckets().buckets(), hasSize(2)); | ||
365 | + } | ||
366 | + | ||
367 | + @Test | ||
368 | + public void testEqualsGroupStoreIdMapKey() { | ||
369 | + DistributedGroupStore.GroupStoreIdMapKey key1 = | ||
370 | + new DistributedGroupStore.GroupStoreIdMapKey(deviceId1, groupId1); | ||
371 | + DistributedGroupStore.GroupStoreIdMapKey sameAsKey1 = | ||
372 | + new DistributedGroupStore.GroupStoreIdMapKey(deviceId1, groupId1); | ||
373 | + DistributedGroupStore.GroupStoreIdMapKey key2 = | ||
374 | + new DistributedGroupStore.GroupStoreIdMapKey(deviceId2, groupId1); | ||
375 | + DistributedGroupStore.GroupStoreIdMapKey key3 = | ||
376 | + new DistributedGroupStore.GroupStoreIdMapKey(deviceId1, groupId2); | ||
377 | + | ||
378 | + new EqualsTester() | ||
379 | + .addEqualityGroup(key1, sameAsKey1) | ||
380 | + .addEqualityGroup(key2) | ||
381 | + .addEqualityGroup(key3) | ||
382 | + .testEquals(); | ||
383 | + } | ||
384 | + | ||
385 | + @Test | ||
386 | + public void testEqualsGroupStoreKeyMapKey() { | ||
387 | + DistributedGroupStore.GroupStoreKeyMapKey key1 = | ||
388 | + new DistributedGroupStore.GroupStoreKeyMapKey(deviceId1, groupKey1); | ||
389 | + DistributedGroupStore.GroupStoreKeyMapKey sameAsKey1 = | ||
390 | + new DistributedGroupStore.GroupStoreKeyMapKey(deviceId1, groupKey1); | ||
391 | + DistributedGroupStore.GroupStoreKeyMapKey key2 = | ||
392 | + new DistributedGroupStore.GroupStoreKeyMapKey(deviceId2, groupKey1); | ||
393 | + DistributedGroupStore.GroupStoreKeyMapKey key3 = | ||
394 | + new DistributedGroupStore.GroupStoreKeyMapKey(deviceId1, groupKey2); | ||
395 | + | ||
396 | + new EqualsTester() | ||
397 | + .addEqualityGroup(key1, sameAsKey1) | ||
398 | + .addEqualityGroup(key2) | ||
399 | + .addEqualityGroup(key3) | ||
400 | + .testEquals(); | ||
401 | + } | ||
402 | + | ||
403 | + @Test | ||
404 | + public void testEqualsGroupStoreMapKey() { | ||
405 | + DistributedGroupStore.GroupStoreMapKey key1 = | ||
406 | + new DistributedGroupStore.GroupStoreMapKey(deviceId1); | ||
407 | + DistributedGroupStore.GroupStoreMapKey sameAsKey1 = | ||
408 | + new DistributedGroupStore.GroupStoreMapKey(deviceId1); | ||
409 | + DistributedGroupStore.GroupStoreMapKey key2 = | ||
410 | + new DistributedGroupStore.GroupStoreMapKey(deviceId2); | ||
411 | + DistributedGroupStore.GroupStoreMapKey key3 = | ||
412 | + new DistributedGroupStore.GroupStoreMapKey(did("dev3")); | ||
413 | + | ||
414 | + new EqualsTester() | ||
415 | + .addEqualityGroup(key1, sameAsKey1) | ||
416 | + .addEqualityGroup(key2) | ||
417 | + .addEqualityGroup(key3) | ||
418 | + .testEquals(); | ||
419 | + } | ||
420 | +} |
-
Please register or login to post a comment