Browse Source

SONAR-12214 - order by created_at instead of technical id (#2029)

* SONAR-12214 - order by created_at instead of technical id
tags/8.0
Jacek 4 years ago
parent
commit
ad082b3d7b

+ 3
- 3
server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml View File

@@ -62,7 +62,7 @@
<include refid="countWarnings"/>
<include refid="sqlSelectByQuery" />
order by
ca.id desc
ca.created_at desc, id desc
limit #{pagination.pageSize,jdbcType=INTEGER} offset #{pagination.offset,jdbcType=INTEGER}
</select>

@@ -75,7 +75,7 @@
) as query
where
query.number between #{pagination.startRowNumber,jdbcType=INTEGER} and #{pagination.endRowNumber,jdbcType=INTEGER}
order by id desc
order by created_at desc, id desc
</select>

<select id="selectByQuery" parameterType="map" resultType="org.sonar.db.ce.CeActivityDto" databaseId="oracle">
@@ -85,7 +85,7 @@
<include refid="columns"/>,
<include refid="countWarnings"/>
<include refid="sqlSelectByQuery" />
order by ca.id desc
order by ca.created_at desc, ca.id desc
) t
) t
where

+ 1
- 1
server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml View File

@@ -299,7 +299,7 @@
select
<include refid="componentColumns"/>
<include refid="sqlSelectByQuery"/>
ORDER BY LOWER(p.name), p.name, p.id
ORDER BY LOWER(p.name), p.name, p.created_at
</select>

<select id="countByQuery" resultType="int">

+ 2
- 2
server/sonar-db-dao/src/main/resources/org/sonar/db/permission/template/PermissionTemplateCharacteristicMapper.xml View File

@@ -26,7 +26,7 @@
<foreach collection="templateIds" open="(" close=")" item="templateId" separator=",">
#{templateId}
</foreach>
order by id
order by ptc.created_at
</select>

<select id="selectByPermissionAndTemplateId" parameterType="map" resultType="PermissionTemplateCharacteristic">
@@ -35,7 +35,7 @@
from perm_tpl_characteristics ptc
where ptc.template_id=#{templateId}
and ptc.permission_key=#{permission}
order by id
order by ptc.created_at
</select>

<insert id="insert" parameterType="PermissionTemplateCharacteristic" keyColumn="id" useGeneratedKeys="true" keyProperty="id">

+ 1
- 1
server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml View File

@@ -139,7 +139,7 @@
</foreach>
and p.resource_id is null
and p.user_id is null
order by p.id
order by p.created_at
</select>

<select id="selectByKeysAndComponentIds" parameterType="map" resultType="ScrapProperty">

+ 1
- 1
server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/QualityGateConditionMapper.xml View File

@@ -17,7 +17,7 @@
select
<include refid="conditionColumns"/>
from quality_gate_conditions where qgate_id=#{qGateId}
order by id asc
order by created_at asc
</select>

<select id="selectById" parameterType="long" resultType="QualityGateCondition">

+ 2
- 2
server/sonar-db-dao/src/main/resources/org/sonar/db/user/GroupMembershipMapper.xml View File

@@ -57,7 +57,7 @@
#{login}
</foreach>
</where>
ORDER BY u.login, g.name, g.id
ORDER BY u.login, g.name, g.created_at
</select>

<select id="selectGroupsByLoginsAndOrganization" parameterType="map" resultType="org.sonar.db.user.LoginGroup">
@@ -72,7 +72,7 @@
</foreach>
and g.organization_uuid=#{organizationUuid,jdbcType=VARCHAR}
</where>
ORDER BY u.login, g.name, g.id
ORDER BY u.login, g.name, g.created_at
</select>

<sql id="userCommonClauses">

+ 52
- 3
server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java View File

