Promote SchemaSourceRepresentation
[yangtools.git] / parser / yang-parser-impl / src / test / java / org / opendaylight / yangtools / yang / parser / repo / SharedSchemaRepositoryTest.java
1 /*
2  * Copyright (c) 2014 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 package org.opendaylight.yangtools.yang.parser.repo;
9
10 import static org.junit.jupiter.api.Assertions.assertEquals;
11 import static org.junit.jupiter.api.Assertions.assertFalse;
12 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
13 import static org.junit.jupiter.api.Assertions.assertNotNull;
14 import static org.junit.jupiter.api.Assertions.assertSame;
15 import static org.junit.jupiter.api.Assertions.assertThrows;
16 import static org.junit.jupiter.api.Assertions.assertTrue;
17 import static org.mockito.Mockito.spy;
18 import static org.mockito.Mockito.times;
19 import static org.mockito.Mockito.verify;
20
21 import java.util.concurrent.ExecutionException;
22 import org.junit.jupiter.api.Test;
23 import org.opendaylight.yangtools.yang.ir.YangIRSchemaSource;
24 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
25 import org.opendaylight.yangtools.yang.model.api.source.SourceIdentifier;
26 import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException;
27 import org.opendaylight.yangtools.yang.model.spi.source.YangTextSource;
28 import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToIRTransformer;
29
30 public class SharedSchemaRepositoryTest {
31     @Test
32     public void testSourceWithAndWithoutRevision() throws Exception {
33         final var sharedSchemaRepository = new SharedSchemaRepository("netconf-mounts");
34
35         final var idNoRevision = loadAndRegisterSource(sharedSchemaRepository, "/no-revision/imported.yang");
36         final var id2 = loadAndRegisterSource(sharedSchemaRepository, "/no-revision/imported@2012-12-12.yang");
37
38         var source = sharedSchemaRepository.getSchemaSource(idNoRevision, YangIRSchemaSource.class);
39         assertEquals(idNoRevision, source.get().sourceId());
40         source = sharedSchemaRepository.getSchemaSource(id2, YangIRSchemaSource.class);
41         assertEquals(id2, source.get().sourceId());
42     }
43
44     private static SourceIdentifier loadAndRegisterSource(final SharedSchemaRepository sharedSchemaRepository,
45             final String resourceName) throws Exception {
46         final var sourceProvider = getImmediateYangSourceProviderFromResource(resourceName);
47         sourceProvider.setResult();
48         final var idNoRevision = sourceProvider.getId();
49         sourceProvider.register(sharedSchemaRepository);
50         return idNoRevision;
51     }
52
53     @Test
54     public void testSimpleSchemaContext() throws Exception {
55         final var sharedSchemaRepository = new SharedSchemaRepository("netconf-mounts");
56
57         final var remoteInetTypesYang =
58             getImmediateYangSourceProviderFromResource("/ietf/ietf-inet-types@2010-09-24.yang");
59         remoteInetTypesYang.register(sharedSchemaRepository);
60         final var registeredSourceFuture = sharedSchemaRepository.getSchemaSource(
61             remoteInetTypesYang.getId(), YangIRSchemaSource.class);
62         assertFalse(registeredSourceFuture.isDone());
63
64         final var fact = sharedSchemaRepository.createEffectiveModelContextFactory();
65         final var schemaContextFuture = fact.createEffectiveModelContext(remoteInetTypesYang.getId());
66         assertFalse(schemaContextFuture.isDone());
67
68         // Make source appear
69         remoteInetTypesYang.setResult();
70         assertEquals(remoteInetTypesYang.getSchemaSourceRepresentation(), registeredSourceFuture.get());
71
72         // Verify schema created successfully
73         assertTrue(schemaContextFuture.isDone());
74         final var firstSchemaContext = schemaContextFuture.get();
75         assertSchemaContext(firstSchemaContext, 1);
76
77         // Try same schema second time
78         final var secondSchemaFuture = sharedSchemaRepository.createEffectiveModelContextFactory()
79             .createEffectiveModelContext(remoteInetTypesYang.getId());
80
81         // Verify second schema created successfully immediately
82         assertTrue(secondSchemaFuture.isDone());
83         // Assert same context instance is returned from first and second attempt
84         assertSame(firstSchemaContext, secondSchemaFuture.get());
85     }
86
87     @Test
88     public void testTwoSchemaContextsSharingSource() throws Exception {
89         final var sharedSchemaRepository = new SharedSchemaRepository("netconf-mounts");
90
91         final var remoteInetTypesYang =
92             getImmediateYangSourceProviderFromResource("/ietf/ietf-inet-types@2010-09-24.yang");
93         remoteInetTypesYang.register(sharedSchemaRepository);
94         remoteInetTypesYang.setResult();
95         final var remoteTopologyYang =
96             getImmediateYangSourceProviderFromResource("/ietf/network-topology@2013-10-21.yang");
97         remoteTopologyYang.register(sharedSchemaRepository);
98         remoteTopologyYang.setResult();
99         final var remoteModuleNoRevYang =
100             getImmediateYangSourceProviderFromResource("/no-revision/module-without-revision.yang");
101         remoteModuleNoRevYang.register(sharedSchemaRepository);
102
103         final var fact = sharedSchemaRepository.createEffectiveModelContextFactory();
104         final var inetAndTopologySchemaContextFuture = fact.createEffectiveModelContext(
105             remoteInetTypesYang.getId(), remoteTopologyYang.getId());
106         assertTrue(inetAndTopologySchemaContextFuture.isDone());
107         assertSchemaContext(inetAndTopologySchemaContextFuture.get(), 2);
108
109         final var inetAndNoRevSchemaContextFuture = fact.createEffectiveModelContext(
110             remoteInetTypesYang.getId(), remoteModuleNoRevYang.getId());
111         assertFalse(inetAndNoRevSchemaContextFuture.isDone());
112
113         remoteModuleNoRevYang.setResult();
114         assertTrue(inetAndNoRevSchemaContextFuture.isDone());
115         assertSchemaContext(inetAndNoRevSchemaContextFuture.get(), 2);
116     }
117
118     @Test
119     public void testFailedSchemaContext() throws Exception {
120         final var sharedSchemaRepository = new SharedSchemaRepository("netconf-mounts");
121
122         final var remoteInetTypesYang =
123             getImmediateYangSourceProviderFromResource("/ietf/ietf-inet-types@2010-09-24.yang");
124         remoteInetTypesYang.register(sharedSchemaRepository);
125
126         final var fact = sharedSchemaRepository.createEffectiveModelContextFactory();
127
128         // Make source appear
129         final var ise = new IllegalStateException("failed schema");
130         remoteInetTypesYang.setException(ise);
131
132         final var schemaContextFuture = fact.createEffectiveModelContext(remoteInetTypesYang.getId());
133         final var ex = assertThrows(ExecutionException.class, schemaContextFuture::get);
134         final var cause = assertInstanceOf(MissingSchemaSourceException.class, ex.getCause());
135         assertSame(ise, cause.getCause());
136     }
137
138     @Test
139     public void testDifferentCosts() throws Exception {
140         final var sharedSchemaRepository = new SharedSchemaRepository("netconf-mounts");
141
142         final var immediateInetTypesYang = spy(
143             getImmediateYangSourceProviderFromResource("/ietf/ietf-inet-types@2010-09-24.yang"));
144         immediateInetTypesYang.register(sharedSchemaRepository);
145         immediateInetTypesYang.setResult();
146
147         final var remoteInetTypesYang = spy(
148             getRemoteYangSourceProviderFromResource("/ietf/ietf-inet-types@2010-09-24.yang"));
149         remoteInetTypesYang.register(sharedSchemaRepository);
150         remoteInetTypesYang.setResult();
151
152         final var fact = sharedSchemaRepository.createEffectiveModelContextFactory();
153         final var schemaContextFuture = fact.createEffectiveModelContext(remoteInetTypesYang.getId());
154
155         assertSchemaContext(schemaContextFuture.get(), 1);
156
157         final var id = immediateInetTypesYang.getId();
158         verify(remoteInetTypesYang, times(0)).getSource(id);
159         verify(immediateInetTypesYang).getSource(id);
160     }
161
162     private static void assertSchemaContext(final EffectiveModelContext schemaContext, final int moduleSize) {
163         assertNotNull(schemaContext);
164         assertEquals(moduleSize, schemaContext.getModules().size());
165     }
166
167     static SettableSchemaProvider<YangIRSchemaSource> getRemoteYangSourceProviderFromResource(final String resourceName)
168             throws Exception {
169         return SettableSchemaProvider.createRemote(
170             TextToIRTransformer.transformText(YangTextSource.forResource(resourceName)), YangIRSchemaSource.class);
171     }
172
173     static SettableSchemaProvider<YangIRSchemaSource> getImmediateYangSourceProviderFromResource(
174             final String resourceName) throws Exception {
175         return SettableSchemaProvider.createImmediate(
176             TextToIRTransformer.transformText(YangTextSource.forResource(resourceName)), YangIRSchemaSource.class);
177     }
178 }