blob: 8144d2293f2225beeee214253b348f6877612aad [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 Haltermane0355ff2017-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 Haltermane0355ff2017-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 Haltermane0355ff2017-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 Haltermane0355ff2017-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 Haltermane0355ff2017-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 Haltermane0355ff2017-07-30 15:05:51 -070044import org.onosproject.store.service.AsyncDocumentTree;
Jordan Haltermane0355ff2017-07-30 15:05:51 -070045import org.onosproject.store.service.DocumentTreeBuilder;
46import org.onosproject.store.service.Serializer;
Jordan Haltermanb8925dc2017-08-25 15:12:54 -070047import org.onosproject.store.service.TestAsyncDocumentTree;
sivachidambaram subramanian5168f612017-03-08 13:53:30 +053048import org.onosproject.store.service.TestStorageService;
Jordan Haltermane0355ff2017-07-30 15:05:51 -070049import org.onosproject.store.service.TestTopic;
50import org.onosproject.store.service.Topic;
sivachidambaram subramanian5168f612017-03-08 13:53:30 +053051
52import static org.easymock.EasyMock.createMock;
53import static org.easymock.EasyMock.expect;
54import static org.easymock.EasyMock.replay;
55import static org.hamcrest.MatcherAssert.assertThat;
56import static org.hamcrest.Matchers.emptyIterable;
57import static org.hamcrest.Matchers.is;
58import static org.hamcrest.Matchers.notNullValue;
59import static org.junit.Assert.assertEquals;
60import static org.onosproject.net.NetTestTools.APP_ID;
61import static org.onosproject.net.NetTestTools.did;
62
63/**
64 * Test class for DistributedFlowRuleStore.
65 */
66public class DistributedFlowRuleStoreTest {
67
68 DistributedFlowRuleStore flowStoreImpl;
sivachidambaram subramanian5168f612017-03-08 13:53:30 +053069 private ClusterService mockClusterService;
70 private ControllerNode mockControllerNode;
71
72 private NodeId nodeId;
73
74 private static final IntentTestsMocks.MockSelector SELECTOR =
75 new IntentTestsMocks.MockSelector();
76 private static final IntentTestsMocks.MockTreatment TREATMENT =
77 new IntentTestsMocks.MockTreatment();
78 DeviceId deviceId = did("device1");
79 FlowRule flowRule =
80 DefaultFlowRule.builder()
81 .forDevice(deviceId)
82 .withSelector(SELECTOR)
83 .withTreatment(TREATMENT)
84 .withPriority(22)
85 .makeTemporary(44)
86 .fromApp(APP_ID)
87 .build();
88 FlowRule flowRule1 =
89 DefaultFlowRule.builder()
90 .forDevice(deviceId)
91 .withSelector(SELECTOR)
92 .withTreatment(TREATMENT)
93 .withPriority(33)
94 .makeTemporary(44)
95 .fromApp(APP_ID)
96 .build();
97
98 static class MasterOfAll extends MastershipServiceAdapter {
99 @Override
100 public MastershipRole getLocalRole(DeviceId deviceId) {
101 return MastershipRole.MASTER;
102 }
103
104 @Override
105 public NodeId getMasterFor(DeviceId deviceId) {
106 return new NodeId("1");
107 }
108 }
109
110
111 private static class MockControllerNode implements ControllerNode {
112 final NodeId id;
113
114 public MockControllerNode(NodeId id) {
115 this.id = id;
116 }
117
118 @Override
119 public NodeId id() {
120 return this.id;
121 }
122
123 @Override
124 public Ip4Address ip() {
125 return Ip4Address.valueOf("127.0.0.1");
126 }
127
128 @Override
129 public int tcpPort() {
130 return 0;
131 }
132 }
133
Jordan Haltermane0355ff2017-07-30 15:05:51 -0700134 private static class MockStorageService extends TestStorageService {
135 @Override
136 public <V> DocumentTreeBuilder<V> documentTreeBuilder() {
137 return new DocumentTreeBuilder<V>() {
138 @Override
139 public AsyncDocumentTree<V> buildDocumentTree() {
140 return build();
141 }
142
143 @Override
144 @SuppressWarnings("unchecked")
145 public AsyncDocumentTree<V> build() {
Jordan Haltermanb8925dc2017-08-25 15:12:54 -0700146 return new TestAsyncDocumentTree<>(name());
Jordan Haltermane0355ff2017-07-30 15:05:51 -0700147 }
148 };
149 }
150
151 @Override
152 public <T> Topic<T> getTopic(String name, Serializer serializer) {
153 return new TestTopic<>(name);
154 }
155 }
156
sivachidambaram subramanian5168f612017-03-08 13:53:30 +0530157 @Before
158 public void setUp() throws Exception {
159 flowStoreImpl = new DistributedFlowRuleStore();
Jordan Haltermane0355ff2017-07-30 15:05:51 -0700160 flowStoreImpl.storageService = new MockStorageService();
sivachidambaram subramanian5168f612017-03-08 13:53:30 +0530161 mockClusterService = createMock(ClusterService.class);
162 flowStoreImpl.clusterService = mockClusterService;
163 nodeId = new NodeId("1");
164 mockControllerNode = new MockControllerNode(nodeId);
165
166 expect(mockClusterService.getLocalNode())
167 .andReturn(mockControllerNode).anyTimes();
168 replay(mockClusterService);
169
170 flowStoreImpl.clusterCommunicator = new ClusterCommunicationServiceAdapter();
171 flowStoreImpl.mastershipService = new MasterOfAll();
172 flowStoreImpl.deviceService = new DeviceServiceAdapter();
173 flowStoreImpl.coreService = new CoreServiceAdapter();
Jordan Haltermane0355ff2017-07-30 15:05:51 -0700174 flowStoreImpl.activate();
sivachidambaram subramanian5168f612017-03-08 13:53:30 +0530175 }
176
177 @After
178 public void tearDown() throws Exception {
Jordan Haltermane0355ff2017-07-30 15:05:51 -0700179 flowStoreImpl.deactivate();
sivachidambaram subramanian5168f612017-03-08 13:53:30 +0530180 }
181
182 /**
183 * Tests the initial state of the store.
184 */
185 @Test
186 public void testEmptyStore() {
187 assertThat(flowStoreImpl.getFlowRuleCount(), is(0));
188 assertThat(flowStoreImpl.getFlowEntries(deviceId), is(emptyIterable()));
189 }
190
191 /**
192 * Tests initial state of flowrule.
193 */
194 @Test
195 public void testStoreBatch() {
196 FlowRuleOperation op = new FlowRuleOperation(flowRule, FlowRuleOperation.Type.ADD);
197 Multimap<DeviceId, FlowRuleBatchEntry> perDeviceBatches = ArrayListMultimap.create();
198 perDeviceBatches.put(op.rule().deviceId(),
199 new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.ADD, op.rule()));
200 FlowRuleBatchOperation b = new FlowRuleBatchOperation(perDeviceBatches.get(deviceId),
201 deviceId, 1);
202 flowStoreImpl.storeBatch(b);
203 FlowEntry flowEntry1 = flowStoreImpl.getFlowEntry(flowRule);
204 assertEquals("PENDING_ADD", flowEntry1.state().toString());
205 }
206
207 /**
208 * Tests adding a flowrule.
209 */
210 @Test
211 public void testAddFlow() {
212 FlowEntry flowEntry = new DefaultFlowEntry(flowRule);
213 FlowRuleOperation op = new FlowRuleOperation(flowRule, FlowRuleOperation.Type.ADD);
214 Multimap<DeviceId, FlowRuleBatchEntry> perDeviceBatches = ArrayListMultimap.create();
215 perDeviceBatches.put(op.rule().deviceId(),
216 new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.ADD, op.rule()));
217 FlowRuleBatchOperation b = new FlowRuleBatchOperation(perDeviceBatches.get(deviceId),
218 deviceId, 1);
219 flowStoreImpl.storeBatch(b);
220 FlowEntry flowEntry1 = flowStoreImpl.getFlowEntry(flowRule);
221 assertEquals("PENDING_ADD", flowEntry1.state().toString());
222
223 flowStoreImpl.addOrUpdateFlowRule(flowEntry);
224 Iterable<FlowEntry> flows = flowStoreImpl.getFlowEntries(deviceId);
225 int sum = 0;
226 Iterator it = flows.iterator();
227 while (it.hasNext()) {
228 it.next();
229 sum++;
230 }
231 assertThat(sum, is(1));
232
233 FlowEntry flowEntry2 = flowStoreImpl.getFlowEntry(flowRule);
234 assertEquals("ADDED", flowEntry2.state().toString());
235 assertThat(flowStoreImpl.getTableStatistics(deviceId), notNullValue());
236 }
237
238 /**
239 * Tests flow removal.
240 */
241 @Test
242 public void testRemoveFlow() {
243 Iterable<FlowEntry> flows1 = flowStoreImpl.getFlowEntries(deviceId);
244 for (FlowEntry flow : flows1) {
245 flowStoreImpl.removeFlowRule(flow);
246 }
247
248 Iterable<FlowEntry> flows2 = flowStoreImpl.getFlowEntries(deviceId);
249 int sum = 0;
250 Iterator it = flows2.iterator();
251 while (it.hasNext()) {
252 it.next();
253 sum++;
254 }
255 assertThat(sum, is(0));
256 }
257
258 /**
259 * Tests purge flow for a device.
260 */
261 @Test
262 public void testPurgeFlow() {
263 FlowEntry flowEntry = new DefaultFlowEntry(flowRule);
Jordan Haltermane0355ff2017-07-30 15:05:51 -0700264 flowStoreImpl.storeBatch(new FlowRuleBatchOperation(
265 Collections.singletonList(new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.ADD, flowEntry)),
266 flowEntry.deviceId(), 1));
sivachidambaram subramanian5168f612017-03-08 13:53:30 +0530267
268 FlowEntry flowEntry1 = new DefaultFlowEntry(flowRule1);
Jordan Haltermane0355ff2017-07-30 15:05:51 -0700269 flowStoreImpl.storeBatch(new FlowRuleBatchOperation(
270 Collections.singletonList(new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.ADD, flowEntry1)),
271 flowEntry1.deviceId(), 2));
272
sivachidambaram subramanian5168f612017-03-08 13:53:30 +0530273 Iterable<FlowEntry> flows1 = flowStoreImpl.getFlowEntries(deviceId);
274 int sum2 = 0;
275 Iterator it1 = flows1.iterator();
276 while (it1.hasNext()) {
277 it1.next();
278 sum2++;
279 }
280 assertThat(sum2, is(2));
281 flowStoreImpl.purgeFlowRule(deviceId);
282
283 Iterable<FlowEntry> flows3 = flowStoreImpl.getFlowEntries(deviceId);
284 int sum3 = 0;
285 Iterator it3 = flows3.iterator();
286 while (it3.hasNext()) {
287 it3.next();
288 sum3++;
289 }
290 assertThat(sum3, is(0));
291 }
292}