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.model.api.EffectiveModelContext;
25 import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException;
26 import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactoryConfiguration;
27 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
28 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
29 import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
30 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
31 import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource;
32 import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToIRTransformer;
34 @RunWith(MockitoJUnitRunner.StrictStubs.class)
35 public class SharedEffectiveModelContextFactoryTest {
37 private final SharedSchemaRepository repository = new SharedSchemaRepository("test");
39 private final SchemaContextFactoryConfiguration config = SchemaContextFactoryConfiguration.getDefault();
40 private SourceIdentifier s1;
41 private SourceIdentifier s2;
45 final YangTextSchemaSource source1 = YangTextSchemaSource.forResource("/ietf/ietf-inet-types@2010-09-24.yang");
46 final YangTextSchemaSource source2 = YangTextSchemaSource.forResource("/ietf/iana-timezones@2012-07-09.yang");
47 s1 = new SourceIdentifier("ietf-inet-types", "2010-09-24");
48 s2 = new SourceIdentifier("iana-timezones", "2012-07-09");
50 final TextToIRTransformer transformer = TextToIRTransformer.create(repository, repository);
51 repository.registerSchemaSourceListener(transformer);
53 repository.registerSchemaSource(sourceIdentifier -> immediateFluentFuture(source1),
54 PotentialSchemaSource.create(s1, YangTextSchemaSource.class, 1));
56 repository.registerSchemaSource(sourceIdentifier -> immediateFluentFuture(source2),
57 PotentialSchemaSource.create(s2, YangTextSchemaSource.class, 1));
61 public void testCreateSchemaContextWithDuplicateRequiredSources() throws InterruptedException, ExecutionException {
62 final SharedEffectiveModelContextFactory sharedSchemaContextFactory =
63 new SharedEffectiveModelContextFactory(repository, config);
64 final ListenableFuture<EffectiveModelContext> schemaContext =
65 sharedSchemaContextFactory.createEffectiveModelContext(s1, s1, s2);
66 assertNotNull(schemaContext.get());
70 public void testSourceRegisteredWithDifferentSI() throws Exception {
71 final YangTextSchemaSource source1 = YangTextSchemaSource.forResource("/ietf/ietf-inet-types@2010-09-24.yang");
72 final YangTextSchemaSource source2 = YangTextSchemaSource.forResource("/ietf/iana-timezones@2012-07-09.yang");
73 s1 = source1.getIdentifier();
74 s2 = source2.getIdentifier();
76 final SettableSchemaProvider<IRSchemaSource> provider =
77 SharedSchemaRepositoryTest.getImmediateYangSourceProviderFromResource(
78 "/no-revision/imported@2012-12-12.yang");
80 provider.register(repository);
82 // Register the same provider under source id without revision
83 final SourceIdentifier sIdWithoutRevision = new SourceIdentifier(provider.getId().name());
84 repository.registerSchemaSource(provider, PotentialSchemaSource.create(
85 sIdWithoutRevision, IRSchemaSource.class, PotentialSchemaSource.Costs.IMMEDIATE.getValue()));
87 final SharedEffectiveModelContextFactory sharedSchemaContextFactory =
88 new SharedEffectiveModelContextFactory(repository, config);
89 final ListenableFuture<EffectiveModelContext> schemaContext =
90 sharedSchemaContextFactory.createEffectiveModelContext(sIdWithoutRevision, provider.getId());
91 assertNotNull(schemaContext.get());
95 public void testTransientFailureWhilreRetrievingSchemaSource() throws Exception {
96 final SourceIdentifier s3 = new SourceIdentifier("network-topology", "2013-10-21");
98 repository.registerSchemaSource(new TransientFailureProvider(
99 YangTextSchemaSource.forResource("/ietf/network-topology@2013-10-21.yang")),
100 PotentialSchemaSource.create(s3, YangTextSchemaSource.class, 1));
102 final SharedEffectiveModelContextFactory sharedSchemaContextFactory =
103 new SharedEffectiveModelContextFactory(repository, config);
105 ListenableFuture<EffectiveModelContext> schemaContext =
106 sharedSchemaContextFactory.createEffectiveModelContext(s1, s3);
108 final ExecutionException exception = assertThrows(ExecutionException.class, schemaContext::get);
109 assertThat(exception.getCause(), instanceOf(MissingSchemaSourceException.class));
111 // check if future is invalidated and resolution of source is retried after failure
112 schemaContext = sharedSchemaContextFactory.createEffectiveModelContext(s1, s3);
113 assertNotNull(schemaContext.get());
117 * Schema source provider that fails on first attempt of getSource() and succeeds on every subsequent call
118 * to simulate transient failures of source retrieval.
120 private static final class TransientFailureProvider implements SchemaSourceProvider<YangTextSchemaSource> {
122 private final YangTextSchemaSource schemaSource;
123 private boolean shouldFail = true;
125 private TransientFailureProvider(final YangTextSchemaSource schemaSource) {
126 this.schemaSource = requireNonNull(schemaSource);
130 public ListenableFuture<? extends YangTextSchemaSource> getSource(final SourceIdentifier sourceIdentifier) {
133 return immediateFailedFluentFuture(new Exception("Transient test failure."));
136 return immediateFluentFuture(schemaSource);