Package org.sonar.batch.mediumtest

Source Code of org.sonar.batch.mediumtest.BatchMediumTester$FakeProjectReferentialsLoader

/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
package org.sonar.batch.mediumtest;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.SonarPlugin;
import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.api.batch.debt.internal.DefaultDebtModel;
import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputPath;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.dependency.Dependency;
import org.sonar.api.batch.sensor.duplication.DuplicationGroup;
import org.sonar.api.batch.sensor.highlighting.TypeOfText;
import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.batch.sensor.symbol.Symbol;
import org.sonar.api.batch.sensor.test.TestCaseCoverage;
import org.sonar.api.batch.sensor.test.TestCaseExecution;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
import org.sonar.api.platform.PluginMetadata;
import org.sonar.batch.bootstrap.PluginsReferential;
import org.sonar.batch.bootstrap.TaskProperties;
import org.sonar.batch.bootstrapper.Batch;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
import org.sonar.batch.dependency.DependencyCache;
import org.sonar.batch.duplication.DuplicationCache;
import org.sonar.batch.highlighting.SyntaxHighlightingData;
import org.sonar.batch.highlighting.SyntaxHighlightingRule;
import org.sonar.batch.index.Cache.Entry;
import org.sonar.batch.index.ComponentDataCache;
import org.sonar.batch.protocol.input.ActiveRule;
import org.sonar.batch.protocol.input.GlobalReferentials;
import org.sonar.batch.protocol.input.ProjectReferentials;
import org.sonar.batch.referential.GlobalReferentialsLoader;
import org.sonar.batch.referential.ProjectReferentialsLoader;
import org.sonar.batch.scan.filesystem.InputPathCache;
import org.sonar.batch.scan2.IssueCache;
import org.sonar.batch.scan2.MeasureCache;
import org.sonar.batch.scan2.ProjectScanContainer;
import org.sonar.batch.scan2.ScanTaskObserver;
import org.sonar.batch.symbol.SymbolData;
import org.sonar.batch.test.TestCaseCoverageCache;
import org.sonar.batch.test.TestCaseExecutionCache;
import org.sonar.core.plugins.DefaultPluginMetadata;
import org.sonar.core.plugins.RemotePlugin;
import org.sonar.core.source.SnapshotDataTypes;

import javax.annotation.CheckForNull;

import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
* Main utility class for writing batch medium tests.
*
*/
public class BatchMediumTester {

  private Batch batch;

  public static BatchMediumTesterBuilder builder() {
    return new BatchMediumTesterBuilder().registerCoreMetrics();
  }

  public static class BatchMediumTesterBuilder {
    private final FakeGlobalReferentialsLoader globalRefProvider = new FakeGlobalReferentialsLoader();
    private final FakeProjectReferentialsLoader projectRefProvider = new FakeProjectReferentialsLoader();
    private final FakePluginsReferential pluginsReferential = new FakePluginsReferential();
    private final Map<String, String> bootstrapProperties = new HashMap<String, String>();

    public BatchMediumTester build() {
      return new BatchMediumTester(this);
    }

    public BatchMediumTesterBuilder registerPlugin(String pluginKey, File location) {
      pluginsReferential.addPlugin(pluginKey, location);
      return this;
    }

    public BatchMediumTesterBuilder registerPlugin(String pluginKey, SonarPlugin instance) {
      pluginsReferential.addPlugin(pluginKey, instance);
      return this;
    }

    public BatchMediumTesterBuilder registerCoreMetrics() {
      for (Metric<?> m : CoreMetrics.getMetrics()) {
        registerMetric(m);
      }
      return this;
    }

    public BatchMediumTesterBuilder registerMetric(Metric<?> metric) {
      globalRefProvider.add(metric);
      return this;
    }

    public BatchMediumTesterBuilder addQProfile(String language, String name) {
      projectRefProvider.addQProfile(language, name);
      return this;
    }

    public BatchMediumTesterBuilder addDefaultQProfile(String language, String name) {
      addQProfile(language, name);
      globalRefProvider.globalSettings().put("sonar.profile." + language, name);
      return this;
    }

    public BatchMediumTesterBuilder bootstrapProperties(Map<String, String> props) {
      bootstrapProperties.putAll(props);
      return this;
    }

    public BatchMediumTesterBuilder activateRule(ActiveRule activeRule) {
      projectRefProvider.addActiveRule(activeRule);
      return this;
    }

  }

  public void start() {
    batch.start();
  }

  public void stop() {
    batch.stop();
  }

