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