Further warnings mitigation
[netconf.git] / restconf / restconf-nb / src / test / java / org / opendaylight / restconf / nb / rfc8040 / rests / transactions / MdsalRestconfStrategyTest.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.jupiter.api.Assertions.assertEquals;
11 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
12 import static org.junit.jupiter.api.Assertions.assertNotSame;
13 import static org.junit.jupiter.api.Assertions.assertNull;
14 import static org.junit.jupiter.api.Assertions.assertThrows;
15 import static org.mockito.Mockito.doNothing;
16 import static org.mockito.Mockito.doReturn;
17 import static org.mockito.Mockito.verify;
18 import static org.mockito.Mockito.when;
19 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFailedFluentFuture;
20 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFalseFluentFuture;
21 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFluentFuture;
22 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateTrueFluentFuture;
23
24 import java.util.Optional;
25 import org.eclipse.jdt.annotation.NonNull;
26 import org.junit.Before;
27 import org.junit.Test;
28 import org.junit.runner.RunWith;
29 import org.mockito.Mock;
30 import org.mockito.junit.MockitoJUnitRunner;
31 import org.opendaylight.mdsal.common.api.CommitInfo;
32 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
33 import org.opendaylight.mdsal.dom.api.DOMActionService;
34 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
35 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
36 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
37 import org.opendaylight.mdsal.dom.api.DOMMountPoint;
38 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
39 import org.opendaylight.mdsal.dom.api.DOMRpcService;
40 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
41 import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
42 import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
43 import org.opendaylight.restconf.api.ApiPath;
44 import org.opendaylight.restconf.api.query.ContentParam;
45 import org.opendaylight.restconf.api.query.WithDefaultsParam;
46 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
47 import org.opendaylight.restconf.common.patch.PatchStatusContext;
48 import org.opendaylight.restconf.common.patch.PatchStatusEntity;
49 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy.StrategyAndTail;
50 import org.opendaylight.restconf.server.api.DatabindContext;
51 import org.opendaylight.yangtools.yang.common.ErrorTag;
52 import org.opendaylight.yangtools.yang.common.ErrorType;
53 import org.opendaylight.yangtools.yang.common.QName;
54 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
55 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
56 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
57 import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
58 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
59 import org.w3c.dom.DOMException;
60
61 @RunWith(MockitoJUnitRunner.StrictStubs.class)
62 public final class MdsalRestconfStrategyTest extends AbstractRestconfStrategyTest {
63     private static final DatabindContext MODULES_DATABIND = DatabindContext.ofModel(
64         YangParserTestUtils.parseYangResourceDirectory("/modules"));
65
66     @Mock
67     private DOMDataTreeReadWriteTransaction readWrite;
68     @Mock
69     private DOMDataBroker dataBroker;
70     @Mock
71     private DOMDataTreeReadTransaction read;
72     @Mock
73     private DOMRpcService rpcService;
74     @Mock
75     private DOMSchemaService schemaService;
76     @Mock
77     private DOMMountPointService mountPointService;
78     @Mock
79     private DOMMountPoint mountPoint;
80     @Mock
81     private NetconfDataTreeService netconfService;
82
83     @Before
84     public void before() {
85         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
86         doReturn(readWrite).when(dataBroker).newReadWriteTransaction();
87     }
88
89     @Override
90     RestconfStrategy newStrategy(final DatabindContext databind) {
91         return new MdsalRestconfStrategy(databind, dataBroker, rpcService, null, null, mountPointService);
92     }
93
94     private @NonNull RestconfStrategy modulesStrategy() {
95         return newStrategy(MODULES_DATABIND);
96     }
97
98     @Override
99     RestconfStrategy testDeleteDataStrategy() {
100         // assert that data to delete exists
101         when(readWrite.exists(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.of()))
102             .thenReturn(immediateTrueFluentFuture());
103         return jukeboxStrategy();
104     }
105
106     @Override
107     RestconfStrategy testNegativeDeleteDataStrategy() {
108         // assert that data to delete does NOT exist
109         when(readWrite.exists(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.of()))
110             .thenReturn(immediateFalseFluentFuture());
111         return jukeboxStrategy();
112     }
113
114     @Override
115     RestconfStrategy testPostListDataStrategy(final MapEntryNode entryNode, final YangInstanceIdentifier node) {
116         doReturn(immediateFalseFluentFuture()).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, node);
117         doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, node, entryNode);
118         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
119         return jukeboxStrategy();
120     }
121
122     @Override
123     RestconfStrategy testPostDataFailStrategy(final DOMException domException) {
124         doReturn(immediateFalseFluentFuture()).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
125         doReturn(immediateFailedFluentFuture(domException)).when(readWrite).commit();
126         doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX);
127         return jukeboxStrategy();
128     }
129
130     @Test
131     public void testPutContainerData() {
132         doReturn(readWrite).when(dataBroker).newReadWriteTransaction();
133         doReturn(read).when(dataBroker).newReadOnlyTransaction();
134         doReturn(immediateFalseFluentFuture()).when(read).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
135         doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX);
136         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
137
138         jukeboxStrategy().putData(JUKEBOX_IID, EMPTY_JUKEBOX, null);
139         verify(read).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
140         verify(readWrite).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX);
141     }
142
143     @Test
144     public void testPutLeafData() {
145         doReturn(readWrite).when(dataBroker).newReadWriteTransaction();
146         doReturn(read).when(dataBroker).newReadOnlyTransaction();
147         doReturn(immediateFalseFluentFuture()).when(read).exists(LogicalDatastoreType.CONFIGURATION, GAP_IID);
148         doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, GAP_IID, GAP_LEAF);
149         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
150
151         jukeboxStrategy().putData(GAP_IID, GAP_LEAF, null);
152         verify(read).exists(LogicalDatastoreType.CONFIGURATION, GAP_IID);
153         verify(readWrite).put(LogicalDatastoreType.CONFIGURATION, GAP_IID, GAP_LEAF);
154     }
155
156
157     @Test
158     public void testPutListData() {
159         doReturn(readWrite).when(dataBroker).newReadWriteTransaction();
160         doReturn(read).when(dataBroker).newReadOnlyTransaction();
161         doReturn(immediateFalseFluentFuture())
162                 .when(read).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
163         doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, JUKEBOX_WITH_BANDS);
164         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
165
166         jukeboxStrategy().putData(JUKEBOX_IID, JUKEBOX_WITH_BANDS, null);
167         verify(read).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
168         verify(readWrite).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, JUKEBOX_WITH_BANDS);
169     }
170
171     @Override
172     RestconfStrategy testPostContainerDataStrategy() {
173         doReturn(immediateFalseFluentFuture()).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
174         doNothing().when(readWrite).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX);
175         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
176         return jukeboxStrategy();
177     }
178
179     @Override
180     RestconfStrategy testPatchContainerDataStrategy() {
181         doReturn(readWrite).when(dataBroker).newReadWriteTransaction();
182         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
183         return jukeboxStrategy();
184     }
185
186     @Override
187     RestconfStrategy testPatchLeafDataStrategy() {
188         doReturn(readWrite).when(dataBroker).newReadWriteTransaction();
189         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
190         return jukeboxStrategy();
191     }
192
193     @Override
194     RestconfStrategy testPatchListDataStrategy() {
195         doReturn(readWrite).when(dataBroker).newReadWriteTransaction();
196         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
197         return jukeboxStrategy();
198     }
199
200     @Override
201     RestconfStrategy testPatchDataReplaceMergeAndRemoveStrategy() {
202         return jukeboxStrategy();
203     }
204
205     @Override
206     RestconfStrategy testPatchDataCreateAndDeleteStrategy() {
207         doReturn(immediateFalseFluentFuture()).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION, PLAYER_IID);
208         doReturn(immediateTrueFluentFuture()).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION,
209             CREATE_AND_DELETE_TARGET);
210         return jukeboxStrategy();
211     }
212
213     @Override
214     RestconfStrategy testPatchMergePutContainerStrategy() {
215         return jukeboxStrategy();
216     }
217
218     @Override
219     RestconfStrategy deleteNonexistentDataTestStrategy() {
220         doReturn(immediateFalseFluentFuture()).when(readWrite).exists(LogicalDatastoreType.CONFIGURATION,
221             CREATE_AND_DELETE_TARGET);
222         return jukeboxStrategy();
223     }
224
225     @Override
226     void assertTestDeleteNonexistentData(final PatchStatusContext status, final PatchStatusEntity edit) {
227         assertNull(status.globalErrors());
228         final var editErrors = edit.getEditErrors();
229         assertEquals(1, editErrors.size());
230         final var editError = editErrors.get(0);
231         assertEquals("Data does not exist", editError.getErrorMessage());
232         assertEquals(ErrorType.PROTOCOL, editError.getErrorType());
233         assertEquals(ErrorTag.DATA_MISSING, editError.getErrorTag());
234     }
235
236     @Override
237     RestconfStrategy readDataConfigTestStrategy() {
238         doReturn(read).when(dataBroker).newReadOnlyTransaction();
239         doReturn(immediateFluentFuture(Optional.of(DATA_3))).when(read)
240             .read(LogicalDatastoreType.CONFIGURATION, PATH);
241         return mockStrategy();
242     }
243
244     @Override
245     RestconfStrategy readAllHavingOnlyConfigTestStrategy() {
246         doReturn(read).when(dataBroker).newReadOnlyTransaction();
247         doReturn(immediateFluentFuture(Optional.of(DATA_3))).when(read)
248             .read(LogicalDatastoreType.CONFIGURATION, PATH);
249         doReturn(immediateFluentFuture(Optional.empty())).when(read)
250             .read(LogicalDatastoreType.OPERATIONAL, PATH);
251         return mockStrategy();
252     }
253
254     @Override
255     RestconfStrategy readAllHavingOnlyNonConfigTestStrategy() {
256         doReturn(read).when(dataBroker).newReadOnlyTransaction();
257         doReturn(immediateFluentFuture(Optional.of(DATA_2))).when(read)
258             .read(LogicalDatastoreType.OPERATIONAL, PATH_2);
259         doReturn(immediateFluentFuture(Optional.empty())).when(read)
260             .read(LogicalDatastoreType.CONFIGURATION, PATH_2);
261         return mockStrategy();
262     }
263
264     @Override
265     RestconfStrategy readDataNonConfigTestStrategy() {
266         doReturn(read).when(dataBroker).newReadOnlyTransaction();
267         doReturn(immediateFluentFuture(Optional.of(DATA_2))).when(read)
268             .read(LogicalDatastoreType.OPERATIONAL, PATH_2);
269         return mockStrategy();
270     }
271
272     @Override
273     RestconfStrategy readContainerDataAllTestStrategy() {
274         doReturn(read).when(dataBroker).newReadOnlyTransaction();
275         doReturn(immediateFluentFuture(Optional.of(DATA_3))).when(read)
276             .read(LogicalDatastoreType.CONFIGURATION, PATH);
277         doReturn(immediateFluentFuture(Optional.of(DATA_4))).when(read)
278             .read(LogicalDatastoreType.OPERATIONAL, PATH);
279         return mockStrategy();
280     }
281
282     @Override
283     RestconfStrategy readContainerDataConfigNoValueOfContentTestStrategy() {
284         doReturn(read).when(dataBroker).newReadOnlyTransaction();
285         doReturn(immediateFluentFuture(Optional.of(DATA_3))).when(read)
286             .read(LogicalDatastoreType.CONFIGURATION, PATH);
287         doReturn(immediateFluentFuture(Optional.of(DATA_4))).when(read)
288             .read(LogicalDatastoreType.OPERATIONAL, PATH);
289         return mockStrategy();
290     }
291
292     @Override
293     RestconfStrategy readListDataAllTestStrategy() {
294         doReturn(read).when(dataBroker).newReadOnlyTransaction();
295         doReturn(immediateFluentFuture(Optional.of(LIST_DATA))).when(read)
296             .read(LogicalDatastoreType.OPERATIONAL, PATH_3);
297         doReturn(immediateFluentFuture(Optional.of(LIST_DATA_2))).when(read)
298             .read(LogicalDatastoreType.CONFIGURATION, PATH_3);
299         return mockStrategy();
300     }
301
302     @Override
303     RestconfStrategy readOrderedListDataAllTestStrategy() {
304         doReturn(read).when(dataBroker).newReadOnlyTransaction();
305         doReturn(immediateFluentFuture(Optional.of(ORDERED_MAP_NODE_1))).when(read)
306             .read(LogicalDatastoreType.OPERATIONAL, PATH_3);
307         doReturn(immediateFluentFuture(Optional.of(ORDERED_MAP_NODE_2))).when(read)
308             .read(LogicalDatastoreType.CONFIGURATION, PATH_3);
309         return mockStrategy();
310     }
311
312     @Override
313     RestconfStrategy readUnkeyedListDataAllTestStrategy() {
314         doReturn(read).when(dataBroker).newReadOnlyTransaction();
315         doReturn(immediateFluentFuture(Optional.of(UNKEYED_LIST_NODE_1))).when(read)
316             .read(LogicalDatastoreType.OPERATIONAL, PATH_3);
317         doReturn(immediateFluentFuture(Optional.of(UNKEYED_LIST_NODE_2))).when(read)
318             .read(LogicalDatastoreType.CONFIGURATION, PATH_3);
319         return mockStrategy();
320     }
321
322     @Override
323     RestconfStrategy readLeafListDataAllTestStrategy() {
324         doReturn(read).when(dataBroker).newReadOnlyTransaction();
325         doReturn(immediateFluentFuture(Optional.of(LEAF_SET_NODE_1))).when(read)
326             .read(LogicalDatastoreType.OPERATIONAL, LEAF_SET_NODE_PATH);
327         doReturn(immediateFluentFuture(Optional.of(LEAF_SET_NODE_2))).when(read)
328             .read(LogicalDatastoreType.CONFIGURATION, LEAF_SET_NODE_PATH);
329         return mockStrategy();
330     }
331
332     @Override
333     RestconfStrategy readOrderedLeafListDataAllTestStrategy() {
334         doReturn(read).when(dataBroker).newReadOnlyTransaction();
335         doReturn(immediateFluentFuture(Optional.of(ORDERED_LEAF_SET_NODE_1))).when(read)
336             .read(LogicalDatastoreType.OPERATIONAL, LEAF_SET_NODE_PATH);
337         doReturn(immediateFluentFuture(Optional.of(ORDERED_LEAF_SET_NODE_2))).when(read)
338             .read(LogicalDatastoreType.CONFIGURATION, LEAF_SET_NODE_PATH);
339         return mockStrategy();
340     }
341
342     @Override
343     RestconfStrategy readDataWrongPathOrNoContentTestStrategy() {
344         doReturn(read).when(dataBroker).newReadOnlyTransaction();
345         doReturn(immediateFluentFuture(Optional.empty())).when(read).read(LogicalDatastoreType.CONFIGURATION, PATH_2);
346         return mockStrategy();
347     }
348
349     @Test
350     public void readLeafWithDefaultParameters() {
351         final var data = ImmutableNodes.newContainerBuilder()
352             .withNodeIdentifier(new NodeIdentifier(CONT_QNAME))
353             .withChild(ImmutableNodes.leafNode(QName.create(BASE, "exampleLeaf"), "i am leaf"))
354             .build();
355         final var path = YangInstanceIdentifier.of(CONT_QNAME);
356         doReturn(read).when(dataBroker).newReadOnlyTransaction();
357         doReturn(immediateFluentFuture(Optional.of(data))).when(read)
358                 .read(LogicalDatastoreType.CONFIGURATION, path);
359         doReturn(immediateFluentFuture(Optional.of(data))).when(read)
360                 .read(LogicalDatastoreType.OPERATIONAL, path);
361
362         assertEquals(data, modulesStrategy().readData(ContentParam.ALL, path, WithDefaultsParam.TRIM));
363     }
364
365     @Test
366     public void readContainerWithDefaultParameters() {
367         final var exampleList = new NodeIdentifier(QName.create(BASE, "exampleList"));
368         final var data = ImmutableNodes.newContainerBuilder()
369             .withNodeIdentifier(new NodeIdentifier(CONT_QNAME))
370             .withChild(ImmutableNodes.newUnkeyedListBuilder()
371                 .withNodeIdentifier(exampleList)
372                 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
373                     .withNodeIdentifier(exampleList)
374                     .withChild(ImmutableNodes.newContainerBuilder()
375                         .withNodeIdentifier(new NodeIdentifier(QName.create(BASE, "containerBool")))
376                         .withChild(ImmutableNodes.leafNode(QName.create(BASE, "leafBool"), true))
377                         .build())
378                     .addChild(ImmutableNodes.newContainerBuilder()
379                         .withNodeIdentifier(new NodeIdentifier(QName.create(BASE, "containerInt")))
380                         .withChild(ImmutableNodes.leafNode(QName.create(BASE, "leafInt"), 12))
381                         .build())
382                     .build())
383                 .build())
384             .build();
385         final var path = YangInstanceIdentifier.of(CONT_QNAME);
386         doReturn(read).when(dataBroker).newReadOnlyTransaction();
387         doReturn(immediateFluentFuture(Optional.of(data))).when(read)
388                 .read(LogicalDatastoreType.CONFIGURATION, path);
389         doReturn(immediateFluentFuture(Optional.of(data))).when(read)
390                 .read(LogicalDatastoreType.OPERATIONAL, path);
391
392         assertEquals(data, modulesStrategy().readData(ContentParam.ALL, path, WithDefaultsParam.TRIM));
393     }
394
395     @Test
396     public void readLeafInListWithDefaultParameters() {
397         final var exampleList = new NodeIdentifier(QName.create(BASE, "exampleList"));
398         final var content = ImmutableNodes.newContainerBuilder()
399             .withNodeIdentifier(new NodeIdentifier(CONT_QNAME))
400             .withChild(ImmutableNodes.newUnkeyedListBuilder()
401                 .withNodeIdentifier(exampleList)
402                 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
403                     .withNodeIdentifier(exampleList)
404                     .addChild(ImmutableNodes.leafNode(QName.create(BASE, "leafInList"), "I am leaf in list"))
405                     .build())
406                 .build())
407             .build();
408         final var path = YangInstanceIdentifier.of(CONT_QNAME);
409         doReturn(read).when(dataBroker).newReadOnlyTransaction();
410         doReturn(immediateFluentFuture(Optional.of(content))).when(read)
411                 .read(LogicalDatastoreType.CONFIGURATION, path);
412         doReturn(immediateFluentFuture(Optional.of(content))).when(read)
413                 .read(LogicalDatastoreType.OPERATIONAL, path);
414
415         assertEquals(content, modulesStrategy().readData(ContentParam.ALL, path, WithDefaultsParam.TRIM));
416     }
417
418     @Test
419     public void testGetRestconfStrategyLocal() {
420         final var strategy = jukeboxStrategy();
421         assertEquals(new StrategyAndTail(strategy, ApiPath.empty()), strategy.resolveStrategy(ApiPath.empty()));
422     }
423
424     @Test
425     public void testGetRestconfStrategyMountDataBroker() throws Exception {
426         doReturn(Optional.empty()).when(mountPoint).getService(NetconfDataTreeService.class);
427         doReturn(Optional.of(dataBroker)).when(mountPoint).getService(DOMDataBroker.class);
428         doReturn(Optional.of(rpcService)).when(mountPoint).getService(DOMRpcService.class);
429         doReturn(Optional.of(new FixedDOMSchemaService(JUKEBOX_SCHEMA))).when(mountPoint)
430             .getService(DOMSchemaService.class);
431         doReturn(Optional.empty()).when(mountPoint).getService(DOMMountPointService.class);
432         doReturn(Optional.empty()).when(mountPoint).getService(DOMActionService.class);
433         doReturn(Optional.of(mountPoint)).when(mountPointService).getMountPoint(YangInstanceIdentifier.of());
434
435         final var strategy = jukeboxStrategy();
436         final var result = strategy.resolveStrategy(ApiPath.parse("yang-ext:mount"));
437         assertEquals(ApiPath.empty(), result.tail());
438         assertNotSame(strategy, assertInstanceOf(MdsalRestconfStrategy.class, result.strategy()));
439     }
440
441     @Test
442     public void testGetRestconfStrategyMountNetconfService() throws Exception {
443         doReturn(Optional.of(netconfService)).when(mountPoint).getService(NetconfDataTreeService.class);
444         doReturn(Optional.of(rpcService)).when(mountPoint).getService(DOMRpcService.class);
445         doReturn(Optional.of(new FixedDOMSchemaService(JUKEBOX_SCHEMA))).when(mountPoint)
446             .getService(DOMSchemaService.class);
447         doReturn(Optional.empty()).when(mountPoint).getService(DOMMountPointService.class);
448         doReturn(Optional.empty()).when(mountPoint).getService(DOMActionService.class);
449         doReturn(Optional.of(mountPoint)).when(mountPointService).getMountPoint(YangInstanceIdentifier.of());
450
451         final var strategy = jukeboxStrategy();
452         final var result = strategy.resolveStrategy(ApiPath.parse("yang-ext:mount"));
453         assertEquals(ApiPath.empty(), result.tail());
454         assertInstanceOf(NetconfRestconfStrategy.class, result.strategy());
455     }
456
457     @Test
458     public void testGetRestconfStrategyMountNone() throws Exception {
459         doReturn(JUKEBOX_IID).when(mountPoint).getIdentifier();
460         doReturn(Optional.empty()).when(mountPoint).getService(NetconfDataTreeService.class);
461         doReturn(Optional.empty()).when(mountPoint).getService(DOMDataBroker.class);
462         doReturn(Optional.empty()).when(mountPoint).getService(DOMMountPointService.class);
463         doReturn(Optional.empty()).when(mountPoint).getService(DOMActionService.class);
464         doReturn(Optional.of(rpcService)).when(mountPoint).getService(DOMRpcService.class);
465         doReturn(Optional.of(new FixedDOMSchemaService(JUKEBOX_SCHEMA))).when(mountPoint)
466             .getService(DOMSchemaService.class);
467         doReturn(Optional.of(mountPoint)).when(mountPointService).getMountPoint(YangInstanceIdentifier.of());
468
469         final var strategy = jukeboxStrategy();
470         final var mountPath = ApiPath.parse("yang-ext:mount");
471
472         final var ex = assertThrows(RestconfDocumentedException.class, () -> strategy.resolveStrategy(mountPath));
473         final var errors = ex.getErrors();
474         assertEquals(1, errors.size());
475         final var error = errors.get(0);
476         assertEquals(ErrorType.APPLICATION, error.getErrorType());
477         assertEquals(ErrorTag.OPERATION_FAILED, error.getErrorTag());
478         assertEquals("Could not find a supported access interface in mount point", error.getErrorMessage());
479         assertEquals(JUKEBOX_IID, error.getErrorPath());
480     }
481 }