@@ -36,6 +36,7 @@ import javax.annotation.Nullable;
import org.assertj.core.api.AbstractListAssert;
import org.assertj.core.api.ObjectAssert;
import org.assertj.core.groups.Tuple;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -67,7 +68,9 @@ public class CeActivityDaoTest {
private static final String MAINCOMPONENT_2 = randomAlphabetic(13);
private static final String COMPONENT_1 = randomAlphabetic(14);

private TestSystem2 system2 = new TestSystem2().setNow(1_450_000_000_000L);
private static final long INITIAL_TIME = 1_450_000_000_000L;

private TestSystem2 system2 = new TestSystem2().setNow(INITIAL_TIME);

@Rule
public DbTester db = DbTester.create(system2);
@@ -75,6 +78,11 @@ public class CeActivityDaoTest {
private DbSession dbSession = db.getSession();
private CeActivityDao underTest = new CeActivityDao(system2);

@Before
public void setup() {
system2.setNow(INITIAL_TIME);
}

@Test
public void test_insert() {
CeActivityDto inserted = insert("TASK_1", REPORT, COMPONENT_1, MAINCOMPONENT_1, SUCCESS);
@@ -93,7 +101,7 @@ public class CeActivityDaoTest {
assertThat(dto.getMainIsLast()).isTrue();
assertThat(dto.getIsLastKey()).isEqualTo("REPORT" + COMPONENT_1);
assertThat(dto.getMainIsLastKey()).isEqualTo("REPORT" + MAINCOMPONENT_1);
assertThat(dto.getCreatedAt()).isEqualTo(1_450_000_000_000L);
assertThat(dto.getCreatedAt()).isEqualTo(INITIAL_TIME + 1);
assertThat(dto.getStartedAt()).isEqualTo(1_500_000_000_000L);
assertThat(dto.getExecutedAt()).isEqualTo(1_500_000_000_500L);
assertThat(dto.getExecutionTimeMs()).isEqualTo(500L);
@@ -440,6 +448,46 @@ public class CeActivityDaoTest {
assertThat(dtos).extracting("uuid").containsExactly("TASK_2");
}

@Test
public void test_selectByQuery_verify_order_if_same_date() {
system2.setNow(INITIAL_TIME);
insert("TASK_1", REPORT, MAINCOMPONENT_1, SUCCESS);
system2.setNow(INITIAL_TIME);
insert("TASK_2", REPORT, MAINCOMPONENT_1, FAILED);
system2.setNow(INITIAL_TIME);
insert("TASK_3", REPORT, MAINCOMPONENT_2, SUCCESS);
system2.setNow(INITIAL_TIME);
insert("TASK_4", "views", null, SUCCESS);

// no filters
CeTaskQuery query = new CeTaskQuery().setStatuses(Collections.emptyList());
List<CeActivityDto> dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(10));
assertThat(dtos).extracting("uuid").containsExactly("TASK_4", "TASK_3", "TASK_2", "TASK_1");

// select by component uuid
query = new CeTaskQuery().setMainComponentUuid(MAINCOMPONENT_1);
dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100));
assertThat(dtos).extracting("uuid").containsExactly("TASK_2", "TASK_1");

// select by status
query = new CeTaskQuery().setStatuses(singletonList(SUCCESS.name()));
dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100));
assertThat(dtos).extracting("uuid").containsExactly("TASK_4", "TASK_3", "TASK_1");

// select by type
query = new CeTaskQuery().setType(REPORT);
dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100));
assertThat(dtos).extracting("uuid").containsExactly("TASK_3", "TASK_2", "TASK_1");
query = new CeTaskQuery().setType("views");
dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100));
assertThat(dtos).extracting("uuid").containsExactly("TASK_4");

// select by multiple conditions
query = new CeTaskQuery().setType(REPORT).setOnlyCurrents(true).setMainComponentUuid(MAINCOMPONENT_1);
dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100));
assertThat(dtos).extracting("uuid").containsExactly("TASK_2");
}