  private BatchMediumTester(BatchMediumTesterBuilder builder) {
    batch = Batch.builder()
      .setEnableLoggingConfiguration(true)
      .addComponents(
        new EnvironmentInformation("mediumTest", "1.0"),
        builder.pluginsReferential,
        builder.globalRefProvider,
        builder.projectRefProvider,
        new DefaultDebtModel())
      .setBootstrapProperties(builder.bootstrapProperties)
      .build();
  }

  public TaskBuilder newTask() {
    return new TaskBuilder(this);
  }

  public TaskBuilder newScanTask(File sonarProps) {
    Properties prop = new Properties();
    FileReader reader = null;
    try {
      reader = new FileReader(sonarProps);
      prop.load(reader);
    } catch (Exception e) {
      throw new IllegalStateException("Unable to read configuration file", e);
    } finally {
      if (reader != null) {
        IOUtils.closeQuietly(reader);
      }
    }
    TaskBuilder builder = new TaskBuilder(this);
    builder.property("sonar.task", "scan");
    builder.property("sonar.projectBaseDir", sonarProps.getParentFile().getAbsolutePath());
    for (Map.Entry entry : prop.entrySet()) {
      builder.property(entry.getKey().toString(), entry.getValue().toString());
    }
    return builder;
  }

  public static class TaskBuilder {
    private final Map<String, String> taskProperties = new HashMap<String, String>();
    private BatchMediumTester tester;

    public TaskBuilder(BatchMediumTester tester) {
      this.tester = tester;
    }

    public TaskResult start() {
      TaskResult result = new TaskResult();
      tester.batch.executeTask(taskProperties,
        result
        );
      return result;
    }

    public TaskBuilder properties(Map<String, String> props) {
      taskProperties.putAll(props);
      return this;
    }

    public TaskBuilder property(String key, String value) {
      taskProperties.put(key, value);
      return this;
    }
  }

  public static class TaskResult implements ScanTaskObserver {

    private static final Logger LOG = LoggerFactory.getLogger(BatchMediumTester.TaskResult.class);

    private List<Issue> issues = new ArrayList<Issue>();
    private List<Measure> measures = new ArrayList<Measure>();
    private Map<String, List<DuplicationGroup>> duplications = new HashMap<String, List<DuplicationGroup>>();
    private Map<String, InputFile> inputFiles = new HashMap<String, InputFile>();
    private Map<String, InputDir> inputDirs = new HashMap<String, InputDir>();
    private Map<InputFile, SyntaxHighlightingData> highlightingPerFile = new HashMap<InputFile, SyntaxHighlightingData>();
    private Map<InputFile, SymbolData> symbolTablePerFile = new HashMap<InputFile, SymbolData>();
    private Map<String, Map<String, TestCaseExecution>> testCasesPerFile = new HashMap<String, Map<String, TestCaseExecution>>();
    private Map<String, Map<String, Map<String, List<Integer>>>> coveragePerTest = new HashMap<String, Map<String, Map<String, List<Integer>>>>();
    private Map<String, Map<String, Integer>> dependencies = new HashMap<String, Map<String, Integer>>();

    @Override
    public void scanTaskCompleted(ProjectScanContainer container) {
      LOG.info("Store analysis results in memory for later assertions in medium test");
      for (Issue issue : container.getComponentByType(IssueCache.class).all()) {
        issues.add(issue);
      }

      for (DefaultMeasure<?> measure : container.getComponentByType(MeasureCache.class).all()) {
        measures.add(measure);
      }

      storeFs(container);
      storeComponentData(container);
      storeDuplication(container);
      storeTestCases(container);
      storeCoveragePerTest(container);
      storeDependencies(container);

    }

    private void storeCoveragePerTest(ProjectScanContainer container) {
      TestCaseCoverageCache testCaseCoverageCache = container.getComponentByType(TestCaseCoverageCache.class);
      for (Entry<TestCaseCoverage> entry : testCaseCoverageCache.entries()) {
        String testFileKey = entry.key()[0].toString();
        if (!coveragePerTest.containsKey(testFileKey)) {
          coveragePerTest.put(testFileKey, new HashMap<String, Map<String, List<Integer>>>());
        }
        String testName = entry.key()[1].toString();
        if (!coveragePerTest.get(testFileKey).containsKey(testName)) {
          coveragePerTest.get(testFileKey).put(testName, new HashMap<String, List<Integer>>());
        }
        TestCaseCoverage value = entry.value();
        coveragePerTest.get(testFileKey).get(testName).put(entry.key()[2].toString(), value != null ? value.coveredLines() : null);
      }
    }

