Skip to content

Commit

Permalink
repo-sqale: first batch of tests, still rather exploratory
Browse files Browse the repository at this point in the history
Not run automatically yet, but they are already helping. :-)
  • Loading branch information
virgo47 committed Mar 3, 2021
1 parent 32710c6 commit 407e375
Show file tree
Hide file tree
Showing 6 changed files with 282 additions and 27 deletions.
6 changes: 6 additions & 0 deletions repo/repo-sqale/pom.xml
Expand Up @@ -166,6 +166,12 @@
<artifactId>spring-aspects</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
@@ -0,0 +1,97 @@
/*
* Copyright (C) 2010-2021 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/
package com.evolveum.midpoint.repo.sqale;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import java.util.List;
import java.util.UUID;

import org.testng.annotations.Test;

import com.evolveum.midpoint.repo.sqale.qmodel.focus.MUser;
import com.evolveum.midpoint.repo.sqale.qmodel.focus.QUser;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;

public class SqaleRepoAddObjectTest extends SqaleRepoBaseTest {

@Test
public void test100AddNamedUserWorksOk() throws ObjectAlreadyExistsException, SchemaException {
OperationResult result = createOperationResult();

given("user with a name");
String userName = "user" + getTestNumber();
UserType userType = new UserType(prismContext)
.name(userName);

when("adding it to the repository");
repositoryService.addObject(userType.asPrismObject(), null, result);

then("operation is successful and user row for it is created");
assertResult(result);

var u = aliasFor(QUser.class);
List<MUser> users = select(u, u.nameOrig.eq(userName));
assertThat(users).hasSize(1);

MUser mUser = users.get(0);
assertThat(mUser.oid).isNotNull();
assertThat(mUser.nameNorm).isNotNull(); // normalized name is stored
assertThat(mUser.version).isEqualTo(1); // base version is set
// read-only column with value generated/stored in the database
assertThat(mUser.objectType).isEqualTo(MObjectTypeMapping.USER.code());
}

@Test
public void test101AddUserWithoutNameFails() {
OperationResult result = createOperationResult();

given("user without specified name");
long baseCount = count(QUser.class);
UserType userType = new UserType(prismContext);

expect("adding it to the repository throws exception and no row is created");
assertThatThrownBy(() -> repositoryService.addObject(userType.asPrismObject(), null, result))
.isInstanceOf(SchemaException.class)
.hasMessage("Attempt to add object without name.");

// TODO what is the reason for result when it's still OK unless I set it here - out of the called method?
// assertResult(result);
assertCount(QUser.class, baseCount);
}

@Test
public void test102AddUserWithProvidedOidWorksOk() throws ObjectAlreadyExistsException, SchemaException {
OperationResult result = createOperationResult();

given("user with provided OID");
UUID providedOid = UUID.randomUUID();
String userName = "user" + getTestNumber();
UserType userType = new UserType(prismContext)
.oid(providedOid.toString())
.name(userName);

when("adding it to the repository");
repositoryService.addObject(userType.asPrismObject(), null, result);

then("operation is successful and user row with provided OID is created");
assertResult(result);

var u = aliasFor(QUser.class);
List<MUser> users = select(u, u.nameOrig.eq(userName));
assertThat(users).hasSize(1);

MUser mUser = users.get(0);
assertThat(mUser.oid).isEqualTo(providedOid);
assertThat(mUser.version).isEqualTo(1); // base version is set
}

}
@@ -0,0 +1,106 @@
/*
* Copyright (C) 2010-2021 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/
package com.evolveum.midpoint.repo.sqale;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.Arrays;
import java.util.List;

import com.querydsl.core.types.Predicate;
import com.querydsl.sql.SQLQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.testng.annotations.BeforeClass;

import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.repo.sqale.qmodel.assignment.QAssignmentMapping;
import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping;
import com.evolveum.midpoint.repo.sqale.qmodel.ref.QReferenceMapping;
import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.test.util.AbstractSpringTest;
import com.evolveum.midpoint.test.util.InfraTestMixin;
import com.evolveum.midpoint.test.util.TestUtil;

@ContextConfiguration(locations = { "../../../../../ctx-test.xml" })
public class SqaleRepoBaseTest extends AbstractSpringTest
implements InfraTestMixin {

@Autowired protected SqaleRepositoryService repositoryService;
@Autowired protected SqaleRepoContext sqlRepoContext;
@Autowired protected PrismContext prismContext;

@BeforeClass
public void cleanDatabase() {
try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession().startTransaction()) {
// TODO delete other non-object tables here
jdbcSession.newDelete(QAssignmentMapping.INSTANCE.defaultAlias()).execute();
jdbcSession.newDelete(QReferenceMapping.INSTANCE.defaultAlias()).execute();
jdbcSession.newDelete(QObjectMapping.INSTANCE.defaultAlias()).execute();
}
}

protected void assertResult(OperationResult opResult) {
if (opResult.isEmpty()) {
// this is OK. Nothing added to result.
return;
}
opResult.computeStatus();
TestUtil.assertSuccess(opResult);
}

/** Returns default query instance (alias) for the specified query type. */
protected <R, Q extends FlexibleRelationalPathBase<R>> Q aliasFor(Class<Q> entityPath) {
return sqlRepoContext.getMappingByQueryType(entityPath).defaultAlias();
}

