From 3779bf3b1e2bb79c614bb8a683d86a4fde788790 Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Thu, 9 Feb 2017 19:23:57 +0100 Subject: [PATCH] SONAR-8761 fix cleanup of db in ITs --- .../src/test/java/it/Category3Suite.java | 8 +- .../test/java/it/analysis/PermissionTest.java | 116 +++++++----------- .../java/it/issue/IssueNotificationsTest.java | 38 +++--- ...anizationIt.java => OrganizationTest.java} | 10 +- .../RootTest.java} | 64 +++++----- .../sonar/server/platform/BackendCleanup.java | 10 ++ .../OrganizationFlagsImplTest.java | 2 +- 7 files changed, 120 insertions(+), 128 deletions(-) rename it/it-tests/src/test/java/it/organization/{OrganizationIt.java => OrganizationTest.java} (98%) rename it/it-tests/src/test/java/it/{root/RootIt.java => organization/RootTest.java} (76%) diff --git a/it/it-tests/src/test/java/it/Category3Suite.java b/it/it-tests/src/test/java/it/Category3Suite.java index 336c3d9249c..6d9e32a1de2 100644 --- a/it/it-tests/src/test/java/it/Category3Suite.java +++ b/it/it-tests/src/test/java/it/Category3Suite.java @@ -34,9 +34,9 @@ import it.analysis.ScannerTest; import it.analysis.SettingsEncryptionTest; import it.analysis.TempFolderTest; import it.measure.DecimalScaleMetricTest; -import it.organization.OrganizationIt; import it.plugins.VersionPluginTest; -import it.root.RootIt; +import it.organization.OrganizationTest; +import it.organization.RootTest; import it.webhook.WebhooksTest; import org.junit.ClassRule; import org.junit.runner.RunWith; @@ -65,9 +65,9 @@ import static util.ItUtils.xooPlugin; // measures DecimalScaleMetricTest.class, // organization - OrganizationIt.class, + OrganizationTest.class, // root users - RootIt.class, + RootTest.class, WebhooksTest.class }) public class Category3Suite { diff --git a/it/it-tests/src/test/java/it/analysis/PermissionTest.java b/it/it-tests/src/test/java/it/analysis/PermissionTest.java index 5ec5bca2b56..372865fa411 100644 --- a/it/it-tests/src/test/java/it/analysis/PermissionTest.java +++ b/it/it-tests/src/test/java/it/analysis/PermissionTest.java @@ -24,16 +24,14 @@ import com.sonar.orchestrator.build.BuildResult; import com.sonar.orchestrator.build.SonarScanner; import it.Category3Suite; import javax.annotation.Nullable; -import org.junit.AfterClass; +import org.junit.After; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.ClassRule; +import org.junit.Rule; import org.junit.Test; import org.sonarqube.ws.WsUserTokens; import org.sonarqube.ws.client.WsClient; -import org.sonarqube.ws.client.permission.AddGroupWsRequest; import org.sonarqube.ws.client.permission.AddUserWsRequest; -import org.sonarqube.ws.client.permission.RemoveGroupWsRequest; import org.sonarqube.ws.client.usertoken.GenerateWsRequest; import org.sonarqube.ws.client.usertoken.RevokeWsRequest; import org.sonarqube.ws.client.usertoken.UserTokensService; @@ -48,48 +46,42 @@ import static util.ItUtils.setServerProperty; public class PermissionTest { - private static final String SIMPLE_USER = "simple-user"; + private static final String A_LOGIN = "a_login"; + private static final String A_PASSWORD = "a_password"; @ClassRule public static Orchestrator orchestrator = Category3Suite.ORCHESTRATOR; - @ClassRule - public static UserRule userRule = UserRule.from(orchestrator); - private static WsClient adminWsClient; + @Rule + public UserRule userRule = UserRule.from(orchestrator); - private static UserTokensService userTokensWsClient; + private WsClient adminWsClient; + private UserTokensService userTokensWsClient; - @BeforeClass - public static void setUp() { - adminWsClient = newAdminWsClient(orchestrator); - userTokensWsClient = adminWsClient.userTokens(); - resetData(); - } + @Before + public void setUp() { + orchestrator.resetData(); - @AfterClass - public static void restoreAnyonePermissionToScan() throws Exception { - addGroupPermission("Anyone", "scan"); - } + // enforce scanners to be authenticated + setServerProperty(orchestrator, "sonar.forceAuthentication", "true"); - @Before - public void deleteData() { - resetData(); + adminWsClient = newAdminWsClient(orchestrator); + userTokensWsClient = adminWsClient.userTokens(); } - private static void resetData() { - orchestrator.resetData(); + @After + public void tearDown() throws Exception { resetSettings(orchestrator, null, "sonar.forceAuthentication"); - userRule.deactivateUsers(SIMPLE_USER); - removeGroupPermission("Anyone", "scan"); + userRule.resetUsers(); } @Test - public void run_analysis_with_token_authentication() { - userRule.createUser(SIMPLE_USER, "password"); - addUserPermission(SIMPLE_USER, "scan", null); - String tokenName = "Analyze Project"; + public void scanner_can_authenticate_with_authentication_token() { + createUserWithProvisioningAndScanPermissions(); + + String tokenName = "For test"; WsUserTokens.GenerateWsResponse generateWsResponse = userTokensWsClient.generate(new GenerateWsRequest() - .setLogin(SIMPLE_USER) + .setLogin(A_LOGIN) .setName(tokenName)); SonarScanner sampleProject = SonarScanner.create(projectDir("shared/xoo-sample")); sampleProject.setProperties( @@ -99,11 +91,11 @@ public class PermissionTest { BuildResult buildResult = orchestrator.executeBuild(sampleProject); assertThat(buildResult.isSuccess()).isTrue(); - userTokensWsClient.revoke(new RevokeWsRequest().setLogin(SIMPLE_USER).setName(tokenName)); + userTokensWsClient.revoke(new RevokeWsRequest().setLogin(A_LOGIN).setName(tokenName)); } @Test - public void run_analysis_with_incorrect_token() { + public void scanner_fails_if_authentication_token_is_not_valid() { SonarScanner sampleProject = SonarScanner.create(projectDir("shared/xoo-sample")); sampleProject.setProperties( "sonar.login", "unknown-token", @@ -118,9 +110,10 @@ public class PermissionTest { * SONAR-4211 Test Sonar Runner when server requires authentication */ @Test - public void should_authenticate_when_needed() { + public void scanner_can_authenticate_with_login_password() { + createUserWithProvisioningAndScanPermissions(); + orchestrator.getServer().provisionProject("sample", "xoo-sample"); - setServerProperty(orchestrator, "sonar.forceAuthentication", "true"); BuildResult buildResult = scanQuietly("shared/xoo-sample", "sonar.login", "", @@ -138,61 +131,29 @@ public class PermissionTest { "Not authorized. Please check the properties sonar.login and sonar.password."); buildResult = scan("shared/xoo-sample", - "sonar.login", "admin", - "sonar.password", "admin"); + "sonar.login", A_LOGIN, + "sonar.password", A_PASSWORD); assertThat(buildResult.getLastStatus()).isEqualTo(0); } @Test - public void run_analysis_with_authenticated_user_having_global_execute_analysis_permission() throws Exception { - userRule.createUser(SIMPLE_USER, "password"); + public void run_scanner_with_user_having_scan_permission_only_on_project() throws Exception { + userRule.createUser(A_LOGIN, A_PASSWORD); orchestrator.getServer().provisionProject("sample", "sample"); - addUserPermission(SIMPLE_USER, "scan", null); + addUserPermission(A_LOGIN, "scan", "sample"); - BuildResult buildResult = scanQuietly("shared/xoo-sample", "sonar.login", SIMPLE_USER, "sonar.password", "password"); + BuildResult buildResult = scanQuietly("shared/xoo-sample", "sonar.login", A_LOGIN, "sonar.password", A_PASSWORD); assertThat(buildResult.isSuccess()).isTrue(); } - @Test - public void run_analysis_with_authenticated_user_having_execute_analysis_permission_only_on_project() throws Exception { - userRule.createUser(SIMPLE_USER, "password"); - orchestrator.getServer().provisionProject("sample", "sample"); - addUserPermission(SIMPLE_USER, "scan", "sample"); - - BuildResult buildResult = scanQuietly("shared/xoo-sample", "sonar.login", SIMPLE_USER, "sonar.password", "password"); - - assertThat(buildResult.isSuccess()).isTrue(); - } - - @Test - public void run_analysis_when_execute_analysis_is_set_to_anyone() throws Exception { - addGroupPermission("Anyone", "scan"); - - BuildResult buildResult = scanQuietly("shared/xoo-sample"); - - assertThat(buildResult.isSuccess()).isTrue(); - } - - private static void addUserPermission(String login, String permission, @Nullable String projectKey) { + private void addUserPermission(String login, String permission, @Nullable String projectKey) { adminWsClient.permissions().addUser(new AddUserWsRequest() .setLogin(login) .setPermission(permission) .setProjectKey(projectKey)); } - private static void addGroupPermission(String groupName, String permission) { - adminWsClient.permissions().addGroup(new AddGroupWsRequest() - .setGroupName(groupName) - .setPermission(permission)); - } - - private static void removeGroupPermission(String groupName, String permission) { - adminWsClient.permissions().removeGroup(new RemoveGroupWsRequest() - .setGroupName(groupName) - .setPermission(permission)); - } - private BuildResult scan(String projectPath, String... props) { SonarScanner scanner = configureScanner(projectPath, props); return orchestrator.executeBuild(scanner); @@ -207,4 +168,11 @@ public class PermissionTest { return SonarScanner.create(ItUtils.projectDir(projectPath)) .setProperties(props); } + + private void createUserWithProvisioningAndScanPermissions() { + userRule.createUser(A_LOGIN, A_PASSWORD); + addUserPermission(A_LOGIN, "provisioning", null); + addUserPermission(A_LOGIN, "scan", null); + } + } diff --git a/it/it-tests/src/test/java/it/issue/IssueNotificationsTest.java b/it/it-tests/src/test/java/it/issue/IssueNotificationsTest.java index b16e6b13ca4..b5f15e8e737 100644 --- a/it/it-tests/src/test/java/it/issue/IssueNotificationsTest.java +++ b/it/it-tests/src/test/java/it/issue/IssueNotificationsTest.java @@ -74,30 +74,12 @@ public class IssueNotificationsTest extends AbstractIssueTest { setServerProperty(ORCHESTRATOR, "email.smtp_host.secured", "localhost"); setServerProperty(ORCHESTRATOR, "email.smtp_port.secured", Integer.toString(smtpServer.getServer().getPort())); - // Create test user - userRule.createUser(USER_LOGIN, "Tester", USER_EMAIL, USER_LOGIN); - // Send test email to the test user newAdminWsClient(ORCHESTRATOR).wsConnector().call(new PostRequest("api/emails/send") .setParam("to", USER_EMAIL) .setParam("message", "This is a test message from SonarQube")) .failIfNotSuccessful(); - // Add notifications to the test user - WsClient wsClient = newUserWsClient(ORCHESTRATOR, USER_LOGIN, USER_PASSWORD); - wsClient.wsConnector().call(new PostRequest("api/notifications/add") - .setParam("type", "NewIssues") - .setParam("channel", "EmailNotificationChannel")) - .failIfNotSuccessful(); - wsClient.wsConnector().call(new PostRequest("api/notifications/add") - .setParam("type", "ChangesOnMyIssue") - .setParam("channel", "EmailNotificationChannel")) - .failIfNotSuccessful(); - wsClient.wsConnector().call(new PostRequest("api/notifications/add") - .setParam("type", "SQ-MyNewIssues") - .setParam("channel", "EmailNotificationChannel")) - .failIfNotSuccessful(); - // We need to wait until all notifications will be delivered waitUntilAllNotificationsAreDelivered(1); @@ -123,6 +105,10 @@ public class IssueNotificationsTest extends AbstractIssueTest { @Before public void prepare() { ORCHESTRATOR.resetData(); + + // Create test user + userRule.createUser(USER_LOGIN, "Tester", USER_EMAIL, USER_LOGIN); + smtpServer.getMessages().clear(); issueClient = ORCHESTRATOR.getServer().adminWsClient().issueClient(); issuesService = newAdminWsClient(ORCHESTRATOR).issues(); @@ -131,6 +117,22 @@ public class IssueNotificationsTest extends AbstractIssueTest { ORCHESTRATOR.getServer().restoreProfile(FileLocation.ofClasspath("/issue/one-issue-per-line-profile.xml")); ORCHESTRATOR.getServer().provisionProject(PROJECT_KEY, "Sample"); ORCHESTRATOR.getServer().associateProjectToQualityProfile(PROJECT_KEY, "xoo", "one-issue-per-line-profile"); + + // Add notifications to the test user + WsClient wsClient = newUserWsClient(ORCHESTRATOR, USER_LOGIN, USER_PASSWORD); + wsClient.wsConnector().call(new PostRequest("api/notifications/add") + .setParam("type", "NewIssues") + .setParam("channel", "EmailNotificationChannel")) + .failIfNotSuccessful(); + wsClient.wsConnector().call(new PostRequest("api/notifications/add") + .setParam("type", "ChangesOnMyIssue") + .setParam("channel", "EmailNotificationChannel")) + .failIfNotSuccessful(); + wsClient.wsConnector().call(new PostRequest("api/notifications/add") + .setParam("type", "SQ-MyNewIssues") + .setParam("channel", "EmailNotificationChannel")) + .failIfNotSuccessful(); + } @Test diff --git a/it/it-tests/src/test/java/it/organization/OrganizationIt.java b/it/it-tests/src/test/java/it/organization/OrganizationTest.java similarity index 98% rename from it/it-tests/src/test/java/it/organization/OrganizationIt.java rename to it/it-tests/src/test/java/it/organization/OrganizationTest.java index f88a29e3871..aa348ee7681 100644 --- a/it/it-tests/src/test/java/it/organization/OrganizationIt.java +++ b/it/it-tests/src/test/java/it/organization/OrganizationTest.java @@ -22,9 +22,11 @@ package it.organization; import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.build.BuildFailureException; import it.Category3Suite; +import java.util.Collections; import java.util.List; import java.util.function.Consumer; import java.util.function.Function; +import org.junit.After; import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; @@ -49,7 +51,7 @@ import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; -public class OrganizationIt { +public class OrganizationTest { private static final String DEFAULT_ORGANIZATION_KEY = "default-organization"; private static final String NAME = "Foo Company"; private static final String KEY = "foo-company"; @@ -73,6 +75,12 @@ public class OrganizationIt { orchestrator.resetData(); userRule.resetUsers(); ItUtils.resetSettings(orchestrator, null, SETTING_ANYONE_CAN_CREATE_ORGANIZATIONS); + orchestrator.getServer().post("api/organizations/enable_support", Collections.emptyMap()); + } + + @After + public void tearDown() throws Exception { + orchestrator.resetData(); } @Test diff --git a/it/it-tests/src/test/java/it/root/RootIt.java b/it/it-tests/src/test/java/it/organization/RootTest.java similarity index 76% rename from it/it-tests/src/test/java/it/root/RootIt.java rename to it/it-tests/src/test/java/it/organization/RootTest.java index 495ead840ab..89b3af24120 100644 --- a/it/it-tests/src/test/java/it/root/RootIt.java +++ b/it/it-tests/src/test/java/it/organization/RootTest.java @@ -17,14 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package it.root; +package it.organization; import com.sonar.orchestrator.Orchestrator; import it.Category3Suite; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Collections; import org.junit.After; import org.junit.ClassRule; import org.junit.Rule; @@ -40,25 +38,38 @@ import static util.ItUtils.newAdminWsClient; import static util.ItUtils.newUserWsClient; import static util.ItUtils.newWsClient; -public class RootIt { +public class RootTest { @ClassRule public static Orchestrator orchestrator = Category3Suite.ORCHESTRATOR; @Rule public UserRule userRule = UserRule.from(orchestrator); @After - public void tearDown() throws Exception { - userRule.resetUsers(); + public void tearDown() { + orchestrator.resetData(); } @Test - public void by_default_admin_is_the_only_root() { - // must be root to call search WS + public void nobody_is_root_by_default() { + // anonymous verifyHttpError(() -> newWsClient(orchestrator).rootService().search(), 403); + // admin + verifyHttpError(() -> newAdminWsClient(orchestrator).rootService().search(), 403); + } + + @Test + public void system_administrator_is_flagged_as_root_when_he_enables_organization_support() { + enableOrganizationSupport(); + assertThat(newAdminWsClient(orchestrator).rootService().search().getRootsList()) .extracting(WsRoot.Root::getLogin) .containsOnly(UserRule.ADMIN_LOGIN); + } + + @Test + public void a_root_can_flag_other_user_as_root() { + enableOrganizationSupport(); userRule.createUser("bar", "foo"); userRule.setRoot("bar"); @@ -70,28 +81,15 @@ public class RootIt { @Test public void last_root_can_not_be_unset_root() throws SQLException { - try (Connection connection = orchestrator.getDatabase().openConnection(); - PreparedStatement preparedStatement = createSelectActiveRootUsers(connection); - ResultSet resultSet = preparedStatement.executeQuery()) { - assertThat(resultSet.next()).as("There should be active root user").isTrue(); - assertThat(resultSet.getString(1)).isEqualTo(UserRule.ADMIN_LOGIN); - assertThat(resultSet.next()).as("There shouldn't be more than one active root user").isFalse(); - } + enableOrganizationSupport(); verifyHttpError(() -> newAdminWsClient(orchestrator).rootService().unsetRoot(UserRule.ADMIN_LOGIN), 400); } - private static void verifyHttpError(Runnable runnable, int expectedErrorCode) { - try { - runnable.run(); - fail("Ws Call should have failed with http code " + expectedErrorCode); - } catch (HttpException e) { - assertThat(e.code()).isEqualTo(expectedErrorCode); - } - } - @Test public void root_can_be_set_and_unset_via_web_services() { + enableOrganizationSupport(); + userRule.createUser("root1", "bar"); userRule.createUser("root2", "bar"); WsClient root1WsClient = newUserWsClient(orchestrator, "root1", "bar"); @@ -113,10 +111,16 @@ public class RootIt { root2WsClient.rootService().unsetRoot("root2"); } - private static PreparedStatement createSelectActiveRootUsers(Connection connection) throws SQLException { - PreparedStatement preparedStatement = connection.prepareStatement("select login from users where is_root = ? and active = ?"); - preparedStatement.setBoolean(1, true); - preparedStatement.setBoolean(2, true); - return preparedStatement; + private void enableOrganizationSupport() { + orchestrator.getServer().post("api/organizations/enable_support", Collections.emptyMap()); + } + + private static void verifyHttpError(Runnable runnable, int expectedErrorCode) { + try { + runnable.run(); + fail("Ws Call should have failed with http code " + expectedErrorCode); + } catch (HttpException e) { + assertThat(e.code()).isEqualTo(expectedErrorCode); + } } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/BackendCleanup.java b/server/sonar-server/src/main/java/org/sonar/server/platform/BackendCleanup.java index f6b0e802c49..46564c2d047 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/BackendCleanup.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/BackendCleanup.java @@ -110,6 +110,9 @@ public class BackendCleanup { truncateAnalysisTables(connection); deleteManualRules(connection); + truncateInternalProperties(null, null, connection); + truncateUsers(null, null, connection); + truncateOrganizations(null, null, connection); } catch (SQLException e) { throw new IllegalStateException("Fail to reset data", e); } @@ -184,6 +187,13 @@ public class BackendCleanup { // commit is useless on some databases connection.commit(); } + // "admin" is not flagged as root by default + try (PreparedStatement preparedStatement = connection.prepareStatement("update users set is_root=?")) { + preparedStatement.setBoolean(1, false); + preparedStatement.execute(); + // commit is useless on some databases + connection.commit(); + } } /** diff --git a/server/sonar-server/src/test/java/org/sonar/server/organization/OrganizationFlagsImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/organization/OrganizationFlagsImplTest.java index 4ec4454e0ca..099ef81edb8 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/organization/OrganizationFlagsImplTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/organization/OrganizationFlagsImplTest.java @@ -43,7 +43,7 @@ public class OrganizationFlagsImplTest { } @Test - public void enable_does_enable_feature_by_inserting_internal_property() { + public void enable_does_enable_support_by_inserting_internal_property() { underTest.enable(db.getSession()); assertThat(underTest.isEnabled(db.getSession())).isTrue(); -- 2.39.5