    private void storeTestCases(ProjectScanContainer container) {
      TestCaseExecutionCache testCaseCache = container.getComponentByType(TestCaseExecutionCache.class);
      for (Entry<TestCaseExecution> entry : testCaseCache.entries()) {
        String effectiveKey = entry.key()[0].toString();
        if (!testCasesPerFile.containsKey(effectiveKey)) {
          testCasesPerFile.put(effectiveKey, new HashMap<String, TestCaseExecution>());
        }
        testCasesPerFile.get(effectiveKey).put(entry.value().name(), entry.value());
      }
    }

    private void storeDuplication(ProjectScanContainer container) {
      DuplicationCache duplicationCache = container.getComponentByType(DuplicationCache.class);
      for (Entry<List<DuplicationGroup>> entry : duplicationCache.entries()) {
        String effectiveKey = entry.key()[0].toString();
        duplications.put(effectiveKey, entry.value());
      }
    }

    private void storeComponentData(ProjectScanContainer container) {
      ComponentDataCache componentDataCache = container.getComponentByType(ComponentDataCache.class);
      for (InputFile file : inputFiles.values()) {
        SyntaxHighlightingData highlighting = componentDataCache.getData(((DefaultInputFile) file).key(), SnapshotDataTypes.SYNTAX_HIGHLIGHTING);
        if (highlighting != null) {
          highlightingPerFile.put(file, highlighting);
        }
        SymbolData symbolTable = componentDataCache.getData(((DefaultInputFile) file).key(), SnapshotDataTypes.SYMBOL_HIGHLIGHTING);
        if (symbolTable != null) {
          symbolTablePerFile.put(file, symbolTable);
        }
      }
    }

    private void storeFs(ProjectScanContainer container) {
      InputPathCache inputFileCache = container.getComponentByType(InputPathCache.class);
      for (InputPath inputPath : inputFileCache.all()) {
        if (inputPath instanceof InputFile) {
          inputFiles.put(inputPath.relativePath(), (InputFile) inputPath);
        } else {
          inputDirs.put(inputPath.relativePath(), (InputDir) inputPath);
        }
      }
    }

    private void storeDependencies(ProjectScanContainer container) {
      DependencyCache dependencyCache = container.getComponentByType(DependencyCache.class);
      for (Entry<Dependency> entry : dependencyCache.entries()) {
        String fromKey = entry.key()[1].toString();
        String toKey = entry.key()[2].toString();
        if (!dependencies.containsKey(fromKey)) {
          dependencies.put(fromKey, new HashMap<String, Integer>());
        }
        dependencies.get(fromKey).put(toKey, entry.value().weight());
      }
    }

    public List<Issue> issues() {
      return issues;
    }

    public List<Measure> measures() {
      return measures;
    }

    public Collection<InputFile> inputFiles() {
      return inputFiles.values();
    }

    @CheckForNull
    public InputFile inputFile(String relativePath) {
      return inputFiles.get(relativePath);
    }

    public Collection<InputDir> inputDirs() {
      return inputDirs.values();
    }

    @CheckForNull
    public InputDir inputDir(String relativePath) {
      return inputDirs.get(relativePath);
    }

    public List<DuplicationGroup> duplicationsFor(InputFile inputFile) {
      return duplications.get(((DefaultInputFile) inputFile).key());
    }

    public Collection<TestCaseExecution> testCasesFor(InputFile inputFile) {
      String key = ((DefaultInputFile) inputFile).key();
      if (testCasesPerFile.containsKey(key)) {
        return testCasesPerFile.get(key).values();
      } else {
        return Collections.emptyList();
      }
    }

    public TestCaseExecution testCase(InputFile inputFile, String testCaseName) {
      return testCasesPerFile.get(((DefaultInputFile) inputFile).key()).get(testCaseName);
    }

    public List<Integer> coveragePerTest(InputFile testFile, String testCaseName, InputFile mainFile) {
      String testKey = ((DefaultInputFile) testFile).key();
      String mainKey = ((DefaultInputFile) mainFile).key();
      if (coveragePerTest.containsKey(testKey) && coveragePerTest.get(testKey).containsKey(testCaseName) && coveragePerTest.get(testKey).get(testCaseName).containsKey(mainKey)) {
        return coveragePerTest.get(testKey).get(testCaseName).get(mainKey);
      } else {
        return Collections.emptyList();
      }
    }