/** Returns new named query instance (alias) for the specified query type. */
protected <R, Q extends FlexibleRelationalPathBase<R>> Q aliasFor(
Class<Q> entityPath, String name) {
return sqlRepoContext.getMappingByQueryType(entityPath).newAlias(name);
}

protected <R, Q extends FlexibleRelationalPathBase<R>> void assertCount(
Class<Q> queryType, long expectedCount) {
assertCount(aliasFor(queryType), expectedCount);
}

protected <R, Q extends FlexibleRelationalPathBase<R>> void assertCount(
Q path, long expectedCount, Predicate... conditions) {
assertThat(count(path, conditions))
.as("Count for %s where %s", path, Arrays.toString(conditions))
.isEqualTo(expectedCount);
}

protected <R, Q extends FlexibleRelationalPathBase<R>> long count(
Class<Q> queryType, Predicate... conditions) {
return count(aliasFor(queryType), conditions);
}

protected <R, Q extends FlexibleRelationalPathBase<R>> long count(
Q path, Predicate[] conditions) {
try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession()) {
SQLQuery<?> query = jdbcSession.newQuery()
.from(path)
.where(conditions);
return query.fetchCount();
}
}

protected <R, Q extends FlexibleRelationalPathBase<R>> List<R> select(
Q path, Predicate... conditions) {
try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession()) {
return jdbcSession.newQuery()
.from(path)
.where(conditions)
.select(path)
.fetch();
}
}
}

This file was deleted.

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2010-2021 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/
package com.evolveum.midpoint.repo.sqale;

import static org.assertj.core.api.Assertions.assertThat;

import org.testng.annotations.Test;

import com.evolveum.midpoint.repo.api.DeleteObjectResult;
import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainer;
import com.evolveum.midpoint.repo.sqale.qmodel.object.QObject;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;

public class SqaleRepoSmokeTest extends SqaleRepoBaseTest {

private String sanityUserOid;

@Test
public void test000Sanity() {
assertThat(repositoryService).isNotNull();

// DB should be empty
assertCount(QObject.CLASS, 0);
assertCount(QContainer.CLASS, 0);

// selects check also mapping to M-classes
assertThat(select(aliasFor(QObject.CLASS))).isEmpty();
assertThat(select(aliasFor(QContainer.CLASS))).isEmpty();
}

@Test
public void test100AddObject() throws ObjectAlreadyExistsException, SchemaException {
OperationResult result = createOperationResult();

UserType userType = new UserType(prismContext)
.name("sanity-user");
sanityUserOid = repositoryService.addObject(userType.asPrismObject(), null, result);

assertThat(sanityUserOid).isNotNull();
assertResult(result);
}

@Test(enabled = false) // TODO deleteObject not implemented yet
public void test900DeleteObject() throws ObjectNotFoundException {
OperationResult result = createOperationResult();

DeleteObjectResult deleteResult =
repositoryService.deleteObject(UserType.class, sanityUserOid, result);

assertThat(deleteResult).isNotNull();
assertResult(result);
}
}
16 changes: 12 additions & 4 deletions repo/repo-sqale/src/test/resources/config-test.xml
Expand Up @@ -12,11 +12,17 @@
<extensionDir>./src/test/resources/schema</extensionDir>
</global>
<repository>
<!-- TODO switch to sqale, of course -->
<repositoryServiceFactoryClass>com.evolveum.midpoint.repo.sql.testing.TestSqlRepositoryFactory</repositoryServiceFactoryClass>
<type>sqale</type>

<port>5438</port>
<dropIfExists>true</dropIfExists>
<!--
Use this Vagrantbox to run this:
https://github.com/virgo47/midpoint-vagrantboxes/tree/master/vagrant-midpoint-db-pg-new-repo
Then connect to it with the info below and execute pgnew-repo.sql file to initialize the DB.
-->
<database>postgresql</database>
<jdbcUrl>jdbc:postgresql://192.168.56.33:5432/midtest</jdbcUrl>
<jdbcUsername>midtest</jdbcUsername>
<jdbcPassword>password</jdbcPassword>

<performanceStatisticsLevel>10</performanceStatisticsLevel>
<performanceStatisticsFile>./target/performance.log</performanceStatisticsFile>
Expand All @@ -25,6 +31,7 @@
<createMissingCustomColumns>true</createMissingCustomColumns>
</repository>
<audit>
<!-- TODO audit not supported yet
<auditService>
<auditServiceFactoryClass>com.evolveum.midpoint.repo.sql.SqlAuditServiceFactory</auditServiceFactoryClass>
<customColumn>
Expand All @@ -36,6 +43,7 @@
<eventRecordPropertyName>bar</eventRecordPropertyName>
</customColumn>
</auditService>
-->
</audit>
<icf>
<scanClasspath>true</scanClasspath>
Expand Down

0 comments on commit 407e375

Please sign in to comment.