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