blob: 60261d69cddd19b8c6883c5c32ca0f2cfd90d5ef [file] [log] [blame]
Jon Hallfa132292017-10-24 11:11:24 -07001/*
2 * Copyright 2016-present Open Networking Foundation
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 */
16package org.onosproject.store.flow.impl;
17
18import com.google.common.collect.ArrayListMultimap;
Jordan Halterman281dbf32018-06-15 17:46:28 -070019import com.google.common.collect.ImmutableMap;
Jon Hallfa132292017-10-24 11:11:24 -070020import com.google.common.collect.Multimap;
21import org.junit.After;
22import org.junit.Before;
23import org.junit.Test;
24
Jordan Haltermane458f002018-09-18 17:42:05 -070025import org.onlab.packet.IpAddress;
Jon Hallfa132292017-10-24 11:11:24 -070026import org.onosproject.cfg.ComponentConfigAdapter;
27import org.onosproject.cluster.NodeId;
28import org.onosproject.cluster.ClusterService;
29import org.onosproject.cluster.ControllerNode;
30import org.onosproject.core.CoreServiceAdapter;
Jordan Halterman281dbf32018-06-15 17:46:28 -070031import org.onosproject.mastership.MastershipInfo;
Jon Hallfa132292017-10-24 11:11:24 -070032import org.onosproject.mastership.MastershipServiceAdapter;
33import org.onosproject.net.device.DeviceServiceAdapter;
34import org.onosproject.net.DeviceId;
35import org.onosproject.net.MastershipRole;
36import org.onosproject.net.flow.FlowRuleOperation;
37import org.onosproject.net.flow.FlowRule;
38import org.onosproject.net.flow.oldbatch.FlowRuleBatchEntry;
39import org.onosproject.net.flow.DefaultFlowEntry;
40import org.onosproject.net.flow.FlowEntry;
41import org.onosproject.net.flow.DefaultFlowRule;
42import org.onosproject.net.flow.oldbatch.FlowRuleBatchOperation;
43import org.onosproject.net.intent.IntentTestsMocks;
44import org.onosproject.store.cluster.messaging.ClusterCommunicationServiceAdapter;
45import org.onosproject.store.persistence.PersistenceServiceAdapter;
Jordan Halterman281dbf32018-06-15 17:46:28 -070046import org.onosproject.store.service.AsyncConsistentMap;
47import org.onosproject.store.service.AsyncConsistentMapAdapter;
48import org.onosproject.store.service.ConsistentMap;
49import org.onosproject.store.service.ConsistentMapBuilder;
Jon Hallfa132292017-10-24 11:11:24 -070050import org.onosproject.store.service.TestStorageService;
51
52import org.onlab.packet.Ip4Address;
Jordan Halterman281dbf32018-06-15 17:46:28 -070053import java.util.Optional;
54
Jon Hallfa132292017-10-24 11:11:24 -070055import org.osgi.service.component.ComponentContext;
56
57import static org.easymock.EasyMock.createMock;
58import static org.easymock.EasyMock.expect;
59import static org.easymock.EasyMock.replay;
60import static org.hamcrest.MatcherAssert.assertThat;
61import static org.hamcrest.Matchers.emptyIterable;
62import static org.hamcrest.Matchers.is;
63import static org.hamcrest.Matchers.notNullValue;
64import static org.junit.Assert.assertEquals;
65import static org.onosproject.net.NetTestTools.APP_ID;
Daniele Moro43ac2892021-07-15 17:02:59 +020066import static org.onosproject.net.NetTestTools.APP_ID_2;
Jon Hallfa132292017-10-24 11:11:24 -070067import static org.onosproject.net.NetTestTools.did;
68
69/**
70 * Test class for ECFlowRuleStore.
71 */
72public class ECFlowRuleStoreTest {
73
74 ECFlowRuleStore flowStoreImpl;
75 ComponentContext context = null;
76 private ClusterService mockClusterService;
77 private ControllerNode mockControllerNode;
78
79 private NodeId nodeId;
80
81 private static final IntentTestsMocks.MockSelector SELECTOR =
82 new IntentTestsMocks.MockSelector();
83 private static final IntentTestsMocks.MockTreatment TREATMENT =
84 new IntentTestsMocks.MockTreatment();
85 DeviceId deviceId = did("device1");
Daniele Moro43ac2892021-07-15 17:02:59 +020086 DeviceId deviceId2 = did("device2");
Jon Hallfa132292017-10-24 11:11:24 -070087 FlowRule flowRule =
88 DefaultFlowRule.builder()
89 .forDevice(deviceId)
90 .withSelector(SELECTOR)
91 .withTreatment(TREATMENT)
92 .withPriority(22)
93 .makeTemporary(44)
94 .fromApp(APP_ID)
95 .build();
96 FlowRule flowRule1 =
97 DefaultFlowRule.builder()
98 .forDevice(deviceId)
99 .withSelector(SELECTOR)
100 .withTreatment(TREATMENT)
101 .withPriority(33)
102 .makeTemporary(44)
103 .fromApp(APP_ID)
104 .build();
Daniele Moro43ac2892021-07-15 17:02:59 +0200105 FlowRule flowRule2 =
106 DefaultFlowRule.builder()
107 .forDevice(deviceId)
108 .withSelector(SELECTOR)
109 .withTreatment(TREATMENT)
110 .withPriority(44)
111 .makePermanent()
112 .fromApp(APP_ID_2)
113 .build();
114 FlowRule flowRule3 =
115 DefaultFlowRule.builder()
116 .forDevice(deviceId2)
117 .withSelector(SELECTOR)
118 .withTreatment(TREATMENT)
119 .withPriority(55)
120 .makePermanent()
121 .fromApp(APP_ID_2)
122 .build();
123
Jon Hallfa132292017-10-24 11:11:24 -0700124
125 static class MasterOfAll extends MastershipServiceAdapter {
126 @Override
127 public MastershipRole getLocalRole(DeviceId deviceId) {
128 return MastershipRole.MASTER;
129 }
130
131 @Override
132 public NodeId getMasterFor(DeviceId deviceId) {
133 return new NodeId("1");
134 }
Jordan Halterman281dbf32018-06-15 17:46:28 -0700135
136 @Override
137 public MastershipInfo getMastershipFor(DeviceId deviceId) {
138 return new MastershipInfo(
139 1,
140 Optional.of(NodeId.nodeId("1")),
141 ImmutableMap.<NodeId, MastershipRole>builder()
142 .put(NodeId.nodeId("1"), MastershipRole.MASTER)
143 .build());
144 }
Jon Hallfa132292017-10-24 11:11:24 -0700145 }
146
147
148 private static class MockControllerNode implements ControllerNode {
149 final NodeId id;
150
151 public MockControllerNode(NodeId id) {
152 this.id = id;
153 }
154
155 @Override
156 public NodeId id() {
157 return this.id;
158 }
159
160 @Override
Jordan Haltermane458f002018-09-18 17:42:05 -0700161 public String host() {
162 return "127.0.0.1";
163 }
164
165 @Override
Jon Hallfa132292017-10-24 11:11:24 -0700166 public Ip4Address ip() {
167 return Ip4Address.valueOf("127.0.0.1");
168 }
169
170 @Override
Jordan Haltermane458f002018-09-18 17:42:05 -0700171 public IpAddress ip(boolean resolve) {
172 return ip();
173 }
174
175 @Override
Jon Hallfa132292017-10-24 11:11:24 -0700176 public int tcpPort() {
177 return 0;
178 }
179 }
180
181 @Before
182 public void setUp() throws Exception {
183 flowStoreImpl = new ECFlowRuleStore();
Jordan Halterman281dbf32018-06-15 17:46:28 -0700184 flowStoreImpl.storageService = new TestStorageService() {
185 @Override
186 public <K, V> ConsistentMapBuilder<K, V> consistentMapBuilder() {
187 return new ConsistentMapBuilder<K, V>() {
188 @Override
189 public AsyncConsistentMap<K, V> buildAsyncMap() {
190 return new AsyncConsistentMapAdapter<K, V>();
191 }
192
193 @Override
194 public ConsistentMap<K, V> build() {
195 return null;
196 }
197 };
198 }
199 };
200
201 ReplicaInfoManager replicaInfoManager = new ReplicaInfoManager();
202 replicaInfoManager.mastershipService = new MasterOfAll();
203
204 flowStoreImpl.replicaInfoManager = replicaInfoManager;
Jon Hallfa132292017-10-24 11:11:24 -0700205 mockClusterService = createMock(ClusterService.class);
206 flowStoreImpl.clusterService = mockClusterService;
207 nodeId = new NodeId("1");
208 mockControllerNode = new MockControllerNode(nodeId);
209
210 expect(mockClusterService.getLocalNode())
211 .andReturn(mockControllerNode).anyTimes();
212 replay(mockClusterService);
213
214 flowStoreImpl.clusterCommunicator = new ClusterCommunicationServiceAdapter();
215 flowStoreImpl.mastershipService = new MasterOfAll();
216 flowStoreImpl.deviceService = new DeviceServiceAdapter();
217 flowStoreImpl.coreService = new CoreServiceAdapter();
218 flowStoreImpl.configService = new ComponentConfigAdapter();
219 flowStoreImpl.persistenceService = new PersistenceServiceAdapter();
220 flowStoreImpl.activate(context);
221 }
222
223 @After
224 public void tearDown() throws Exception {
225 flowStoreImpl.deactivate(context);
226 }
227
228 /**
229 * Tests the initial state of the store.
230 */
231 @Test
232 public void testEmptyStore() {
233 assertThat(flowStoreImpl.getFlowRuleCount(), is(0));
234 assertThat(flowStoreImpl.getFlowEntries(deviceId), is(emptyIterable()));
235 }
236
237 /**
238 * Tests initial state of flowrule.
239 */
240 @Test
241 public void testStoreBatch() {
242 FlowRuleOperation op = new FlowRuleOperation(flowRule, FlowRuleOperation.Type.ADD);
243 Multimap<DeviceId, FlowRuleBatchEntry> perDeviceBatches = ArrayListMultimap.create();
244 perDeviceBatches.put(op.rule().deviceId(),
245 new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.ADD, op.rule()));
246 FlowRuleBatchOperation b = new FlowRuleBatchOperation(perDeviceBatches.get(deviceId),
247 deviceId, 1);
248 flowStoreImpl.storeBatch(b);
249 FlowEntry flowEntry1 = flowStoreImpl.getFlowEntry(flowRule);
250 assertEquals("PENDING_ADD", flowEntry1.state().toString());
251 }
252
253 /**
254 * Tests adding a flowrule.
255 */
256 @Test
257 public void testAddFlow() {
258 FlowEntry flowEntry = new DefaultFlowEntry(flowRule);
259 FlowRuleOperation op = new FlowRuleOperation(flowRule, FlowRuleOperation.Type.ADD);
260 Multimap<DeviceId, FlowRuleBatchEntry> perDeviceBatches = ArrayListMultimap.create();
261 perDeviceBatches.put(op.rule().deviceId(),
262 new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.ADD, op.rule()));
263 FlowRuleBatchOperation b = new FlowRuleBatchOperation(perDeviceBatches.get(deviceId),
264 deviceId, 1);
265 flowStoreImpl.storeBatch(b);
266 FlowEntry flowEntry1 = flowStoreImpl.getFlowEntry(flowRule);
267 assertEquals("PENDING_ADD", flowEntry1.state().toString());
268
269 flowStoreImpl.addOrUpdateFlowRule(flowEntry);
Daniele Moro43ac2892021-07-15 17:02:59 +0200270 assertFlowsOnDevice(deviceId, 1);
Jon Hallfa132292017-10-24 11:11:24 -0700271
272 FlowEntry flowEntry2 = flowStoreImpl.getFlowEntry(flowRule);
273 assertEquals("ADDED", flowEntry2.state().toString());
274 assertThat(flowStoreImpl.getTableStatistics(deviceId), notNullValue());
275 }
276
277 /**
278 * Tests flow removal.
279 */
280 @Test
281 public void testRemoveFlow() {
282 Iterable<FlowEntry> flows1 = flowStoreImpl.getFlowEntries(deviceId);
283 for (FlowEntry flow : flows1) {
284 flowStoreImpl.removeFlowRule(flow);
285 }
Daniele Moro43ac2892021-07-15 17:02:59 +0200286 assertFlowsOnDevice(deviceId, 0);
Jon Hallfa132292017-10-24 11:11:24 -0700287 }
288
289 /**
290 * Tests purge flow for a device.
291 */
292 @Test
293 public void testPurgeFlow() {
294 FlowEntry flowEntry = new DefaultFlowEntry(flowRule);
295 flowStoreImpl.addOrUpdateFlowRule(flowEntry);
296
297 FlowEntry flowEntry1 = new DefaultFlowEntry(flowRule1);
298 flowStoreImpl.addOrUpdateFlowRule(flowEntry1);
Daniele Moro43ac2892021-07-15 17:02:59 +0200299 assertFlowsOnDevice(deviceId, 2);
Jon Hallfa132292017-10-24 11:11:24 -0700300 flowStoreImpl.purgeFlowRule(deviceId);
301
Daniele Moro43ac2892021-07-15 17:02:59 +0200302 assertFlowsOnDevice(deviceId, 0);
303 }
304
305 /**
306 * Tests purge flow for a device and an application.
307 */
308 @Test
309 public void testPurgeFlowAppId() {
310 FlowEntry flowEntry1 = new DefaultFlowEntry(flowRule1);
311 flowStoreImpl.addOrUpdateFlowRule(flowEntry1);
312
313 FlowEntry flowEntry2 = new DefaultFlowEntry(flowRule2);
314 flowStoreImpl.addOrUpdateFlowRule(flowEntry2);
315
316 FlowEntry flowEntry3 = new DefaultFlowEntry(flowRule3);
317 flowStoreImpl.addOrUpdateFlowRule(flowEntry3);
318
319 assertFlowsOnDevice(deviceId, 2);
320 assertFlowsOnDevice(deviceId2, 1);
321
322 flowStoreImpl.purgeFlowRules(deviceId, APP_ID_2);
323
324 assertFlowsOnDevice(deviceId, 1);
325 assertFlowsOnDevice(deviceId2, 1);
326 }
327
328 private void assertFlowsOnDevice(DeviceId deviceId, int nFlows) {
329 Iterable<FlowEntry> flows1 = flowStoreImpl.getFlowEntries(deviceId);
330 int sum1 = 0;
331 for (FlowEntry flowEntry : flows1) {
332 sum1++;
Jon Hallfa132292017-10-24 11:11:24 -0700333 }
Daniele Moro43ac2892021-07-15 17:02:59 +0200334 assertThat(sum1, is(nFlows));
Jon Hallfa132292017-10-24 11:11:24 -0700335 }
336}