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