Bump upstreams
[netconf.git] / restconf / restconf-nb / src / test / java / org / opendaylight / restconf / nb / jaxrs / RestconfSchemaServiceMountTest.java
1 /*
2  * Copyright (c) 2016 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.restconf.nb.jaxrs;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.mockito.ArgumentMatchers.any;
12 import static org.mockito.Mockito.doCallRealMethod;
13 import static org.mockito.Mockito.doReturn;
14 import static org.opendaylight.restconf.nb.jaxrs.AbstractRestconfTest.assertEntity;
15 import static org.opendaylight.restconf.nb.jaxrs.AbstractRestconfTest.assertError;
16
17 import com.google.common.io.CharStreams;
18 import java.io.Reader;
19 import java.util.List;
20 import org.junit.Before;
21 import org.junit.Test;
22 import org.junit.runner.RunWith;
23 import org.mockito.Mock;
24 import org.mockito.junit.MockitoJUnitRunner;
25 import org.opendaylight.mdsal.dom.api.DOMActionService;
26 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
27 import org.opendaylight.mdsal.dom.api.DOMRpcService;
28 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
29 import org.opendaylight.mdsal.dom.api.DOMSchemaService.YangTextSourceExtension;
30 import org.opendaylight.mdsal.dom.broker.DOMMountPointServiceImpl;
31 import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
32 import org.opendaylight.restconf.api.ApiPath;
33 import org.opendaylight.restconf.nb.rfc8040.legacy.ErrorTags;
34 import org.opendaylight.restconf.server.mdsal.MdsalRestconfServer;
35 import org.opendaylight.yangtools.yang.common.ErrorTag;
36 import org.opendaylight.yangtools.yang.common.ErrorType;
37 import org.opendaylight.yangtools.yang.common.QName;
38 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
39 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
40 import org.opendaylight.yangtools.yang.model.api.source.YangTextSource;
41 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
42
43 /**
44  * Unit tests for {@code RestconfSchemaService}.
45  */
46 @RunWith(MockitoJUnitRunner.StrictStubs.class)
47 public class RestconfSchemaServiceMountTest {
48     private static final ApiPath MOUNT_POINT = AbstractRestconfTest.apiPath("mount-point-1:cont/yang-ext:mount");
49     private static final ApiPath NULL_MOUNT_POINT = AbstractRestconfTest.apiPath("mount-point-2:cont/yang-ext:mount");
50     private static final ApiPath NOT_EXISTING_MOUNT_POINT =
51         AbstractRestconfTest.apiPath("mount-point-3:cont/yang-ext:mount");
52
53     // schema context with modules behind mount point
54     private static final EffectiveModelContext SCHEMA_CONTEXT_BEHIND_MOUNT_POINT =
55         YangParserTestUtils.parseYangResourceDirectory("/modules/modules-behind-mount-point");
56     // schema context with mount points
57     private static final EffectiveModelContext SCHEMA_CONTEXT_WITH_MOUNT_POINTS =
58         YangParserTestUtils.parseYangResourceDirectory("/modules/mount-points");
59
60     // handlers
61     @Mock
62     private DOMSchemaService schemaService;
63     @Mock
64     private YangTextSourceExtension sourceProvider;
65     @Mock
66     private DOMDataBroker dataBroker;
67     @Mock
68     private DOMActionService actionService;
69     @Mock
70     private DOMRpcService rpcService;
71     @Mock
72     private YangTextSource yangSource;
73     @Mock
74     private Reader yangReader;
75
76     // service under test
77     private JaxRsRestconf restconf;
78
79     @Before
80     public void setup() throws Exception {
81         final var mountPointService = new DOMMountPointServiceImpl();
82         // create and register mount points
83         mountPointService
84                 .createMountPoint(YangInstanceIdentifier.of(QName.create("mount:point:1", "2016-01-01", "cont")))
85                 .addService(DOMSchemaService.class, new FixedDOMSchemaService(SCHEMA_CONTEXT_BEHIND_MOUNT_POINT))
86                 .addService(DOMDataBroker.class, dataBroker)
87                 .register();
88         mountPointService
89                 .createMountPoint(YangInstanceIdentifier.of(QName.create("mount:point:2", "2016-01-01", "cont")))
90                 .register();
91
92         doCallRealMethod().when(schemaService).extension(any());
93         doReturn(List.of(sourceProvider)).when(schemaService).supportedExtensions();
94         doReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS).when(schemaService).getGlobalContext();
95
96         restconf = new JaxRsRestconf(new MdsalRestconfServer(schemaService, dataBroker, rpcService, actionService,
97             mountPointService));
98     }
99
100     /**
101      * Get schema with identifier of existing module behind mount point and check if correct module was found.
102      */
103     @Test
104     public void getSchemaMountPointTest() throws Exception {
105         final var reader = assertEntity(Reader.class, 200,
106             ar -> restconf.modulesYangGET(MOUNT_POINT, "module1-behind-mount-point", "2014-02-03", ar));
107         assertEquals("""
108             module module1-behind-mount-point {
109               namespace module:1:behind:mount:point;
110               prefix mod1bemopo;
111               revision 2014-02-03;
112               rpc rpc-behind-module1;
113             }
114             """, CharStreams.toString(reader));
115     }
116
117     /**
118      * Get schema with identifier of not-existing module behind mount point. Trying to create
119      * <code>SchemaExportContext</code> with not-existing module behind mount point should result in error.
120      */
121     @Test
122     public void getSchemaForNotExistingModuleMountPointTest() {
123         final var error = assertError(ar -> restconf.modulesYangGET(MOUNT_POINT, "not-existing", "2016-01-01", ar));
124         assertEquals("Source not-existing@2016-01-01 not found", error.getErrorMessage());
125         assertEquals(ErrorTag.DATA_MISSING, error.getErrorTag());
126         assertEquals(ErrorType.APPLICATION, error.getErrorType());
127     }
128
129     /**
130      * Try to get schema with <code>null</code> <code>SchemaContext</code> behind mount point when using
131      * <code>NULL_MOUNT_POINT</code>. Test is expected to fail with <code>NullPointerException</code>.
132      */
133     @Test
134     public void getSchemaNullSchemaContextBehindMountPointTest() {
135         // make test - call service on mount point with null schema context
136         // NULL_MOUNT_POINT contains null schema context
137         final var error = assertError(
138             ar -> restconf.modulesYangGET(NULL_MOUNT_POINT, "module1-behind-mount-point", "2014-02-03", ar));
139         assertEquals("Mount point 'mount-point-2:cont' does not expose DOMSchemaService", error.getErrorMessage());
140         assertEquals(ErrorType.PROTOCOL, error.getErrorType());
141         assertEquals(ErrorTags.RESOURCE_DENIED_TRANSPORT, error.getErrorTag());
142     }
143
144     /**
145      * Try to get schema with empty (not valid) identifier behind mount point catching
146      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
147      * values.
148      */
149     @Test
150     public void getSchemaWithEmptyIdentifierMountPointTest() {
151         final var error = assertError(ar -> restconf.modulesYangGET(MOUNT_POINT, "", null, ar));
152         assertEquals("Identifier must start with character from set 'a-zA-Z_", error.getErrorMessage());
153         assertEquals(ErrorType.PROTOCOL, error.getErrorType());
154         assertEquals(ErrorTag.INVALID_VALUE, error.getErrorTag());
155     }
156
157     /**
158      * Try to get schema behind mount point with not-parsable identifier catching
159      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
160      * values.
161      */
162     @Test
163     public void getSchemaWithNotParsableIdentifierMountPointTest() {
164         final var error = assertError(ar -> restconf.modulesYangGET(MOUNT_POINT, "01_module", "2016-01-01", ar));
165         assertEquals("Identifier must start with character from set 'a-zA-Z_", error.getErrorMessage());
166         assertEquals(ErrorType.PROTOCOL, error.getErrorType());
167         assertEquals(ErrorTag.INVALID_VALUE, error.getErrorTag());
168     }
169
170     /**
171      * Try to get schema with wrong (not valid) identifier behind mount point catching
172      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
173      * values.
174      *
175      * <p>
176      * Not valid identifier contains only revision without module name.
177      */
178     @Test
179     public void getSchemaWrongIdentifierMountPointTest() {
180         final var error = assertError(ar -> restconf.modulesYangGET(MOUNT_POINT, "2014-01-01", null, ar));
181         assertEquals("Identifier must start with character from set 'a-zA-Z_", error.getErrorMessage());
182         assertEquals(ErrorType.PROTOCOL, error.getErrorType());
183         assertEquals(ErrorTag.INVALID_VALUE, error.getErrorTag());
184     }
185
186     /**
187      * Try to get schema behind mount point with identifier when does not contain revision catching
188      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
189      * values.
190      */
191     @Test
192     public void getSchemaWithoutRevisionMountPointTest() {
193         final var error = assertError(ar -> restconf.modulesYangGET(MOUNT_POINT, "module", null, ar));
194         assertEquals("Source module not found", error.getErrorMessage());
195         assertEquals(ErrorType.APPLICATION, error.getErrorType());
196         assertEquals(ErrorTag.DATA_MISSING, error.getErrorTag());
197     }
198
199     /**
200      * Negative test when mount point module is not found in current <code>SchemaContext</code> for mount points.
201      * <code>IllegalArgumentException</code> exception is expected.
202      */
203     @Test
204     public void getSchemaContextWithNotExistingMountPointTest() {
205         final var error = assertError(
206             ar -> restconf.modulesYangGET(NOT_EXISTING_MOUNT_POINT, "module1-behind-mount-point", "2014-02-03", ar));
207         assertEquals("Failed to lookup for module with name 'mount-point-3'.", error.getErrorMessage());
208         assertEquals(ErrorType.PROTOCOL, error.getErrorType());
209         assertEquals(ErrorTag.UNKNOWN_ELEMENT, error.getErrorTag());
210     }
211 }