@Test
public void selectByQuery_does_not_populate_errorStacktrace_field() {
insert("TASK_1", REPORT, MAINCOMPONENT_1, FAILED);
@@ -706,6 +754,7 @@ public class CeActivityDaoTest {

private CeActivityDto insert(String uuid, String type, @Nullable String componentUuid, @Nullable String mainComponentUuid, CeActivityDto.Status status) {
CeActivityDto dto = createActivityDto(uuid, type, componentUuid, mainComponentUuid, status);
system2.tick();
underTest.insert(db.getSession(), dto);
return dto;
}
@@ -718,7 +767,7 @@ public class CeActivityDaoTest {
creating.setComponentUuid(componentUuid);
creating.setMainComponentUuid(mainComponentUuid);
creating.setSubmitterUuid("submitter uuid");
creating.setCreatedAt(1_300_000_000_000L);
creating.setCreatedAt(system2.now());

db.getDbClient().ceQueueDao().insert(dbSession, creating);
makeInProgress(dbSession, "worker uuid", 1_400_000_000_000L, creating);

+ 48
- 10
server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java View File

@@ -26,6 +26,7 @@ import com.tngtech.java.junit.dataprovider.UseDataProvider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -43,6 +44,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.sonar.api.impl.utils.AlwaysIncreasingSystem2;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
import org.sonar.api.utils.System2;
@@ -94,8 +96,11 @@ public class ComponentDaoTest {

@Rule
public ExpectedException expectedException = ExpectedException.none();

private System2 system2 = AlwaysIncreasingSystem2.INSTANCE;

@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
public DbTester db = DbTester.create(system2);

private Random random = new Random();
private DbSession dbSession = db.getSession();
@@ -228,7 +233,7 @@ public class ComponentDaoTest {

@DataProvider
public static Object[][] branchBranchTypes() {
return new Object[][] {
return new Object[][]{
{BranchType.SHORT},
{BranchType.LONG}
};
@@ -329,15 +334,15 @@ public class ComponentDaoTest {
assertThat(underTest.selectByKeysAndBranches(db.getSession(), ImmutableMap.of(
projectBranch.getKey(), projectBranch.getBranch(),
applicationBranch.getKey(), applicationBranch.getBranch())))
.extracting(ComponentDto::getKey, ComponentDto::getBranch)
.containsExactlyInAnyOrder(
tuple(projectBranch.getKey(), "my_branch"),
tuple(applicationBranch.getKey(), "my_branch"));
.extracting(ComponentDto::getKey, ComponentDto::getBranch)
.containsExactlyInAnyOrder(
tuple(projectBranch.getKey(), "my_branch"),
tuple(applicationBranch.getKey(), "my_branch"));
assertThat(underTest.selectByKeysAndBranches(db.getSession(), ImmutableMap.of(
projectBranch.getKey(), "unknown",
"unknown", projectBranch.getBranch())))
.extracting(ComponentDto::getDbKey)
.isEmpty();
.extracting(ComponentDto::getDbKey)
.isEmpty();
assertThat(underTest.selectByKeysAndBranches(db.getSession(), Collections.emptyMap())).isEmpty();
}

@@ -762,7 +767,7 @@ public class ComponentDaoTest {

@DataProvider
public static Object[][] oneOrMoreProjects() {
return new Object[][] {
return new Object[][]{
{1},
{1 + new Random().nextInt(10)}
};
@@ -991,7 +996,7 @@ public class ComponentDaoTest {

@DataProvider
public static Object[][] portfolioOrApplicationRootViewQualifier() {
return new Object[][] {
return new Object[][]{
{Qualifiers.VIEW},
{Qualifiers.APP},
};
@@ -1170,6 +1175,39 @@ public class ComponentDaoTest {
.isEmpty();
}

@Test
public void selectByQuery_verify_order() {
OrganizationDto organization = db.organizations().insert();

Date firstDate = new Date(system2.now());
Date secondDate = new Date(system2.now());
Date thirdDate = new Date(system2.now());

ComponentDto project3 = db.components().insertPrivateProject(organization, "project3", componentDto -> componentDto.setCreatedAt(thirdDate));
ComponentDto project1 = db.components().insertPrivateProject(organization, "project1", componentDto -> componentDto.setCreatedAt(firstDate));
ComponentDto project2 = db.components().insertPrivateProject(organization, "project2", componentDto -> componentDto.setCreatedAt(secondDate));

Supplier<ComponentQuery.Builder> query = () -> ComponentQuery.builder()
.setQualifiers(PROJECT)
.setOnProvisionedOnly(true);

List<ComponentDto> results = underTest.selectByQuery(dbSession, organization.getUuid(), query.get().build(), 0, 10);
assertThat(results)
.extracting(ComponentDto::uuid)
.containsExactly(
project1.uuid(),
project2.uuid(),
project3.uuid()
);
assertThat(results)
.extracting(ComponentDto::getCreatedAt)
.containsExactly(
firstDate,
secondDate,
thirdDate
);
}

@Test
public void count_provisioned() {
OrganizationDto organization = db.organizations().insert();

+ 9
- 3
server/sonar-db-dao/src/test/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDaoTest.java View File

@@ -56,6 +56,12 @@ public class PermissionTemplateCharacteristicDaoTest {
.setWithProjectCreator(false)
.setCreatedAt(1_000_000_000L)
.setUpdatedAt(2_000_000_000L));
PermissionTemplateCharacteristicDto templatePermission3 = underTest.insert(dbSession, new PermissionTemplateCharacteristicDto()
.setPermission(UserRole.USER)
.setTemplateId(3L)
.setWithProjectCreator(false)
.setCreatedAt(1_000_000_001L)
.setUpdatedAt(2_000_000_000L));
PermissionTemplateCharacteristicDto templatePermissionForAnotherTemplate = underTest.insert(dbSession, new PermissionTemplateCharacteristicDto()
.setPermission(UserRole.ADMIN)
.setTemplateId(42L)
@@ -63,12 +69,12 @@ public class PermissionTemplateCharacteristicDaoTest {
.setCreatedAt(1_000_000_000L)
.setUpdatedAt(2_000_000_000L));

List<PermissionTemplateCharacteristicDto> result = underTest.selectByTemplateIds(dbSession, newArrayList(1L, 2L));
List<PermissionTemplateCharacteristicDto> result = underTest.selectByTemplateIds(dbSession, newArrayList(1L, 2L, 3L));
assertThat(result)
.hasSize(2)
.hasSize(3)
.extracting("id")
.doesNotContain(templatePermissionForAnotherTemplate.getId())
.containsOnly(templatePermission1.getId(), templatePermission2.getId());
.containsExactly(templatePermission1.getId(), templatePermission2.getId(), templatePermission3.getId());
assertThat(result.get(0))
.isEqualToComparingFieldByField(templatePermission1);
}

+ 74
- 91
server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertiesDaoTest.java View File

@@ -23,7 +23,6 @@ import com.google.common.collect.ImmutableMap;
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -36,7 +35,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.sonar.api.utils.System2;
import org.sonar.api.impl.utils.AlwaysIncreasingSystem2;
import org.sonar.api.web.UserRole;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
@@ -54,8 +53,6 @@ import static java.util.Collections.singletonList;
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.groups.Tuple.tuple;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.db.property.PropertyTesting.newComponentPropertyDto;
import static org.sonar.db.property.PropertyTesting.newGlobalPropertyDto;
import static org.sonar.db.property.PropertyTesting.newPropertyDto;
@@ -65,13 +62,9 @@ import static org.sonar.db.property.PropertyTesting.newUserPropertyDto;
public class PropertiesDaoTest {
private static final String VALUE_SIZE_4000 = String.format("%1$4000.4000s", "*");
private static final String VALUE_SIZE_4001 = VALUE_SIZE_4000 + "P";
private static final long DATE_1 = 1_555_000L;
private static final long DATE_2 = 1_666_000L;
private static final long DATE_3 = 1_777_000L;
private static final long DATE_4 = 1_888_000L;
private static final long DATE_5 = 1_999_000L;
private static final long INITIAL_DATE = 1_444_000L;

private System2 system2 = mock(System2.class);
private AlwaysIncreasingSystem2 system2 = new AlwaysIncreasingSystem2(INITIAL_DATE, 1);

@Rule
public ExpectedException thrown = ExpectedException.none();
@@ -515,7 +508,7 @@ public class PropertiesDaoTest {

@DataProvider
public static Object[][] allValuesForSelect() {
return new Object[][] {
return new Object[][]{
{null, ""},
{"", ""},
{"some value", "some value"},
@@ -573,15 +566,24 @@ public class PropertiesDaoTest {
insertProperty(key, "value", null, userId);
insertProperty(anotherKey, "value", null, null);

insertProperty("key1", "value", null, null);
insertProperty("key2", "value", null, null);
insertProperty("key3", "value", null, null);

assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet(key)))
.extracting("key")
.containsOnly(key);
.containsExactly(key);
assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet(key, anotherKey)))
.extracting("key")
.containsOnly(key, anotherKey);
.containsExactly(key, anotherKey);
assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet(key, anotherKey, "unknown")))
.extracting("key")
.containsOnly(key, anotherKey);
.containsExactly(key, anotherKey);

assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet("key2", "key1", "key3")))
.extracting("key")
.containsExactly("key1", "key2", "key3");

assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet("unknown")))
.isEmpty();
}
@@ -605,9 +607,9 @@ public class PropertiesDaoTest {
.extracting("key", "resourceId").containsOnly(tuple(key, project.getId()));
assertThat(underTest.selectPropertiesByComponentIds(session, newHashSet(project.getId(), project2.getId())))
.extracting("key", "resourceId").containsOnly(
tuple(key, project.getId()),
tuple(key, project2.getId()),
tuple(anotherKey, project2.getId()));
tuple(key, project.getId()),
tuple(key, project2.getId()),
tuple(anotherKey, project2.getId()));

assertThat(underTest.selectPropertiesByComponentIds(session, newHashSet(123456789L))).isEmpty();
}
@@ -631,13 +633,13 @@ public class PropertiesDaoTest {
.extracting("key", "resourceId").containsOnly(tuple(key, project.getId()));
assertThat(underTest.selectPropertiesByKeysAndComponentIds(session, newHashSet(key), newHashSet(project.getId(), project2.getId())))
.extracting("key", "resourceId").containsOnly(
tuple(key, project.getId()),
tuple(key, project2.getId()));
tuple(key, project.getId()),
tuple(key, project2.getId()));
assertThat(underTest.selectPropertiesByKeysAndComponentIds(session, newHashSet(key, anotherKey), newHashSet(project.getId(), project2.getId())))
.extracting("key", "resourceId").containsOnly(
tuple(key, project.getId()),
tuple(key, project2.getId()),
tuple(anotherKey, project2.getId()));
tuple(key, project.getId()),
tuple(key, project2.getId()),
tuple(anotherKey, project2.getId()));

assertThat(underTest.selectPropertiesByKeysAndComponentIds(session, newHashSet("unknown"), newHashSet(project.getId()))).isEmpty();
assertThat(underTest.selectPropertiesByKeysAndComponentIds(session, newHashSet("key"), newHashSet(123456789L))).isEmpty();
@@ -686,8 +688,6 @@ public class PropertiesDaoTest {

@Test
public void saveProperty_inserts_global_properties_when_they_do_not_exist_in_db() {
when(system2.now()).thenReturn(DATE_1, DATE_2, DATE_3, DATE_4, DATE_5);

underTest.saveProperty(new PropertyDto().setKey("global.null").setValue(null));
underTest.saveProperty(new PropertyDto().setKey("global.empty").setValue(""));
underTest.saveProperty(new PropertyDto().setKey("global.text").setValue("some text"));
@@ -698,33 +698,31 @@ public class PropertiesDaoTest {
.hasNoResourceId()
.hasNoUserId()
.isEmpty()
.hasCreatedAt(DATE_1);
.hasCreatedAt(INITIAL_DATE + 2);
assertThatPropertiesRow("global.empty")
.hasNoResourceId()
.hasNoUserId()
.isEmpty()
.hasCreatedAt(DATE_2);
.hasCreatedAt(INITIAL_DATE + 3);
assertThatPropertiesRow("global.text")
.hasNoResourceId()
.hasNoUserId()
.hasTextValue("some text")
.hasCreatedAt(DATE_3);
.hasCreatedAt(INITIAL_DATE + 4);
assertThatPropertiesRow("global.4000")
.hasNoResourceId()
.hasNoUserId()
.hasTextValue(VALUE_SIZE_4000)
.hasCreatedAt(DATE_4);
.hasCreatedAt(INITIAL_DATE + 5);
assertThatPropertiesRow("global.clob")
.hasNoResourceId()
.hasNoUserId()
.hasClobValue(VALUE_SIZE_4001)
.hasCreatedAt(DATE_5);
.hasCreatedAt(INITIAL_DATE + 6);
}

@Test
public void saveProperty_inserts_component_properties_when_they_do_not_exist_in_db() {
when(system2.now()).thenReturn(DATE_1, DATE_2, DATE_3, DATE_4, DATE_5);

long resourceId = 12;
underTest.saveProperty(new PropertyDto().setKey("component.null").setResourceId(resourceId).setValue(null));
underTest.saveProperty(new PropertyDto().setKey("component.empty").setResourceId(resourceId).setValue(""));
@@ -736,33 +734,31 @@ public class PropertiesDaoTest {
.hasResourceId(resourceId)
.hasNoUserId()
.isEmpty()
.hasCreatedAt(DATE_1);
.hasCreatedAt(INITIAL_DATE + 2);
assertThatPropertiesRow("component.empty")
.hasResourceId(resourceId)
.hasNoUserId()
.isEmpty()
.hasCreatedAt(DATE_2);
.hasCreatedAt(INITIAL_DATE + 3);
assertThatPropertiesRow("component.text")
.hasResourceId(resourceId)
.hasNoUserId()
.hasTextValue("some text")
.hasCreatedAt(DATE_3);
.hasCreatedAt(INITIAL_DATE + 4);
assertThatPropertiesRow("component.4000")
.hasResourceId(resourceId)
.hasNoUserId()
.hasTextValue(VALUE_SIZE_4000)
.hasCreatedAt(DATE_4);
.hasCreatedAt(INITIAL_DATE + 5);
assertThatPropertiesRow("component.clob")
.hasResourceId(resourceId)
.hasNoUserId()
.hasClobValue(VALUE_SIZE_4001)
.hasCreatedAt(DATE_5);
.hasCreatedAt(INITIAL_DATE + 6);
}

@Test
public void saveProperty_inserts_user_properties_when_they_do_not_exist_in_db() {
when(system2.now()).thenReturn(DATE_1, DATE_2, DATE_3, DATE_4, DATE_5);

int userId = 100;
underTest.saveProperty(new PropertyDto().setKey("user.null").setUserId(userId).setValue(null));
underTest.saveProperty(new PropertyDto().setKey("user.empty").setUserId(userId).setValue(""));
@@ -774,34 +770,33 @@ public class PropertiesDaoTest {
.hasNoResourceId()
.hasUserId(userId)
.isEmpty()
.hasCreatedAt(DATE_1);
.hasCreatedAt(INITIAL_DATE + 2);
assertThatPropertiesRow("user.empty")
.hasNoResourceId()
.hasUserId(userId)
.isEmpty()
.hasCreatedAt(DATE_2);
.hasCreatedAt(INITIAL_DATE + 3);
assertThatPropertiesRow("user.text")
.hasNoResourceId()
.hasUserId(userId)
.hasTextValue("some text")
.hasCreatedAt(DATE_3);
.hasCreatedAt(INITIAL_DATE + 4);
assertThatPropertiesRow("user.4000")
.hasNoResourceId()
.hasUserId(userId)
.hasTextValue(VALUE_SIZE_4000)
.hasCreatedAt(DATE_4);
.hasCreatedAt(INITIAL_DATE + 5);
assertThatPropertiesRow("user.clob")
.hasNoResourceId()
.hasUserId(userId)
.hasClobValue(VALUE_SIZE_4001)
.hasCreatedAt(DATE_5);
.hasCreatedAt(INITIAL_DATE + 6);
}

@Test
@UseDataProvider("valueUpdatesDataProvider")
public void saveProperty_deletes_then_inserts_global_properties_when_they_exist_in_db(@Nullable String oldValue, @Nullable String newValue) throws SQLException {
long id = insertProperty("global", oldValue, null, null, DATE_1);
when(system2.now()).thenReturn(DATE_4);
public void saveProperty_deletes_then_inserts_global_properties_when_they_exist_in_db(@Nullable String oldValue, @Nullable String newValue) {
long id = insertProperty("global", oldValue, null, null);

underTest.saveProperty(new PropertyDto().setKey("global").setValue(newValue));

@@ -811,7 +806,7 @@ public class PropertiesDaoTest {
PropertiesRowAssert propertiesRowAssert = assertThatPropertiesRow("global")
.hasNoResourceId()
.hasNoUserId()
.hasCreatedAt(DATE_4);
.hasCreatedAt(INITIAL_DATE + 3);
if (newValue == null || newValue.isEmpty()) {
propertiesRowAssert.isEmpty();
} else if (newValue.length() > 4000) {
@@ -823,20 +818,18 @@ public class PropertiesDaoTest {

@Test
@UseDataProvider("valueUpdatesDataProvider")
public void saveProperty_deletes_then_inserts_component_properties_when_they_exist_in_db(@Nullable String oldValue, @Nullable String newValue) throws SQLException {
public void saveProperty_deletes_then_inserts_component_properties_when_they_exist_in_db(@Nullable String oldValue, @Nullable String newValue) {
long resourceId = 999L;
long id = insertProperty("global", oldValue, resourceId, null, DATE_1);
when(system2.now()).thenReturn(DATE_4);
long id = insertProperty("global", oldValue, resourceId, null);

underTest.saveProperty(new PropertyDto().setKey("global").setResourceId(resourceId).setValue(newValue));

assertThatPropertiesRow(id)
.doesNotExist();

PropertiesRowAssert propertiesRowAssert = assertThatPropertiesRow("global")
.hasResourceId(resourceId)
.hasNoUserId()
.hasCreatedAt(DATE_4);
.hasCreatedAt(INITIAL_DATE + 3);
if (newValue == null || newValue.isEmpty()) {
propertiesRowAssert.isEmpty();
} else if (newValue.length() > 4000) {
@@ -848,10 +841,9 @@ public class PropertiesDaoTest {

@Test
@UseDataProvider("valueUpdatesDataProvider")
public void saveProperty_deletes_then_inserts_user_properties_when_they_exist_in_db(@Nullable String oldValue, @Nullable String newValue) throws SQLException {
public void saveProperty_deletes_then_inserts_user_properties_when_they_exist_in_db(@Nullable String oldValue, @Nullable String newValue) {
int userId = 90;
long id = insertProperty("global", oldValue, null, userId, DATE_1);
when(system2.now()).thenReturn(DATE_4);
long id = insertProperty("global", oldValue, null, userId);

underTest.saveProperty(new PropertyDto().setKey("global").setUserId(userId).setValue(newValue));

@@ -861,7 +853,7 @@ public class PropertiesDaoTest {
PropertiesRowAssert propertiesRowAssert = assertThatPropertiesRow("global")
.hasNoResourceId()
.hasUserId(userId)
.hasCreatedAt(DATE_4);
.hasCreatedAt(INITIAL_DATE + 3);
if (newValue == null || newValue.isEmpty()) {
propertiesRowAssert.isEmpty();
} else if (newValue.length() > 4000) {
@@ -873,7 +865,7 @@ public class PropertiesDaoTest {

@DataProvider
public static Object[][] valueUpdatesDataProvider() {
return new Object[][] {
return new Object[][]{
{null, null},
{null, ""},
{null, "some value"},
@@ -1093,8 +1085,6 @@ public class PropertiesDaoTest {

@Test
public void saveGlobalProperties_insert_property_if_does_not_exist_in_db() {
when(system2.now()).thenReturn(DATE_1, DATE_2, DATE_3, DATE_4, DATE_5);

underTest.saveGlobalProperties(mapOf(
"null_value_property", null,
"empty_value_property", "",
@@ -1106,33 +1096,32 @@ public class PropertiesDaoTest {
.hasNoResourceId()
.hasNoUserId()
.isEmpty()
.hasCreatedAt(DATE_1);
.hasCreatedAt(INITIAL_DATE + 2);
assertThatPropertiesRow("empty_value_property")
.hasNoResourceId()
.hasNoUserId()
.isEmpty()
.hasCreatedAt(DATE_2);
.hasCreatedAt(INITIAL_DATE + 3);
assertThatPropertiesRow("text_value_property")
.hasNoResourceId()
.hasNoUserId()
.hasTextValue("dfdsfsd")
.hasCreatedAt(DATE_3);
.hasCreatedAt(INITIAL_DATE + 4);
assertThatPropertiesRow("4000_char_value_property")
.hasNoResourceId()
.hasNoUserId()
.hasTextValue(VALUE_SIZE_4000)
.hasCreatedAt(DATE_4);
.hasCreatedAt(INITIAL_DATE + 5);
assertThatPropertiesRow("clob_value_property")
.hasNoResourceId()
.hasNoUserId()
.hasClobValue(VALUE_SIZE_4001)
.hasCreatedAt(DATE_5);
.hasCreatedAt(INITIAL_DATE + 6);
}

@Test
public void saveGlobalProperties_delete_and_insert_new_value_when_property_exists_in_db() throws SQLException {
long id = insertProperty("to_be_updated", "old_value", null, null, DATE_1);
when(system2.now()).thenReturn(DATE_3);
public void saveGlobalProperties_delete_and_insert_new_value_when_property_exists_in_db() {
long id = insertProperty("to_be_updated", "old_value", null, null);

underTest.saveGlobalProperties(ImmutableMap.of("to_be_updated", "new value"));

@@ -1143,7 +1132,7 @@ public class PropertiesDaoTest {
.hasNoResourceId()
.hasNoUserId()
.hasTextValue("new value")
.hasCreatedAt(DATE_3);
.hasCreatedAt(INITIAL_DATE + 3);
}

private static Map<String, String> mapOf(String... values) {
@@ -1157,13 +1146,13 @@ public class PropertiesDaoTest {
}

@Test
public void renamePropertyKey_updates_global_component_and_user_properties() throws SQLException {
long id1 = insertProperty("foo", "bar", null, null, DATE_1);
long id2 = insertProperty("old_name", "doc1", null, null, DATE_1);
long id3 = insertProperty("old_name", "doc2", 15L, null, DATE_1);
long id4 = insertProperty("old_name", "doc3", 16L, null, DATE_1);
long id5 = insertProperty("old_name", "doc4", null, 100, DATE_1);
long id6 = insertProperty("old_name", "doc5", null, 101, DATE_1);
public void renamePropertyKey_updates_global_component_and_user_properties() {
long id1 = insertProperty("foo", "bar", null, null);
long id2 = insertProperty("old_name", "doc1", null, null);
long id3 = insertProperty("old_name", "doc2", 15L, null);
long id4 = insertProperty("old_name", "doc3", 16L, null);
long id5 = insertProperty("old_name", "doc4", null, 100);
long id6 = insertProperty("old_name", "doc5", null, 101);

underTest.renamePropertyKey("old_name", "new_name");

@@ -1172,46 +1161,45 @@ public class PropertiesDaoTest {
.hasNoUserId()
.hasNoResourceId()
.hasTextValue("bar")
.hasCreatedAt(DATE_1);
.hasCreatedAt(INITIAL_DATE + 2);
assertThatPropertiesRow(id2)
.hasKey("new_name")
.hasNoResourceId()
.hasNoUserId()
.hasTextValue("doc1")
.hasCreatedAt(DATE_1);
.hasCreatedAt(INITIAL_DATE + 3);
assertThatPropertiesRow(id3)
.hasKey("new_name")
.hasResourceId(15)
.hasNoUserId()
.hasTextValue("doc2")
.hasCreatedAt(DATE_1);
.hasCreatedAt(INITIAL_DATE + 4);
assertThatPropertiesRow(id4)
.hasKey("new_name")
.hasResourceId(16)
.hasNoUserId()
.hasTextValue("doc3")
.hasCreatedAt(DATE_1);
.hasCreatedAt(INITIAL_DATE + 5);
assertThatPropertiesRow(id5)
.hasKey("new_name")
.hasNoResourceId()
.hasUserId(100)
.hasTextValue("doc4")
.hasCreatedAt(DATE_1);
.hasCreatedAt(INITIAL_DATE + 6);
assertThatPropertiesRow(id6)
.hasKey("new_name")
.hasNoResourceId()
.hasUserId(101)
.hasTextValue("doc5")
.hasCreatedAt(DATE_1);
.hasCreatedAt(INITIAL_DATE + 7);
}

@Test
public void rename_to_same_key_has_no_effect() throws SQLException {
long now = 1_890_999L;
long id = insertProperty("foo", "bar", null, null, now);
public void rename_to_same_key_has_no_effect() {
long id = insertProperty("foo", "bar", null, null);

assertThatPropertiesRow(id)
.hasCreatedAt(now);
.hasCreatedAt(INITIAL_DATE + 2);

underTest.renamePropertyKey("foo", "foo");

@@ -1220,7 +1208,7 @@ public class PropertiesDaoTest {
.hasNoUserId()
.hasNoResourceId()
.hasTextValue("bar")
.hasCreatedAt(now);
.hasCreatedAt(INITIAL_DATE + 2);
}

@Test
@@ -1251,11 +1239,6 @@ public class PropertiesDaoTest {
session.commit();
}

private long insertProperty(String key, @Nullable String value, @Nullable Long resourceId, @Nullable Integer userId, long createdAt) {
when(system2.now()).thenReturn(createdAt);
return insertProperty(key, value, resourceId, userId);
}

private long insertProperty(String key, @Nullable String value, @Nullable Long resourceId, @Nullable Integer userId) {
PropertyDto dto = new PropertyDto().setKey(key)
.setResourceId(resourceId)

+ 21
- 3
server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/QualityGateConditionDaoTest.java View File

@@ -19,6 +19,8 @@
*/
package org.sonar.db.qualitygate;

import java.util.Collection;
import java.util.Comparator;
import java.util.Random;
import java.util.stream.IntStream;
import org.junit.Rule;
@@ -52,13 +54,29 @@ public class QualityGateConditionDaoTest {
public void testSelectForQualityGate() {
long qg1Id = 1L;
long qg2Id = 2L;
int qg1Conditions = 1 + new Random().nextInt(5);
int qg1Conditions = 2 + new Random().nextInt(5);
int qg2Conditions = 10 + new Random().nextInt(5);

IntStream.range(0, qg1Conditions).forEach(i -> insertQGCondition(qg1Id));
IntStream.range(0, qg2Conditions).forEach(i -> insertQGCondition(qg2Id));

assertThat(underTest.selectForQualityGate(dbSession, qg1Id)).hasSize(qg1Conditions);
assertThat(underTest.selectForQualityGate(dbSession, qg2Id)).hasSize(qg2Conditions);
Collection<QualityGateConditionDto> conditions = underTest.selectForQualityGate(dbSession, qg1Id);
assertThat(conditions).hasSize(qg1Conditions);
assertThat(conditions)
.extracting("id")
.containsExactly(conditions.stream()
.sorted(Comparator.comparing(QualityGateConditionDto::getCreatedAt))
.map(QualityGateConditionDto::getId).toArray());

conditions = underTest.selectForQualityGate(dbSession, qg2Id);
assertThat(conditions).hasSize(qg2Conditions);
assertThat(conditions)
.extracting("id")
.containsExactly(conditions.stream()
.sorted(Comparator.comparing(QualityGateConditionDto::getCreatedAt))
.map(QualityGateConditionDto::getId)
.toArray());

assertThat(underTest.selectForQualityGate(dbSession, 5)).isEmpty();
}


+ 11
- 1
sonar-plugin-api-impl/src/main/java/org/sonar/api/impl/utils/TestSystem2.java View File

@@ -32,12 +32,22 @@ public class TestSystem2 extends System2 {
return this;
}

public TestSystem2 tick() {
throwExceptionIfNowLesserOrEqualZero();
this.now = this.now + 1;
return this;
}

@Override
public long now() {
throwExceptionIfNowLesserOrEqualZero();
return now;
}

private void throwExceptionIfNowLesserOrEqualZero() {
if (now <= 0L) {
throw new IllegalStateException("Method setNow() was not called by test");
}
return now;
}

public TestSystem2 setDefaultTimeZone(TimeZone defaultTimeZone) {

+ 102
- 0
sonar-plugin-api-impl/src/test/java/org/sonar/api/impl/utils/TestSystem2Test.java View File

@@ -0,0 +1,102 @@
/*
* SonarQube
* Copyright (C) 2009-2019 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.api.impl.utils;

import java.util.TimeZone;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;


public class TestSystem2Test {

private TestSystem2 underTest;

@Rule
public ExpectedException expectedException = ExpectedException.none();

@Before
public void setup() {
underTest = new TestSystem2();
}

@Test
public void test_tick() {
underTest.setNow(1000L);
underTest.tick();
Assert.assertEquals(underTest.now(), 1001L);
}

@Test
public void test_now() {
underTest.setNow(1000L);
Assert.assertEquals(underTest.now(), 1000L);
}

@Test
public void test_default_time_zone() {
underTest.setDefaultTimeZone(TimeZone.getDefault());
TimeZone result = underTest.getDefaultTimeZone();
Assert.assertNotNull(result);
Assert.assertEquals(result.getID(), TimeZone.getDefault().getID());
}

@Test
public void throw_ISE_if_now_equal_zero() {
underTest.setNow(0);

expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("Method setNow() was not called by test");

underTest.now();
}

@Test
public void throw_ISE_if_now_lesser_than_zero() {
underTest.setNow(-1);

expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("Method setNow() was not called by test");

underTest.now();
}

@Test
public void throw_ISE_if_now_equal_zero_and_try_to_tick() {
underTest.setNow(0);

expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("Method setNow() was not called by test");

underTest.tick();
}

@Test
public void throw_ISE_if_now_lesser_than_zero_and_try_to_tick() {
underTest.setNow(-1);

expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("Method setNow() was not called by test");

underTest.tick();
}
}

Loading…
Cancel
Save