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