package pl.edu.icm.saos.webapp.common;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import java.util.List;
import net.sf.ehcache.Cache;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.mockito.Mockito;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.test.context.web.WebAppConfiguration;
import pl.edu.icm.saos.common.testcommon.category.SlowTest;
import pl.edu.icm.saos.persistence.model.SupremeCourtChamberDivision;
import pl.edu.icm.saos.persistence.model.SupremeCourtJudgmentForm;
import pl.edu.icm.saos.persistence.repository.ScChamberDivisionRepository;
import pl.edu.icm.saos.persistence.repository.ScJudgmentFormRepository;
import pl.edu.icm.saos.webapp.WebappTestSupport;
import pl.edu.icm.saos.webapp.court.ScListService;
import pl.edu.icm.saos.webapp.court.SimpleEntity;
import pl.edu.icm.saos.webapp.court.SimpleEntityConverter;
import com.google.common.collect.Lists;
/**
* @author Łukasz Dumiszewski
*/
@WebAppConfiguration
@Category(SlowTest.class)
public class CachingTest extends WebappTestSupport {
private static Logger log = LoggerFactory.getLogger(CachingTest.class);
@Autowired
private CacheManager cacheManager;
@Autowired
private ScListService scListService;
@Autowired
private ScJudgmentFormRepository scJudgmentFormRepository;
@Autowired
private ScChamberDivisionRepository scChamberDivisionRepository;
@Autowired
private SimpleEntityConverter simpleEntityConverter;
private ScJudgmentFormRepository mockedScJudgmentFormRepository = mock(ScJudgmentFormRepository.class);
private ScChamberDivisionRepository mockedScChamberDivisionRepository = mock(ScChamberDivisionRepository.class);
private SimpleEntityConverter mockedSimpleEntityConverter = mock(SimpleEntityConverter.class);
@Before
public void before() {
scListService.setScJudgmentFormRepository(mockedScJudgmentFormRepository);
scListService.setScChamberDivisionRepository(mockedScChamberDivisionRepository);
scListService.setSimpleEntityConverter(mockedSimpleEntityConverter);
}
@After
public void after() {
scListService.setScJudgmentFormRepository(scJudgmentFormRepository);
scListService.setScChamberDivisionRepository(scChamberDivisionRepository);
scListService.setSimpleEntityConverter(simpleEntityConverter);
}
//------------------------ LOGIC --------------------------
@Test
public void findScJudgmentForms_NoArgumentFunctionCaching() throws InterruptedException {
// given
SupremeCourtJudgmentForm scJudgmentForm1 = mock(SupremeCourtJudgmentForm.class);
SupremeCourtJudgmentForm scJudgmentForm2 = mock(SupremeCourtJudgmentForm.class);
List<SupremeCourtJudgmentForm> scJudgmentForms = Lists.newArrayList(scJudgmentForm1, scJudgmentForm2);
when(mockedScJudgmentFormRepository.findAll()).thenReturn(scJudgmentForms);
SimpleEntity simpleEntity1 = mock(SimpleEntity.class);
SimpleEntity simpleEntity2 = mock(SimpleEntity.class);
List<SimpleEntity> simpleEntities = Lists.newArrayList(simpleEntity1, simpleEntity2);
when(mockedSimpleEntityConverter.convertScJudgmentForms(scJudgmentForms)).thenReturn(simpleEntities);
// execute & assert
// should fetch from db
List<SimpleEntity> retScJudgmentForms = scListService.findScJudgmentForms();
assertTrue(simpleEntities == retScJudgmentForms);
verify(mockedScJudgmentFormRepository).findAll();
// should use cache
retScJudgmentForms = scListService.findScJudgmentForms();
assertTrue(simpleEntities == retScJudgmentForms);
verifyNoMoreInteractions(mockedScJudgmentFormRepository);
// should fetch from db (cache invalidated after some time)
Thread.sleep(1200);
retScJudgmentForms = scListService.findScJudgmentForms();
assertTrue(simpleEntities == retScJudgmentForms);
verify(mockedScJudgmentFormRepository, Mockito.times(2)).findAll();
}
@Test
public void findScJudgmentForms_ArgumentFunctionCaching() throws InterruptedException {
// given
SupremeCourtChamberDivision scDivision1 = mock(SupremeCourtChamberDivision.class);
SupremeCourtChamberDivision scDivision2 = mock(SupremeCourtChamberDivision.class);
SupremeCourtChamberDivision scDivision3 = mock(SupremeCourtChamberDivision.class);
when(scDivision1.getName()).thenReturn("Wydział1");
when(scDivision2.getName()).thenReturn("Wydział2");
when(scDivision3.getName()).thenReturn("Wydział3");
List<SupremeCourtChamberDivision> scDivisions_1_2 = Lists.newArrayList(scDivision1, scDivision2);
List<SupremeCourtChamberDivision> scDivisions_3 = Lists.newArrayList(scDivision3);
when(mockedScChamberDivisionRepository.findAllByScChamberId(1)).thenReturn(scDivisions_1_2);
when(mockedScChamberDivisionRepository.findAllByScChamberId(2)).thenReturn(scDivisions_3);
SimpleEntity simpleDivision1 = mock(SimpleEntity.class);
SimpleEntity simpleDivision2 = mock(SimpleEntity.class);
SimpleEntity simpleDivision3 = mock(SimpleEntity.class);
List<SimpleEntity> simpleDivisions_1_2 = Lists.newArrayList(simpleDivision1, simpleDivision2);
List<SimpleEntity> simpleDivisions_3 = Lists.newArrayList(simpleDivision3);
when(mockedSimpleEntityConverter.convertScChamberDivisions(scDivisions_1_2)).thenReturn(simpleDivisions_1_2);
when(mockedSimpleEntityConverter.convertScChamberDivisions(scDivisions_3)).thenReturn(simpleDivisions_3);
// execute & assert
// for id = 1 should fetch from db
List<SimpleEntity> retScDivisions = scListService.findScChamberDivisions(1);
assertTrue(simpleDivisions_1_2 == retScDivisions);
verify(mockedScChamberDivisionRepository).findAllByScChamberId(1);
// for id = 2 should fetch from db
retScDivisions = scListService.findScChamberDivisions(2);
assertTrue(simpleDivisions_3 == retScDivisions);
verify(mockedScChamberDivisionRepository).findAllByScChamberId(2);
// for id = 1 should use cache
retScDivisions = scListService.findScChamberDivisions(1);
assertTrue(simpleDivisions_1_2 == retScDivisions);
verifyNoMoreInteractions(mockedScChamberDivisionRepository);
// for id = 1 should fetch from db (cache invalidated after some time)
Thread.sleep(1200);
retScDivisions = scListService.findScChamberDivisions(1);
assertTrue(simpleDivisions_1_2 == retScDivisions);
verify(mockedScChamberDivisionRepository, Mockito.times(2)).findAllByScChamberId(1);
printCacheStatistics();
}
//------------------------ PRIVATE --------------------------
private void printCacheStatistics() {
for (String cacheName : cacheManager.getCacheNames()) {
Cache cache = (Cache)cacheManager.getCache(cacheName).getNativeCache();
log.info(cacheName+" - "+ cache.getStatistics());
log.info("keys" + cache.getKeys());
}
}
}