Merge "Fixed tag for <nexus.repository.snapshot>"
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / test / java / org / opendaylight / controller / sal / binding / impl / connect / dom / RpcInvocationStrategyTest.java
1 /*
2 * Copyright (c) 2014 Brocade Communications 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.controller.sal.binding.impl.connect.dom;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.mockito.Matchers.any;
13 import static org.mockito.Matchers.eq;
14 import static org.mockito.Mockito.mock;
15 import static org.mockito.Mockito.when;
16 import com.google.common.util.concurrent.Futures;
17 import com.google.common.util.concurrent.ListenableFuture;
18 import java.net.URI;
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.Date;
22 import java.util.concurrent.ExecutionException;
23 import java.util.concurrent.Future;
24 import org.junit.Before;
25 import org.junit.Test;
26 import org.mockito.Mock;
27 import org.mockito.MockitoAnnotations;
28 import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
29 import org.opendaylight.yangtools.yang.binding.DataObject;
30 import org.opendaylight.yangtools.yang.binding.RpcService;
31 import org.opendaylight.yangtools.yang.common.QName;
32 import org.opendaylight.yangtools.yang.common.RpcError;
33 import org.opendaylight.yangtools.yang.common.RpcResult;
34 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
35 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
36 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
37
38 public class RpcInvocationStrategyTest {
39
40     @Mock
41     private BindingIndependentMappingService mockMappingService;
42     @Mock
43     private RpcProvisionRegistry mockbiRpcRegistry;
44
45     private RpcInvocationStrategy rpcInvocationStrategy;
46     private ListenableFuture<RpcResult<DataObject>> futureDataObj;
47     private ListenableFuture<RpcResult<CompositeNode>> futureCompNode;
48     private final RpcError rpcError = mock(RpcError.class);
49     private final Collection<RpcError> errors = new ArrayList<RpcError>();
50
51     private final CompositeNode inputInvokeOn = mock(CompositeNode.class);
52     private final CompositeNode outputInvokeOn = mock(CompositeNode.class);
53
54     private final DataObject toDataDomInput = mock(DataObject.class);
55     private final CompositeNode toDataDomReturn = mock(CompositeNode.class);
56     private final CompositeNode invokeRpcResult = mock(CompositeNode.class);
57
58     private final DataObject inputForward = mock(DataObject.class);
59     private final DataObject outputForward = mock(DataObject.class);
60
61     private QName mockQName;
62     private URI urn;
63
64     private final MockRpcService mockRpcService = new MockRpcService();
65
66     public class MockRpcService implements RpcService {
67
68         public Future<?> rpcnameWithInputNoOutput(final DataObject input) {
69             return futureDataObj;
70         }
71
72         public Future<RpcResult<DataObject>> rpcnameWithInputWithOutput(final DataObject input) {
73             return futureDataObj;
74         }
75
76         public Future<RpcResult<DataObject>> rpcnameNoInputWithOutput() {
77             return futureDataObj;
78         }
79
80         public Future<?> rpcnameNoInputNoOutput() {
81             return futureDataObj;
82         }
83     }
84
85     public RpcInvocationStrategyTest() {
86         MockitoAnnotations.initMocks(this);
87     }
88
89     @Before
90     public void testInit() throws Exception {
91         urn = new URI(new String("urn:a:valid:urn"));
92     }
93
94     private void setupForForwardToDom(final boolean hasOutput, final boolean hasInput, final int expectedErrorSize) {
95
96         if (expectedErrorSize > 0) {
97             errors.add(rpcError);
98         }
99         RpcResult<CompositeNode> result = RpcResultBuilder.<CompositeNode>success(invokeRpcResult)
100                                                             .withRpcErrors( errors ).build();
101         futureCompNode = Futures.immediateFuture(result);
102         if( hasInput )
103         {
104             when(mockMappingService.toDataDom(inputForward)).thenReturn(toDataDomReturn);
105         }
106         when(mockbiRpcRegistry.invokeRpc(eq(mockQName), any(CompositeNode.class))).thenReturn(
107                 futureCompNode);
108         if (hasOutput) {
109             when(
110                     mockMappingService.dataObjectFromDataDom(eq(rpcInvocationStrategy
111                             .getOutputClass().get()), any(CompositeNode.class))).thenReturn(
112                     outputForward);
113         }
114
115     }
116
117     private void validateForwardToDomBroker(final ListenableFuture<RpcResult<?>> forwardToDomBroker,
118             final boolean expectedSuccess, final DataObject expectedResult, final int expectedErrorSize)
119             throws InterruptedException, ExecutionException {
120         assertNotNull(forwardToDomBroker);
121         assertEquals(expectedSuccess, forwardToDomBroker.get().isSuccessful());
122         assertEquals(expectedResult, forwardToDomBroker.get().getResult());
123         assertEquals(expectedErrorSize, forwardToDomBroker.get().getErrors().size());
124     }
125
126     private void setupTestMethod(final String rpcName, final String testMethodName, final boolean hasInput)
127             throws NoSuchMethodException {
128         mockQName = QName.create(urn, new Date(0L), new String(rpcName));
129         java.lang.reflect.Method rpcMethod = hasInput ? MockRpcService.class.getMethod(rpcName,
130                 DataObject.class) : MockRpcService.class.getMethod(rpcName);
131         rpcInvocationStrategy = new RpcInvocationStrategy(mockQName, rpcMethod, mockMappingService,
132                 mockbiRpcRegistry);
133     }
134
135     /*
136      * forwardToDomBroker tests
137      */
138     @Test
139     public void testForwardToDomBroker_WithInputNoOutput() throws Exception {
140         setupTestMethod("rpcnameWithInputNoOutput", "testForwardToDomBroker_WithInputNoOutput",
141                 true);
142         setupForForwardToDom(false, true, 0);
143         ListenableFuture<RpcResult<?>> forwardToDomBroker = rpcInvocationStrategy
144                 .forwardToDomBroker(inputForward);
145
146         validateForwardToDomBroker(forwardToDomBroker, true, null, 0);
147     }
148
149     @Test
150     public void testForwardToDomBroker_WithInputNoOutput_error() throws Exception {
151         setupTestMethod("rpcnameWithInputNoOutput",
152                 "testForwardToDomBroker_WithInputNoOutput_error", true);
153         setupForForwardToDom(false, true, 1);
154         ListenableFuture<RpcResult<?>> forwardToDomBroker = rpcInvocationStrategy
155                 .forwardToDomBroker(inputForward);
156
157         validateForwardToDomBroker(forwardToDomBroker, true, null, 1);
158     }
159
160     @Test
161     public void testForwardToDomBroker_WithInputWithOutput() throws Exception {
162         setupTestMethod("rpcnameWithInputWithOutput", "testForwardToDomBroker_WithInputWithOutput",
163                 true);
164         setupForForwardToDom(true, true, 0);
165         ListenableFuture<RpcResult<?>> forwardToDomBroker = rpcInvocationStrategy
166                 .forwardToDomBroker(inputForward);
167         validateForwardToDomBroker(forwardToDomBroker, true, outputForward, 0);
168     }
169
170     @Test
171     public void testForwardToDomBroker_NoInputWithOutput() throws Exception {
172         setupTestMethod("rpcnameNoInputWithOutput", "testForwardToDomBroker_NoInputWithOutput",
173                 false);
174         setupForForwardToDom(true, false, 0);
175         ListenableFuture<RpcResult<?>> forwardToDomBroker = rpcInvocationStrategy
176                 .forwardToDomBroker(null);
177         validateForwardToDomBroker(forwardToDomBroker, true, outputForward, 0);
178     }
179
180     @Test
181     public void testForwardToDomBroker_NoInputNoOutput() throws Exception {
182         setupTestMethod("rpcnameNoInputNoOutput", "testForwardToDomBroker_NoInputNoOutput", false);
183         setupForForwardToDom(false, false, 0);
184         ListenableFuture<RpcResult<?>> forwardToDomBroker = rpcInvocationStrategy
185                 .forwardToDomBroker(null);
186         validateForwardToDomBroker(forwardToDomBroker, true, null, 0);
187     }
188
189     /*
190      * invokeOn Tests
191      */
192     private void setupRpcResultsWithOutput(final int expectedErrorSize) {
193         if (expectedErrorSize > 0) {
194             errors.add(rpcError);
195         }
196         RpcResult<CompositeNode> resultCompNode = RpcResultBuilder.<CompositeNode>success(inputInvokeOn)
197                                                                         .withRpcErrors(errors).build();
198         futureCompNode = Futures.immediateFuture(resultCompNode);
199         RpcResult<DataObject> resultDataObj = RpcResultBuilder.<DataObject>success(toDataDomInput)
200                                                                            .withRpcErrors(errors).build();
201         futureDataObj = Futures.immediateFuture(resultDataObj);
202
203         when(mockMappingService.toDataDom(toDataDomInput)).thenReturn(outputInvokeOn);
204     }
205
206     private void setupRpcResultsNoOutput(final int expectedErrorSize) {
207         if (expectedErrorSize > 0) {
208             errors.add(rpcError);
209         }
210         RpcResult<CompositeNode> resultCompNode = RpcResultBuilder.<CompositeNode>success(inputInvokeOn)
211                                                                           .withRpcErrors(errors).build();
212         futureCompNode = Futures.immediateFuture(resultCompNode);
213         RpcResult<DataObject> resultDataObj = RpcResultBuilder.<DataObject>success()
214                                                                           .withRpcErrors(errors).build();
215         futureDataObj = Futures.immediateFuture(resultDataObj);
216     }
217
218     private void validateReturnedImmediateFuture(
219             final ListenableFuture<RpcResult<CompositeNode>> immediateFuture, final boolean expectedSuccess,
220             final CompositeNode expectedReturn, final int expectedErrorSize) throws InterruptedException,
221             ExecutionException {
222         assertNotNull(immediateFuture);
223         assertEquals(expectedSuccess, immediateFuture.get().isSuccessful());
224         assertEquals(expectedReturn, immediateFuture.get().getResult());
225         assertEquals(expectedErrorSize, immediateFuture.get().getErrors().size());
226     }
227
228     @Test
229     public void testInvokeOn_NoInputNoOutput() throws Exception {
230         setupTestMethod("rpcnameNoInputNoOutput", "testInvokeOn_NoInputNoOutput", false);
231         setupRpcResultsNoOutput(0);
232         ListenableFuture<RpcResult<CompositeNode>> immediateFuture = Futures
233                 .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn));
234         validateReturnedImmediateFuture(immediateFuture, true, null, 0);
235     }
236
237     @Test
238     public void testInvokeOn_NoInputNoOutput_errors() throws Exception {
239         setupTestMethod("rpcnameNoInputNoOutput", "testInvokeOn_NoInputNoOutput", false);
240         setupRpcResultsNoOutput(1);
241         ListenableFuture<RpcResult<CompositeNode>> immediateFuture = Futures
242                 .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn));
243         validateReturnedImmediateFuture(immediateFuture, true, null, 1);
244     }
245
246     @Test
247     public void testInvokeOn_WithInputNoOutput() throws Exception {
248         setupTestMethod("rpcnameWithInputNoOutput", "testInvokeOn_WithInputNoOutput", true);
249         setupRpcResultsNoOutput(0);
250         ListenableFuture<RpcResult<CompositeNode>> immediateFuture = Futures
251                 .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn));
252         validateReturnedImmediateFuture(immediateFuture, true, null, 0);
253     }
254
255     @Test
256     public void testInvokeOn_WithInputWithOutput() throws Exception {
257         setupTestMethod("rpcnameWithInputWithOutput", "testInvokeOn_WithInputWithOutput", true);
258         setupRpcResultsWithOutput(0);
259         ListenableFuture<RpcResult<CompositeNode>> immediateFuture = Futures
260                 .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn));
261         validateReturnedImmediateFuture(immediateFuture, true, outputInvokeOn, 0);
262     }
263
264     @Test
265     public void testInvokeOn_NoInputWithOutput() throws Exception {
266         setupTestMethod("rpcnameNoInputWithOutput", "testInvokeOn_NoInputWithOutput", false);
267         setupRpcResultsWithOutput(0);
268         ListenableFuture<RpcResult<CompositeNode>> immediateFuture = Futures
269                 .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn));
270         validateReturnedImmediateFuture(immediateFuture, true, outputInvokeOn, 0);
271     }
272 }