    /**
     * Get highlighting types at a given position in an inputfile
     * @param charIndex 0-based offset in file
     */
    public List<TypeOfText> highlightingTypeFor(InputFile file, int charIndex) {
      SyntaxHighlightingData syntaxHighlightingData = highlightingPerFile.get(file);
      if (syntaxHighlightingData == null) {
        return Collections.emptyList();
      }
      List<TypeOfText> result = new ArrayList<TypeOfText>();
      for (SyntaxHighlightingRule sortedRule : syntaxHighlightingData.syntaxHighlightingRuleSet()) {
        if (sortedRule.getStartPosition() <= charIndex && sortedRule.getEndPosition() > charIndex) {
          result.add(sortedRule.getTextType());
        }
      }
      return result;
    }

    /**
     * Get list of all positions of a symbol in an inputfile
     * @param symbolStartOffset 0-based start offset for the symbol in file
     * @param symbolEndOffset 0-based end offset for the symbol in file
     */
    @CheckForNull
    public Set<Integer> symbolReferencesFor(InputFile file, int symbolStartOffset, int symbolEndOffset) {
      SymbolData data = symbolTablePerFile.get(file);
      if (data == null) {
        return null;
      }
      for (Symbol symbol : data.referencesBySymbol().keySet()) {
        if (symbol.getDeclarationStartOffset() == symbolStartOffset && symbol.getDeclarationEndOffset() == symbolEndOffset) {
          return data.referencesBySymbol().get(symbol);
        }
      }
      return null;
    }

    /**
     * @return null if no dependency else return dependency weight.
     */
    @CheckForNull
    public Integer dependencyWeight(InputFile from, InputFile to) {
      String fromKey = ((DefaultInputFile) from).key();
      String toKey = ((DefaultInputFile) to).key();
      return dependencies.containsKey(fromKey) ? dependencies.get(fromKey).get(toKey) : null;
    }
  }

  private static class FakeGlobalReferentialsLoader implements GlobalReferentialsLoader {

    private int metricId = 1;

    private GlobalReferentials ref = new GlobalReferentials();

    @Override
    public GlobalReferentials load() {
      return ref;
    }

    public Map<String, String> globalSettings() {
      return ref.globalSettings();
    }

    public FakeGlobalReferentialsLoader add(Metric metric) {
      Boolean optimizedBestValue = metric.isOptimizedBestValue();
      ref.metrics().add(new org.sonar.batch.protocol.input.Metric(metricId,
        metric.key(),
        metric.getType().name(),
        metric.getDescription(),
        metric.getDirection(),
        metric.getName(),
        metric.getQualitative(),
        metric.getUserManaged(),
        metric.getWorstValue(),
        metric.getBestValue(),
        optimizedBestValue != null ? optimizedBestValue : false));
      metricId++;
      return this;
    }
  }

  private static class FakeProjectReferentialsLoader implements ProjectReferentialsLoader {

    private ProjectReferentials ref = new ProjectReferentials();

    @Override
    public ProjectReferentials load(ProjectReactor reactor, TaskProperties taskProperties) {
      return ref;
    }

    public FakeProjectReferentialsLoader addQProfile(String language, String name) {
      ref.addQProfile(new org.sonar.batch.protocol.input.QProfile(name, name, language, new Date()));
      return this;
    }

    public FakeProjectReferentialsLoader addActiveRule(ActiveRule activeRule) {
      ref.addActiveRule(activeRule);
      return this;
    }
  }

  private static class FakePluginsReferential implements PluginsReferential {

    private List<RemotePlugin> pluginList = new ArrayList<RemotePlugin>();
    private Map<RemotePlugin, File> pluginFiles = new HashMap<RemotePlugin, File>();
    Map<PluginMetadata, SonarPlugin> localPlugins = new HashMap<PluginMetadata, SonarPlugin>();

    @Override
    public List<RemotePlugin> pluginList() {
      return pluginList;
    }

    @Override
    public File pluginFile(RemotePlugin remote) {
      return pluginFiles.get(remote);
    }

    public FakePluginsReferential addPlugin(String pluginKey, File location) {
      RemotePlugin plugin = new RemotePlugin(pluginKey, false);
      pluginList.add(plugin);
      pluginFiles.put(plugin, location);
      return this;
    }

    public FakePluginsReferential addPlugin(String pluginKey, SonarPlugin pluginInstance) {
      localPlugins.put(DefaultPluginMetadata.create(pluginKey), pluginInstance);
      return this;
    }

    @Override
    public Map<PluginMetadata, SonarPlugin> localPlugins() {
      return localPlugins;
    }

  }

}
TOP

Related Classes of org.sonar.batch.mediumtest.BatchMediumTester$FakeProjectReferentialsLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.