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.yangtools.yang.parser.repo;
10 import static java.util.Objects.requireNonNull;
11 import static org.hamcrest.CoreMatchers.instanceOf;
12 import static org.hamcrest.MatcherAssert.assertThat;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.assertThrows;
15 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFailedFluentFuture;
16 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFluentFuture;
18 import com.google.common.util.concurrent.ListenableFuture;
19 import java.util.concurrent.ExecutionException;
20 import org.junit.Before;
21 import org.junit.Test;
22 import org.junit.runner.RunWith;
23 import org.mockito.junit.MockitoJUnitRunner;
24 import org.opendaylight.yangtools.yang.common.Revision;
25 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
26 import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException;
27 import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
28 import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactoryConfiguration;
29 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
30 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
31 import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
32 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
33 import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource;
34 import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToIRTransformer;
36 @RunWith(MockitoJUnitRunner.StrictStubs.class)
37 public class SharedEffectiveModelContextFactoryTest {
39 private final SharedSchemaRepository repository = new SharedSchemaRepository("test");
41 private final SchemaContextFactoryConfiguration config = SchemaContextFactoryConfiguration.getDefault();
42 private SourceIdentifier s1;
43 private SourceIdentifier s2;
47 final YangTextSchemaSource source1 = YangTextSchemaSource.forResource("/ietf/ietf-inet-types@2010-09-24.yang");
48 final YangTextSchemaSource source2 = YangTextSchemaSource.forResource("/ietf/iana-timezones@2012-07-09.yang");
49 s1 = RevisionSourceIdentifier.create("ietf-inet-types", Revision.of("2010-09-24"));
50 s2 = RevisionSourceIdentifier.create("iana-timezones", Revision.of("2012-07-09"));
52 final TextToIRTransformer transformer = TextToIRTransformer.create(repository, repository);
53 repository.registerSchemaSourceListener(transformer);
55 repository.registerSchemaSource(sourceIdentifier -> immediateFluentFuture(source1),
56 PotentialSchemaSource.create(s1, YangTextSchemaSource.class, 1));
58 repository.registerSchemaSource(sourceIdentifier -> immediateFluentFuture(source2),
59 PotentialSchemaSource.create(s2, YangTextSchemaSource.class, 1));
63 public void testCreateSchemaContextWithDuplicateRequiredSources() throws InterruptedException, ExecutionException {
64 final SharedEffectiveModelContextFactory sharedSchemaContextFactory =
65 new SharedEffectiveModelContextFactory(repository, config);
66 final ListenableFuture<EffectiveModelContext> schemaContext =
67 sharedSchemaContextFactory.createEffectiveModelContext(s1, s1, s2);
68 assertNotNull(schemaContext.get());
72 public void testSourceRegisteredWithDifferentSI() throws Exception {
73 final YangTextSchemaSource source1 = YangTextSchemaSource.forResource("/ietf/ietf-inet-types@2010-09-24.yang");
74 final YangTextSchemaSource source2 = YangTextSchemaSource.forResource("/ietf/iana-timezones@2012-07-09.yang");
75 s1 = source1.getIdentifier();
76 s2 = source2.getIdentifier();
78 final SettableSchemaProvider<IRSchemaSource> provider =
79 SharedSchemaRepositoryTest.getImmediateYangSourceProviderFromResource(
80 "/no-revision/imported@2012-12-12.yang");
82 provider.register(repository);
84 // Register the same provider under source id without revision
85 final SourceIdentifier sIdWithoutRevision = RevisionSourceIdentifier.create(provider.getId().getName());
86 repository.registerSchemaSource(provider, PotentialSchemaSource.create(
87 sIdWithoutRevision, IRSchemaSource.class, PotentialSchemaSource.Costs.IMMEDIATE.getValue()));
89 final SharedEffectiveModelContextFactory sharedSchemaContextFactory =
90 new SharedEffectiveModelContextFactory(repository, config);
91 final ListenableFuture<EffectiveModelContext> schemaContext =
92 sharedSchemaContextFactory.createEffectiveModelContext(sIdWithoutRevision, provider.getId());
93 assertNotNull(schemaContext.get());
97 public void testTransientFailureWhilreRetrievingSchemaSource() throws Exception {
98 final RevisionSourceIdentifier s3 =
99 RevisionSourceIdentifier.create("network-topology", Revision.of("2013-10-21"));
101 repository.registerSchemaSource(new TransientFailureProvider(
102 YangTextSchemaSource.forResource("/ietf/network-topology@2013-10-21.yang")),
103 PotentialSchemaSource.create(s3, YangTextSchemaSource.class, 1));
105 final SharedEffectiveModelContextFactory sharedSchemaContextFactory =
106 new SharedEffectiveModelContextFactory(repository, config);
108 ListenableFuture<EffectiveModelContext> schemaContext =
109 sharedSchemaContextFactory.createEffectiveModelContext(s1, s3);
111 final ExecutionException exception = assertThrows(ExecutionException.class, schemaContext::get);
112 assertThat(exception.getCause(), instanceOf(MissingSchemaSourceException.class));
114 // check if future is invalidated and resolution of source is retried after failure
115 schemaContext = sharedSchemaContextFactory.createEffectiveModelContext(s1, s3);
116 assertNotNull(schemaContext.get());
120 * Schema source provider that fails on first attempt of getSource() and succeeds on every subsequent call
121 * to simulate transient failures of source retrieval.
123 private static final class TransientFailureProvider implements SchemaSourceProvider<YangTextSchemaSource> {
125 private final YangTextSchemaSource schemaSource;
126 private boolean shouldFail = true;
128 private TransientFailureProvider(final YangTextSchemaSource schemaSource) {
129 this.schemaSource = requireNonNull(schemaSource);
133 public ListenableFuture<? extends YangTextSchemaSource> getSource(final SourceIdentifier sourceIdentifier) {
136 return immediateFailedFluentFuture(new Exception("Transient test failure."));
139 return immediateFluentFuture(schemaSource);