2 * Copyright (c) 2014 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.model.repo.fs;
10 import static org.hamcrest.CoreMatchers.both;
11 import static org.hamcrest.CoreMatchers.containsString;
12 import static org.hamcrest.CoreMatchers.either;
13 import static org.hamcrest.CoreMatchers.hasItem;
14 import static org.hamcrest.MatcherAssert.assertThat;
15 import static org.junit.Assert.assertEquals;
16 import static org.junit.Assert.assertNotNull;
17 import static org.junit.Assert.assertThrows;
18 import static org.junit.Assert.assertTrue;
19 import static org.mockito.ArgumentMatchers.any;
20 import static org.mockito.Mockito.doReturn;
21 import static org.mockito.Mockito.times;
22 import static org.mockito.Mockito.verify;
24 import com.google.common.base.MoreObjects;
25 import com.google.common.collect.Collections2;
26 import com.google.common.io.Files;
27 import com.google.common.util.concurrent.ListenableFuture;
28 import java.io.ByteArrayInputStream;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.nio.charset.StandardCharsets;
33 import java.util.Arrays;
34 import java.util.Collection;
35 import java.util.List;
36 import java.util.Optional;
37 import java.util.concurrent.ExecutionException;
38 import org.junit.Before;
39 import org.junit.Test;
40 import org.junit.runner.RunWith;
41 import org.mockito.Mock;
42 import org.mockito.junit.MockitoJUnitRunner;
43 import org.opendaylight.yangtools.yang.common.Revision;
44 import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
45 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
46 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
47 import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
48 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
49 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration;
50 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
52 @RunWith(MockitoJUnitRunner.StrictStubs.class)
53 public class FilesystemSchemaSourceCacheTest {
55 public SchemaSourceRegistry registry;
57 public SchemaSourceRegistration<?> registration;
59 public File storageDir;
62 public void setUp() throws Exception {
63 this.storageDir = Files.createTempDir();
64 doReturn(this.registration).when(this.registry).registerSchemaSource(any(SchemaSourceProvider.class),
65 any(PotentialSchemaSource.class));
69 public void testCacheAndRestore() throws Exception {
70 final FilesystemSchemaSourceCache<YangTextSchemaSource> cache
71 = new FilesystemSchemaSourceCache<>(this.registry, YangTextSchemaSource.class, this.storageDir);
73 final String content = "content1";
74 final YangTextSchemaSource source = new TestingYangSource("test", "2012-12-12", content);
77 final String content2 = "content2";
78 final YangTextSchemaSource source2 = new TestingYangSource("test2", null, content);
81 final List<File> storedFiles = getFilesFromCache();
82 assertEquals(2, storedFiles.size());
83 final Collection<String> fileNames = filesToFilenamesWithoutRevision(storedFiles);
85 assertThat(fileNames, both(hasItem("test2")).and(hasItem("test@2012-12-12")));
87 assertThat(Files.asCharSource(storedFiles.get(0), StandardCharsets.UTF_8).read(),
88 either(containsString(content)).or(containsString(content2)));
89 assertThat(Files.asCharSource(storedFiles.get(1), StandardCharsets.UTF_8).read(),
90 either(containsString(content)).or(containsString(content2)));
92 verify(this.registry, times(2)).registerSchemaSource(any(SchemaSourceProvider.class),
93 any(PotentialSchemaSource.class));
95 // Create new cache from stored sources
96 new FilesystemSchemaSourceCache<>(this.registry, YangTextSchemaSource.class, this.storageDir);
98 verify(this.registry, times(4)).registerSchemaSource(any(SchemaSourceProvider.class),
99 any(PotentialSchemaSource.class));
101 final List<File> storedFilesAfterNewCache = getFilesFromCache();
102 assertEquals(2, storedFilesAfterNewCache.size());
105 private static Collection<String> filesToFilenamesWithoutRevision(final List<File> storedFiles) {
106 return Collections2.transform(storedFiles, input -> Files.getNameWithoutExtension(input.getName()));
110 public void testCacheDuplicate() throws Exception {
111 final FilesystemSchemaSourceCache<YangTextSchemaSource> cache
112 = new FilesystemSchemaSourceCache<>(this.registry, YangTextSchemaSource.class, this.storageDir);
114 final String content = "content1";
115 final YangTextSchemaSource source = new TestingYangSource("test", null, content);
120 final List<File> storedFiles = getFilesFromCache();
121 assertEquals(1, storedFiles.size());
122 verify(this.registry).registerSchemaSource(any(SchemaSourceProvider.class), any(PotentialSchemaSource.class));
126 public void testCacheMultipleRevisions() throws Exception {
127 final FilesystemSchemaSourceCache<YangTextSchemaSource> cache
128 = new FilesystemSchemaSourceCache<>(this.registry, YangTextSchemaSource.class, this.storageDir);
130 final String content = "content1";
131 final YangTextSchemaSource source = new TestingYangSource("test", null, content);
132 final YangTextSchemaSource source2 = new TestingYangSource("test", "2012-12-12", content);
133 final YangTextSchemaSource source3 = new TestingYangSource("test", "2013-12-12", content);
136 cache.offer(source2);
137 cache.offer(source3);
139 final List<File> storedFiles = getFilesFromCache();
140 assertEquals(3, storedFiles.size());
142 assertThat(filesToFilenamesWithoutRevision(storedFiles), both(hasItem("test"))
143 .and(hasItem("test@2012-12-12")).and(hasItem("test@2013-12-12")));
145 verify(this.registry, times(3)).registerSchemaSource(any(SchemaSourceProvider.class),
146 any(PotentialSchemaSource.class));
150 public void sourceIdToFileEmptyRevWithEmptyDir() {
151 final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create("test");
152 final File sourceIdToFile = FilesystemSchemaSourceCache.sourceIdToFile(sourceIdentifier, this.storageDir);
153 final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(this.registry,
154 YangTextSchemaSource.class, sourceIdToFile);
155 assertNotNull(cache);
156 final List<File> storedFiles = Arrays.asList(sourceIdToFile.listFiles());
157 assertEquals(0, storedFiles.size());
161 public void sourceIdToFileEmptyRevWithOneItemInDir() {
162 final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(this.registry,
163 YangTextSchemaSource.class, this.storageDir);
164 final String content = "content1";
165 final YangTextSchemaSource source = new TestingYangSource("test", "2013-12-12", content);
168 final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create("test");
169 final File sourceIdToFile = FilesystemSchemaSourceCache.sourceIdToFile(sourceIdentifier,
171 assertNotNull(sourceIdToFile);
172 final List<File> storedFiles = Arrays.asList(this.storageDir.listFiles());
173 assertEquals(1, storedFiles.size());
177 public void sourceIdToFileEmptyRevWithMoreItemsInDir() {
178 final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(this.registry,
179 YangTextSchemaSource.class, this.storageDir);
180 final String content = "content1";
181 final YangTextSchemaSource source = new TestingYangSource("test", "2012-12-12", content);
182 final YangTextSchemaSource source2 = new TestingYangSource("test", "2013-12-12", content);
184 cache.offer(source2);
186 final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create("test");
187 final File sourceIdToFile = FilesystemSchemaSourceCache.sourceIdToFile(sourceIdentifier, this.storageDir);
188 assertNotNull(sourceIdToFile);
189 final List<File> storedFiles = Arrays.asList(this.storageDir.listFiles());
190 assertEquals(2, storedFiles.size());
194 public void test() throws Exception {
196 final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(this.registry,
197 YangTextSchemaSource.class, this.storageDir);
198 final String content = "content1";
199 final YangTextSchemaSource source = new TestingYangSource("test", "2013-12-12", content);
201 final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create("test", Revision.of("2013-12-12"));
202 final ListenableFuture<? extends YangTextSchemaSource> checked = cache.getSource(sourceIdentifier);
203 assertNotNull(checked);
204 final YangTextSchemaSource checkedGet = checked.get();
205 assertEquals(sourceIdentifier, checkedGet.getIdentifier());
206 assertTrue(checked.isDone());
210 public void test1() throws Exception {
212 final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(this.registry,
213 YangTextSchemaSource.class, this.storageDir);
214 final String content = "content1";
215 final YangTextSchemaSource source = new TestingYangSource("test", "2013-12-12", content);
217 final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create("test1", Revision.of("2012-12-12"));
218 final ListenableFuture<? extends YangTextSchemaSource> checked = cache.getSource(sourceIdentifier);
219 assertNotNull(checked);
220 assertThrows(ExecutionException.class, () -> checked.get());
223 private List<File> getFilesFromCache() {
224 return Arrays.asList(this.storageDir.listFiles());
227 private class TestingYangSource extends YangTextSchemaSource {
228 private final String content;
230 TestingYangSource(final String name, final String revision, final String content) {
231 super(RevisionSourceIdentifier.create(name, Revision.ofNullable(revision)));
232 this.content = content;
236 protected MoreObjects.ToStringHelper addToStringAttributes(final MoreObjects.ToStringHelper toStringHelper) {
237 return toStringHelper;
241 public InputStream openStream() throws IOException {
242 return new ByteArrayInputStream(this.content.getBytes(StandardCharsets.UTF_8));
246 public Optional<String> getSymbolicName() {
247 return Optional.empty();