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