a25cb63e862852040513692c954cc66f0ca510f1
[netconf.git] /
1 /*
2  * Copyright (c) 2023 PANTHEON.tech, s.r.o. 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.restconf.nb.rfc8040.rests.transactions;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertNull;
13 import static org.mockito.ArgumentMatchers.any;
14 import static org.mockito.Mockito.doReturn;
15 import static org.mockito.Mockito.mock;
16 import static org.mockito.Mockito.never;
17 import static org.mockito.Mockito.spy;
18 import static org.mockito.Mockito.times;
19 import static org.mockito.Mockito.verify;
20 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFailedFluentFuture;
21 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFluentFuture;
22
23 import com.google.common.util.concurrent.Futures;
24 import java.text.ParseException;
25 import java.util.List;
26 import java.util.Optional;
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 import org.mockito.Mock;
31 import org.mockito.junit.MockitoJUnitRunner;
32 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
33 import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
34 import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
35 import org.opendaylight.netconf.api.NetconfDocumentedException;
36 import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
37 import org.opendaylight.restconf.api.ApiPath;
38 import org.opendaylight.restconf.api.ErrorMessage;
39 import org.opendaylight.restconf.api.QueryParameters;
40 import org.opendaylight.restconf.api.query.InsertParam;
41 import org.opendaylight.restconf.api.query.PointParam;
42 import org.opendaylight.restconf.api.query.PrettyPrintParam;
43 import org.opendaylight.restconf.common.errors.SettableRestconfFuture;
44 import org.opendaylight.restconf.server.api.DatabindContext;
45 import org.opendaylight.restconf.server.api.JsonDataPostBody;
46 import org.opendaylight.restconf.server.api.JsonResourceBody;
47 import org.opendaylight.restconf.server.api.PatchStatusContext;
48 import org.opendaylight.restconf.server.api.PatchStatusEntity;
49 import org.opendaylight.restconf.server.api.ServerRequest;
50 import org.opendaylight.yangtools.yang.common.ErrorSeverity;
51 import org.opendaylight.yangtools.yang.common.ErrorTag;
52 import org.opendaylight.yangtools.yang.common.ErrorType;
53 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
54 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
55 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
56 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
57 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
58 import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
59 import org.w3c.dom.DOMException;
60
61 @RunWith(MockitoJUnitRunner.StrictStubs.class)
62 public final class NetconfRestconfStrategyTest extends AbstractRestconfStrategyTest {
63     @Mock
64     private NetconfDataTreeService netconfService;
65
66     @Before
67     public void before() {
68         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
69         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).discardChanges();
70         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).unlock();
71         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).lock();
72         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
73             .delete(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.of());
74         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).merge(any(), any(),
75             any(), any());
76     }
77
78     @Override
79     RestconfStrategy newStrategy(final DatabindContext databind) {
80         return new NetconfRestconfStrategy(databind, netconfService, null, null, null, null);
81     }
82
83     @Override
84     RestconfStrategy testDeleteDataStrategy() {
85         return jukeboxStrategy();
86     }
87
88     @Override
89     RestconfStrategy testNegativeDeleteDataStrategy() {
90         doReturn(Futures.immediateFailedFuture(new TransactionCommitFailedException(
91             "Commit of transaction " + this + " failed", new NetconfDocumentedException("id",
92                 ErrorType.RPC, ErrorTag.DATA_MISSING, ErrorSeverity.ERROR)))).when(netconfService).commit();
93         return jukeboxStrategy();
94     }
95
96     @Test
97     public void testDeleteFullList() {
98         final var songListPath = YangInstanceIdentifier.builder().node(JUKEBOX_QNAME).node(PLAYLIST_QNAME)
99             .node(NodeIdentifierWithPredicates.of(PLAYLIST_QNAME, NAME_QNAME, "playlist"))
100             .node(SONG_QNAME).build();
101         final var songListWildcardPath = songListPath.node(NodeIdentifierWithPredicates.of(SONG_QNAME));
102         final var song1Path = songListPath.node(SONG1.name());
103         final var song2Path = songListPath.node(SONG2.name());
104         final var songListData = ImmutableNodes.newUserMapBuilder()
105             .withNodeIdentifier(new NodeIdentifier(SONG_QNAME))
106             .withChild(SONG1).withChild(SONG2).build();
107         final var songKeyFields = List.of(YangInstanceIdentifier.of(SONG_INDEX_QNAME));
108
109         // data fetched using key field names to minimize amount of data returned
110         doReturn(immediateFluentFuture(Optional.of(songListData))).when(netconfService)
111             .getConfig(songListWildcardPath, songKeyFields);
112         // list elements expected to be deleted one by one
113         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
114             .delete(LogicalDatastoreType.CONFIGURATION, song1Path);
115         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
116             .delete(LogicalDatastoreType.CONFIGURATION, song2Path);
117
118         jukeboxStrategy().delete(new SettableRestconfFuture<>(), null, songListPath);
119         verify(netconfService).getConfig(songListWildcardPath, songKeyFields);
120         verify(netconfService).delete(LogicalDatastoreType.CONFIGURATION, song1Path);
121         verify(netconfService).delete(LogicalDatastoreType.CONFIGURATION, song2Path);
122         verify(netconfService, never()).delete(LogicalDatastoreType.CONFIGURATION, songListPath);
123     }
124
125     @Override
126     RestconfStrategy testPostContainerDataStrategy() {
127         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
128         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
129             .create(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX, Optional.empty());
130         return jukeboxStrategy();
131     }
132
133     @Override
134     RestconfStrategy testPostListDataStrategy(final MapEntryNode entryNode, final YangInstanceIdentifier node) {
135         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
136             // FIXME: exact match
137             .merge(any(), any(), any(), any());
138         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
139         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).create(
140             LogicalDatastoreType.CONFIGURATION, node, entryNode, Optional.empty());
141         return jukeboxStrategy();
142     }
143
144     @Override
145     RestconfStrategy testPostDataFailStrategy(final DOMException domException) {
146         doReturn(immediateFailedFluentFuture(domException)).when(netconfService)
147             // FIXME: exact match
148             .create(any(), any(), any(), any());
149         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).discardChanges();
150         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).unlock();
151         return jukeboxStrategy();
152     }
153
154     @Override
155     RestconfStrategy testPatchContainerDataStrategy() {
156         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).merge(any(), any(),any(),
157             any());
158         return jukeboxStrategy();
159     }
160
161     @Override
162     RestconfStrategy testPatchLeafDataStrategy() {
163         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
164             .merge(any(), any(), any(), any());
165         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
166         return jukeboxStrategy();
167     }
168
169     @Override
170     RestconfStrategy testPatchListDataStrategy() {
171         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
172         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
173             .merge(any(), any(),any(),any());
174         return jukeboxStrategy();
175     }
176
177     @Test
178     public void testPutCreateContainerData() {
179         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(JUKEBOX_IID);
180         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
181         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
182             .replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX, Optional.empty());
183
184         jukeboxStrategy().putData(JUKEBOX_IID, EMPTY_JUKEBOX, null);
185         verify(netconfService).lock();
186         verify(netconfService).getConfig(JUKEBOX_IID);
187         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX,
188             Optional.empty());
189     }
190
191     @Test
192     public void testPutReplaceContainerData() {
193         doReturn(immediateFluentFuture(Optional.of(mock(ContainerNode.class)))).when(netconfService)
194             .getConfig(JUKEBOX_IID);
195         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
196         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
197             .replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX, Optional.empty());
198
199         jukeboxStrategy().putData(JUKEBOX_IID, EMPTY_JUKEBOX, null);
200         verify(netconfService).getConfig(JUKEBOX_IID);
201         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX,
202             Optional.empty());
203     }
204
205     @Test
206     public void testPutCreateLeafData() {
207         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(GAP_IID);
208         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
209         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
210             .replace(LogicalDatastoreType.CONFIGURATION, GAP_IID, GAP_LEAF, Optional.empty());
211
212         jukeboxStrategy().putData(GAP_IID, GAP_LEAF, null);
213         verify(netconfService).getConfig(GAP_IID);
214         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, GAP_IID, GAP_LEAF, Optional.empty());
215     }
216
217     @Test
218     public void testPutReplaceLeafData() {
219         doReturn(immediateFluentFuture(Optional.of(mock(ContainerNode.class)))).when(netconfService)
220             .getConfig(GAP_IID);
221         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
222         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
223             .replace(LogicalDatastoreType.CONFIGURATION, GAP_IID, GAP_LEAF, Optional.empty());
224
225         jukeboxStrategy().putData(GAP_IID, GAP_LEAF, null);
226         verify(netconfService).getConfig(GAP_IID);
227         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, GAP_IID, GAP_LEAF, Optional.empty());
228     }
229
230     @Test
231     public void testPutCreateListData() {
232         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(JUKEBOX_IID);
233         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
234         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
235             .replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, JUKEBOX_WITH_BANDS, Optional.empty());
236
237         jukeboxStrategy().putData(JUKEBOX_IID, JUKEBOX_WITH_BANDS, null);
238         verify(netconfService).getConfig(JUKEBOX_IID);
239         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, JUKEBOX_WITH_BANDS,
240             Optional.empty());
241     }
242
243     /**
244      * Test for put with insert=after option for last element of the list. Here we're trying to insert new element of
245      * the ordered list after last existing element. Test uses list with two items and add third one at the end. After
246      * this we check how many times replace transaction was called to know how many items was inserted.
247      * @throws ParseException if ApiPath string cannot be parsed
248      */
249     @Test
250     public void testPutDataWithInsertAfterLast() throws ParseException {
251         // Spy of jukeboxStrategy will be used later to count how many items was inserted
252         final var spyStrategy = spy(jukeboxStrategy());
253         final var spyTx = spy(jukeboxStrategy().prepareWriteExecution());
254         doReturn(spyTx).when(spyStrategy).prepareWriteExecution();
255         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(any());
256
257         final var songListPath = YangInstanceIdentifier.builder().node(JUKEBOX_QNAME).node(PLAYLIST_QNAME)
258             .node(NodeIdentifierWithPredicates.of(PLAYLIST_QNAME, NAME_QNAME, "0")).node(SONG_QNAME).build();
259         doReturn(immediateFluentFuture(Optional.of(PLAYLIST_WITH_SONGS))).when(spyTx).read(songListPath);
260
261         // Inserting new song at 3rd position (aka as last element)
262         spyStrategy.dataPUT(ServerRequest.of(QueryParameters.of(
263             // insert new item after last existing item in list
264             InsertParam.AFTER, PointParam.forUriValue("example-jukebox:jukebox/playlist=0/song=2")),
265             PrettyPrintParam.TRUE),
266             ApiPath.parse("example-jukebox:jukebox/playlist=0/song=3"),
267             new JsonResourceBody(stringInputStream("""
268                 {
269                   "example-jukebox:song" : [
270                     {
271                        "index": "3",
272                        "id" = "C"
273                     }
274                   ]
275                 }""")));
276
277         // Counting how many times we insert items in list
278         verify(spyTx, times(3)).replace(any(), any());
279     }
280
281     /**
282      * Test for post with insert=after option for last element of the list. Here we're trying to insert new element of
283      * the ordered list after last existing element. Test uses list with two items and add third one at the end. After
284      * this we check how many times replace transaction was called to know how many items was inserted.
285      * @throws ParseException if ApiPath string cannot be parsed
286      */
287     @Test
288     public void testPostDataWithInsertAfterLast() throws ParseException {
289         // Spy of jukeboxStrategy will be used later to count how many items was inserted
290         final var spyStrategy = spy(jukeboxStrategy());
291         final var spyTx = spy(jukeboxStrategy().prepareWriteExecution());
292         doReturn(spyTx).when(spyStrategy).prepareWriteExecution();
293         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(any());
294
295         final var songListPath = YangInstanceIdentifier.builder().node(JUKEBOX_QNAME).node(PLAYLIST_QNAME)
296             .node(NodeIdentifierWithPredicates.of(PLAYLIST_QNAME, NAME_QNAME, "0")).node(SONG_QNAME).build();
297         doReturn(immediateFluentFuture(Optional.of(PLAYLIST_WITH_SONGS))).when(spyTx).read(songListPath);
298
299         // Inserting new song at 3rd position (aka as last element)
300         spyStrategy.dataPOST(ServerRequest.of(QueryParameters.of(InsertParam.AFTER,
301             PointParam.forUriValue("example-jukebox:jukebox/playlist=0/song=2")), PrettyPrintParam.FALSE),
302             ApiPath.parse("example-jukebox:jukebox/playlist=0"),
303             // insert new item after last existing item in list
304             new JsonDataPostBody(stringInputStream("""
305                 {
306                   "example-jukebox:song" : [
307                     {
308                        "index": "3",
309                        "id" = "C"
310                     }
311                   ]
312                 }""")));
313
314         // Counting how many times we insert items in list
315         verify(spyTx, times(3)).replace(any(), any());
316     }
317
318     @Test
319     public void testPutReplaceListData() {
320         doReturn(immediateFluentFuture(Optional.of(mock(ContainerNode.class)))).when(netconfService)
321             .getConfig(JUKEBOX_IID);
322         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
323         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
324             .replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, JUKEBOX_WITH_BANDS, Optional.empty());
325
326         jukeboxStrategy().putData(JUKEBOX_IID, JUKEBOX_WITH_BANDS, null);
327         verify(netconfService).getConfig(JUKEBOX_IID);
328         verify(netconfService).replace(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, JUKEBOX_WITH_BANDS,
329             Optional.empty());
330     }
331
332     @Override
333     RestconfStrategy testPatchDataReplaceMergeAndRemoveStrategy() {
334         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
335             .remove(LogicalDatastoreType.CONFIGURATION, ARTIST_IID);
336         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
337             // FIXME: exact match
338             .replace(any(), any(), any(), any());
339         return jukeboxStrategy();
340     }
341
342     @Override
343     RestconfStrategy testPatchDataCreateAndDeleteStrategy() {
344         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
345             .create(LogicalDatastoreType.CONFIGURATION, PLAYER_IID, EMPTY_JUKEBOX, Optional.empty());
346         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
347             .delete(LogicalDatastoreType.CONFIGURATION, CREATE_AND_DELETE_TARGET);
348         return jukeboxStrategy();
349     }
350
351     @Override
352     RestconfStrategy testPatchMergePutContainerStrategy() {
353         return jukeboxStrategy();
354     }
355
356     @Override
357     RestconfStrategy deleteNonexistentDataTestStrategy() {
358         doReturn(Futures.immediateFailedFuture(
359             new TransactionCommitFailedException("Commit of transaction " + this + " failed",
360                 new NetconfDocumentedException("id", ErrorType.RPC, ErrorTag.DATA_MISSING, ErrorSeverity.ERROR))))
361             .when(netconfService).commit();
362         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
363             .delete(LogicalDatastoreType.CONFIGURATION, CREATE_AND_DELETE_TARGET);
364         return jukeboxStrategy();
365     }
366
367     @Override
368     void assertTestDeleteNonexistentData(final PatchStatusContext status, final PatchStatusEntity edit) {
369         assertNull(edit.getEditErrors());
370         final var globalErrors = status.globalErrors();
371         assertNotNull(globalErrors);
372         assertEquals(1, globalErrors.size());
373         final var globalError = globalErrors.get(0);
374         assertEquals(new ErrorMessage("Data does not exist"), globalError.message());
375         assertEquals(ErrorType.PROTOCOL, globalError.type());
376         assertEquals(ErrorTag.DATA_MISSING, globalError.tag());
377     }
378
379     @Override
380     RestconfStrategy readDataConfigTestStrategy() {
381         doReturn(immediateFluentFuture(Optional.of(DATA_3))).when(netconfService).getConfig(PATH);
382         return mockStrategy();
383     }
384
385     @Override
386     RestconfStrategy readAllHavingOnlyConfigTestStrategy() {
387         doReturn(immediateFluentFuture(Optional.of(DATA_3))).when(netconfService).getConfig(PATH);
388         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).get(PATH);
389         return mockStrategy();
390     }
391
392     @Override
393     RestconfStrategy readAllHavingOnlyNonConfigTestStrategy() {
394         doReturn(immediateFluentFuture(Optional.of(DATA_2))).when(netconfService).get(PATH_2);
395         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(PATH_2);
396         return mockStrategy();
397     }
398
399     @Override
400     RestconfStrategy readDataNonConfigTestStrategy() {
401         doReturn(immediateFluentFuture(Optional.of(DATA_2))).when(netconfService).get(PATH_2);
402         return mockStrategy();
403     }
404
405     @Override
406     RestconfStrategy readContainerDataAllTestStrategy() {
407         doReturn(immediateFluentFuture(Optional.of(DATA_3))).when(netconfService).getConfig(PATH);
408         doReturn(immediateFluentFuture(Optional.of(DATA_4))).when(netconfService).get(PATH);
409         return mockStrategy();
410     }
411
412     @Override
413     RestconfStrategy readContainerDataConfigNoValueOfContentTestStrategy() {
414         doReturn(immediateFluentFuture(Optional.of(DATA_3))).when(netconfService).getConfig(PATH);
415         doReturn(immediateFluentFuture(Optional.of(DATA_4))).when(netconfService).get(PATH);
416         return mockStrategy();
417     }
418
419     @Override
420     RestconfStrategy readListDataAllTestStrategy() {
421         doReturn(immediateFluentFuture(Optional.of(LIST_DATA))).when(netconfService).get(PATH_3);
422         doReturn(immediateFluentFuture(Optional.of(LIST_DATA_2))).when(netconfService).getConfig(PATH_3);
423         return mockStrategy();
424     }
425
426     @Override
427     RestconfStrategy readOrderedListDataAllTestStrategy() {
428         doReturn(immediateFluentFuture(Optional.of(ORDERED_MAP_NODE_1))).when(netconfService).get(PATH_3);
429         doReturn(immediateFluentFuture(Optional.of(ORDERED_MAP_NODE_2))).when(netconfService).getConfig(PATH_3);
430         return mockStrategy();
431     }
432
433     @Override
434     RestconfStrategy readUnkeyedListDataAllTestStrategy() {
435         doReturn(immediateFluentFuture(Optional.of(UNKEYED_LIST_NODE_1))).when(netconfService).get(PATH_3);
436         doReturn(immediateFluentFuture(Optional.of(UNKEYED_LIST_NODE_2))).when(netconfService).getConfig(PATH_3);
437         return mockStrategy();
438     }
439
440     @Override
441     RestconfStrategy readLeafListDataAllTestStrategy() {
442         doReturn(immediateFluentFuture(Optional.of(LEAF_SET_NODE_1))).when(netconfService)
443             .get(LEAF_SET_NODE_PATH);
444         doReturn(immediateFluentFuture(Optional.of(LEAF_SET_NODE_2))).when(netconfService)
445             .getConfig(LEAF_SET_NODE_PATH);
446         return mockStrategy();
447     }
448
449     @Override
450     RestconfStrategy readOrderedLeafListDataAllTestStrategy() {
451         doReturn(immediateFluentFuture(Optional.of(ORDERED_LEAF_SET_NODE_1))).when(netconfService)
452             .get(LEAF_SET_NODE_PATH);
453         doReturn(immediateFluentFuture(Optional.of(ORDERED_LEAF_SET_NODE_2))).when(netconfService)
454             .getConfig(LEAF_SET_NODE_PATH);
455         return mockStrategy();
456     }
457
458     @Override
459     RestconfStrategy readDataWrongPathOrNoContentTestStrategy() {
460         doReturn(immediateFluentFuture(Optional.empty())).when(netconfService).getConfig(PATH_2);
461         return mockStrategy();
462     }
463 }