From: simonbrandhof Date: Mon, 27 Dec 2010 00:14:52 +0000 (+0000) Subject: Move timemachine components from core plugin to batch + do not depend on Snapshot... X-Git-Tag: 2.6~218 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=f86a62e3c24d2e2587b0f76988fbd9220ee4931a;p=sonarqube.git Move timemachine components from core plugin to batch + do not depend on Snapshot in PastSnapshotLoader components + fix NPE when calculating variations on measures that are still not persisted --- diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java index 5a16664dac2..8af552c5f52 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java @@ -119,7 +119,7 @@ import java.util.List; description = "Period used to compare measures and track new violations. Values are : ", project = false, global = true, - defaultValue = PastSnapshotFinder.DEFAULT_VALUE_1 + defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_1 ), @Property( key = "sonar.timemachine.period2", @@ -127,7 +127,7 @@ import java.util.List; description = "See the property 'Period 1'", project = false, global = true, - defaultValue = PastSnapshotFinder.DEFAULT_VALUE_2 + defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_2 ), @Property( key = "sonar.timemachine.period3", @@ -135,21 +135,23 @@ import java.util.List; description = "See the property 'Period 1'", project = false, global = true, - defaultValue = PastSnapshotFinder.DEFAULT_VALUE_3 + defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_3 ), @Property( key = "sonar.timemachine.period4", name = "Period 4", description = "Period used to compare measures and track new violations. This property is specific to the project. Values are : ", project = true, - global = false + global = false, + defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_4 ), @Property( key = "sonar.timemachine.period5", name = "Period 5", description = "See the property 'Period 4'", project = true, - global = false + global = false, + defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_5 ) }) public class CorePlugin implements Plugin { @@ -229,15 +231,7 @@ public class CorePlugin implements Plugin { // time machine extensions.add(TendencyDecorator.class); - extensions.add(PastSnapshotFinderByDate.class); - extensions.add(PastSnapshotFinderByDays.class); - extensions.add(PastSnapshotFinderByPreviousAnalysis.class); - extensions.add(PastSnapshotFinderByVersion.class); - extensions.add(PastMeasuresLoader.class); - extensions.add(PastSnapshotFinder.class); - extensions.add(TimeMachineConfiguration.class); extensions.add(VariationDecorator.class); - extensions.add(PastViolationsLoader.class); extensions.add(ViolationPersisterDecorator.class); extensions.add(NewViolationsDecorator.class); extensions.add(TimeMachineConfigurationPersister.class); diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java index c491feafdab..ec470304406 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java @@ -20,7 +20,6 @@ package org.sonar.plugins.core.timemachine; import com.google.common.collect.*; -import org.apache.commons.lang.time.DateUtils; import org.sonar.api.batch.Decorator; import org.sonar.api.batch.DecoratorContext; import org.sonar.api.batch.DependedUpon; @@ -32,6 +31,8 @@ import org.sonar.api.resources.ResourceUtils; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RulePriority; import org.sonar.api.rules.Violation; +import org.sonar.batch.components.PastSnapshot; +import org.sonar.batch.components.TimeMachineConfiguration; import java.util.*; diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastMeasuresLoader.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastMeasuresLoader.java deleted file mode 100644 index 7fc073956fc..00000000000 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastMeasuresLoader.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.timemachine; - -import com.google.common.collect.Maps; -import org.apache.commons.lang.ObjectUtils; -import org.sonar.api.BatchExtension; -import org.sonar.api.database.DatabaseSession; -import org.sonar.api.database.model.MeasureModel; -import org.sonar.api.database.model.Snapshot; -import org.sonar.api.measures.Metric; -import org.sonar.api.measures.MetricFinder; -import org.sonar.api.resources.Resource; - -import java.util.Collection; -import java.util.List; -import java.util.Map; - -public class PastMeasuresLoader implements BatchExtension { - - private Map metricByIds; - private DatabaseSession session; - - public PastMeasuresLoader(DatabaseSession session, MetricFinder metricFinder) { - this(session, metricFinder.findAll()); - } - - PastMeasuresLoader(DatabaseSession session, Collection metrics) { - this.session = session; - this.metricByIds = Maps.newHashMap(); - for (Metric metric : metrics) { - if (metric.isNumericType()) { - metricByIds.put(metric.getId(), metric); - } - } - } - - public Collection getMetrics() { - return metricByIds.values(); - } - - public List getPastMeasures(Resource resource, PastSnapshot projectPastSnapshot) { - return getPastMeasures(resource, projectPastSnapshot.getProjectSnapshot()); - } - - public List getPastMeasures(Resource resource, Snapshot projectSnapshot) { - // assume that the resource has already been saved - return getPastMeasures(resource.getId(), projectSnapshot); - } - - public List getPastMeasures(int resourceId, Snapshot projectSnapshot) { - // TODO improvement : select only some columns - // TODO support measure on characteristics - String hql = "select m from " + MeasureModel.class.getSimpleName() + " m, " + Snapshot.class.getSimpleName() + " s " + - "where m.snapshotId=s.id and m.metricId in (:metricIds) and m.ruleId=null and m.rulePriority=null and m.characteristic=null " - + "and (s.rootId=:rootSnapshotId or s.id=:rootSnapshotId) and s.resourceId=:resourceId and s.status=:status"; - return session.createQuery(hql) - .setParameter("metricIds", metricByIds.keySet()) - .setParameter("rootSnapshotId", ObjectUtils.defaultIfNull(projectSnapshot.getRootId(), projectSnapshot.getId())) - .setParameter("resourceId", resourceId) - .setParameter("status", Snapshot.STATUS_PROCESSED) - .getResultList(); - } -} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshot.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshot.java deleted file mode 100644 index 6909cf29e5a..00000000000 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshot.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.timemachine; - -import org.apache.commons.lang.builder.ReflectionToStringBuilder; -import org.sonar.api.database.model.Snapshot; - -import java.util.Date; - -public class PastSnapshot { - - private int index; - private String mode, modeParameter; - private Snapshot projectSnapshot; - private Date targetDate; - - public PastSnapshot(String mode, Date targetDate, Snapshot projectSnapshot) { - this.mode = mode; - this.targetDate = targetDate; - this.projectSnapshot = projectSnapshot; - } - - public PastSnapshot(String mode, Snapshot projectSnapshot) { - this.mode = mode; - this.projectSnapshot = projectSnapshot; - } - - public PastSnapshot setIndex(int index) { - this.index = index; - return this; - } - - public int getIndex() { - return index; - } - - public Snapshot getProjectSnapshot() { - return projectSnapshot; - } - - public Date getDate() { - return projectSnapshot.getCreatedAt(); - } - - public String getMode() { - return mode; - } - - public String getModeParameter() { - return modeParameter; - } - - public PastSnapshot setModeParameter(String s) { - this.modeParameter = s; - return this; - } - - public Integer getProjectSnapshotId() { - return (projectSnapshot!=null ? projectSnapshot.getId() : null); - } - - public Date getTargetDate() { - return targetDate; - } - - public PastSnapshot setTargetDate(Date d) { - this.targetDate = d; - return this; - } - - @Override - public String toString() { - return ReflectionToStringBuilder.toString(this); - } -} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshotFinder.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshotFinder.java deleted file mode 100644 index bf7d8ba5d9f..00000000000 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshotFinder.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.timemachine; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.lang.StringUtils; -import org.sonar.api.BatchExtension; -import org.sonar.api.utils.Logs; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; - -public class PastSnapshotFinder implements BatchExtension { - - /** - * IMPORTANT : please update default values in the ruby side too. See app/helpers/FiltersHelper.rb, method period_names() - */ - public static final String DEFAULT_VALUE_1 = PastSnapshotFinderByPreviousAnalysis.MODE; - public static final String DEFAULT_VALUE_2 = "5"; - public static final String DEFAULT_VALUE_3 = "30"; - public static final String PROPERTY_PREFIX = "sonar.timemachine.period"; - - private PastSnapshotFinderByDays finderByDays; - private PastSnapshotFinderByVersion finderByVersion; - private PastSnapshotFinderByDate finderByDate; - private PastSnapshotFinderByPreviousAnalysis finderByPreviousAnalysis; - - public PastSnapshotFinder(PastSnapshotFinderByDays finderByDays, PastSnapshotFinderByVersion finderByVersion, - PastSnapshotFinderByDate finderByDate, PastSnapshotFinderByPreviousAnalysis finderByPreviousAnalysis) { - this.finderByDays = finderByDays; - this.finderByVersion = finderByVersion; - this.finderByDate = finderByDate; - this.finderByPreviousAnalysis = finderByPreviousAnalysis; - } - - public PastSnapshot find(Configuration conf, int index) { - String propertyValue = getPropertyValue(conf, index); - PastSnapshot pastSnapshot = find(index, propertyValue); - if (pastSnapshot==null && StringUtils.isNotBlank(propertyValue)) { - Logs.INFO.warn("The property " + PROPERTY_PREFIX + index + " has an unvalid value: " + propertyValue); - } - return pastSnapshot; - } - - static String getPropertyValue(Configuration conf, int index) { - String defaultValue = null; - switch (index) { - // only global settings (from 1 to 3) have default values - case 1: defaultValue = DEFAULT_VALUE_1; break; - case 2: defaultValue = DEFAULT_VALUE_2; break; - case 3: defaultValue = DEFAULT_VALUE_3; break; - } - return conf.getString(PROPERTY_PREFIX + index, defaultValue); - } - - public PastSnapshot find(int index, String property) { - if (StringUtils.isBlank(property)) { - return null; - } - - PastSnapshot result = findByDays(property); - if (result == null) { - result = findByDate(property); - if (result == null) { - result = findByPreviousAnalysis(property); - if (result == null) { - result = findByVersion(property); - } - } - } - - if (result != null) { - result.setIndex(index); - } - - return result; - } - - private PastSnapshot findByPreviousAnalysis(String property) { - PastSnapshot pastSnapshot = null; - if (StringUtils.equals(PastSnapshotFinderByPreviousAnalysis.MODE, property)) { - pastSnapshot = finderByPreviousAnalysis.findByPreviousAnalysis(); - } - return pastSnapshot; - } - - private PastSnapshot findByDate(String property) { - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - Date date = format.parse(property); - return finderByDate.findByDate(date); - - } catch (ParseException e) { - return null; - } - } - - private PastSnapshot findByVersion(String property) { - return finderByVersion.findByVersion(property); - } - - private PastSnapshot findByDays(String property) { - try { - int days = Integer.parseInt(property); - return finderByDays.findFromDays(days); - - } catch (NumberFormatException e) { - return null; - } - } - -} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDate.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDate.java deleted file mode 100644 index d33ead7c16b..00000000000 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDate.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.timemachine; - -import org.sonar.api.BatchExtension; -import org.sonar.api.database.DatabaseSession; -import org.sonar.api.database.model.Snapshot; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.List; - -public class PastSnapshotFinderByDate implements BatchExtension{ - - public static final String MODE = "date"; - - - private Snapshot projectSnapshot; // TODO replace by PersistenceManager - private DatabaseSession session; - - public PastSnapshotFinderByDate(Snapshot projectSnapshot, DatabaseSession session) { - this.projectSnapshot = projectSnapshot; - this.session = session; - } - - PastSnapshot findByDate(Date date) { - String hql = "from " + Snapshot.class.getSimpleName() + " where createdAt>=:date AND resourceId=:resourceId AND status=:status order by createdAt asc"; - List snapshots = session.createQuery(hql) - .setParameter("date", date) - .setParameter("resourceId", projectSnapshot.getResourceId()) - .setParameter("status", Snapshot.STATUS_PROCESSED) - .setMaxResults(1) - .getResultList(); - if (snapshots.isEmpty()) { - return null; - } - - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - return new PastSnapshot(MODE, date, snapshots.get(0)).setModeParameter(format.format(date)); - } - -} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDays.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDays.java deleted file mode 100644 index 8daea1a6bd1..00000000000 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDays.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.timemachine; - -import org.apache.commons.lang.time.DateUtils; -import org.sonar.api.BatchExtension; -import org.sonar.api.database.DatabaseSession; -import org.sonar.api.database.model.Snapshot; - -import java.util.Date; -import java.util.List; - -public class PastSnapshotFinderByDays implements BatchExtension { - - public static final String MODE = "days"; - - - private Snapshot projectSnapshot; // TODO replace by PersistenceManager - private DatabaseSession session; - - public PastSnapshotFinderByDays(Snapshot projectSnapshot, DatabaseSession session) { - this.projectSnapshot = projectSnapshot; - this.session = session; - } - - PastSnapshot findFromDays(int days) { - Date targetDate = DateUtils.addDays(projectSnapshot.getCreatedAt(), -days); - String hql = "from " + Snapshot.class.getSimpleName() + " where resourceId=:resourceId AND status=:status AND createdAt>=:from AND createdAt<:to order by createdAt asc"; - List snapshots = session.createQuery(hql) - .setParameter("from", targetDate) - .setParameter("to", projectSnapshot.getCreatedAt()) - .setParameter("resourceId", projectSnapshot.getResourceId()) - .setParameter("status", Snapshot.STATUS_PROCESSED) - .setMaxResults(1) - .getResultList(); - - if (snapshots.isEmpty()) { - return null; - } - return new PastSnapshot(MODE, targetDate, snapshots.get(0)).setModeParameter(String.valueOf(days)); - } -} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByPreviousAnalysis.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByPreviousAnalysis.java deleted file mode 100644 index e8c0432fd67..00000000000 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByPreviousAnalysis.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.timemachine; - -import org.sonar.api.BatchExtension; -import org.sonar.api.database.DatabaseSession; -import org.sonar.api.database.model.Snapshot; - -import java.text.SimpleDateFormat; -import java.util.List; - -public class PastSnapshotFinderByPreviousAnalysis implements BatchExtension { - public static final String MODE = "previous_analysis"; - - private Snapshot projectSnapshot; // TODO replace by PersistenceManager - private DatabaseSession session; - - public PastSnapshotFinderByPreviousAnalysis(Snapshot projectSnapshot, DatabaseSession session) { - this.projectSnapshot = projectSnapshot; - this.session = session; - } - - PastSnapshot findByPreviousAnalysis() { - String hql = "from " + Snapshot.class.getSimpleName() + " where createdAt<:date AND resourceId=:resourceId AND status=:status and last=true order by createdAt desc"; - List snapshots = session.createQuery(hql) - .setParameter("date", projectSnapshot.getCreatedAt()) - .setParameter("resourceId", projectSnapshot.getResourceId()) - .setParameter("status", Snapshot.STATUS_PROCESSED) - .setMaxResults(1) - .getResultList(); - - if (snapshots.isEmpty()) { - return null; - } - Snapshot snapshot = snapshots.get(0); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - return new PastSnapshot(MODE, snapshot.getCreatedAt(), snapshot).setModeParameter(format.format(snapshot.getCreatedAt())); - } - -} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByVersion.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByVersion.java deleted file mode 100644 index bba16f91fad..00000000000 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByVersion.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.timemachine; - -import org.sonar.api.BatchExtension; -import org.sonar.api.database.DatabaseSession; -import org.sonar.api.database.model.Snapshot; - -import java.util.List; - -public class PastSnapshotFinderByVersion implements BatchExtension { - - public static final String MODE = "version"; - - private Snapshot projectSnapshot; // TODO replace by PersistenceManager - private DatabaseSession session; - - public PastSnapshotFinderByVersion(Snapshot projectSnapshot, DatabaseSession session) { - this.projectSnapshot = projectSnapshot; - this.session = session; - } - - PastSnapshot findByVersion(String version) { - String hql = "from " + Snapshot.class.getSimpleName() + " where version=:version AND resourceId=:resourceId AND status=:status order by createdAt desc"; - List snapshots = session.createQuery(hql) - .setParameter("version", version) - .setParameter("resourceId", projectSnapshot.getResourceId()) - .setParameter("status", Snapshot.STATUS_PROCESSED) - .setMaxResults(1) - .getResultList(); - - if (snapshots.isEmpty()) { - return null; - } - Snapshot snapshot = snapshots.get(0); - return new PastSnapshot(MODE, snapshot.getCreatedAt(), snapshot).setModeParameter(snapshot.getVersion()); - } - -} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastViolationsLoader.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastViolationsLoader.java deleted file mode 100644 index d8b064fbee0..00000000000 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastViolationsLoader.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.sonar.plugins.core.timemachine; - -import org.sonar.api.BatchExtension; -import org.sonar.api.database.DatabaseSession; -import org.sonar.api.database.model.RuleFailureModel; -import org.sonar.api.database.model.Snapshot; -import org.sonar.api.database.model.SnapshotSource; -import org.sonar.api.resources.Resource; -import org.sonar.api.utils.SonarException; -import org.sonar.batch.index.ResourcePersister; - -import java.util.Collections; -import java.util.List; - -public class PastViolationsLoader implements BatchExtension { - - private DatabaseSession session; - private ResourcePersister resourcePersister; - - public PastViolationsLoader(DatabaseSession session, ResourcePersister resourcePersister) { - this.session = session; - this.resourcePersister = resourcePersister; - } - - public List getPastViolations(Resource resource) { - if (resource == null) { - return Collections.emptyList(); - } - - Snapshot snapshot = resourcePersister.getSnapshot(resource); - if (snapshot == null) { - throw new SonarException("This resource has no snapshot ???" + resource); - } - Snapshot previousLastSnapshot = resourcePersister.getLastSnapshot(snapshot, true); - if (previousLastSnapshot == null) { - return Collections.emptyList(); - } - return session.getResults(RuleFailureModel.class, - "snapshotId", previousLastSnapshot.getId()); - } - - public SnapshotSource getSource(Resource resource) { - Snapshot snapshot = resourcePersister.getSnapshot(resource); - return session.getSingleResult(SnapshotSource.class, - "snapshotId", snapshot.getId()); - } - -} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TendencyDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TendencyDecorator.java index d92ba8f1376..836d23613e8 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TendencyDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TendencyDecorator.java @@ -30,6 +30,7 @@ import org.sonar.api.measures.MetricFinder; import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; import org.sonar.api.resources.ResourceUtils; +import org.sonar.batch.components.TimeMachineConfiguration; import java.util.List; diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfiguration.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfiguration.java deleted file mode 100644 index 1658381f0d4..00000000000 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfiguration.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.timemachine; - -import com.google.common.collect.Lists; -import org.apache.commons.configuration.Configuration; -import org.sonar.api.BatchExtension; -import org.sonar.api.CoreProperties; -import org.sonar.api.utils.Logs; - -import java.util.Collections; -import java.util.List; - -public class TimeMachineConfiguration implements BatchExtension { - - private static final int NUMBER_OF_VARIATION_SNAPSHOTS = 5; - - private final Configuration configuration; - private List projectPastSnapshots; - - public TimeMachineConfiguration(Configuration configuration, PastSnapshotFinder variationSnapshotFinder) { - this.configuration = configuration; - initVariationSnapshots(variationSnapshotFinder); - } - - private void initVariationSnapshots(PastSnapshotFinder variationSnapshotFinder) { - projectPastSnapshots = Lists.newLinkedList(); - for (int index = 1; index <= NUMBER_OF_VARIATION_SNAPSHOTS; index++) { - PastSnapshot variationSnapshot = variationSnapshotFinder.find(configuration, index); - if (variationSnapshot != null) { - Logs.INFO.info("Comparison date: " + variationSnapshot.getDate()); - projectPastSnapshots.add(variationSnapshot); - } - } - } - - - /** - * for unit tests - */ - TimeMachineConfiguration(Configuration configuration) { - this.configuration = configuration; - this.projectPastSnapshots = Collections.emptyList(); - } - - - public boolean skipTendencies() { - return configuration.getBoolean(CoreProperties.SKIP_TENDENCIES_PROPERTY, CoreProperties.SKIP_TENDENCIES_DEFAULT_VALUE); - } - - public int getTendencyPeriodInDays() { - return configuration.getInt(CoreProperties.CORE_TENDENCY_DEPTH_PROPERTY, CoreProperties.CORE_TENDENCY_DEPTH_DEFAULT_VALUE); - } - - public List getProjectPastSnapshots() { - return projectPastSnapshots; - } -} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersister.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersister.java index 90eb28b2710..4e1bba5d7c3 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersister.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersister.java @@ -22,6 +22,8 @@ package org.sonar.plugins.core.timemachine; import org.sonar.api.BatchExtension; import org.sonar.api.database.DatabaseSession; import org.sonar.api.database.model.Snapshot; +import org.sonar.batch.components.PastSnapshot; +import org.sonar.batch.components.TimeMachineConfiguration; import java.util.List; diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java index 4672fdbc10f..4e6ddddf74e 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java @@ -22,15 +22,15 @@ package org.sonar.plugins.core.timemachine; import com.google.common.collect.Maps; import org.sonar.api.batch.*; import org.sonar.api.database.model.MeasureModel; -import org.sonar.api.measures.Measure; -import org.sonar.api.measures.MeasuresFilters; -import org.sonar.api.measures.Metric; -import org.sonar.api.measures.RuleMeasure; +import org.sonar.api.measures.*; import org.sonar.api.qualitymodel.Characteristic; import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; import org.sonar.api.resources.ResourceUtils; import org.sonar.api.rules.RulePriority; +import org.sonar.batch.components.PastMeasuresLoader; +import org.sonar.batch.components.PastSnapshot; +import org.sonar.batch.components.TimeMachineConfiguration; import java.util.Collection; import java.util.List; @@ -41,14 +41,17 @@ public class VariationDecorator implements Decorator { private List projectPastSnapshots; private PastMeasuresLoader pastMeasuresLoader; + private MetricFinder metricFinder; + + public VariationDecorator(PastMeasuresLoader pastMeasuresLoader, MetricFinder metricFinder, TimeMachineConfiguration configuration) { + this(pastMeasuresLoader, metricFinder, configuration.getProjectPastSnapshots()); - public VariationDecorator(PastMeasuresLoader pastMeasuresLoader, TimeMachineConfiguration configuration) { - this(pastMeasuresLoader, configuration.getProjectPastSnapshots()); } - VariationDecorator(PastMeasuresLoader pastMeasuresLoader, List projectPastSnapshots) { + VariationDecorator(PastMeasuresLoader pastMeasuresLoader, MetricFinder metricFinder, List projectPastSnapshots) { this.pastMeasuresLoader = pastMeasuresLoader; this.projectPastSnapshots = projectPastSnapshots; + this.metricFinder = metricFinder; } public boolean shouldExecuteOnProject(Project project) { @@ -87,7 +90,8 @@ public class VariationDecorator implements Decorator { // for each measure, search equivalent past measure for (Measure measure : context.getMeasures(MeasuresFilters.all())) { // compare with past measure - MeasureModel pastMeasure = pastMeasuresByKey.get(new MeasureKey(measure)); + Integer metricId = (measure.getMetric().getId()!=null ? measure.getMetric().getId() : metricFinder.findByKey(measure.getMetric().getKey()).getId()); + MeasureModel pastMeasure = pastMeasuresByKey.get(new MeasureKey(measure, metricId)); if (updateVariation(measure, pastMeasure, index)) { context.saveMeasure(measure); } @@ -121,14 +125,14 @@ public class VariationDecorator implements Decorator { characteristic = model.getCharacteristic(); } - MeasureKey(Measure measure) { - metricId = measure.getMetric().getId(); - characteristic = measure.getCharacteristic(); + MeasureKey(Measure measure, Integer metricId) { + this.metricId = metricId; + this.characteristic = measure.getCharacteristic(); // TODO merge RuleMeasure into Measure if (measure instanceof RuleMeasure) { RuleMeasure rm = (RuleMeasure) measure; - ruleId = (rm.getRule() == null ? null : rm.getRule().getId()); - priority = rm.getRulePriority(); + this.ruleId = (rm.getRule() == null ? null : rm.getRule().getId()); + this.priority = rm.getRulePriority(); } } diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/ViolationPersisterDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/ViolationPersisterDecorator.java index 5290bd6b02f..9d90f3e81b2 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/ViolationPersisterDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/ViolationPersisterDecorator.java @@ -20,6 +20,7 @@ import org.sonar.api.rules.Rule; import org.sonar.api.rules.RuleFinder; import org.sonar.api.rules.Violation; import org.sonar.api.utils.SonarException; +import org.sonar.batch.components.PastViolationsLoader; import org.sonar.batch.index.ViolationPersister; import java.io.IOException; diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java index 0ac22acda20..8170bb55dfe 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java @@ -36,8 +36,9 @@ import org.sonar.api.resources.Resource; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RulePriority; import org.sonar.api.rules.Violation; +import org.sonar.batch.components.PastSnapshot; +import org.sonar.batch.components.TimeMachineConfiguration; -import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastMeasuresLoaderTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastMeasuresLoaderTest.java deleted file mode 100644 index 73959db7844..00000000000 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastMeasuresLoaderTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.timemachine; - -import org.junit.Test; -import org.sonar.api.database.model.MeasureModel; -import org.sonar.api.database.model.Snapshot; -import org.sonar.api.measures.Metric; -import org.sonar.jpa.test.AbstractDbUnitTestCase; - -import java.util.Arrays; -import java.util.List; - -import static org.hamcrest.CoreMatchers.anyOf; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.internal.matchers.IsCollectionContaining.hasItems; - -public class PastMeasuresLoaderTest extends AbstractDbUnitTestCase { - - private static final int PROJECT_SNAPSHOT_ID = 1000; - private static final int PROJECT_ID = 1; - private static final int FILE_ID = 3; - - @Test - public void shouldGetPastResourceMeasures() { - setupData("shared"); - - List metrics = selectMetrics(); - Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID); - - PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics); - List measures = loader.getPastMeasures(FILE_ID, projectSnapshot); - assertThat(measures.size(), is(2)); - - for (MeasureModel measure : measures) { - assertThat(measure.getId(), anyOf(is(5L), is(6L))); - assertThat(measure.getValue(), anyOf(is(5.0), is(60.0))); - } - } - - @Test - public void shouldGetPastProjectMeasures() { - setupData("shared"); - - List metrics = selectMetrics(); - Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID); - - PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics); - List measures = loader.getPastMeasures(PROJECT_ID, projectSnapshot); - assertThat(measures.size(), is(2)); - - for (MeasureModel measure : measures) { - assertThat(measure.getId(), anyOf(is(1L), is(2L))); - assertThat(measure.getValue(), anyOf(is(60.0), is(80.0))); - } - } - - @Test - public void shouldKeepOnlyNumericalMetrics() { - Metric ncloc = new Metric("ncloc", Metric.ValueType.INT); - ncloc.setId(1); - Metric complexity = new Metric("complexity", Metric.ValueType.INT); - complexity.setId(2); - Metric data = new Metric("data", Metric.ValueType.DATA); - data.setId(3); - List metrics = Arrays.asList(ncloc, complexity, data); - - PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics); - - assertThat(loader.getMetrics().size(), is(2)); - assertThat(loader.getMetrics(), hasItems(ncloc, complexity)); - } - - private List selectMetrics() { - return getSession().getResults(Metric.class); - } -} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDateTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDateTest.java deleted file mode 100644 index 5ee48a6595d..00000000000 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDateTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.timemachine; - -import org.junit.Test; -import org.sonar.api.database.model.Snapshot; -import org.sonar.jpa.test.AbstractDbUnitTestCase; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -public class PastSnapshotFinderByDateTest extends AbstractDbUnitTestCase { - public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); - - @Test - public void shouldFindDate() throws ParseException { - setupData("shared"); - - Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); - PastSnapshotFinderByDate finder = new PastSnapshotFinderByDate(projectSnapshot, getSession()); - - Date date = DATE_FORMAT.parse("2008-11-22"); - - PastSnapshot pastSnapshot = finder.findByDate(date); - assertThat(pastSnapshot.getProjectSnapshotId(), is(1006)); - } - - @Test - public void shouldFindNearestLaterDate() throws ParseException { - setupData("shared"); - - Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); - PastSnapshotFinderByDate finder = new PastSnapshotFinderByDate(projectSnapshot, getSession()); - - Date date = DATE_FORMAT.parse("2008-11-24"); - - PastSnapshot pastSnapshot = finder.findByDate(date); - assertThat(pastSnapshot.getProjectSnapshotId(), is(1009)); - } -} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDaysTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDaysTest.java deleted file mode 100644 index 226010b327b..00000000000 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDaysTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.timemachine; - -import org.hamcrest.core.IsNull; -import org.junit.Test; -import org.sonar.api.database.model.Snapshot; -import org.sonar.jpa.test.AbstractDbUnitTestCase; - -import java.text.ParseException; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertThat; - -public class PastSnapshotFinderByDaysTest extends AbstractDbUnitTestCase { - - @Test - public void shouldGetNextSnapshot() throws ParseException { - setupData("shared"); - - Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1009); // 2008-11-16 - PastSnapshotFinderByDays finder = new PastSnapshotFinderByDays(projectSnapshot, getSession()); - - assertThat(finder.findFromDays(50).getProjectSnapshotId(), is(1000)); - } - - @Test - public void shouldIgnoreUnprocessedSnapshots() throws ParseException { - setupData("shared"); - - Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1009); // 2008-11-16 - PastSnapshotFinderByDays finder = new PastSnapshotFinderByDays(projectSnapshot, getSession()); - - assertThat(finder.findFromDays(7).getProjectSnapshotId(), is(1006)); - } - - @Test - public void shouldNotFindSelf() throws ParseException { - setupData("shared"); - - Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1009); // 2008-11-16 - PastSnapshotFinderByDays finder = new PastSnapshotFinderByDays(projectSnapshot, getSession()); - - assertThat(finder.findFromDays(1), nullValue()); - } - -} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByPreviousAnalysisTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByPreviousAnalysisTest.java deleted file mode 100644 index 992ebc37aa6..00000000000 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByPreviousAnalysisTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.timemachine; - -import org.junit.Test; -import org.sonar.api.database.model.Snapshot; -import org.sonar.jpa.test.AbstractDbUnitTestCase; - -import java.text.ParseException; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; - -public class PastSnapshotFinderByPreviousAnalysisTest extends AbstractDbUnitTestCase { - - @Test - public void shouldFindPreviousAnalysis() throws ParseException { - setupData("shouldFindPreviousAnalysis"); - - Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); - PastSnapshotFinderByPreviousAnalysis finder = new PastSnapshotFinderByPreviousAnalysis(projectSnapshot, getSession()); - - PastSnapshot pastSnapshot = finder.findByPreviousAnalysis(); - assertThat(pastSnapshot.getProjectSnapshotId(), is(1009)); - } - - @Test - public void shouldNotFindPreviousAnalysis() throws ParseException { - setupData("shouldNotFindPreviousAnalysis"); - - Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); - PastSnapshotFinderByPreviousAnalysis finder = new PastSnapshotFinderByPreviousAnalysis(projectSnapshot, getSession()); - - assertNull(finder.findByPreviousAnalysis()); - } -} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByVersionTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByVersionTest.java deleted file mode 100644 index c051c5d4dae..00000000000 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderByVersionTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.timemachine; - -import org.junit.Test; -import org.sonar.api.database.model.Snapshot; -import org.sonar.jpa.test.AbstractDbUnitTestCase; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.core.IsNull.nullValue; -import static org.junit.Assert.assertThat; - -public class PastSnapshotFinderByVersionTest extends AbstractDbUnitTestCase { - - @Test - public void shouldFindByVersion() { - setupData("shared"); - - Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); - PastSnapshotFinderByVersion finder = new PastSnapshotFinderByVersion(currentProjectSnapshot, getSession()); - - assertThat(finder.findByVersion("1.1").getProjectSnapshotId(), is(1009)); - } - - @Test - public void shouldNotFindVersion() { - setupData("shared"); - - Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); - PastSnapshotFinderByVersion finder = new PastSnapshotFinderByVersion(currentProjectSnapshot, getSession()); - - assertThat(finder.findByVersion("1.0"), nullValue()); - } -} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderTest.java deleted file mode 100644 index 127933294d9..00000000000 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastSnapshotFinderTest.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * Sonar is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * Sonar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.plugins.core.timemachine; - -import org.apache.commons.configuration.PropertiesConfiguration; -import org.hamcrest.BaseMatcher; -import org.hamcrest.Description; -import org.junit.Before; -import org.junit.Test; -import org.sonar.api.database.model.Snapshot; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; - -import static junit.framework.Assert.assertNull; -import static org.hamcrest.Matchers.nullValue; -import static org.hamcrest.core.Is.is; -import static org.hamcrest.core.IsNot.not; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.*; - -public class PastSnapshotFinderTest { - - private PastSnapshotFinderByDays finderByDays; - private PastSnapshotFinderByDate finderByDate; - private PastSnapshotFinderByVersion finderByVersion; - private PastSnapshotFinderByPreviousAnalysis finderByPreviousAnalysis; - private PastSnapshotFinder finder; - - @Before - public void initFinders() { - finderByDays = mock(PastSnapshotFinderByDays.class); - finderByDate = mock(PastSnapshotFinderByDate.class); - finderByVersion = mock(PastSnapshotFinderByVersion.class); - finderByPreviousAnalysis = mock(PastSnapshotFinderByPreviousAnalysis.class); - finder = new PastSnapshotFinder(finderByDays, finderByVersion, finderByDate, finderByPreviousAnalysis); - } - - @Test - public void shouldFindByNumberOfDays() { - when(finderByDays.findFromDays(30)).thenReturn(new PastSnapshot("days", null).setModeParameter("30")); - - PastSnapshot variationSnapshot = finder.find(1, "30"); - - verify(finderByDays).findFromDays(30); - assertNotNull(variationSnapshot); - assertThat(variationSnapshot.getIndex(), is(1)); - assertThat(variationSnapshot.getMode(), is("days")); - assertThat(variationSnapshot.getModeParameter(), is("30")); - } - - @Test - public void shouldNotFindByNumberOfDays() { - PastSnapshot variationSnapshot = finder.find(1, "30"); - - verify(finderByDays).findFromDays(30); - assertNull(variationSnapshot); - } - - @Test - public void shouldFindByDate() throws ParseException { - final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - final Date date = format.parse("2010-05-18"); - when(finderByDate.findByDate(date)).thenReturn(new PastSnapshot("date", new Snapshot())); - - PastSnapshot variationSnapshot = finder.find(2, "2010-05-18"); - - verify(finderByDate).findByDate(argThat(new BaseMatcher() { - public boolean matches(Object o) { - return o.equals(date); - } - - public void describeTo(Description description) { - - } - })); - assertThat(variationSnapshot.getIndex(), is(2)); - assertThat(variationSnapshot.getMode(), is("date")); - assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue())); - } - - @Test - public void shouldNotFindByDate() throws ParseException { - when(finderByDate.findByDate((Date) anyObject())).thenReturn(null); - - PastSnapshot variationSnapshot = finder.find(2, "2010-05-18"); - - verify(finderByDate).findByDate((Date) anyObject()); - assertNull(variationSnapshot); - } - - @Test - public void shouldFindByPreviousAnalysis() throws ParseException { - final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - final Date date = format.parse("2010-05-18"); - Snapshot snapshot = new Snapshot(); - snapshot.setCreatedAt(date); - when(finderByPreviousAnalysis.findByPreviousAnalysis()).thenReturn(new PastSnapshot(PastSnapshotFinderByPreviousAnalysis.MODE, snapshot)); - - PastSnapshot variationSnapshot = finder.find(2, PastSnapshotFinderByPreviousAnalysis.MODE); - - verify(finderByPreviousAnalysis).findByPreviousAnalysis(); - assertThat(variationSnapshot.getIndex(), is(2)); - assertThat(variationSnapshot.getMode(), is(PastSnapshotFinderByPreviousAnalysis.MODE)); - assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue())); - } - - @Test - public void shouldNotFindPreviousAnalysis() { - when(finderByPreviousAnalysis.findByPreviousAnalysis()).thenReturn(null); - - PastSnapshot variationSnapshot = finder.find(2, PastSnapshotFinderByPreviousAnalysis.MODE); - - verify(finderByPreviousAnalysis).findByPreviousAnalysis(); - - assertNull(variationSnapshot); - } - - @Test - public void shouldFindByVersion() { - when(finderByVersion.findByVersion("1.2")).thenReturn(new PastSnapshot("version", new Snapshot())); - - PastSnapshot variationSnapshot = finder.find(2, "1.2"); - - verify(finderByVersion).findByVersion("1.2"); - assertThat(variationSnapshot.getIndex(), is(2)); - assertThat(variationSnapshot.getMode(), is("version")); - assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue())); - } - - @Test - public void shouldNotFindVersion() { - when(finderByVersion.findByVersion("1.2")).thenReturn(null); - - PastSnapshot variationSnapshot = finder.find(2, "1.2"); - - verify(finderByVersion).findByVersion("1.2"); - assertNull(variationSnapshot); - } - - @Test - public void shouldNotFailIfUnknownFormat() { - when(finderByPreviousAnalysis.findByPreviousAnalysis()).thenReturn(new PastSnapshot(PastSnapshotFinderByPreviousAnalysis.MODE, new Snapshot())); // should not be called - assertNull(finder.find(2, "foooo")); - } - - @Test - public void shouldGetPropertyValue() { - PropertiesConfiguration conf = new PropertiesConfiguration(); - conf.setProperty("sonar.timemachine.period1", "5"); - - assertThat(PastSnapshotFinder.getPropertyValue(conf, 1), is("5")); - assertThat(PastSnapshotFinder.getPropertyValue(conf, 999), nullValue()); - } - - @Test - public void shouldGetDefaultPropertyValue() { - PropertiesConfiguration conf = new PropertiesConfiguration(); - conf.setProperty("sonar.timemachine.period1", "5"); - - assertThat(PastSnapshotFinder.getPropertyValue(conf, 2), is(PastSnapshotFinder.DEFAULT_VALUE_2)); - } -} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastViolationsLoaderTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastViolationsLoaderTest.java deleted file mode 100644 index 341b5107c4c..00000000000 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastViolationsLoaderTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.sonar.plugins.core.timemachine; - -import org.junit.Before; -import org.junit.Test; -import org.sonar.api.database.model.RuleFailureModel; -import org.sonar.api.database.model.Snapshot; -import org.sonar.api.resources.JavaFile; -import org.sonar.api.resources.Resource; -import org.sonar.batch.index.ResourcePersister; -import org.sonar.jpa.test.AbstractDbUnitTestCase; - -import java.util.List; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.notNullValue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -public class PastViolationsLoaderTest extends AbstractDbUnitTestCase { - - private ResourcePersister resourcePersister; - private PastViolationsLoader loader; - - @Before - public void setUp() { - setupData("shared"); - resourcePersister = mock(ResourcePersister.class); - loader = new PastViolationsLoader(getSession(), resourcePersister); - } - - @Test - public void shouldGetPastResourceViolations() { - Snapshot snapshot = getSession().getSingleResult(Snapshot.class, "id", 1000); - doReturn(snapshot).when(resourcePersister) - .getSnapshot(any(Resource.class)); - doReturn(snapshot).when(resourcePersister) - .getLastSnapshot(any(Snapshot.class), anyBoolean()); - - List violations = loader.getPastViolations(new JavaFile("file")); - - assertThat(violations.size(), is(2)); - } - - @Test - public void shouldReturnEmptyList() { - List violations = loader.getPastViolations(null); - - assertThat(violations, notNullValue()); - assertThat(violations.size(), is(0)); - } - -} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TendencyDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TendencyDecoratorTest.java index 05aea8b53fb..ddf68f6d428 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TendencyDecoratorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TendencyDecoratorTest.java @@ -29,6 +29,7 @@ import org.sonar.api.measures.Measure; import org.sonar.api.measures.MetricFinder; import org.sonar.api.resources.JavaPackage; import org.sonar.api.resources.Project; +import org.sonar.batch.components.TimeMachineConfiguration; import java.text.ParseException; import java.text.SimpleDateFormat; diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersisterTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersisterTest.java index 9f1900b8fb8..6c0477004f5 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersisterTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersisterTest.java @@ -21,6 +21,8 @@ package org.sonar.plugins.core.timemachine; import org.junit.Test; import org.sonar.api.database.model.Snapshot; +import org.sonar.batch.components.PastSnapshot; +import org.sonar.batch.components.TimeMachineConfiguration; import org.sonar.jpa.test.AbstractDbUnitTestCase; import java.text.ParseException; diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationTest.java index f9cbfc6cf60..4a834d65796 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationTest.java @@ -23,6 +23,9 @@ import org.apache.commons.configuration.PropertiesConfiguration; import org.junit.Test; import org.sonar.api.CoreProperties; import org.sonar.api.database.model.Snapshot; +import org.sonar.batch.components.PastSnapshot; +import org.sonar.batch.components.PastSnapshotFinder; +import org.sonar.batch.components.TimeMachineConfiguration; import org.sonar.jpa.test.AbstractDbUnitTestCase; import java.text.ParseException; @@ -49,17 +52,17 @@ public class TimeMachineConfigurationTest extends AbstractDbUnitTestCase { } @Test - public void shouldInitVariationSnapshots() throws ParseException { + public void shouldInitPastSnapshots() throws ParseException { PropertiesConfiguration conf = new PropertiesConfiguration(); - PastSnapshotFinder snapshotReferenceFinder = mock(PastSnapshotFinder.class); - when(snapshotReferenceFinder.find(conf, 1)).thenReturn(new PastSnapshot("days", null, newSnapshot("2010-10-15"))); - when(snapshotReferenceFinder.find(conf, 3)).thenReturn(new PastSnapshot("days", null, newSnapshot("2010-10-13"))); + PastSnapshotFinder pastSnapshotFinder = mock(PastSnapshotFinder.class); + when(pastSnapshotFinder.find(null, conf, 1)).thenReturn(new PastSnapshot("days", null, newSnapshot("2010-10-15"))); + when(pastSnapshotFinder.find(null, conf, 3)).thenReturn(new PastSnapshot("days", null, newSnapshot("2010-10-13"))); - TimeMachineConfiguration timeMachineConfiguration = new TimeMachineConfiguration(conf, snapshotReferenceFinder); + TimeMachineConfiguration timeMachineConfiguration = new TimeMachineConfiguration(conf, pastSnapshotFinder, null); - verify(snapshotReferenceFinder).find(conf, 1); - verify(snapshotReferenceFinder).find(conf, 2); - verify(snapshotReferenceFinder).find(conf, 3); + verify(pastSnapshotFinder).find(null, conf, 1); + verify(pastSnapshotFinder).find(null, conf, 2); + verify(pastSnapshotFinder).find(null, conf, 3); assertThat(timeMachineConfiguration.getProjectPastSnapshots().size(), is(2)); } diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java index 0f02f0c2268..76fddcfb7f9 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java @@ -27,7 +27,10 @@ import org.sonar.api.database.model.Snapshot; import org.sonar.api.measures.Measure; import org.sonar.api.measures.MeasuresFilter; import org.sonar.api.measures.Metric; +import org.sonar.api.measures.MetricFinder; import org.sonar.api.resources.*; +import org.sonar.batch.components.PastMeasuresLoader; +import org.sonar.batch.components.PastSnapshot; import org.sonar.jpa.test.AbstractDbUnitTestCase; import java.util.Arrays; @@ -76,7 +79,7 @@ public class VariationDecoratorTest extends AbstractDbUnitTestCase { Measure currentCoverage = newMeasure(COVERAGE, 80.0); when(context.getMeasures(Matchers.anyObject())).thenReturn(Arrays.asList(currentNcloc, currentCoverage)); - VariationDecorator decorator = new VariationDecorator(pastMeasuresLoader, Arrays.asList(pastSnapshot1, pastSnapshot3)); + VariationDecorator decorator = new VariationDecorator(pastMeasuresLoader, mock(MetricFinder.class), Arrays.asList(pastSnapshot1, pastSnapshot3)); decorator.decorate(javaPackage, context); // context updated for each variation : 2 times for ncloc and 1 time for coverage diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastMeasuresLoaderTest/shared.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastMeasuresLoaderTest/shared.xml deleted file mode 100644 index bcde5f6100f..00000000000 --- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastMeasuresLoaderTest/shared.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDateTest/shared.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDateTest/shared.xml deleted file mode 100644 index 87f673c46f4..00000000000 --- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDateTest/shared.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDaysTest/shared.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDaysTest/shared.xml deleted file mode 100644 index f9c84713489..00000000000 --- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastSnapshotFinderByDaysTest/shared.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastSnapshotFinderByPreviousAnalysisTest/shouldFindPreviousAnalysis.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastSnapshotFinderByPreviousAnalysisTest/shouldFindPreviousAnalysis.xml deleted file mode 100644 index 6b30b66983a..00000000000 --- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastSnapshotFinderByPreviousAnalysisTest/shouldFindPreviousAnalysis.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastSnapshotFinderByPreviousAnalysisTest/shouldNotFindPreviousAnalysis.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastSnapshotFinderByPreviousAnalysisTest/shouldNotFindPreviousAnalysis.xml deleted file mode 100644 index 2ac2dbbc8a1..00000000000 --- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastSnapshotFinderByPreviousAnalysisTest/shouldNotFindPreviousAnalysis.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastSnapshotFinderByVersionTest/shared.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastSnapshotFinderByVersionTest/shared.xml deleted file mode 100644 index 72207acb9cc..00000000000 --- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastSnapshotFinderByVersionTest/shared.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastViolationsLoaderTest/shared.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastViolationsLoaderTest/shared.xml deleted file mode 100644 index a7a222fe037..00000000000 --- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastViolationsLoaderTest/shared.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/sonar-batch/src/main/java/org/sonar/batch/Batch.java b/sonar-batch/src/main/java/org/sonar/batch/Batch.java index 91e981e41ac..bf5b1e348bd 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/Batch.java +++ b/sonar-batch/src/main/java/org/sonar/batch/Batch.java @@ -33,6 +33,7 @@ import org.sonar.batch.bootstrap.BatchPluginRepository; import org.sonar.batch.bootstrap.BootstrapClassLoader; import org.sonar.batch.bootstrap.ExtensionDownloader; import org.sonar.batch.bootstrap.TempDirectories; +import org.sonar.batch.components.*; import org.sonar.batch.index.*; import org.sonar.core.components.CacheMetricFinder; import org.sonar.core.components.CacheRuleFinder; @@ -92,6 +93,12 @@ public class Batch { batchContainer.as(Characteristics.CACHE).addComponent(MeasuresDao.class); batchContainer.as(Characteristics.CACHE).addComponent(CacheRuleFinder.class); batchContainer.as(Characteristics.CACHE).addComponent(CacheMetricFinder.class); + batchContainer.as(Characteristics.CACHE).addComponent(PastSnapshotFinderByDate.class); + batchContainer.as(Characteristics.CACHE).addComponent(PastSnapshotFinderByDays.class); + batchContainer.as(Characteristics.CACHE).addComponent(PastSnapshotFinderByPreviousAnalysis.class); + batchContainer.as(Characteristics.CACHE).addComponent(PastSnapshotFinderByVersion.class); + batchContainer.as(Characteristics.CACHE).addComponent(PastMeasuresLoader.class); + batchContainer.as(Characteristics.CACHE).addComponent(PastSnapshotFinder.class); batchContainer.start(); ProjectTree projectTree = batchContainer.getComponent(ProjectTree.class); diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java index afccb16fdda..6bc1ac2862c 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java +++ b/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java @@ -36,6 +36,8 @@ import org.sonar.api.rules.DefaultRulesManager; import org.sonar.api.utils.IocContainer; import org.sonar.api.utils.SonarException; import org.sonar.batch.bootstrap.BatchPluginRepository; +import org.sonar.batch.components.PastViolationsLoader; +import org.sonar.batch.components.TimeMachineConfiguration; import org.sonar.batch.index.DefaultIndex; import org.sonar.batch.index.DefaultResourcePersister; import org.sonar.batch.phases.Phases; @@ -93,6 +95,8 @@ public class ProjectBatch { batchContainer.as(Characteristics.CACHE).addComponent(ViolationFilters.class); batchContainer.as(Characteristics.CACHE).addComponent(ResourceFilters.class); batchContainer.as(Characteristics.CACHE).addComponent(DefaultModelFinder.class); + batchContainer.as(Characteristics.CACHE).addComponent(TimeMachineConfiguration.class); + batchContainer.as(Characteristics.CACHE).addComponent(PastViolationsLoader.class); batchContainer.addAdapter(new ProfileProvider()); batchContainer.addAdapter(new CheckProfileProvider()); loadCoreComponents(batchContainer); diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java b/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java new file mode 100644 index 00000000000..ee3ad649957 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java @@ -0,0 +1,81 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.components; + +import com.google.common.collect.Maps; +import org.apache.commons.lang.ObjectUtils; +import org.sonar.api.BatchExtension; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.MeasureModel; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.measures.Metric; +import org.sonar.api.measures.MetricFinder; +import org.sonar.api.resources.Resource; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +public class PastMeasuresLoader implements BatchExtension { + + private Map metricByIds; + private DatabaseSession session; + + public PastMeasuresLoader(DatabaseSession session, MetricFinder metricFinder) { + this(session, metricFinder.findAll()); + } + + PastMeasuresLoader(DatabaseSession session, Collection metrics) { + this.session = session; + this.metricByIds = Maps.newHashMap(); + for (Metric metric : metrics) { + if (metric.isNumericType()) { + metricByIds.put(metric.getId(), metric); + } + } + } + + public Collection getMetrics() { + return metricByIds.values(); + } + + public List getPastMeasures(Resource resource, PastSnapshot projectPastSnapshot) { + return getPastMeasures(resource, projectPastSnapshot.getProjectSnapshot()); + } + + public List getPastMeasures(Resource resource, Snapshot projectSnapshot) { + // assume that the resource has already been saved + return getPastMeasures(resource.getId(), projectSnapshot); + } + + public List getPastMeasures(int resourceId, Snapshot projectSnapshot) { + // TODO improvement : select only some columns + // TODO support measure on characteristics + String hql = "select m from " + MeasureModel.class.getSimpleName() + " m, " + Snapshot.class.getSimpleName() + " s " + + "where m.snapshotId=s.id and m.metricId in (:metricIds) and m.ruleId=null and m.rulePriority=null and m.characteristic=null " + + "and (s.rootId=:rootSnapshotId or s.id=:rootSnapshotId) and s.resourceId=:resourceId and s.status=:status"; + return session.createQuery(hql) + .setParameter("metricIds", metricByIds.keySet()) + .setParameter("rootSnapshotId", ObjectUtils.defaultIfNull(projectSnapshot.getRootId(), projectSnapshot.getId())) + .setParameter("resourceId", resourceId) + .setParameter("status", Snapshot.STATUS_PROCESSED) + .getResultList(); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshot.java b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshot.java new file mode 100644 index 00000000000..b55ad44d661 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshot.java @@ -0,0 +1,92 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.components; + +import org.apache.commons.lang.builder.ReflectionToStringBuilder; +import org.sonar.api.database.model.Snapshot; + +import java.util.Date; + +public class PastSnapshot { + + private int index; + private String mode, modeParameter; + private Snapshot projectSnapshot; + private Date targetDate; + + public PastSnapshot(String mode, Date targetDate, Snapshot projectSnapshot) { + this.mode = mode; + this.targetDate = targetDate; + this.projectSnapshot = projectSnapshot; + } + + public PastSnapshot(String mode, Snapshot projectSnapshot) { + this.mode = mode; + this.projectSnapshot = projectSnapshot; + } + + public PastSnapshot setIndex(int index) { + this.index = index; + return this; + } + + public int getIndex() { + return index; + } + + public Snapshot getProjectSnapshot() { + return projectSnapshot; + } + + public Date getDate() { + return projectSnapshot.getCreatedAt(); + } + + public String getMode() { + return mode; + } + + public String getModeParameter() { + return modeParameter; + } + + public PastSnapshot setModeParameter(String s) { + this.modeParameter = s; + return this; + } + + public Integer getProjectSnapshotId() { + return (projectSnapshot!=null ? projectSnapshot.getId() : null); + } + + public Date getTargetDate() { + return targetDate; + } + + public PastSnapshot setTargetDate(Date d) { + this.targetDate = d; + return this; + } + + @Override + public String toString() { + return ReflectionToStringBuilder.toString(this); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinder.java b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinder.java new file mode 100644 index 00000000000..00f112a1b56 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinder.java @@ -0,0 +1,128 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.components; + +import org.apache.commons.configuration.Configuration; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.BatchExtension; +import org.sonar.api.CoreProperties; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.utils.Logs; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class PastSnapshotFinder implements BatchExtension { + + /** + * IMPORTANT : please update default values in the ruby side too. See app/helpers/FiltersHelper.rb, method period_names() + */ + private PastSnapshotFinderByDays finderByDays; + private PastSnapshotFinderByVersion finderByVersion; + private PastSnapshotFinderByDate finderByDate; + private PastSnapshotFinderByPreviousAnalysis finderByPreviousAnalysis; + + public PastSnapshotFinder(PastSnapshotFinderByDays finderByDays, PastSnapshotFinderByVersion finderByVersion, + PastSnapshotFinderByDate finderByDate, PastSnapshotFinderByPreviousAnalysis finderByPreviousAnalysis) { + this.finderByDays = finderByDays; + this.finderByVersion = finderByVersion; + this.finderByDate = finderByDate; + this.finderByPreviousAnalysis = finderByPreviousAnalysis; + } + + public PastSnapshot find(Snapshot projectSnapshot, Configuration conf, int index) { + String propertyValue = getPropertyValue(conf, index); + PastSnapshot pastSnapshot = find(projectSnapshot, index, propertyValue); + if (pastSnapshot==null && StringUtils.isNotBlank(propertyValue)) { + Logs.INFO.warn("The property " + CoreProperties.TIMEMACHINE_PERIOD_PREFIX + index + " has an unvalid value: " + propertyValue); + } + return pastSnapshot; + } + + static String getPropertyValue(Configuration conf, int index) { + String defaultValue = null; + switch (index) { + case 1: defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_1; break; + case 2: defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_2; break; + case 3: defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_3; break; + case 4: defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_4; break; + case 5: defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_5; break; + } + return conf.getString(CoreProperties.TIMEMACHINE_PERIOD_PREFIX + index, defaultValue); + } + + public PastSnapshot find(Snapshot projectSnapshot, int index, String property) { + if (StringUtils.isBlank(property)) { + return null; + } + + PastSnapshot result = findByDays(projectSnapshot, property); + if (result == null) { + result = findByDate(projectSnapshot, property); + if (result == null) { + result = findByPreviousAnalysis(projectSnapshot, property); + if (result == null) { + result = findByVersion(projectSnapshot, property); + } + } + } + + if (result != null) { + result.setIndex(index); + } + + return result; + } + + private PastSnapshot findByPreviousAnalysis(Snapshot projectSnapshot, String property) { + PastSnapshot pastSnapshot = null; + if (StringUtils.equals(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, property)) { + pastSnapshot = finderByPreviousAnalysis.findByPreviousAnalysis(projectSnapshot); + } + return pastSnapshot; + } + + private PastSnapshot findByDate(Snapshot projectSnapshot, String property) { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + Date date = format.parse(property); + return finderByDate.findByDate(projectSnapshot, date); + + } catch (ParseException e) { + return null; + } + } + + private PastSnapshot findByVersion(Snapshot projectSnapshot, String property) { + return finderByVersion.findByVersion(projectSnapshot, property); + } + + private PastSnapshot findByDays(Snapshot projectSnapshot, String property) { + try { + int days = Integer.parseInt(property); + return finderByDays.findFromDays(projectSnapshot, days); + + } catch (NumberFormatException e) { + return null; + } + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinderByDate.java b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinderByDate.java new file mode 100644 index 00000000000..75ef31b9084 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinderByDate.java @@ -0,0 +1,56 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.components; + +import org.sonar.api.BatchExtension; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.Snapshot; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +public class PastSnapshotFinderByDate implements BatchExtension { + + public static final String MODE = "date"; + + private DatabaseSession session; + + public PastSnapshotFinderByDate(DatabaseSession session) { + this.session = session; + } + + PastSnapshot findByDate(Snapshot projectSnapshot, Date date) { + String hql = "from " + Snapshot.class.getSimpleName() + " where createdAt>=:date AND resourceId=:resourceId AND status=:status order by createdAt asc"; + List snapshots = session.createQuery(hql) + .setParameter("date", date) + .setParameter("resourceId", projectSnapshot.getResourceId()) + .setParameter("status", Snapshot.STATUS_PROCESSED) + .setMaxResults(1) + .getResultList(); + if (snapshots.isEmpty()) { + return null; + } + + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + return new PastSnapshot(MODE, date, snapshots.get(0)).setModeParameter(format.format(date)); + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinderByDays.java b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinderByDays.java new file mode 100644 index 00000000000..6894a802ec1 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinderByDays.java @@ -0,0 +1,56 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.components; + +import org.apache.commons.lang.time.DateUtils; +import org.sonar.api.BatchExtension; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.Snapshot; + +import java.util.Date; +import java.util.List; + +public class PastSnapshotFinderByDays implements BatchExtension { + + public static final String MODE = "days"; + + private DatabaseSession session; + + public PastSnapshotFinderByDays(DatabaseSession session) { + this.session = session; + } + + PastSnapshot findFromDays(Snapshot projectSnapshot, int days) { + Date targetDate = DateUtils.addDays(projectSnapshot.getCreatedAt(), -days); + String hql = "from " + Snapshot.class.getSimpleName() + " where resourceId=:resourceId AND status=:status AND createdAt>=:from AND createdAt<:to order by createdAt asc"; + List snapshots = session.createQuery(hql) + .setParameter("from", targetDate) + .setParameter("to", projectSnapshot.getCreatedAt()) + .setParameter("resourceId", projectSnapshot.getResourceId()) + .setParameter("status", Snapshot.STATUS_PROCESSED) + .setMaxResults(1) + .getResultList(); + + if (snapshots.isEmpty()) { + return null; + } + return new PastSnapshot(MODE, targetDate, snapshots.get(0)).setModeParameter(String.valueOf(days)); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinderByPreviousAnalysis.java b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinderByPreviousAnalysis.java new file mode 100644 index 00000000000..55dda549bbc --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinderByPreviousAnalysis.java @@ -0,0 +1,55 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.components; + +import org.sonar.api.BatchExtension; +import org.sonar.api.CoreProperties; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.Snapshot; + +import java.text.SimpleDateFormat; +import java.util.List; + +public class PastSnapshotFinderByPreviousAnalysis implements BatchExtension { + + private DatabaseSession session; + + public PastSnapshotFinderByPreviousAnalysis(DatabaseSession session) { + this.session = session; + } + + PastSnapshot findByPreviousAnalysis(Snapshot projectSnapshot) { + String hql = "from " + Snapshot.class.getSimpleName() + " where createdAt<:date AND resourceId=:resourceId AND status=:status and last=true order by createdAt desc"; + List snapshots = session.createQuery(hql) + .setParameter("date", projectSnapshot.getCreatedAt()) + .setParameter("resourceId", projectSnapshot.getResourceId()) + .setParameter("status", Snapshot.STATUS_PROCESSED) + .setMaxResults(1) + .getResultList(); + + if (snapshots.isEmpty()) { + return null; + } + Snapshot snapshot = snapshots.get(0); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + return new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, snapshot.getCreatedAt(), snapshot).setModeParameter(format.format(snapshot.getCreatedAt())); + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinderByVersion.java b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinderByVersion.java new file mode 100644 index 00000000000..cd360d2b125 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinderByVersion.java @@ -0,0 +1,54 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.components; + +import org.sonar.api.BatchExtension; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.Snapshot; + +import java.util.List; + +public class PastSnapshotFinderByVersion implements BatchExtension { + + public static final String MODE = "version"; + + private DatabaseSession session; + + public PastSnapshotFinderByVersion(DatabaseSession session) { + this.session = session; + } + + PastSnapshot findByVersion(Snapshot projectSnapshot, String version) { + String hql = "from " + Snapshot.class.getSimpleName() + " where version=:version AND resourceId=:resourceId AND status=:status order by createdAt desc"; + List snapshots = session.createQuery(hql) + .setParameter("version", version) + .setParameter("resourceId", projectSnapshot.getResourceId()) + .setParameter("status", Snapshot.STATUS_PROCESSED) + .setMaxResults(1) + .getResultList(); + + if (snapshots.isEmpty()) { + return null; + } + Snapshot snapshot = snapshots.get(0); + return new PastSnapshot(MODE, snapshot.getCreatedAt(), snapshot).setModeParameter(snapshot.getVersion()); + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/PastViolationsLoader.java b/sonar-batch/src/main/java/org/sonar/batch/components/PastViolationsLoader.java new file mode 100644 index 00000000000..5f238ee9aed --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/components/PastViolationsLoader.java @@ -0,0 +1,48 @@ +package org.sonar.batch.components; + +import org.sonar.api.BatchExtension; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.RuleFailureModel; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.database.model.SnapshotSource; +import org.sonar.api.resources.Resource; +import org.sonar.api.utils.SonarException; +import org.sonar.batch.index.ResourcePersister; + +import java.util.Collections; +import java.util.List; + +public class PastViolationsLoader implements BatchExtension { + + private DatabaseSession session; + private ResourcePersister resourcePersister; + + public PastViolationsLoader(DatabaseSession session, ResourcePersister resourcePersister) { + this.session = session; + this.resourcePersister = resourcePersister; + } + + public List getPastViolations(Resource resource) { + if (resource == null) { + return Collections.emptyList(); + } + + Snapshot snapshot = resourcePersister.getSnapshot(resource); + if (snapshot == null) { + throw new SonarException("This resource has no snapshot ???" + resource); + } + Snapshot previousLastSnapshot = resourcePersister.getLastSnapshot(snapshot, true); + if (previousLastSnapshot == null) { + return Collections.emptyList(); + } + return session.getResults(RuleFailureModel.class, + "snapshotId", previousLastSnapshot.getId()); + } + + public SnapshotSource getSource(Resource resource) { + Snapshot snapshot = resourcePersister.getSnapshot(resource); + return session.getSingleResult(SnapshotSource.class, + "snapshotId", snapshot.getId()); + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/TimeMachineConfiguration.java b/sonar-batch/src/main/java/org/sonar/batch/components/TimeMachineConfiguration.java new file mode 100644 index 00000000000..eb1977270e7 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/components/TimeMachineConfiguration.java @@ -0,0 +1,72 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.components; + +import com.google.common.collect.Lists; +import org.apache.commons.configuration.Configuration; +import org.sonar.api.BatchExtension; +import org.sonar.api.CoreProperties; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.utils.Logs; + +import java.util.Collections; +import java.util.List; + +public class TimeMachineConfiguration implements BatchExtension { + + private static final int NUMBER_OF_VARIATION_SNAPSHOTS = 5; + + private final Configuration configuration; + private List projectPastSnapshots; + + public TimeMachineConfiguration(Configuration configuration, PastSnapshotFinder pastSnapshotFinder, Snapshot projectSnapshot) { + this.configuration = configuration; + initPastSnapshots(pastSnapshotFinder, projectSnapshot); + } + + private void initPastSnapshots(PastSnapshotFinder pastSnapshotFinder, Snapshot projectSnapshot) { + projectPastSnapshots = Lists.newLinkedList(); + for (int index = 1; index <= NUMBER_OF_VARIATION_SNAPSHOTS; index++) { + PastSnapshot variationSnapshot = pastSnapshotFinder.find(projectSnapshot, configuration, index); + if (variationSnapshot != null) { + Logs.INFO.info("Comparison date: " + variationSnapshot.getDate()); + projectPastSnapshots.add(variationSnapshot); + } + } + } + + public TimeMachineConfiguration(Configuration configuration) { + this.configuration = configuration; + this.projectPastSnapshots = Collections.emptyList(); + } + + + public boolean skipTendencies() { + return configuration.getBoolean(CoreProperties.SKIP_TENDENCIES_PROPERTY, CoreProperties.SKIP_TENDENCIES_DEFAULT_VALUE); + } + + public int getTendencyPeriodInDays() { + return configuration.getInt(CoreProperties.CORE_TENDENCY_DEPTH_PROPERTY, CoreProperties.CORE_TENDENCY_DEPTH_DEFAULT_VALUE); + } + + public List getProjectPastSnapshots() { + return projectPastSnapshots; + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultPersistenceManager.java b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultPersistenceManager.java index c91bf3205aa..942dd3aa127 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultPersistenceManager.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultPersistenceManager.java @@ -26,7 +26,6 @@ import org.sonar.api.measures.Measure; import org.sonar.api.resources.Project; import org.sonar.api.resources.ProjectLink; import org.sonar.api.resources.Resource; -import org.sonar.api.rules.Violation; import java.util.List; diff --git a/sonar-batch/src/test/java/org/sonar/batch/components/PastMeasuresLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/components/PastMeasuresLoaderTest.java new file mode 100644 index 00000000000..1f3301424ed --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/components/PastMeasuresLoaderTest.java @@ -0,0 +1,96 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.components; + +import org.junit.Test; +import org.sonar.api.database.model.MeasureModel; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.measures.Metric; +import org.sonar.batch.components.PastMeasuresLoader; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.util.Arrays; +import java.util.List; + +import static org.hamcrest.CoreMatchers.anyOf; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.internal.matchers.IsCollectionContaining.hasItems; + +public class PastMeasuresLoaderTest extends AbstractDbUnitTestCase { + + private static final int PROJECT_SNAPSHOT_ID = 1000; + private static final int PROJECT_ID = 1; + private static final int FILE_ID = 3; + + @Test + public void shouldGetPastResourceMeasures() { + setupData("shared"); + + List metrics = selectMetrics(); + Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID); + + PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics); + List measures = loader.getPastMeasures(FILE_ID, projectSnapshot); + assertThat(measures.size(), is(2)); + + for (MeasureModel measure : measures) { + assertThat(measure.getId(), anyOf(is(5L), is(6L))); + assertThat(measure.getValue(), anyOf(is(5.0), is(60.0))); + } + } + + @Test + public void shouldGetPastProjectMeasures() { + setupData("shared"); + + List metrics = selectMetrics(); + Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID); + + PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics); + List measures = loader.getPastMeasures(PROJECT_ID, projectSnapshot); + assertThat(measures.size(), is(2)); + + for (MeasureModel measure : measures) { + assertThat(measure.getId(), anyOf(is(1L), is(2L))); + assertThat(measure.getValue(), anyOf(is(60.0), is(80.0))); + } + } + + @Test + public void shouldKeepOnlyNumericalMetrics() { + Metric ncloc = new Metric("ncloc", Metric.ValueType.INT); + ncloc.setId(1); + Metric complexity = new Metric("complexity", Metric.ValueType.INT); + complexity.setId(2); + Metric data = new Metric("data", Metric.ValueType.DATA); + data.setId(3); + List metrics = Arrays.asList(ncloc, complexity, data); + + PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics); + + assertThat(loader.getMetrics().size(), is(2)); + assertThat(loader.getMetrics(), hasItems(ncloc, complexity)); + } + + private List selectMetrics() { + return getSession().getResults(Metric.class); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderByDateTest.java b/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderByDateTest.java new file mode 100644 index 00000000000..2013424d30c --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderByDateTest.java @@ -0,0 +1,61 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.components; + +import org.junit.Test; +import org.sonar.api.database.model.Snapshot; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class PastSnapshotFinderByDateTest extends AbstractDbUnitTestCase { + public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); + + @Test + public void shouldFindDate() throws ParseException { + setupData("shared"); + + Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); + PastSnapshotFinderByDate finder = new PastSnapshotFinderByDate(getSession()); + + Date date = DATE_FORMAT.parse("2008-11-22"); + + PastSnapshot pastSnapshot = finder.findByDate(projectSnapshot, date); + assertThat(pastSnapshot.getProjectSnapshotId(), is(1006)); + } + + @Test + public void shouldFindNearestLaterDate() throws ParseException { + setupData("shared"); + + Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); + PastSnapshotFinderByDate finder = new PastSnapshotFinderByDate(getSession()); + + Date date = DATE_FORMAT.parse("2008-11-24"); + + PastSnapshot pastSnapshot = finder.findByDate(projectSnapshot, date); + assertThat(pastSnapshot.getProjectSnapshotId(), is(1009)); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderByDaysTest.java b/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderByDaysTest.java new file mode 100644 index 00000000000..6db32df71c7 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderByDaysTest.java @@ -0,0 +1,64 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.components; + +import org.junit.Test; +import org.sonar.api.database.model.Snapshot; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.text.ParseException; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; + +public class PastSnapshotFinderByDaysTest extends AbstractDbUnitTestCase { + + @Test + public void shouldGetNextSnapshot() throws ParseException { + setupData("shared"); + + Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1009); // 2008-11-16 + PastSnapshotFinderByDays finder = new PastSnapshotFinderByDays(getSession()); + + assertThat(finder.findFromDays(projectSnapshot, 50).getProjectSnapshotId(), is(1000)); + } + + @Test + public void shouldIgnoreUnprocessedSnapshots() throws ParseException { + setupData("shared"); + + Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1009); // 2008-11-16 + PastSnapshotFinderByDays finder = new PastSnapshotFinderByDays(getSession()); + + assertThat(finder.findFromDays(projectSnapshot, 7).getProjectSnapshotId(), is(1006)); + } + + @Test + public void shouldNotFindSelf() throws ParseException { + setupData("shared"); + + Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1009); // 2008-11-16 + PastSnapshotFinderByDays finder = new PastSnapshotFinderByDays(getSession()); + + assertThat(finder.findFromDays(projectSnapshot, 1), nullValue()); + } + +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderByPreviousAnalysisTest.java b/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderByPreviousAnalysisTest.java new file mode 100644 index 00000000000..b72947d275e --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderByPreviousAnalysisTest.java @@ -0,0 +1,54 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.components; + +import org.junit.Test; +import org.sonar.api.database.model.Snapshot; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.text.ParseException; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; + +public class PastSnapshotFinderByPreviousAnalysisTest extends AbstractDbUnitTestCase { + + @Test + public void shouldFindPreviousAnalysis() throws ParseException { + setupData("shouldFindPreviousAnalysis"); + + Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); + PastSnapshotFinderByPreviousAnalysis finder = new PastSnapshotFinderByPreviousAnalysis(getSession()); + + PastSnapshot pastSnapshot = finder.findByPreviousAnalysis(projectSnapshot); + assertThat(pastSnapshot.getProjectSnapshotId(), is(1009)); + } + + @Test + public void shouldNotFindPreviousAnalysis() throws ParseException { + setupData("shouldNotFindPreviousAnalysis"); + + Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); + PastSnapshotFinderByPreviousAnalysis finder = new PastSnapshotFinderByPreviousAnalysis(getSession()); + + assertNull(finder.findByPreviousAnalysis(projectSnapshot)); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderByVersionTest.java b/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderByVersionTest.java new file mode 100644 index 00000000000..6a6f084b842 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderByVersionTest.java @@ -0,0 +1,51 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.components; + +import org.junit.Test; +import org.sonar.api.database.model.Snapshot; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.core.IsNull.nullValue; +import static org.junit.Assert.assertThat; + +public class PastSnapshotFinderByVersionTest extends AbstractDbUnitTestCase { + + @Test + public void shouldFindByVersion() { + setupData("shared"); + + Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); + PastSnapshotFinderByVersion finder = new PastSnapshotFinderByVersion(getSession()); + + assertThat(finder.findByVersion(currentProjectSnapshot, "1.1").getProjectSnapshotId(), is(1009)); + } + + @Test + public void shouldNotFindVersion() { + setupData("shared"); + + Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); + PastSnapshotFinderByVersion finder = new PastSnapshotFinderByVersion(getSession()); + + assertThat(finder.findByVersion(currentProjectSnapshot, "1.0"), nullValue()); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderTest.java b/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderTest.java new file mode 100644 index 00000000000..eb59d8d4139 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderTest.java @@ -0,0 +1,183 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.components; + +import org.apache.commons.configuration.PropertiesConfiguration; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.CoreProperties; +import org.sonar.api.database.model.Snapshot; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import static junit.framework.Assert.assertNull; +import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsNot.not; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.*; + +public class PastSnapshotFinderTest { + + private PastSnapshotFinderByDays finderByDays; + private PastSnapshotFinderByDate finderByDate; + private PastSnapshotFinderByVersion finderByVersion; + private PastSnapshotFinderByPreviousAnalysis finderByPreviousAnalysis; + private PastSnapshotFinder finder; + + @Before + public void initFinders() { + finderByDays = mock(PastSnapshotFinderByDays.class); + finderByDate = mock(PastSnapshotFinderByDate.class); + finderByVersion = mock(PastSnapshotFinderByVersion.class); + finderByPreviousAnalysis = mock(PastSnapshotFinderByPreviousAnalysis.class); + finder = new PastSnapshotFinder(finderByDays, finderByVersion, finderByDate, finderByPreviousAnalysis); + } + + @Test + public void shouldFindByNumberOfDays() { + when(finderByDays.findFromDays(null, 30)).thenReturn(new PastSnapshot("days", null).setModeParameter("30")); + + PastSnapshot variationSnapshot = finder.find(null, 1, "30"); + + verify(finderByDays).findFromDays(null, 30); + assertNotNull(variationSnapshot); + assertThat(variationSnapshot.getIndex(), is(1)); + assertThat(variationSnapshot.getMode(), is("days")); + assertThat(variationSnapshot.getModeParameter(), is("30")); + } + + @Test + public void shouldNotFindByNumberOfDays() { + PastSnapshot variationSnapshot = finder.find(null, 1, "30"); + + verify(finderByDays).findFromDays(null, 30); + assertNull(variationSnapshot); + } + + @Test + public void shouldFindByDate() throws ParseException { + final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + final Date date = format.parse("2010-05-18"); + when(finderByDate.findByDate(null, date)).thenReturn(new PastSnapshot("date", new Snapshot())); + + PastSnapshot variationSnapshot = finder.find(null, 2, "2010-05-18"); + + verify(finderByDate).findByDate((Snapshot) anyObject(), argThat(new BaseMatcher() { + public boolean matches(Object o) { + return o.equals(date); + } + + public void describeTo(Description description) { + + } + })); + assertThat(variationSnapshot.getIndex(), is(2)); + assertThat(variationSnapshot.getMode(), is("date")); + assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue())); + } + + @Test + public void shouldNotFindByDate() throws ParseException { + when(finderByDate.findByDate((Snapshot) anyObject(), (Date) anyObject())).thenReturn(null); + + PastSnapshot variationSnapshot = finder.find(null, 2, "2010-05-18"); + + verify(finderByDate).findByDate((Snapshot) anyObject(), (Date) anyObject()); + assertNull(variationSnapshot); + } + + @Test + public void shouldFindByPreviousAnalysis() throws ParseException { + final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + final Date date = format.parse("2010-05-18"); + Snapshot snapshot = new Snapshot(); + snapshot.setCreatedAt(date); + when(finderByPreviousAnalysis.findByPreviousAnalysis(null)).thenReturn(new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, snapshot)); + + PastSnapshot variationSnapshot = finder.find(null, 2, CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS); + + verify(finderByPreviousAnalysis).findByPreviousAnalysis(null); + assertThat(variationSnapshot.getIndex(), is(2)); + assertThat(variationSnapshot.getMode(), is(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS)); + assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue())); + } + + @Test + public void shouldNotFindPreviousAnalysis() { + when(finderByPreviousAnalysis.findByPreviousAnalysis(null)).thenReturn(null); + + PastSnapshot variationSnapshot = finder.find(null, 2, CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS); + + verify(finderByPreviousAnalysis).findByPreviousAnalysis(null); + + assertNull(variationSnapshot); + } + + @Test + public void shouldFindByVersion() { + when(finderByVersion.findByVersion(null, "1.2")).thenReturn(new PastSnapshot("version", new Snapshot())); + + PastSnapshot variationSnapshot = finder.find(null, 2, "1.2"); + + verify(finderByVersion).findByVersion(null, "1.2"); + assertThat(variationSnapshot.getIndex(), is(2)); + assertThat(variationSnapshot.getMode(), is("version")); + assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue())); + } + + @Test + public void shouldNotFindVersion() { + when(finderByVersion.findByVersion(null, "1.2")).thenReturn(null); + + PastSnapshot variationSnapshot = finder.find(null, 2, "1.2"); + + verify(finderByVersion).findByVersion(null, "1.2"); + assertNull(variationSnapshot); + } + + @Test + public void shouldNotFailIfUnknownFormat() { + when(finderByPreviousAnalysis.findByPreviousAnalysis(null)).thenReturn(new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, new Snapshot())); // should not be called + assertNull(finder.find(null, 2, "foooo")); + } + + @Test + public void shouldGetPropertyValue() { + PropertiesConfiguration conf = new PropertiesConfiguration(); + conf.setProperty("sonar.timemachine.period1", "5"); + + assertThat(PastSnapshotFinder.getPropertyValue(conf, 1), is("5")); + assertThat(PastSnapshotFinder.getPropertyValue(conf, 999), nullValue()); + } + + @Test + public void shouldGetDefaultPropertyValue() { + PropertiesConfiguration conf = new PropertiesConfiguration(); + conf.setProperty("sonar.timemachine.period1", "5"); + + assertThat(PastSnapshotFinder.getPropertyValue(conf, 2), is(CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_2)); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/components/PastViolationsLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/components/PastViolationsLoaderTest.java new file mode 100644 index 00000000000..bbc35b4b878 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/components/PastViolationsLoaderTest.java @@ -0,0 +1,55 @@ +package org.sonar.batch.components; + +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.database.model.RuleFailureModel; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.resources.JavaFile; +import org.sonar.api.resources.Resource; +import org.sonar.batch.index.ResourcePersister; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.notNullValue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +public class PastViolationsLoaderTest extends AbstractDbUnitTestCase { + + private ResourcePersister resourcePersister; + private PastViolationsLoader loader; + + @Before + public void setUp() { + setupData("shared"); + resourcePersister = mock(ResourcePersister.class); + loader = new PastViolationsLoader(getSession(), resourcePersister); + } + + @Test + public void shouldGetPastResourceViolations() { + Snapshot snapshot = getSession().getSingleResult(Snapshot.class, "id", 1000); + doReturn(snapshot).when(resourcePersister) + .getSnapshot(any(Resource.class)); + doReturn(snapshot).when(resourcePersister) + .getLastSnapshot(any(Snapshot.class), anyBoolean()); + + List violations = loader.getPastViolations(new JavaFile("file")); + + assertThat(violations.size(), is(2)); + } + + @Test + public void shouldReturnEmptyList() { + List violations = loader.getPastViolations(null); + + assertThat(violations, notNullValue()); + assertThat(violations.size(), is(0)); + } + +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/ViolationPersisterTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/ViolationPersisterTest.java index f9bd575af86..b307e8dbe67 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/index/ViolationPersisterTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/index/ViolationPersisterTest.java @@ -51,7 +51,6 @@ public class ViolationPersisterTest extends AbstractDbUnitTestCase { Snapshot snapshot = getSession().getSingleResult(Snapshot.class, "id", 1000); ResourcePersister resourcePersister = mock(ResourcePersister.class); when(resourcePersister.saveResource((Project) anyObject(), eq(javaFile))).thenReturn(snapshot); - when(resourcePersister.getLastSnapshot(snapshot, true)).thenReturn(snapshot); when(resourcePersister.getSnapshot(javaFile)).thenReturn(snapshot); violationPersister = new ViolationPersister(getSession(), resourcePersister, new DefaultRuleFinder(getSessionFactory())); } diff --git a/sonar-batch/src/test/resources/org/sonar/batch/components/PastMeasuresLoaderTest/shared.xml b/sonar-batch/src/test/resources/org/sonar/batch/components/PastMeasuresLoaderTest/shared.xml new file mode 100644 index 00000000000..bcde5f6100f --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/components/PastMeasuresLoaderTest/shared.xml @@ -0,0 +1,85 @@ + + + \ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByDateTest/shared.xml b/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByDateTest/shared.xml new file mode 100644 index 00000000000..87f673c46f4 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByDateTest/shared.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByDaysTest/shared.xml b/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByDaysTest/shared.xml new file mode 100644 index 00000000000..f9c84713489 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByDaysTest/shared.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousAnalysisTest/shouldFindPreviousAnalysis.xml b/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousAnalysisTest/shouldFindPreviousAnalysis.xml new file mode 100644 index 00000000000..6b30b66983a --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousAnalysisTest/shouldFindPreviousAnalysis.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousAnalysisTest/shouldNotFindPreviousAnalysis.xml b/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousAnalysisTest/shouldNotFindPreviousAnalysis.xml new file mode 100644 index 00000000000..2ac2dbbc8a1 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByPreviousAnalysisTest/shouldNotFindPreviousAnalysis.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByVersionTest/shared.xml b/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByVersionTest/shared.xml new file mode 100644 index 00000000000..72207acb9cc --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/components/PastSnapshotFinderByVersionTest/shared.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/components/PastViolationsLoaderTest/shared.xml b/sonar-batch/src/test/resources/org/sonar/batch/components/PastViolationsLoaderTest/shared.xml new file mode 100644 index 00000000000..a7a222fe037 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/components/PastViolationsLoaderTest/shared.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java b/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java index 2e52aa374a3..d1455f00aec 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java @@ -115,4 +115,13 @@ public interface CoreProperties { /* Surefire */ String SUREFIRE_PLUGIN = "surefire"; String SUREFIRE_REPORTS_PATH_PROPERTY = "sonar.surefire.reportsPath"; + + /* Time machine periods */ + String TIMEMACHINE_PERIOD_PREFIX = "sonar.timemachine.period"; + String TIMEMACHINE_MODE_PREVIOUS_ANALYSIS = "previous_analysis"; + String TIMEMACHINE_DEFAULT_PERIOD_1 = TIMEMACHINE_MODE_PREVIOUS_ANALYSIS; + String TIMEMACHINE_DEFAULT_PERIOD_2 = "5"; + String TIMEMACHINE_DEFAULT_PERIOD_3 = "30"; + String TIMEMACHINE_DEFAULT_PERIOD_4 = ""; + String TIMEMACHINE_DEFAULT_PERIOD_5 = ""; } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/HttpDownloader.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/HttpDownloader.java index 71ea6f72ff6..923e1606e10 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/HttpDownloader.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/HttpDownloader.java @@ -170,7 +170,7 @@ public class HttpDownloader implements BatchComponent, ServerComponent { } private HttpURLConnection newHttpConnection(URI uri) throws IOException { - LoggerFactory.getLogger(getClass()).info("Download: " + uri + " (" + getProxySynthesis(uri) + ")"); + LoggerFactory.getLogger(getClass()).debug("Download: " + uri + " (" + getProxySynthesis(uri) + ")"); HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection(); connection.setConnectTimeout(TIMEOUT_MILLISECONDS); connection.setReadTimeout(TIMEOUT_MILLISECONDS);