2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.openflowplugin.applications.frsync.impl;
11 import java.math.BigInteger;
12 import java.util.Collections;
13 import java.util.concurrent.Future;
14 import java.util.concurrent.TimeUnit;
16 import org.junit.Assert;
17 import org.junit.Before;
18 import org.junit.Test;
19 import org.junit.runner.RunWith;
20 import org.mockito.ArgumentCaptor;
21 import org.mockito.Captor;
22 import org.mockito.Matchers;
23 import org.mockito.Mock;
24 import org.mockito.Mockito;
25 import org.mockito.runners.MockitoJUnitRunner;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutputBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutputBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutputBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlow;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
59 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
60 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
61 import org.opendaylight.yangtools.yang.common.RpcResult;
62 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
65 * Test for {@link FlowForwarder}.
67 @RunWith(MockitoJUnitRunner.class)
68 public class FlowForwarderTest {
69 private final NodeKey s1Key = new NodeKey(new NodeId("S1"));
70 private final TableKey tableKey = new TableKey((short) 2);
71 private final FlowId flowId = new FlowId("test_Flow");
72 private final FlowKey flowKey = new FlowKey(flowId);
73 private final Match emptyMatch = new MatchBuilder().build();
74 private final Flow flow = new FlowBuilder()
76 .setTableId((short) 2)
80 private final KeyedInstanceIdentifier<Node, NodeKey> nodePath = InstanceIdentifier.create(Nodes.class)
81 .child(Node.class, s1Key);
82 private final InstanceIdentifier<FlowCapableNode> flowCapableNodePath = nodePath
83 .augmentation(FlowCapableNode.class);
84 private final InstanceIdentifier<Table> tableII = flowCapableNodePath.child(Table.class, tableKey);
85 private final InstanceIdentifier<Flow> flowPath = tableII.child(Flow.class, flowKey);
87 private FlowForwarder flowForwarder;
90 private SalFlowService salFlowService;
92 private ArgumentCaptor<AddFlowInput> addFlowInputCpt;
94 private ArgumentCaptor<UpdateFlowInput> updateFlowInputCpt;
96 private ArgumentCaptor<RemoveFlowInput> removeFlowInputCpt;
100 public void setUp() throws Exception {
101 flowForwarder = new FlowForwarder(salFlowService);
105 public void addTest() throws Exception {
106 Mockito.when(salFlowService.addFlow(addFlowInputCpt.capture())).thenReturn(
107 RpcResultBuilder.success(
108 new AddFlowOutputBuilder()
109 .setTransactionId(new TransactionId(BigInteger.ONE))
110 .build()).buildFuture());
112 final Future<RpcResult<AddFlowOutput>> addResult = flowForwarder.add(flowPath, flow, flowCapableNodePath);
114 Mockito.verify(salFlowService).addFlow(Matchers.<AddFlowInput>any());
115 final AddFlowInput flowInput = addFlowInputCpt.getValue();
116 Assert.assertEquals(2, flowInput.getTableId().shortValue());
117 Assert.assertEquals(emptyMatch, flowInput.getMatch());
118 Assert.assertEquals(null, flowInput.getInstructions());
119 Assert.assertEquals(nodePath, flowInput.getNode().getValue());
120 Assert.assertEquals(flowPath, flowInput.getFlowRef().getValue());
121 Assert.assertEquals(null, flowInput.isStrict());
124 final RpcResult<AddFlowOutput> addFlowOutputRpcResult = addResult.get(2, TimeUnit.SECONDS);
125 Assert.assertTrue(addFlowOutputRpcResult.isSuccessful());
126 final AddFlowOutput resultValue = addFlowOutputRpcResult.getResult();
127 Assert.assertEquals(1, resultValue.getTransactionId().getValue().intValue());
131 public void updateTest() throws Exception {
132 Mockito.when(salFlowService.updateFlow(updateFlowInputCpt.capture())).thenReturn(
133 RpcResultBuilder.success(
134 new UpdateFlowOutputBuilder()
135 .setTransactionId(new TransactionId(BigInteger.ONE))
136 .build()).buildFuture());
138 final Instructions originalInstructions = new InstructionsBuilder()
139 .setInstruction(Collections.singletonList(new InstructionBuilder()
140 .setInstruction(new ApplyActionsCaseBuilder()
141 .setApplyActions(new ApplyActionsBuilder()
142 .setAction(Collections.singletonList(new ActionBuilder()
143 .setAction(new DropActionCaseBuilder()
151 final Flow flowUpdated = new FlowBuilder(flow)
152 .setInstructions(originalInstructions)
153 .setMatch(new MatchBuilder().build())
156 final Future<RpcResult<UpdateFlowOutput>> updateResult = flowForwarder.update(flowPath, flow, flowUpdated, flowCapableNodePath);
158 Mockito.verify(salFlowService).updateFlow(Matchers.<UpdateFlowInput>any());
159 final UpdateFlowInput updateFlowInput = updateFlowInputCpt.getValue();
160 final OriginalFlow flowOrigInput = updateFlowInput.getOriginalFlow();
161 final UpdatedFlow flowInput = updateFlowInput.getUpdatedFlow();
163 Assert.assertEquals(nodePath, updateFlowInput.getNode().getValue());
164 Assert.assertEquals(flowPath, updateFlowInput.getFlowRef().getValue());
166 Assert.assertEquals(2, flowInput.getTableId().shortValue());
167 Assert.assertEquals(emptyMatch, flowInput.getMatch());
168 Assert.assertEquals(originalInstructions, flowInput.getInstructions());
169 Assert.assertEquals(true, flowInput.isStrict());
171 Assert.assertEquals(2, flowOrigInput.getTableId().shortValue());
172 Assert.assertEquals(emptyMatch, flowOrigInput.getMatch());
173 Assert.assertEquals(null, flowOrigInput.getInstructions());
174 Assert.assertEquals(true, flowOrigInput.isStrict());
177 final RpcResult<UpdateFlowOutput> updateFlowOutputRpcResult = updateResult.get(2, TimeUnit.SECONDS);
178 Assert.assertTrue(updateFlowOutputRpcResult.isSuccessful());
179 final UpdateFlowOutput resultValue = updateFlowOutputRpcResult.getResult();
180 Assert.assertEquals(1, resultValue.getTransactionId().getValue().intValue());
184 public void removeTest() throws Exception {
185 Mockito.when(salFlowService.removeFlow(removeFlowInputCpt.capture())).thenReturn(
186 RpcResultBuilder.success(
187 new RemoveFlowOutputBuilder()
188 .setTransactionId(new TransactionId(BigInteger.ONE))
189 .build()).buildFuture());
191 final Flow removeFlow = new FlowBuilder(flow).build();
192 final Future<RpcResult<RemoveFlowOutput>> removeResult = flowForwarder.remove(flowPath, removeFlow, flowCapableNodePath);
194 Mockito.verify(salFlowService).removeFlow(Matchers.<RemoveFlowInput>any());
195 final RemoveFlowInput flowInput = removeFlowInputCpt.getValue();
196 Assert.assertEquals(2, flowInput.getTableId().shortValue());
197 Assert.assertEquals(emptyMatch, flowInput.getMatch());
198 Assert.assertEquals(null, flowInput.getInstructions());
199 Assert.assertEquals(true, flowInput.isStrict());
202 final RpcResult<RemoveFlowOutput> removeFlowOutputRpcResult = removeResult.get(2, TimeUnit.SECONDS);
203 Assert.assertTrue(removeFlowOutputRpcResult.isSuccessful());
204 final RemoveFlowOutput resultValue = removeFlowOutputRpcResult.getResult();
205 Assert.assertEquals(1, resultValue.getTransactionId().getValue().intValue());