Skip to content

Commit

Permalink
Issue 392 improve integration test coverage (#682)
Browse files Browse the repository at this point in the history
  • Loading branch information
sahibamittal authored Jul 28, 2023
1 parent 8d83659 commit 551284b
Show file tree
Hide file tree
Showing 4 changed files with 516 additions and 124 deletions.
5 changes: 5 additions & 0 deletions repository-meta-analyzer/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-suite</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-mockito</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import com.github.tomakehurst.wiremock.http.ContentTypeHeader;
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusIntegrationTest;
import io.quarkus.test.junit.QuarkusTestProfile;
import io.quarkus.test.junit.TestProfile;
import io.quarkus.test.kafka.InjectKafkaCompanion;
import io.quarkus.test.kafka.KafkaCompanionResource;
import io.smallrye.reactive.messaging.kafka.companion.KafkaCompanion;
Expand All @@ -22,6 +24,8 @@
import org.hyades.util.WireMockTestResource.InjectWireMock;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;

import java.sql.Connection;
import java.sql.DriverManager;
Expand All @@ -31,86 +35,264 @@

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

@QuarkusIntegrationTest
@QuarkusTestResource(KafkaCompanionResource.class)
@QuarkusTestResource(WireMockTestResource.class)
@Suite
@SelectClasses(value = {
RepositoryMetaAnalyzerIT.WithValidPurl.class,
RepositoryMetaAnalyzerIT.WithInvalidPurl.class,
RepositoryMetaAnalyzerIT.NoCapableAnalyzer.class,
RepositoryMetaAnalyzerIT.InternalAnalyzerNonInternalComponent.class
})
class RepositoryMetaAnalyzerIT {

@InjectKafkaCompanion
KafkaCompanion kafkaCompanion;

@InjectWireMock
WireMockServer wireMockServer;

@BeforeEach
void beforeEach() throws Exception {
// Workaround for the fact that Quarkus < 2.17.0 does not support initializing the database container
// with data. We can't use EntityManager etc. because the test is executed against an already built
// artifact (JAR, container, or native image).
// Can be replaced with quarkus.datasource.devservices.init-script-path after upgrading to Quarkus 2.17.0:
// https://github.com/quarkusio/quarkus/pull/30455
try (final Connection connection = DriverManager.getConnection(
ConfigProvider.getConfig().getValue("quarkus.datasource.jdbc.url", String.class),
ConfigProvider.getConfig().getValue("quarkus.datasource.username", String.class),
ConfigProvider.getConfig().getValue("quarkus.datasource.password", String.class))) {
final PreparedStatement ps = connection.prepareStatement("""
INSERT INTO "REPOSITORY" ("ENABLED", "IDENTIFIER", "INTERNAL", "PASSWORD", "RESOLUTION_ORDER", "TYPE", "URL", "AUTHENTICATIONREQUIRED")
VALUES ('true', 'test', false, NULL, 1, 'GO_MODULES', 'http://localhost:%d', false);
""".formatted(wireMockServer.port()));
ps.execute();
}
@QuarkusIntegrationTest
@QuarkusTestResource(KafkaCompanionResource.class)
@QuarkusTestResource(WireMockTestResource.class)
@TestProfile(WithValidPurl.TestProfile.class)
static class WithValidPurl {

public static class TestProfile implements QuarkusTestProfile {}

@InjectKafkaCompanion
KafkaCompanion kafkaCompanion;

wireMockServer.stubFor(WireMock.get(WireMock.anyUrl())
.willReturn(WireMock.aResponse()
.withStatus(200)
.withResponseBody(Body.ofBinaryOrText("""
{
"Version": "v6.6.6",
"Time": "2022-09-28T21:59:32Z",
"Origin": {
"VCS": "git",
"URL": "https://github.com/acme/acme-lib",
"Ref": "refs/tags/v6.6.6",
"Hash": "39a1d8f8f69040a53114e1ea481e48f6d792c05e"
@InjectWireMock
WireMockServer wireMockServer;

@BeforeEach
void beforeEach() throws Exception {
// Workaround for the fact that Quarkus < 2.17.0 does not support initializing the database container
// with data. We can't use EntityManager etc. because the test is executed against an already built
// artifact (JAR, container, or native image).
// Can be replaced with quarkus.datasource.devservices.init-script-path after upgrading to Quarkus 2.17.0:
// https://github.com/quarkusio/quarkus/pull/30455
try (final Connection connection = DriverManager.getConnection(
ConfigProvider.getConfig().getValue("quarkus.datasource.jdbc.url", String.class),
ConfigProvider.getConfig().getValue("quarkus.datasource.username", String.class),
ConfigProvider.getConfig().getValue("quarkus.datasource.password", String.class))) {
final PreparedStatement ps = connection.prepareStatement("""
INSERT INTO "REPOSITORY" ("ENABLED", "IDENTIFIER", "INTERNAL", "PASSWORD", "RESOLUTION_ORDER", "TYPE", "URL", "AUTHENTICATIONREQUIRED")
VALUES ('true', 'test', false, NULL, 1, 'GO_MODULES', 'http://localhost:%d', false);
""".formatted(wireMockServer.port()));
ps.execute();
}

wireMockServer.stubFor(WireMock.get(WireMock.anyUrl())
.willReturn(WireMock.aResponse()
.withStatus(200)
.withResponseBody(Body.ofBinaryOrText("""
{
"Version": "v6.6.6",
"Time": "2022-09-28T21:59:32Z",
"Origin": {
"VCS": "git",
"URL": "https://github.com/acme/acme-lib",
"Ref": "refs/tags/v6.6.6",
"Hash": "39a1d8f8f69040a53114e1ea481e48f6d792c05e"
}
}
}
""".getBytes(), new ContentTypeHeader(MediaType.APPLICATION_JSON))
)));
""".getBytes(), new ContentTypeHeader(MediaType.APPLICATION_JSON))
)));
}

@Test
void test() {
final var command = AnalysisCommand.newBuilder()
.setComponent(org.hyades.proto.repometaanalysis.v1.Component.newBuilder()
.setPurl("pkg:golang/github.com/acme/[email protected]"))
.build();

kafkaCompanion
.produce(Serdes.String(), new KafkaProtobufSerde<>(AnalysisCommand.parser()))
.fromRecords(new ProducerRecord<>(KafkaTopic.REPO_META_ANALYSIS_COMMAND.getName(), "foo", command));

final List<ConsumerRecord<String, AnalysisResult>> results = kafkaCompanion
.consume(Serdes.String(), new KafkaProtobufSerde<>(AnalysisResult.parser()))
.fromTopics(KafkaTopic.REPO_META_ANALYSIS_RESULT.getName(), 1, Duration.ofSeconds(5))
.awaitCompletion()
.getRecords();

assertThat(results).satisfiesExactly(
record -> {
assertThat(record.key()).isEqualTo("pkg:golang/github.com/acme/acme-lib");
assertThat(record.value()).isNotNull();
final AnalysisResult result = record.value();
assertThat(result.hasComponent()).isTrue();
assertThat(result.hasRepository()).isTrue();
assertThat(result.getRepository()).isEqualTo("test");
assertThat(result.hasLatestVersion()).isTrue();
assertThat(result.getLatestVersion()).isEqualTo("v6.6.6");
assertThat(result.hasPublished()).isTrue();
assertThat(result.getPublished().getSeconds()).isEqualTo(1664402372);
}
);
}
}

@QuarkusIntegrationTest
@QuarkusTestResource(KafkaCompanionResource.class)
@QuarkusTestResource(WireMockTestResource.class)
@TestProfile(WithInvalidPurl.TestProfile.class)
static class WithInvalidPurl {

public static class TestProfile implements QuarkusTestProfile {}

@InjectKafkaCompanion
KafkaCompanion kafkaCompanion;

@InjectWireMock
WireMockServer wireMockServer;

@BeforeEach
void beforeEach() throws Exception {
try (final Connection connection = DriverManager.getConnection(
ConfigProvider.getConfig().getValue("quarkus.datasource.jdbc.url", String.class),
ConfigProvider.getConfig().getValue("quarkus.datasource.username", String.class),
ConfigProvider.getConfig().getValue("quarkus.datasource.password", String.class))) {
final PreparedStatement ps = connection.prepareStatement("""
INSERT INTO "REPOSITORY" ("ENABLED", "IDENTIFIER", "INTERNAL", "PASSWORD", "RESOLUTION_ORDER", "TYPE", "URL", "AUTHENTICATIONREQUIRED")
VALUES ('true', 'test', false, NULL, 2, 'NPM', 'http://localhost:%d', false);
""".formatted(wireMockServer.port()));
ps.execute();
}
}

@Test
void test() {
final var command = AnalysisCommand.newBuilder()
.setComponent(org.hyades.proto.repometaanalysis.v1.Component.newBuilder()
.setPurl("invalid-purl"))
.build();

kafkaCompanion
.produce(Serdes.String(), new KafkaProtobufSerde<>(AnalysisCommand.parser()))
.fromRecords(new ProducerRecord<>(KafkaTopic.REPO_META_ANALYSIS_COMMAND.getName(), "foo", command));

final List<ConsumerRecord<String, AnalysisResult>> results = kafkaCompanion
.consume(Serdes.String(), new KafkaProtobufSerde<>(AnalysisResult.parser()))
.fromTopics(KafkaTopic.REPO_META_ANALYSIS_RESULT.getName(), 1, Duration.ofSeconds(5))
.awaitCompletion()
.getRecords();

assertThat(results).isEmpty();
}
}

@Test
void test() {
final var command = AnalysisCommand.newBuilder()
.setComponent(org.hyades.proto.repometaanalysis.v1.Component.newBuilder()
.setPurl("pkg:golang/github.com/acme/[email protected]"))
.build();

kafkaCompanion
.produce(Serdes.String(), new KafkaProtobufSerde<>(AnalysisCommand.parser()))
.fromRecords(new ProducerRecord<>(KafkaTopic.REPO_META_ANALYSIS_COMMAND.getName(), "foo", command));

final List<ConsumerRecord<String, AnalysisResult>> results = kafkaCompanion
.consume(Serdes.String(), new KafkaProtobufSerde<>(AnalysisResult.parser()))
.fromTopics(KafkaTopic.REPO_META_ANALYSIS_RESULT.getName(), 1, Duration.ofSeconds(5))
.awaitCompletion()
.getRecords();

assertThat(results).satisfiesExactly(
record -> {
assertThat(record.key()).isEqualTo("pkg:golang/github.com/acme/acme-lib");
assertThat(record.value()).isNotNull();

final AnalysisResult result = record.value();
assertThat(result.hasComponent()).isTrue();
assertThat(result.getComponent()).isEqualTo(command.getComponent());
assertThat(result.hasRepository()).isTrue();
assertThat(result.getRepository()).isEqualTo("test");
assertThat(result.hasLatestVersion()).isTrue();
assertThat(result.getLatestVersion()).isEqualTo("v6.6.6");
assertThat(result.hasPublished()).isTrue();
assertThat(result.getPublished().getSeconds()).isEqualTo(1664402372);
}
);
@QuarkusIntegrationTest
@QuarkusTestResource(KafkaCompanionResource.class)
@QuarkusTestResource(WireMockTestResource.class)
@TestProfile(NoCapableAnalyzer.TestProfile.class)
static class NoCapableAnalyzer {

public static class TestProfile implements QuarkusTestProfile {}

@InjectKafkaCompanion
KafkaCompanion kafkaCompanion;

@InjectWireMock
WireMockServer wireMockServer;

@BeforeEach
void beforeEach() throws Exception {
try (final Connection connection = DriverManager.getConnection(
ConfigProvider.getConfig().getValue("quarkus.datasource.jdbc.url", String.class),
ConfigProvider.getConfig().getValue("quarkus.datasource.username", String.class),
ConfigProvider.getConfig().getValue("quarkus.datasource.password", String.class))) {
final PreparedStatement ps = connection.prepareStatement("""
INSERT INTO "REPOSITORY" ("ENABLED", "IDENTIFIER", "INTERNAL", "PASSWORD", "RESOLUTION_ORDER", "TYPE", "URL", "AUTHENTICATIONREQUIRED")
VALUES ('true', 'test', false, NULL, 2, 'CPAN', 'http://localhost:%d', false);
""".formatted(wireMockServer.port()));
ps.execute();
}
}

@Test
void test() {
final var command = AnalysisCommand.newBuilder()
.setComponent(org.hyades.proto.repometaanalysis.v1.Component.newBuilder()
.setPurl("pkg:github/github.com/acme/[email protected]"))
.build();

kafkaCompanion
.produce(Serdes.String(), new KafkaProtobufSerde<>(AnalysisCommand.parser()))
.fromRecords(new ProducerRecord<>(KafkaTopic.REPO_META_ANALYSIS_COMMAND.getName(), "foo", command));

final List<ConsumerRecord<String, AnalysisResult>> results = kafkaCompanion
.consume(Serdes.String(), new KafkaProtobufSerde<>(AnalysisResult.parser()))
.fromTopics(KafkaTopic.REPO_META_ANALYSIS_RESULT.getName(), 1, Duration.ofSeconds(5))
.awaitCompletion()
.getRecords();
assertThat(results).satisfiesExactly(
record -> {
assertThat(record.key()).isEqualTo("pkg:github/github.com/acme/acme-lib");
assertThat(record.value()).isNotNull();
final AnalysisResult result = record.value();
assertThat(result.hasComponent()).isTrue();
assertThat(result.getComponent()).isEqualTo(command.getComponent());
assertThat(result.hasRepository()).isFalse();
assertThat(result.hasLatestVersion()).isFalse();
assertThat(result.hasPublished()).isFalse();
}
);
}
}

@QuarkusIntegrationTest
@QuarkusTestResource(KafkaCompanionResource.class)
@QuarkusTestResource(WireMockTestResource.class)
@TestProfile(InternalAnalyzerNonInternalComponent.TestProfile.class)
static class InternalAnalyzerNonInternalComponent {

public static class TestProfile implements QuarkusTestProfile {}

@InjectKafkaCompanion
KafkaCompanion kafkaCompanion;

@InjectWireMock
WireMockServer wireMockServer;

@BeforeEach
void beforeEach() throws Exception {
try (final Connection connection = DriverManager.getConnection(
ConfigProvider.getConfig().getValue("quarkus.datasource.jdbc.url", String.class),
ConfigProvider.getConfig().getValue("quarkus.datasource.username", String.class),
ConfigProvider.getConfig().getValue("quarkus.datasource.password", String.class))) {
final PreparedStatement ps = connection.prepareStatement("""
INSERT INTO "REPOSITORY" ("ENABLED", "IDENTIFIER", "INTERNAL", "PASSWORD", "RESOLUTION_ORDER", "TYPE", "URL", "AUTHENTICATIONREQUIRED")
VALUES ('true', 'test', true, NULL, 2, 'MAVEN', 'http://localhost:%d', false);
""".formatted(wireMockServer.port()));
ps.execute();
}
}

@Test
void test() {
final var command = AnalysisCommand.newBuilder()
.setComponent(org.hyades.proto.repometaanalysis.v1.Component.newBuilder()
.setPurl("pkg:golang/github.com/acme/[email protected]")
.setInternal(false))
.build();

kafkaCompanion
.produce(Serdes.String(), new KafkaProtobufSerde<>(AnalysisCommand.parser()))
.fromRecords(new ProducerRecord<>(KafkaTopic.REPO_META_ANALYSIS_COMMAND.getName(), "foo", command));

final List<ConsumerRecord<String, AnalysisResult>> results = kafkaCompanion
.consume(Serdes.String(), new KafkaProtobufSerde<>(AnalysisResult.parser()))
.fromTopics(KafkaTopic.REPO_META_ANALYSIS_RESULT.getName(), 1, Duration.ofSeconds(5))
.awaitCompletion()
.getRecords();
assertThat(results).satisfiesExactly(
record -> {
assertThat(record.key()).isEqualTo("pkg:golang/github.com/acme/acme-lib");
assertThat(record.value()).isNotNull();
final AnalysisResult result = record.value();
assertThat(result.hasComponent()).isTrue();
assertThat(result.getComponent()).isEqualTo(command.getComponent());
assertThat(result.hasRepository()).isFalse();
assertThat(result.hasLatestVersion()).isFalse();
assertThat(result.hasPublished()).isFalse();
}
);
}
}
}
Loading

0 comments on commit 551284b

Please sign in to comment.