Remove unnecessary stubbings from CachingContentStoreTest

This commit is contained in:
Sara Aspery
2025-02-25 14:48:11 +00:00
parent 99fce928fa
commit 6c08c3cff2

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -25,13 +25,11 @@
*/
package org.alfresco.repo.content.caching;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
@@ -51,6 +49,13 @@ import java.util.Collections;
import java.util.Locale;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.alfresco.repo.content.ContentContext;
import org.alfresco.repo.content.ContentRestoreParams;
import org.alfresco.repo.content.ContentStore;
@@ -62,12 +67,6 @@ import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentStreamListener;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.DirectAccessUrl;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
/**
* Tests for the CachingContentStore class. Tests use mock backing store and cache.
@@ -80,38 +79,35 @@ public class CachingContentStoreTest
private CachingContentStore cachingStore;
private ContentReader sourceContent;
private ContentReader cachedContent;
@Mock
private ContentStore backingStore;
@Mock
private ContentCache cache;
@Before
public void setUp() throws Exception
{
cachingStore = new CachingContentStore(backingStore, cache, false);
cachingStore.setQuota(new UnlimitedQuotaStrategy());
sourceContent = mock(ContentReader.class, "sourceContent");
cachedContent = mock(ContentReader.class, "cachedContent");
}
@Test
public void getReaderForItemInCache()
{
when(cache.contains("url")).thenReturn(true);
when(cache.getReader("url")).thenReturn(cachedContent);
ContentReader returnedReader = cachingStore.getReader("url");
ContentReader returnedReader = cachingStore.getReader("url");
assertSame(returnedReader, cachedContent);
verify(backingStore, never()).getReader(anyString());
}
@Test
// Item isn't in cache, so will be cached and returned.
public void getReaderForItemMissingFromCache()
@@ -120,64 +116,57 @@ public class CachingContentStoreTest
when(backingStore.getReader("url")).thenReturn(sourceContent);
when(sourceContent.getSize()).thenReturn(1274L);
when(cache.put("url", sourceContent)).thenReturn(true);
QuotaManagerStrategy quota = mock(QuotaManagerStrategy.class);
cachingStore.setQuota(quota);
when(quota.beforeWritingCacheFile(1274L)).thenReturn(true);
when(quota.afterWritingCacheFile(1274L)).thenReturn(true);
ContentReader returnedReader = cachingStore.getReader("url");
assertSame(returnedReader, cachedContent);
verify(quota).afterWritingCacheFile(1274L);
// Check backing store reader is only acquired once
verify(backingStore, only()).getReader("url");
}
@Test
public void getReaderForItemMissingFromCacheWillGiveUpAfterRetrying()
{
when(cache.getReader("url")).thenThrow(new CacheMissException("url"));
when(backingStore.getReader("url")).thenReturn(sourceContent);
when(cache.put("url", sourceContent)).thenReturn(true);
ContentReader returnedReader = cachingStore.getReader("url");
// Upon failure, item is removed from cache
verify(cache, atLeastOnce()).remove("url");
// The content comes direct from the backing store
assertSame(returnedReader, sourceContent);
}
@Test
public void getReaderForItemMissingFromCacheWillRetryAndCanSucceed()
{
when(cache.getReader("url")).
thenThrow(new CacheMissException("url")).
thenReturn(cachedContent);
when(cache.getReader("url")).thenThrow(new CacheMissException("url")).thenReturn(cachedContent);
when(backingStore.getReader("url")).thenReturn(sourceContent);
when(cache.put("url", sourceContent)).thenReturn(true);
ContentReader returnedReader = cachingStore.getReader("url");
assertSame(returnedReader, cachedContent);
}
@Test
public void getReaderForItemMissingFromCacheButNoContentToCache()
{
when(cache.getReader("url")).thenThrow(new CacheMissException("url"));
when(backingStore.getReader("url")).thenReturn(sourceContent);
when(cache.put("url", sourceContent)).thenReturn(false);
cachingStore.getReader("url");
}
@Test
// When attempting to read uncached content.
public void quotaManagerCanVetoCacheFileWriting()
@@ -187,32 +176,30 @@ public class CachingContentStoreTest
cachingStore.setQuota(quota);
when(sourceContent.getSize()).thenReturn(1274L);
when(quota.beforeWritingCacheFile(1274L)).thenReturn(false);
ContentReader returnedReader = cachingStore.getReader("url");
verify(cache, never()).put("url", sourceContent);
assertSame(returnedReader, sourceContent);
verify(quota, never()).afterWritingCacheFile(anyLong());
}
@Test
public void getWriterWhenNotCacheOnInbound()
{
{
QuotaManagerStrategy quota = mock(QuotaManagerStrategy.class);
cachingStore.setQuota(quota);
ContentContext ctx = ContentContext.NULL_CONTEXT;
cachingStore.getWriter(ctx);
verify(backingStore).getWriter(ctx);
// No quota manager interaction - as no caching happening.
verify(quota, never()).beforeWritingCacheFile(anyLong());
verify(quota, never()).afterWritingCacheFile(anyLong());
}
@Test
public void getWriterWhenCacheOnInbound() throws ContentIOException, IOException
{
@@ -229,12 +216,12 @@ public class CachingContentStoreTest
when(cacheWriter.getSize()).thenReturn(54321L);
QuotaManagerStrategy quota = mock(QuotaManagerStrategy.class);
cachingStore.setQuota(quota);
// Quota manager interceptor is fired.
when(quota.beforeWritingCacheFile(0L)).thenReturn(true);
cachingStore.getWriter(ctx);
// Check that a listener was attached to cacheWriter with the correct behaviour
ArgumentCaptor<ContentStreamListener> arg = ArgumentCaptor.forClass(ContentStreamListener.class);
verify(cacheWriter).addListener(arg.capture());
@@ -245,8 +232,7 @@ public class CachingContentStoreTest
// Post caching quota manager hook is fired.
verify(quota).afterWritingCacheFile(54321L);
}
@Test
// When attempting to perform write-through caching, i.e. cacheOnInbound = true
public void quotaManagerCanVetoInboundCaching()
@@ -254,19 +240,18 @@ public class CachingContentStoreTest
cachingStore = new CachingContentStore(backingStore, cache, true);
QuotaManagerStrategy quota = mock(QuotaManagerStrategy.class);
cachingStore.setQuota(quota);
ContentContext ctx = ContentContext.NULL_CONTEXT;
ContentWriter backingStoreWriter = mock(ContentWriter.class);
when(backingStore.getWriter(ctx)).thenReturn(backingStoreWriter);
when(quota.beforeWritingCacheFile(0L)).thenReturn(false);
ContentWriter returnedWriter = cachingStore.getWriter(ctx);
assertSame("Should be writing direct to backing store", backingStoreWriter, returnedWriter);
verify(quota, never()).afterWritingCacheFile(anyLong());
}
@Test
public void quotaManagerCanRequestFileDeletionFromCacheAfterWrite()
{
@@ -283,19 +268,19 @@ public class CachingContentStoreTest
when(cacheWriter.getSize()).thenReturn(54321L);
QuotaManagerStrategy quota = mock(QuotaManagerStrategy.class);
cachingStore.setQuota(quota);
// Quota manager interceptor is fired.
when(quota.beforeWritingCacheFile(0L)).thenReturn(true);
cachingStore.getWriter(ctx);
// Check that a listener was attached to cacheWriter with the correct behaviour
ArgumentCaptor<ContentStreamListener> arg = ArgumentCaptor.forClass(ContentStreamListener.class);
verify(cacheWriter).addListener(arg.capture());
// Don't keep the new cache file
when(quota.afterWritingCacheFile(54321L)).thenReturn(false);
// Simulate a stream close
arg.getValue().contentStreamClosed();
// Check behaviour of the listener
@@ -306,7 +291,7 @@ public class CachingContentStoreTest
verify(cache).deleteFile("url");
verify(cache).remove("url");
}
@Test
public void quotaManagerCanRequestFileDeletionFromCacheAfterWriteWhenNotCacheOnInbound()
{
@@ -314,17 +299,16 @@ public class CachingContentStoreTest
when(backingStore.getReader("url")).thenReturn(sourceContent);
when(sourceContent.getSize()).thenReturn(1274L);
when(cache.put("url", sourceContent)).thenReturn(true);
QuotaManagerStrategy quota = mock(QuotaManagerStrategy.class);
cachingStore.setQuota(quota);
// Don't veto writing the cache file.
when(quota.beforeWritingCacheFile(1274L)).thenReturn(true);
// Do request cache file deletion.
when(quota.afterWritingCacheFile(1234L)).thenReturn(false);
ContentReader returnedReader = cachingStore.getReader("url");
// Was the file deleted?
verify(cache).deleteFile("url");
verify(cache).remove("url");
@@ -332,12 +316,12 @@ public class CachingContentStoreTest
// rather than the cache.
assertSame(returnedReader, sourceContent);
}
@Test(expected=RuntimeException.class)
@Test(expected = RuntimeException.class)
// Check that exceptions raised by the backing store's putContent(ContentReader)
// aren't swallowed and can therefore cause the transaction to fail.
public void exceptionRaisedWhenCopyingTempToBackingStoreIsPropogatedCorrectly()
throws ContentIOException, IOException
public void exceptionRaisedWhenCopyingTempToBackingStoreIsPropogatedCorrectly()
throws ContentIOException, IOException
{
cachingStore = new CachingContentStore(backingStore, cache, true);
ContentContext ctx = ContentContext.NULL_CONTEXT;
@@ -348,19 +332,18 @@ public class CachingContentStoreTest
when(cache.getWriter("url")).thenReturn(cacheWriter);
ContentReader readerFromCacheWriter = mock(ContentReader.class);
when(cacheWriter.getReader()).thenReturn(readerFromCacheWriter);
doThrow(new RuntimeException()).when(bsWriter).putContent(any(ContentReader.class));
cachingStore.getWriter(ctx);
// Get the stream listener and trigger it
ArgumentCaptor<ContentStreamListener> arg = ArgumentCaptor.forClass(ContentStreamListener.class);
verify(cacheWriter).addListener(arg.capture());
// Simulate a stream close
arg.getValue().contentStreamClosed();
}
@Test
public void encodingAttrsCopiedToBackingStoreWriter()
{
@@ -373,28 +356,28 @@ public class CachingContentStoreTest
when(cache.getWriter("url")).thenReturn(cacheWriter);
ContentReader readerFromCacheWriter = mock(ContentReader.class);
when(cacheWriter.getReader()).thenReturn(readerFromCacheWriter);
when(cacheWriter.getEncoding()).thenReturn("UTF-8");
when(cacheWriter.getLocale()).thenReturn(Locale.UK);
when(cacheWriter.getMimetype()).thenReturn("not/real/mimetype");
when(cacheWriter.getMimetype()).thenReturn("not/real/mimetype");
cachingStore.getWriter(ctx);
// Get the stream listener and trigger it
ArgumentCaptor<ContentStreamListener> arg = ArgumentCaptor.forClass(ContentStreamListener.class);
verify(cacheWriter).addListener(arg.capture());
// Simulate a stream close
arg.getValue().contentStreamClosed();
verify(bsWriter).setEncoding("UTF-8");
verify(bsWriter).setLocale(Locale.UK);
verify(bsWriter).setMimetype("not/real/mimetype");
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tests for spoofed content follow...
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@Test
public void spoofedGetReader()
{
@@ -405,7 +388,7 @@ public class CachingContentStoreTest
assertEquals(1024, reader.getSize());
verify(backingStore, never()).getReader(anyString());
}
@Test
public void spoofedDelete()
{
@@ -415,7 +398,7 @@ public class CachingContentStoreTest
assertFalse(deleted);
verify(backingStore, never()).delete(anyString());
}
@Test
public void spoofedExists()
{
@@ -425,7 +408,7 @@ public class CachingContentStoreTest
assertTrue(exists);
verify(backingStore, never()).exists(anyString());
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tests for delegated methods follow...
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -434,64 +417,58 @@ public class CachingContentStoreTest
{
when(backingStore.isContentUrlSupported("url")).thenReturn(true);
assertTrue(cachingStore.isContentUrlSupported("url"));
when(backingStore.isContentUrlSupported("url")).thenReturn(false);
assertFalse(cachingStore.isContentUrlSupported("url"));
}
@Test
public void delegatedIsWriteSupported()
{
when(backingStore.isWriteSupported()).thenReturn(true);
assertTrue(cachingStore.isWriteSupported());
when(backingStore.isWriteSupported()).thenReturn(false);
assertFalse(cachingStore.isWriteSupported());
}
@Test
public void delegatedGetSpaceFree()
{
when(backingStore.getSpaceFree()).thenReturn(124L);
assertEquals(124L, cachingStore.getSpaceFree());
}
@Test
public void delegatedGetSpaceTotal()
{
when(backingStore.getSpaceTotal()).thenReturn(4234L);
assertEquals(4234L, cachingStore.getSpaceTotal());
}
@Test
public void delegatedGetRootLocation()
{
when(backingStore.getRootLocation()).thenReturn("/random/root/dir");
assertEquals("/random/root/dir", cachingStore.getRootLocation());
}
@Test
public void delegatedExists()
{
when(backingStore.exists("url")).thenReturn(true);
assertTrue(cachingStore.exists("url"));
when(backingStore.exists("url")).thenReturn(false);
assertFalse(cachingStore.exists("url"));
}
@Test
public void delegatedDelete()
{
when(backingStore.delete("url")).thenReturn(true);
assertTrue(cachingStore.delete("url"));
when(backingStore.delete("url")).thenReturn(false);
assertFalse(cachingStore.delete("url"));
}
@@ -511,7 +488,7 @@ public class CachingContentStoreTest
try
{
when(backingStore.requestContentDirectUrl(anyString(), eq(true), anyString(), anyString(), anyLong())).thenThrow(new UnsupportedOperationException());
cachingStore.requestContentDirectUrl("url", true,"someFile", "someMimetype", 30L);
cachingStore.requestContentDirectUrl("url", true, "someFile", "someMimetype", 30L);
fail();
}
catch (UnsupportedOperationException e)
@@ -524,7 +501,7 @@ public class CachingContentStoreTest
public void getRequestContentDirectUrl()
{
when(backingStore.requestContentDirectUrl(anyString(), eq(true), anyString(), anyString(), anyLong())).thenReturn(new DirectAccessUrl());
cachingStore.requestContentDirectUrl("url", true,"someFile", "someMimeType", 30L);
cachingStore.requestContentDirectUrl("url", true, "someFile", "someMimeType", 30L);
}
@Test