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