abc4aab24c4ac8dff587be06a465bcfcf268e714
[openflowplugin.git] / openflowplugin-impl / src / test / java / org / opendaylight / openflowplugin / impl / util / FlowUtilTest.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.openflowplugin.impl.util;
9
10 import com.google.common.collect.Lists;
11 import java.util.Collections;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.function.Function;
15 import org.apache.commons.lang3.tuple.Pair;
16 import org.junit.Assert;
17 import org.junit.Test;
18 import org.mockito.Mockito;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierOutput;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchOutput;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.AddFlowsBatchOutputBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.BatchFlowIdGrouping;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.BatchFlowOutputListGrouping;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.output.list.grouping.BatchFailedFlowsOutput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.output.list.grouping.BatchFailedFlowsOutputBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flows.service.rev160314.batch.flow.output.list.grouping.BatchFailedFlowsOutputKey;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
35 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
36 import org.opendaylight.yangtools.yang.binding.util.BindingMap;
37 import org.opendaylight.yangtools.yang.common.RpcError;
38 import org.opendaylight.yangtools.yang.common.RpcResult;
39 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
40 import org.opendaylight.yangtools.yang.common.Uint16;
41 import org.opendaylight.yangtools.yang.common.Uint8;
42
43 public class FlowUtilTest {
44     public static final NodeId DUMMY_NODE_ID = new NodeId("dummyNodeId");
45     public static final FlowId DUMMY_FLOW_ID = new FlowId("dummyFlowId");
46     public static final FlowId DUMMY_FLOW_ID_2 = new FlowId("dummyFlowId_2");
47     public static final Uint8 DUMMY_TABLE_ID = Uint8.ONE;
48
49     @Test
50     public void testBuildFlowPath() {
51         final InstanceIdentifier<Node> nodePath = InstanceIdentifier
52                 .create(Nodes.class)
53                 .child(Node.class, new NodeKey(DUMMY_NODE_ID));
54
55         final FlowRef flowRef = FlowUtil.buildFlowPath(nodePath, DUMMY_TABLE_ID, DUMMY_FLOW_ID);
56         final InstanceIdentifier<?> flowRefValue = flowRef.getValue();
57         Assert.assertEquals(DUMMY_NODE_ID, flowRefValue.firstKeyOf(Node.class).getId());
58         Assert.assertEquals(DUMMY_TABLE_ID, flowRefValue.firstKeyOf(Table.class).getId());
59         Assert.assertEquals(DUMMY_FLOW_ID, flowRefValue.firstKeyOf(Flow.class).getId());
60     }
61
62     @Test
63     public void testCreateCumulatingFunction() {
64         final Function<List<RpcResult<String>>, RpcResult<List<BatchFailedFlowsOutput>>> function =
65                 FlowUtil.createCumulatingFunction(Lists.newArrayList(createBatchFlowIdGrouping(DUMMY_FLOW_ID),
66                         createBatchFlowIdGrouping(DUMMY_FLOW_ID_2)));
67
68         final RpcResult<List<BatchFailedFlowsOutput>> summary = function.apply(Lists.newArrayList(
69                 RpcResultBuilder.success("a").build(),
70                 RpcResultBuilder.<String>failed()
71                         .withError(RpcError.ErrorType.APPLICATION, "action-failed reason")
72                         .build()));
73
74         Assert.assertFalse(summary.isSuccessful());
75         Assert.assertEquals(1, summary.getResult().size());
76         Assert.assertEquals(1, summary.getErrors().size());
77         Assert.assertEquals(DUMMY_FLOW_ID_2, summary.getResult().get(0).getFlowId());
78         Assert.assertEquals(1, summary.getResult().get(0).getBatchOrder().intValue());
79     }
80
81     protected BatchFlowIdGrouping createBatchFlowIdGrouping(final FlowId flowId) {
82         final BatchFlowIdGrouping mock = Mockito.mock(BatchFlowIdGrouping.class);
83         Mockito.when(mock.getFlowId()).thenReturn(flowId);
84         return mock;
85     }
86
87     @Test
88     public void testFlowAddTransformFailure() {
89         final RpcResult<List<BatchFailedFlowsOutput>> input = createBatchOutcomeWithError();
90         checkBatchErrorOutcomeTransformation(FlowUtil.FLOW_ADD_TRANSFORM.apply(input));
91     }
92
93     @Test
94     public void testFlowAddTransformSuccess() {
95         final RpcResult<List<BatchFailedFlowsOutput>> input = createEmptyBatchOutcome();
96         checkBatchSuccessOutcomeTransformation(FlowUtil.FLOW_ADD_TRANSFORM.apply(input));
97     }
98
99     @Test
100     public void testFlowRemoveTransformFailure() {
101         final RpcResult<List<BatchFailedFlowsOutput>> input = createBatchOutcomeWithError();
102         checkBatchErrorOutcomeTransformation(FlowUtil.FLOW_REMOVE_TRANSFORM.apply(input));
103     }
104
105     @Test
106     public void testFlowRemoveTransformSuccess() {
107         final RpcResult<List<BatchFailedFlowsOutput>> input = createEmptyBatchOutcome();
108         checkBatchSuccessOutcomeTransformation(FlowUtil.FLOW_REMOVE_TRANSFORM.apply(input));
109     }
110
111     @Test
112     public void testFlowUpdateTransformFailure() {
113         final RpcResult<List<BatchFailedFlowsOutput>> input = createBatchOutcomeWithError();
114         checkBatchErrorOutcomeTransformation(FlowUtil.FLOW_UPDATE_TRANSFORM.apply(input));
115     }
116
117     @Test
118     public void testFlowUpdateTransformSuccess() {
119         final RpcResult<List<BatchFailedFlowsOutput>> input = createEmptyBatchOutcome();
120         checkBatchSuccessOutcomeTransformation(FlowUtil.FLOW_UPDATE_TRANSFORM.apply(input));
121     }
122
123     private static <T extends BatchFlowOutputListGrouping> void checkBatchSuccessOutcomeTransformation(
124             final RpcResult<T> output) {
125         Assert.assertTrue(output.isSuccessful());
126         Map<BatchFailedFlowsOutputKey, BatchFailedFlowsOutput> failedFlows
127                 = output.getResult().nonnullBatchFailedFlowsOutput();
128         Assert.assertEquals(0, failedFlows.size());
129         Assert.assertEquals(0, output.getErrors().size());
130     }
131
132     private static RpcResult<List<BatchFailedFlowsOutput>> createEmptyBatchOutcome() {
133         return RpcResultBuilder
134                 .success(Collections.<BatchFailedFlowsOutput>emptyList())
135                 .build();
136     }
137
138     private static RpcResult<List<BatchFailedFlowsOutput>> createBatchOutcomeWithError() {
139         return RpcResultBuilder.<List<BatchFailedFlowsOutput>>failed()
140                 .withError(RpcError.ErrorType.APPLICATION, "ut-flowAddFail")
141                 .withResult(Collections.singletonList(new BatchFailedFlowsOutputBuilder()
142                         .setFlowId(DUMMY_FLOW_ID)
143                         .setBatchOrder(Uint16.ZERO)
144                         .build()))
145                 .build();
146     }
147
148     private static <T extends BatchFlowOutputListGrouping> void checkBatchErrorOutcomeTransformation(
149             final RpcResult<T> output) {
150         Assert.assertFalse(output.isSuccessful());
151         Assert.assertEquals(1, output.getResult().nonnullBatchFailedFlowsOutput().size());
152         Assert.assertEquals(DUMMY_FLOW_ID,
153             output.getResult().nonnullBatchFailedFlowsOutput().values().iterator().next().getFlowId());
154
155         Assert.assertEquals(1, output.getErrors().size());
156     }
157
158     @Test
159     public void testCreateComposingFunction_success_success() {
160         final Function<Pair<RpcResult<AddFlowsBatchOutput>, RpcResult<SendBarrierOutput>>,
161                 RpcResult<AddFlowsBatchOutput>> compositeFunction = FlowUtil.createComposingFunction();
162
163         final RpcResult<AddFlowsBatchOutput> addFlowBatchOutput = createAddFlowsBatchSuccessOutput();
164         final RpcResult<SendBarrierOutput> barrierOutput = RpcResultBuilder.<SendBarrierOutput>success().build();
165         final Pair<RpcResult<AddFlowsBatchOutput>, RpcResult<SendBarrierOutput>> input
166                 = Pair.of(addFlowBatchOutput, barrierOutput);
167         final RpcResult<AddFlowsBatchOutput> composite = compositeFunction.apply(input);
168
169         Assert.assertTrue(composite.isSuccessful());
170         Assert.assertEquals(0, composite.getErrors().size());
171         Map<BatchFailedFlowsOutputKey, BatchFailedFlowsOutput> failedFlows
172                 = composite.getResult().nonnullBatchFailedFlowsOutput();
173         Assert.assertEquals(0, failedFlows.size());
174     }
175
176     @Test
177     public void testCreateComposingFunction_failure_success() {
178         final Function<Pair<RpcResult<AddFlowsBatchOutput>, RpcResult<SendBarrierOutput>>,
179                 RpcResult<AddFlowsBatchOutput>> compositeFunction = FlowUtil.createComposingFunction();
180
181         final RpcResult<AddFlowsBatchOutput> addFlowBatchOutput = createAddFlowsBatchFailureOutcome();
182         final RpcResult<SendBarrierOutput> barrierOutput = RpcResultBuilder.<SendBarrierOutput>success().build();
183         final Pair<RpcResult<AddFlowsBatchOutput>, RpcResult<SendBarrierOutput>> input
184                 = Pair.of(addFlowBatchOutput, barrierOutput);
185         final RpcResult<AddFlowsBatchOutput> composite = compositeFunction.apply(input);
186
187         Assert.assertFalse(composite.isSuccessful());
188         Assert.assertEquals(1, composite.getErrors().size());
189         Assert.assertEquals(1, composite.getResult().getBatchFailedFlowsOutput().size());
190     }
191
192     @Test
193     public void testCreateComposingFunction_success_failure() {
194         final Function<Pair<RpcResult<AddFlowsBatchOutput>, RpcResult<SendBarrierOutput>>,
195                 RpcResult<AddFlowsBatchOutput>> compositeFunction = FlowUtil.createComposingFunction();
196
197         final RpcResult<AddFlowsBatchOutput> addFlowBatchOutput = createAddFlowsBatchSuccessOutput();
198         final RpcResult<SendBarrierOutput> barrierOutput = createBarrierFailureOutcome();
199         final Pair<RpcResult<AddFlowsBatchOutput>, RpcResult<SendBarrierOutput>> input
200                 = Pair.of(addFlowBatchOutput, barrierOutput);
201         final RpcResult<AddFlowsBatchOutput> composite = compositeFunction.apply(input);
202
203         Assert.assertFalse(composite.isSuccessful());
204         Assert.assertEquals(1, composite.getErrors().size());
205         Map<BatchFailedFlowsOutputKey, BatchFailedFlowsOutput> failedFlows
206                 = composite.getResult().nonnullBatchFailedFlowsOutput();
207         Assert.assertEquals(0, failedFlows.size());
208     }
209
210     @Test
211     public void testCreateComposingFunction_failure_failure() {
212         final Function<Pair<RpcResult<AddFlowsBatchOutput>, RpcResult<SendBarrierOutput>>,
213                 RpcResult<AddFlowsBatchOutput>> compositeFunction = FlowUtil.createComposingFunction();
214
215         final RpcResult<AddFlowsBatchOutput> addFlowBatchOutput = createAddFlowsBatchFailureOutcome();
216         final RpcResult<SendBarrierOutput> barrierOutput = createBarrierFailureOutcome();
217         final Pair<RpcResult<AddFlowsBatchOutput>, RpcResult<SendBarrierOutput>> input
218                 = Pair.of(addFlowBatchOutput, barrierOutput);
219         final RpcResult<AddFlowsBatchOutput> composite = compositeFunction.apply(input);
220
221         Assert.assertFalse(composite.isSuccessful());
222         Assert.assertEquals(2, composite.getErrors().size());
223         Assert.assertEquals(1, composite.getResult().getBatchFailedFlowsOutput().size());
224     }
225
226     private static RpcResult<SendBarrierOutput> createBarrierFailureOutcome() {
227         return RpcResultBuilder.<SendBarrierOutput>failed()
228                 .withError(RpcError.ErrorType.APPLICATION, "ut-barrier-error")
229                 .build();
230     }
231
232     private static RpcResult<AddFlowsBatchOutput> createAddFlowsBatchSuccessOutput() {
233         return RpcResultBuilder
234                 .success(new AddFlowsBatchOutputBuilder()
235                         .setBatchFailedFlowsOutput(Collections.emptyMap())
236                         .build())
237                 .build();
238     }
239
240     private static RpcResult<AddFlowsBatchOutput> createAddFlowsBatchFailureOutcome() {
241         final RpcResult<List<BatchFailedFlowsOutput>> batchOutcomeWithError = createBatchOutcomeWithError();
242         return RpcResultBuilder.<AddFlowsBatchOutput>failed()
243                 .withResult(new AddFlowsBatchOutputBuilder()
244                         .setBatchFailedFlowsOutput(BindingMap.ordered(batchOutcomeWithError.getResult()))
245                         .build())
246                 .withRpcErrors(batchOutcomeWithError.getErrors())
247                 .build();
248     }
249 }