bd90201ac6cb3600562aa8708f76427c1596a92c
[netconf.git] / restconf / restconf-nb / 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.assertThrows;
13 import static org.mockito.Mockito.when;
14
15 import java.io.FileNotFoundException;
16 import java.util.NoSuchElementException;
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.nb.rfc8040.TestRestconfUtils;
31 import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
32 import org.opendaylight.restconf.nb.rfc8040.rests.services.api.RestconfSchemaService;
33 import org.opendaylight.restconf.nb.rfc8040.rests.services.api.SchemaExportContext;
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. Trying to create <code>SchemaExportContext</code> with
129      * not-existing module should result in error.
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 & verify
137         assertThrows(NoSuchElementException.class, () -> schemaService.getSchema(NOT_EXISTING_MODULE));
138     }
139
140     /**
141      * Get schema with identifier of existing module behind mount point and check if correct module was found.
142      */
143     @Test
144     public void getSchemaMountPointTest() {
145         // prepare conditions - return schema context with mount points
146         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
147
148         // make test
149         final SchemaExportContext exportContext =
150                 schemaService.getSchema(MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT);
151
152         // verify
153         assertNotNull("Export context should not be null", exportContext);
154
155         final Module module = exportContext.getModule();
156         assertNotNull("Existing module should be found", module);
157
158         assertEquals("Not expected module name", "module1-behind-mount-point", module.getName());
159         assertEquals("Not expected module revision", Revision.ofNullable("2014-02-03"), module.getRevision());
160         assertEquals("Not expected module namespace", "module:1:behind:mount:point", module.getNamespace().toString());
161     }
162
163     /**
164      * Get schema with identifier of not-existing module behind mount point. Trying to create
165      * <code>SchemaExportContext</code> with not-existing module behind mount point should result in error.
166      */
167     @Test
168     public void getSchemaForNotExistingModuleMountPointTest() {
169         // prepare conditions - return schema context with mount points
170         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
171
172         // make test & verify
173         assertThrows(NoSuchElementException.class, () -> schemaService.getSchema(MOUNT_POINT + NOT_EXISTING_MODULE));
174     }
175
176     /**
177      * Try to get schema with <code>null</code> <code>SchemaContext</code> expecting <code>NullPointerException</code>.
178      */
179     @Test
180     public void getSchemaWithNullSchemaContextTest() {
181         // prepare conditions - returned schema context is null
182         when(this.mockContextHandler.get()).thenReturn(null);
183
184         // make test
185         assertThrows(NullPointerException.class, () -> schemaService.getSchema(TEST_MODULE));
186     }
187
188     /**
189      * Try to get schema with <code>null</code> <code>SchemaContext</code> for mount points.
190      * <code>NullPointerException</code> is expected.
191      */
192     @Test
193     public void getSchemaWithNullSchemaContextMountPointTest() {
194         // prepare conditions - returned schema context for mount points is null
195         when(this.mockContextHandler.get()).thenReturn(null);
196
197         // make test
198         assertThrows(NullPointerException.class,
199             () -> schemaService.getSchema(MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT));
200     }
201
202     /**
203      * Try to get schema with <code>null</code> <code>SchemaContext</code> behind mount point when using
204      * <code>NULL_MOUNT_POINT</code>. Test is expected to fail with <code>NullPointerException</code>.
205      */
206     @Test
207     public void getSchemaNullSchemaContextBehindMountPointTest() {
208         // prepare conditions - return correct schema context for mount points (this is not null)
209         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
210
211         // make test - call service on mount point with null schema context
212         assertThrows(IllegalStateException.class,
213             // NULL_MOUNT_POINT contains null schema context
214             () -> this.schemaService.getSchema(NULL_MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT));
215     }
216
217     /**
218      * Try to get schema with null identifier expecting <code>NullPointerException</code>. The same processing is for
219      * server and also for mount point.
220      */
221     @Test
222     public void getSchemaWithNullIdentifierTest() {
223         // prepare conditions - return correct schema context
224         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
225
226         // make test
227         assertThrows(NullPointerException.class, () -> this.schemaService.getSchema(null));
228     }
229
230     /**
231      * Try to get schema with empty (not valid) identifier catching <code>RestconfDocumentedException</code>. Error
232      * type, error tag and error status code are compared to expected values.
233      */
234     @Test
235     public void getSchemaWithEmptyIdentifierTest() {
236         // prepare conditions - return correct schema context
237         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
238
239         // make test and verify
240         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
241             () -> schemaService.getSchema(""));
242         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
243         assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
244     }
245
246     /**
247      * Try to get schema with empty (not valid) identifier behind mount point catching
248      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
249      * values.
250      */
251     @Test
252     public void getSchemaWithEmptyIdentifierMountPointTest() {
253         // prepare conditions - return correct schema context with mount points
254         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
255
256         // make test and verify
257         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
258             () -> schemaService.getSchema(MOUNT_POINT + ""));
259         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
260         assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
261     }
262
263     /**
264      * Try to get schema with not-parsable identifier catching <code>RestconfDocumentedException</code>. Error type,
265      * error tag and error status code are compared to expected values.
266      */
267     @Test
268     public void getSchemaWithNotParsableIdentifierTest() {
269         // prepare conditions - return correct schema context without mount points
270         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
271
272         // make test and verify
273         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
274             () -> schemaService.getSchema("01_module/2016-01-01"));
275         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
276         assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
277     }
278
279     /**
280      * Try to get schema behind mount point with not-parsable identifier catching
281      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
282      * values.
283      */
284     @Test
285     public void getSchemaWithNotParsableIdentifierMountPointTest() {
286         // prepare conditions - return correct schema context with mount points
287         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
288
289         // make test and verify
290         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
291             () -> schemaService.getSchema(MOUNT_POINT + "01_module/2016-01-01"));
292         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
293         assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
294     }
295
296     /**
297      * Try to get schema with wrong (not valid) identifier catching <code>RestconfDocumentedException</code>. Error
298      * type, error tag and error status code are compared to expected values.
299      *
300      * <p>
301      * Not valid identifier contains only revision without module name.
302      */
303     @Test
304     public void getSchemaWrongIdentifierTest() {
305         // prepare conditions - return correct schema context without mount points
306         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
307
308         // make test and verify
309         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
310             () -> schemaService.getSchema("2014-01-01"));
311         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
312         assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
313     }
314
315     /**
316      * Try to get schema with wrong (not valid) identifier behind mount point catching
317      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
318      * values.
319      *
320      * <p>
321      * Not valid identifier contains only revision without module name.
322      */
323     @Test
324     public void getSchemaWrongIdentifierMountPointTest() {
325         // prepare conditions - return correct schema context with mount points
326         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
327
328         // make test and verify
329         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
330             () -> schemaService.getSchema(MOUNT_POINT + "2014-01-01"));
331         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
332         assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
333     }
334
335     /**
336      * Try to get schema with identifier which does not contain revision catching
337      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
338      * values.
339      */
340     @Test
341     public void getSchemaWithoutRevisionTest() {
342         // prepare conditions - return correct schema context without mount points
343         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
344
345         // make test and verify
346         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
347             () -> schemaService.getSchema("module"));
348         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
349         assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
350     }
351
352     /**
353      * Try to get schema behind mount point with identifier when does not contain revision catching
354      * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
355      * values.
356      */
357     @Test
358     public void getSchemaWithoutRevisionMountPointTest() {
359         // prepare conditions - return correct schema context with mount points
360         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
361
362         // make test and verify
363         final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
364             () -> schemaService.getSchema(MOUNT_POINT + "module"));
365         assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
366         assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
367     }
368
369     /**
370      * Negative test when mount point module is not found in current <code>SchemaContext</code> for mount points.
371      * <code>IllegalArgumentException</code> exception is expected.
372      */
373     @Test
374     public void getSchemaContextWithNotExistingMountPointTest() {
375         // prepare conditions - return schema context with mount points
376         when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
377
378         // make test
379         assertThrows(RestconfDocumentedException.class,
380             () -> schemaService.getSchema(NOT_EXISTING_MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT));
381     }
382 }