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