@@ -27,7 +27,7 @@ import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.api.resources.ResourceType; | |||
import org.sonar.api.resources.ResourceTypeTree; | |||
@InstantiationStrategy(InstantiationStrategy.BATCH) | |||
@InstantiationStrategy(InstantiationStrategy.PER_BATCH) | |||
public final class DefaultResourceTypes extends ExtensionProvider implements BatchExtension, ServerExtension { | |||
@Override | |||
public ResourceTypeTree provide() { |
@@ -19,16 +19,16 @@ | |||
*/ | |||
package org.sonar.plugins.core.batch; | |||
import org.sonar.api.batch.DryRunIncompatible; | |||
import org.sonar.api.batch.PostJob; | |||
import org.sonar.api.batch.SensorContext; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.core.NotDryRun; | |||
import org.sonar.core.resource.ResourceIndexerDao; | |||
/** | |||
* @since 2.13 | |||
*/ | |||
@NotDryRun | |||
@DryRunIncompatible | |||
public class IndexProjectPostJob implements PostJob { | |||
private ResourceIndexerDao indexer; | |||
@@ -34,14 +34,13 @@ import org.sonar.api.resources.ResourceUtils; | |||
import org.sonar.api.rules.Violation; | |||
import org.sonar.api.violations.ViolationQuery; | |||
import org.sonar.batch.index.ResourcePersister; | |||
import org.sonar.core.NotDryRun; | |||
import org.sonar.core.review.ReviewDao; | |||
import org.sonar.core.review.ReviewDto; | |||
import javax.annotation.Nullable; | |||
import java.util.*; | |||
@NotDryRun | |||
@DryRunIncompatible | |||
@DependsUpon(DecoratorBarriers.END_OF_VIOLATION_TRACKING) | |||
@DependedUpon(ReviewWorkflowDecorator.END_OF_REVIEWS_UPDATES) | |||
public class ReviewWorkflowDecorator implements Decorator { |
@@ -20,15 +20,15 @@ | |||
package org.sonar.plugins.core.sensors; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.batch.DryRunIncompatible; | |||
import org.sonar.api.batch.Event; | |||
import org.sonar.api.batch.Sensor; | |||
import org.sonar.api.batch.SensorContext; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.core.NotDryRun; | |||
import java.util.Iterator; | |||
@NotDryRun | |||
@DryRunIncompatible | |||
public class VersionEventsSensor implements Sensor { | |||
public boolean shouldExecuteOnProject(Project project) { |
@@ -33,7 +33,6 @@ import org.sonar.api.resources.Scopes; | |||
import org.sonar.api.utils.KeyValueFormat; | |||
import org.sonar.batch.components.PastSnapshot; | |||
import org.sonar.batch.components.TimeMachineConfiguration; | |||
import org.sonar.core.NotDryRun; | |||
import java.util.Arrays; | |||
import java.util.Date; | |||
@@ -43,7 +42,7 @@ import java.util.Map; | |||
/** | |||
* @since 2.7 | |||
*/ | |||
@NotDryRun | |||
@DryRunIncompatible | |||
@DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE) | |||
public abstract class AbstractNewCoverageFileAnalyzer implements Decorator { | |||
@@ -32,11 +32,10 @@ import org.sonar.api.resources.Project; | |||
import org.sonar.api.resources.Resource; | |||
import org.sonar.api.resources.Scopes; | |||
import org.sonar.batch.components.TimeMachineConfiguration; | |||
import org.sonar.core.NotDryRun; | |||
import java.util.List; | |||
@NotDryRun | |||
@DryRunIncompatible | |||
@DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE) | |||
public class TendencyDecorator implements Decorator { | |||
@@ -21,6 +21,7 @@ package org.sonar.plugins.core.timemachine; | |||
import org.sonar.api.batch.Decorator; | |||
import org.sonar.api.batch.DecoratorContext; | |||
import org.sonar.api.batch.DryRunIncompatible; | |||
import org.sonar.api.database.DatabaseSession; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.resources.Project; | |||
@@ -28,11 +29,10 @@ import org.sonar.api.resources.Resource; | |||
import org.sonar.api.resources.ResourceUtils; | |||
import org.sonar.batch.components.PastSnapshot; | |||
import org.sonar.batch.components.TimeMachineConfiguration; | |||
import org.sonar.core.NotDryRun; | |||
import java.util.List; | |||
@NotDryRun | |||
@DryRunIncompatible | |||
public final class TimeMachineConfigurationPersister implements Decorator { | |||
private TimeMachineConfiguration configuration; |
@@ -30,11 +30,10 @@ import org.sonar.api.rules.RuleFinder; | |||
import org.sonar.api.rules.Violation; | |||
import org.sonar.api.violations.ViolationQuery; | |||
import org.sonar.batch.index.ResourcePersister; | |||
import org.sonar.core.NotDryRun; | |||
import java.util.List; | |||
@NotDryRun | |||
@DryRunIncompatible | |||
@DependsUpon({ DecoratorBarriers.END_OF_VIOLATION_TRACKING, DecoratorBarriers.START_VIOLATION_PERSISTENCE }) | |||
@DependedUpon(DecoratorBarriers.END_OF_VIOLATION_PERSISTENCE) | |||
public class ViolationPersisterDecorator implements Decorator { |
@@ -19,13 +19,13 @@ | |||
*/ | |||
package org.sonar.plugins.dbcleaner; | |||
import org.sonar.api.batch.DryRunIncompatible; | |||
import org.sonar.api.batch.PostJob; | |||
import org.sonar.api.batch.SensorContext; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.core.NotDryRun; | |||
import org.sonar.plugins.dbcleaner.api.PurgeTask; | |||
@NotDryRun | |||
@DryRunIncompatible | |||
public class ProjectPurgePostJob implements PostJob { | |||
private PurgeTask purgeTask; |
@@ -19,8 +19,8 @@ | |||
*/ | |||
package org.sonar.batch; | |||
import org.apache.commons.configuration.Configuration; | |||
import org.sonar.api.batch.ResourceCreationLock; | |||
import org.sonar.api.config.Settings; | |||
/** | |||
* This lock is used to ensure that Sonar resources (files, packages, directories) are not created by buggy plugins | |||
@@ -31,13 +31,10 @@ import org.sonar.api.batch.ResourceCreationLock; | |||
public final class DefaultResourceCreationLock implements ResourceCreationLock { | |||
private boolean locked = false; | |||
private boolean failWhenLocked=false; | |||
private boolean failWhenLocked = false; | |||
public DefaultResourceCreationLock() { | |||
} | |||
public DefaultResourceCreationLock(Configuration configuration) { | |||
this.failWhenLocked = configuration.getBoolean("sonar.hardIndexLock", false); | |||
public DefaultResourceCreationLock(Settings settings) { | |||
this.failWhenLocked = settings.getBoolean("sonar.hardIndexLock"); | |||
} | |||
public boolean isLocked() { |
@@ -25,6 +25,7 @@ import org.apache.commons.lang.ObjectUtils; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.bootstrap.ProjectReactor; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.batch.bootstrap.ProjectReactorReady; | |||
import java.util.List; | |||
import java.util.Map; | |||
@@ -38,15 +39,12 @@ public class ProjectTree { | |||
private Map<ProjectDefinition, Project> projectsByDef; | |||
public ProjectTree(ProjectReactor projectReactor, | |||
ProjectConfigurator projectConfigurator) { | |||
ProjectConfigurator projectConfigurator, | |||
ProjectReactorReady reactorReady) { | |||
this.projectReactor = projectReactor; | |||
this.configurator = projectConfigurator; | |||
} | |||
ProjectTree(ProjectConfigurator configurator) { | |||
this.configurator = configurator; | |||
} | |||
public void start() { | |||
doStart(projectReactor.getProjects()); | |||
} |
@@ -20,6 +20,7 @@ | |||
package org.sonar.batch.bootstrap; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.batch.local.DryRunDatabase; | |||
import org.sonar.core.persistence.DefaultDatabase; | |||
import java.util.Properties; | |||
@@ -29,9 +30,14 @@ import java.util.Properties; | |||
*/ | |||
public class BatchDatabase extends DefaultDatabase { | |||
// the dependency on JdbcDriverHolder is required to be sure that the JDBC driver | |||
// has been downloaded and injected into classloader | |||
public BatchDatabase(Settings settings, JdbcDriverHolder jdbcDriverHolder) { | |||
public BatchDatabase(Settings settings, | |||
// The dependency on JdbcDriverHolder is required to be sure that the JDBC driver | |||
// has been downloaded and injected into classloader | |||
JdbcDriverHolder jdbcDriverHolder, | |||
// The dependency on DryRunDatabase is required to be sure that the dryRun mode | |||
// changed settings | |||
DryRunDatabase dryRun) { | |||
super(settings); | |||
} | |||
@@ -0,0 +1,39 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2008-2012 SonarSource | |||
* 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.bootstrap; | |||
import org.sonar.api.database.DatabaseSession; | |||
import org.sonar.jpa.session.DatabaseSessionFactory; | |||
public class BatchDatabaseSessionFactory implements DatabaseSessionFactory { | |||
private DatabaseSession session; | |||
public BatchDatabaseSessionFactory(DatabaseSession session) { | |||
this.session = session; | |||
} | |||
public DatabaseSession getSession() { | |||
return session; | |||
} | |||
public void clear() { | |||
} | |||
} |
@@ -20,6 +20,7 @@ | |||
package org.sonar.batch.bootstrap; | |||
import org.sonar.api.batch.InstantiationStrategy; | |||
import org.sonar.api.config.EmailSettings; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.api.resources.ResourceTypes; | |||
import org.sonar.batch.DefaultFileLinesContextFactory; | |||
@@ -33,6 +34,7 @@ import org.sonar.batch.components.PastSnapshotFinderByDays; | |||
import org.sonar.batch.components.PastSnapshotFinderByPreviousAnalysis; | |||
import org.sonar.batch.components.PastSnapshotFinderByPreviousVersion; | |||
import org.sonar.batch.components.PastSnapshotFinderByVersion; | |||
import org.sonar.batch.config.BatchDatabaseSettingsLoader; | |||
import org.sonar.batch.index.DefaultIndex; | |||
import org.sonar.batch.index.DefaultPersistenceManager; | |||
import org.sonar.batch.index.DefaultResourcePersister; | |||
@@ -42,11 +44,19 @@ import org.sonar.batch.index.LinkPersister; | |||
import org.sonar.batch.index.MeasurePersister; | |||
import org.sonar.batch.index.MemoryOptimizer; | |||
import org.sonar.batch.index.SourcePersister; | |||
import org.sonar.batch.local.DryRunDatabase; | |||
import org.sonar.core.i18n.I18nManager; | |||
import org.sonar.core.i18n.RuleI18nManager; | |||
import org.sonar.core.metric.CacheMetricFinder; | |||
import org.sonar.core.notification.DefaultNotificationManager; | |||
import org.sonar.core.persistence.DaoUtils; | |||
import org.sonar.core.persistence.DatabaseVersion; | |||
import org.sonar.core.persistence.MyBatis; | |||
import org.sonar.core.rule.CacheRuleFinder; | |||
import org.sonar.core.user.DefaultUserFinder; | |||
import org.sonar.jpa.dao.MeasuresDao; | |||
import org.sonar.jpa.session.DefaultDatabaseConnector; | |||
import org.sonar.jpa.session.JpaDatabaseSession; | |||
/** | |||
* Level-2 components. Connected to database. | |||
@@ -55,6 +65,17 @@ public class BatchModule extends Module { | |||
@Override | |||
protected void configure() { | |||
registerCoreComponents(); | |||
registerDatabaseComponents(); | |||
registerBatchExtensions(); | |||
} | |||
private void registerCoreComponents() { | |||
container.addSingleton(EmailSettings.class); | |||
container.addSingleton(I18nManager.class); | |||
container.addSingleton(RuleI18nManager.class); | |||
container.addSingleton(ProjectExclusions.class); | |||
container.addSingleton(ProjectReactorReady.class); | |||
container.addSingleton(ProjectTree.class); | |||
container.addSingleton(ProjectConfigurator.class); | |||
container.addSingleton(DefaultResourceCreationLock.class); | |||
@@ -82,12 +103,29 @@ public class BatchModule extends Module { | |||
container.addSingleton(DefaultUserFinder.class); | |||
container.addSingleton(ResourceTypes.class); | |||
container.addSingleton(MetricProvider.class); | |||
addBatchExtensions(); | |||
} | |||
private void addBatchExtensions() { | |||
private void registerDatabaseComponents() { | |||
container.addSingleton(JdbcDriverHolder.class); | |||
container.addSingleton(DryRunDatabase.class); | |||
container.addSingleton(BatchDatabase.class); | |||
container.addSingleton(MyBatis.class); | |||
container.addSingleton(DatabaseVersion.class); | |||
container.addSingleton(DatabaseBatchCompatibility.class); | |||
for (Class daoClass : DaoUtils.getDaoClasses()) { | |||
container.addSingleton(daoClass); | |||
} | |||
// hibernate | |||
container.addSingleton(DefaultDatabaseConnector.class); | |||
container.addSingleton(JpaDatabaseSession.class); | |||
container.addSingleton(BatchDatabaseSessionFactory.class); | |||
container.addSingleton(BatchDatabaseSettingsLoader.class); | |||
} | |||
private void registerBatchExtensions() { | |||
ExtensionInstaller installer = container.getComponentByType(ExtensionInstaller.class); | |||
installer.install(container, InstantiationStrategy.BATCH); | |||
installer.install(container, InstantiationStrategy.PER_BATCH); | |||
} | |||
@Override |
@@ -30,6 +30,7 @@ import org.sonar.api.Plugin; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.platform.PluginMetadata; | |||
import org.sonar.api.platform.PluginRepository; | |||
import org.sonar.batch.config.BootstrapSettings; | |||
import org.sonar.core.plugins.PluginClassloaders; | |||
import org.sonar.core.plugins.PluginInstaller; | |||
import org.sonar.core.plugins.RemotePlugin; |
@@ -21,25 +21,13 @@ package org.sonar.batch.bootstrap; | |||
import org.apache.commons.configuration.PropertiesConfiguration; | |||
import org.sonar.api.batch.bootstrap.ProjectReactor; | |||
import org.sonar.api.config.EmailSettings; | |||
import org.sonar.api.utils.HttpDownloader; | |||
import org.sonar.api.utils.UriReader; | |||
import org.sonar.batch.FakeMavenPluginExecutor; | |||
import org.sonar.batch.MavenPluginExecutor; | |||
import org.sonar.batch.ServerMetadata; | |||
import org.sonar.batch.config.BatchDatabaseSettingsLoader; | |||
import org.sonar.batch.config.BootstrapSettings; | |||
import org.sonar.batch.local.DryRunDatabase; | |||
import org.sonar.batch.local.DryRunExporter; | |||
import org.sonar.core.config.Logback; | |||
import org.sonar.core.i18n.I18nManager; | |||
import org.sonar.core.i18n.RuleI18nManager; | |||
import org.sonar.core.persistence.DaoUtils; | |||
import org.sonar.core.persistence.DatabaseVersion; | |||
import org.sonar.core.persistence.MyBatis; | |||
import org.sonar.jpa.session.DatabaseSessionProvider; | |||
import org.sonar.jpa.session.DefaultDatabaseConnector; | |||
import org.sonar.jpa.session.ThreadLocalDatabaseSessionFactory; | |||
import org.sonar.wsclient.Sonar; | |||
/** | |||
@@ -72,40 +60,14 @@ public class BootstrapModule extends Module { | |||
container.addSingleton(HttpDownloader.class); | |||
container.addSingleton(UriReader.class); | |||
container.addSingleton(PluginDownloader.class); | |||
container.addSingleton(EmailSettings.class); | |||
container.addSingleton(I18nManager.class); | |||
container.addSingleton(RuleI18nManager.class); | |||
for (Object component : boostrapperComponents) { | |||
if (component != null) { | |||
container.addSingleton(component); | |||
} | |||
} | |||
container.addSingleton(BootstrapExtensionExecutor.class); | |||
if (!isMavenPluginExecutorRegistered()) { | |||
container.addSingleton(FakeMavenPluginExecutor.class); | |||
} | |||
addDatabaseComponents(); | |||
} | |||
private void addDatabaseComponents() { | |||
container.addSingleton(JdbcDriverHolder.class); | |||
container.addSingleton(DryRunDatabase.class); | |||
// mybatis | |||
container.addSingleton(BatchDatabase.class); | |||
container.addSingleton(MyBatis.class); | |||
container.addSingleton(DatabaseVersion.class); | |||
container.addSingleton(DatabaseBatchCompatibility.class); | |||
for (Class daoClass : DaoUtils.getDaoClasses()) { | |||
container.addSingleton(daoClass); | |||
} | |||
// hibernate | |||
container.addSingleton(DefaultDatabaseConnector.class); | |||
container.addSingleton(ThreadLocalDatabaseSessionFactory.class); | |||
container.addPicoAdapter(new DatabaseSessionProvider()); | |||
container.addSingleton(BatchDatabaseSettingsLoader.class); | |||
} | |||
boolean isMavenPluginExecutorRegistered() { |
@@ -27,11 +27,11 @@ import org.sonar.api.PropertyType; | |||
import org.sonar.api.config.Settings; | |||
@Properties({ | |||
@Property(key = "sonar.dryRun", defaultValue = "false", name = "Dry Run", type = PropertyType.BOOLEAN), | |||
@Property(key = "sonar.dryRun.export.path", defaultValue = "dryRun.json", name = "Dry Run Results Export File", type = PropertyType.STRING) | |||
@Property(key = "sonar.dryRun", defaultValue = "false", name = "Dry Run", type = PropertyType.BOOLEAN, global = false, project = false), | |||
@Property(key = "sonar.dryRun.export.path", defaultValue = "dryRun.json", name = "Dry Run Results Export File", type = PropertyType.STRING, global = false, project = false) | |||
}) | |||
public class DryRun implements BatchComponent { | |||
private final Settings settings; | |||
private Settings settings; | |||
public DryRun(Settings settings) { | |||
this.settings = settings; |
@@ -98,7 +98,7 @@ public class ExtensionInstaller implements BatchComponent { | |||
* Example : C# plugin adds sub-projects at runtime, even if they are not defined in root pom. | |||
*/ | |||
static boolean isMavenExtensionOnEmulatedMavenProject(Object extension, String instantiationStrategy, ComponentContainer container) { | |||
if (InstantiationStrategy.PROJECT.equals(instantiationStrategy) && ExtensionUtils.isMavenExtensionOnly(extension)) { | |||
if (InstantiationStrategy.PER_PROJECT.equals(instantiationStrategy) && ExtensionUtils.isMavenExtensionOnly(extension)) { | |||
Project project = container.getComponentByType(Project.class); | |||
return project!=null && project.getPom()==null; | |||
} |
@@ -22,11 +22,11 @@ package org.sonar.batch.bootstrap; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.BatchExtension; | |||
import org.sonar.api.Extension; | |||
import org.sonar.api.batch.DryRunIncompatible; | |||
import org.sonar.api.batch.InstantiationStrategy; | |||
import org.sonar.api.batch.SupportedEnvironment; | |||
import org.sonar.api.utils.AnnotationUtils; | |||
import org.sonar.batch.bootstrapper.EnvironmentInformation; | |||
import org.sonar.core.NotDryRun; | |||
final class ExtensionUtils { | |||
@@ -39,7 +39,7 @@ final class ExtensionUtils { | |||
if (annotation != null) { | |||
return strategy.equals(annotation.value()); | |||
} | |||
return InstantiationStrategy.PROJECT.equals(strategy); | |||
return InstantiationStrategy.PER_PROJECT.equals(strategy); | |||
} | |||
static boolean isBatchExtension(Object extension) { | |||
@@ -60,7 +60,7 @@ final class ExtensionUtils { | |||
} | |||
static boolean supportsDryRun(Object extension) { | |||
return AnnotationUtils.getAnnotation(extension, NotDryRun.class) == null; | |||
return AnnotationUtils.getAnnotation(extension, DryRunIncompatible.class) == null; | |||
} | |||
static boolean isMavenExtensionOnly(Object extension) { |
@@ -83,11 +83,11 @@ public class JdbcDriverHolder { | |||
} | |||
/** | |||
* This method automatically invoked by PicoContainer and deregisters JDBC drivers, which were forgotten. | |||
* This method automatically invoked by PicoContainer and unregisters JDBC drivers, which were forgotten. | |||
* <p> | |||
* Dynamically loaded JDBC drivers can not be simply used and this is a well known problem of {@link java.sql.DriverManager}, | |||
* so <a href="http://stackoverflow.com/questions/288828/how-to-use-a-jdbc-driver-from-an-arbitrary-location">workaround is to use proxy</a>. | |||
* However DriverManager also contains memory leak, thus not only proxy, but also original driver must be deregistered, | |||
* However DriverManager also contains memory leak, thus not only proxy, but also original driver must be unregistered, | |||
* otherwise our class loader would be kept in memory. | |||
* </p> | |||
* <p> |
@@ -63,7 +63,8 @@ public class JdbcLeakPrevention { | |||
Set<Driver> registeredDrivers = new HashSet<Driver>(); | |||
Enumeration<Driver> drivers = DriverManager.getDrivers(); | |||
while (drivers.hasMoreElements()) { | |||
registeredDrivers.add(drivers.nextElement()); | |||
Driver driver = drivers.nextElement(); | |||
registeredDrivers.add(driver); | |||
} | |||
return registeredDrivers; | |||
} |
@@ -30,7 +30,7 @@ import org.sonar.api.measures.Metrics; | |||
import java.util.List; | |||
@InstantiationStrategy(InstantiationStrategy.BATCH) | |||
@InstantiationStrategy(InstantiationStrategy.PER_BATCH) | |||
public class MetricProvider extends ExtensionProvider implements BatchExtension { | |||
private Metrics[] factories; |
@@ -25,6 +25,7 @@ import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.api.BatchComponent; | |||
import org.sonar.api.batch.InstantiationStrategy; | |||
import org.sonar.api.batch.bootstrap.ProjectBuilder; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.bootstrap.ProjectReactor; | |||
import org.sonar.api.config.Settings; | |||
@@ -34,7 +35,6 @@ import org.sonar.api.config.Settings; | |||
* | |||
* @since 2.12 | |||
*/ | |||
@InstantiationStrategy(InstantiationStrategy.BOOTSTRAP) | |||
public class ProjectExclusions implements BatchComponent { | |||
private static final Logger LOG = LoggerFactory.getLogger(ProjectExclusions.class); | |||
@@ -42,11 +42,15 @@ public class ProjectExclusions implements BatchComponent { | |||
private Settings settings; | |||
private ProjectReactor reactor; | |||
public ProjectExclusions(Settings settings, ProjectReactor reactor) { | |||
public ProjectExclusions(Settings settings, ProjectReactor reactor, ProjectBuilder[] projectBuilders) { | |||
this.settings = settings; | |||
this.reactor = reactor; | |||
} | |||
public ProjectExclusions(Settings settings, ProjectReactor reactor) { | |||
this(settings, reactor, new ProjectBuilder[0]); | |||
} | |||
public void start() { | |||
LOG.info("Apply project exclusions"); | |||
for (ProjectDefinition project : reactor.getProjects()) { |
@@ -41,7 +41,7 @@ import org.sonar.batch.config.ProjectSettings; | |||
import org.sonar.batch.config.UnsupportedProperties; | |||
import org.sonar.batch.events.EventBus; | |||
import org.sonar.batch.index.DefaultIndex; | |||
import org.sonar.batch.index.DefaultResourcePersister; | |||
import org.sonar.batch.index.ResourcePersister; | |||
import org.sonar.batch.local.DryRunExporter; | |||
import org.sonar.batch.phases.Phases; | |||
import org.sonar.batch.phases.PhasesTimeProfiler; | |||
@@ -61,11 +61,16 @@ public class ProjectModule extends Module { | |||
protected void configure() { | |||
logSettings(); | |||
addCoreComponents(); | |||
addProjectComponents(); | |||
addProjectPluginExtensions(); | |||
addPluginExtensions(); | |||
} | |||
private void addProjectComponents() { | |||
private void addCoreComponents() { | |||
container.addSingleton(EventBus.class); | |||
container.addSingleton(Phases.class); | |||
container.addSingleton(PhasesTimeProfiler.class); | |||
for (Class clazz : Phases.getPhaseClasses()) { | |||
container.addSingleton(clazz); | |||
} | |||
ProjectDefinition projectDefinition = container.getComponentByType(ProjectTree.class).getProjectDefinition(project); | |||
container.addSingleton(projectDefinition); | |||
container.addSingleton(project); | |||
@@ -82,7 +87,7 @@ public class ProjectModule extends Module { | |||
container.addSingleton(RulesDao.class); | |||
// the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor) | |||
container.addSingleton(container.getComponentByType(DefaultResourcePersister.class).getSnapshot(project)); | |||
container.addSingleton(container.getComponentByType(ResourcePersister.class).getSnapshot(project)); | |||
container.addSingleton(TimeMachineConfiguration.class); | |||
container.addSingleton(org.sonar.api.database.daos.MeasuresDao.class); | |||
@@ -98,18 +103,9 @@ public class ProjectModule extends Module { | |||
container.addPicoAdapter(new ProfileProvider()); | |||
} | |||
private void addCoreComponents() { | |||
container.addSingleton(EventBus.class); | |||
container.addSingleton(Phases.class); | |||
container.addSingleton(PhasesTimeProfiler.class); | |||
for (Class clazz : Phases.getPhaseClasses()) { | |||
container.addSingleton(clazz); | |||
} | |||
} | |||
private void addProjectPluginExtensions() { | |||
private void addPluginExtensions() { | |||
ExtensionInstaller installer = container.getComponentByType(ExtensionInstaller.class); | |||
installer.install(container, InstantiationStrategy.PROJECT); | |||
installer.install(container, InstantiationStrategy.PER_PROJECT); | |||
} | |||
private void logSettings() { | |||
@@ -124,9 +120,9 @@ public class ProjectModule extends Module { | |||
protected void doStart() { | |||
DefaultIndex index = container.getComponentByType(DefaultIndex.class); | |||
index.setCurrentProject(project, | |||
container.getComponentByType(ResourceFilters.class), | |||
container.getComponentByType(ViolationFilters.class), | |||
container.getComponentByType(RulesProfile.class)); | |||
container.getComponentByType(ResourceFilters.class), | |||
container.getComponentByType(ViolationFilters.class), | |||
container.getComponentByType(RulesProfile.class)); | |||
container.getComponentByType(Phases.class).execute(project); | |||
} |
@@ -19,27 +19,29 @@ | |||
*/ | |||
package org.sonar.batch.bootstrap; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.api.batch.InstantiationStrategy; | |||
import org.sonar.api.platform.ComponentContainer; | |||
import org.sonar.api.batch.bootstrap.ProjectBuilder; | |||
public class BootstrapExtensionExecutor { | |||
/** | |||
* Barrier to control the project lifecycle : | |||
* <p/> | |||
* <ul> | |||
* <li>initialize the project configuration by executing ProjectBuilder extensions</li> | |||
* <li>apply sub-project exclusions (sonar.skippedModules, ...)</li> | |||
* <li>---- this barrier ----</li> | |||
* <li>run optional dry run database</li> | |||
* <li>connect to dry-run or remote database</li> | |||
* </ul> | |||
*/ | |||
public class ProjectReactorReady { | |||
private ComponentContainer container; | |||
private ExtensionInstaller installer; | |||
public ProjectReactorReady(ProjectExclusions exclusions, ProjectBuilder[] projectBuilders) { | |||
} | |||
public BootstrapExtensionExecutor(ComponentContainer container, ExtensionInstaller installer) { | |||
this.container = container; | |||
this.installer = installer; | |||
public ProjectReactorReady(ProjectExclusions exclusions) { | |||
this(exclusions, new ProjectBuilder[0]); | |||
} | |||
public void start() { | |||
LoggerFactory.getLogger(BootstrapExtensionExecutor.class).debug("Execute bootstrap extensions"); | |||
ComponentContainer childContainer = container.createChild(); | |||
installer.install(childContainer, InstantiationStrategy.BOOTSTRAP); | |||
childContainer.addSingleton(ProjectExclusions.class); | |||
childContainer.startComponents(); | |||
childContainer.stopComponents(); | |||
container.removeChild(); | |||
} | |||
} |
@@ -27,6 +27,7 @@ import org.sonar.api.config.Settings; | |||
import org.sonar.api.database.DatabaseProperties; | |||
import org.sonar.api.utils.SonarException; | |||
import org.sonar.batch.bootstrap.DryRun; | |||
import org.sonar.batch.bootstrap.ProjectReactorReady; | |||
import org.sonar.batch.bootstrap.ServerClient; | |||
import org.sonar.batch.bootstrap.TempDirectories; | |||
@@ -51,7 +52,9 @@ public class DryRunDatabase implements BatchComponent { | |||
private final TempDirectories tempDirectories; | |||
private final ProjectReactor reactor; | |||
public DryRunDatabase(DryRun dryRun, Settings settings, ServerClient server, TempDirectories tempDirectories, ProjectReactor reactor) { | |||
public DryRunDatabase(DryRun dryRun, Settings settings, ServerClient server, TempDirectories tempDirectories, ProjectReactor reactor, | |||
// project reactor must be completely built | |||
ProjectReactorReady reactorReady) { | |||
this.dryRun = dryRun; | |||
this.settings = settings; | |||
this.server = server; |
@@ -21,18 +21,18 @@ package org.sonar.batch.phases; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.api.BatchComponent; | |||
import org.sonar.api.batch.DryRunIncompatible; | |||
import org.sonar.api.database.DatabaseSession; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.resources.Scopes; | |||
import org.sonar.batch.bootstrap.ServerClient; | |||
import org.sonar.batch.index.ResourcePersister; | |||
import org.sonar.core.NotDryRun; | |||
import javax.persistence.Query; | |||
import java.util.List; | |||
@NotDryRun | |||
@DryRunIncompatible | |||
public class UpdateStatusJob implements BatchComponent { | |||
private DatabaseSession session; |
@@ -19,25 +19,41 @@ | |||
*/ | |||
package org.sonar.batch; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.sonar.api.config.Settings; | |||
import static org.hamcrest.core.Is.is; | |||
import static org.junit.Assert.assertThat; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
public class DefaultResourceCreationLockTest { | |||
Settings settings; | |||
@Before | |||
public void init() { | |||
settings = new Settings(); | |||
} | |||
@Test | |||
public void shouldNotBeLockedAtStartup() { | |||
assertThat(new DefaultResourceCreationLock().isLocked(), is(false)); | |||
assertThat(new DefaultResourceCreationLock(settings).isLocked()).isFalse(); | |||
} | |||
@Test | |||
public void should_fail_if_locked() { | |||
DefaultResourceCreationLock lock = new DefaultResourceCreationLock(settings); | |||
assertThat(lock.isFailWhenLocked()).isFalse(); | |||
lock.setFailWhenLocked(true); | |||
assertThat(lock.isFailWhenLocked()).isTrue(); | |||
} | |||
@Test | |||
public void shouldLock() { | |||
DefaultResourceCreationLock lock = new DefaultResourceCreationLock(); | |||
public void should_lock() { | |||
DefaultResourceCreationLock lock = new DefaultResourceCreationLock(settings); | |||
lock.lock(); | |||
assertThat(lock.isLocked(), is(true)); | |||
assertThat(lock.isLocked()).isTrue(); | |||
lock.unlock(); | |||
assertThat(lock.isLocked(), is(false)); | |||
assertThat(lock.isLocked()).isFalse(); | |||
} | |||
} |
@@ -0,0 +1,36 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2008-2012 SonarSource | |||
* 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.bootstrap; | |||
import org.junit.Test; | |||
import org.sonar.api.database.DatabaseSession; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
public class BatchDatabaseSessionFactoryTest { | |||
@Test | |||
public void getSession() { | |||
DatabaseSession session = mock(DatabaseSession.class); | |||
BatchDatabaseSessionFactory factory = new BatchDatabaseSessionFactory(session); | |||
assertThat(factory.getSession()).isSameAs(session); | |||
} | |||
} |
@@ -21,6 +21,7 @@ package org.sonar.batch.bootstrap; | |||
import org.junit.Test; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.batch.local.DryRunDatabase; | |||
import java.util.Properties; | |||
@@ -30,7 +31,7 @@ import static org.mockito.Mockito.mock; | |||
public class BatchDatabaseTest { | |||
@Test | |||
public void should_init_at_least_two_connections() { | |||
BatchDatabase db = new BatchDatabase(new Settings(), mock(JdbcDriverHolder.class)); | |||
BatchDatabase db = new BatchDatabase(new Settings(), mock(JdbcDriverHolder.class), mock(DryRunDatabase.class)); | |||
Properties props = new Properties(); | |||
db.doCompleteProperties(props); |
@@ -44,7 +44,7 @@ public class BatchModuleTest { | |||
BatchModule module = new BatchModule(); | |||
bootstrapModule.installChild(module); | |||
verify(extensionInstaller).install(any(ComponentContainer.class), eq(InstantiationStrategy.BATCH)); | |||
verify(extensionInstaller).install(any(ComponentContainer.class), eq(InstantiationStrategy.PER_BATCH)); | |||
assertThat(module.container.getComponentByType(MetricProvider.class)).isNotNull(); | |||
} | |||
} |
@@ -1,74 +0,0 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2008-2012 SonarSource | |||
* 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.bootstrap; | |||
import org.junit.Test; | |||
import org.mockito.invocation.InvocationOnMock; | |||
import org.mockito.stubbing.Answer; | |||
import org.picocontainer.Startable; | |||
import org.sonar.api.batch.InstantiationStrategy; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.bootstrap.ProjectReactor; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.platform.ComponentContainer; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
import static org.mockito.Matchers.any; | |||
import static org.mockito.Matchers.eq; | |||
import static org.mockito.Mockito.doAnswer; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verify; | |||
public class BootstrapExtensionExecutorTest { | |||
private ProjectReactor reactor = new ProjectReactor(ProjectDefinition.create().setKey("foo")); | |||
@Test | |||
public void start() { | |||
ComponentContainer container = new ComponentContainer(); | |||
// dependencies required for ProjectExclusions | |||
container.addSingleton(reactor); | |||
container.addSingleton(new Settings()); | |||
// declare a bootstrap component | |||
final Startable bootstrapComponent = mock(Startable.class); | |||
ExtensionInstaller installer = mock(ExtensionInstaller.class); | |||
doAnswer(new Answer() { | |||
public Object answer(InvocationOnMock invocationOnMock) throws Throwable { | |||
ComponentContainer childContainer = (ComponentContainer) invocationOnMock.getArguments()[0]; | |||
childContainer.addSingleton(bootstrapComponent); | |||
return null; | |||
} | |||
}).when(installer).install(any(ComponentContainer.class), eq(InstantiationStrategy.BOOTSTRAP)); | |||
BootstrapExtensionExecutor executor = new BootstrapExtensionExecutor(container, installer); | |||
executor.start(); | |||
// should install bootstrap components into a ephemeral container | |||
verify(installer).install(any(ComponentContainer.class), eq(InstantiationStrategy.BOOTSTRAP)); | |||
verify(bootstrapComponent).start(); | |||
verify(bootstrapComponent).stop(); | |||
// the ephemeral container is destroyed | |||
assertThat(container.getComponentByType(ProjectExclusions.class)).isNull(); | |||
assertThat(container.getChild()).isNull(); | |||
} | |||
} |
@@ -31,6 +31,7 @@ import org.sonar.api.batch.SupportedEnvironment; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.platform.ComponentContainer; | |||
import org.sonar.api.platform.PluginMetadata; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.batch.bootstrapper.EnvironmentInformation; | |||
import java.util.Arrays; | |||
@@ -64,7 +65,7 @@ public class ExtensionInstallerTest { | |||
ComponentContainer container = new ComponentContainer(); | |||
ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("ant", "1.7"), new Settings()); | |||
installer.install(container, InstantiationStrategy.BATCH); | |||
installer.install(container, InstantiationStrategy.PER_BATCH); | |||
assertThat(container.getComponentByType(BatchService.class)).isNotNull(); | |||
assertThat(container.getComponentByType(ProjectService.class)).isNull(); | |||
@@ -78,7 +79,7 @@ public class ExtensionInstallerTest { | |||
ComponentContainer container = new ComponentContainer(); | |||
ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("ant", "1.7"), new Settings()); | |||
installer.install(container, InstantiationStrategy.BATCH); | |||
installer.install(container, InstantiationStrategy.PER_BATCH); | |||
assertThat(container.getComponentByType(BatchService.class)).isNotNull(); | |||
assertThat(container.getComponentByType(ProjectService.class)).isNull(); | |||
@@ -94,13 +95,29 @@ public class ExtensionInstallerTest { | |||
ComponentContainer container = new ComponentContainer(); | |||
ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("ant", "1.7"), new Settings()); | |||
installer.install(container, InstantiationStrategy.PROJECT); | |||
installer.install(container, InstantiationStrategy.PER_PROJECT); | |||
assertThat(container.getComponentByType(MavenService.class)).isNull(); | |||
assertThat(container.getComponentByType(BuildToolService.class)).isNotNull(); | |||
} | |||
@InstantiationStrategy(InstantiationStrategy.BATCH) | |||
@Test | |||
public void should_disable_maven_extensions_if_virtual_module_in_maven_project() { | |||
Project project = mock(Project.class); | |||
when(project.getPom()).thenReturn(null); | |||
BatchPluginRepository pluginRepository = mock(BatchPluginRepository.class); | |||
when(pluginRepository.getPluginsByMetadata()).thenReturn(newPlugin(MavenService.class)); | |||
ComponentContainer container = new ComponentContainer(); | |||
container.addSingleton(project); | |||
ExtensionInstaller installer = new ExtensionInstaller(pluginRepository, new EnvironmentInformation("maven", "2.2.1"), new Settings()); | |||
installer.install(container, InstantiationStrategy.PER_PROJECT); | |||
assertThat(container.getComponentByType(MavenService.class)).isNull(); | |||
} | |||
@InstantiationStrategy(InstantiationStrategy.PER_BATCH) | |||
public static class BatchService implements BatchExtension { | |||
} | |||
@@ -113,7 +130,7 @@ public class ExtensionInstallerTest { | |||
} | |||
@InstantiationStrategy(InstantiationStrategy.BATCH) | |||
@InstantiationStrategy(InstantiationStrategy.PER_BATCH) | |||
public static class BatchServiceProvider extends ExtensionProvider implements BatchExtension { | |||
@Override |
@@ -22,10 +22,10 @@ package org.sonar.batch.bootstrap; | |||
import org.junit.Test; | |||
import org.sonar.api.BatchExtension; | |||
import org.sonar.api.ServerExtension; | |||
import org.sonar.api.batch.DryRunIncompatible; | |||
import org.sonar.api.batch.InstantiationStrategy; | |||
import org.sonar.api.batch.SupportedEnvironment; | |||
import org.sonar.batch.bootstrapper.EnvironmentInformation; | |||
import org.sonar.core.NotDryRun; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
@@ -33,22 +33,22 @@ public class ExtensionUtilsTest { | |||
@Test | |||
public void shouldBeBatchInstantiationStrategy() { | |||
assertThat(ExtensionUtils.isInstantiationStrategy(BatchService.class, InstantiationStrategy.BATCH)).isTrue(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(new BatchService(), InstantiationStrategy.BATCH)).isTrue(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(ProjectService.class, InstantiationStrategy.BATCH)).isFalse(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(new ProjectService(), InstantiationStrategy.BATCH)).isFalse(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(DefaultService.class, InstantiationStrategy.BATCH)).isFalse(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(new DefaultService(), InstantiationStrategy.BATCH)).isFalse(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(BatchService.class, InstantiationStrategy.PER_BATCH)).isTrue(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(new BatchService(), InstantiationStrategy.PER_BATCH)).isTrue(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(ProjectService.class, InstantiationStrategy.PER_BATCH)).isFalse(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(new ProjectService(), InstantiationStrategy.PER_BATCH)).isFalse(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(DefaultService.class, InstantiationStrategy.PER_BATCH)).isFalse(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(new DefaultService(), InstantiationStrategy.PER_BATCH)).isFalse(); | |||
} | |||
@Test | |||
public void shouldBeProjectInstantiationStrategy() { | |||
assertThat(ExtensionUtils.isInstantiationStrategy(BatchService.class, InstantiationStrategy.PROJECT)).isFalse(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(new BatchService(), InstantiationStrategy.PROJECT)).isFalse(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(ProjectService.class, InstantiationStrategy.PROJECT)).isTrue(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(new ProjectService(), InstantiationStrategy.PROJECT)).isTrue(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(DefaultService.class, InstantiationStrategy.PROJECT)).isTrue(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(new DefaultService(), InstantiationStrategy.PROJECT)).isTrue(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(BatchService.class, InstantiationStrategy.PER_PROJECT)).isFalse(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(new BatchService(), InstantiationStrategy.PER_PROJECT)).isFalse(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(ProjectService.class, InstantiationStrategy.PER_PROJECT)).isTrue(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(new ProjectService(), InstantiationStrategy.PER_PROJECT)).isTrue(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(DefaultService.class, InstantiationStrategy.PER_PROJECT)).isTrue(); | |||
assertThat(ExtensionUtils.isInstantiationStrategy(new DefaultService(), InstantiationStrategy.PER_PROJECT)).isTrue(); | |||
} | |||
@Test | |||
@@ -87,12 +87,12 @@ public class ExtensionUtilsTest { | |||
assertThat(ExtensionUtils.supportsDryRun(new PersistentService())).isFalse(); | |||
} | |||
@InstantiationStrategy(InstantiationStrategy.BATCH) | |||
@InstantiationStrategy(InstantiationStrategy.PER_BATCH) | |||
public static class BatchService implements BatchExtension { | |||
} | |||
@InstantiationStrategy(InstantiationStrategy.PROJECT) | |||
@InstantiationStrategy(InstantiationStrategy.PER_PROJECT) | |||
public static class ProjectService implements BatchExtension { | |||
} | |||
@@ -115,7 +115,7 @@ public class ExtensionUtilsTest { | |||
} | |||
@NotDryRun | |||
@DryRunIncompatible | |||
public static class PersistentService implements BatchExtension { | |||
} |
@@ -21,13 +21,16 @@ package org.sonar.batch.bootstrap; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.utils.SonarException; | |||
import org.sonar.core.plugins.RemotePlugin; | |||
import java.io.File; | |||
import java.util.List; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
import static org.mockito.Mockito.doThrow; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.when; | |||
@@ -37,6 +40,9 @@ public class PluginDownloaderTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
@Rule | |||
public ExpectedException thrown = ExpectedException.none(); | |||
@Test | |||
public void should_request_list_of_plugins() { | |||
TempDirectories tempDirs = mock(TempDirectories.class); | |||
@@ -72,4 +78,14 @@ public class PluginDownloaderTest { | |||
verify(server).download("/deploy/plugins/checkstyle/checkstyle-plugin.jar", pluginFile); | |||
verify(server).download("/deploy/plugins/checkstyle/checkstyle-extensions.jar", extFile); | |||
} | |||
@Test | |||
public void should_fail_to_get_plugin_index() throws Exception { | |||
thrown.expect(SonarException.class); | |||
ServerClient server = mock(ServerClient.class); | |||
doThrow(new SonarException()).when(server).request("/deploy/plugins/index.txt"); | |||
new PluginDownloader(mock(TempDirectories.class), server).downloadPluginIndex(); | |||
} | |||
} |
@@ -0,0 +1,72 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2008-2012 SonarSource | |||
* 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.bootstrap; | |||
import org.apache.commons.configuration.PropertiesConfiguration; | |||
import org.junit.Test; | |||
import org.mockito.Matchers; | |||
import org.sonar.api.batch.InstantiationStrategy; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.platform.ComponentContainer; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.api.resources.Resource; | |||
import org.sonar.batch.ProjectTree; | |||
import org.sonar.batch.config.ProjectSettings; | |||
import org.sonar.batch.index.ResourcePersister; | |||
import org.sonar.core.properties.PropertiesDao; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
import static org.mockito.Matchers.any; | |||
import static org.mockito.Matchers.eq; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.when; | |||
public class ProjectModuleTest { | |||
@Test | |||
public void should_register_project_extensions() { | |||
// components injected in the parent container | |||
final Project project = new Project("foo"); | |||
project.setConfiguration(new PropertiesConfiguration()); | |||
final ProjectTree projectTree = mock(ProjectTree.class); | |||
when(projectTree.getProjectDefinition(project)).thenReturn(ProjectDefinition.create()); | |||
final ResourcePersister resourcePersister = mock(ResourcePersister.class); | |||
when(resourcePersister.getSnapshot(Matchers.<Resource>any())).thenReturn(new Snapshot()); | |||
final ExtensionInstaller extensionInstaller = mock(ExtensionInstaller.class); | |||
Module batchModule = new Module() { | |||
@Override | |||
protected void configure() { | |||
container.addSingleton(extensionInstaller); | |||
container.addSingleton(projectTree); | |||
container.addSingleton(resourcePersister); | |||
container.addSingleton(mock(PropertiesDao.class)); | |||
} | |||
}; | |||
batchModule.init(); | |||
ProjectModule projectModule = new ProjectModule(project); | |||
batchModule.installChild(projectModule); | |||
verify(extensionInstaller).install(any(ComponentContainer.class), eq(InstantiationStrategy.PER_PROJECT)); | |||
assertThat(projectModule.container.getComponentByType(ProjectSettings.class)).isNotNull(); | |||
} | |||
} |
@@ -0,0 +1,40 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2008-2012 SonarSource | |||
* 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.bootstrap; | |||
import org.junit.Test; | |||
import org.sonar.api.batch.bootstrap.ProjectBuilder; | |||
import static org.mockito.Mockito.mock; | |||
public class ProjectReactorReadyTest { | |||
@Test | |||
public void should_do_nothing() { | |||
// it's only a barrier | |||
ProjectReactorReady barrier = new ProjectReactorReady(mock(ProjectExclusions.class), new ProjectBuilder[]{mock(ProjectBuilder.class)}); | |||
barrier.start(); | |||
} | |||
@Test | |||
public void project_builders_should_be_optional() { | |||
ProjectReactorReady barrier = new ProjectReactorReady(mock(ProjectExclusions.class)); | |||
barrier.start(); | |||
} | |||
} |
@@ -29,6 +29,7 @@ import org.apache.commons.lang.StringUtils; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.sonar.api.batch.ResourceFilter; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.measures.CoreMetrics; | |||
import org.sonar.api.measures.Measure; | |||
import org.sonar.api.measures.MeasuresFilters; | |||
@@ -60,7 +61,7 @@ public class DefaultIndexTest { | |||
@Before | |||
public void createIndex() { | |||
lock = new DefaultResourceCreationLock(); | |||
lock = new DefaultResourceCreationLock(new Settings()); | |||
MetricFinder metricFinder = mock(MetricFinder.class); | |||
when(metricFinder.findByKey("ncloc")).thenReturn(CoreMetrics.NCLOC); | |||
@@ -29,6 +29,7 @@ import org.sonar.api.config.Settings; | |||
import org.sonar.api.database.DatabaseProperties; | |||
import org.sonar.api.utils.SonarException; | |||
import org.sonar.batch.bootstrap.DryRun; | |||
import org.sonar.batch.bootstrap.ProjectReactorReady; | |||
import org.sonar.batch.bootstrap.ServerClient; | |||
import org.sonar.batch.bootstrap.TempDirectories; | |||
@@ -57,7 +58,7 @@ public class DryRunDatabaseTest { | |||
@Before | |||
public void setUp() { | |||
dryRunDatabase = new DryRunDatabase(dryRun, settings, server, tempDirectories, projectReactor); | |||
dryRunDatabase = new DryRunDatabase(dryRun, settings, server, tempDirectories, projectReactor, mock(ProjectReactorReady.class)); | |||
} | |||
@Test |
@@ -17,7 +17,7 @@ | |||
* License along with Sonar; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.core; | |||
package org.sonar.api.batch; | |||
import java.lang.annotation.ElementType; | |||
import java.lang.annotation.Retention; | |||
@@ -25,11 +25,18 @@ import java.lang.annotation.RetentionPolicy; | |||
import java.lang.annotation.Target; | |||
/** | |||
* Disables component on dry runs. | |||
* This annotation must be used by core modules only. It MUST not be used by external plugins. | |||
* @since 2.9 | |||
* The presence of this annotation on an extension class indicates that the extension | |||
* may be disabled when the dry-run mode is enabled (-Dsonar.dryRun=true). | |||
* It's generally used by the extensions that push data to external systems, for example : | |||
* <ul> | |||
* <li>Send emails</li> | |||
* <li>Create a JIRA issue</li> | |||
* </ul> | |||
* | |||
* | |||
* @since 3.4 | |||
*/ | |||
@Retention(RetentionPolicy.RUNTIME) | |||
@Target(ElementType.TYPE) | |||
public @interface NotDryRun { | |||
public @interface DryRunIncompatible { | |||
} |
@@ -34,32 +34,13 @@ public @interface InstantiationStrategy { | |||
/** | |||
* Shared extension. Lifecycle is the full analysis. | |||
* @deprecated replaced by the constant {@link org.sonar.api.batch.InstantiationStrategy.BATCH} since version 3.4 | |||
*/ | |||
@Deprecated | |||
String PER_BATCH = "PER_BATCH"; | |||
/** | |||
* Created and initialized for each project and sub-project (a project is a module in Maven terminology). | |||
* @deprecated replaced by the constant {@link org.sonar.api.batch.InstantiationStrategy.PROJECT} since version 3.4 | |||
*/ | |||
@Deprecated | |||
String PER_PROJECT = "PER_PROJECT"; | |||
/** | |||
* @since 3.4 | |||
*/ | |||
String BOOTSTRAP = "BOOTSTRAP"; | |||
/** | |||
* @since 3.4 | |||
*/ | |||
String BATCH = "PER_BATCH"; | |||
/** | |||
* @since 3.4 | |||
*/ | |||
String PROJECT = "PER_PROJECT"; | |||
String value(); | |||
} |
@@ -34,7 +34,7 @@ import org.sonar.api.batch.InstantiationStrategy; | |||
* | |||
* @since 2.9 | |||
*/ | |||
@InstantiationStrategy(InstantiationStrategy.BOOTSTRAP) | |||
@InstantiationStrategy(InstantiationStrategy.PER_BATCH) | |||
public abstract class ProjectBuilder implements BatchExtension { | |||
private ProjectReactor reactor; |
@@ -35,7 +35,7 @@ import javax.persistence.*; | |||
*/ | |||
@Table(name = "metrics") | |||
@Entity(name = "Metric") | |||
@InstantiationStrategy(InstantiationStrategy.BATCH) | |||
@InstantiationStrategy(InstantiationStrategy.PER_BATCH) | |||
public class Metric implements ServerExtension, BatchExtension { | |||
/** |
@@ -28,7 +28,7 @@ import java.util.List; | |||
/** | |||
* @since 1.10 | |||
*/ | |||
@InstantiationStrategy(InstantiationStrategy.BATCH) | |||
@InstantiationStrategy(InstantiationStrategy.PER_BATCH) | |||
public interface Metrics extends BatchExtension, ServerExtension { | |||
List<Metric> getMetrics(); | |||
} |
@@ -36,7 +36,7 @@ import java.util.List; | |||
*/ | |||
@Beta | |||
@Immutable | |||
@InstantiationStrategy(InstantiationStrategy.BATCH) | |||
@InstantiationStrategy(InstantiationStrategy.PER_BATCH) | |||
public final class ResourceTypeTree implements BatchExtension, ServerExtension { | |||
private List<ResourceType> types; |