Skip to content
Snippets Groups Projects
Commit 7f77e439 authored by Martin Weise's avatar Martin Weise
Browse files

added automatic integration test dependencies

Former-commit-id: 3b957dd7
parent 37ad7609
No related branches found
No related tags found
1 merge request!23Sprint results
Showing
with 265 additions and 121 deletions
......@@ -85,6 +85,8 @@ services:
SPRING_PROFILES_ACTIVE: docker
ports:
- 9092:9092
volumes:
- /var/run/docker.sock:/var/run/docker.sock
links:
- fda-discovery-service
- fda-container-service
......
......@@ -23,11 +23,11 @@ public class ContainerGateway {
this.restClient = restClient;
}
public ContainerDto inspect(Long id) {
final ResponseEntity<ContainerDto> response;
response = restClient.exchange(URL + id, HttpMethod.GET, null, new ParameterizedTypeReference<>() {
});
return response.getBody();
}
// public ContainerDto inspect(Long id) {
// final ResponseEntity<ContainerDto> response;
// response = restClient.exchange(URL + id, HttpMethod.GET, null, new ParameterizedTypeReference<>() {
// });
// return response.getBody();
// }
}
......@@ -169,6 +169,10 @@
<version>${jacoco.version}</version>
<configuration>
<excludes>
<exclude>at/tuwien/config/**/*</exclude>
<exclude>at/tuwien/mapper/**/*</exclude>
<exclude>at/tuwien/exception/**/*</exclude>
<exclude>**/JdbcConnector.class</exclude>
<exclude>**/FdaDatabaseManagingApplication.class</exclude>
</excludes>
</configuration>
......
package at.tuwien;
import at.tuwien.entities.container.Container;
import at.tuwien.entities.container.image.ContainerImage;
import at.tuwien.entities.database.Database;
import org.springframework.test.context.TestPropertySource;
import java.time.Instant;
@TestPropertySource(locations = "classpath:application.properties")
public abstract class BaseIntegrationTest {
public final Long IMAGE_1_ID = 1L;
public final String IMAGE_1_REPO = "postgres";
public final String IMAGE_1_TAG = "latest";
public final Integer IMAGE_1_PORT = 5432;
public final Instant IMAGE_1_CREATED = Instant.now();
public final Instant IMAGE_1_UPDATED = Instant.now();
public final Long DATABASE_1_ID = 1L;
public final String DATABASE_1_NAME = "Fundamentals SEC";
public final String DATABASE_1_INTERNALNAME = "fundamentals_sec";
public final String DATABASE_1_IMAGE = "postgres:latest";
public final Instant DATABASE_1_CREATED = Instant.now();
public final Instant DATABASE_1_UPDATED = Instant.now();
public final Long CONTAINER_1_ID = 1L;
public final String CONTAINER_1_NAME = "fda-userdb-fundamentals-sec";
public final Instant CONTAINER_1_CREATED = Instant.now();
public final Instant CONTAINER_1_UPDATED = Instant.now();
public final ContainerImage IMAGE_1 = ContainerImage.builder()
.id(IMAGE_1_ID)
.repository(IMAGE_1_REPO)
.tag(IMAGE_1_TAG)
.created(IMAGE_1_CREATED)
.defaultPort(IMAGE_1_PORT)
.compiled(IMAGE_1_UPDATED)
.build();
public final Container CONTAINER_1 = Container.builder()
.id(CONTAINER_1_ID)
.name(CONTAINER_1_NAME)
.internalName(CONTAINER_1_NAME)
.containerCreated(CONTAINER_1_CREATED)
.lastModified(CONTAINER_1_UPDATED)
.image(IMAGE_1)
.build();
public final Database DATABASE_1 = Database.builder()
.id(DATABASE_1_ID)
.name(DATABASE_1_NAME)
.internalName(DATABASE_1_INTERNALNAME)
.created(DATABASE_1_CREATED)
.lastModified(DATABASE_1_UPDATED)
.container(CONTAINER_1)
.build();
}
package at.tuwien;
import at.tuwien.entities.container.Container;
import at.tuwien.entities.container.image.ContainerImage;
import at.tuwien.entities.database.Database;
import org.springframework.test.context.TestPropertySource;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;
import static java.time.temporal.ChronoUnit.HOURS;
@TestPropertySource(locations = "classpath:application.properties")
public abstract class BaseUnitTest {
public final static Long IMAGE_1_ID = 1L;
public final static String IMAGE_1_REPO = "postgres";
public final static String IMAGE_1_TAG = "latest";
public final static Integer IMAGE_1_PORT = 5432;
public final static Instant IMAGE_1_CREATED = Instant.now();
public final static Instant IMAGE_1_UPDATED = Instant.now();
public final static Long IMAGE_2_ID = 2L;
public final static String IMAGE_2_REPO = "mariadb";
public final static String IMAGE_2_TAG = "latest";
public final static Integer IMAGE_2_PORT = 5432;
public final static Instant IMAGE_2_CREATED = Instant.now();
public final static Instant IMAGE_2_UPDATED = Instant.now();
public final static Long DATABASE_1_ID = 1L;
public final static String DATABASE_1_NAME = "Fundamentals SEC";
public final static String DATABASE_1_INTERNALNAME = "sec";
public final static Instant DATABASE_1_CREATED = Instant.now().minus(1, HOURS);
public final static Instant DATABASE_1_UPDATED = Instant.now();
public final static Long DATABASE_2_ID = 2L;
public final static String DATABASE_2_NAME = "River Flow";
public final static String DATABASE_2_INTERNALNAME = "river_flow";
public final static Instant DATABASE_2_CREATED = Instant.now().minus(1, HOURS);
public final static Instant DATABASE_2_UPDATED = Instant.now();
public final static Long CONTAINER_1_ID = 1L;
public static String CONTAINER_1_HASH = "deadbeef";
public final static String CONTAINER_1_NAME = "Fundamentals";
public final static String CONTAINER_1_INTERNALNAME = "fda-userdb-fundamentals";
public final static Instant CONTAINER_1_CREATED = Instant.now().minus(2, HOURS);
public final static Instant CONTAINER_1_UPDATED = Instant.now();
public final static Long CONTAINER_2_ID = 2L;
public final static String CONTAINER_2_NAME = "BOKU";
public final static String CONTAINER_2_INTERNALNAME = "fda-userdb-boku";
public final static Instant CONTAINER_2_CREATED = Instant.now().minus(2, HOURS);
public final static Instant CONTAINER_2_UPDATED = Instant.now();
public final static ContainerImage IMAGE_1 = ContainerImage.builder()
.id(IMAGE_1_ID)
.repository(IMAGE_1_REPO)
.tag(IMAGE_1_TAG)
.created(IMAGE_1_CREATED)
.defaultPort(IMAGE_1_PORT)
.compiled(IMAGE_1_UPDATED)
.build();
public final static ContainerImage IMAGE_2 = ContainerImage.builder()
.id(IMAGE_2_ID)
.repository(IMAGE_2_REPO)
.tag(IMAGE_2_TAG)
.created(IMAGE_2_CREATED)
.defaultPort(IMAGE_2_PORT)
.compiled(IMAGE_2_UPDATED)
.build();
public final static Container CONTAINER_1 = Container.builder()
.id(CONTAINER_1_ID)
.name(CONTAINER_1_NAME)
.hash(CONTAINER_1_HASH)
.internalName(CONTAINER_1_NAME)
.containerCreated(CONTAINER_1_CREATED)
.lastModified(CONTAINER_1_UPDATED)
.image(IMAGE_1)
.build();
public final static Container CONTAINER_2 = Container.builder()
.id(CONTAINER_2_ID)
.name(CONTAINER_2_NAME)
.internalName(CONTAINER_2_NAME)
.containerCreated(CONTAINER_2_CREATED)
.lastModified(CONTAINER_2_UPDATED)
.image(IMAGE_2)
.build();
public final static Database DATABASE_1 = Database.builder()
.id(DATABASE_1_ID)
.name(DATABASE_1_NAME)
.internalName(DATABASE_1_INTERNALNAME)
.created(DATABASE_1_CREATED)
.lastModified(DATABASE_1_UPDATED)
.container(CONTAINER_1)
.build();
public final static Database DATABASE_2 = Database.builder()
.id(DATABASE_2_ID)
.name(DATABASE_2_NAME)
.internalName(DATABASE_2_INTERNALNAME)
.created(DATABASE_2_CREATED)
.lastModified(DATABASE_2_UPDATED)
.container(CONTAINER_2)
.build();
public final static List<String> IMAGE_1_ENVIRONMENT = List.of("POSTGRES_USER=postgres",
"POSTGRES_PASSWORD=postgres", "POSTGRES_DB=" + DATABASE_1_INTERNALNAME);
}
package at.tuwien.endpoint;
import at.tuwien.BaseIntegrationTest;
import at.tuwien.BaseUnitTest;
import at.tuwien.api.database.DatabaseBriefDto;
import at.tuwien.api.database.DatabaseCreateDto;
import at.tuwien.endpoints.DatabaseEndpoint;
......@@ -26,7 +26,7 @@ import static org.mockito.Mockito.when;
@SpringBootTest
@ExtendWith(SpringExtension.class)
public class EndpointUnitTest extends BaseIntegrationTest {
public class EndpointUnitTest extends BaseUnitTest {
@MockBean
private DatabaseService databaseService;
......
package at.tuwien.gateway;
import at.tuwien.BaseUnitTest;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@SpringBootTest
@ExtendWith(SpringExtension.class)
public class GatewayUnitTest extends BaseUnitTest {
}
package at.tuwien.service;
import at.tuwien.BaseIntegrationTest;
import at.tuwien.BaseUnitTest;
import at.tuwien.exception.DatabaseConnectionException;
import at.tuwien.exception.DatabaseMalformedException;
import com.netflix.discovery.converters.Auto;
import org.apache.catalina.connector.Connector;
import org.h2.jdbc.JdbcConnection;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.exception.NotModifiedException;
import com.github.dockerjava.api.model.HostConfig;
import com.github.dockerjava.api.model.PortBinding;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
......@@ -13,26 +15,29 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import javax.transaction.Transactional;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Properties;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;
/**
* We cannot use the postgreSQL service directly since it connects within the docker network, we need "127.0.0.1" = localhost
*/
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
@Transactional // rollback on each test
@SpringBootTest
@ExtendWith(SpringExtension.class)
public class PostgresIntegrationTest extends BaseIntegrationTest {
public class PostgresIntegrationTest extends BaseUnitTest {
@MockBean
private PostgresService postgresService;
......@@ -40,38 +45,71 @@ public class PostgresIntegrationTest extends BaseIntegrationTest {
@Autowired
private Properties postgresProperties;
private Connection CONNECTION;
@Autowired
private HostConfig hostConfig;
@Autowired
private DockerClient dockerClient;
@BeforeEach
public void beforeEach() throws SQLException {
CONNECTION = DriverManager.getConnection("jdbc:postgresql://localhost:5433/fda-test", postgresProperties);
public void beforeEach() throws SQLException, InterruptedException {
afterEach();
/* create container */
final CreateContainerResponse request = dockerClient.createContainerCmd("postgres:latest")
.withEnv(IMAGE_1_ENVIRONMENT)
.withHostConfig(hostConfig.withNetworkMode("bridge")
.withPortBindings(PortBinding.parse("5433:5432")))
.withName(CONTAINER_1_INTERNALNAME)
.withHostName(CONTAINER_1_INTERNALNAME)
.exec();
System.out.println("CREATE CONTAINER " + CONTAINER_1_INTERNALNAME);
/* start container */
dockerClient.startContainerCmd(request.getId()).exec();
System.out.println("START CONTAINER " + CONTAINER_1_INTERNALNAME);
CONTAINER_1_HASH = request.getId();
CONTAINER_1.setHash(CONTAINER_1_HASH);
System.out.println("Wait 5s for DB to get up");
Thread.sleep(5 * 1000);
}
@AfterEach
public void afterEach() throws SQLException {
final Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5433/", postgresProperties);
final PreparedStatement statement = connection.prepareStatement("DROP DATABASE IF EXISTS " + DATABASE_1_INTERNALNAME + ";");
statement.execute();
public void afterEach() {
/* stop containers and remove them */
dockerClient.listContainersCmd()
.withShowAll(true)
.exec()
.forEach(container -> {
try {
dockerClient.stopContainerCmd(container.getId()).exec();
System.out.println("STOP CONTAINER " + Arrays.toString(container.getNames()));
} catch (NotModifiedException e) {
// ignore
}
dockerClient.removeContainerCmd(container.getId()).exec();
System.out.println("DELETE CONTAINER " + Arrays.toString(container.getNames()));
});
}
@Test
public void create_succeeds() throws SQLException, DatabaseConnectionException, DatabaseMalformedException {
final Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5433/" + DATABASE_1_INTERNALNAME, postgresProperties);
when(postgresService.open(anyString(), any()))
.thenReturn(CONNECTION);
when(postgresService.getCreateDatabaseStatement(CONNECTION, DATABASE_1))
.thenReturn(connection);
when(postgresService.getCreateDatabaseStatement(connection, DATABASE_2))
.thenCallRealMethod();
doCallRealMethod()
.when(postgresService)
.create(DATABASE_1);
.create(DATABASE_2);
/* test */
postgresService.create(DATABASE_1);
postgresService.create(DATABASE_2);
}
@Test
public void create_noConnection_fails() throws SQLException, DatabaseConnectionException, DatabaseMalformedException {
final Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5433/" + DATABASE_1_INTERNALNAME, postgresProperties);
when(postgresService.open(anyString(), any()))
.thenThrow(SQLException.class);
when(postgresService.getCreateDatabaseStatement(CONNECTION, DATABASE_1))
when(postgresService.getCreateDatabaseStatement(connection, DATABASE_1))
.thenCallRealMethod();
doCallRealMethod()
.when(postgresService)
......@@ -85,9 +123,10 @@ public class PostgresIntegrationTest extends BaseIntegrationTest {
@Test
public void create_invalidSyntax_fails() throws SQLException, DatabaseConnectionException, DatabaseMalformedException {
final Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5433/" + DATABASE_1_INTERNALNAME, postgresProperties);
when(postgresService.open(anyString(), any()))
.thenReturn(CONNECTION);
when(postgresService.getCreateDatabaseStatement(CONNECTION, DATABASE_1))
.thenReturn(connection);
when(postgresService.getCreateDatabaseStatement(connection, DATABASE_1))
.thenThrow(SQLException.class);
doCallRealMethod()
.when(postgresService)
......@@ -106,9 +145,10 @@ public class PostgresIntegrationTest extends BaseIntegrationTest {
@Test
public void delete_noConnection_fails() throws SQLException, DatabaseConnectionException, DatabaseMalformedException {
final Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5433/" + DATABASE_1_INTERNALNAME, postgresProperties);
when(postgresService.open(anyString(), any()))
.thenThrow(SQLException.class);
when(postgresService.getDeleteDatabaseStatement(CONNECTION, DATABASE_1))
when(postgresService.getDeleteDatabaseStatement(connection, DATABASE_1))
.thenCallRealMethod();
doCallRealMethod()
.when(postgresService)
......@@ -122,9 +162,10 @@ public class PostgresIntegrationTest extends BaseIntegrationTest {
@Test
public void delete_invalidSyntax_fails() throws SQLException, DatabaseConnectionException, DatabaseMalformedException {
final Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5433/" + DATABASE_1_INTERNALNAME, postgresProperties);
when(postgresService.open(anyString(), any()))
.thenReturn(CONNECTION);
when(postgresService.getDeleteDatabaseStatement(CONNECTION, DATABASE_1))
.thenReturn(connection);
when(postgresService.getDeleteDatabaseStatement(connection, DATABASE_1))
.thenThrow(SQLException.class);
doCallRealMethod()
.when(postgresService)
......@@ -138,23 +179,25 @@ public class PostgresIntegrationTest extends BaseIntegrationTest {
@Test
public void getCreateStatement_succeeds() throws SQLException {
final Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5433/" + DATABASE_1_INTERNALNAME, postgresProperties);
when(postgresService.open(anyString(), any()))
.thenReturn(CONNECTION);
when(postgresService.getCreateDatabaseStatement(CONNECTION, DATABASE_1))
.thenReturn(connection);
when(postgresService.getCreateDatabaseStatement(connection, DATABASE_1))
.thenCallRealMethod();
/* test */
postgresService.getCreateDatabaseStatement(CONNECTION, DATABASE_1);
postgresService.getCreateDatabaseStatement(connection, DATABASE_1);
}
@Test
public void getDeleteStatement_succeeds() throws SQLException {
final Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5433/" + DATABASE_1_INTERNALNAME, postgresProperties);
when(postgresService.open(anyString(), any()))
.thenReturn(CONNECTION);
when(postgresService.getDeleteDatabaseStatement(CONNECTION, DATABASE_1))
.thenReturn(connection);
when(postgresService.getDeleteDatabaseStatement(connection, DATABASE_1))
.thenCallRealMethod();
/* test */
postgresService.getDeleteDatabaseStatement(CONNECTION, DATABASE_1);
postgresService.getDeleteDatabaseStatement(connection, DATABASE_1);
}
}
package at.tuwien.service;
import at.tuwien.BaseIntegrationTest;
import at.tuwien.BaseUnitTest;
import at.tuwien.api.database.DatabaseCreateDto;
import at.tuwien.entities.container.Container;
import at.tuwien.entities.database.Database;
......@@ -24,7 +24,7 @@ import static org.mockito.Mockito.when;
@SpringBootTest
@ExtendWith(SpringExtension.class)
public class ServiceUnitTest extends BaseIntegrationTest {
public class ServiceUnitTest extends BaseUnitTest {
@Autowired
private DatabaseService databaseService;
......@@ -73,7 +73,8 @@ public class ServiceUnitTest extends BaseIntegrationTest {
}
@Test
public void delete_succeeds() throws DatabaseConnectionException, DatabaseNotFoundException, ImageNotSupportedException, DatabaseMalformedException {
public void delete_succeeds() throws DatabaseConnectionException, DatabaseNotFoundException,
ImageNotSupportedException, DatabaseMalformedException {
when(databaseRepository.findById(DATABASE_1_ID))
.thenReturn(Optional.of(DATABASE_1));
......@@ -106,7 +107,8 @@ public class ServiceUnitTest extends BaseIntegrationTest {
}
@Test
public void create_succeeds() throws DatabaseConnectionException, ImageNotSupportedException, ContainerNotFoundException, DatabaseMalformedException {
public void create_succeeds() throws DatabaseConnectionException, ImageNotSupportedException,
ContainerNotFoundException, DatabaseMalformedException {
final DatabaseCreateDto request = DatabaseCreateDto.builder()
.name(DATABASE_1_NAME)
.containerId(CONTAINER_1_ID)
......@@ -139,14 +141,12 @@ public class ServiceUnitTest extends BaseIntegrationTest {
@Test
public void create_notSupported_fails() {
final Container notPostgresContainer = CONTAINER_1;
notPostgresContainer.getImage().setRepository("mariadb");
final DatabaseCreateDto request = DatabaseCreateDto.builder()
.name(DATABASE_1_NAME)
.containerId(CONTAINER_1_ID)
.name(DATABASE_2_NAME)
.containerId(CONTAINER_2_ID)
.build();
when(containerRepository.findById(CONTAINER_1_ID))
.thenReturn(Optional.of(notPostgresContainer));
when(containerRepository.findById(CONTAINER_2_ID))
.thenReturn(Optional.of(CONTAINER_2));
/* test */
assertThrows(ImageNotSupportedException.class, () -> {
......
#!/bin/bash
\ No newline at end of file
docker stop fda-metadata-db-test
docker rm fda-metadata-db-test
\ No newline at end of file
#!/bin/bash
\ No newline at end of file
docker stop fda-metadata-db-test
docker rm fda-metadata-db-test
docker run --name fda-metadata-db-test \
--publish 5433:5432 \
--env POSTGRES_USER=postgres \
--env POSTGRES_PASSWORD=postgres \
--env POSTGRES_DB=fda-test \
--detach postgres:latest
\ No newline at end of file
package at.tuwien.config;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.model.HostConfig;
import com.github.dockerjava.api.model.RestartPolicy;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientBuilder;
import com.github.dockerjava.core.DockerClientConfig;
import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
import com.github.dockerjava.transport.DockerHttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DockerConfig {
@Bean
public HostConfig hostConfig() {
return HostConfig.newHostConfig()
.withRestartPolicy(RestartPolicy.alwaysRestart());
}
@Bean
public DockerClient dockerClientConfiguration() {
final DockerClientConfig dockerClientConfig = DefaultDockerClientConfig.createDefaultConfigBuilder()
.withDockerHost("unix:///var/run/docker.sock")
.build();
final DockerHttpClient dockerHttpClient = new ApacheDockerHttpClient.Builder()
.dockerHost(dockerClientConfig.getDockerHost())
.sslConfig(dockerClientConfig.getSSLConfig())
.build();
return DockerClientBuilder.getInstance()
.withDockerHttpClient(dockerHttpClient)
.build();
}
}
......@@ -70,7 +70,7 @@ public class DatabaseService {
log.debug("retrieved database {}", database);
// check if postgres
if (!database.getContainer().getImage().getRepository().equals("postgres")) {
log.error("only postgres is supported currently");
log.error("No support for {}:{}", database.getContainer().getImage().getRepository(), database.getContainer().getImage().getTag());
throw new ImageNotSupportedException("Currently only PostgreSQL is supported.");
}
// call container to create database
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment