91f27b6c8dbbba7a47079dfd51dbed1cda1d0d5b
[yangtools.git] / yang / yang-repo-fs / src / test / java / org / opendaylight / yangtools / yang / model / repo / fs / FilesystemSchemaSourceCacheTest.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.model.repo.fs;
9
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;
23
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;
29 import java.io.File;
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;
51
52 @RunWith(MockitoJUnitRunner.StrictStubs.class)
53 public class FilesystemSchemaSourceCacheTest {
54     @Mock
55     public SchemaSourceRegistry registry;
56     @Mock
57     public SchemaSourceRegistration<?> registration;
58
59     public File storageDir;
60
61     @Before
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));
66     }
67
68     @Test
69     public void testCacheAndRestore() throws Exception {
70         final FilesystemSchemaSourceCache<YangTextSchemaSource> cache
71                 = new FilesystemSchemaSourceCache<>(this.registry, YangTextSchemaSource.class, this.storageDir);
72
73         final String content = "content1";
74         final YangTextSchemaSource source = new TestingYangSource("test", "2012-12-12", content);
75         cache.offer(source);
76
77         final String content2 = "content2";
78         final YangTextSchemaSource source2 = new TestingYangSource("test2", null, content);
79         cache.offer(source2);
80
81         final List<File> storedFiles = getFilesFromCache();
82         assertEquals(2, storedFiles.size());
83         final Collection<String> fileNames = filesToFilenamesWithoutRevision(storedFiles);
84
85         assertThat(fileNames, both(hasItem("test2")).and(hasItem("test@2012-12-12")));
86
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)));
91
92         verify(this.registry, times(2)).registerSchemaSource(any(SchemaSourceProvider.class),
93             any(PotentialSchemaSource.class));
94
95         // Create new cache from stored sources
96         new FilesystemSchemaSourceCache<>(this.registry, YangTextSchemaSource.class, this.storageDir);
97
98         verify(this.registry, times(4)).registerSchemaSource(any(SchemaSourceProvider.class),
99             any(PotentialSchemaSource.class));
100
101         final List<File> storedFilesAfterNewCache = getFilesFromCache();
102         assertEquals(2, storedFilesAfterNewCache.size());
103     }
104
105     private static Collection<String> filesToFilenamesWithoutRevision(final List<File> storedFiles) {
106         return Collections2.transform(storedFiles, input -> Files.getNameWithoutExtension(input.getName()));
107     }
108
109     @Test
110     public void testCacheDuplicate() throws Exception {
111         final FilesystemSchemaSourceCache<YangTextSchemaSource> cache
112                 = new FilesystemSchemaSourceCache<>(this.registry, YangTextSchemaSource.class, this.storageDir);
113
114         final String content = "content1";
115         final YangTextSchemaSource source = new TestingYangSource("test", null, content);
116         // Double offer
117         cache.offer(source);
118         cache.offer(source);
119
120         final List<File> storedFiles = getFilesFromCache();
121         assertEquals(1, storedFiles.size());
122         verify(this.registry).registerSchemaSource(any(SchemaSourceProvider.class), any(PotentialSchemaSource.class));
123     }
124
125     @Test
126     public void testCacheMultipleRevisions() throws Exception {
127         final FilesystemSchemaSourceCache<YangTextSchemaSource> cache
128                 = new FilesystemSchemaSourceCache<>(this.registry, YangTextSchemaSource.class, this.storageDir);
129
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);
134         // Double offer
135         cache.offer(source);
136         cache.offer(source2);
137         cache.offer(source3);
138
139         final List<File> storedFiles = getFilesFromCache();
140         assertEquals(3, storedFiles.size());
141
142         assertThat(filesToFilenamesWithoutRevision(storedFiles), both(hasItem("test"))
143             .and(hasItem("test@2012-12-12")).and(hasItem("test@2013-12-12")));
144
145         verify(this.registry, times(3)).registerSchemaSource(any(SchemaSourceProvider.class),
146             any(PotentialSchemaSource.class));
147     }
148
149     @Test
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());
158     }
159
160     @Test
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);
166         cache.offer(source);
167
168         final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create("test");
169         final File sourceIdToFile = FilesystemSchemaSourceCache.sourceIdToFile(sourceIdentifier,
170                 this.storageDir);
171         assertNotNull(sourceIdToFile);
172         final List<File> storedFiles = Arrays.asList(this.storageDir.listFiles());
173         assertEquals(1, storedFiles.size());
174     }
175
176     @Test
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);
183         cache.offer(source);
184         cache.offer(source2);
185
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());
191     }
192
193     @Test
194     public void test() throws Exception {
195
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);
200         cache.offer(source);
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());
207     }
208
209     @Test
210     public void test1() throws Exception {
211
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);
216         cache.offer(source);
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());
221     }
222
223     private List<File> getFilesFromCache() {
224         return Arrays.asList(this.storageDir.listFiles());
225     }
226
227     private class TestingYangSource extends YangTextSchemaSource {
228         private final String content;
229
230         TestingYangSource(final String name, final String revision, final String content) {
231             super(RevisionSourceIdentifier.create(name, Revision.ofNullable(revision)));
232             this.content = content;
233         }
234
235         @Override
236         protected MoreObjects.ToStringHelper addToStringAttributes(final MoreObjects.ToStringHelper toStringHelper) {
237             return toStringHelper;
238         }
239
240         @Override
241         public InputStream openStream() throws IOException {
242             return new ByteArrayInputStream(this.content.getBytes(StandardCharsets.UTF_8));
243         }
244
245         @Override
246         public Optional<String> getSymbolicName() {
247             return Optional.empty();
248         }
249     }
250 }