From 40b5a0937811d860b97bbc57284a050c4b259b81 Mon Sep 17 00:00:00 2001 From: Duarte Meneses Date: Wed, 30 Sep 2015 15:34:39 +0200 Subject: [PATCH] SONAR-6879 Don't delete cache if update fails and change strategy --- .../cache/NonAssociatedCacheSynchronizer.java | 2 - .../batch/cache/ProjectCacheSynchronizer.java | 40 +++++++++++++--- .../cache/ProjectCacheSynchronizerTest.java | 48 +++++++++++++++++++ .../batch/mediumtest/cache/CacheSyncTest.java | 2 +- .../home/cache/PersistentCacheBuilder.java | 2 +- 5 files changed, 83 insertions(+), 11 deletions(-) diff --git a/sonar-batch/src/main/java/org/sonar/batch/cache/NonAssociatedCacheSynchronizer.java b/sonar-batch/src/main/java/org/sonar/batch/cache/NonAssociatedCacheSynchronizer.java index 2df946dc0ae..592ad0ed305 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/cache/NonAssociatedCacheSynchronizer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/cache/NonAssociatedCacheSynchronizer.java @@ -55,13 +55,11 @@ public class NonAssociatedCacheSynchronizer { } else { LOG.info("-- Found cache [{}], synchronizing data..", lastSync); } - cacheStatus.delete(); } else { LOG.info("-- Cache not found, synchronizing data.."); } loadData(); - cacheStatus.save(); LOG.info("-- Succesfully synchronized cache"); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheSynchronizer.java b/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheSynchronizer.java index fbba13fbbc8..c6366cfce6d 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheSynchronizer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheSynchronizer.java @@ -20,7 +20,6 @@ package org.sonar.batch.cache; import org.sonar.batch.repository.ProjectRepositoriesLoader; - import org.sonarqube.ws.QualityProfiles.WsSearchResponse.QualityProfile; import com.google.common.base.Function; import org.apache.commons.lang.StringUtils; @@ -36,6 +35,7 @@ import org.sonar.batch.repository.user.UserRepositoryLoader; import org.sonar.batch.rule.ActiveRulesLoader; import java.util.ArrayList; +import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.HashSet; @@ -63,22 +63,48 @@ public class ProjectCacheSynchronizer { this.cacheStatus = cacheStatus; } + private static boolean isToday(Date d) { + Calendar c1 = Calendar.getInstance(); + Calendar c2 = Calendar.getInstance(); + c2.setTime(d); + + return c1.get(Calendar.DAY_OF_YEAR) == c2.get(Calendar.DAY_OF_YEAR) && + c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR); + } + + private static boolean shouldUpdate(Date lastUpdate) { + return !isToday(lastUpdate); + } + public void load(String projectKey, boolean force) { Date lastSync = cacheStatus.getSyncStatus(); + boolean failOnError = true; if (lastSync != null) { - if (!force) { + if (force) { + LOG.info("-- Found project [{}] cache [{}], synchronizing data (forced)..", projectKey, lastSync); + } else if (shouldUpdate(lastSync)) { + LOG.info("-- Found project [{}] cache [{}], synchronizing data..", projectKey, lastSync); + failOnError = false; + } else { LOG.info("Found project [{}] cache [{}]", projectKey, lastSync); return; - } else { - LOG.info("-- Found project [{}] cache [{}], synchronizing data..", projectKey, lastSync); } - cacheStatus.delete(); } else { LOG.info("-- Cache for project [{}] not found, synchronizing data..", projectKey); } - loadData(projectKey); + try { + loadData(projectKey); + } catch (Exception e) { + if (failOnError) { + throw e; + } + + LOG.warn("-- Cache update for project [{}] failed, continuing from cache..", projectKey, e); + return; + } + saveStatus(); } @@ -121,7 +147,7 @@ public class ProjectCacheSynchronizer { issuesLoader.load(projectKey, consumer); profiler.stopInfo(); - profiler.startInfo("Load user information (" + consumer.loginSet.size() + " users)"); + profiler.startInfo("Load user information"); for (String login : consumer.loginSet) { userRepository.load(login, null); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/cache/ProjectCacheSynchronizerTest.java b/sonar-batch/src/test/java/org/sonar/batch/cache/ProjectCacheSynchronizerTest.java index 6098850be55..ebaa797cc43 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/cache/ProjectCacheSynchronizerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/cache/ProjectCacheSynchronizerTest.java @@ -147,4 +147,52 @@ public class ProjectCacheSynchronizerTest { verifyNoMoreInteractions(issuesLoader, userRepositoryLoader, qualityProfileLoader, activeRulesLoader, projectRepositoriesLoader); } + + @Test + public void testLastAnalysisToday() { + ProjectCacheSynchronizer synchronizer = createMockedLoaders(true, new Date()); + + when(cacheStatus.getSyncStatus()).thenReturn(new Date()); + synchronizer.load(PROJECT_KEY, false); + + verify(cacheStatus).getSyncStatus(); + verifyNoMoreInteractions(issuesLoader, userRepositoryLoader, qualityProfileLoader, activeRulesLoader, projectRepositoriesLoader, cacheStatus); + } + + @Test + public void testLastAnalysisYesterday() { + ProjectCacheSynchronizer synchronizer = createMockedLoaders(true, new Date()); + + Date d = new Date(new Date().getTime() - 60 * 60 * 24 * 1000); + when(cacheStatus.getSyncStatus()).thenReturn(d); + synchronizer.load(PROJECT_KEY, false); + + verify(cacheStatus).save(); + verify(cacheStatus).getSyncStatus(); + } + + @Test + public void testDontFailOnError() { + ProjectCacheSynchronizer synchronizer = createMockedLoaders(true, new Date()); + + Date d = new Date(new Date().getTime() - 60 * 60 * 24 * 1000); + when(cacheStatus.getSyncStatus()).thenReturn(d); + + when(projectRepositoriesLoader.load(anyString(), anyBoolean(), any(MutableBoolean.class))).thenThrow(IllegalStateException.class); + synchronizer.load(PROJECT_KEY, false); + + verify(cacheStatus).getSyncStatus(); + verifyNoMoreInteractions(cacheStatus); + } + + @Test + public void testForce() { + ProjectCacheSynchronizer synchronizer = createMockedLoaders(true, new Date()); + + when(cacheStatus.getSyncStatus()).thenReturn(new Date()); + synchronizer.load(PROJECT_KEY, true); + + verify(cacheStatus).save(); + verify(cacheStatus).getSyncStatus(); + } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/cache/CacheSyncTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/cache/CacheSyncTest.java index 41c5eda71cf..052e33a43e2 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/cache/CacheSyncTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/cache/CacheSyncTest.java @@ -119,7 +119,7 @@ public class CacheSyncTest { tester.syncProject("test-project"); assertThat(logOutput.getAsString()).contains("-- Found project [test-project]"); assertThat(logOutput.getAsString()).contains("not found, synchronizing data"); - assertThat(logOutput.getAsString()).contains("], synchronizing data.."); + assertThat(logOutput.getAsString()).contains("], synchronizing data (forced).."); } @Test diff --git a/sonar-home/src/main/java/org/sonar/home/cache/PersistentCacheBuilder.java b/sonar-home/src/main/java/org/sonar/home/cache/PersistentCacheBuilder.java index 152f17fc402..b58102cbf8c 100644 --- a/sonar-home/src/main/java/org/sonar/home/cache/PersistentCacheBuilder.java +++ b/sonar-home/src/main/java/org/sonar/home/cache/PersistentCacheBuilder.java @@ -37,7 +37,7 @@ import javax.annotation.Nullable; * */ public class PersistentCacheBuilder { - private static final long DEFAULT_EXPIRE_DURATION = TimeUnit.MILLISECONDS.convert(1L, TimeUnit.DAYS); + private static final long DEFAULT_EXPIRE_DURATION = TimeUnit.MILLISECONDS.convert(9999L, TimeUnit.DAYS); private static final String DIR_NAME = "ws_cache"; private Path cacheBasePath; -- 2.39.5