/* * SonarQube * Copyright (C) 2009-2017 SonarSource SA * mailto:info AT sonarsource DOT com * * This program 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. * * This program 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.scanner.report; import com.google.common.collect.ImmutableMap; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Properties; import org.apache.commons.io.FileUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.utils.System2; import org.sonar.api.utils.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; import org.sonar.core.platform.PluginInfo; import org.sonar.scanner.bootstrap.GlobalSettings; import org.sonar.scanner.bootstrap.ScannerPluginRepository; import org.sonar.scanner.protocol.output.ScannerReportWriter; import org.sonar.scanner.repository.ProjectRepositories; import org.sonar.updatecenter.common.Version; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; public class AnalysisContextReportPublisherTest { private static final String BIZ = "BIZ"; private static final String FOO = "FOO"; private static final String SONAR_SKIP = "sonar.skip"; private static final String COM_FOO = "com.foo"; @Rule public LogTester logTester = new LogTester(); @Rule public TemporaryFolder temp = new TemporaryFolder(); private ScannerPluginRepository pluginRepo = mock(ScannerPluginRepository.class); private AnalysisContextReportPublisher publisher; private AnalysisMode analysisMode = mock(AnalysisMode.class); private System2 system2; private ProjectRepositories projectRepos; private GlobalSettings globalSettings; @Before public void prepare() throws Exception { logTester.setLevel(LoggerLevel.INFO); system2 = mock(System2.class); when(system2.properties()).thenReturn(new Properties()); projectRepos = mock(ProjectRepositories.class); globalSettings = mock(GlobalSettings.class); publisher = new AnalysisContextReportPublisher(analysisMode, pluginRepo, system2, projectRepos, globalSettings); } @Test public void shouldOnlyDumpPluginsByDefault() throws Exception { when(pluginRepo.getPluginInfos()).thenReturn(Arrays.asList(new PluginInfo("xoo").setName("Xoo").setVersion(Version.create("1.0")))); ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); publisher.init(writer); assertThat(writer.getFileStructure().analysisLog()).exists(); assertThat(FileUtils.readFileToString(writer.getFileStructure().analysisLog())).contains("Xoo 1.0 (xoo)"); verifyZeroInteractions(system2); } @Test public void shouldNotDumpInIssuesMode() throws Exception { when(analysisMode.isIssues()).thenReturn(true); ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); publisher.init(writer); publisher.dumpModuleSettings(ProjectDefinition.create().setProperty("sonar.projectKey", "foo")); assertThat(writer.getFileStructure().analysisLog()).doesNotExist(); } @Test public void dumpServerSideGlobalProps() throws Exception { logTester.setLevel(LoggerLevel.DEBUG); ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); when(globalSettings.getServerSideSettings()).thenReturn(ImmutableMap.of(COM_FOO, "bar", SONAR_SKIP, "true")); publisher.init(writer); String content = FileUtils.readFileToString(writer.getFileStructure().analysisLog()); assertThat(content).containsOnlyOnce(COM_FOO); assertThat(content).containsOnlyOnce(SONAR_SKIP); } @Test public void dumpServerSideModuleProps() throws Exception { logTester.setLevel(LoggerLevel.DEBUG); ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); publisher.init(writer); when(projectRepos.moduleExists("foo")).thenReturn(true); when(projectRepos.settings("foo")).thenReturn(ImmutableMap.of(COM_FOO, "bar", SONAR_SKIP, "true")); publisher.dumpModuleSettings(ProjectDefinition.create() .setProperty("sonar.projectKey", "foo")); String content = FileUtils.readFileToString(writer.getFileStructure().analysisLog()); assertThat(content).doesNotContain(COM_FOO); assertThat(content).containsOnlyOnce(SONAR_SKIP); } @Test public void shouldNotDumpSQPropsInSystemProps() throws Exception { logTester.setLevel(LoggerLevel.DEBUG); ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); Properties props = new Properties(); props.setProperty(COM_FOO, "bar"); props.setProperty(SONAR_SKIP, "true"); when(system2.properties()).thenReturn(props); publisher.init(writer); String content = FileUtils.readFileToString(writer.getFileStructure().analysisLog()); assertThat(content).containsOnlyOnce(COM_FOO); assertThat(content).doesNotContain(SONAR_SKIP); publisher.dumpModuleSettings(ProjectDefinition.create() .setProperty("sonar.projectKey", "foo") .setProperty(COM_FOO, "bar") .setProperty(SONAR_SKIP, "true")); content = FileUtils.readFileToString(writer.getFileStructure().analysisLog()); assertThat(content).containsOnlyOnce(COM_FOO); assertThat(content).containsOnlyOnce(SONAR_SKIP); } @Test public void shouldNotDumpEnvTwice() throws Exception { logTester.setLevel(LoggerLevel.DEBUG); ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); Map<String, String> env = new HashMap<>(); env.put(FOO, "BAR"); env.put(BIZ, "BAZ"); when(system2.envVariables()).thenReturn(env); publisher.init(writer); String content = FileUtils.readFileToString(writer.getFileStructure().analysisLog()); assertThat(content).containsOnlyOnce(FOO); assertThat(content).containsOnlyOnce(BIZ); assertThat(content).containsSequence(BIZ, FOO); publisher.dumpModuleSettings(ProjectDefinition.create() .setProperty("sonar.projectKey", "foo") .setProperty("env." + FOO, "BAR")); content = FileUtils.readFileToString(writer.getFileStructure().analysisLog()); assertThat(content).containsOnlyOnce(FOO); assertThat(content).containsOnlyOnce(BIZ); assertThat(content).doesNotContain("env." + FOO); } @Test public void shouldNotDumpSensitiveModuleProperties() throws Exception { ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); publisher.init(writer); assertThat(writer.getFileStructure().analysisLog()).exists(); publisher.dumpModuleSettings(ProjectDefinition.create() .setProperty("sonar.projectKey", "foo") .setProperty("sonar.projectKey", "foo") .setProperty("sonar.login", "my_token") .setProperty("sonar.password", "azerty") .setProperty("sonar.cpp.license.secured", "AZERTY")); assertThat(FileUtils.readFileToString(writer.getFileStructure().analysisLog())).containsSequence( "sonar.cpp.license.secured=******", "sonar.login=******", "sonar.password=******", "sonar.projectKey=foo"); } // SONAR-7598 @Test public void shouldNotDumpSensitiveGlobalProperties() throws Exception { ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); when(globalSettings.getServerSideSettings()).thenReturn(ImmutableMap.of("sonar.login", "my_token", "sonar.password", "azerty", "sonar.cpp.license.secured", "AZERTY")); publisher.init(writer); assertThat(FileUtils.readFileToString(writer.getFileStructure().analysisLog())).containsSequence( "sonar.cpp.license.secured=******", "sonar.login=******", "sonar.password=******"); } // SONAR-7371 @Test public void dontDumpParentProps() throws Exception { logTester.setLevel(LoggerLevel.DEBUG); ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); publisher.init(writer); ProjectDefinition module = ProjectDefinition.create() .setProperty("sonar.projectKey", "foo") .setProperty(SONAR_SKIP, "true"); ProjectDefinition.create() .setProperty("sonar.projectKey", "parent") .setProperty(SONAR_SKIP, "true") .addSubProject(module); publisher.dumpModuleSettings(module); String content = FileUtils.readFileToString(writer.getFileStructure().analysisLog()); assertThat(content).doesNotContain(SONAR_SKIP); } }