blob: d49f1ccf8cb0b3524827aa2c245847acf671cef0 [file] [log] [blame]
sivachidambaram subramanian5168f612017-03-08 13:53:30 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
sivachidambaram subramanian5168f612017-03-08 13:53:30 +05303 *
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
Jordan Haltermanf7554092017-07-30 15:05:51 -070018import java.util.Collections;
19import java.util.Iterator;
20
sivachidambaram subramanian5168f612017-03-08 13:53:30 +053021import com.google.common.collect.ArrayListMultimap;
22import com.google.common.collect.Multimap;
23import org.junit.After;
24import org.junit.Before;
25import org.junit.Test;
Jordan Haltermanf7554092017-07-30 15:05:51 -070026import org.onlab.packet.Ip4Address;
sivachidambaram subramanian5168f612017-03-08 13:53:30 +053027import org.onosproject.cluster.ClusterService;
28import org.onosproject.cluster.ControllerNode;
Jordan Haltermanf7554092017-07-30 15:05:51 -070029import org.onosproject.cluster.NodeId;
sivachidambaram subramanian5168f612017-03-08 13:53:30 +053030import org.onosproject.core.CoreServiceAdapter;
31import org.onosproject.mastership.MastershipServiceAdapter;
sivachidambaram subramanian5168f612017-03-08 13:53:30 +053032import org.onosproject.net.DeviceId;
33import org.onosproject.net.MastershipRole;
Jordan Haltermanf7554092017-07-30 15:05:51 -070034import org.onosproject.net.device.DeviceServiceAdapter;
35import org.onosproject.net.flow.DefaultFlowEntry;
36import org.onosproject.net.flow.DefaultFlowRule;
37import org.onosproject.net.flow.FlowEntry;
sivachidambaram subramanian5168f612017-03-08 13:53:30 +053038import org.onosproject.net.flow.FlowRule;
39import org.onosproject.net.flow.FlowRuleBatchEntry;
sivachidambaram subramanian5168f612017-03-08 13:53:30 +053040import org.onosproject.net.flow.FlowRuleBatchOperation;
Jordan Haltermanf7554092017-07-30 15:05:51 -070041import org.onosproject.net.flow.FlowRuleOperation;
sivachidambaram subramanian5168f612017-03-08 13:53:30 +053042import org.onosproject.net.intent.IntentTestsMocks;
43import org.onosproject.store.cluster.messaging.ClusterCommunicationServiceAdapter;
Jordan Haltermanf7554092017-07-30 15:05:51 -070044import org.onosproject.store.service.AsyncDocumentTree;
45import org.onosproject.store.service.AsyncDocumentTreeAdapter;
46import org.onosproject.store.service.DocumentTree;
47import org.onosproject.store.service.DocumentTreeBuilder;
48import org.onosproject.store.service.Serializer;
49import org.onosproject.store.service.TestDocumentTree;
sivachidambaram subramanian5168f612017-03-08 13:53:30 +053050import org.onosproject.store.service.TestStorageService;
Jordan Haltermanf7554092017-07-30 15:05:51 -070051import org.onosproject.store.service.TestTopic;
52import org.onosproject.store.service.Topic;
sivachidambaram subramanian5168f612017-03-08 13:53:30 +053053
54import static org.easymock.EasyMock.createMock;
55import static org.easymock.EasyMock.expect;
56import static org.easymock.EasyMock.replay;
57import static org.hamcrest.MatcherAssert.assertThat;
58import static org.hamcrest.Matchers.emptyIterable;
59import static org.hamcrest.Matchers.is;
60import static org.hamcrest.Matchers.notNullValue;
61import static org.junit.Assert.assertEquals;
62import static org.onosproject.net.NetTestTools.APP_ID;
63import static org.onosproject.net.NetTestTools.did;
64
65/**
66 * Test class for DistributedFlowRuleStore.
67 */
68public class DistributedFlowRuleStoreTest {
69
70 DistributedFlowRuleStore flowStoreImpl;
sivachidambaram subramanian5168f612017-03-08 13:53:30 +053071 private ClusterService mockClusterService;
72 private ControllerNode mockControllerNode;
73
74 private NodeId nodeId;
75
76 private static final IntentTestsMocks.MockSelector SELECTOR =
77 new IntentTestsMocks.MockSelector();
78 private static final IntentTestsMocks.MockTreatment TREATMENT =
79 new IntentTestsMocks.MockTreatment();
80 DeviceId deviceId = did("device1");
81 FlowRule flowRule =
82 DefaultFlowRule.builder()
83 .forDevice(deviceId)
84 .withSelector(SELECTOR)
85 .withTreatment(TREATMENT)
86 .withPriority(22)
87 .makeTemporary(44)
88 .fromApp(APP_ID)
89 .build();
90 FlowRule flowRule1 =
91 DefaultFlowRule.builder()
92 .forDevice(deviceId)
93 .withSelector(SELECTOR)
94 .withTreatment(TREATMENT)
95 .withPriority(33)
96 .makeTemporary(44)
97 .fromApp(APP_ID)
98 .build();
99
100 static class MasterOfAll extends MastershipServiceAdapter {
101 @Override
102 public MastershipRole getLocalRole(DeviceId deviceId) {
103 return MastershipRole.MASTER;
104 }
105
106 @Override
107 public NodeId getMasterFor(DeviceId deviceId) {
108 return new NodeId("1");
109 }
110 }
111
112
113 private static class MockControllerNode implements ControllerNode {
114 final NodeId id;
115
116 public MockControllerNode(NodeId id) {
117 this.id = id;
118 }
119
120 @Override
121 public NodeId id() {
122 return this.id;
123 }
124
125 @Override
126 public Ip4Address ip() {
127 return Ip4Address.valueOf("127.0.0.1");
128 }
129
130 @Override
131 public int tcpPort() {
132 return 0;
133 }
134 }
135
Jordan Haltermanf7554092017-07-30 15:05:51 -0700136 private static class MockStorageService extends TestStorageService {
137 @Override
138 public <V> DocumentTreeBuilder<V> documentTreeBuilder() {
139 return new DocumentTreeBuilder<V>() {
140 @Override
141 public AsyncDocumentTree<V> buildDocumentTree() {
142 return build();
143 }
144
145 @Override
146 @SuppressWarnings("unchecked")
147 public AsyncDocumentTree<V> build() {
148 String name = name();
149 return new AsyncDocumentTreeAdapter() {
150 @Override
151 public DocumentTree asDocumentTree() {
152 return new TestDocumentTree(name);
153 }
154 };
155 }
156 };
157 }
158
159 @Override
160 public <T> Topic<T> getTopic(String name, Serializer serializer) {
161 return new TestTopic<>(name);
162 }
163 }
164
sivachidambaram subramanian5168f612017-03-08 13:53:30 +0530165 @Before
166 public void setUp() throws Exception {
167 flowStoreImpl = new DistributedFlowRuleStore();
Jordan Haltermanf7554092017-07-30 15:05:51 -0700168 flowStoreImpl.storageService = new MockStorageService();
sivachidambaram subramanian5168f612017-03-08 13:53:30 +0530169 mockClusterService = createMock(ClusterService.class);
170 flowStoreImpl.clusterService = mockClusterService;
171 nodeId = new NodeId("1");
172 mockControllerNode = new MockControllerNode(nodeId);
173
174 expect(mockClusterService.getLocalNode())
175 .andReturn(mockControllerNode).anyTimes();
176 replay(mockClusterService);
177
178 flowStoreImpl.clusterCommunicator = new ClusterCommunicationServiceAdapter();
179 flowStoreImpl.mastershipService = new MasterOfAll();
180 flowStoreImpl.deviceService = new DeviceServiceAdapter();
181 flowStoreImpl.coreService = new CoreServiceAdapter();
Jordan Haltermanf7554092017-07-30 15:05:51 -0700182 flowStoreImpl.activate();
sivachidambaram subramanian5168f612017-03-08 13:53:30 +0530183 }
184
185 @After
186 public void tearDown() throws Exception {
Jordan Haltermanf7554092017-07-30 15:05:51 -0700187 flowStoreImpl.deactivate();
sivachidambaram subramanian5168f612017-03-08 13:53:30 +0530188 }
189
190 /**
191 * Tests the initial state of the store.
192 */
193 @Test
194 public void testEmptyStore() {
195 assertThat(flowStoreImpl.getFlowRuleCount(), is(0));
196 assertThat(flowStoreImpl.getFlowEntries(deviceId), is(emptyIterable()));
197 }
198
199 /**
200 * Tests initial state of flowrule.
201 */
202 @Test
203 public void testStoreBatch() {
204 FlowRuleOperation op = new FlowRuleOperation(flowRule, FlowRuleOperation.Type.ADD);
205 Multimap<DeviceId, FlowRuleBatchEntry> perDeviceBatches = ArrayListMultimap.create();
206 perDeviceBatches.put(op.rule().deviceId(),
207 new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.ADD, op.rule()));
208 FlowRuleBatchOperation b = new FlowRuleBatchOperation(perDeviceBatches.get(deviceId),
209 deviceId, 1);
210 flowStoreImpl.storeBatch(b);
211 FlowEntry flowEntry1 = flowStoreImpl.getFlowEntry(flowRule);
212 assertEquals("PENDING_ADD", flowEntry1.state().toString());
213 }
214
215 /**
216 * Tests adding a flowrule.
217 */
218 @Test
219 public void testAddFlow() {
220 FlowEntry flowEntry = new DefaultFlowEntry(flowRule);
221 FlowRuleOperation op = new FlowRuleOperation(flowRule, FlowRuleOperation.Type.ADD);
222 Multimap<DeviceId, FlowRuleBatchEntry> perDeviceBatches = ArrayListMultimap.create();
223 perDeviceBatches.put(op.rule().deviceId(),
224 new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.ADD, op.rule()));
225 FlowRuleBatchOperation b = new FlowRuleBatchOperation(perDeviceBatches.get(deviceId),
226 deviceId, 1);
227 flowStoreImpl.storeBatch(b);
228 FlowEntry flowEntry1 = flowStoreImpl.getFlowEntry(flowRule);
229 assertEquals("PENDING_ADD", flowEntry1.state().toString());
230
231 flowStoreImpl.addOrUpdateFlowRule(flowEntry);
232 Iterable<FlowEntry> flows = flowStoreImpl.getFlowEntries(deviceId);
233 int sum = 0;
234 Iterator it = flows.iterator();
235 while (it.hasNext()) {
236 it.next();
237 sum++;
238 }
239 assertThat(sum, is(1));
240
241 FlowEntry flowEntry2 = flowStoreImpl.getFlowEntry(flowRule);
242 assertEquals("ADDED", flowEntry2.state().toString());
243 assertThat(flowStoreImpl.getTableStatistics(deviceId), notNullValue());
244 }
245
246 /**
247 * Tests flow removal.
248 */
249 @Test
250 public void testRemoveFlow() {
251 Iterable<FlowEntry> flows1 = flowStoreImpl.getFlowEntries(deviceId);
252 for (FlowEntry flow : flows1) {
253 flowStoreImpl.removeFlowRule(flow);
254 }
255
256 Iterable<FlowEntry> flows2 = flowStoreImpl.getFlowEntries(deviceId);
257 int sum = 0;
258 Iterator it = flows2.iterator();
259 while (it.hasNext()) {
260 it.next();
261 sum++;
262 }
263 assertThat(sum, is(0));
264 }
265
266 /**
267 * Tests purge flow for a device.
268 */
269 @Test
270 public void testPurgeFlow() {
271 FlowEntry flowEntry = new DefaultFlowEntry(flowRule);
Jordan Haltermanf7554092017-07-30 15:05:51 -0700272 flowStoreImpl.storeBatch(new FlowRuleBatchOperation(
273 Collections.singletonList(new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.ADD, flowEntry)),
274 flowEntry.deviceId(), 1));
sivachidambaram subramanian5168f612017-03-08 13:53:30 +0530275
276 FlowEntry flowEntry1 = new DefaultFlowEntry(flowRule1);
Jordan Haltermanf7554092017-07-30 15:05:51 -0700277 flowStoreImpl.storeBatch(new FlowRuleBatchOperation(
278 Collections.singletonList(new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.ADD, flowEntry1)),
279 flowEntry1.deviceId(), 2));
280
sivachidambaram subramanian5168f612017-03-08 13:53:30 +0530281 Iterable<FlowEntry> flows1 = flowStoreImpl.getFlowEntries(deviceId);
282 int sum2 = 0;
283 Iterator it1 = flows1.iterator();
284 while (it1.hasNext()) {
285 it1.next();
286 sum2++;
287 }
288 assertThat(sum2, is(2));
289 flowStoreImpl.purgeFlowRule(deviceId);
290
291 Iterable<FlowEntry> flows3 = flowStoreImpl.getFlowEntries(deviceId);
292 int sum3 = 0;
293 Iterator it3 = flows3.iterator();
294 while (it3.hasNext()) {
295 it3.next();
296 sum3++;
297 }
298 assertThat(sum3, is(0));
299 }
300}