2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.restconf.nb.rfc8040.rests.services.impl;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertNull;
13 import static org.junit.Assert.assertThrows;
14 import static org.mockito.Mockito.when;
16 import java.io.FileNotFoundException;
17 import org.junit.AfterClass;
18 import org.junit.Before;
19 import org.junit.BeforeClass;
20 import org.junit.Test;
21 import org.junit.runner.RunWith;
22 import org.mockito.Mock;
23 import org.mockito.junit.MockitoJUnitRunner;
24 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
25 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
26 import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
27 import org.opendaylight.mdsal.dom.broker.DOMMountPointServiceImpl;
28 import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
29 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
30 import org.opendaylight.restconf.common.schema.SchemaExportContext;
31 import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
32 import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
33 import org.opendaylight.restconf.nb.rfc8040.rests.services.api.RestconfSchemaService;
34 import org.opendaylight.yangtools.yang.common.ErrorTag;
35 import org.opendaylight.yangtools.yang.common.ErrorType;
36 import org.opendaylight.yangtools.yang.common.QName;
37 import org.opendaylight.yangtools.yang.common.Revision;
38 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
39 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
40 import org.opendaylight.yangtools.yang.model.api.Module;
41 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
44 * Unit tests for {@code RestconfSchemaService}.
46 @RunWith(MockitoJUnitRunner.StrictStubs.class)
47 public class RestconfSchemaServiceTest {
48 private static final String MOUNT_POINT = "mount-point-1:cont/yang-ext:mount/";
49 private static final String NULL_MOUNT_POINT = "mount-point-2:cont/yang-ext:mount/";
50 private static final String NOT_EXISTING_MOUNT_POINT = "mount-point-3:cont/yang-ext:mount/";
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";
56 // schema context with modules
57 private static EffectiveModelContext SCHEMA_CONTEXT;
58 // schema context with modules behind mount point
59 private static EffectiveModelContext SCHEMA_CONTEXT_BEHIND_MOUNT_POINT;
60 // schema context with mount points
61 private static EffectiveModelContext SCHEMA_CONTEXT_WITH_MOUNT_POINTS;
64 private RestconfSchemaService schemaService;
68 private SchemaContextHandler mockContextHandler;
70 private DOMYangTextSourceProvider sourceProvider;
71 // mount point service
72 private DOMMountPointService mountPointService;
75 public static void beforeClass() throws FileNotFoundException {
76 SCHEMA_CONTEXT = YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/modules"));
77 SCHEMA_CONTEXT_BEHIND_MOUNT_POINT = YangParserTestUtils.parseYangFiles(
78 TestRestconfUtils.loadFiles("/modules/modules-behind-mount-point"));
79 SCHEMA_CONTEXT_WITH_MOUNT_POINTS = YangParserTestUtils.parseYangFiles(
80 TestRestconfUtils.loadFiles("/modules/mount-points"));
84 public static void afterClass() {
85 SCHEMA_CONTEXT = null;
86 SCHEMA_CONTEXT_BEHIND_MOUNT_POINT = null;
87 SCHEMA_CONTEXT_WITH_MOUNT_POINTS = null;
91 public void setup() throws Exception {
92 this.mountPointService = new DOMMountPointServiceImpl();
93 // create and register mount points
95 .createMountPoint(YangInstanceIdentifier.of(QName.create("mount:point:1", "2016-01-01", "cont")))
96 .addService(DOMSchemaService.class, FixedDOMSchemaService.of(SCHEMA_CONTEXT_BEHIND_MOUNT_POINT))
99 .createMountPoint(YangInstanceIdentifier.of(QName.create("mount:point:2", "2016-01-01", "cont")))
102 this.schemaService = new RestconfSchemaServiceImpl(this.mockContextHandler, mountPointService, sourceProvider);
106 * Get schema with identifier of existing module and check if correct module was found.
109 public void getSchemaTest() {
110 // prepare conditions - return not-mount point schema context
111 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
114 final SchemaExportContext exportContext = schemaService.getSchema(TEST_MODULE);
117 assertNotNull("Export context should not be null", exportContext);
119 final Module module = exportContext.getModule();
120 assertNotNull("Existing module should be found", module);
122 assertEquals("Not expected module name", "module1", module.getName());
123 assertEquals("Not expected module revision", Revision.ofNullable("2014-01-01"), module.getRevision());
124 assertEquals("Not expected module namespace", "module:1", module.getNamespace().toString());
128 * Get schema with identifier of not-existing module. <code>SchemaExportContext</code> is still created, but module
129 * should be set to <code>null</code>.
132 public void getSchemaForNotExistingModuleTest() {
133 // prepare conditions - return not-mount point schema context
134 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
137 final SchemaExportContext exportContext = schemaService.getSchema(NOT_EXISTING_MODULE);
140 assertNotNull("Export context should not be null", exportContext);
141 assertNull("Not-existing module should not be found", exportContext.getModule());
145 * Get schema with identifier of existing module behind mount point and check if correct module was found.
148 public void getSchemaMountPointTest() {
149 // prepare conditions - return schema context with mount points
150 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
153 final SchemaExportContext exportContext =
154 schemaService.getSchema(MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT);
157 assertNotNull("Export context should not be null", exportContext);
159 final Module module = exportContext.getModule();
160 assertNotNull("Existing module should be found", module);
162 assertEquals("Not expected module name", "module1-behind-mount-point", module.getName());
163 assertEquals("Not expected module revision", Revision.ofNullable("2014-02-03"), module.getRevision());
164 assertEquals("Not expected module namespace", "module:1:behind:mount:point", module.getNamespace().toString());
168 * Get schema with identifier of not-existing module behind mount point. <code>SchemaExportContext</code> is still
169 * created, but module should be set to <code>null</code>.
172 public void getSchemaForNotExistingModuleMountPointTest() {
173 // prepare conditions - return schema context with mount points
174 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
177 final SchemaExportContext exportContext = schemaService.getSchema(MOUNT_POINT + NOT_EXISTING_MODULE);
180 assertNotNull("Export context should not be null", exportContext);
181 assertNull("Not-existing module should not be found", exportContext.getModule());
185 * Try to get schema with <code>null</code> <code>SchemaContext</code> expecting <code>NullPointerException</code>.
188 public void getSchemaWithNullSchemaContextTest() {
189 // prepare conditions - returned schema context is null
190 when(this.mockContextHandler.get()).thenReturn(null);
193 assertThrows(NullPointerException.class, () -> schemaService.getSchema(TEST_MODULE));
197 * Try to get schema with <code>null</code> <code>SchemaContext</code> for mount points.
198 * <code>NullPointerException</code> is expected.
201 public void getSchemaWithNullSchemaContextMountPointTest() {
202 // prepare conditions - returned schema context for mount points is null
203 when(this.mockContextHandler.get()).thenReturn(null);
206 assertThrows(NullPointerException.class,
207 () -> schemaService.getSchema(MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT));
211 * Try to get schema with <code>null</code> <code>SchemaContext</code> behind mount point when using
212 * <code>NULL_MOUNT_POINT</code>. Test is expected to fail with <code>NullPointerException</code>.
215 public void getSchemaNullSchemaContextBehindMountPointTest() {
216 // prepare conditions - return correct schema context for mount points (this is not null)
217 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
219 // make test - call service on mount point with null schema context
220 assertThrows(IllegalStateException.class,
221 // NULL_MOUNT_POINT contains null schema context
222 () -> this.schemaService.getSchema(NULL_MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT));
226 * Try to get schema with null identifier expecting <code>NullPointerException</code>. The same processing is for
227 * server and also for mount point.
230 public void getSchemaWithNullIdentifierTest() {
231 // prepare conditions - return correct schema context
232 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
235 assertThrows(NullPointerException.class, () -> this.schemaService.getSchema(null));
239 * Try to get schema with empty (not valid) identifier catching <code>RestconfDocumentedException</code>. Error
240 * type, error tag and error status code are compared to expected values.
243 public void getSchemaWithEmptyIdentifierTest() {
244 // prepare conditions - return correct schema context
245 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
247 // make test and verify
248 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
249 () -> schemaService.getSchema(""));
250 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
251 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
255 * Try to get schema with empty (not valid) identifier behind mount point catching
256 * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
260 public void getSchemaWithEmptyIdentifierMountPointTest() {
261 // prepare conditions - return correct schema context with mount points
262 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
264 // make test and verify
265 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
266 () -> schemaService.getSchema(MOUNT_POINT + ""));
267 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
268 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
272 * Try to get schema with not-parsable identifier catching <code>RestconfDocumentedException</code>. Error type,
273 * error tag and error status code are compared to expected values.
276 public void getSchemaWithNotParsableIdentifierTest() {
277 // prepare conditions - return correct schema context without mount points
278 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
280 // make test and verify
281 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
282 () -> schemaService.getSchema("01_module/2016-01-01"));
283 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
284 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
288 * Try to get schema behind mount point with not-parsable identifier catching
289 * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
293 public void getSchemaWithNotParsableIdentifierMountPointTest() {
294 // prepare conditions - return correct schema context with mount points
295 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
297 // make test and verify
298 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
299 () -> schemaService.getSchema(MOUNT_POINT + "01_module/2016-01-01"));
300 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
301 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
305 * Try to get schema with wrong (not valid) identifier catching <code>RestconfDocumentedException</code>. Error
306 * type, error tag and error status code are compared to expected values.
309 * Not valid identifier contains only revision without module name.
312 public void getSchemaWrongIdentifierTest() {
313 // prepare conditions - return correct schema context without mount points
314 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
316 // make test and verify
317 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
318 () -> schemaService.getSchema("2014-01-01"));
319 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
320 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
324 * Try to get schema with wrong (not valid) identifier behind mount point catching
325 * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
329 * Not valid identifier contains only revision without module name.
332 public void getSchemaWrongIdentifierMountPointTest() {
333 // prepare conditions - return correct schema context with mount points
334 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
336 // make test and verify
337 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
338 () -> schemaService.getSchema(MOUNT_POINT + "2014-01-01"));
339 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
340 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
344 * Try to get schema with identifier which does not contain revision catching
345 * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
349 public void getSchemaWithoutRevisionTest() {
350 // prepare conditions - return correct schema context without mount points
351 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
353 // make test and verify
354 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
355 () -> schemaService.getSchema("module"));
356 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
357 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
361 * Try to get schema behind mount point with identifier when does not contain revision catching
362 * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
366 public void getSchemaWithoutRevisionMountPointTest() {
367 // prepare conditions - return correct schema context with mount points
368 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
370 // make test and verify
371 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
372 () -> schemaService.getSchema(MOUNT_POINT + "module"));
373 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
374 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
378 * Negative test when mount point module is not found in current <code>SchemaContext</code> for mount points.
379 * <code>IllegalArgumentException</code> exception is expected.
382 public void getSchemaContextWithNotExistingMountPointTest() {
383 // prepare conditions - return schema context with mount points
384 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
387 assertThrows(RestconfDocumentedException.class,
388 () -> schemaService.getSchema(NOT_EXISTING_MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT));