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 com.google.common.collect.ImmutableClassToInstanceMap;
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.DOMSchemaService;
24 import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
25 import org.opendaylight.mdsal.dom.broker.DOMMountPointServiceImpl;
26 import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
27 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
28 import org.opendaylight.restconf.nb.rfc8040.rests.services.api.RestconfSchemaService;
29 import org.opendaylight.restconf.nb.rfc8040.rests.services.api.SchemaExportContext;
30 import org.opendaylight.yangtools.yang.common.ErrorTag;
31 import org.opendaylight.yangtools.yang.common.ErrorType;
32 import org.opendaylight.yangtools.yang.common.QName;
33 import org.opendaylight.yangtools.yang.common.Revision;
34 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
35 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
36 import org.opendaylight.yangtools.yang.model.api.Module;
37 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
40 * Unit tests for {@code RestconfSchemaService}.
42 @RunWith(MockitoJUnitRunner.StrictStubs.class)
43 public class RestconfSchemaServiceTest {
44 private static final String MOUNT_POINT = "mount-point-1:cont/yang-ext:mount/";
45 private static final String NULL_MOUNT_POINT = "mount-point-2:cont/yang-ext:mount/";
46 private static final String NOT_EXISTING_MOUNT_POINT = "mount-point-3:cont/yang-ext:mount/";
48 private static final String TEST_MODULE = "module1/2014-01-01";
49 private static final String TEST_MODULE_BEHIND_MOUNT_POINT = "module1-behind-mount-point/2014-02-03";
50 private static final String NOT_EXISTING_MODULE = "not-existing/2016-01-01";
52 // schema context with modules
53 private static EffectiveModelContext SCHEMA_CONTEXT;
54 // schema context with modules behind mount point
55 private static EffectiveModelContext SCHEMA_CONTEXT_BEHIND_MOUNT_POINT;
56 // schema context with mount points
57 private static EffectiveModelContext SCHEMA_CONTEXT_WITH_MOUNT_POINTS;
60 private RestconfSchemaService schemaService;
64 private DOMSchemaService mockSchemaService;
66 private DOMYangTextSourceProvider mockSourceProvider;
69 public static void beforeClass() {
70 SCHEMA_CONTEXT = YangParserTestUtils.parseYangResourceDirectory("/modules");
71 SCHEMA_CONTEXT_BEHIND_MOUNT_POINT =
72 YangParserTestUtils.parseYangResourceDirectory("/modules/modules-behind-mount-point");
73 SCHEMA_CONTEXT_WITH_MOUNT_POINTS = YangParserTestUtils.parseYangResourceDirectory("/modules/mount-points");
77 public static void afterClass() {
78 SCHEMA_CONTEXT = null;
79 SCHEMA_CONTEXT_BEHIND_MOUNT_POINT = null;
80 SCHEMA_CONTEXT_WITH_MOUNT_POINTS = null;
84 public void setup() throws Exception {
85 final var mountPointService = new DOMMountPointServiceImpl();
86 // create and register mount points
88 .createMountPoint(YangInstanceIdentifier.of(QName.create("mount:point:1", "2016-01-01", "cont")))
89 .addService(DOMSchemaService.class, FixedDOMSchemaService.of(SCHEMA_CONTEXT_BEHIND_MOUNT_POINT))
92 .createMountPoint(YangInstanceIdentifier.of(QName.create("mount:point:2", "2016-01-01", "cont")))
95 when(mockSchemaService.getExtensions())
96 .thenReturn(ImmutableClassToInstanceMap.of(DOMYangTextSourceProvider.class, mockSourceProvider));
97 schemaService = new RestconfSchemaServiceImpl(mockSchemaService, mountPointService);
101 * Get schema with identifier of existing module and check if correct module was found.
104 public void getSchemaTest() {
105 // prepare conditions - return not-mount point schema context
106 when(mockSchemaService.getGlobalContext()).thenReturn(SCHEMA_CONTEXT);
109 final SchemaExportContext exportContext = schemaService.getSchema(TEST_MODULE);
112 assertNotNull("Export context should not be null", exportContext);
114 final Module module = exportContext.module();
115 assertNotNull("Existing module should be found", module);
117 assertEquals("Not expected module name", "module1", module.getName());
118 assertEquals("Not expected module revision", Revision.ofNullable("2014-01-01"), module.getRevision());
119 assertEquals("Not expected module namespace", "module:1", module.getNamespace().toString());
123 * Get schema with identifier of not-existing module. Trying to create <code>SchemaExportContext</code> with
124 * not-existing module should result in error.
127 public void getSchemaForNotExistingModuleTest() {
128 // prepare conditions - return not-mount point schema context
129 when(mockSchemaService.getGlobalContext()).thenReturn(SCHEMA_CONTEXT);
131 // make test & verify
132 final var ex = assertThrows(RestconfDocumentedException.class, () ->
133 schemaService.getSchema(NOT_EXISTING_MODULE));
134 assertEquals("Not expected error tag", ErrorTag.DATA_MISSING, ex.getErrors().get(0).getErrorTag());
135 assertEquals("Not expected error type", ErrorType.APPLICATION, ex.getErrors().get(0).getErrorType());
139 * Get schema with identifier of existing module behind mount point and check if correct module was found.
142 public void getSchemaMountPointTest() {
143 // prepare conditions - return schema context with mount points
144 when(mockSchemaService.getGlobalContext()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
147 final SchemaExportContext exportContext =
148 schemaService.getSchema(MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT);
151 assertNotNull("Export context should not be null", exportContext);
153 final Module module = exportContext.module();
154 assertNotNull("Existing module should be found", module);
156 assertEquals("Not expected module name", "module1-behind-mount-point", module.getName());
157 assertEquals("Not expected module revision", Revision.ofNullable("2014-02-03"), module.getRevision());
158 assertEquals("Not expected module namespace", "module:1:behind:mount:point", module.getNamespace().toString());
162 * Get schema with identifier of not-existing module behind mount point. Trying to create
163 * <code>SchemaExportContext</code> with not-existing module behind mount point should result in error.
166 public void getSchemaForNotExistingModuleMountPointTest() {
167 // prepare conditions - return schema context with mount points
168 when(mockSchemaService.getGlobalContext()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
170 // make test & verify
171 final var ex = assertThrows(RestconfDocumentedException.class, () ->
172 schemaService.getSchema(MOUNT_POINT + NOT_EXISTING_MODULE));
173 assertEquals("Not expected error tag", ErrorTag.DATA_MISSING, ex.getErrors().get(0).getErrorTag());
174 assertEquals("Not expected error type", ErrorType.APPLICATION, ex.getErrors().get(0).getErrorType());
178 * Try to get schema with <code>null</code> <code>SchemaContext</code> expecting <code>NullPointerException</code>.
181 public void getSchemaWithNullSchemaContextTest() {
182 // prepare conditions - returned schema context is null
183 when(mockSchemaService.getGlobalContext()).thenReturn(null);
186 assertThrows(NullPointerException.class, () -> schemaService.getSchema(TEST_MODULE));
190 * Try to get schema with <code>null</code> <code>SchemaContext</code> for mount points.
191 * <code>NullPointerException</code> is expected.
194 public void getSchemaWithNullSchemaContextMountPointTest() {
195 // prepare conditions - returned schema context for mount points is null
196 when(mockSchemaService.getGlobalContext()).thenReturn(null);
199 assertThrows(NullPointerException.class,
200 () -> schemaService.getSchema(MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT));
204 * Try to get schema with <code>null</code> <code>SchemaContext</code> behind mount point when using
205 * <code>NULL_MOUNT_POINT</code>. Test is expected to fail with <code>NullPointerException</code>.
208 public void getSchemaNullSchemaContextBehindMountPointTest() {
209 // prepare conditions - return correct schema context for mount points (this is not null)
210 when(mockSchemaService.getGlobalContext()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
212 // make test - call service on mount point with null schema context
213 assertThrows(IllegalStateException.class,
214 // NULL_MOUNT_POINT contains null schema context
215 () -> schemaService.getSchema(NULL_MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT));
219 * Try to get schema with null identifier expecting <code>NullPointerException</code>. The same processing is for
220 * server and also for mount point.
223 public void getSchemaWithNullIdentifierTest() {
224 // prepare conditions - return correct schema context
225 when(mockSchemaService.getGlobalContext()).thenReturn(SCHEMA_CONTEXT);
228 assertThrows(NullPointerException.class, () -> schemaService.getSchema(null));
232 * Try to get schema with empty (not valid) identifier catching <code>RestconfDocumentedException</code>. Error
233 * type, error tag and error status code are compared to expected values.
236 public void getSchemaWithEmptyIdentifierTest() {
237 // prepare conditions - return correct schema context
238 when(mockSchemaService.getGlobalContext()).thenReturn(SCHEMA_CONTEXT);
240 // make test and verify
241 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
242 () -> schemaService.getSchema(""));
243 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
244 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
248 * Try to get schema with empty (not valid) identifier behind mount point catching
249 * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
253 public void getSchemaWithEmptyIdentifierMountPointTest() {
254 // prepare conditions - return correct schema context with mount points
255 when(mockSchemaService.getGlobalContext()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
257 // make test and verify
258 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
259 () -> schemaService.getSchema(MOUNT_POINT + ""));
260 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
261 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
265 * Try to get schema with not-parsable identifier catching <code>RestconfDocumentedException</code>. Error type,
266 * error tag and error status code are compared to expected values.
269 public void getSchemaWithNotParsableIdentifierTest() {
270 // prepare conditions - return correct schema context without mount points
271 when(mockSchemaService.getGlobalContext()).thenReturn(SCHEMA_CONTEXT);
273 // make test and verify
274 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
275 () -> schemaService.getSchema("01_module/2016-01-01"));
276 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
277 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
281 * Try to get schema behind mount point with not-parsable identifier catching
282 * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
286 public void getSchemaWithNotParsableIdentifierMountPointTest() {
287 // prepare conditions - return correct schema context with mount points
288 when(mockSchemaService.getGlobalContext()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
290 // make test and verify
291 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
292 () -> schemaService.getSchema(MOUNT_POINT + "01_module/2016-01-01"));
293 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
294 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
298 * Try to get schema with wrong (not valid) identifier catching <code>RestconfDocumentedException</code>. Error
299 * type, error tag and error status code are compared to expected values.
302 * Not valid identifier contains only revision without module name.
305 public void getSchemaWrongIdentifierTest() {
306 // prepare conditions - return correct schema context without mount points
307 when(mockSchemaService.getGlobalContext()).thenReturn(SCHEMA_CONTEXT);
309 // make test and verify
310 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
311 () -> schemaService.getSchema("2014-01-01"));
312 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
313 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
317 * Try to get schema with wrong (not valid) identifier behind mount point catching
318 * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
322 * Not valid identifier contains only revision without module name.
325 public void getSchemaWrongIdentifierMountPointTest() {
326 // prepare conditions - return correct schema context with mount points
327 when(mockSchemaService.getGlobalContext()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
329 // make test and verify
330 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
331 () -> schemaService.getSchema(MOUNT_POINT + "2014-01-01"));
332 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
333 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
337 * Try to get schema with identifier which does not contain revision catching
338 * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
342 public void getSchemaWithoutRevisionTest() {
343 // prepare conditions - return correct schema context without mount points
344 when(mockSchemaService.getGlobalContext()).thenReturn(SCHEMA_CONTEXT);
346 // make test and verify
347 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
348 () -> schemaService.getSchema("module"));
349 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
350 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
354 * Try to get schema behind mount point with identifier when does not contain revision catching
355 * <code>RestconfDocumentedException</code>. Error type, error tag and error status code are compared to expected
359 public void getSchemaWithoutRevisionMountPointTest() {
360 // prepare conditions - return correct schema context with mount points
361 when(mockSchemaService.getGlobalContext()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
363 // make test and verify
364 final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class,
365 () -> schemaService.getSchema(MOUNT_POINT + "module"));
366 assertEquals(ErrorType.PROTOCOL, ex.getErrors().get(0).getErrorType());
367 assertEquals(ErrorTag.INVALID_VALUE, ex.getErrors().get(0).getErrorTag());
371 * Negative test when mount point module is not found in current <code>SchemaContext</code> for mount points.
372 * <code>IllegalArgumentException</code> exception is expected.
375 public void getSchemaContextWithNotExistingMountPointTest() {
376 // prepare conditions - return schema context with mount points
377 when(mockSchemaService.getGlobalContext()).thenReturn(SCHEMA_CONTEXT_WITH_MOUNT_POINTS);
380 assertThrows(RestconfDocumentedException.class,
381 () -> schemaService.getSchema(NOT_EXISTING_MOUNT_POINT + TEST_MODULE_BEHIND_MOUNT_POINT));