Skip to content
Snippets Groups Projects
Commit a12a8a15 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Configured DAO testing

parent febfcadb
No related branches found
No related tags found
No related merge requests found
...@@ -2,11 +2,19 @@ stages: ...@@ -2,11 +2,19 @@ stages:
- test - test
- dockerize - dockerize
variables:
# to avoid "fatal: git fetch-pack: expected shallow list"
GIT_STRATEGY: clone
test: test:
stage: test stage: test
tags: tags:
- docker - docker
image: "git.ia2.inaf.it:5050/vospace/vospace-oats/vospace-test-env"
variables:
FILE_CATALOG_REPO_URL: "https://gitlab-ci-token:${CI_JOB_TOKEN}@www.ict.inaf.it/gitlab/vospace/vospace-file-catalog.git"
script: script:
- git clone ${FILE_CATALOG_REPO_URL}
- mvn clean test - mvn clean test
- awk -F"," '{ instructions += $4 + $5; covered += $5 } END { print "coverage=" 100*covered/instructions }' target/site/jacoco/jacoco.csv - awk -F"," '{ instructions += $4 + $5; covered += $5 } END { print "coverage=" 100*covered/instructions }' target/site/jacoco/jacoco.csv
coverage: '/coverage=\d+\.\d+/' coverage: '/coverage=\d+\.\d+/'
......
...@@ -15,8 +15,10 @@ ...@@ -15,8 +15,10 @@
<description>VOSpace File service</description> <description>VOSpace File service</description>
<properties> <properties>
<java.version>14</java.version>
<finalName>${project.artifactId}-${project.version}</finalName> <finalName>${project.artifactId}-${project.version}</finalName>
<!-- File catalog repository directory -->
<init_database_scripts_path>../../../vospace-file-catalog</init_database_scripts_path>
<zonky.postgres-binaries.version>12.5.0</zonky.postgres-binaries.version>
</properties> </properties>
<dependencies> <dependencies>
...@@ -57,7 +59,50 @@ ...@@ -57,7 +59,50 @@
<artifactId>rap-client</artifactId> <artifactId>rap-client</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
</dependency> </dependency>
<!-- Embedded PostgreSQL: -->
<dependency>
<groupId>com.opentable.components</groupId>
<artifactId>otj-pg-embedded</artifactId>
<version>0.13.3</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>platform-linux</id>
<activation>
<os>
<family>unix</family>
</os>
</activation>
<dependencies>
<dependency>
<groupId>io.zonky.test.postgres</groupId>
<artifactId>embedded-postgres-binaries-linux-amd64</artifactId>
<version>${zonky.postgres-binaries.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
<profile>
<id>platform-windows</id>
<activation>
<os>
<family>windows</family>
</os>
</activation>
<dependencies>
<dependency>
<groupId>io.zonky.test.postgres</groupId>
<artifactId>embedded-postgres-binaries-windows-amd64</artifactId>
<version>${zonky.postgres-binaries.version}</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</profile>
</profiles>
<repositories> <repositories>
<repository> <repository>
...@@ -69,6 +114,25 @@ ...@@ -69,6 +114,25 @@
<build> <build>
<finalName>${finalName}</finalName> <finalName>${finalName}</finalName>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
<includes>
<include>test.properties</include>
</includes>
</testResource>
<testResource>
<directory>src/test/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/*</include>
</includes>
<excludes>
<exclude>test.properties</exclude>
</excludes>
</testResource>
</testResources>
<plugins> <plugins>
<plugin> <plugin>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
......
package it.inaf.ia2.transfer.persistence;
import com.opentable.db.postgres.embedded.EmbeddedPostgres;
import com.opentable.db.postgres.embedded.PgBinaryResolver;
import com.opentable.db.postgres.embedded.UncompressBundleDirectoryResolver;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.Connection;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.sql.DataSource;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.init.ScriptUtils;
/**
* Generates a DataSource that can be used for testing DAO classes. It loads an
* embedded Postgres database and fills it using the data from
* vospace-transfer-service repository (folder must exists; it location can be
* configured using the init_database_scripts_path in test.properties).
*/
@TestConfiguration
public class DataSourceConfig {
@Value("${init_database_scripts_path}")
private String scriptPath;
/**
* Using the prototype scope we are generating a different database in each
* test.
*/
@Bean
@Scope("prototype")
@Primary
public DataSource dataSource() throws Exception {
DataSource embeddedPostgresDS = EmbeddedPostgres.builder()
.setPgDirectoryResolver(new UncompressBundleDirectoryResolver(new CustomPostgresBinaryResolver()))
.start().getPostgresDatabase();
initDatabase(embeddedPostgresDS);
return embeddedPostgresDS;
}
private class CustomPostgresBinaryResolver implements PgBinaryResolver {
/**
* Loads specific embedded Postgres version.
*/
@Override
public InputStream getPgBinary(String system, String architecture) throws IOException {
ClassPathResource resource = new ClassPathResource(String.format("postgres-%s-%s.txz", system.toLowerCase(), architecture));
return resource.getInputStream();
}
}
/**
* Loads SQL scripts for database initialization from
* vospace-transfer-service repo directory.
*/
private void initDatabase(DataSource dataSource) throws Exception {
try ( Connection conn = dataSource.getConnection()) {
File currentDir = new File(DataSourceConfig.class.getClassLoader().getResource(".").getFile());
File scriptDir = currentDir.toPath().resolve(scriptPath).toFile().getCanonicalFile();
assertTrue(scriptDir.exists(), "DAO tests require " + scriptDir.getAbsolutePath() + " to exists.\n"
+ "Please clone the repository from https://www.ict.inaf.it/gitlab/vospace/vospace-file-catalog.git");
File[] scripts = scriptDir.listFiles(f -> f.getName().endsWith(".sql"));
Arrays.sort(scripts); // sort alphabetically
for (File script : scripts) {
ByteArrayResource scriptResource = replaceDollarQuoting(script.toPath());
ScriptUtils.executeSqlScript(conn, scriptResource);
}
ScriptUtils.executeSqlScript(conn, new ClassPathResource("test-data.sql"));
}
}
/**
* It seems that dollar quoting (used in UDF) is broken in JDBC. Replacing
* it with single quotes solves the problem. We replace the quoting here
* instead of inside the original files because dollar quoting provides a
* better visibility.
*/
private ByteArrayResource replaceDollarQuoting(Path sqlScriptPath) throws Exception {
String scriptContent = Files.readString(sqlScriptPath);
if (scriptContent.contains("$func$")) {
String func = extractFunctionDefinition(scriptContent);
String originalFunction = "$func$" + func + "$func$";
String newFunction = "'" + func.replaceAll("'", "''") + "'";
scriptContent = scriptContent.replace(originalFunction, newFunction);
}
return new ByteArrayResource(scriptContent.getBytes());
}
private String extractFunctionDefinition(String scriptContent) {
Pattern pattern = Pattern.compile("\\$func\\$(.*?)\\$func\\$", Pattern.DOTALL);
Matcher matcher = pattern.matcher(scriptContent);
if (matcher.find()) {
return matcher.group(1);
}
throw new IllegalArgumentException(scriptContent + " doesn't contain $func$");
}
}
DELETE FROM node;
ALTER SEQUENCE node_node_id_seq RESTART WITH 1;
INSERT INTO node (parent_path, parent_relative_path, name, type, owner_id, creator_id) VALUES (NULL, NULL, '', 'container', '0', '0');
INSERT INTO node (parent_path, parent_relative_path, name, type, owner_id, creator_id, group_read, group_write) VALUES ('', NULL, 'test1', 'container', 'user1', 'user1', '{"group1","group2"}','{"group2"}'); -- /test1
INSERT INTO node (parent_path, parent_relative_path, name, type, owner_id, creator_id, group_read, group_write) VALUES ('2', NULL, '.tmp-123.txt', 'structured', 'user1', 'user1', '{"group1","group2"}','{"group2"}'); -- /test1/.tmp-123.txt
INSERT INTO node (parent_path, parent_relative_path, name, type, owner_id, creator_id, group_read, group_write) VALUES ('2', NULL, 'file1.txt', 'data', 'user1', 'user1', '{"group1","group2"}','{"group2"}'); -- /test1/file1.txt
INSERT INTO node (parent_path, parent_relative_path, name, type, owner_id, creator_id, group_read, group_write) VALUES ('2', NULL, 'file2.txt', 'data', 'user1', 'user1', '{"group1","group2"}','{"group2"}'); -- /test1/file2.txt
# File catalog repository directory (filled by pom.xml, overridable passing environment variable)
init_database_scripts_path=@init_database_scripts_path@
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment