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