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;
27 import java.io.ByteArrayInputStream;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.nio.charset.StandardCharsets;
32 import java.nio.file.Files;
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.jupiter.api.BeforeEach;
39 import org.junit.jupiter.api.Test;
40 import org.junit.jupiter.api.extension.ExtendWith;
41 import org.mockito.Mock;
42 import org.mockito.junit.jupiter.MockitoExtension;
43 import org.mockito.junit.jupiter.MockitoSettings;
44 import org.mockito.quality.Strictness;
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 @ExtendWith(MockitoExtension.class)
53 @MockitoSettings(strictness = Strictness.LENIENT)
54 public class FilesystemSchemaSourceCacheTest {
56 public SchemaSourceRegistry registry;
58 public SchemaSourceRegistration<?> registration;
60 public File storageDir;
63 public void setUp() throws Exception {
64 storageDir = Files.createTempDirectory(null).toFile();
65 doReturn(registration).when(registry).registerSchemaSource(any(SchemaSourceProvider.class),
66 any(PotentialSchemaSource.class));
70 public void testCacheAndRestore() throws Exception {
71 final FilesystemSchemaSourceCache<YangTextSchemaSource> cache
72 = new FilesystemSchemaSourceCache<>(registry, YangTextSchemaSource.class, storageDir);
74 final String content = "content1";
75 final YangTextSchemaSource source = new TestingYangSource("test", "2012-12-12", content);
78 final String content2 = "content2";
79 final YangTextSchemaSource source2 = new TestingYangSource("test2", null, content);
82 final List<File> storedFiles = getFilesFromCache();
83 assertEquals(2, storedFiles.size());
84 final Collection<String> fileNames = filesToFilenamesWithoutRevision(storedFiles);
86 assertThat(fileNames, both(hasItem("test2")).and(hasItem("test@2012-12-12")));
88 assertThat(Files.readString(storedFiles.get(0).toPath()),
89 either(containsString(content)).or(containsString(content2)));
90 assertThat(Files.readString(storedFiles.get(1).toPath()),
91 either(containsString(content)).or(containsString(content2)));
93 verify(registry, times(2)).registerSchemaSource(any(SchemaSourceProvider.class),
94 any(PotentialSchemaSource.class));
96 // Create new cache from stored sources
97 new FilesystemSchemaSourceCache<>(registry, YangTextSchemaSource.class, storageDir);
99 verify(registry, times(4)).registerSchemaSource(any(SchemaSourceProvider.class),
100 any(PotentialSchemaSource.class));
102 final List<File> storedFilesAfterNewCache = getFilesFromCache();
103 assertEquals(2, storedFilesAfterNewCache.size());
106 private static Collection<String> filesToFilenamesWithoutRevision(final List<File> storedFiles) {
107 return Collections2.transform(storedFiles, input -> {
108 final String fileName = input.getName();
109 final int dotIndex = fileName.lastIndexOf('.');
110 return dotIndex == -1 ? fileName : fileName.substring(0, dotIndex);
115 public void testCacheDuplicate() throws Exception {
116 final FilesystemSchemaSourceCache<YangTextSchemaSource> cache
117 = new FilesystemSchemaSourceCache<>(registry, YangTextSchemaSource.class, storageDir);
119 final String content = "content1";
120 final YangTextSchemaSource source = new TestingYangSource("test", null, content);
125 final List<File> storedFiles = getFilesFromCache();
126 assertEquals(1, storedFiles.size());
127 verify(registry).registerSchemaSource(any(SchemaSourceProvider.class), any(PotentialSchemaSource.class));
131 public void testCacheMultipleRevisions() throws Exception {
132 final FilesystemSchemaSourceCache<YangTextSchemaSource> cache
133 = new FilesystemSchemaSourceCache<>(registry, YangTextSchemaSource.class, storageDir);
135 final String content = "content1";
136 final YangTextSchemaSource source = new TestingYangSource("test", null, content);
137 final YangTextSchemaSource source2 = new TestingYangSource("test", "2012-12-12", content);
138 final YangTextSchemaSource source3 = new TestingYangSource("test", "2013-12-12", content);
141 cache.offer(source2);
142 cache.offer(source3);
144 final List<File> storedFiles = getFilesFromCache();
145 assertEquals(3, storedFiles.size());
147 assertThat(filesToFilenamesWithoutRevision(storedFiles), both(hasItem("test"))
148 .and(hasItem("test@2012-12-12")).and(hasItem("test@2013-12-12")));
150 verify(registry, times(3)).registerSchemaSource(any(SchemaSourceProvider.class),
151 any(PotentialSchemaSource.class));
155 public void sourceIdToFileEmptyRevWithEmptyDir() {
156 final SourceIdentifier sourceIdentifier = new SourceIdentifier("test");
157 final File sourceIdToFile = FilesystemSchemaSourceCache.sourceIdToFile(sourceIdentifier, storageDir);
158 final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(registry,
159 YangTextSchemaSource.class, sourceIdToFile);
160 assertNotNull(cache);
161 final List<File> storedFiles = Arrays.asList(sourceIdToFile.listFiles());
162 assertEquals(0, storedFiles.size());
166 public void sourceIdToFileEmptyRevWithOneItemInDir() {
167 final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(registry,
168 YangTextSchemaSource.class, storageDir);
169 final String content = "content1";
170 final YangTextSchemaSource source = new TestingYangSource("test", "2013-12-12", content);
173 final SourceIdentifier sourceIdentifier = new SourceIdentifier("test");
174 final File sourceIdToFile = FilesystemSchemaSourceCache.sourceIdToFile(sourceIdentifier,
176 assertNotNull(sourceIdToFile);
177 final List<File> storedFiles = Arrays.asList(storageDir.listFiles());
178 assertEquals(1, storedFiles.size());
182 public void sourceIdToFileEmptyRevWithMoreItemsInDir() {
183 final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(registry,
184 YangTextSchemaSource.class, storageDir);
185 final String content = "content1";
186 final YangTextSchemaSource source = new TestingYangSource("test", "2012-12-12", content);
187 final YangTextSchemaSource source2 = new TestingYangSource("test", "2013-12-12", content);
189 cache.offer(source2);
191 final SourceIdentifier sourceIdentifier = new SourceIdentifier("test");
192 final File sourceIdToFile = FilesystemSchemaSourceCache.sourceIdToFile(sourceIdentifier, storageDir);
193 assertNotNull(sourceIdToFile);
194 final List<File> storedFiles = Arrays.asList(storageDir.listFiles());
195 assertEquals(2, storedFiles.size());
199 public void test() throws Exception {
200 final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(registry,
201 YangTextSchemaSource.class, storageDir);
202 final String content = "content1";
203 final YangTextSchemaSource source = new TestingYangSource("test", "2013-12-12", content);
205 final SourceIdentifier sourceIdentifier = new SourceIdentifier("test", "2013-12-12");
206 final ListenableFuture<? extends YangTextSchemaSource> checked = cache.getSource(sourceIdentifier);
207 assertNotNull(checked);
208 assertTrue(checked.isDone());
209 final YangTextSchemaSource checkedGet = checked.get();
210 assertEquals(sourceIdentifier, checkedGet.getIdentifier());
214 public void test1() throws Exception {
215 final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(registry,
216 YangTextSchemaSource.class, storageDir);
217 final String content = "content1";
218 final YangTextSchemaSource source = new TestingYangSource("test", "2013-12-12", content);
220 final SourceIdentifier sourceIdentifier = new SourceIdentifier("test1", "2012-12-12");
221 final ListenableFuture<? extends YangTextSchemaSource> checked = cache.getSource(sourceIdentifier);
222 assertNotNull(checked);
223 assertThrows(ExecutionException.class, () -> checked.get());
226 private List<File> getFilesFromCache() {
227 return Arrays.asList(storageDir.listFiles());
230 private static class TestingYangSource extends YangTextSchemaSource {
231 private final String content;
233 TestingYangSource(final String name, final String revision, final String content) {
234 super(new SourceIdentifier(name, revision));
235 this.content = content;
239 protected MoreObjects.ToStringHelper addToStringAttributes(final MoreObjects.ToStringHelper toStringHelper) {
240 return toStringHelper;
244 public InputStream openStream() throws IOException {
245 return new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
249 public Optional<String> getSymbolicName() {
250 return Optional.empty();