33ba82bbb77edf6c2a833399a25cf4e8cc2653ea
[netconf.git] / restconf / restconf-nb-rfc8040 / src / test / java / org / opendaylight / restconf / nb / rfc8040 / rests / services / impl / RestconfSchemaServiceTest.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.rfc8040.rests.services.impl;
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.junit.Assert.assertThrows;
14 import static org.mockito.Mockito.when;
15
16 import java.io.FileNotFoundException;
17 import org.junit.AfterClass;
18 import org.junit.Before;
19 import org.junit.BeforeClass;
20 import org.junit.Test;
21 import org.junit.runner.RunWith;
22 import org.mockito.Mock;
23 import org.mockito.junit.MockitoJUnitRunner;
24 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
25 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
26 import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
27 import org.opendaylight.mdsal.dom.broker.DOMMountPointServiceImpl;
28 import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
29 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
30 import org.opendaylight.restconf.common.schema.SchemaExportContext;
31 import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
32 import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
33 import org.opendaylight.restconf.nb.rfc8040.rests.services.api.RestconfSchemaService;
34 import org.opendaylight.yangtools.yang.common.ErrorTag;
35 import org.opendaylight.yangtools.yang.common.ErrorType;
36 import org.opendaylight.yangtools.yang.common.QName;
37 import org.opendaylight.yangtools.yang.common.Revision;
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.Module;
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 RestconfSchemaServiceTest {
48     private static final String MOUNT_POINT = "mount-point-1:cont/yang-ext:mount/";
49     private static final String NULL_MOUNT_POINT = "mount-point-2:cont/yang-ext:mount/";
50     private static final String NOT_EXISTING_MOUNT_POINT = "mount-point-3:cont/yang-ext:mount/";
51
52     private static final String TEST_MODULE = "module1/2014-01-01";
53     private static final String TEST_MODULE_BEHIND_MOUNT_POINT = "module1-behind-mount-point/2014-02-03";
54     private static final String NOT_EXISTING_MODULE = "not-existing/2016-01-01";
55
56     // schema context with modules
57     private static EffectiveModelContext SCHEMA_CONTEXT;
58     // schema context with modules behind mount point
59     private static EffectiveModelContext SCHEMA_CONTEXT_BEHIND_MOUNT_POINT;
60     // schema context with mount points
61     private static EffectiveModelContext SCHEMA_CONTEXT_WITH_MOUNT_POINTS;
62
63     // service under test
64     private RestconfSchemaService schemaService;
65
66     // handlers
67     @Mock
68     private SchemaContextHandler mockContextHandler;
69     @Mock
70     private DOMYangTextSourceProvider sourceProvider;
71     // mount point service
72     private DOMMountPointService mountPointService;
73
74     @BeforeClass
75     public static void beforeClass() throws FileNotFoundException {
76         SCHEMA_CONTEXT = YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/modules"));
77         SCHEMA_CONTEXT_BEHIND_MOUNT_POINT = YangParserTestUtils.parseYangFiles(
78             TestRestconfUtils.loadFiles("/modules/modules-behind-mount-point"));
79         SCHEMA_CONTEXT_WITH_MOUNT_POINTS = YangParserTestUtils.parseYangFiles(
80             TestRestconfUtils.loadFiles("/modules/mount-points"));
81     }
82
83     @AfterClass
84     public static void afterClass() {
85         SCHEMA_CONTEXT = null;
86         SCHEMA_CONTEXT_BEHIND_MOUNT_POINT = null;
87         SCHEMA_CONTEXT_WITH_MOUNT_POINTS = null;
88     }
89
90     @Before
91     public void setup() throws Exception {
92         this.mountPointService = new DOMMountPointServiceImpl();
93         // create and register mount points
94         mountPointService
95                 .createMountPoint(YangInstanceIdentifier.of(QName.create("mount:point:1", "2016-01-01", "cont")))
96                 .addService(DOMSchemaService.class, FixedDOMSchemaService.of(SCHEMA_CONTEXT_BEHIND_MOUNT_POINT))
97                 .register();
98         mountPointService
99                 .createMountPoint(YangInstanceIdentifier.of(QName.create("mount:point:2", "2016-01-01", "cont")))
100                 .register();
101
102         this.schemaService = new RestconfSchemaServiceImpl(this.mockContextHandler, mountPointService, sourceProvider);
103     }
104
105     /**
106      * Get schema with identifier of existing module and check if correct module was found.
107      */
108     @Test
109     public void getSchemaTest() {
110         // prepare conditions - return not-mount point schema context
111         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
112
113         // make test
114         final SchemaExportContext exportContext = schemaService.getSchema(TEST_MODULE);
115
116         // verify
117         assertNotNull("Export context should not be null", exportContext);
118
119         final Module module = exportContext.getModule();
120         assertNotNull("Existing module should be found", module);
121
122         assertEquals("Not expected module name", "module1", module.getName());
123         assertEquals("Not expected module revision", Revision.ofNullable("2014-01-01"), module.getRevision());
124         assertEquals("Not expected module namespace", "module:1", module.getNamespace().toString());
125     }
126
127     /**
128      * Get schema with identifier of not-existing module. <code>SchemaExportContext</code> is still created, but module
129      * should be set to <code>null</code>.
130      */
131     @Test
132     public void getSchemaForNotExistingModuleTest() {
133         // prepare conditions - return not-mount point schema context
134         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
135
136         // make test
137         final SchemaExportContext exportContext = schemaService.getSchema(NOT_EXISTING_MODULE);
138
139         // verify
140         assertNotNull("Export context should not be null", exportContext);
141         assertNull("Not-existing module should not be found", exportContext.getModule());
142     }
143
144     /**
145      * Get schema with identifier of existing module behind mount point and check if correct module was found.
146      */
147     @Test
148     public void getSchemaMountPointTest() {
149         // prepare conditions - return schema context with mount points
150         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
151
152         // make test
153         final SchemaExportContext exportContext =
154                 schemaService.getSchema(MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT);
155
156         // verify
157         assertNotNull("Export context should not be null", exportContext);
158
159         final Module module = exportContext.getModule();
160         assertNotNull("Existing module should be found", module);
161
162         assertEquals("Not expected module name", "module1-behind-mount-point", module.getName());
163         assertEquals("Not expected module revision", Revision.ofNullable("2014-02-03"), module.getRevision());
164         assertEquals("Not expected module namespace", "module:1:behind:mount:point", module.getNamespace().toString());
165     }
166
167     /**
168      * Get schema with identifier of not-existing module behind mount point. <code>SchemaExportContext</code> is still
169      * created, but module should be set to <code>null</code>.
170      */
171     @Test
172     public void getSchemaForNotExistingModuleMountPointTest() {
173         // prepare conditions - return schema context with mount points
174         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
175
176         // make test
177         final SchemaExportContext exportContext = schemaService.getSchema(MOUNT_POINT + NOT_EXISTING_MODULE);
178
179         // verify
180         assertNotNull("Export context should not be null", exportContext);
181         assertNull("Not-existing module should not be found", exportContext.getModule());
182     }
183
184     /**
185      * Try to get schema with <code>null</code> <code>SchemaContext</code> expecting <code>NullPointerException</code>.
186      */
187     @Test
188     public void getSchemaWithNullSchemaContextTest() {
189         // prepare conditions - returned schema context is null
190         when(this.mockContextHandler.get()).thenReturn(null);
191
192         // make test
193         assertThrows(NullPointerException.class, () -> schemaService.getSchema(TEST_MODULE));
194     }
195
196     /**
197      * Try to get schema with <code>null</code> <code>SchemaContext</code> for mount points.
198      * <code>NullPointerException</code> is expected.
199      */
200     @Test
201     public void getSchemaWithNullSchemaContextMountPointTest() {
202         // prepare conditions - returned schema context for mount points is null
203         when(this.mockContextHandler.get()).thenReturn(null);
204
205         // make test
206         assertThrows(NullPointerException.class,
207             () -> schemaService.getSchema(MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT));
208     }
209
210     /**
211      * Try to get schema with <code>null</code> <code>SchemaContext</code> behind mount point when using
212      * <code>NULL_MOUNT_POINT</code>. Test is expected to fail with <code>NullPointerException</code>.
213      */
214     @Test
215     public void getSchemaNullSchemaContextBehindMountPointTest() {
216         // prepare conditions - return correct schema context for mount points (this is not null)
217         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
218
219         // make test - call service on mount point with null schema context
220         assertThrows(IllegalStateException.class,
221             // NULL_MOUNT_POINT contains null schema context
222             () -> this.schemaService.getSchema(NULL_MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT));
223     }
224
225     /**
226      * Try to get schema with null identifier expecting <code>NullPointerException</code>. The same processing is for
227      * server and also for mount point.
228      */
229     @Test
230     public void getSchemaWithNullIdentifierTest() {
231         // prepare conditions - return correct schema context
232         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
233
234         // make test
235         assertThrows(NullPointerException.class, () -> this.schemaService.getSchema(null));
236     }
237
238     /**
239      * Try to get schema with empty (not valid) identifier catching <code>RestconfDocumentedException</code>. Error
240      * type, error tag and error status code are compared to expected values.
241      */
242     @Test
243     public void getSchemaWithEmptyIdentifierTest() {
244         // prepare conditions - return correct schema context
245         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
246
247         // make test and verify
248         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
249             () -> schemaService.getSchema(""));
250         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
251         assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
252     }
253
254     /**
255      * Try to get schema with empty (not valid) identifier behind mount point catching
256      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
257      * values.
258      */
259     @Test
260     public void getSchemaWithEmptyIdentifierMountPointTest() {
261         // prepare conditions - return correct schema context with mount points
262         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
263
264         // make test and verify
265         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
266             () -> schemaService.getSchema(MOUNT_POINT + ""));
267         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
268         assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
269     }
270
271     /**
272      * Try to get schema with not-parsable identifier catching <code>RestconfDocumentedException</code>. Error type,
273      * error tag and error status code are compared to expected values.
274      */
275     @Test
276     public void getSchemaWithNotParsableIdentifierTest() {
277         // prepare conditions - return correct schema context without mount points
278         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
279
280         // make test and verify
281         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
282             () -> schemaService.getSchema("01_module/2016-01-01"));
283         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
284         assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
285     }
286
287     /**
288      * Try to get schema behind mount point with not-parsable identifier catching
289      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
290      * values.
291      */
292     @Test
293     public void getSchemaWithNotParsableIdentifierMountPointTest() {
294         // prepare conditions - return correct schema context with mount points
295         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
296
297         // make test and verify
298         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
299             () -> schemaService.getSchema(MOUNT_POINT + "01_module/2016-01-01"));
300         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
301         assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
302     }
303
304     /**
305      * Try to get schema with wrong (not valid) identifier catching <code>RestconfDocumentedException</code>. Error
306      * type, error tag and error status code are compared to expected values.
307      *
308      * <p>
309      * Not valid identifier contains only revision without module name.
310      */
311     @Test
312     public void getSchemaWrongIdentifierTest() {
313         // prepare conditions - return correct schema context without mount points
314         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
315
316         // make test and verify
317         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
318             () -> schemaService.getSchema("2014-01-01"));
319         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
320         assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
321     }
322
323     /**
324      * Try to get schema with wrong (not valid) identifier behind mount point catching
325      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
326      * values.
327      *
328      * <p>
329      * Not valid identifier contains only revision without module name.
330      */
331     @Test
332     public void getSchemaWrongIdentifierMountPointTest() {
333         // prepare conditions - return correct schema context with mount points
334         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
335
336         // make test and verify
337         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
338             () -> schemaService.getSchema(MOUNT_POINT + "2014-01-01"));
339         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
340         assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
341     }
342
343     /**
344      * Try to get schema with identifier which does not contain revision catching
345      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
346      * values.
347      */
348     @Test
349     public void getSchemaWithoutRevisionTest() {
350         // prepare conditions - return correct schema context without mount points
351         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
352
353         // make test and verify
354         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
355             () -> schemaService.getSchema("module"));
356         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
357         assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
358     }
359
360     /**
361      * Try to get schema behind mount point with identifier when does not contain revision catching
362      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
363      * values.
364      */
365     @Test
366     public void getSchemaWithoutRevisionMountPointTest() {
367         // prepare conditions - return correct schema context with mount points
368         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
369
370         // make test and verify
371         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
372             () -> schemaService.getSchema(MOUNT_POINT + "module"));
373         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
374         assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
375     }
376
377     /**
378      * Negative test when mount point module is not found in current <code>SchemaContext</code> for mount points.
379      * <code>IllegalArgumentException</code> exception is expected.
380      */
381     @Test
382     public void getSchemaContextWithNotExistingMountPointTest() {
383         // prepare conditions - return schema context with mount points
384         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
385
386         // make test
387         assertThrows(RestconfDocumentedException.class,
388             () -> schemaService.getSchema(NOT_EXISTING_MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT));
389     }
390 }