/* * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.yangtools.yang.model.repo.util; import static org.hamcrest.CoreMatchers.both; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.either; import static org.hamcrest.CoreMatchers.hasItem; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import com.google.common.base.MoreObjects; import com.google.common.base.Optional; import com.google.common.collect.Collections2; import com.google.common.io.Files; import com.google.common.util.concurrent.CheckedFuture; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.concurrent.ExecutionException; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier; import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException; import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource; import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider; import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration; import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry; public class FilesystemSchemaSourceCacheTest { @Mock private SchemaSourceRegistry registry; @Mock private SchemaSourceRegistration<?> registration; private File storageDir; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); this.storageDir = Files.createTempDir(); doReturn(this.registration).when(this.registry).registerSchemaSource(any(SchemaSourceProvider.class), any(PotentialSchemaSource.class)); } @Test public void testCacheAndRestore() throws Exception { final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(this.registry, YangTextSchemaSource.class, this.storageDir); final String content = "content1"; final YangTextSchemaSource source = new TestingYangSource("test", "2012-12-12", content); cache.offer(source); final String content2 = "content2"; final YangTextSchemaSource source2 = new TestingYangSource("test2", null, content); cache.offer(source2); final List<File> storedFiles = getFilesFromCache(); assertEquals(2, storedFiles.size()); final Collection<String> fileNames = filesToFilenamesWithoutRevision(storedFiles); assertThat(fileNames, both(hasItem("test2")).and(hasItem("test@2012-12-12"))); assertThat(Files.toString(storedFiles.get(0), StandardCharsets.UTF_8), either(containsString(content)).or(containsString(content2))); assertThat(Files.toString(storedFiles.get(1), StandardCharsets.UTF_8), either(containsString(content)).or(containsString(content2))); verify(this.registry, times(2)).registerSchemaSource(any(SchemaSourceProvider.class), any(PotentialSchemaSource.class)); // Create new cache from stored sources new FilesystemSchemaSourceCache<>(this.registry, YangTextSchemaSource.class, this.storageDir); verify(this.registry, times(4)).registerSchemaSource(any(SchemaSourceProvider.class), any(PotentialSchemaSource.class)); final List<File> storedFilesAfterNewCache = getFilesFromCache(); assertEquals(2, storedFilesAfterNewCache.size()); } private static Collection<String> filesToFilenamesWithoutRevision(final List<File> storedFiles) { return Collections2.transform(storedFiles, input -> Files.getNameWithoutExtension(input.getName())); } @Test public void testCacheDuplicate() throws Exception { final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(this.registry, YangTextSchemaSource.class, this.storageDir); final String content = "content1"; final YangTextSchemaSource source = new TestingYangSource("test", null, content); // Double offer cache.offer(source); cache.offer(source); final List<File> storedFiles = getFilesFromCache(); assertEquals(1, storedFiles.size()); verify(this.registry).registerSchemaSource(any(SchemaSourceProvider.class), any(PotentialSchemaSource.class)); } @Test public void testCacheMultipleRevisions() throws Exception { final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(this.registry, YangTextSchemaSource.class, this.storageDir); final String content = "content1"; final YangTextSchemaSource source = new TestingYangSource("test", null, content); final YangTextSchemaSource source2 = new TestingYangSource("test", "2012-12-12", content); final YangTextSchemaSource source3 = new TestingYangSource("test", "2013-12-12", content); // Double offer cache.offer(source); cache.offer(source2); cache.offer(source3); final List<File> storedFiles = getFilesFromCache(); assertEquals(3, storedFiles.size()); assertThat(filesToFilenamesWithoutRevision(storedFiles), both(hasItem("test")) .and(hasItem("test@2012-12-12")).and(hasItem("test@2013-12-12"))); verify(this.registry, times(3)).registerSchemaSource(any(SchemaSourceProvider.class), any(PotentialSchemaSource.class)); } @Test public void sourceIdToFileEmptyRevWithEmptyDir() { final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create("test", ""); final File sourceIdToFile = FilesystemSchemaSourceCache.sourceIdToFile(sourceIdentifier, this.storageDir); final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(this.registry, YangTextSchemaSource.class, sourceIdToFile); Assert.assertNotNull(cache); final List<File> storedFiles = Arrays.asList(sourceIdToFile.listFiles()); assertEquals(0, storedFiles.size()); } @Test public void sourceIdToFileEmptyRevWithOneItemInDir() { final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(this.registry, YangTextSchemaSource.class, this.storageDir); final String content = "content1"; final YangTextSchemaSource source = new TestingYangSource("test", "2013-12-12", content); cache.offer(source); final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create("test", ""); final File sourceIdToFile = FilesystemSchemaSourceCache.sourceIdToFile(sourceIdentifier, this.storageDir); Assert.assertNotNull(sourceIdToFile); final List<File> storedFiles = Arrays.asList(this.storageDir.listFiles()); assertEquals(1, storedFiles.size()); } @Test public void sourceIdToFileEmptyRevWithMoreItemsInDir() { final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(this.registry, YangTextSchemaSource.class, this.storageDir); final String content = "content1"; final YangTextSchemaSource source = new TestingYangSource("test", "2012-12-12", content); final YangTextSchemaSource source2 = new TestingYangSource("test", "2013-12-12", content); cache.offer(source); cache.offer(source2); final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create("test", ""); final File sourceIdToFile = FilesystemSchemaSourceCache.sourceIdToFile(sourceIdentifier, this.storageDir); Assert.assertNotNull(sourceIdToFile); final List<File> storedFiles = Arrays.asList(this.storageDir.listFiles()); assertEquals(2, storedFiles.size()); } @Test public void test() throws Exception { final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(this.registry, YangTextSchemaSource.class, this.storageDir); final String content = "content1"; final YangTextSchemaSource source = new TestingYangSource("test", "2013-12-12", content); cache.offer(source); final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create("test", "2013-12-12"); final CheckedFuture<? extends YangTextSchemaSource, SchemaSourceException> checked = cache .getSource(sourceIdentifier); Assert.assertNotNull(checked); final YangTextSchemaSource checkedGet = checked.checkedGet(); Assert.assertEquals(sourceIdentifier, checkedGet.getIdentifier()); Assert.assertTrue(checked.isDone()); } @Test(expected = ExecutionException.class) public void test1() throws Exception { final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(this.registry, YangTextSchemaSource.class, this.storageDir); final String content = "content1"; final YangTextSchemaSource source = new TestingYangSource("test", "2013-12-12", content); cache.offer(source); final SourceIdentifier sourceIdentifier = RevisionSourceIdentifier.create("test1", "2012-12-12"); final CheckedFuture<? extends YangTextSchemaSource, SchemaSourceException> checked = cache .getSource(sourceIdentifier); Assert.assertNotNull(checked); checked.get(); } private List<File> getFilesFromCache() { return Arrays.asList(this.storageDir.listFiles()); } private class TestingYangSource extends YangTextSchemaSource { private final String content; protected TestingYangSource(final String name, final String revision, final String content) { super(RevisionSourceIdentifier.create(name, Optional.fromNullable(revision))); this.content = content; } @Override protected MoreObjects.ToStringHelper addToStringAttributes(final MoreObjects.ToStringHelper toStringHelper) { return toStringHelper; } @Override public InputStream openStream() throws IOException { return new ByteArrayInputStream(this.content.getBytes(StandardCharsets.UTF_8)); } } }