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.jupiter.api.Assertions.assertEquals;
16 import static org.junit.jupiter.api.Assertions.assertNotNull;
17 import static org.junit.jupiter.api.Assertions.assertThrows;
18 import static org.junit.jupiter.api.Assertions.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.util.concurrent.ListenableFuture;
28 import java.io.IOException;
29 import java.io.Reader;
30 import java.io.StringReader;
31 import java.nio.file.Files;
32 import java.util.Arrays;
33 import java.util.Collection;
34 import java.util.List;
35 import java.util.concurrent.ExecutionException;
36 import org.junit.jupiter.api.BeforeEach;
37 import org.junit.jupiter.api.Test;
38 import org.junit.jupiter.api.extension.ExtendWith;
39 import org.mockito.Mock;
40 import org.mockito.junit.jupiter.MockitoExtension;
41 import org.mockito.junit.jupiter.MockitoSettings;
42 import org.mockito.quality.Strictness;
43 import org.opendaylight.yangtools.concepts.Registration;
44 import org.opendaylight.yangtools.yang.model.api.source.SourceIdentifier;
45 import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
46 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
47 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
48 import org.opendaylight.yangtools.yang.model.spi.source.YangTextSource;
50 @ExtendWith(MockitoExtension.class)
51 @MockitoSettings(strictness = Strictness.LENIENT)
52 public class FilesystemSchemaSourceCacheTest {
54 public SchemaSourceRegistry registry;
56 public Registration registration;
58 public File storageDir;
61 public void setUp() throws Exception {
62 storageDir = Files.createTempDirectory(null).toFile();
63 doReturn(registration).when(registry).registerSchemaSource(any(SchemaSourceProvider.class),
64 any(PotentialSchemaSource.class));
68 public void testCacheAndRestore() throws Exception {
69 final FilesystemSchemaSourceCache<YangTextSource> cache = new FilesystemSchemaSourceCache<>(registry,
70 YangTextSource.class, storageDir);
72 final String content = "content1";
73 final YangTextSource source = new TestingYangSource("test", "2012-12-12", content);
76 final String content2 = "content2";
77 final YangTextSource source2 = new TestingYangSource("test2", null, content);
80 final List<File> storedFiles = getFilesFromCache();
81 assertEquals(2, storedFiles.size());
82 final Collection<String> fileNames = filesToFilenamesWithoutRevision(storedFiles);
84 assertThat(fileNames, both(hasItem("test2")).and(hasItem("test@2012-12-12")));
86 assertThat(Files.readString(storedFiles.get(0).toPath()),
87 either(containsString(content)).or(containsString(content2)));
88 assertThat(Files.readString(storedFiles.get(1).toPath()),
89 either(containsString(content)).or(containsString(content2)));
91 verify(registry, times(2)).registerSchemaSource(any(SchemaSourceProvider.class),
92 any(PotentialSchemaSource.class));
94 // Create new cache from stored sources
95 new FilesystemSchemaSourceCache<>(registry, YangTextSource.class, storageDir);
97 verify(registry, times(4)).registerSchemaSource(any(SchemaSourceProvider.class),
98 any(PotentialSchemaSource.class));
100 final List<File> storedFilesAfterNewCache = getFilesFromCache();
101 assertEquals(2, storedFilesAfterNewCache.size());
104 private static Collection<String> filesToFilenamesWithoutRevision(final List<File> storedFiles) {
105 return Collections2.transform(storedFiles, input -> {
106 final String fileName = input.getName();
107 final int dotIndex = fileName.lastIndexOf('.');
108 return dotIndex == -1 ? fileName : fileName.substring(0, dotIndex);
113 public void testCacheDuplicate() throws Exception {
114 final FilesystemSchemaSourceCache<YangTextSource> cache = new FilesystemSchemaSourceCache<>(registry,
115 YangTextSource.class, storageDir);
117 final String content = "content1";
118 final YangTextSource source = new TestingYangSource("test", null, content);
123 final List<File> storedFiles = getFilesFromCache();
124 assertEquals(1, storedFiles.size());
125 verify(registry).registerSchemaSource(any(SchemaSourceProvider.class), any(PotentialSchemaSource.class));
129 public void testCacheMultipleRevisions() throws Exception {
130 final FilesystemSchemaSourceCache<YangTextSource> cache = new FilesystemSchemaSourceCache<>(registry,
131 YangTextSource.class, storageDir);
133 final String content = "content1";
134 final YangTextSource source = new TestingYangSource("test", null, content);
135 final YangTextSource source2 = new TestingYangSource("test", "2012-12-12", content);
136 final YangTextSource source3 = new TestingYangSource("test", "2013-12-12", content);
139 cache.offer(source2);
140 cache.offer(source3);
142 final List<File> storedFiles = getFilesFromCache();
143 assertEquals(3, storedFiles.size());
145 assertThat(filesToFilenamesWithoutRevision(storedFiles), both(hasItem("test"))
146 .and(hasItem("test@2012-12-12")).and(hasItem("test@2013-12-12")));
148 verify(registry, times(3)).registerSchemaSource(any(SchemaSourceProvider.class),
149 any(PotentialSchemaSource.class));
153 public void sourceIdToFileEmptyRevWithEmptyDir() {
154 final SourceIdentifier sourceIdentifier = new SourceIdentifier("test");
155 final File sourceIdToFile = FilesystemSchemaSourceCache.sourceIdToFile(sourceIdentifier, storageDir);
156 final FilesystemSchemaSourceCache<YangTextSource> cache = new FilesystemSchemaSourceCache<>(registry,
157 YangTextSource.class, sourceIdToFile);
158 assertNotNull(cache);
159 final List<File> storedFiles = Arrays.asList(sourceIdToFile.listFiles());
160 assertEquals(0, storedFiles.size());
164 public void sourceIdToFileEmptyRevWithOneItemInDir() {
165 final FilesystemSchemaSourceCache<YangTextSource> cache = new FilesystemSchemaSourceCache<>(registry,
166 YangTextSource.class, storageDir);
167 final String content = "content1";
168 final YangTextSource source = new TestingYangSource("test", "2013-12-12", content);
171 final SourceIdentifier sourceIdentifier = new SourceIdentifier("test");
172 final File sourceIdToFile = FilesystemSchemaSourceCache.sourceIdToFile(sourceIdentifier,
174 assertNotNull(sourceIdToFile);
175 final List<File> storedFiles = Arrays.asList(storageDir.listFiles());
176 assertEquals(1, storedFiles.size());
180 public void sourceIdToFileEmptyRevWithMoreItemsInDir() {
181 final FilesystemSchemaSourceCache<YangTextSource> cache = new FilesystemSchemaSourceCache<>(registry,
182 YangTextSource.class, storageDir);
183 final String content = "content1";
184 final YangTextSource source = new TestingYangSource("test", "2012-12-12", content);
185 final YangTextSource source2 = new TestingYangSource("test", "2013-12-12", content);
187 cache.offer(source2);
189 final SourceIdentifier sourceIdentifier = new SourceIdentifier("test");
190 final File sourceIdToFile = FilesystemSchemaSourceCache.sourceIdToFile(sourceIdentifier, storageDir);
191 assertNotNull(sourceIdToFile);
192 final List<File> storedFiles = Arrays.asList(storageDir.listFiles());
193 assertEquals(2, storedFiles.size());
197 public void test() throws Exception {
198 final FilesystemSchemaSourceCache<YangTextSource> cache = new FilesystemSchemaSourceCache<>(registry,
199 YangTextSource.class, storageDir);
200 final String content = "content1";
201 final YangTextSource source = new TestingYangSource("test", "2013-12-12", content);
203 final SourceIdentifier sourceIdentifier = new SourceIdentifier("test", "2013-12-12");
204 final ListenableFuture<? extends YangTextSource> checked = cache.getSource(sourceIdentifier);
205 assertNotNull(checked);
206 assertTrue(checked.isDone());
207 final YangTextSource checkedGet = checked.get();
208 assertEquals(sourceIdentifier, checkedGet.sourceId());
212 public void test1() throws Exception {
213 final FilesystemSchemaSourceCache<YangTextSource> cache = new FilesystemSchemaSourceCache<>(registry,
214 YangTextSource.class, storageDir);
215 final String content = "content1";
216 final YangTextSource source = new TestingYangSource("test", "2013-12-12", content);
218 final SourceIdentifier sourceIdentifier = new SourceIdentifier("test1", "2012-12-12");
219 final ListenableFuture<? extends YangTextSource> checked = cache.getSource(sourceIdentifier);
220 assertNotNull(checked);
221 assertThrows(ExecutionException.class, () -> checked.get());
224 private List<File> getFilesFromCache() {
225 return Arrays.asList(storageDir.listFiles());
228 private static class TestingYangSource extends YangTextSource {
229 private final String content;
231 TestingYangSource(final String name, final String revision, final String content) {
232 super(new SourceIdentifier(name, revision));
233 this.content = content;
237 protected MoreObjects.ToStringHelper addToStringAttributes(final MoreObjects.ToStringHelper toStringHelper) {
238 return toStringHelper;
242 public Reader openStream() throws IOException {
243 return new StringReader(content);
247 public String symbolicName() {