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.assertThrows;
13 import static org.mockito.Mockito.when;
15 import java.io.FileNotFoundException;
16 import org.junit.AfterClass;
17 import org.junit.Before;
18 import org.junit.BeforeClass;
19 import org.junit.Test;
20 import org.junit.runner.RunWith;
21 import org.mockito.Mock;
22 import org.mockito.junit.MockitoJUnitRunner;
23 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
24 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
25 import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
26 import org.opendaylight.mdsal.dom.broker.DOMMountPointServiceImpl;
27 import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
28 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
29 import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
30 import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
31 import org.opendaylight.restconf.nb.rfc8040.rests.services.api.RestconfSchemaService;
32 import org.opendaylight.restconf.nb.rfc8040.rests.services.api.SchemaExportContext;
33 import org.opendaylight.yangtools.yang.common.ErrorTag;
34 import org.opendaylight.yangtools.yang.common.ErrorType;
35 import org.opendaylight.yangtools.yang.common.QName;
36 import org.opendaylight.yangtools.yang.common.Revision;
37 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
38 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
39 import org.opendaylight.yangtools.yang.model.api.Module;
40 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
43 * Unit tests for {@code RestconfSchemaService}.
45 @RunWith(MockitoJUnitRunner.StrictStubs.class)
46 public class RestconfSchemaServiceTest {
47 private static final String MOUNT_POINT = "mount-point-1:cont/yang-ext:mount/";
48 private static final String NULL_MOUNT_POINT = "mount-point-2:cont/yang-ext:mount/";
49 private static final String NOT_EXISTING_MOUNT_POINT = "mount-point-3:cont/yang-ext:mount/";
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";
55 // schema context with modules
56 private static EffectiveModelContext SCHEMA_CONTEXT;
57 // schema context with modules behind mount point
58 private static EffectiveModelContext SCHEMA_CONTEXT_BEHIND_MOUNT_POINT;
59 // schema context with mount points
60 private static EffectiveModelContext SCHEMA_CONTEXT_WITH_MOUNT_POINTS;
63 private RestconfSchemaService schemaService;
67 private SchemaContextHandler mockContextHandler;
69 private DOMYangTextSourceProvider sourceProvider;
70 // mount point service
71 private DOMMountPointService mountPointService;
74 public static void beforeClass() throws FileNotFoundException {
75 SCHEMA_CONTEXT = YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles("/modules"));
76 SCHEMA_CONTEXT_BEHIND_MOUNT_POINT = YangParserTestUtils.parseYangFiles(
77 TestRestconfUtils.loadFiles("/modules/modules-behind-mount-point"));
78 SCHEMA_CONTEXT_WITH_MOUNT_POINTS = YangParserTestUtils.parseYangFiles(
79 TestRestconfUtils.loadFiles("/modules/mount-points"));
83 public static void afterClass() {
84 SCHEMA_CONTEXT = null;
85 SCHEMA_CONTEXT_BEHIND_MOUNT_POINT = null;
86 SCHEMA_CONTEXT_WITH_MOUNT_POINTS = null;
90 public void setup() throws Exception {
91 this.mountPointService = new DOMMountPointServiceImpl();
92 // create and register mount points
94 .createMountPoint(YangInstanceIdentifier.of(QName.create("mount:point:1", "2016-01-01", "cont")))
95 .addService(DOMSchemaService.class, FixedDOMSchemaService.of(SCHEMA_CONTEXT_BEHIND_MOUNT_POINT))
98 .createMountPoint(YangInstanceIdentifier.of(QName.create("mount:point:2", "2016-01-01", "cont")))
101 this.schemaService = new RestconfSchemaServiceImpl(this.mockContextHandler, mountPointService, sourceProvider);
105 * Get schema with identifier of existing module and check if correct module was found.
108 public void getSchemaTest() {
109 // prepare conditions - return not-mount point schema context
110 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
113 final SchemaExportContext exportContext = schemaService.getSchema(TEST_MODULE);
116 assertNotNull("Export context should not be null", exportContext);
118 final Module module = exportContext.getModule();
119 assertNotNull("Existing module should be found", module);
121 assertEquals("Not expected module name", "module1", module.getName());
122 assertEquals("Not expected module revision", Revision.ofNullable("2014-01-01"), module.getRevision());
123 assertEquals("Not expected module namespace", "module:1", module.getNamespace().toString());
127 * Get schema with identifier of not-existing module. Trying to create <code>SchemaExportContext</code> with
128 * not-existing module should result in error.
131 public void getSchemaForNotExistingModuleTest() {
132 // prepare conditions - return not-mount point schema context
133 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
135 // make test & verify
136 final var ex = assertThrows(RestconfDocumentedException.class, () ->
137 schemaService.getSchema(NOT_EXISTING_MODULE));
138 assertEquals("Not expected error tag", ErrorTag.DATA_MISSING, ex.getErrors().get(0).getErrorTag());
139 assertEquals("Not expected error type", ErrorType.APPLICATION, ex.getErrors().get(0).getErrorType());
143 * Get schema with identifier of existing module behind mount point and check if correct module was found.
146 public void getSchemaMountPointTest() {
147 // prepare conditions - return schema context with mount points
148 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
151 final SchemaExportContext exportContext =
152 schemaService.getSchema(MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT);
155 assertNotNull("Export context should not be null", exportContext);
157 final Module module = exportContext.getModule();
158 assertNotNull("Existing module should be found", module);
160 assertEquals("Not expected module name", "module1-behind-mount-point", module.getName());
161 assertEquals("Not expected module revision", Revision.ofNullable("2014-02-03"), module.getRevision());
162 assertEquals("Not expected module namespace", "module:1:behind:mount:point", module.getNamespace().toString());
166 * Get schema with identifier of not-existing module behind mount point. Trying to create
167 * <code>SchemaExportContext</code> with not-existing module behind mount point should result in error.
170 public void getSchemaForNotExistingModuleMountPointTest() {
171 // prepare conditions - return schema context with mount points
172 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
174 // make test & verify
175 final var ex = assertThrows(RestconfDocumentedException.class, () ->
176 schemaService.getSchema(MOUNT_POINT + NOT_EXISTING_MODULE));
177 assertEquals("Not expected error tag", ErrorTag.DATA_MISSING, ex.getErrors().get(0).getErrorTag());
178 assertEquals("Not expected error type", ErrorType.APPLICATION, ex.getErrors().get(0).getErrorType());
182 * Try to get schema with <code>null</code> <code>SchemaContext</code> expecting <code>NullPointerException</code>.
185 public void getSchemaWithNullSchemaContextTest() {
186 // prepare conditions - returned schema context is null
187 when(this.mockContextHandler.get()).thenReturn(null);
190 assertThrows(NullPointerException.class, () -> schemaService.getSchema(TEST_MODULE));
194 * Try to get schema with <code>null</code> <code>SchemaContext</code> for mount points.
195 * <code>NullPointerException</code> is expected.
198 public void getSchemaWithNullSchemaContextMountPointTest() {
199 // prepare conditions - returned schema context for mount points is null
200 when(this.mockContextHandler.get()).thenReturn(null);
203 assertThrows(NullPointerException.class,
204 () -> schemaService.getSchema(MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT));
208 * Try to get schema with <code>null</code> <code>SchemaContext</code> behind mount point when using
209 * <code>NULL_MOUNT_POINT</code>. Test is expected to fail with <code>NullPointerException</code>.
212 public void getSchemaNullSchemaContextBehindMountPointTest() {
213 // prepare conditions - return correct schema context for mount points (this is not null)
214 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
216 // make test - call service on mount point with null schema context
217 assertThrows(IllegalStateException.class,
218 // NULL_MOUNT_POINT contains null schema context
219 () -> this.schemaService.getSchema(NULL_MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT));
223 * Try to get schema with null identifier expecting <code>NullPointerException</code>. The same processing is for
224 * server and also for mount point.
227 public void getSchemaWithNullIdentifierTest() {
228 // prepare conditions - return correct schema context
229 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
232 assertThrows(NullPointerException.class, () -> this.schemaService.getSchema(null));
236 * Try to get schema with empty (not valid) identifier catching <code>RestconfDocumentedException</code>. Error
237 * type, error tag and error status code are compared to expected values.
240 public void getSchemaWithEmptyIdentifierTest() {
241 // prepare conditions - return correct schema context
242 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
244 // make test and verify
245 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
246 () -> schemaService.getSchema(""));
247 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
248 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
252 * Try to get schema with empty (not valid) identifier behind mount point catching
253 * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
257 public void getSchemaWithEmptyIdentifierMountPointTest() {
258 // prepare conditions - return correct schema context with mount points
259 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
261 // make test and verify
262 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
263 () -> schemaService.getSchema(MOUNT_POINT + ""));
264 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
265 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
269 * Try to get schema with not-parsable identifier catching <code>RestconfDocumentedException</code>. Error type,
270 * error tag and error status code are compared to expected values.
273 public void getSchemaWithNotParsableIdentifierTest() {
274 // prepare conditions - return correct schema context without mount points
275 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
277 // make test and verify
278 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
279 () -> schemaService.getSchema("01_module/2016-01-01"));
280 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
281 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
285 * Try to get schema behind mount point with not-parsable identifier catching
286 * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
290 public void getSchemaWithNotParsableIdentifierMountPointTest() {
291 // prepare conditions - return correct schema context with mount points
292 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
294 // make test and verify
295 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
296 () -> schemaService.getSchema(MOUNT_POINT + "01_module/2016-01-01"));
297 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
298 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
302 * Try to get schema with wrong (not valid) identifier catching <code>RestconfDocumentedException</code>. Error
303 * type, error tag and error status code are compared to expected values.
306 * Not valid identifier contains only revision without module name.
309 public void getSchemaWrongIdentifierTest() {
310 // prepare conditions - return correct schema context without mount points
311 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
313 // make test and verify
314 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
315 () -> schemaService.getSchema("2014-01-01"));
316 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
317 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
321 * Try to get schema with wrong (not valid) identifier behind mount point catching
322 * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
326 * Not valid identifier contains only revision without module name.
329 public void getSchemaWrongIdentifierMountPointTest() {
330 // prepare conditions - return correct schema context with mount points
331 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
333 // make test and verify
334 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
335 () -> schemaService.getSchema(MOUNT_POINT + "2014-01-01"));
336 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
337 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
341 * Try to get schema with identifier which does not contain revision catching
342 * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
346 public void getSchemaWithoutRevisionTest() {
347 // prepare conditions - return correct schema context without mount points
348 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT);
350 // make test and verify
351 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
352 () -> schemaService.getSchema("module"));
353 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
354 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
358 * Try to get schema behind mount point with identifier when does not contain revision catching
359 * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
363 public void getSchemaWithoutRevisionMountPointTest() {
364 // prepare conditions - return correct schema context with mount points
365 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
367 // make test and verify
368 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
369 () -> schemaService.getSchema(MOUNT_POINT + "module"));
370 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
371 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
375 * Negative test when mount point module is not found in current <code>SchemaContext</code> for mount points.
376 * <code>IllegalArgumentException</code> exception is expected.
379 public void getSchemaContextWithNotExistingMountPointTest() {
380 // prepare conditions - return schema context with mount points
381 when(this.mockContextHandler.get()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
384 assertThrows(RestconfDocumentedException.class,
385 () -> schemaService.getSchema(NOT_EXISTING_MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT));